summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2011-04-04 23:06:09 +0000
committerGreg Hudson <ghudson@mit.edu>2011-04-04 23:06:09 +0000
commit79c34ed3d829ee9e3fa64aa5b3b90b4e37514cf7 (patch)
treeaff16b0d48c7ceaa24142527741e9f7d056b271f
parent308efc2ae8a8b21a6e74a8015197801d414f1bfb (diff)
downloadkrb5-79c34ed3d829ee9e3fa64aa5b3b90b4e37514cf7.tar.gz
krb5-79c34ed3d829ee9e3fa64aa5b3b90b4e37514cf7.tar.xz
krb5-79c34ed3d829ee9e3fa64aa5b3b90b4e37514cf7.zip
More sensical mech selection for gss_acquire_cred/accept_sec_context
If a caller passes an empty mech set to gss_acquire_cred, get a cred for all mechs instead of just the krb5 mech, as we don't know what mechanism the cred is going to be used with (particularly in the acceptor case). As a related fix, if a caller passes a credential to gss_accept_sec_context and it does not contain a mech-specific cred for the token's mech, error out instead of using the default cred with the token's mechanism. ticket: 6894 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24840 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/gssapi/mechglue/g_accept_sec_context.c15
-rw-r--r--src/lib/gssapi/mechglue/g_acquire_cred.c78
2 files changed, 44 insertions, 49 deletions
diff --git a/src/lib/gssapi/mechglue/g_accept_sec_context.c b/src/lib/gssapi/mechglue/g_accept_sec_context.c
index 8714f3fb7..8e0b7c5a0 100644
--- a/src/lib/gssapi/mechglue/g_accept_sec_context.c
+++ b/src/lib/gssapi/mechglue/g_accept_sec_context.c
@@ -115,7 +115,6 @@ gss_cred_id_t * d_cred;
OM_uint32 status, temp_status, temp_minor_status;
OM_uint32 temp_ret_flags = 0;
gss_union_ctx_id_t union_ctx_id;
- gss_union_cred_t union_cred;
gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL;
gss_cred_id_t tmp_d_cred = GSS_C_NO_CREDENTIAL;
gss_name_t internal_name = GSS_C_NO_NAME;
@@ -181,11 +180,17 @@ gss_cred_id_t * d_cred;
/*
* get the appropriate cred handle from the union cred struct.
- * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will
- * use the default credential.
*/
- union_cred = (gss_union_cred_t) verifier_cred_handle;
- input_cred_handle = gssint_get_mechanism_cred(union_cred, token_mech_type);
+ if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
+ input_cred_handle =
+ gssint_get_mechanism_cred((gss_union_cred_t)verifier_cred_handle,
+ token_mech_type);
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
+ /* verifier credential specified but no acceptor credential found */
+ status = GSS_S_NO_CRED;
+ goto error_out;
+ }
+ }
/*
* now select the approprate underlying mechanism routine and
diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c
index 6dfc65f7b..71bbf9e21 100644
--- a/src/lib/gssapi/mechglue/g_acquire_cred.c
+++ b/src/lib/gssapi/mechglue/g_acquire_cred.c
@@ -103,14 +103,11 @@ gss_OID_set * actual_mechs;
OM_uint32 * time_rec;
{
- OM_uint32 major = GSS_S_FAILURE;
+ OM_uint32 major = GSS_S_FAILURE, tmpMinor;
OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE;
- gss_OID_set_desc default_OID_set;
- gss_OID_set mechs;
- gss_OID_desc default_OID;
- gss_mechanism mech;
+ gss_OID_set mechs = GSS_C_NO_OID_SET;
unsigned int i;
- gss_union_cred_t creds;
+ gss_union_cred_t creds = NULL;
major = val_acq_cred_args(minor_status,
desired_name,
@@ -121,44 +118,37 @@ OM_uint32 * time_rec;
actual_mechs,
time_rec);
if (major != GSS_S_COMPLETE)
- return (major);
-
- /* Initial value needed below. */
- major = GSS_S_FAILURE;
+ goto cleanup;
/*
- * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an
- * appropriate default. We use the first mechanism in the
- * mechansim list as the default. This set is created with
- * statics thus needs not be freed
+ * if desired_mechs equals GSS_C_NULL_OID_SET, then try to
+ * acquire credentials for all mechanisms.
*/
- if(desired_mechs == GSS_C_NULL_OID_SET) {
- mech = gssint_get_mechanism(NULL);
- if (mech == NULL)
- return (GSS_S_BAD_MECH);
-
- mechs = &default_OID_set;
- default_OID_set.count = 1;
- default_OID_set.elements = &default_OID;
- default_OID.length = mech->mech_type.length;
- default_OID.elements = mech->mech_type.elements;
+ if (desired_mechs == GSS_C_NULL_OID_SET) {
+ major = gss_indicate_mechs(minor_status, &mechs);
+ if (major != GSS_S_COMPLETE)
+ goto cleanup;
} else
mechs = desired_mechs;
- if (mechs->count == 0)
- return (GSS_S_BAD_MECH);
+ if (mechs->count == 0) {
+ major = GSS_S_BAD_MECH;
+ goto cleanup;
+ }
/* allocate the output credential structure */
- creds = (gss_union_cred_t)malloc(sizeof (gss_union_cred_desc));
- if (creds == NULL)
- return (GSS_S_FAILURE);
+ creds = (gss_union_cred_t)calloc(1, sizeof (gss_union_cred_desc));
+ if (creds == NULL) {
+ major = GSS_S_FAILURE;
+ *minor_status = ENOMEM;
+ goto cleanup;
+ }
- /* initialize to 0s */
- (void) memset(creds, 0, sizeof (gss_union_cred_desc));
+ creds->count = 0;
creds->loopback = creds;
/* for each requested mech attempt to obtain a credential */
- for (i = 0; i < mechs->count; i++) {
+ for (i = 0, major = GSS_S_UNAVAILABLE; i < mechs->count; i++) {
major = gss_add_cred(minor_status, (gss_cred_id_t)creds,
desired_name,
&mechs->elements[i],
@@ -188,10 +178,8 @@ OM_uint32 * time_rec;
} /* for */
/* ensure that we have at least one credential element */
- if (creds->count < 1) {
- free(creds);
- return (major);
- }
+ if (creds->count < 1)
+ goto cleanup;
/*
* fill in output parameters
@@ -204,20 +192,22 @@ OM_uint32 * time_rec;
oids.elements = creds->mechs_array;
major = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs);
- if (GSS_ERROR(major)) {
- (void) gss_release_cred(minor_status,
- (gss_cred_id_t *)&creds);
- return (major);
- }
+ if (GSS_ERROR(major))
+ goto cleanup;
}
if (time_rec)
*time_rec = outTime;
-
- creds->loopback = creds;
*output_cred_handle = (gss_cred_id_t)creds;
- return (GSS_S_COMPLETE);
+
+cleanup:
+ if (GSS_ERROR(major))
+ gss_release_cred(&tmpMinor, (gss_cred_id_t *)&creds);
+ if (desired_mechs == GSS_C_NO_OID_SET)
+ generic_gss_release_oid_set(&tmpMinor, &mechs);
+
+ return (major);
}
static OM_uint32