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