diff options
author | wyllys <none@none> | 2005-07-13 10:02:39 -0700 |
---|---|---|
committer | wyllys <none@none> | 2005-07-13 10:02:39 -0700 |
commit | 354d1447ce995f3923a8f53d41c49fd3e6543282 (patch) | |
tree | b3380cb1588026a43df9055acffff2ed4428a11a /usr/src/lib/libgss | |
parent | f3f5a4dd0d8a3e3659add4eeca8b25772c3b35a2 (diff) | |
download | illumos-gate-354d1447ce995f3923a8f53d41c49fd3e6543282.tar.gz |
6259944 call gss_acquire_cred() with SPNEGO OID, it returns GSS_S_COMPLETE but did not return any credential
6260520 Call gss_context_time() with a handle of an un-established SPNEGO context, it will core dump.
6285582 gss_add_cred() is broken when input_cred_handle == GSS_C_NO_CREDENTIAL, assumes GSS_C_NO_NAME
6287358 SPNEGO init_sec_context fails when given 'actual_mechs' parameter
6290437 gss_accept_sec_context needs better handling of delegated credentials
6293338 call gss_create_empty_oid_set() with oid_set=NULL, it will seg fault.
Diffstat (limited to 'usr/src/lib/libgss')
-rw-r--r-- | usr/src/lib/libgss/g_accept_sec_context.c | 180 | ||||
-rw-r--r-- | usr/src/lib/libgss/g_acquire_cred.c | 62 | ||||
-rw-r--r-- | usr/src/lib/libgss/g_inquire_cred.c | 41 | ||||
-rw-r--r-- | usr/src/lib/libgss/oid_ops.c | 33 |
4 files changed, 187 insertions, 129 deletions
diff --git a/usr/src/lib/libgss/g_accept_sec_context.c b/usr/src/lib/libgss/g_accept_sec_context.c index 442d472f47..cf2ed8696b 100644 --- a/usr/src/lib/libgss/g_accept_sec_context.c +++ b/usr/src/lib/libgss/g_accept_sec_context.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -63,7 +63,7 @@ OM_uint32 *time_rec; gss_cred_id_t *d_cred; /* delegated cred handle */ { - OM_uint32 status, temp_status, temp_minor_status; + OM_uint32 status, temp_status, t_minstat; 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; @@ -72,6 +72,8 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ gss_name_t tmp_src_name = GSS_C_NO_NAME; gss_OID_desc token_mech_type_desc; gss_OID token_mech_type = &token_mech_type_desc; + gss_OID actual_mech = GSS_C_NO_OID; + OM_uint32 flags; gss_mechanism mech; /* check parameters first */ @@ -119,7 +121,7 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ return (GSS_S_FAILURE); union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT; - status = generic_gss_copy_oid(&temp_minor_status, + status = generic_gss_copy_oid(&t_minstat, token_mech_type, &union_ctx_id->mech_type); if (status != GSS_S_COMPLETE) { @@ -158,9 +160,9 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ input_token_buffer, input_chan_bindings, &internal_name, - mech_type, + &actual_mech, output_token, - ret_flags, + &flags, time_rec, d_cred ? &tmp_d_cred : NULL); @@ -172,6 +174,9 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ if (status != GSS_S_COMPLETE) goto error_out; + if (mech_type != NULL) + *mech_type = actual_mech; + /* * if src_name is non-NULL, * convert internal_name into a union name equivalent @@ -181,18 +186,18 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ */ if (internal_name != NULL) { temp_status = __gss_convert_name_to_union_name( - &temp_minor_status, mech, + &t_minstat, mech, internal_name, &tmp_src_name); if (temp_status != GSS_S_COMPLETE) { - *minor_status = temp_minor_status; + *minor_status = t_minstat; if (output_token->length) (void) gss_release_buffer( - &temp_minor_status, + &t_minstat, output_token); if (internal_name != GSS_C_NO_NAME) mech->gss_release_name( mech->context, - &temp_minor_status, + &t_minstat, &internal_name); return (temp_status); } @@ -204,88 +209,107 @@ gss_cred_id_t *d_cred; /* delegated cred handle */ } /* Ensure we're returning correct creds format */ - if ((ret_flags && GSS_C_DELEG_FLAG) && - tmp_d_cred != GSS_C_NO_CREDENTIAL) { - gss_union_cred_t d_u_cred = NULL; - - d_u_cred = malloc(sizeof (gss_union_cred_desc)); - if (d_u_cred == NULL) { - status = GSS_S_FAILURE; - goto error_out; - } - (void) memset(d_u_cred, 0, - sizeof (gss_union_cred_desc)); + if ((flags & GSS_C_DELEG_FLAG) && + tmp_d_cred != GSS_C_NO_CREDENTIAL) { + /* + * If we got back an OID different from the original + * token OID, assume the delegated_cred is already + * a proper union_cred and just return it. Don't + * try to re-wrap it. This is for SPNEGO or other + * pseudo-mechanisms. + */ + if (actual_mech != GSS_C_NO_OID && + token_mech_type != GSS_C_NO_OID && + !g_OID_equal(actual_mech, token_mech_type)) { + *d_cred = tmp_d_cred; + } else { + gss_union_cred_t d_u_cred = NULL; - d_u_cred->count = 1; + d_u_cred = malloc(sizeof (gss_union_cred_desc)); + if (d_u_cred == NULL) { + status = GSS_S_FAILURE; + goto error_out; + } + (void) memset(d_u_cred, 0, + sizeof (gss_union_cred_desc)); - status = generic_gss_copy_oid(&temp_minor_status, - token_mech_type, - &d_u_cred->mechs_array); + d_u_cred->count = 1; - if (status != GSS_S_COMPLETE) { - free(d_u_cred); - goto error_out; - } + status = generic_gss_copy_oid( + &t_minstat, + actual_mech, + &d_u_cred->mechs_array); - d_u_cred->cred_array = malloc(sizeof (gss_cred_id_t)); - if (d_u_cred->cred_array != NULL) { - d_u_cred->cred_array[0] = tmp_d_cred; - } else { - free(d_u_cred); - status = GSS_S_FAILURE; - goto error_out; - } + if (status != GSS_S_COMPLETE) { + free(d_u_cred); + goto error_out; + } - if (status != GSS_S_COMPLETE) { - free(d_u_cred->cred_array); - free(d_u_cred); - goto error_out; - } + d_u_cred->cred_array = malloc( + sizeof (gss_cred_id_t)); + if (d_u_cred->cred_array != NULL) { + d_u_cred->cred_array[0] = tmp_d_cred; + } else { + free(d_u_cred); + status = GSS_S_FAILURE; + goto error_out; + } - internal_name = GSS_C_NO_NAME; + if (status != GSS_S_COMPLETE) { + free(d_u_cred->cred_array); + free(d_u_cred); + goto error_out; + } - d_u_cred->auxinfo.creation_time = time(0); - d_u_cred->auxinfo.time_rec = 0; + internal_name = GSS_C_NO_NAME; - if (mech->gss_inquire_cred) { - status = mech->gss_inquire_cred(mech->context, - minor_status, - tmp_d_cred, - &internal_name, - &d_u_cred->auxinfo.time_rec, - &d_u_cred->auxinfo.cred_usage, - NULL); - } + d_u_cred->auxinfo.creation_time = time(0); + d_u_cred->auxinfo.time_rec = 0; - if (internal_name != NULL) { - temp_status = __gss_convert_name_to_union_name( - &temp_minor_status, mech, - internal_name, &tmp_src_name); - if (temp_status != GSS_S_COMPLETE) { - *minor_status = temp_minor_status; - if (output_token->length) - (void) gss_release_buffer( - &temp_minor_status, - output_token); - free(d_u_cred->cred_array); - free(d_u_cred); - return (temp_status); + if (mech->gss_inquire_cred) { + status = mech->gss_inquire_cred( + mech->context, + minor_status, + tmp_d_cred, + &internal_name, + &d_u_cred->auxinfo.time_rec, + &d_u_cred->auxinfo.cred_usage, + NULL); } - } - if (tmp_src_name != NULL) { - status = gss_display_name( - &temp_minor_status, - tmp_src_name, - &d_u_cred->auxinfo.name, - &d_u_cred->auxinfo.name_type); - } + if (internal_name != NULL) { + temp_status = + __gss_convert_name_to_union_name( + &t_minstat, mech, + internal_name, &tmp_src_name); + if (temp_status != GSS_S_COMPLETE) { + *minor_status = t_minstat; + if (output_token->length) + (void) gss_release_buffer( + &t_minstat, + output_token); + free(d_u_cred->cred_array); + free(d_u_cred); + return (temp_status); + } + } - *d_cred = (gss_cred_id_t)d_u_cred; + if (tmp_src_name != NULL) { + status = gss_display_name( + &t_minstat, + tmp_src_name, + &d_u_cred->auxinfo.name, + &d_u_cred->auxinfo.name_type); + } + + *d_cred = (gss_cred_id_t)d_u_cred; + } + if (ret_flags != NULL) + *ret_flags = flags; } if (src_name == NULL && tmp_src_name != NULL) - (void) gss_release_name(&temp_minor_status, + (void) gss_release_name(&t_minstat, &tmp_src_name); return (status); } else { @@ -305,13 +329,13 @@ error_out: } if (output_token->length) - (void) gss_release_buffer(&temp_minor_status, output_token); + (void) gss_release_buffer(&t_minstat, output_token); if (src_name) *src_name = GSS_C_NO_NAME; if (tmp_src_name != GSS_C_NO_NAME) - (void) gss_release_buffer(&temp_minor_status, + (void) gss_release_buffer(&t_minstat, (gss_buffer_t)tmp_src_name); return (status); diff --git a/usr/src/lib/libgss/g_acquire_cred.c b/usr/src/lib/libgss/g_acquire_cred.c index a6ecd5a533..9fffa3c63d 100644 --- a/usr/src/lib/libgss/g_acquire_cred.c +++ b/usr/src/lib/libgss/g_acquire_cred.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,7 +29,6 @@ /* * glue routine for gss_acquire_cred */ - #include <mechglueP.h> #include <stdio.h> #ifdef HAVE_STDLIB_H @@ -274,33 +273,52 @@ 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 { + /* Input Cred is non-NULL */ union_cred = (gss_union_cred_t)input_cred_handle; + if (__gss_get_mechanism_cred(union_cred, desired_mech) != - GSS_C_NO_CREDENTIAL) - return (GSS_S_DUPLICATE_ELEMENT); + GSS_C_NO_CREDENTIAL) { + status = GSS_S_DUPLICATE_ELEMENT; + goto errout; + } - /* may need to create a mechanism specific name */ - if (desired_name) { - union_name = (gss_union_name_t)desired_name; - if (union_name->mech_type && - g_OID_equal(union_name->mech_type, - &mech->mech_type)) - internal_name = union_name->mech_name; - else { - if (__gss_import_internal_name(minor_status, - &mech->mech_type, union_name, - &allocated_name) != GSS_S_COMPLETE) - return (GSS_S_BAD_NAME); + /* + * If no name was given, determine the name from the + * existing credential. + */ + if (desired_name == GSS_C_NO_NAME) { + if (gss_import_name(minor_status, + &union_cred->auxinfo.name, + union_cred->auxinfo.name_type, + &allocated_name) == GSS_S_COMPLETE && + (gss_canonicalize_name(minor_status, + allocated_name, + &mech->mech_type, + NULL) == GSS_S_COMPLETE)) { internal_name = allocated_name; } + } /* else, get the name from the desired_name below */ + } + if (desired_name != GSS_C_NO_NAME) { + /* may need to create a mechanism specific name */ + union_name = (gss_union_name_t)desired_name; + + if (union_name->mech_type && + g_OID_equal(union_name->mech_type, + &mech->mech_type)) + internal_name = union_name->mech_name; + else { + if (__gss_import_internal_name(minor_status, + &mech->mech_type, union_name, + &allocated_name) != GSS_S_COMPLETE) { + status = GSS_S_BAD_NAME; + goto errout; + } + internal_name = allocated_name; } } - if (cred_usage == GSS_C_ACCEPT) time_req = acceptor_time_req; else if (cred_usage == GSS_C_INITIATE) @@ -317,7 +335,7 @@ gss_add_cred(minor_status, input_cred_handle, if (status != GSS_S_COMPLETE) goto errout; - /* may need to set credential auxinfo strucutre */ + /* may need to set credential auxinfo structure */ if (union_cred->auxinfo.creation_time == 0) { union_cred->auxinfo.creation_time = time(NULL); union_cred->auxinfo.time_rec = time_rec; @@ -327,7 +345,7 @@ gss_add_cred(minor_status, input_cred_handle, * we must set the name; if name is not supplied * we must do inquire cred to get it */ - if (internal_name == NULL) { + if (internal_name == GSS_C_NO_NAME) { if (mech->gss_inquire_cred == NULL || ((status = mech->gss_inquire_cred( mech->context, diff --git a/usr/src/lib/libgss/g_inquire_cred.c b/usr/src/lib/libgss/g_inquire_cred.c index 78fc641b74..f7b4d025c4 100644 --- a/usr/src/lib/libgss/g_inquire_cred.c +++ b/usr/src/lib/libgss/g_inquire_cred.c @@ -20,7 +20,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -234,26 +234,31 @@ gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name, if (mech_cred == NULL) return (GSS_S_DEFECTIVE_CREDENTIAL); - status = mech->gss_inquire_cred_by_mech(mech->context, minor_status, - mech_cred, mech_type, - name ? &internal_name : NULL, - initiator_lifetime, - acceptor_lifetime, cred_usage); - - if (status != GSS_S_COMPLETE) - return (status); + if (mech->gss_inquire_cred_by_mech != NULL) { + status = mech->gss_inquire_cred_by_mech(mech->context, + minor_status, + mech_cred, mech_type, + name ? &internal_name : NULL, + initiator_lifetime, + acceptor_lifetime, cred_usage); - if (name) { - /* - * Convert internal_name into a union_name equivalent. - */ - status = __gss_convert_name_to_union_name( - &temp_minor_status, mech, - internal_name, name); - if (status != GSS_S_COMPLETE) { - *minor_status = temp_minor_status; + if (status != GSS_S_COMPLETE) return (status); + + if (name) { + /* + * Convert internal_name into a union_name equivalent. + */ + status = __gss_convert_name_to_union_name( + &temp_minor_status, mech, + internal_name, name); + if (status != GSS_S_COMPLETE) { + *minor_status = temp_minor_status; + return (status); + } } + } else { + return (GSS_S_UNAVAILABLE); } return (GSS_S_COMPLETE); diff --git a/usr/src/lib/libgss/oid_ops.c b/usr/src/lib/libgss/oid_ops.c index 135b45deea..3e806b510b 100644 --- a/usr/src/lib/libgss/oid_ops.c +++ b/usr/src/lib/libgss/oid_ops.c @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -103,6 +103,12 @@ generic_gss_copy_oid(minor_status, oid, new_oid) if (minor_status) *minor_status = 0; + if (new_oid == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + + if (oid == GSS_C_NO_OID) + return (GSS_S_CALL_INACCESSIBLE_READ); + p = (gss_OID) malloc(sizeof (gss_OID_desc)); if (!p) { return (GSS_S_FAILURE); @@ -127,6 +133,9 @@ gss_OID_set *oid_set; if (minor_status) *minor_status = 0; + if (oid_set == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + if ((*oid_set = (gss_OID_set) malloc(sizeof (gss_OID_set_desc)))) { (void) memset(*oid_set, 0, sizeof (gss_OID_set_desc)); return (GSS_S_COMPLETE); @@ -147,30 +156,34 @@ gss_OID_set *oid_set; if (minor_status) *minor_status = 0; - if (member_oid == NULL || member_oid->length == 0 || + if (member_oid == GSS_C_NO_OID || member_oid->length == 0 || member_oid->elements == NULL) return (GSS_S_CALL_INACCESSIBLE_READ); + if (oid_set == NULL) + return (GSS_S_CALL_INACCESSIBLE_WRITE); + elist = (*oid_set)->elements; /* Get an enlarged copy of the array */ if (((*oid_set)->elements = (gss_OID) malloc(((*oid_set)->count+1) * sizeof (gss_OID_desc)))) { - /* Copy in the old junk */ + /* Copy in the old junk */ if (elist) (void) memcpy((*oid_set)->elements, elist, ((*oid_set)->count * sizeof (gss_OID_desc))); - /* Duplicate the input element */ + /* Duplicate the input element */ lastel = &(*oid_set)->elements[(*oid_set)->count]; if ((lastel->elements = (void *) malloc(member_oid->length))) { - /* Success - copy elements */ + + /* Success - copy elements */ (void) memcpy(lastel->elements, member_oid->elements, member_oid->length); - /* Set length */ + /* Set length */ lastel->length = member_oid->length; - /* Update count */ + /* Update count */ (*oid_set)->count++; if (elist) free(elist); @@ -196,7 +209,7 @@ generic_gss_test_oid_set_member(minor_status, member, set, present) if (minor_status) *minor_status = 0; - if (member == NULL || set == NULL) + if (member == GSS_C_NO_OID || set == NULL) return (GSS_S_CALL_INACCESSIBLE_READ); if (present == NULL) @@ -235,14 +248,12 @@ gss_buffer_t oid_str; if (minor_status) *minor_status = 0; - if (oid == NULL || oid->length == 0 || oid->elements == NULL) + if (oid == GSS_C_NO_OID || oid->length == 0 || oid->elements == NULL) return (GSS_S_CALL_INACCESSIBLE_READ); if (oid_str == NULL) return (GSS_S_CALL_INACCESSIBLE_WRITE); - /* Decoded according to krb5/gssapi_krb5.c */ - /* First determine the size of the string */ string_length = 0; number = 0; |