[krbdev.mit.edu #8845] SPNEGO init/accept output parameter bugs

Greg Hudson via RT rt-comment at KRBDEV-PROD-APP-1.mit.edu
Tue Nov 5 13:47:37 EST 2019


Tue Nov 05 13:47:37 2019: Request 8845 was acted upon.
 Transaction: Ticket created by ghudson at mit.edu
       Queue: krb5
     Subject: SPNEGO init/accept output parameter bugs
       Owner: Nobody
  Requestors: ghudson at mit.edu
      Status: open
 Ticket <URL: https://krbdev.mit.edu/rt/Ticket/Display.html?id=8845 >


gss_init_sec_context() and gss_accept_sec_context() both output a token and
either create or modify a security context. There are some additional outputs:
actual_mech_type, ret_flags, and time_rec for gss_init_sec_context(), and
src_name, mech_type, ret_flags, time_rec, and delegated_cred_handle for
gss_accept_sec_context(). RFC 2744 sections 5.1 and 5.19 define some rules for
how these parameters should be set when GSS_S_CONTINUE_NEEDED is returned.

Although the mechglue initializes most output parameters, it does not do so for
ret_flags and time_rec. This is a separate bug, which impacts the following
SPNEGO misbehaviors; if SPNEGO does not set these output parameters, the
caller's value will remain unchanged.

The current SPNEGO implementation has the following bugs related to the
additional output parameters:

* gss_init_sec_context() only sets ret_flags if the underlying mech is called
and returns GSS_S_COMPLETE, or if SPNEGO itself will return GSS_S_COMPLETE.
gss_accept_sec_context() initializes ret_flags to 0, and only sets ret_flags to
another value if the underlying mech is called and returns GSS_S_COMPLETE;
ret_flags could remain as 0 on SPNEGO's final return from
gss_accept_sec_context(), if the MIC exchange forces an extra round trip.

* gss_init_sec_context() and gss_accept_sec_context() do not filter out
PROT_READY from ret_flags as required by RFC 4178.

* gss_init_sec_context() and gss_accept_sec_context() pass time_rec directly to
the underlying mech. gss_accept_sec_context() initializes time_rec to 0 but
gss_init_sec_context() does not. Neither function will set time_rec to a
meaningful value if the underlying mech is not called on the final SPNEGO call
due to the MIC exchange. Note that time_rec is relative to the current time; if
SPNEGO records time_rec from the underlying mech at one step and reports it to
the caller at a later step, the time differential between steps could render
that value inaccurate. SPNEGO could either adjust the value by the
differential, or call gss_context_time() on the underlying context.

* gss_accept_sec_context() initializes mech_type to GSS_C_NO_OID and passes it
directly to the underlying mech. If the underlying mech is not called on the
final step, mech_type will remain as GSS_C_NO_OID.

* gss_accept_sec_context() initializes delegated_cred_handle to
GSS_C_NO_CREDENTIAL and passes it directly to the underlying mech. SPNEGO could
report a delegated cred to the caller too early (before the MIC exchange) and
not on the final call.

* gss_accept_sec_context() could leak a value of src_name (recorded as
sc->internal_name) if the underlying mech reports it twice. RFC 2744 doesn't
explicitly prohibit this, although it seems like it should be unusual.




More information about the krb5-bugs mailing list