From 1e8deb6f55be391b9859fda702335c5f6ad57541 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Mon, 22 Feb 2010 16:10:05 +0000 Subject: [PATCH] Explain the current SPNEGO initiator/acceptor design in comments. No code changes. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23743 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/gssapi/spnego/spnego_mech.c | 77 ++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index daabf6357..f7fcb5e55 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -29,7 +29,7 @@ * * A module that implements the spnego security mechanism. * It is used to negotiate the security mechanism between - * peers using the GSS-API. + * peers using the GSS-API. SPNEGO is specified in RFC 4178. * */ /* @@ -336,6 +336,8 @@ spnego_gss_acquire_cred(OM_uint32 *minor_status, if (time_rec) *time_rec = 0; + /* We will obtain a mechglue credential and wrap it in a + * spnego_gss_cred_id_rec structure. Allocate the wrapper. */ spcred = malloc(sizeof(spnego_gss_cred_id_rec)); if (spcred == NULL) { *minor_status = ENOMEM; @@ -892,14 +894,6 @@ spnego_gss_init_sec_context( OM_uint32 *ret_flags, OM_uint32 *time_rec) { - /* - * send_token is used to indicate in later steps - * what type of token, if any should be sent or processed. - * NO_TOKEN_SEND = no token should be sent - * INIT_TOKEN_SEND = initial token will be sent - * CONT_TOKEN_SEND = continuing tokens to be sent - * CHECK_MIC = no token to be sent, but have a MIC to check. - */ send_token_flag send_token = NO_TOKEN_SEND; OM_uint32 tmpmin, ret, negState; gss_buffer_t mechtok_in, mechListMIC_in, mechListMIC_out; @@ -913,6 +907,29 @@ spnego_gss_init_sec_context( mechtok_in = mechListMIC_out = mechListMIC_in = GSS_C_NO_BUFFER; negState = REJECT; + /* + * This function works in three steps: + * + * 1. Perform mechanism negotiation. + * 2. Invoke the negotiated or optimistic mech's gss_init_sec_context + * function and examine the results. + * 3. Process or generate MICs if necessary. + * + * The three steps share responsibility for determining when the + * exchange is complete. If the selected mech completed in a previous + * call and no MIC exchange is expected, then step 1 will decide. If + * the selected mech completes in this call and no MIC exchange is + * expected, then step 2 will decide. If a MIC exchange is expected, + * then step 3 will decide. If an error occurs in any step, the + * exchange will be aborted, possibly with an error token. + * + * negState determines the state of the negotiation, and is + * communicated to the acceptor if a continuing token is sent. + * send_token is used to indicate what type of token, if any, should be + * generated. + */ + + /* Validate arguments. */ if (minor_status != NULL) *minor_status = 0; if (output_token != GSS_C_NO_BUFFER) { @@ -927,6 +944,7 @@ spnego_gss_init_sec_context( if (actual_mech != NULL) *actual_mech = GSS_C_NO_OID; + /* Step 1: perform mechanism negotiation. */ spcred = (spnego_gss_cred_id_t)claimant_cred_handle; if (*context_handle == GSS_C_NO_CONTEXT) { ret = init_ctx_new(minor_status, spcred, @@ -942,6 +960,9 @@ spnego_gss_init_sec_context( goto cleanup; } } + + /* Step 2: invoke the selected or optimistic mechanism's + * gss_init_sec_context function, if it didn't complete previously. */ spnego_ctx = (spnego_gss_ctx_id_t)*context_handle; if (!spnego_ctx->mech_complete) { ret = init_ctx_call_init( @@ -952,7 +973,9 @@ spnego_gss_init_sec_context( ret_flags, time_rec, &negState, &send_token); } - /* create mic/check mic */ + + /* Step 3: process or generate the MIC, if the negotiated mech is + * complete and supports MICs. */ if (!HARD_ERROR(ret) && spnego_ctx->mech_complete && (spnego_ctx->ctx_flags & GSS_C_INTEG_FLAG)) { @@ -1574,6 +1597,29 @@ spnego_gss_accept_sec_context( mechtok_in = mic_in = mic_out = GSS_C_NO_BUFFER; + /* + * This function works in three steps: + * + * 1. Perform mechanism negotiation. + * 2. Invoke the negotiated mech's gss_accept_sec_context function + * and examine the results. + * 3. Process or generate MICs if necessary. + * + * Step one determines whether the negotiation requires a MIC exchange, + * while steps two and three share responsibility for determining when + * the exchange is complete. If the selected mech completes in this + * call and no MIC exchange is expected, then step 2 will decide. If a + * MIC exchange is expected, then step 3 will decide. If an error + * occurs in any step, the exchange will be aborted, possibly with an + * error token. + * + * negState determines the state of the negotiation, and is + * communicated to the acceptor if a continuing token is sent. + * return_token is used to indicate what type of token, if any, should + * be generated. + */ + + /* Validate arguments. */ if (minor_status != NULL) *minor_status = 0; if (output_token != GSS_C_NO_BUFFER) { @@ -1589,9 +1635,11 @@ spnego_gss_accept_sec_context( if (input_token == GSS_C_NO_BUFFER) return GSS_S_CALL_INACCESSIBLE_READ; + /* Step 1: Perform mechanism negotiation. */ sc = (spnego_gss_ctx_id_t)*context_handle; spcred = (spnego_gss_cred_id_t)verifier_cred_handle; if (sc == NULL || sc->internal_mech == GSS_C_NO_OID) { + /* Process an initial token or request for NegHints. */ if (src_name != NULL) *src_name = GSS_C_NO_NAME; if (mech_type != NULL) @@ -1623,7 +1671,8 @@ spnego_gss_accept_sec_context( ret = GSS_S_CONTINUE_NEEDED; } } else { - /* Can set negState to ACCEPT_INCOMPLETE */ + /* Process a response token. Can set negState to + * ACCEPT_INCOMPLETE. */ ret = acc_ctx_cont(minor_status, input_token, context_handle, &mechtok_in, &mic_in, &negState, &return_token); @@ -1631,6 +1680,9 @@ spnego_gss_accept_sec_context( goto cleanup; ret = GSS_S_CONTINUE_NEEDED; } + + /* Step 2: invoke the negotiated mechanism's gss_accept_sec_context + * function. */ sc = (spnego_gss_ctx_id_t)*context_handle; /* * Handle mechtok_in and mic_in only if they are @@ -1649,6 +1701,9 @@ spnego_gss_accept_sec_context( } else if (negState == REQUEST_MIC) { mechstat = GSS_S_CONTINUE_NEEDED; } + + /* Step 3: process or generate the MIC, if the negotiated mech is + * complete and supports MICs. */ if (!HARD_ERROR(ret) && sc->mech_complete && (sc->ctx_flags & GSS_C_INTEG_FLAG)) { -- 2.26.2