From: Luke Howard Date: Sat, 1 Jan 2011 11:05:34 +0000 (+1100) Subject: More Heimdal reauth portability X-Git-Tag: vm/20110310~77 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=mech_eap.orig;a=commitdiff_plain;h=4db629dfb3dcd4ef95590ac2631e6917eb5c9400 More Heimdal reauth portability --- diff --git a/accept_sec_context.c b/accept_sec_context.c index d7a4708..bdf86ea 100644 --- a/accept_sec_context.c +++ b/accept_sec_context.c @@ -716,7 +716,7 @@ acceptReadyKrb(OM_uint32 *minor, { OM_uint32 major; - major = gssEapGlueToMechName(minor, initiator, &ctx->initiatorName); + major = gssEapGlueToMechName(minor, ctx, initiator, &ctx->initiatorName); if (GSS_ERROR(major)) return major; diff --git a/gssapiP_eap.h b/gssapiP_eap.h index b53e131..eed57a1 100644 --- a/gssapiP_eap.h +++ b/gssapiP_eap.h @@ -35,6 +35,10 @@ #include "config.h" +#ifdef HAVE_HEIMDAL_VERSION +#define KRB5_DEPRECATED /* so we can use krb5_free_unparsed_name() */ +#endif + #include #include #include diff --git a/util.h b/util.h index 826a335..cc9bb68 100644 --- a/util.h +++ b/util.h @@ -406,6 +406,12 @@ krbMakeAuthDataKdcIssued(krb5_context context, #endif ); +krb5_error_code +krbMakeCred(krb5_context context, + krb5_auth_context authcontext, + krb5_creds *creds, + krb5_data *data); + /* util_lucid.c */ OM_uint32 gssEapExportLucidSecContext(OM_uint32 *minor, diff --git a/util_krb.c b/util_krb.c index 9ee0ae5..d753fe2 100644 --- a/util_krb.c +++ b/util_krb.c @@ -485,3 +485,101 @@ cleanup: adKdcIssued); #endif /* HAVE_HEIMDAL_VERSION */ } + +krb5_error_code +krbMakeCred(krb5_context krbContext, + krb5_auth_context authContext, + krb5_creds *creds, + krb5_data *data) +{ + krb5_error_code code; +#ifdef HAVE_HEIMDAL_VERSION + KRB_CRED krbCred; + KrbCredInfo krbCredInfo; + krb5_keyblock *key; + krb5_crypto krbCrypto = NULL; + unsigned char *buf = NULL; + size_t buf_size, len; +#else + krb5_data **d; +#endif + + memset(data, 0, sizeof(*data)); + memset(&krbCred, 0, sizeof(krbCred)); + memset(&krbCredInfo, 0, sizeof(krbCredInfo)); + + key = (authContext->local_subkey != NULL) + ? authContext->local_subkey + : authContext->keyblock; + +#ifdef HAVE_HEIMDAL_VERSION + krbCred.pvno = 5; + krbCred.msg_type = krb_cred; + krbCred.tickets.val = (Ticket *)GSSEAP_CALLOC(1, sizeof(Ticket)); + if (krbCred.tickets.val == NULL) { + code = ENOMEM; + goto cleanup; + } + krbCred.tickets.len = 1; + + code = decode_Ticket(creds->ticket.data, + creds->ticket.length, + krbCred.tickets.val, &len); + if (code != 0) + goto cleanup; + + krbCredInfo.key = creds->session; + krbCredInfo.prealm = &creds->client->realm; + krbCredInfo.pname = &creds->client->name; + krbCredInfo.flags = &creds->flags.b; + krbCredInfo.authtime = &creds->times.authtime; + krbCredInfo.starttime = &creds->times.starttime; + krbCredInfo.endtime = &creds->times.endtime; + krbCredInfo.renew_till = &creds->times.renew_till; + krbCredInfo.srealm = &creds->server->realm; + krbCredInfo.sname = &creds->server->name; + krbCredInfo.caddr = creds->addresses.len ? &creds->addresses : NULL; + + ASN1_MALLOC_ENCODE(KrbCredInfo, buf, buf_size, &krbCredInfo, &len, code); + if (code != 0) + goto cleanup; + + code = krb5_crypto_init(krbContext, key, 0, &krbCrypto); + if (code != 0) + goto cleanup; + + code = krb5_encrypt_EncryptedData(krbContext, + krbCrypto, + KRB5_KU_KRB_CRED, + buf, + len, + 0, + &krbCred.enc_part); + if (code != 0) + goto cleanup; + + GSSEAP_FREE(buf); + buf = NULL; + + ASN1_MALLOC_ENCODE(KRB_CRED, buf, buf_size, &krbCred, &len, code); + if (code != 0) + goto cleanup; + +cleanup: + if (buf != NULL) + GSSEAP_FREE(buf); + if (krbCrypto != NULL) + krb5_crypto_destroy(krbContext, krbCrypto); + free_KRB_CRED(&krbCred); + + return code; +#else + code = krb5_mk_1cred(krbContext, authContext, creds, &d); + if (code == 0) { + *data = **d; + GSSEAP_FREE(d); + } + + return code; +#endif /* HAVE_HEIMDAL_VERSION */ +} diff --git a/util_reauth.c b/util_reauth.c index 0a8373d..3790016 100644 --- a/util_reauth.c +++ b/util_reauth.c @@ -219,7 +219,7 @@ gssEapMakeReauthCreds(OM_uint32 *minor, krb5_ticket ticket; krb5_enc_tkt_part enc_part; #endif - krb5_data *ticketData = NULL, *credsData = NULL; + krb5_data *ticketData = NULL, credsData = { 0 }; krb5_creds creds = { 0 }; krb5_auth_context authContext = NULL; @@ -354,11 +354,11 @@ gssEapMakeReauthCreds(OM_uint32 *minor, if (code != 0) goto cleanup; - code = krb5_mk_1cred(krbContext, authContext, &creds, &credsData, NULL); + code = krbMakeCred(krbContext, authContext, &creds, &credsData); if (code != 0) goto cleanup; - krbDataToGssBuffer(credsData, credBuf); + krbDataToGssBuffer(&credsData, credBuf); cleanup: #ifdef HAVE_HEIMDAL_VERSION @@ -378,8 +378,6 @@ cleanup: krb5_free_keyblock_contents(krbContext, &acceptorKey); krb5_free_data(krbContext, ticketData); krb5_auth_con_free(krbContext, authContext); - if (credsData != NULL) - GSSEAP_FREE(credsData); if (major == GSS_S_COMPLETE) { *minor = code; @@ -643,9 +641,11 @@ cleanup: return major; } +#ifndef HAVE_HEIMDAL_VERSION static gss_buffer_desc radiusAvpKrbAttr = { sizeof("urn:authdata-radius-avp") - 1, "urn:authdata-radius-avp" }; +#endif /* * Unfortunately extracting an AD-KDCIssued authorization data element @@ -665,15 +665,46 @@ static gss_buffer_desc radiusAvpKrbAttr = { */ static OM_uint32 defrostAttrContext(OM_uint32 *minor, + gss_ctx_id_t glueContext, gss_name_t glueName, gss_name_t mechName) { OM_uint32 major, tmpMinor; +#ifdef HAVE_HEIMDAL_VERSION + gss_OID_desc oid = { 0 }; + gss_buffer_set_t authData = GSS_C_NO_BUFFER_SET; +#else gss_buffer_desc authData = GSS_C_EMPTY_BUFFER; gss_buffer_desc authDataDisplay = GSS_C_EMPTY_BUFFER; int more = -1; int authenticated, complete; +#endif + +#ifdef HAVE_HEIMDAL_VERSION + major = composeOid(minor, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->elements, + GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_X->length, + KRB5_AUTHDATA_RADIUS_AVP, &oid); + if (GSS_ERROR(major)) + return major; + /* XXX we are assuming that this verifies AD-KDCIssued signature */ + major = gssInquireSecContextByOid(minor, glueContext, + &oid, &authData); + if (major == GSS_S_COMPLETE) { + if (authData == GSS_C_NO_BUFFER_SET || authData->count != 1) + major = GSS_S_FAILURE; + else + major = gssEapImportAttrContext(minor, authData->elements, mechName); + } else if (major == GSS_S_FAILURE && *minor == ENOENT) { + /* This is the equivalent of GSS_S_UNAVAILABLE for MIT attr APIs */ + *minor = 0; + major = GSS_S_COMPLETE; + } + + gss_release_buffer_set(&tmpMinor, &authData); + GSSEAP_FREE(oid.elements); +#else major = gssGetNameAttribute(minor, glueName, &radiusAvpKrbAttr, &authenticated, &complete, &authData, &authDataDisplay, &more); @@ -688,6 +719,7 @@ defrostAttrContext(OM_uint32 *minor, gss_release_buffer(&tmpMinor, &authData); gss_release_buffer(&tmpMinor, &authDataDisplay); +#endif /* HAVE_HEIMDAL_VERSION */ return major; } @@ -698,6 +730,7 @@ defrostAttrContext(OM_uint32 *minor, */ OM_uint32 gssEapGlueToMechName(OM_uint32 *minor, + gss_ctx_id_t glueContext, gss_name_t glueName, gss_name_t *pMechName) { @@ -715,7 +748,7 @@ gssEapGlueToMechName(OM_uint32 *minor, if (GSS_ERROR(major)) goto cleanup; - major = defrostAttrContext(minor, glueName, *pMechName); + major = defrostAttrContext(minor, glueContext, glueName, *pMechName); if (GSS_ERROR(major)) goto cleanup; diff --git a/util_reauth.h b/util_reauth.h index 96287d2..29f2f2e 100644 --- a/util_reauth.h +++ b/util_reauth.h @@ -124,6 +124,7 @@ gssEapStoreReauthCreds(OM_uint32 *minor, OM_uint32 gssEapGlueToMechName(OM_uint32 *minor, + gss_ctx_id_t glueContext, gss_name_t glueName, gss_name_t *pMechName);