[krbdev.mit.edu #6604] issues with gss_inquire_context and gss_display_context when using SPNEGO

Arlene Berry via RT rt-comment at krbdev.mit.edu
Tue Dec 22 21:29:32 EST 2009


When using SPNEGO the resulting security context is a union context with
type SPNEGO which contains another union context which contains the
actual mechanism.  This double union context causes gss_inquire_context
to report SPNEGO for the mechanism rather than the actual mechanism and
causes gss_display_status to not work for mechanism error codes since
the SPNEGO version of gss_display_status only translates SPNEGO error
codes.  Per Sam Hartman there was talk of collapsing the double union
context into a single context.  This patch does that which fixes both
issues.  Note that this requires the fix for bug #6598.  


Index: src/lib/gssapi/mechglue/g_accept_sec_context.c
===================================================================
--- src/lib/gssapi/mechglue/g_accept_sec_context.c	(revision 23482)
+++ src/lib/gssapi/mechglue/g_accept_sec_context.c	(working copy)
@@ -333,6 +333,23 @@
 		}
 	    }
 
+            if (status == GSS_S_COMPLETE && actual_mech) {
+                gss_OID temp_mech_type = union_ctx_id->mech_type;
+
+                status = generic_gss_copy_oid(minor_status,
actual_mech,
+
&union_ctx_id->mech_type);
+                if (status != GSS_S_COMPLETE) {
+
gssint_delete_internal_sec_context(&temp_minor_status,
+                                                       actual_mech,
+
&union_ctx_id->internal_ctx_id,
+                                                       NULL);
+                    free(union_ctx_id);
+                    *context_handle = GSS_C_NO_CONTEXT;
+                }
+                free(temp_mech_type->elements);
+                free(temp_mech_type);
+            }
+
 	    if (mech_type != NULL)
 		*mech_type = actual_mech;
 	    else
Index: src/lib/gssapi/mechglue/g_init_sec_context.c
===================================================================
--- src/lib/gssapi/mechglue/g_init_sec_context.c	(revision 23482)
+++ src/lib/gssapi/mechglue/g_init_sec_context.c	(working copy)
@@ -117,6 +117,7 @@
     gss_name_t		internal_name;
     gss_union_ctx_id_t	union_ctx_id;
     gss_OID		mech_type = (gss_OID) req_mech_type;
+    gss_OID		local_actual_mech = GSS_C_NO_OID;
     gss_mechanism	mech;
     gss_cred_id_t	input_cred_handle;
 
@@ -218,7 +219,7 @@
 	time_req,
 	input_chan_bindings,
 	input_token,
-	actual_mech_type,
+	&local_actual_mech,
 	output_token,
 	ret_flags,
 	time_rec);
@@ -240,7 +241,28 @@
 	union_ctx_id->loopback = union_ctx_id;
 	*context_handle = (gss_ctx_id_t)union_ctx_id;
     }
+    if (status == GSS_S_COMPLETE && local_actual_mech) {
+        gss_OID temp_mech_type = union_ctx_id->mech_type;
 
+        status = generic_gss_copy_oid(minor_status, local_actual_mech,
+				      &union_ctx_id->mech_type);
+        if (status != GSS_S_COMPLETE) {
+            gssint_delete_internal_sec_context(&temp_minor_status,
+                                               local_actual_mech,
+
&union_ctx_id->internal_ctx_id,
+                                               NULL);
+            free(union_ctx_id);
+            *context_handle = GSS_C_NO_CONTEXT;
+        }
+
+        free(temp_mech_type->elements);
+        free(temp_mech_type);
+    }
+
+    if (actual_mech_type != NULL) {
+        *actual_mech_type = local_actual_mech;
+    }
+
 end:
     if (union_name->mech_name == NULL ||
 	union_name->mech_name != internal_name) {
Index: src/lib/gssapi/spnego/spnego_mech.c
===================================================================
--- src/lib/gssapi/spnego/spnego_mech.c	(revision 23482)
+++ src/lib/gssapi/spnego/spnego_mech.c	(working copy)
@@ -967,11 +967,14 @@
 		 * Now, switch the output context to refer to the
 		 * negotiated mechanism's context.
 		 */
-		*context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle;
+		*context_handle =
(gss_union_ctx_id_t)(spnego_ctx->ctx_handle)->internal_ctx_id;
 		if (actual_mech != NULL)
 			*actual_mech = spnego_ctx->actual_mech;
 		if (ret_flags != NULL)
 			*ret_flags = spnego_ctx->ctx_flags;
+
free(((gss_union_ctx_id_t)spnego_ctx->ctx_handle)->mech_type->elements);
+
free(((gss_union_ctx_id_t)spnego_ctx->ctx_handle)->mech_type);
+		free(spnego_ctx->ctx_handle);
 		release_spnego_ctx(&spnego_ctx);
 	} else if (ret != GSS_S_CONTINUE_NEEDED) {
 		if (spnego_ctx != NULL) {
@@ -1686,11 +1689,14 @@
 			ret = GSS_S_FAILURE;
 	}
 	if (ret == GSS_S_COMPLETE) {
-		*context_handle = (gss_ctx_id_t)sc->ctx_handle;
+		*context_handle =
(gss_union_ctx_id_t)(sc->ctx_handle)->internal_ctx_id;
 		if (sc->internal_name != GSS_C_NO_NAME &&
 		    src_name != NULL) {
 			*src_name = sc->internal_name;
		}
+
free(((gss_union_ctx_id_t)sc->ctx_handle)->mech_type->elements);
+		free(((gss_union_ctx_id_t)sc->ctx_handle)->mech_type);
+		free(sc->ctx_handle);
 		release_spnego_ctx(&sc);
 	} else if (ret != GSS_S_CONTINUE_NEEDED) {
 		if (sc != NULL) {





More information about the krb5-bugs mailing list