krb5 commit [krb5-1.12]: Let SPNEGO display mechanism errors

Tom Yu tlyu at MIT.EDU
Wed Jan 8 22:30:24 EST 2014


https://github.com/krb5/krb5/commit/b95c27a4360164c3cc918e2c2e4915a0f35883a7
commit b95c27a4360164c3cc918e2c2e4915a0f35883a7
Author: Simo Sorce <simo at redhat.com>
Date:   Tue Dec 17 16:15:14 2013 -0500

    Let SPNEGO display mechanism errors
    
    To avoid potential recursion we use a thread local variable that tells
    us whether the ancestor was called via spnego_gss_display_name().  If
    we detect recursion, we assume that we returned a com_err code like
    ENOMEM and call error_message(); in the worst case that will result in
    an "Unknown error" message.
    
    [ghudson at mit.edu: Edited comments and commit message; removed an
    unneeded line of code.]
    
    (cherry picked from commit d160bc733a3dbeb6d84f4e175234ff18738d9f66)
    
    ticket: 7045

 src/include/k5-thread.h             |    1 +
 src/lib/gssapi/spnego/spnego_mech.c |   42 ++++++++++++++++++++++++++++------
 2 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/src/include/k5-thread.h b/src/include/k5-thread.h
index 1b7fa69..ab46ec3 100644
--- a/src/include/k5-thread.h
+++ b/src/include/k5-thread.h
@@ -406,6 +406,7 @@ typedef enum {
     K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME,
     K5_KEY_GSS_KRB5_CCACHE_NAME,
     K5_KEY_GSS_KRB5_ERROR_MESSAGE,
+    K5_KEY_GSS_SPNEGO_STATUS,
 #if defined(__MACH__) && defined(__APPLE__)
     K5_KEY_IPC_CONNECTION_INFO,
 #endif
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 24c3440..7a58c1b 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -85,8 +85,8 @@ extern int gssint_put_der_length(unsigned int, unsigned char **, unsigned int);
 
 
 /* private routines for spnego_mechanism */
-static spnego_token_t make_spnego_token(char *);
-static gss_buffer_desc make_err_msg(char *);
+static spnego_token_t make_spnego_token(const char *);
+static gss_buffer_desc make_err_msg(const char *);
 static int g_token_size(gss_OID_const, unsigned int);
 static int g_make_token_header(gss_OID_const, unsigned int,
 			       unsigned char **, unsigned int);
@@ -316,6 +316,12 @@ int gss_krb5int_lib_init(void);
 
 int gss_spnegoint_lib_init(void)
 {
+	int err;
+
+	err = k5_key_register(K5_KEY_GSS_SPNEGO_STATUS, NULL);
+	if (err)
+		return err;
+
 #ifdef _GSS_STATIC_LINK
 	return gss_spnegomechglue_init();
 #else
@@ -1791,7 +1797,6 @@ cleanup:
 }
 #endif /*  LEAN_CLIENT */
 
-
 /*ARGSUSED*/
 OM_uint32 KRB5_CALLCONV
 spnego_gss_display_status(
@@ -1802,6 +1807,9 @@ spnego_gss_display_status(
 		OM_uint32 *message_context,
 		gss_buffer_t status_string)
 {
+	OM_uint32 maj = GSS_S_COMPLETE;
+	int ret;
+
 	dsyslog("Entering display_status\n");
 
 	*message_context = 0;
@@ -1832,13 +1840,31 @@ spnego_gss_display_status(
 						"return a valid token"));
 		break;
 	    default:
-		status_string->length = 0;
-		status_string->value = "";
+		/* Not one of our minor codes; might be from a mech.  Call back
+		 * to gss_display_status, but first check for recursion. */
+		if (k5_getspecific(K5_KEY_GSS_SPNEGO_STATUS) != NULL) {
+			/* Perhaps we returned a com_err code like ENOMEM. */
+			const char *err = error_message(status_value);
+			*status_string = make_err_msg(err);
+			break;
+		}
+		/* Set a non-null pointer value; doesn't matter which one. */
+		ret = k5_setspecific(K5_KEY_GSS_SPNEGO_STATUS, &ret);
+		if (ret != 0) {
+			*minor_status = ret;
+			maj = GSS_S_FAILURE;
+			break;
+		}
+		maj = gss_display_status(minor_status, status_value,
+					 status_type, mech_type,
+					 message_context, status_string);
+		/* This is unlikely to fail; not much we can do if it does. */
+		(void)k5_setspecific(K5_KEY_GSS_SPNEGO_STATUS, NULL);
 		break;
 	}
 
 	dsyslog("Leaving display_status\n");
-	return (GSS_S_COMPLETE);
+	return maj;
 }
 
 
@@ -3547,13 +3573,13 @@ negotiate_mech(gss_OID_set supported, gss_OID_set received,
  * these routines will be changes to return the error string.
  */
 static spnego_token_t
-make_spnego_token(char *name)
+make_spnego_token(const char *name)
 {
 	return (spnego_token_t)strdup(name);
 }
 
 static gss_buffer_desc
-make_err_msg(char *name)
+make_err_msg(const char *name)
 {
 	gss_buffer_desc buffer;
 


More information about the cvs-krb5 mailing list