# Protocol errors that can be returned in an error token. This should match
# up with makeErrorToken in accept_sec_context.c.
#
-error_code GSSEAP_RESERVED, ""
-error_code GSSEAP_WRONG_SIZE, "Buffer is incorrect size"
-error_code GSSEAP_WRONG_MECH, "Mechanism OID is incorrect"
-error_code GSSEAP_BAD_TOK_HEADER, "Token header is malformed or corrupt"
-error_code GSSEAP_TOK_TRUNC, "Token is missing data"
-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_CRIT_EXT_UNAVAILABLE, "Critical extension unavailable"
-error_code GSSEAP_MISSING_REQUIRED_EXT, "Missing required extension"
-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_RESERVED, ""
+error_code GSSEAP_WRONG_SIZE, "Buffer is incorrect size"
+error_code GSSEAP_WRONG_MECH, "Mechanism OID is incorrect"
+error_code GSSEAP_BAD_TOK_HEADER, "Token header is malformed or corrupt"
+error_code GSSEAP_TOK_TRUNC, "Token is missing data"
+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_CRIT_EXT_UNAVAILABLE, "Critical extension unavailable"
+error_code GSSEAP_MISSING_REQUIRED_EXT, "Missing required extension"
+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"
#
# Context errors
#
-error_code GSSEAP_CONTEXT_ESTABLISHED, "Context is already fully established"
-error_code GSSEAP_CONTEXT_INCOMPLETE, "Attempt to use incomplete security context"
-error_code GSSEAP_BAD_CONTEXT_TOKEN, "Context token is malformed or corrupt"
-error_code GSSEAP_BAD_ERROR_TOKEN, "Error token is malformed or corrupt"
-error_code GSSEAP_BAD_CONTEXT_OPTION, "Bad context option"
+error_code GSSEAP_CONTEXT_ESTABLISHED, "Context is already fully established"
+error_code GSSEAP_CONTEXT_INCOMPLETE, "Attempt to use incomplete security context"
+error_code GSSEAP_BAD_CONTEXT_TOKEN, "Context token is malformed or corrupt"
+error_code GSSEAP_BAD_ERROR_TOKEN, "Error token is malformed or corrupt"
+error_code GSSEAP_BAD_CONTEXT_OPTION, "Bad context option"
#
# Name errors
#
-error_code GSSEAP_BAD_SERVICE_NAME, "Name is not a valid service name"
-error_code GSSEAP_BAD_INITIATOR_NAME, "Initiator identity must be a valid name"
-error_code GSSEAP_NO_HOSTNAME, "Could not determine local host name"
+error_code GSSEAP_BAD_SERVICE_NAME, "Name is not a valid service name"
+error_code GSSEAP_BAD_INITIATOR_NAME, "Initiator identity must be a valid name"
+error_code GSSEAP_NO_HOSTNAME, "Could not determine local host name"
#
# Credential errors
#
-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_CRED_MECH_MISMATCH, "Credential is not usable with this mechanism"
-error_code GSSEAP_BAD_CRED_OPTION, "Bad credential option"
+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_CRED_MECH_MISMATCH, "Credential is not usable with this mechanism"
+error_code GSSEAP_BAD_CRED_OPTION, "Bad credential option"
#
# Wrap/unwrap/PRF errors
#
-error_code GSSEAP_BAD_WRAP_TOKEN, "Bad RFC 4121 wrap or MIC token"
-error_code GSSEAP_MISSING_IOV, "IOV is missing required buffer"
-error_code GSSEAP_BAD_STREAM_IOV, "Stream IOV can only contain a single data buffer"
-error_code GSSEAP_BAD_PADDING_IOV, "Padding IOV is not permitted for RFC 4121 tokens"
-error_code GSSEAP_UNKNOWN_QOP, "Unknown quality of protection specified"
-error_code GSSEAP_INPUT_TOO_LONG, "PRF input too long"
-error_code GSSEAP_BAD_PRF_KEY, "PRF key usage type is unknown"
+error_code GSSEAP_BAD_WRAP_TOKEN, "Bad RFC 4121 wrap or MIC token"
+error_code GSSEAP_MISSING_IOV, "IOV is missing required buffer"
+error_code GSSEAP_BAD_STREAM_IOV, "Stream IOV can only contain a single data buffer"
+error_code GSSEAP_BAD_PADDING_IOV, "Padding IOV is not permitted for RFC 4121 tokens"
+error_code GSSEAP_UNKNOWN_QOP, "Unknown quality of protection specified"
+error_code GSSEAP_INPUT_TOO_LONG, "PRF input too long"
+error_code GSSEAP_BAD_PRF_KEY, "PRF key usage type is unknown"
#
# libeap errors
#
-error_code GSSEAP_LIBEAP_INIT_FAILURE, "Failed to initialise EAP library"
-error_code GSSEAP_PEER_SM_INIT_FAILURE, "Failed to create EAP state machine"
-error_code GSSEAP_PEER_AUTH_FAILURE, "EAP peer authentication failure"
-error_code GSSEAP_PEER_BAD_MESSAGE, "Received bad EAP message"
+error_code GSSEAP_LIBEAP_INIT_FAILURE, "Failed to initialize EAP library"
+error_code GSSEAP_PEER_SM_INIT_FAILURE, "Failed to create EAP state machine"
+error_code GSSEAP_PEER_AUTH_FAILURE, "EAP peer authentication failure"
+error_code GSSEAP_PEER_BAD_MESSAGE, "Received bad EAP message"
#
# RadSec initialisation errors
#
-error_code GSSEAP_RADSEC_INIT_FAILURE, "Failed to initialise RadSec library"
-error_code GSSEAP_RADSEC_CONTEXT_FAILURE, "Failed to create RadSec context"
+error_code GSSEAP_RADSEC_INIT_FAILURE, "Failed to initialize RadSec library"
+error_code GSSEAP_RADSEC_CONTEXT_FAILURE, "Failed to create RadSec context"
#
-# SAML/Shibboleth/attribute errors
+# Attribute errors
#
-error_code GSSEAP_SAML_INIT_FAILURE, "Failed to initialise SAML library"
-error_code GSSEAP_SHIB_INIT_FAILURE, "Failed to initialise Shibboleth"
-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"
-error_code GSSEAP_BAD_ATTR_TOKEN, "Serialised attributes are malformed or corrupt"
-error_code GSSEAP_ATTR_CONTEXT_FAILURE, "Failed to initialise attribute context"
+error_code GSSEAP_NO_ATTR_CONTEXT, "Name has no attributes"
+error_code GSSEAP_NO_ATTR_PROVIDERS, "Failed to initialize attribute providers"
+error_code GSSEAP_NO_SUCH_ATTR, "Unknown naming attribute"
+error_code GSSEAP_BAD_ATTR_TOKEN, "Serialised attributes are malformed or corrupt"
+error_code GSSEAP_ATTR_CONTEXT_FAILURE, "Failed to initialize attribute context"
+
+#
+# OpenSAML errors
+#
+error_code GSSEAP_SAML_INIT_FAILURE, "Failed to initialize SAML library"
+error_code GSSEAP_SAML_SEC_POLICY_FAILURE, "Failed to process SAML security policy"
+error_code GSSEAP_SAML_BINDING_FAILURE, "Failed in SAML binding processing"
+error_code GSSEAP_SAML_PROFILE_FAILURE, "Failed to process SAML profile"
+error_code GSSEAP_SAML_FATAL_PROFILE_FAILURE, "Non-recoverable failure in SAML profile processing"
+error_code GSSEAP_SAML_RETRY_PROFILE_FAILURE, "Temporary failure in SAML profile processing"
+error_code GSSEAP_SAML_METADATA_FAILURE, "Failure related to SAML metadata use"
+
+#
+# Shibboleth errors
+#
+error_code GSSEAP_SHIB_INIT_FAILURE, "Failed to initialize Shibboleth"
+error_code GSSEAP_SHIB_ATTR_FAILURE, "Failure during local attribute processing"
+error_code GSSEAP_SHIB_ATTR_EXTRACT_FAILURE, "Failed to extract local attributes"
+error_code GSSEAP_SHIB_ATTR_FILTER_FAILURE, "Failed to filter local attributes"
+error_code GSSEAP_SHIB_ATTR_RESOLVE_FAILURE, "Failed to resolve local attributes"
+error_code GSSEAP_SHIB_CONFIG_FAILURE, "Local attribute configuration failure"
+error_code GSSEAP_SHIB_LISTENER_FAILURE, "Failed to communicate with local attribute server"
#
# Extensions
#
-error_code GSSEAP_BINDINGS_MISMATCH, "Channel bindings do not match"
-error_code GSSEAP_NO_MECHGLUE_SYMBOL, "Could not find symbol in mechanism glue"
-error_code GSSEAP_BAD_INVOCATION, "Bad mechanism invoke OID"
+error_code GSSEAP_BINDINGS_MISMATCH, "Channel bindings do not match"
+error_code GSSEAP_NO_MECHGLUE_SYMBOL, "Could not find symbol in mechanism glue"
+error_code GSSEAP_BAD_INVOCATION, "Bad mechanism invoke OID"
end
return expiryTime;
}
-/*
- * Map C++ exception to GSS status
- */
-static OM_uint32
-mapException(OM_uint32 *minor, std::exception &e)
+OM_uint32
+gss_eap_attr_ctx::mapException(OM_uint32 *minor, std::exception &e) const
{
- OM_uint32 major = GSS_S_FAILURE;
+ unsigned int i;
+ OM_uint32 major;
+
+ /* Errors we handle ourselves */
+ major = GSS_S_FAILURE;
- /* XXX TODO implement other mappings */
- if (typeid(e) == typeid(std::bad_alloc))
+ if (typeid(e) == typeid(std::bad_alloc)) {
*minor = ENOMEM;
- else
- *minor = 0;
+ goto cleanup;
+ }
-#ifdef GSSEAP_DEBUG
+ /* Errors we delegate to providers */
+ major = GSS_S_CONTINUE_NEEDED;
+
+ for (i = ATTR_TYPE_MIN; i <= ATTR_TYPE_MAX; i++) {
+ gss_eap_attr_provider *provider = m_providers[i];
+
+ if (provider == NULL)
+ continue;
+
+ major = provider->mapException(minor, e);
+ if (major != GSS_S_CONTINUE_NEEDED)
+ break;
+ }
+
+ if (major == GSS_S_CONTINUE_NEEDED) {
+ *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
+ major = GSS_S_FAILURE;
+ }
+
+cleanup:
+#if 0
/* rethrow for now for debugging */
throw e;
#endif
+ assert(GSS_ERROR(major));
+
return major;
}
return GSS_S_UNAVAILABLE;
}
} catch (std::exception &e) {
- return mapException(minor, e);
+ return name->attrCtx->mapException(minor, e);
}
return GSS_S_COMPLETE;
return GSS_S_UNAVAILABLE;
}
} catch (std::exception &e) {
- return mapException(minor, e);
+ return name->attrCtx->mapException(minor, e);
}
return GSS_S_COMPLETE;
(int)attr->length, (char *)attr->value);
return GSS_S_UNAVAILABLE;
}
- } catch (std::exception &ex) {
- return mapException(minor, ex);
+ } catch (std::exception &e) {
+ return name->attrCtx->mapException(minor, e);
}
return GSS_S_COMPLETE;
(int)attr->length, (char *)attr->value);
return GSS_S_UNAVAILABLE;
}
- } catch (std::exception &ex) {
- return mapException(minor, ex);
+ } catch (std::exception &e) {
+ return name->attrCtx->mapException(minor, e);
}
return GSS_S_COMPLETE;
try {
name->attrCtx->exportToBuffer(buffer);
} catch (std::exception &e) {
- return mapException(minor, e);
+ return name->attrCtx->mapException(minor, e);
}
return GSS_S_COMPLETE;
name->attrCtx = ctx;
} catch (std::exception &e) {
delete ctx;
- return mapException(minor, e);
+ return name->attrCtx->mapException(minor, e);
}
}
}
} catch (std::exception &e) {
delete ctx;
- return mapException(minor, e);
+ return in->attrCtx->mapException(minor, e);
}
return GSS_S_COMPLETE;
try {
*output = name->attrCtx->mapToAny(authenticated, type_id);
} catch (std::exception &e) {
- return mapException(minor, e);
+ return name->attrCtx->mapException(minor, e);
}
return GSS_S_COMPLETE;
name->attrCtx->releaseAnyNameMapping(type_id, *input);
*input = NULL;
} catch (std::exception &e) {
- return mapException(minor, e);
+ return name->attrCtx->mapException(minor, e);
}
return GSS_S_COMPLETE;
assert(gssCtx != GSS_C_NO_CONTEXT);
+ *pAttrContext = NULL;
+
major = gssEapAttrProvidersInit(minor);
if (GSS_ERROR(major))
return major;
- ctx = new gss_eap_attr_ctx();
- if (!ctx->initFromGssContext(gssCred, gssCtx)) {
+ try {
+ ctx = new gss_eap_attr_ctx();
+ if (!ctx->initFromGssContext(gssCred, gssCtx)) {
+ delete ctx;
+ *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
+ return GSS_S_FAILURE;
+ }
+ } catch (std::exception &e) {
+ major = ctx->mapException(minor, e);
delete ctx;
- *minor = GSSEAP_ATTR_CONTEXT_FAILURE;
- return GSS_S_FAILURE;
+ return major;
}
gssCtx->expiryTime = ctx->getExpiryTime();
+ *pAttrContext = ctx;
+
*minor = 0;
return GSS_S_COMPLETE;
}