summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-02-22 04:52:30 +0000
committerGreg Hudson <ghudson@mit.edu>2010-02-22 04:52:30 +0000
commitd1da896d356bc80e632a9713e5b4246384fb3e77 (patch)
treee470cdf6093e57a906a00eec9a093e07d5e92373 /src
parentfc3f2e78462b01338055cadc1e224e29d4ed4e9a (diff)
downloadkrb5-d1da896d356bc80e632a9713e5b4246384fb3e77.tar.gz
krb5-d1da896d356bc80e632a9713e5b4246384fb3e77.tar.xz
krb5-d1da896d356bc80e632a9713e5b4246384fb3e77.zip
Fix two unrelated problems in SPNEGO which don't crop up with the krb5
mechanism. 1. The third call to spnego_init_accept_context uses faulty logic to determine if the exchange is complete, preventing a third mech token from being sent to the acceptor if no MIC exchange is required. Follow the logic used in the second call (in init_ctx_nego), which is correct. 2. If the acceptor selects a mech other than the optimistic mech, it sets sc->mic_reqd to 1 whether or not the selected mech supports MICs (which isn't known until the mech completes). Most code outside of handle_mic checks sc->mic_reqd along with (sc->ctx_flags & GSS_C_INTEG_FLAG), but the code in acc_ctx_call_acc neglected to do so, so it could improperly delegate responsibility for deciding when the negotiation was finished to handle_mic--which never gets called if (sc->ctx_flags & GSS_C_INTEG_FLAG) is false. Fix acc_ctx_call_acc to check sc->ctx_flags so that mechs which don't support integrity protection can complete if they are selected non-optimistically. ticket: 6603 target_version: 1.8 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23742 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/lib/gssapi/spnego/spnego_mech.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 100e129cf9..daabf63572 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -448,8 +448,9 @@ create_spnego_ctx(void)
}
/*
- * Both initiator and acceptor call here to verify and/or create
- * mechListMIC, and to consistency-check the MIC state.
+ * Both initiator and acceptor call here to verify and/or create mechListMIC,
+ * and to consistency-check the MIC state. handle_mic is invoked only if the
+ * negotiated mech has completed and supports MICs.
*/
static OM_uint32
handle_mic(OM_uint32 *minor_status, gss_buffer_t mic_in,
@@ -658,18 +659,20 @@ init_ctx_cont(OM_uint32 *minor_status, gss_ctx_id_t *ctx, gss_buffer_t buf,
supportedMech, responseToken,
mechListMIC,
negState, tokflag);
- } else if (!sc->mech_complete &&
- *responseToken == GSS_C_NO_BUFFER) {
- /*
- * mech not finished and mech token missing
- */
+ } else if ((!sc->mech_complete && *responseToken == GSS_C_NO_BUFFER) ||
+ (sc->mech_complete && *responseToken != GSS_C_NO_BUFFER)) {
+ /* Missing or spurious token from acceptor. */
ret = GSS_S_DEFECTIVE_TOKEN;
- } else if (sc->mic_reqd &&
- (sc->ctx_flags & GSS_C_INTEG_FLAG)) {
+ } else if (!sc->mech_complete ||
+ (sc->mic_reqd &&
+ (sc->ctx_flags & GSS_C_INTEG_FLAG))) {
+ /* Not obviously done; we may decide we're done later in
+ * init_ctx_call_init or handle_mic. */
*negState = ACCEPT_INCOMPLETE;
*tokflag = CONT_TOKEN_SEND;
ret = GSS_S_CONTINUE_NEEDED;
} else {
+ /* mech finished on last pass and no MIC required, so done. */
*negState = ACCEPT_COMPLETE;
*tokflag = NO_TOKEN_SEND;
ret = GSS_S_COMPLETE;
@@ -1529,10 +1532,13 @@ acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
if (ret_flags != NULL)
*ret_flags = sc->ctx_flags;
- if (!sc->mic_reqd) {
+ if (!sc->mic_reqd ||
+ !(sc->ctx_flags & GSS_C_INTEG_FLAG)) {
+ /* No MIC exchange required, so we're done. */
*negState = ACCEPT_COMPLETE;
ret = GSS_S_COMPLETE;
} else {
+ /* handle_mic will decide if we're done. */
ret = GSS_S_CONTINUE_NEEDED;
}
} else if (ret != GSS_S_CONTINUE_NEEDED) {