our SPNEGO direction

Sam Hartman hartmans at MIT.EDU
Thu Nov 7 19:14:01 EST 2002

Here are some implementation notes I've written up on where we're
going with SPNEGO.  So far, the basic design has been reviewed by Tom
Yu and myself.  I evaluated the umich mechglue patch in hopes of
actually writing a multi-mechanism spnego implementation.  However I
don't think the code is ready to be integrated and the author of the
patch indicated he wanted to rethink it, so we're not going that

		 Implementation Notes for MIT Spnego

Currently the SPNEGO mechanism is closely associated with the krb5
mechanism.  By default if no OID is passed into the desired_mech
parameter of gss_init_sec_context then the krb5 mechanism is used.  If
the SPNEGO OID is passed in the SPNEGO is used.  By default
gss_accept_sec_context allows either mechanism but if an explicit OID
is passed in then that OID must be used.

Since both SPNEGO with a krb5 mech and krb5 use the same credentials,
you cannot control which mechanism is used at the credential level.

The SPNEGO code is split into four driver functions:

* gssint_spnego_init_before
* gssint_spnego_init_after
* gssint_spnego_accept_before
* gssint_spnego_accept_after

The _before functions  will unwrap   and decode a SPNEGO token
returning any mechanism token within the  spnego token.  

The calling sequence and control flow characteristics of the _before
functions is similar to that of gss_init_sec_context and
gss_accept_sec_context .  They can output both a mechanism token and a
response token, although at most one of these outputs will be
used. The functions can return  in the following manners:

* GSS_S_COMPLETE with no output tokens: caller should return
  GSS_S_COMPLETE and context is set up.  If mechanism level routines
  have not yet returned GSS_S_COMPLETE, then caller should treat this
  as an error.

* GSS_S_CONTINUE_NEEDED with a response token:  Caller should return
  GSS_S_CONTINUE_NEEDED with the response token provided and not
  update the context state.  This happens for example if
  gssint_spnego_init_before notes that the target does not
  support optimistic negotiation and the mechanism token must be

* GSS_S_CONTINUE_NEEDED with a mechanism token: caller should process
  mechanism token .

* An error, possibly with a response token: Caller should return error
and response token.

Note that neither of the before functions deals with the peer
selecting a non-default mechanism at all.  That's just not currently

The _after functions have significantly less complex control flow.
They will return one of:

* GSS_S_COMPLETE   possibly with a response token--no additional calls

* GSS_S_CONTINUE_NEEDED with a response token

* Some error possibly with a response token

Note that even if the inputs to gssint_spnego_*_after indicate that
GSS_S_COMPLETE will be returned, the *_after may decide that
GSS_S_CONTINUE_NEEDED should be returned.  This means that another
SPNEGO token is expected even though no mechanism tokens are expected.
In this case, the next call to the appropriate _before function should
be expected to return GSS_S_COMPLETE.

		     Expanding to multi-mechanism

Here are changes that may need to be rolled back to expand to a
multi-mechanism usage.

* Calls to spnego functions have been integrated into
  krb5_gss_init_sec_context and krb5_gss_accept_sec_context.

* Credential management functions  know about the SPNEGO mechanism

In addition, support in the _before functions to deal with changing
mechanism types is needed.  In particular
gssint_spnego_init_before needs to delete the existing
mechanism context if the target chooses a mechanism different than the
optimal one.

More information about the krbdev mailing list