outputToken, NULL);
if (GSS_ERROR(major))
return major;
- } else if (inputToken != GSS_C_NO_BUFFER &&
- ctx->acceptorName == GSS_C_NO_NAME) {
- /* Accept target name hint from acceptor */
+ } else if (inputToken != GSS_C_NO_BUFFER) {
+ OM_uint32 tmpMinor;
+ gss_name_t nameHint;
+ int equal;
+
+ /* Accept target name hint from acceptor or verify acceptor */
major = gssEapImportName(minor, inputToken,
GSS_C_NT_USER_NAME,
ctx->mechanismUsed,
- &ctx->acceptorName);
+ &nameHint);
if (GSS_ERROR(major))
return major;
+
+ if (ctx->acceptorName != GSS_C_NO_NAME) {
+ /* verify name hint matched asserted acceptor name */
+ major = gssEapCompareName(minor,
+ nameHint,
+ ctx->acceptorName,
+ COMPARE_NAME_FLAG_IGNORE_EMPTY_REALMS,
+ &equal);
+ if (GSS_ERROR(major)) {
+ gssEapReleaseName(&tmpMinor, &nameHint);
+ return major;
+ }
+
+ gssEapReleaseName(&tmpMinor, &nameHint);
+
+ if (!equal) {
+ *minor = GSSEAP_WRONG_ACCEPTOR_NAME;
+ return GSS_S_DEFECTIVE_TOKEN;
+ }
+ } else { /* acceptor name is no_name */
+ /* accept acceptor name hint */
+ ctx->acceptorName = nameHint;
+ nameHint = GSS_C_NO_NAME;
+ }
}
+
/*
* Currently, other parts of the code assume that the acceptor name
* is available, hence this check.
OM_uint32 *smFlags)
{
OM_uint32 major;
- gss_buffer_desc buffer = GSS_C_EMPTY_BUFFER;
+ krb5_error_code code;
+ krb5_context krbContext;
+ krb5_data data;
+ krb5_checksum cksum;
+ gss_buffer_desc cksumBuffer;
- if (chanBindings != GSS_C_NO_CHANNEL_BINDINGS)
- buffer = chanBindings->application_data;
+ if (chanBindings == GSS_C_NO_CHANNEL_BINDINGS ||
+ chanBindings->application_data.length == 0)
+ return GSS_S_CONTINUE_NEEDED;
- major = gssEapWrap(minor, ctx, TRUE, GSS_C_QOP_DEFAULT,
- &buffer, NULL, outputToken);
- if (GSS_ERROR(major))
- return major;
+ GSSEAP_KRB_INIT(&krbContext);
+
+ KRB_DATA_INIT(&data);
+
+ gssBufferToKrbData(&chanBindings->application_data, &data);
- GSSEAP_ASSERT(outputToken->value != NULL);
+ code = krb5_c_make_checksum(krbContext, ctx->checksumType,
+ &ctx->rfc3961Key,
+ KEY_USAGE_GSSEAP_CHBIND_MIC,
+ &data, &cksum);
+ if (code != 0) {
+ *minor = code;
+ return GSS_S_FAILURE;
+ }
+
+ cksumBuffer.length = KRB_CHECKSUM_LENGTH(&cksum);
+ cksumBuffer.value = KRB_CHECKSUM_DATA(&cksum);
+
+ major = duplicateBuffer(minor, &cksumBuffer, outputToken);
+ if (GSS_ERROR(major)) {
+ krb5_free_checksum_contents(krbContext, &cksum);
+ return major;
+ }
*minor = 0;
*smFlags |= SM_FLAG_OUTPUT_TOKEN_CRITICAL;
+ krb5_free_checksum_contents(krbContext, &cksum);
+
return GSS_S_CONTINUE_NEEDED;
}
return GSS_S_CONTINUE_NEEDED;
}
-
+
#ifdef GSSEAP_ENABLE_REAUTH
static OM_uint32
eapGssSmInitReauthCreds(OM_uint32 *minor,
{
ITOK_TYPE_ACCEPTOR_NAME_RESP,
ITOK_TYPE_ACCEPTOR_NAME_REQ,
- GSSEAP_STATE_INITIAL | GSSEAP_STATE_AUTHENTICATE,
+ GSSEAP_STATE_INITIAL | GSSEAP_STATE_AUTHENTICATE |
+ GSSEAP_STATE_ACCEPTOR_EXTS,
0,
eapGssSmInitAcceptorName
},
ITOK_TYPE_NONE,
ITOK_TYPE_GSS_CHANNEL_BINDINGS,
GSSEAP_STATE_INITIATOR_EXTS,
- SM_ITOK_FLAG_REQUIRED,
+ 0,
eapGssSmInitGssChannelBindings
},
{