aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Howard <lukeh@padl.com>2009-11-15 19:28:42 +0000
committerLuke Howard <lukeh@padl.com>2009-11-15 19:28:42 +0000
commitb4b4978d7cdee45d7c6b1efd8737a6ede752ecda (patch)
tree48192c0a068c82a298b7c92dda30f617b4e357b3
parentd6ea15b9d969c0f4120abca0653cc7b516a2e754 (diff)
downloadkrb5-b4b4978d7cdee45d7c6b1efd8737a6ede752ecda.zip
krb5-b4b4978d7cdee45d7c6b1efd8737a6ede752ecda.tar.gz
krb5-b4b4978d7cdee45d7c6b1efd8737a6ede752ecda.tar.bz2
checkpoint
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/iakerb@23209 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/lib/gssapi/generic/gssapiP_generic.h2
-rw-r--r--src/lib/gssapi/generic/util_token.c2
-rw-r--r--src/lib/gssapi/krb5/acquire_cred.c128
-rw-r--r--src/lib/gssapi/krb5/iakerb.c45
4 files changed, 96 insertions, 81 deletions
diff --git a/src/lib/gssapi/generic/gssapiP_generic.h b/src/lib/gssapi/generic/gssapiP_generic.h
index 1100f6b..cb2340a 100644
--- a/src/lib/gssapi/generic/gssapiP_generic.h
+++ b/src/lib/gssapi/generic/gssapiP_generic.h
@@ -294,6 +294,4 @@ OM_uint32 generic_gss_copy_oid_set
const gss_OID_set_desc *, /* const oidset*/
gss_OID_set * /*new_oidset*/);
-int der_read_length(unsigned char **buf, int *bufsize);
-
#endif /* _GSSAPIP_GENERIC_H_ */
diff --git a/src/lib/gssapi/generic/util_token.c b/src/lib/gssapi/generic/util_token.c
index a0b9250..b597788 100644
--- a/src/lib/gssapi/generic/util_token.c
+++ b/src/lib/gssapi/generic/util_token.c
@@ -100,7 +100,7 @@ der_write_length(unsigned char **buf, int length)
/* returns decoded length, or < 0 on failure. Advances buf and
decrements bufsize */
-int
+static int
der_read_length(unsigned char **buf, int *bufsize)
{
unsigned char sf;
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index bc1e330..53078b6 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -336,7 +336,6 @@ acquire_init_cred(krb5_context context,
}
/* turn off OPENCLOSE mode while extensive frobbing is going on */
-
flags = 0; /* turns off OPENCLOSE mode */
if ((code = krb5_cc_set_flags(context, ccache, flags))) {
(void)krb5_cc_close(context, ccache);
@@ -345,7 +344,6 @@ acquire_init_cred(krb5_context context,
}
/* get out the principal name and see if it matches */
-
if ((code = krb5_cc_get_principal(context, ccache, &princ))) {
(void)krb5_cc_close(context, ccache);
*minor_status = code;
@@ -372,6 +370,22 @@ acquire_init_cred(krb5_context context,
}
}
+ if (cred->iakerb) {
+ krb5_data data;
+
+ data.length = password->length;
+ data.data = (char *)password->value;
+
+ code = krb5int_copy_data_contents_add0(context, &data, &cred->password);
+ if (code != 0) {
+ *minor_status = code;
+ return GSS_S_FAILURE;
+ }
+
+ cred->ccache = ccache;
+ return GSS_S_COMPLETE;
+ }
+
/* iterate over the ccache, find the tgt */
if ((code = krb5_cc_start_seq_get(context, ccache, &cur))) {
@@ -494,19 +508,15 @@ acquire_cred(minor_status, desired_name, password, time_req,
gss_OID_set ret_mechs = GSS_C_NO_OID_SET;
int req_old, req_new;
OM_uint32 ret;
- krb5_error_code code;
+ krb5_error_code code = 0;
code = gss_krb5int_initialize_library();
- if (code) {
- *minor_status = code;
- return GSS_S_FAILURE;
- }
+ if (code)
+ goto krb_error_out;
code = krb5_gss_init_context(&context);
- if (code) {
- *minor_status = code;
- return GSS_S_FAILURE;
- }
+ if (code)
+ goto krb_error_out;
/* make sure all outputs are valid */
@@ -521,9 +531,14 @@ acquire_cred(minor_status, desired_name, password, time_req,
/*SUPPRESS 29*/
if ((desired_name != GSS_C_NO_NAME) &&
(! kg_validate_name(desired_name))) {
- *minor_status = (OM_uint32) G_VALIDATE_FAILED;
- krb5_free_context(context);
- return(GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME);
+ code = G_VALIDATE_FAILED;
+ goto krb_error_out;
+ }
+
+ if (iakerb &&
+ (cred_usage != GSS_C_INITIATE /*|| desired_name == GSS_C_NO_NAME*/)) {
+ code = G_BAD_USAGE;
+ goto krb_error_out;
}
/* verify that the requested mechanism set is the default, or
@@ -544,28 +559,15 @@ acquire_cred(minor_status, desired_name, password, time_req,
}
if (!req_old && !req_new) {
- *minor_status = 0;
- krb5_free_context(context);
- return(GSS_S_BAD_MECH);
+ ret = GSS_S_BAD_MECH;
+ goto error_out;
}
}
- if (iakerb &&
- (cred_usage != GSS_C_INITIATE || desired_name == GSS_C_NO_NAME)) {
- *minor_status = G_BAD_USAGE;
- krb5_free_context(context);
- return GSS_S_FAILURE;
- }
-
/* create the gss cred structure */
-
- if ((cred =
- (krb5_gss_cred_id_t) xmalloc(sizeof(krb5_gss_cred_id_rec))) == NULL) {
- *minor_status = ENOMEM;
- krb5_free_context(context);
- return(GSS_S_FAILURE);
- }
- memset(cred, 0, sizeof(krb5_gss_cred_id_rec));
+ cred = k5alloc(sizeof(krb5_gss_cred_id_rec), &code);
+ if (code != 0)
+ goto krb_error_out;
cred->usage = cred_usage;
cred->name = NULL;
@@ -580,11 +582,9 @@ acquire_cred(minor_status, desired_name, password, time_req,
cred->ccache = NULL;
code = k5_mutex_init(&cred->lock);
- if (code) {
- *minor_status = code;
- krb5_free_context(context);
- return GSS_S_FAILURE;
- }
+ if (code)
+ goto krb_error_out;
+
/* Note that we don't need to lock this GSSAPI credential record
here, because no other thread can gain access to it until we
return it. */
@@ -613,40 +613,24 @@ acquire_cred(minor_status, desired_name, password, time_req,
/* this will fill in cred->name if it wasn't set above, and
the desired_name is not specified */
- if ((cred->iakerb == 0 && cred_usage == GSS_C_INITIATE) ||
- (cred_usage == GSS_C_BOTH)) {
- if ((ret =
- acquire_init_cred(context, minor_status,
- cred->name?cred->name:(krb5_gss_name_t)desired_name,
- &cred->name, password, cred))
- != GSS_S_COMPLETE) {
- goto error_out;
- }
- } else if (cred->iakerb) {
- /* save the password for later. */
- krb5_data data;
-
- data.length = password->length;
- data.data = (char *)password->value;
-
- code = krb5int_copy_data_contents_add0(context, &data, &cred->password);
- if (code != 0) {
- *minor_status = code;
- ret = GSS_S_FAILURE;
+ if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
+ ret = acquire_init_cred(context, minor_status,
+ cred->name ?
+ cred->name : (krb5_gss_name_t)desired_name,
+ &cred->name, password, cred);
+ if (ret != GSS_S_COMPLETE)
goto error_out;
- }
}
/* if the princ wasn't filled in already, fill it in now */
- if (!cred->name && (desired_name != GSS_C_NO_NAME))
- if ((code = kg_duplicate_name(context,
- (krb5_gss_name_t)desired_name,
- 0, &cred->name))) {
- *minor_status = code;
- ret = GSS_S_FAILURE;
- goto error_out;
- }
+ if (!cred->name && (desired_name != GSS_C_NO_NAME)) {
+ code = kg_duplicate_name(context,
+ (krb5_gss_name_t)desired_name,
+ 0, &cred->name);
+ if (code != 0)
+ goto krb_error_out;
+ }
/*** at this point, the cred structure has been completely created */
@@ -658,11 +642,9 @@ acquire_cred(minor_status, desired_name, password, time_req,
} else {
krb5_timestamp now;
- if ((code = krb5_timeofday(context, &now))) {
- *minor_status = code;
- ret = GSS_S_FAILURE;
- goto error_out;
- }
+ code = krb5_timeofday(context, &now);
+ if (code != 0)
+ goto krb_error_out;
if (time_rec)
*time_rec = (cred->tgt_expire > now) ? (cred->tgt_expire - now) : 0;
@@ -703,6 +685,10 @@ acquire_cred(minor_status, desired_name, password, time_req,
krb5_free_context(context);
return(GSS_S_COMPLETE);
+krb_error_out:
+ *minor_status = code;
+ ret = GSS_S_FAILURE;
+
error_out:
if (ret_mechs != GSS_C_NO_OID_SET) {
free(ret_mechs->elements);
diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
index 1861795..9b47e1a 100644
--- a/src/lib/gssapi/krb5/iakerb.c
+++ b/src/lib/gssapi/krb5/iakerb.c
@@ -34,6 +34,8 @@
* IAKERB implementation
*/
+extern int gssint_get_der_length(unsigned char **, OM_uint32, unsigned int*);
+
struct _iakerb_ctx_id_rec {
krb5_magic magic;
krb5_context k5c;
@@ -151,7 +153,8 @@ iakerb_parse_token(iakerb_ctx_id_t ctx,
{
krb5_error_code code;
krb5_iakerb_header *iah = NULL;
- unsigned int bodysize;
+ unsigned int bodysize, lenlen;
+ int length;
unsigned char *ptr;
int flags = 0;
krb5_data data;
@@ -174,11 +177,21 @@ iakerb_parse_token(iakerb_ctx_id_t ctx,
goto cleanup;
data.data = (char *)ptr;
- data.length = der_read_length(&ptr, &bodysize);
- if (data.length < 0) {
+
+ if (bodysize-- == 0 || *ptr++ != 0x30 /* SEQUENCE */) {
+ code = ASN1_BAD_ID;
+ goto cleanup;
+ }
+
+ length = gssint_get_der_length(&ptr, bodysize, &lenlen);
+ if (length < 0 || bodysize - lenlen < (unsigned int)length) {
code = KRB5_BAD_MSIZE;
goto cleanup;
}
+ data.length = 1 /* SEQUENCE */ + lenlen + length;
+
+ ptr += length;
+ bodysize -= (lenlen + length);
code = decode_krb5_iakerb_header(&data, &iah);
if (code != 0)
@@ -197,6 +210,9 @@ iakerb_parse_token(iakerb_ctx_id_t ctx,
request->data = (char *)ptr;
request->length = bodysize;
+ assert(request->data + request->length ==
+ (char *)token->value + token->length);
+
cleanup:
krb5_free_iakerb_header(ctx->k5c, iah);
@@ -248,7 +264,7 @@ iakerb_make_token(iakerb_ctx_id_t ctx,
if (initialContextToken)
tokenSize = g_token_size(gss_mech_iakerb, data->length);
else
- tokenSize = 2;
+ tokenSize = 2 + data->length;
token->value = q = k5alloc(tokenSize, &code);
if (code != 0)
@@ -263,6 +279,9 @@ iakerb_make_token(iakerb_ctx_id_t ctx,
q += 2;
}
memcpy(q, data->data, data->length);
+ q += data->length;
+
+ assert(q == (unsigned char *)token->value + token->length);
cleanup:
krb5_free_data(ctx->k5c, data);
@@ -524,8 +543,11 @@ iakerb_gss_delete_sec_context(OM_uint32 *minor_status,
{
OM_uint32 major_status = GSS_S_COMPLETE;
- output_token->length = 0;
- output_token->value = NULL;
+ if (output_token != GSS_C_NO_BUFFER) {
+ output_token->length = 0;
+ output_token->value = NULL;
+ }
+
*minor_status = 0;
if (*context_handle != GSS_C_NO_CONTEXT) {
@@ -599,6 +621,10 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status,
major_status = GSS_S_DEFECTIVE_TOKEN;
if (code != 0)
goto cleanup;
+ if (initialContextToken) {
+ *context_handle = (gss_ctx_id_t)ctx;
+ ctx = NULL;
+ }
if (src_name != NULL)
*src_name = GSS_C_NO_NAME;
if (mech_type != NULL)
@@ -609,6 +635,7 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status,
*time_rec = 0;
if (delegated_cred_handle != NULL)
*delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+ major_status = GSS_S_CONTINUE_NEEDED;
}
cleanup:
@@ -668,6 +695,8 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,
goto cleanup;
}
+ major_status = GSS_S_FAILURE;
+
if (initialContextToken) {
code = iakerb_init_creds_ctx(ctx, kcred, (krb5_gss_name_t)target_name);
if (code != 0)
@@ -717,8 +746,10 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,
iakerb_release_context(ctx);
}
} else {
- if (initialContextToken)
+ if (initialContextToken) {
*context_handle = (gss_ctx_id_t)ctx;
+ ctx = NULL;
+ }
if (actual_mech_type != NULL)
*actual_mech_type = (gss_OID)gss_mech_iakerb;
if (ret_flags != NULL)