summaryrefslogtreecommitdiff
path: root/usr/src/lib/libgss
diff options
context:
space:
mode:
authorwyllys <none@none>2005-07-13 10:02:39 -0700
committerwyllys <none@none>2005-07-13 10:02:39 -0700
commit354d1447ce995f3923a8f53d41c49fd3e6543282 (patch)
treeb3380cb1588026a43df9055acffff2ed4428a11a /usr/src/lib/libgss
parentf3f5a4dd0d8a3e3659add4eeca8b25772c3b35a2 (diff)
downloadillumos-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.c180
-rw-r--r--usr/src/lib/libgss/g_acquire_cred.c62
-rw-r--r--usr/src/lib/libgss/g_inquire_cred.c41
-rw-r--r--usr/src/lib/libgss/oid_ops.c33
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;