X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=import_sec_context.c;h=1e05f93edea2cc9676285a5e54980373f155ca5d;hb=15c93f06ee6ddefa7e7b095351f6e66698c7cc9e;hp=751ed54fc5abd167f3980dde429b7b24a4b0e6a1;hpb=965a423f231aef69ce965232d6d7e8be0975ad05;p=mech_eap.git diff --git a/import_sec_context.c b/import_sec_context.c index 751ed54..1e05f93 100644 --- a/import_sec_context.c +++ b/import_sec_context.c @@ -32,29 +32,69 @@ #include "gssapiP_eap.h" +#define UPDATE_REMAIN(n) do { \ + p += (n); \ + remain -= (n); \ + } while (0) + +#define CHECK_REMAIN(n) do { \ + if (remain < (n)) { \ + *minor = GSSEAP_WRONG_SIZE; \ + return GSS_S_DEFECTIVE_TOKEN; \ + } \ + } while (0) + static OM_uint32 gssEapImportPartialContext(OM_uint32 *minor, unsigned char **pBuf, size_t *pRemain, gss_ctx_id_t ctx) { + OM_uint32 major; unsigned char *p = *pBuf; size_t remain = *pRemain; gss_buffer_desc buf; + size_t serverLen; - if (remain < 4) { - *minor = ERANGE; - return GSS_S_DEFECTIVE_TOKEN; + /* Selected RADIUS server */ + CHECK_REMAIN(4); + serverLen = load_uint32_be(p); + UPDATE_REMAIN(4); + + if (serverLen != 0) { + CHECK_REMAIN(serverLen); + + ctx->acceptorCtx.radServer = GSSEAP_MALLOC(serverLen + 1); + if (ctx->acceptorCtx.radServer == NULL) { + *minor = ENOMEM; + return GSS_S_FAILURE; + } + memcpy(ctx->acceptorCtx.radServer, p, serverLen); + ctx->acceptorCtx.radServer[serverLen] = '\0'; + + UPDATE_REMAIN(serverLen); } + /* RADIUS state blob */ + CHECK_REMAIN(4); buf.length = load_uint32_be(p); + UPDATE_REMAIN(4); if (buf.length != 0) { - *minor = EINVAL; - return GSS_S_DEFECTIVE_TOKEN; + CHECK_REMAIN(buf.length); + + buf.value = p; + + major = duplicateBuffer(minor, &buf, &ctx->acceptorCtx.state); + if (GSS_ERROR(major)) + return major; + + UPDATE_REMAIN(buf.length); } - *minor = 0; + *pBuf = p; + *pRemain = remain; + return GSS_S_COMPLETE; } @@ -71,13 +111,14 @@ importMechanismOid(OM_uint32 *minor, oidBuf.length = load_uint32_be(p); if (remain < 4 + oidBuf.length || oidBuf.length == 0) { - *minor = ERANGE; + *minor = GSSEAP_WRONG_SIZE; return GSS_S_DEFECTIVE_TOKEN; } oidBuf.elements = &p[4]; if (!gssEapIsConcreteMechanismOid(&oidBuf)) { + *minor = GSSEAP_WRONG_MECH; return GSS_S_BAD_MECH; } @@ -109,7 +150,7 @@ importKerberosKey(OM_uint32 *minor, gss_buffer_desc tmp; if (remain < 12) { - *minor = ERANGE; + *minor = GSSEAP_WRONG_SIZE; return GSS_S_DEFECTIVE_TOKEN; } @@ -118,12 +159,12 @@ importKerberosKey(OM_uint32 *minor, length = load_uint32_be(&p[8]); if ((length != 0) != (encryptionType != ENCTYPE_NULL)) { - *minor = ERANGE; + *minor = GSSEAP_BAD_CONTEXT_TOKEN; return GSS_S_DEFECTIVE_TOKEN; } if (remain - 12 < length) { - *minor = ERANGE; + *minor = GSSEAP_WRONG_SIZE; return GSS_S_DEFECTIVE_TOKEN; } @@ -156,14 +197,14 @@ importName(OM_uint32 *minor, gss_buffer_desc tmp; if (remain < 4) { - *minor = ERANGE; + *minor = GSSEAP_WRONG_SIZE; return GSS_S_DEFECTIVE_TOKEN; } tmp.length = load_uint32_be(p); if (tmp.length != 0) { if (remain - 4 < tmp.length) { - *minor = ERANGE; + *minor = GSSEAP_WRONG_SIZE; return GSS_S_DEFECTIVE_TOKEN; } @@ -192,11 +233,11 @@ gssEapImportContext(OM_uint32 *minor, size_t remain = token->length; if (remain < 16) { - *minor = ERANGE; + *minor = GSSEAP_WRONG_SIZE; return GSS_S_DEFECTIVE_TOKEN; } if (load_uint32_be(&p[0]) != EAP_EXPORT_CONTEXT_V1) { - *minor = EINVAL; + *minor = GSSEAP_BAD_CONTEXT_TOKEN; return GSS_S_DEFECTIVE_TOKEN; } ctx->state = load_uint32_be(&p[4]); @@ -241,7 +282,7 @@ gssEapImportContext(OM_uint32 *minor, } if (remain < 24 + sequenceSize(ctx->seqState)) { - *minor = ERANGE; + *minor = GSSEAP_WRONG_SIZE; return GSS_S_DEFECTIVE_TOKEN; } ctx->expiryTime = (time_t)load_uint64_be(&p[0]); /* XXX */ @@ -259,6 +300,8 @@ gssEapImportContext(OM_uint32 *minor, * acceptor contexts. */ if (!CTX_IS_INITIATOR(ctx) && !CTX_IS_ESTABLISHED(ctx)) { + assert((ctx->flags & CTX_FLAG_KRB_REAUTH_GSS) == 0); + major = gssEapImportPartialContext(minor, &p, &remain, ctx); if (GSS_ERROR(major)) return major; @@ -282,6 +325,7 @@ gss_import_sec_context(OM_uint32 *minor, OM_uint32 major, tmpMinor; gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; + *minor = 0; *context_handle = GSS_C_NO_CONTEXT; if (interprocess_token == GSS_C_NO_BUFFER ||