Content-Transfer-Encoding: binary To: rt@krbdev.mit.edu Subject: SPNEGO init/accept output parameter bugs X-RT-Interface: Web Date: Tue, 05 Nov 2019 13:47:37 -0500 Message-ID: Content-Disposition: inline X-Mailer: MIME-tools 5.507 (Entity 5.507) MIME-Version: 1.0 Content-Type: text/html; charset="utf-8" From: ghudson@mit.edu X-RT-Original-Encoding: utf-8 Content-Length: 2935 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.