diff options
author | Luke Howard <lukeh@padl.com> | 2009-11-15 19:28:42 +0000 |
---|---|---|
committer | Luke Howard <lukeh@padl.com> | 2009-11-15 19:28:42 +0000 |
commit | b4b4978d7cdee45d7c6b1efd8737a6ede752ecda (patch) | |
tree | 48192c0a068c82a298b7c92dda30f617b4e357b3 | |
parent | d6ea15b9d969c0f4120abca0653cc7b516a2e754 (diff) | |
download | krb5-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.h | 2 | ||||
-rw-r--r-- | src/lib/gssapi/generic/util_token.c | 2 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/acquire_cred.c | 128 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/iakerb.c | 45 |
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) |