From 67df8888f7a6f5260fd6b0dbc5c2837b37b77e07 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Tue, 12 Oct 2010 01:16:56 +0100 Subject: [PATCH] Add error token type --- mech_eap/accept_sec_context.c | 64 +++++++++++++++++++++++++++++++------------ mech_eap/gssapiP_eap.h | 1 + mech_eap/gsseap_err.et | 1 + mech_eap/init_sec_context.c | 50 ++++++++++++++++++++++++++++----- mech_eap/util.h | 13 +++++---- 5 files changed, 99 insertions(+), 30 deletions(-) diff --git a/mech_eap/accept_sec_context.c b/mech_eap/accept_sec_context.c index b8446d3..86327eb 100644 --- a/mech_eap/accept_sec_context.c +++ b/mech_eap/accept_sec_context.c @@ -463,6 +463,24 @@ eapGssSmAcceptEstablished(OM_uint32 *minor, return GSS_S_BAD_STATUS; } +static OM_uint32 +makeErrorToken(OM_uint32 *minor, + OM_uint32 majorStatus, + OM_uint32 minorStatus, + gss_buffer_t outputToken) +{ + unsigned char errorData[8]; + gss_buffer_desc errorBuffer; + + store_uint32_be(majorStatus, &errorData[0]); + store_uint32_be(minorStatus, &errorData[4]); + + errorBuffer.length = sizeof(errorData); + errorBuffer.value = errorData; + + return duplicateBuffer(minor, &errorBuffer, outputToken); +} + static struct gss_eap_acceptor_sm { enum gss_eap_token_type inputTokenType; enum gss_eap_token_type outputTokenType; @@ -473,13 +491,14 @@ static struct gss_eap_acceptor_sm { gss_channel_bindings_t, gss_buffer_t); } eapGssAcceptorSm[] = { - { TOK_TYPE_EAP_RESP, TOK_TYPE_EAP_REQ, eapGssSmAcceptIdentity }, - { TOK_TYPE_EAP_RESP, TOK_TYPE_EAP_REQ, eapGssSmAcceptAuthenticate }, - { TOK_TYPE_EXT_REQ, TOK_TYPE_NONE, eapGssSmAcceptExtensionsReq }, - { TOK_TYPE_NONE, TOK_TYPE_EXT_RESP, eapGssSmAcceptExtensionsResp }, - { TOK_TYPE_NONE, TOK_TYPE_NONE, eapGssSmAcceptEstablished }, + { TOK_TYPE_EAP_RESP, TOK_TYPE_EAP_REQ, eapGssSmAcceptIdentity }, + { TOK_TYPE_EAP_RESP, TOK_TYPE_EAP_REQ, eapGssSmAcceptAuthenticate }, + { TOK_TYPE_EXT_REQ, TOK_TYPE_NONE, eapGssSmAcceptExtensionsReq }, + { TOK_TYPE_NONE, TOK_TYPE_EXT_RESP, eapGssSmAcceptExtensionsResp }, + { TOK_TYPE_NONE, TOK_TYPE_NONE, eapGssSmAcceptEstablished }, + { TOK_TYPE_NONE, TOK_TYPE_CONTEXT_ERR, NULL }, #ifdef GSSEAP_ENABLE_REAUTH - { TOK_TYPE_GSS_REAUTH, TOK_TYPE_GSS_REAUTH, eapGssSmAcceptGssReauth }, + { TOK_TYPE_GSS_REAUTH, TOK_TYPE_GSS_REAUTH, eapGssSmAcceptGssReauth }, #endif }; @@ -575,23 +594,23 @@ gss_accept_sec_context(OM_uint32 *minor, &innerInputToken, input_chan_bindings, &innerOutputToken); - if (GSS_ERROR(major)) - goto cleanup; + if (GSS_ERROR(major)) { + /* Generate an error token */ + tmpMajor = makeErrorToken(&tmpMinor, major, *minor, &innerOutputToken); + if (GSS_ERROR(tmpMajor)) { + major = tmpMajor; + goto cleanup; + } + + sm = &eapGssAcceptorSm[EAP_STATE_ERROR]; + goto send_token; + } } while (major == GSS_S_CONTINUE_NEEDED && innerOutputToken.length == 0); if (mech_type != NULL) { if (!gssEapInternalizeOid(ctx->mechanismUsed, mech_type)) duplicateOid(&tmpMinor, ctx->mechanismUsed, mech_type); } - if (innerOutputToken.value != NULL) { - tmpMajor = gssEapMakeToken(&tmpMinor, ctx, &innerOutputToken, - sm->outputTokenType, output_token); - if (GSS_ERROR(tmpMajor)) { - major = tmpMajor; - *minor = tmpMinor; - goto cleanup; - } - } if (ret_flags != NULL) *ret_flags = ctx->gssFlags; if (delegated_cred_handle != NULL) @@ -609,6 +628,17 @@ gss_accept_sec_context(OM_uint32 *minor, assert(ctx->state == EAP_STATE_ESTABLISHED || major == GSS_S_CONTINUE_NEEDED); +send_token: + if (innerOutputToken.value != NULL) { + tmpMajor = gssEapMakeToken(&tmpMinor, ctx, &innerOutputToken, + sm->outputTokenType, output_token); + if (GSS_ERROR(tmpMajor)) { + major = tmpMajor; + *minor = tmpMinor; + goto cleanup; + } + } + cleanup: if (cred != GSS_C_NO_CREDENTIAL) GSSEAP_MUTEX_UNLOCK(&cred->mutex); diff --git a/mech_eap/gssapiP_eap.h b/mech_eap/gssapiP_eap.h index de45508..d5e9da4 100644 --- a/mech_eap/gssapiP_eap.h +++ b/mech_eap/gssapiP_eap.h @@ -130,6 +130,7 @@ enum gss_eap_state { EAP_STATE_EXTENSIONS_REQ, EAP_STATE_EXTENSIONS_RESP, EAP_STATE_ESTABLISHED, + EAP_STATE_ERROR, #ifdef GSSEAP_ENABLE_REAUTH EAP_STATE_KRB_REAUTH_GSS #endif diff --git a/mech_eap/gsseap_err.et b/mech_eap/gsseap_err.et index 99f89f9..0e4a359 100644 --- a/mech_eap/gsseap_err.et +++ b/mech_eap/gsseap_err.et @@ -62,5 +62,6 @@ error_code GSSEAP_BAD_CONTEXT_TOKEN, "Context token is malformed or corru 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_PRF_KEY, "PRF key usage type is unknown" +error_code GSSEAP_BAD_ERROR_TOKEN, "Error token is malformed or corrupt" end diff --git a/mech_eap/init_sec_context.c b/mech_eap/init_sec_context.c index f7eda20..56f41de 100644 --- a/mech_eap/init_sec_context.c +++ b/mech_eap/init_sec_context.c @@ -562,6 +562,39 @@ eapGssSmInitEstablished(OM_uint32 *minor, return GSS_S_BAD_STATUS; } +static OM_uint32 +eapGssSmInitError(OM_uint32 *minor, + gss_cred_id_t cred, + gss_ctx_id_t ctx, + gss_name_t target, + gss_OID mech, + OM_uint32 reqFlags, + OM_uint32 timeReq, + gss_channel_bindings_t chanBindings, + gss_buffer_t inputToken, + gss_buffer_t outputToken) +{ + OM_uint32 major; + unsigned char *p; + + if (inputToken->length < 8) { + *minor = GSSEAP_WRONG_SIZE; + return GSS_S_DEFECTIVE_TOKEN; + } + + p = (unsigned char *)inputToken->value; + + major = load_uint32_be(&p[0]); + *minor = load_uint32_be(&p[4]); + + if (!GSS_ERROR(major)) { + *minor = GSSEAP_BAD_ERROR_TOKEN; + major = GSS_S_FAILURE; + } + + return major; +} + static struct gss_eap_initiator_sm { enum gss_eap_token_type inputTokenType; enum gss_eap_token_type outputTokenType; @@ -576,13 +609,14 @@ static struct gss_eap_initiator_sm { gss_buffer_t, gss_buffer_t); } eapGssInitiatorSm[] = { - { TOK_TYPE_NONE, TOK_TYPE_EAP_RESP, eapGssSmInitIdentity }, - { TOK_TYPE_EAP_REQ, TOK_TYPE_EAP_RESP, eapGssSmInitAuthenticate }, - { TOK_TYPE_NONE, TOK_TYPE_EXT_REQ, eapGssSmInitExtensionsReq }, - { TOK_TYPE_EXT_RESP,TOK_TYPE_NONE, eapGssSmInitExtensionsResp }, - { TOK_TYPE_NONE, TOK_TYPE_NONE, eapGssSmInitEstablished }, + { TOK_TYPE_NONE, TOK_TYPE_EAP_RESP, eapGssSmInitIdentity }, + { TOK_TYPE_EAP_REQ, TOK_TYPE_EAP_RESP, eapGssSmInitAuthenticate }, + { TOK_TYPE_NONE, TOK_TYPE_EXT_REQ, eapGssSmInitExtensionsReq }, + { TOK_TYPE_EXT_RESP, TOK_TYPE_NONE, eapGssSmInitExtensionsResp }, + { TOK_TYPE_NONE, TOK_TYPE_NONE, eapGssSmInitEstablished }, + { TOK_TYPE_CONTEXT_ERR, TOK_TYPE_NONE, eapGssSmInitError }, #ifdef GSSEAP_ENABLE_REAUTH - { TOK_TYPE_GSS_REAUTH, TOK_TYPE_GSS_REAUTH, eapGssSmInitGssReauth }, + { TOK_TYPE_GSS_REAUTH, TOK_TYPE_GSS_REAUTH, eapGssSmInitGssReauth }, #endif }; @@ -673,7 +707,9 @@ gss_init_sec_context(OM_uint32 *minor, if (GSS_ERROR(major)) goto cleanup; - if (tokType != sm->inputTokenType) { + if (tokType == TOK_TYPE_CONTEXT_ERR) { + ctx->state = EAP_STATE_ERROR; + } else if (tokType != sm->inputTokenType) { *minor = GSSEAP_WRONG_TOK_ID; major = GSS_S_DEFECTIVE_TOKEN; goto cleanup; diff --git a/mech_eap/util.h b/mech_eap/util.h index 3494aab..33d4482 100644 --- a/mech_eap/util.h +++ b/mech_eap/util.h @@ -84,13 +84,14 @@ enum gss_eap_token_type { TOK_TYPE_MIC = 0x0404, /* RFC 4121 MIC token */ TOK_TYPE_WRAP = 0x0504, /* RFC 4121 wrap token */ TOK_TYPE_EXPORT_NAME = 0x0401, /* RFC 2743 exported name */ - TOK_TYPE_EXPORT_NAME_COMPOSITE = 0x0402, /* draft-ietf-kitten-gss-naming */ + TOK_TYPE_EXPORT_NAME_COMPOSITE = 0x0402, /* exported composite name */ TOK_TYPE_DELETE_CONTEXT = 0x0405, /* RFC 2743 delete context */ - TOK_TYPE_EAP_RESP = 0x0601, /* draft-howlett-eap-gss */ - TOK_TYPE_EAP_REQ = 0x0602, /* draft-howlett-eap-gss */ - TOK_TYPE_EXT_REQ = 0x0603, /* draft-howlett-eap-gss */ - TOK_TYPE_EXT_RESP = 0x0604, /* to be specified */ - TOK_TYPE_GSS_REAUTH = 0x0605, /* to be specified */ + TOK_TYPE_EAP_RESP = 0x0601, /* EAP response */ + TOK_TYPE_EAP_REQ = 0x0602, /* EAP request */ + TOK_TYPE_EXT_REQ = 0x0603, /* GSS EAP extensions request */ + TOK_TYPE_EXT_RESP = 0x0604, /* GSS EAP extensions response */ + TOK_TYPE_GSS_REAUTH = 0x0605, /* GSS EAP fast reauthentication token */ + TOK_TYPE_CONTEXT_ERR = 0x0606, /* context error */ }; #define EAP_EXPORT_CONTEXT_V1 1 -- 2.1.4