squash error codes before emitting error tokens
authorLuke Howard <lukeh@padl.com>
Tue, 12 Oct 2010 01:04:18 +0000 (12:04 +1100)
committerLuke Howard <lukeh@padl.com>
Tue, 12 Oct 2010 01:04:18 +0000 (12:04 +1100)
accept_sec_context.c
gsseap_err.et
init_sec_context.c
util_radius.h

index 86327eb..2fe3abf 100644 (file)
@@ -366,11 +366,12 @@ eapGssSmAcceptAuthenticate(OM_uint32 *minor,
         major = GSS_S_CONTINUE_NEEDED;
         break;
     case PW_AUTHENTICATION_REJECT:
-        *minor = GSSEAP_PEER_AUTH_FAILURE;
+        *minor = GSSEAP_RADIUS_AUTH_FAILURE;
         major = GSS_S_DEFECTIVE_CREDENTIAL;
         goto cleanup;
         break;
     default:
+        *minor = GSSEAP_UNKNOWN_RADIUS_CODE;
         major = GSS_S_FAILURE;
         goto cleanup;
         break;
@@ -378,8 +379,11 @@ eapGssSmAcceptAuthenticate(OM_uint32 *minor,
 
     major = gssEapRadiusGetAvp(minor, frresp->vps, PW_EAP_MESSAGE, 0,
                                outputToken, TRUE);
-    if ((major == GSS_S_UNAVAILABLE && frresp->code != PW_AUTHENTICATION_ACK) ||
-        GSS_ERROR(major))
+    if (major == GSS_S_UNAVAILABLE && frresp->code == PW_ACCESS_CHALLENGE) {
+        *minor = GSSEAP_MISSING_EAP_REQUEST;
+        major = GSS_S_DEFECTIVE_TOKEN;
+        goto cleanup;
+    } else if (GSS_ERROR(major))
         goto cleanup;
 
     if (frresp->code == PW_ACCESS_CHALLENGE) {
@@ -472,6 +476,36 @@ makeErrorToken(OM_uint32 *minor,
     unsigned char errorData[8];
     gss_buffer_desc errorBuffer;
 
+    assert(GSS_ERROR(majorStatus));
+
+    /*
+     * Only return error codes that the initiator could have caused,
+     * to avoid information leakage.
+     */
+    switch (minorStatus) {
+    case GSSEAP_WRONG_SIZE:
+    case GSSEAP_WRONG_MECH:
+    case GSSEAP_BAD_TOK_HEADER:
+    case GSSEAP_BAD_DIRECTION:
+    case GSSEAP_WRONG_TOK_ID:
+    case GSSEAP_CRIT_EXT_UNAVAILABLE:
+    case GSSEAP_MISSING_REQUIRED_EXT:
+    case GSSEAP_KEY_UNAVAILABLE:
+    case GSSEAP_KEY_TOO_SHORT:
+    case GSSEAP_RADIUS_AUTH_FAILURE:
+    case GSSEAP_UNKNOWN_RADIUS_CODE:
+    case GSSEAP_MISSING_EAP_REQUEST:
+        break;
+    default:
+        /* Don't return system error codes */
+        if (IS_RADIUS_ERROR(minorStatus))
+            minorStatus = GSSEAP_GENERIC_RADIUS_ERROR;
+        else
+            return GSS_S_COMPLETE;
+    }
+
+    minorStatus -= ERROR_TABLE_BASE_eapg;
+
     store_uint32_be(majorStatus, &errorData[0]);
     store_uint32_be(minorStatus, &errorData[4]);
 
index 0e4a359..8d4d53f 100644 (file)
 
 error_table eapg
 
-error_code GSSEAP_BAD_SERVICE_NAME,         "Could not parse service name"
+error_code GSSEAP_RESERVED,                 ""
 error_code GSSEAP_WRONG_SIZE,               "Buffer is incorrect size"
-error_code GSSEAP_BAD_USAGE,                "Credential usage type is unknown"
 error_code GSSEAP_WRONG_MECH,               "Mechanism OID is incorrect"
 error_code GSSEAP_BAD_TOK_HEADER,           "Token header is malformed or corrupt"
 error_code GSSEAP_BAD_DIRECTION,            "Packet was replayed in wrong direction"
 error_code GSSEAP_WRONG_TOK_ID,             "Received token ID does not match expected token ID"
-error_code GSSEAP_CRED_USAGE_MISMATCH,      "Credential usage does not match requested usage"
 error_code GSSEAP_CRIT_EXT_UNAVAILABLE,     "Critical extension unavailable"
 error_code GSSEAP_MISSING_REQUIRED_EXT,     "Missing required extension"
+error_code GSSEAP_BAD_SERVICE_NAME,         "Could not parse service name"
+error_code GSSEAP_KEY_UNAVAILABLE,          "EAP key unavailable"
+error_code GSSEAP_KEY_TOO_SHORT,            "EAP key too short"
+error_code GSSEAP_RADIUS_AUTH_FAILURE,      "Authentication rejected by RADIUS server"
+error_code GSSEAP_UNKNOWN_RADIUS_CODE,      "Received unknown response code from RADIUS server"
+error_code GSSEAP_MISSING_EAP_REQUEST,      "RADIUS response is missing EAP request"
+error_code GSSEAP_GENERIC_RADIUS_ERROR,     "Generic RADIUS error"
+error_code GSSEAP_BAD_USAGE,                "Credential usage type is unknown"
+error_code GSSEAP_CRED_USAGE_MISMATCH,      "Credential usage does not match requested usage"
 error_code GSSEAP_INPUT_TOO_LONG,           "PRF input too long"
 error_code GSSEAP_CONTEXT_ESTABLISHED,      "Context is already fully established"
 error_code GSSEAP_CONTEXT_INCOMPLETE,       "Attempt to use incomplete security context"
@@ -49,10 +56,8 @@ error_code GSSEAP_RADSEC_INIT_FAILURE,      "Failed to initialise RadSec library
 error_code GSSEAP_SAML_INIT_FAILURE,        "Failed to initialise SAML library"
 error_code GSSEAP_SHIB_INIT_FAILURE,        "Failed to initialise Shibboleth"
 error_code GSSEAP_PEER_INIT_FAILURE,        "Failed to initialise EAP state machine"
-error_code GSSEAP_PEER_AUTH_FAILURE,        "EAP authentication failure"
+error_code GSSEAP_PEER_AUTH_FAILURE,        "EAP peer authentication failure"
 error_code GSSEAP_PEER_BAD_MESSAGE,         "Received bad EAP message"
-error_code GSSEAP_KEY_UNAVAILABLE,          "EAP key unavailable"
-error_code GSSEAP_KEY_TOO_SHORT,            "EAP key too short"
 error_code GSSEAP_NO_ATTR_CONTEXT,          "Name has no attributes"
 error_code GSSEAP_NO_ATTR_PROVIDERS,        "Failed to initialise attribute providers"
 error_code GSSEAP_NO_SUCH_ATTR,             "Unknown naming attribute"
index 56f41de..fb34b36 100644 (file)
@@ -585,7 +585,7 @@ eapGssSmInitError(OM_uint32 *minor,
     p = (unsigned char *)inputToken->value;
 
     major = load_uint32_be(&p[0]);
-    *minor = load_uint32_be(&p[4]);
+    *minor = ERROR_TABLE_BASE_eapg + load_uint32_be(&p[4]);
 
     if (!GSS_ERROR(major)) {
         *minor = GSSEAP_BAD_ERROR_TOKEN;
index 68561ce..4ab7b91 100644 (file)
@@ -156,6 +156,9 @@ gssEapRadiusMapError(OM_uint32 *minor,
 #define PW_GSS_ACCEPTOR_REALM_NAME          131
 #define PW_SAML_AAA_ASSERTION               132
 
+#define IS_RADIUS_ERROR(code)               ((code) >= ERROR_TABLE_BASE_rse && \
+                                             (code) <= ERROR_TABLE_BASE_rse + RSE_SOME_ERROR)
+
 #ifdef __cplusplus
 }
 #endif