krb5 commit: Introduce credential store extensions

Greg Hudson ghudson at MIT.EDU
Fri Jul 20 15:36:23 EDT 2012


https://github.com/krb5/krb5/commit/25ee704e83c2c63d4b5ecd12ea31c1979239041e
commit 25ee704e83c2c63d4b5ecd12ea31c1979239041e
Author: Simo Sorce <simo at redhat.com>
Date:   Fri Mar 2 18:27:49 2012 -0500

    Introduce credential store extensions
    
    Add new APIs gss_acquire_cred_from, gss_add_cred_from, and
    gss_store_cred_into, which take additional argments to specify the
    location of the credential storage using a key-value map, where keys
    are interpreted by the mechanisms.
    
    ticket: 7217 (new)

 src/lib/gssapi/generic/gssapi_ext.h      |   56 +++++++++++++++
 src/lib/gssapi/libgssapi_krb5.exports    |    3 +
 src/lib/gssapi/mechglue/g_acquire_cred.c |  104 +++++++++++++++++++++++++---
 src/lib/gssapi/mechglue/g_store_cred.c   |  110 ++++++++++++++++++++++++------
 src/lib/gssapi/mechglue/mglueP.h         |   28 ++++++++
 5 files changed, 269 insertions(+), 32 deletions(-)

diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h
index b4f8a77..05f1ed7 100644
--- a/src/lib/gssapi/generic/gssapi_ext.h
+++ b/src/lib/gssapi/generic/gssapi_ext.h
@@ -461,6 +461,62 @@ int KRB5_CALLCONV gss_oid_equal
     gss_const_OID       /* second_oid */
 );
 
+/* Credential store extensions */
+
+struct gss_key_value_element_struct {
+    const char *key;
+    const char *value;
+};
+typedef struct gss_key_value_element_struct gss_key_value_element_desc;
+
+struct gss_key_value_set_struct {
+    OM_uint32 count;
+    gss_key_value_element_desc *elements;
+};
+typedef struct gss_key_value_set_struct gss_key_value_set_desc;
+typedef const gss_key_value_set_desc *gss_const_key_value_set_t;
+
+#define GSS_C_NO_CRED_STORE ((gss_const_key_value_set_t) 0)
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_from(
+    OM_uint32 *,               /* minor_status */
+    gss_name_t,                /* desired_name */
+    OM_uint32,                 /* time_req */
+    gss_OID_set,               /* desired_mechs */
+    gss_cred_usage_t,          /* cred_usage */
+    gss_const_key_value_set_t, /* cred_store */
+    gss_cred_id_t *,           /* output_cred_handle */
+    gss_OID_set *,             /* actual_mechs */
+    OM_uint32 *);              /* time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_from(
+    OM_uint32 *,               /* minor_status */
+    gss_cred_id_t,             /* input_cred_handle */
+    gss_name_t,                /* desired_name */
+    gss_OID,                   /* desired_mech */
+    gss_cred_usage_t,          /* cred_usage */
+    OM_uint32,                 /* initiator_time_req */
+    OM_uint32,                 /* acceptor_time_req */
+    gss_const_key_value_set_t, /* cred_store */
+    gss_cred_id_t *,           /* output_cred_handle */
+    gss_OID_set *,             /* actual_mechs */
+    OM_uint32 *,               /* initiator_time_rec */
+    OM_uint32 *);              /* acceptor_time_rec */
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred_into(
+    OM_uint32 *,               /* minor_status */
+    gss_cred_id_t,             /* input_cred_handle */
+    gss_cred_usage_t,          /* input_usage */
+    gss_OID,                   /* desired_mech */
+    OM_uint32,                 /* overwrite_cred */
+    OM_uint32,                 /* default_cred */
+    gss_const_key_value_set_t, /* cred_store */
+    gss_OID_set *,             /* elements_stored */
+    gss_cred_usage_t *);       /* cred_usage_stored */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports
index 58111aa..a8ee3f2 100644
--- a/src/lib/gssapi/libgssapi_krb5.exports
+++ b/src/lib/gssapi/libgssapi_krb5.exports
@@ -148,3 +148,6 @@ krb5_gss_dbg_client_expcreds
 krb5_gss_register_acceptor_identity
 krb5_gss_use_kdc_context
 gss_inquire_name
+gss_acquire_cred_from
+gss_add_cred_from
+gss_store_cred_into
diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c
index ad4e99b..c28bf72 100644
--- a/src/lib/gssapi/mechglue/g_acquire_cred.c
+++ b/src/lib/gssapi/mechglue/g_acquire_cred.c
@@ -42,6 +42,7 @@ val_acq_cred_args(
     OM_uint32 time_req,
     gss_OID_set desired_mechs,
     int cred_usage,
+    gss_const_key_value_set_t cred_store,
     gss_cred_id_t *output_cred_handle,
     gss_OID_set *actual_mechs,
     OM_uint32 *time_rec)
@@ -79,6 +80,12 @@ val_acq_cred_args(
 	return GSS_S_FAILURE;
     }
 
+    if (cred_store != NULL && cred_store->count == 0) {
+	*minor_status = EINVAL;
+	map_errcode(minor_status);
+	return GSS_S_FAILURE;
+    }
+
     return (GSS_S_COMPLETE);
 }
 
@@ -103,6 +110,33 @@ gss_OID_set *		actual_mechs;
 OM_uint32 *		time_rec;
 
 {
+    return gss_acquire_cred_from(minor_status, desired_name, time_req,
+				 desired_mechs, cred_usage, NULL,
+				 output_cred_handle, actual_mechs, time_rec);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_acquire_cred_from(minor_status,
+		      desired_name,
+		      time_req,
+		      desired_mechs,
+		      cred_usage,
+		      cred_store,
+		      output_cred_handle,
+		      actual_mechs,
+		      time_rec)
+
+OM_uint32 *			minor_status;
+gss_name_t			desired_name;
+OM_uint32			time_req;
+gss_OID_set			desired_mechs;
+int				cred_usage;
+gss_const_key_value_set_t	cred_store;
+gss_cred_id_t *			output_cred_handle;
+gss_OID_set *			actual_mechs;
+OM_uint32 *			time_rec;
+
+{
     OM_uint32 major = GSS_S_FAILURE, tmpMinor;
     OM_uint32 first_major = GSS_S_COMPLETE, first_minor = 0;
     OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE;
@@ -115,6 +149,7 @@ OM_uint32 *		time_rec;
 			      time_req,
 			      desired_mechs,
 			      cred_usage,
+			      cred_store,
 			      output_cred_handle,
 			      actual_mechs,
 			      time_rec);
@@ -150,11 +185,11 @@ OM_uint32 *		time_rec;
 
     /* for each requested mech attempt to obtain a credential */
     for (i = 0, major = GSS_S_UNAVAILABLE; i < mechs->count; i++) {
-	major = gss_add_cred(&tmpMinor, (gss_cred_id_t)creds,
-			     desired_name,
-			     &mechs->elements[i],
-			     cred_usage, time_req, time_req, NULL,
-			     NULL, &initTimeOut, &acceptTimeOut);
+	major = gss_add_cred_from(&tmpMinor, (gss_cred_id_t)creds,
+				  desired_name, &mechs->elements[i],
+				  cred_usage, time_req, time_req,
+				  cred_store, NULL, NULL, &initTimeOut,
+				  &acceptTimeOut);
 	if (major == GSS_S_COMPLETE) {
 	    /* update the credential's time */
 	    if (cred_usage == GSS_C_ACCEPT) {
@@ -226,6 +261,7 @@ val_add_cred_args(
     gss_name_t desired_name,
     gss_OID desired_mech,
     gss_cred_usage_t cred_usage,
+    gss_const_key_value_set_t cred_store,
     OM_uint32 initiator_time_req,
     OM_uint32 acceptor_time_req,
     gss_cred_id_t *output_cred_handle,
@@ -270,6 +306,12 @@ val_add_cred_args(
 	return GSS_S_FAILURE;
     }
 
+    if (cred_store != NULL && cred_store->count == 0) {
+	*minor_status = EINVAL;
+	map_errcode(minor_status);
+	return GSS_S_FAILURE;
+    }
+
     return (GSS_S_COMPLETE);
 }
 
@@ -293,6 +335,34 @@ gss_add_cred(minor_status, input_cred_handle,
     OM_uint32		*initiator_time_rec;
     OM_uint32		*acceptor_time_rec;
 {
+    return gss_add_cred_from(minor_status, input_cred_handle, desired_name,
+			     desired_mech, cred_usage, initiator_time_req,
+			     acceptor_time_req, NULL, output_cred_handle,
+			     actual_mechs, initiator_time_rec,
+			     acceptor_time_rec);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_add_cred_from(minor_status, input_cred_handle,
+		  desired_name, desired_mech,
+		  cred_usage,
+		  initiator_time_req, acceptor_time_req,
+		  cred_store,
+		  output_cred_handle, actual_mechs,
+		  initiator_time_rec, acceptor_time_rec)
+    OM_uint32		*minor_status;
+    gss_cred_id_t	input_cred_handle;
+    gss_name_t		desired_name;
+    gss_OID		desired_mech;
+    gss_cred_usage_t	cred_usage;
+    OM_uint32		initiator_time_req;
+    OM_uint32		acceptor_time_req;
+    gss_const_key_value_set_t  cred_store;
+    gss_cred_id_t	*output_cred_handle;
+    gss_OID_set		*actual_mechs;
+    OM_uint32		*initiator_time_rec;
+    OM_uint32		*acceptor_time_rec;
+{
     OM_uint32		status, temp_minor_status;
     OM_uint32		time_req, time_rec;
     gss_union_name_t	union_name;
@@ -309,6 +379,7 @@ gss_add_cred(minor_status, input_cred_handle,
 			       desired_name,
 			       desired_mech,
 			       cred_usage,
+			       cred_store,
 			       initiator_time_req,
 			       acceptor_time_req,
 			       output_cred_handle,
@@ -330,15 +401,16 @@ gss_add_cred(minor_status, input_cred_handle,
 	    return (GSS_S_FAILURE);
 
 	(void) memset(union_cred, 0, sizeof (gss_union_cred_desc));
-
-	/* for default credentials we will use GSS_C_NO_NAME */
-	internal_name = GSS_C_NO_NAME;
     } else {
 	union_cred = (gss_union_cred_t)input_cred_handle;
 	if (gssint_get_mechanism_cred(union_cred, desired_mech) !=
 	    GSS_C_NO_CREDENTIAL)
 	    return (GSS_S_DUPLICATE_ELEMENT);
+    }
 
+    /* for default credentials we will use GSS_C_NO_NAME */
+    if (input_cred_handle != GSS_C_NO_CREDENTIAL ||
+        cred_store != GSS_C_NO_CRED_STORE) {
 	/* may need to create a mechanism specific name */
 	if (desired_name) {
 	    union_name = (gss_union_name_t)desired_name;
@@ -367,10 +439,18 @@ gss_add_cred(minor_status, input_cred_handle,
     else
 	time_req = 0;
 
-    status = mech->gss_acquire_cred(minor_status,
-				    internal_name, time_req,
-				    GSS_C_NULL_OID_SET, cred_usage,
-				    &cred, NULL, &time_rec);
+    if (mech->gss_acquire_cred_from) {
+	status = mech->gss_acquire_cred_from(minor_status, internal_name,
+					     time_req, GSS_C_NULL_OID_SET,
+					     cred_usage, cred_store, &cred,
+					     NULL, &time_rec);
+    } else if (cred_store == GSS_C_NO_CRED_STORE) {
+	status = mech->gss_acquire_cred(minor_status, internal_name, time_req,
+					GSS_C_NULL_OID_SET, cred_usage, &cred,
+					NULL, &time_rec);
+    } else {
+	return GSS_S_UNAVAILABLE;
+    }
 
     if (status != GSS_S_COMPLETE) {
 	map_error(minor_status, mech);
diff --git a/src/lib/gssapi/mechglue/g_store_cred.c b/src/lib/gssapi/mechglue/g_store_cred.c
index f7de1d6..a68a587 100644
--- a/src/lib/gssapi/mechglue/g_store_cred.c
+++ b/src/lib/gssapi/mechglue/g_store_cred.c
@@ -12,6 +12,36 @@
 #include <mglueP.h>
 
 static OM_uint32
+store_cred_fallback(
+	OM_uint32 *minor_status,
+	gss_mechanism mech,
+	gss_cred_id_t mech_cred,
+	gss_cred_usage_t cred_usage,
+	gss_OID desired_mech,
+	OM_uint32 overwrite_cred,
+	OM_uint32 default_cred,
+	gss_const_key_value_set_t cred_store,
+	gss_OID_set *elements_stored,
+	gss_cred_usage_t *cred_usage_stored)
+{
+	if (mech->gss_store_cred_into != NULL) {
+		return mech->gss_store_cred_into(minor_status, mech_cred,
+						 cred_usage, desired_mech,
+						 overwrite_cred, default_cred,
+						 cred_store, elements_stored,
+						 cred_usage_stored);
+	} else if (cred_store == GSS_C_NO_CRED_STORE) {
+		return mech->gss_store_cred(minor_status, mech_cred,
+					    cred_usage, desired_mech,
+					    overwrite_cred, default_cred,
+					    elements_stored,
+					    cred_usage_stored);
+	} else {
+		return GSS_S_UNAVAILABLE;
+	}
+}
+
+static OM_uint32
 val_store_cred_args(
 	OM_uint32 *minor_status,
 	const gss_cred_id_t input_cred_handle,
@@ -19,6 +49,7 @@ val_store_cred_args(
 	const gss_OID desired_mech,
 	OM_uint32 overwrite_cred,
 	OM_uint32 default_cred,
+	gss_const_key_value_set_t cred_store,
 	gss_OID_set *elements_stored,
 	gss_cred_usage_t *cred_usage_stored)
 {
@@ -49,6 +80,12 @@ val_store_cred_args(
 	    return GSS_S_FAILURE;
 	}
 
+	if (cred_store != NULL && cred_store->count == 0) {
+		*minor_status = EINVAL;
+		map_errcode(minor_status);
+		return GSS_S_FAILURE;
+	}
+
 	return (GSS_S_COMPLETE);
 }
 
@@ -73,6 +110,34 @@ gss_OID_set		*elements_stored;
 gss_cred_usage_t	*cred_usage_stored;
 
 {
+	return gss_store_cred_into(minor_status, input_cred_handle, cred_usage,
+				   desired_mech, overwrite_cred, default_cred,
+				   GSS_C_NO_CRED_STORE, elements_stored,
+				   cred_usage_stored);
+}
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred_into(minor_status,
+		    input_cred_handle,
+		    cred_usage,
+		    desired_mech,
+		    overwrite_cred,
+		    default_cred,
+		    cred_store,
+		    elements_stored,
+		    cred_usage_stored)
+
+OM_uint32			 *minor_status;
+gss_cred_id_t			 input_cred_handle;
+gss_cred_usage_t		 cred_usage;
+gss_OID				 desired_mech;
+OM_uint32			 overwrite_cred;
+OM_uint32			 default_cred;
+gss_const_key_value_set_t	 cred_store;
+gss_OID_set			 *elements_stored;
+gss_cred_usage_t		 *cred_usage_stored;
+
+{
 	OM_uint32		major_status = GSS_S_FAILURE;
 	gss_union_cred_t	union_cred;
 	gss_cred_id_t		mech_cred;
@@ -86,6 +151,7 @@ gss_cred_usage_t	*cred_usage_stored;
 					   desired_mech,
 					   overwrite_cred,
 					   default_cred,
+					   cred_store,
 					   elements_stored,
 					   cred_usage_stored);
 	if (major_status != GSS_S_COMPLETE)
@@ -105,22 +171,25 @@ gss_cred_usage_t	*cred_usage_stored;
 		if (mech == NULL)
 			return (GSS_S_BAD_MECH);
 
-		if (mech->gss_store_cred == NULL)
+		if (mech->gss_store_cred_into == NULL &&
+		    cred_store != GSS_C_NO_CRED_STORE)
+			return (major_status);
+
+		if (mech->gss_store_cred == NULL &&
+		    mech->gss_store_cred_into == NULL)
 			return (major_status);
 
 		mech_cred = gssint_get_mechanism_cred(union_cred, desired_mech);
 		if (mech_cred == GSS_C_NO_CREDENTIAL)
 			return (GSS_S_NO_CRED);
 
-		major_status = mech->gss_store_cred(
-						    minor_status,
-						    (gss_cred_id_t)mech_cred,
-						    cred_usage,
-						    desired_mech,
-						    overwrite_cred,
-						    default_cred,
-						    elements_stored,
-						    cred_usage_stored);
+		major_status = store_cred_fallback(minor_status, mech,
+						   mech_cred, cred_usage,
+						   desired_mech,
+						   overwrite_cred,
+						   default_cred, cred_store,
+						   elements_stored,
+						   cred_usage_stored);
 		if (major_status != GSS_S_COMPLETE)
 		    map_error(minor_status, mech);
 		return major_status;
@@ -137,22 +206,23 @@ gss_cred_usage_t	*cred_usage_stored;
 		if (mech == NULL)
 			continue;
 
-		if (mech->gss_store_cred == NULL)
+		if (mech->gss_store_cred_into == NULL &&
+		    cred_store != GSS_C_NO_CRED_STORE)
+			continue;
+
+		if (mech->gss_store_cred == NULL &&
+		    mech->gss_store_cred_into == NULL)
 			continue;
 
 		mech_cred = gssint_get_mechanism_cred(union_cred, dmech);
 		if (mech_cred == GSS_C_NO_CREDENTIAL)
 			continue; /* can't happen, but safe to ignore */
 
-		major_status = mech->gss_store_cred(
-						minor_status,
-						(gss_cred_id_t)mech_cred,
-						cred_usage,
-						dmech,
-						overwrite_cred,
-						default_cred,
-						NULL,
-						cred_usage_stored);
+		major_status = store_cred_fallback(minor_status, mech,
+						   mech_cred, cred_usage,
+						   dmech, overwrite_cred,
+						   default_cred, cred_store,
+						   NULL, cred_usage_stored);
 		if (major_status != GSS_S_COMPLETE) {
 		    map_error(minor_status, mech);
 		    continue;
diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h
index 577f573..efbb370 100644
--- a/src/lib/gssapi/mechglue/mglueP.h
+++ b/src/lib/gssapi/mechglue/mglueP.h
@@ -605,6 +605,34 @@ typedef struct gss_config {
 	    gss_OID_set *		/* known_mech_attrs */
 	/* */);
 
+	/* Credential store extensions */
+
+	OM_uint32       (KRB5_CALLCONV *gss_acquire_cred_from)
+	(
+	    OM_uint32 *,		/* minor_status */
+	    gss_name_t,			/* desired_name */
+	    OM_uint32,			/* time_req */
+	    gss_OID_set,		/* desired_mechs */
+	    gss_cred_usage_t,		/* cred_usage */
+	    gss_const_key_value_set_t,	/* cred_store */
+	    gss_cred_id_t *,		/* output_cred_handle */
+	    gss_OID_set *,		/* actual_mechs */
+	    OM_uint32 *			/* time_rec */
+	/* */);
+
+	OM_uint32       (KRB5_CALLCONV *gss_store_cred_into)
+	(
+	    OM_uint32 *,		/* minor_status */
+	    gss_cred_id_t,		/* input_cred_handle */
+	    gss_cred_usage_t,		/* input_usage */
+	    gss_OID,			/* desired_mech */
+	    OM_uint32,			/* overwrite_cred */
+	    OM_uint32,			/* default_cred */
+	    gss_const_key_value_set_t,	/* cred_store */
+	    gss_OID_set *,		/* elements_stored */
+	    gss_cred_usage_t *		/* cred_usage_stored */
+	/* */);
+
 } *gss_mechanism;
 
 /* This structure MUST NOT be used by any code outside libgss */


More information about the cvs-krb5 mailing list