aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandra Ellwood <lxs@mit.edu>2006-05-10 21:48:53 +0000
committerAlexandra Ellwood <lxs@mit.edu>2006-05-10 21:48:53 +0000
commit256446ab7fad68b15773d5fe8cc88b9abe3c461a (patch)
treec81d42d09001046516ba2edc7b2f3e58a585725a
parent15a4448eeff11554e17f77b481ae5881a7ec89a6 (diff)
downloadkrb5-256446ab7fad68b15773d5fe8cc88b9abe3c461a.zip
krb5-256446ab7fad68b15773d5fe8cc88b9abe3c461a.tar.gz
krb5-256446ab7fad68b15773d5fe8cc88b9abe3c461a.tar.bz2
Fixed the krb5_cc_gen_new memory ccache implementation and updated
krb5_verify_init_creds() and rd_and_store_for_creds() to use the API properly (possible now that it's been fixed). ticket: 3746 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17997 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/gssapi/krb5/accept_sec_context.c16
-rw-r--r--src/lib/krb5/ccache/cc_memory.c65
-rw-r--r--src/lib/krb5/krb/vfy_increds.c14
3 files changed, 83 insertions, 12 deletions
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 657176b..b6c50f9 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -93,6 +93,7 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
{
krb5_creds ** creds = NULL;
krb5_error_code retval;
+ krb5_ccache template_ccache = NULL;
krb5_ccache ccache = NULL;
krb5_gss_cred_id_t cred = NULL;
krb5_auth_context new_auth_ctx = NULL;
@@ -136,9 +137,10 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
/* Lots of kludging going on here... Some day the ccache interface
will be rewritten though */
- if ((retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &ccache)))
- goto cleanup;
+ if ((retval = krb5_cc_resolve(context, "MEMORY:GSSAPI", &template_ccache)))
+ goto cleanup;
+ ccache = template_ccache; /* krb5_cc_gen_new will replace so make a copy */
if ((retval = krb5_cc_gen_new(context, &ccache)))
goto cleanup;
@@ -182,8 +184,9 @@ rd_and_store_for_creds(context, auth_context, inbuf, out_cred)
cred->prerfc_mech = 1; /* this cred will work with all three mechs */
cred->rfc_mech = 1;
cred->keytab = NULL; /* no keytab associated with this... */
- cred->ccache = ccache; /* but there is a credential cache */
cred->tgt_expire = creds[0]->times.endtime; /* store the end time */
+ cred->ccache = ccache; /* the ccache containing the credential */
+ ccache = NULL; /* cred takes ownership so don't destroy */
}
/* If there were errors, there might have been a memory leak
@@ -195,8 +198,11 @@ cleanup:
if (creds)
krb5_free_tgt_creds(context, creds);
- if (!cred && ccache)
- (void)krb5_cc_close(context, ccache);
+ if (template_ccache)
+ (void)krb5_cc_close(context, template_ccache);
+
+ if (ccache)
+ (void)krb5_cc_destroy(context, ccache);
if (out_cred)
*out_cred = cred; /* return credential */
diff --git a/src/lib/krb5/ccache/cc_memory.c b/src/lib/krb5/ccache/cc_memory.c
index 1417aab..fd42710 100644
--- a/src/lib/krb5/ccache/cc_memory.c
+++ b/src/lib/krb5/ccache/cc_memory.c
@@ -440,6 +440,8 @@ new_mcc_data (const char *name, krb5_mcc_data **dataptr)
return 0;
}
+static krb5_error_code random_string (krb5_context, char *, krb5_int32);
+
/*
* Effects:
* Creates a new file cred cache whose name is guaranteed to be
@@ -454,13 +456,15 @@ new_mcc_data (const char *name, krb5_mcc_data **dataptr)
* krb5_ccache. id is undefined.
* system errors (from open)
*/
+
krb5_error_code KRB5_CALLCONV
krb5_mcc_generate_new (krb5_context context, krb5_ccache *id)
{
krb5_ccache lid;
- char scratch[6+1]; /* 6 for the scratch part, +1 for NUL */
+ char uniquename[8];
krb5_error_code err;
krb5_mcc_data *d;
+ krb5_mcc_list_node *ptr;
/* Allocate memory */
lid = (krb5_ccache) malloc(sizeof(struct _krb5_ccache));
@@ -469,25 +473,78 @@ krb5_mcc_generate_new (krb5_context context, krb5_ccache *id)
lid->ops = &krb5_mcc_ops;
- (void) strcpy(scratch, "XXXXXX");
- mktemp(scratch);
+ random_string (context, uniquename, sizeof (uniquename));
err = k5_mutex_lock(&krb5int_mcc_mutex);
if (err) {
free(lid);
return err;
}
- err = new_mcc_data(scratch, &d);
+
+ /* Check for uniqueness with mutex locked to avoid race conditions */
+ while (1) {
+ for (ptr = mcc_head; ptr; ptr=ptr->next) {
+ if (!strcmp(ptr->cache->name, uniquename)) {
+ /* name already exists. Pick a new one and start over. */
+ random_string (context, uniquename, sizeof (uniquename));
+ ptr = mcc_head;
+ continue;
+ }
+ }
+ break; /* got a unique name. Stop. */
+ }
+
+ err = new_mcc_data(uniquename, &d);
+
k5_mutex_unlock(&krb5int_mcc_mutex);
if (err) {
krb5_xfree(lid);
return err;
}
lid->data = d;
+ *id = lid;
krb5_change_cache ();
return KRB5_OK;
}
+/* Utility routine: Creates a random memory ccache name.
+ * This algorithm was selected because it creates readable
+ * random ccache names in a fixed size buffer. */
+
+static krb5_error_code
+random_string (krb5_context context, char *string, krb5_int32 length)
+{
+ static const unsigned char charlist[] =
+ "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ krb5_error_code err = 0;
+ u_int8_t *bytes = NULL;
+ size_t bytecount = length - 1;
+
+ if (!err) {
+ bytes = malloc (bytecount);
+ if (bytes == NULL) { err = ENOMEM; }
+ }
+
+ if (!err) {
+ krb5_data data;
+ data.length = bytecount;
+ data.data = (char *) bytes;
+ err = krb5_c_random_make_octets (context, &data);
+ }
+
+ if (!err) {
+ krb5_int32 i;
+ for (i = 0; i < bytecount; i++) {
+ string [i] = charlist[bytes[i] % (sizeof (charlist) - 1)];
+ }
+ string[length - 1] = '\0';
+ }
+
+ if (bytes != NULL) { free (bytes); }
+
+ return err;
+}
+
/*
* Requires:
* id is a file credential cache
diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c
index 62b535d..10a68f2 100644
--- a/src/lib/krb5/krb/vfy_increds.c
+++ b/src/lib/krb5/krb/vfy_increds.c
@@ -60,6 +60,7 @@ krb5_verify_init_creds(krb5_context context,
krb5_error_code ret;
krb5_principal server;
krb5_keytab keytab;
+ krb5_ccache template_ccache;
krb5_ccache ccache;
krb5_keytab_entry kte;
krb5_creds in_creds, *out_creds;
@@ -70,6 +71,7 @@ krb5_verify_init_creds(krb5_context context,
server = NULL;
keytab = NULL;
+ template_ccache = NULL;
ccache = NULL;
out_creds = NULL;
authcon = NULL;
@@ -137,10 +139,14 @@ krb5_verify_init_creds(krb5_context context,
internals with a coherent idea of "in" and "out". */
/* insert the initial cred into the ccache */
-
- if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req", &ccache)))
+
+ if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req", &template_ccache)))
goto cleanup;
-
+ ccache = template_ccache; /* krb5_cc_gen_new will replace so make a copy */
+
+ if ((ret = krb5_cc_gen_new(context, &ccache)))
+ goto cleanup;
+
if ((ret = krb5_cc_initialize(context, ccache, creds->client)))
goto cleanup;
@@ -209,6 +215,8 @@ cleanup:
krb5_free_principal(context, server);
if (!keytab_arg && keytab)
krb5_kt_close(context, keytab);
+ if (template_ccache)
+ krb5_cc_close(context, template_ccache);
if (ccache)
krb5_cc_destroy(context, ccache);
if (out_creds)