aboutsummaryrefslogtreecommitdiff
path: root/lib/libgssapi
diff options
context:
space:
mode:
authorDoug Rabson <dfr@FreeBSD.org>2008-05-07 13:53:12 +0000
committerDoug Rabson <dfr@FreeBSD.org>2008-05-07 13:53:12 +0000
commit33f12199250a09b573f7a518b523fdac3f120b8f (patch)
tree1338a6c0e5d3e7c3b0da720ac15cd79fc72c6b5a /lib/libgssapi
parent4fe54d7c6acb302aacc6ac18798804b26c882c13 (diff)
downloadsrc-33f12199250a09b573f7a518b523fdac3f120b8f.tar.gz
src-33f12199250a09b573f7a518b523fdac3f120b8f.zip
Fix conflicts after heimdal-1.1 import and add build infrastructure. Import
all non-style changes made by heimdal to our own libgssapi.
Notes
Notes: svn path=/head/; revision=178828
Diffstat (limited to 'lib/libgssapi')
-rw-r--r--lib/libgssapi/Makefile81
-rw-r--r--lib/libgssapi/Symbol.map69
-rw-r--r--lib/libgssapi/context.h1
-rw-r--r--lib/libgssapi/cred.h1
-rw-r--r--lib/libgssapi/gss_accept_sec_context.c222
-rw-r--r--lib/libgssapi/gss_acquire_cred.c29
-rw-r--r--lib/libgssapi/gss_add_cred.c46
-rw-r--r--lib/libgssapi/gss_buffer_set.c126
-rw-r--r--lib/libgssapi/gss_canonicalize_name.c11
-rw-r--r--lib/libgssapi/gss_compare_name.c11
-rw-r--r--lib/libgssapi/gss_create_empty_oid_set.c2
-rw-r--r--lib/libgssapi/gss_decapsulate_token.c107
-rw-r--r--lib/libgssapi/gss_delete_sec_context.c9
-rw-r--r--lib/libgssapi/gss_display_name.c10
-rw-r--r--lib/libgssapi/gss_display_status.c193
-rw-r--r--lib/libgssapi/gss_duplicate_name.c40
-rw-r--r--lib/libgssapi/gss_duplicate_oid.c65
-rw-r--r--lib/libgssapi/gss_encapsulate_token.c131
-rw-r--r--lib/libgssapi/gss_export_name.c9
-rw-r--r--lib/libgssapi/gss_export_sec_context.c6
-rw-r--r--lib/libgssapi/gss_get_mic.c7
-rw-r--r--lib/libgssapi/gss_import_name.c28
-rw-r--r--lib/libgssapi/gss_import_sec_context.c3
-rw-r--r--lib/libgssapi/gss_indicate_mechs.c8
-rw-r--r--lib/libgssapi/gss_init_sec_context.c63
-rw-r--r--lib/libgssapi/gss_inquire_context.c33
-rw-r--r--lib/libgssapi/gss_inquire_cred.c73
-rw-r--r--lib/libgssapi/gss_inquire_cred_by_mech.c24
-rw-r--r--lib/libgssapi/gss_inquire_cred_by_oid.c93
-rw-r--r--lib/libgssapi/gss_inquire_mechs_for_name.c2
-rw-r--r--lib/libgssapi/gss_inquire_names_for_mech.c9
-rw-r--r--lib/libgssapi/gss_inquire_sec_context_by_oid.c60
-rw-r--r--lib/libgssapi/gss_mech_switch.c54
-rw-r--r--lib/libgssapi/gss_names.c46
-rw-r--r--lib/libgssapi/gss_oid_to_str.c118
-rw-r--r--lib/libgssapi/gss_pseudo_random.c72
-rw-r--r--lib/libgssapi/gss_release_buffer.c6
-rw-r--r--lib/libgssapi/gss_release_cred.c2
-rw-r--r--lib/libgssapi/gss_release_name.c4
-rw-r--r--lib/libgssapi/gss_release_oid.c61
-rw-r--r--lib/libgssapi/gss_release_oid_set.c4
-rw-r--r--lib/libgssapi/gss_set_cred_option.c125
-rw-r--r--lib/libgssapi/gss_set_sec_context_option.c92
-rw-r--r--lib/libgssapi/gss_test_oid_set_member.c4
-rw-r--r--lib/libgssapi/gss_unseal.c2
-rw-r--r--lib/libgssapi/gss_utils.c4
-rw-r--r--lib/libgssapi/gss_verify.c3
-rw-r--r--lib/libgssapi/gss_verify_mic.c7
-rw-r--r--lib/libgssapi/gss_wrap.c9
-rw-r--r--lib/libgssapi/gss_wrap_size_limit.c6
-rw-r--r--lib/libgssapi/mech.59
-rw-r--r--lib/libgssapi/mech_switch.h53
-rw-r--r--lib/libgssapi/name.h7
-rw-r--r--lib/libgssapi/utils.h2
54 files changed, 1930 insertions, 332 deletions
diff --git a/lib/libgssapi/Makefile b/lib/libgssapi/Makefile
index cedc4243576f..5d4fef39e3ec 100644
--- a/lib/libgssapi/Makefile
+++ b/lib/libgssapi/Makefile
@@ -1,51 +1,64 @@
# $FreeBSD$
LIB= gssapi
-SHLIB_MAJOR= 9
+SHLIB_MAJOR= 10
+WARNS= 6
+VERSION_DEF= ${.CURDIR}/../libc/Versions.def
+SYMBOL_MAPS= ${.CURDIR}/Symbol.map
SRCS=
-SRCS+= gss_utils.c
-SRCS+= gss_mech_switch.c
-SRCS+= gss_names.c
-SRCS+= gss_acquire_cred.c
-SRCS+= gss_release_cred.c
-SRCS+= gss_init_sec_context.c
SRCS+= gss_accept_sec_context.c
-SRCS+= gss_process_context_token.c
-SRCS+= gss_delete_sec_context.c
-SRCS+= gss_context_time.c
-SRCS+= gss_get_mic.c
-SRCS+= gss_verify_mic.c
-SRCS+= gss_wrap.c
-SRCS+= gss_unwrap.c
-SRCS+= gss_display_status.c
-SRCS+= gss_indicate_mechs.c
+SRCS+= gss_acquire_cred.c
+SRCS+= gss_add_cred.c
+SRCS+= gss_add_oid_set_member.c
+SRCS+= gss_buffer_set.c
+SRCS+= gss_canonicalize_name.c
SRCS+= gss_compare_name.c
+SRCS+= gss_context_time.c
+SRCS+= gss_create_empty_oid_set.c
+SRCS+= gss_decapsulate_token.c
+SRCS+= gss_delete_sec_context.c
SRCS+= gss_display_name.c
-SRCS+= gss_import_name.c
+SRCS+= gss_display_status.c
+SRCS+= gss_duplicate_name.c
+SRCS+= gss_duplicate_oid.c
+SRCS+= gss_encapsulate_token.c
SRCS+= gss_export_name.c
-SRCS+= gss_release_name.c
-SRCS+= gss_inquire_cred.c
-SRCS+= gss_inquire_context.c
-SRCS+= gss_wrap_size_limit.c
-SRCS+= gss_add_cred.c
-SRCS+= gss_inquire_cred_by_mech.c
SRCS+= gss_export_sec_context.c
+SRCS+= gss_get_mic.c
+SRCS+= gss_import_name.c
SRCS+= gss_import_sec_context.c
-SRCS+= gss_inquire_names_for_mech.c
+SRCS+= gss_indicate_mechs.c
+SRCS+= gss_init_sec_context.c
+SRCS+= gss_inquire_context.c
+SRCS+= gss_inquire_cred.c
+SRCS+= gss_inquire_cred_by_mech.c
+SRCS+= gss_inquire_cred_by_oid.c
SRCS+= gss_inquire_mechs_for_name.c
-SRCS+= gss_canonicalize_name.c
-SRCS+= gss_duplicate_name.c
-SRCS+= gss_sign.c
-SRCS+= gss_verify.c
+SRCS+= gss_inquire_names_for_mech.c
+SRCS+= gss_inquire_sec_context_by_oid.c
+SRCS+= gss_mech_switch.c
+SRCS+= gss_names.c
+SRCS+= gss_oid_to_str.c
+SRCS+= gss_process_context_token.c
+SRCS+= gss_pseudo_random.c
+SRCS+= gss_release_buffer.c
+SRCS+= gss_release_cred.c
+SRCS+= gss_release_name.c
+SRCS+= gss_release_oid.c
+SRCS+= gss_release_oid_set.c
SRCS+= gss_seal.c
-SRCS+= gss_unseal.c
-SRCS+= gss_krb5.c
-SRCS+= gss_create_empty_oid_set.c
-SRCS+= gss_add_oid_set_member.c
+SRCS+= gss_set_cred_option.c
+SRCS+= gss_set_sec_context_option.c
+SRCS+= gss_sign.c
SRCS+= gss_test_oid_set_member.c
-SRCS+= gss_release_oid_set.c
-SRCS+= gss_release_buffer.c
+SRCS+= gss_unseal.c
+SRCS+= gss_unwrap.c
+SRCS+= gss_utils.c
+SRCS+= gss_verify.c
+SRCS+= gss_verify_mic.c
+SRCS+= gss_wrap.c
+SRCS+= gss_wrap_size_limit.c
MAN=
MAN+= gssapi.3
diff --git a/lib/libgssapi/Symbol.map b/lib/libgssapi/Symbol.map
new file mode 100644
index 000000000000..d2746da3653d
--- /dev/null
+++ b/lib/libgssapi/Symbol.map
@@ -0,0 +1,69 @@
+/*
+ * $FreeBSD$
+ */
+
+FBSD_1.1 {
+ GSS_C_NT_ANONYMOUS;
+ GSS_C_NT_EXPORT_NAME;
+ GSS_C_NT_HOSTBASED_SERVICE;
+ GSS_C_NT_HOSTBASED_SERVICE_X;
+ GSS_C_NT_MACHINE_UID_NAME;
+ GSS_C_NT_STRING_UID_NAME;
+ GSS_C_NT_USER_NAME;
+ GSS_KRB5_NT_MACHINE_UID_NAME;
+ GSS_KRB5_NT_PRINCIPAL_NAME;
+ GSS_KRB5_NT_STRING_UID_NAME;
+ GSS_KRB5_NT_USER_NAME;
+ gss_accept_sec_context;
+ gss_acquire_cred;
+ gss_add_buffer_set_member;
+ gss_add_cred;
+ gss_add_oid_set_member;
+ gss_canonicalize_name;
+ gss_compare_name;
+ gss_context_time;
+ gss_create_empty_buffer_set;
+ gss_create_empty_oid_set;
+ gss_decapsulate_token;
+ gss_delete_sec_context;
+ gss_display_name;
+ gss_display_status;
+ gss_duplicate_name;
+ gss_duplicate_oid;
+ gss_encapsulate_token;
+ gss_export_name;
+ gss_export_sec_context;
+ gss_get_mic;
+ gss_import_name;
+ gss_import_sec_context;
+ gss_indicate_mechs;
+ gss_init_sec_context;
+ gss_inquire_context;
+ gss_inquire_cred;
+ gss_inquire_cred_by_mech;
+ gss_inquire_cred_by_oid;
+ gss_inquire_mechs_for_name;
+ gss_inquire_names_for_mech;
+ gss_inquire_sec_context_by_oid;
+ gss_oid_equal;
+ gss_oid_to_str;
+ gss_process_context_token;
+ gss_pseudo_random;
+ gss_release_buffer;
+ gss_release_buffer_set;
+ gss_release_cred;
+ gss_release_name;
+ gss_release_oid;
+ gss_release_oid_set;
+ gss_seal;
+ gss_set_cred_option;
+ gss_set_sec_context_option;
+ gss_sign;
+ gss_test_oid_set_member;
+ gss_unseal;
+ gss_unwrap;
+ gss_verify;
+ gss_verify_mic;
+ gss_wrap;
+ gss_wrap_size_limit;
+};
diff --git a/lib/libgssapi/context.h b/lib/libgssapi/context.h
index 403b3909ca9f..ac162aa1d6ac 100644
--- a/lib/libgssapi/context.h
+++ b/lib/libgssapi/context.h
@@ -30,3 +30,4 @@ struct _gss_context {
struct _gss_mech_switch *gc_mech;
gss_ctx_id_t gc_ctx;
};
+
diff --git a/lib/libgssapi/cred.h b/lib/libgssapi/cred.h
index 6301b895b59c..e6fed6f88b93 100644
--- a/lib/libgssapi/cred.h
+++ b/lib/libgssapi/cred.h
@@ -37,7 +37,6 @@ struct _gss_mechanism_cred {
SLIST_HEAD(_gss_mechanism_cred_list, _gss_mechanism_cred);
struct _gss_cred {
- gss_cred_usage_t gc_usage;
struct _gss_mechanism_cred_list gc_mc;
};
diff --git a/lib/libgssapi/gss_accept_sec_context.c b/lib/libgssapi/gss_accept_sec_context.c
index 62a3bdadfa89..b4240920c59e 100644
--- a/lib/libgssapi/gss_accept_sec_context.c
+++ b/lib/libgssapi/gss_accept_sec_context.c
@@ -35,6 +35,116 @@
#include "context.h"
#include "cred.h"
#include "name.h"
+#include "utils.h"
+
+static OM_uint32
+parse_header(const gss_buffer_t input_token, gss_OID mech_oid)
+{
+ unsigned char *p = input_token->value;
+ size_t len = input_token->length;
+ size_t a, b;
+
+ /*
+ * Token must start with [APPLICATION 0] SEQUENCE.
+ * But if it doesn't assume it is DCE-STYLE Kerberos!
+ */
+ if (len == 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ p++;
+ len--;
+
+ /*
+ * Decode the length and make sure it agrees with the
+ * token length.
+ */
+ if (len == 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if ((*p & 0x80) == 0) {
+ a = *p;
+ p++;
+ len--;
+ } else {
+ b = *p & 0x7f;
+ p++;
+ len--;
+ if (len < b)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ a = 0;
+ while (b) {
+ a = (a << 8) | *p;
+ p++;
+ len--;
+ b--;
+ }
+ }
+ if (a != len)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /*
+ * Decode the OID for the mechanism. Simplify life by
+ * assuming that the OID length is less than 128 bytes.
+ */
+ if (len < 2 || *p != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if ((p[1] & 0x80) || p[1] > (len - 2))
+ return (GSS_S_DEFECTIVE_TOKEN);
+ mech_oid->length = p[1];
+ p += 2;
+ len -= 2;
+ mech_oid->elements = p;
+
+ return (GSS_S_COMPLETE);
+}
+
+static gss_OID_desc krb5_mechanism =
+{9, (void *)(uintptr_t) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
+static gss_OID_desc ntlm_mechanism =
+{10, (void *)(uintptr_t) "\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"};
+static gss_OID_desc spnego_mechanism =
+{6, (void *)(uintptr_t) "\x2b\x06\x01\x05\x05\x02"};
+
+static OM_uint32
+choose_mech(const gss_buffer_t input, gss_OID mech_oid)
+{
+ OM_uint32 status;
+
+ /*
+ * First try to parse the gssapi token header and see if it's a
+ * correct header, use that in the first hand.
+ */
+
+ status = parse_header(input, mech_oid);
+ if (status == GSS_S_COMPLETE)
+ return (GSS_S_COMPLETE);
+
+ /*
+ * Lets guess what mech is really is, callback function to mech ??
+ */
+
+ if (input->length > 8 &&
+ memcmp((const char *)input->value, "NTLMSSP\x00", 8) == 0)
+ {
+ *mech_oid = ntlm_mechanism;
+ return (GSS_S_COMPLETE);
+ } else if (input->length != 0 &&
+ ((const char *)input->value)[0] == 0x6E)
+ {
+ /* Could be a raw AP-REQ (check for APPLICATION tag) */
+ *mech_oid = krb5_mechanism;
+ return (GSS_S_COMPLETE);
+ } else if (input->length == 0) {
+ /*
+ * There is the a wierd mode of SPNEGO (in CIFS and
+ * SASL GSS-SPENGO where the first token is zero
+ * length and the acceptor returns a mech_list, lets
+ * hope that is what is happening now.
+ */
+ *mech_oid = spnego_mechanism;
+ return (GSS_S_COMPLETE);
+ }
+ return (status);
+}
OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
@@ -58,71 +168,28 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
int allocated_ctx;
*minor_status = 0;
- if (src_name) *src_name = 0;
- if (mech_type) *mech_type = 0;
- if (ret_flags) *ret_flags = 0;
- if (time_rec) *time_rec = 0;
- if (delegated_cred_handle) *delegated_cred_handle = 0;
- output_token->length = 0;
- output_token->value = 0;
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = 0;
+ if (delegated_cred_handle)
+ *delegated_cred_handle = GSS_C_NO_CREDENTIAL;
+ _gss_buffer_zero(output_token);
/*
* If this is the first call (*context_handle is NULL), we must
* parse the input token to figure out the mechanism to use.
*/
if (*context_handle == GSS_C_NO_CONTEXT) {
- unsigned char *p = input_token->value;
- size_t len = input_token->length;
- size_t a, b;
gss_OID_desc mech_oid;
- /*
- * Token must start with [APPLICATION 0] SEQUENCE.
- */
- if (len == 0 || *p != 0x60)
- return (GSS_S_DEFECTIVE_TOKEN);
- p++;
- len--;
-
- /*
- * Decode the length and make sure it agrees with the
- * token length.
- */
- if (len == 0)
- return (GSS_S_DEFECTIVE_TOKEN);
- if ((*p & 0x80) == 0) {
- a = *p;
- p++;
- len--;
- } else {
- b = *p & 0x7f;
- p++;
- len--;
- if (len < b)
- return (GSS_S_DEFECTIVE_TOKEN);
- a = 0;
- while (b) {
- a = (a << 8) | *p;
- p++;
- len--;
- b--;
- }
- }
- if (a != len)
- return (GSS_S_DEFECTIVE_TOKEN);
-
- /*
- * Decode the OID for the mechanism. Simplify life by
- * assuming that the OID length is less than 128 bytes.
- */
- if (len < 2 || *p != 0x06)
- return (GSS_S_DEFECTIVE_TOKEN);
- if ((p[1] & 0x80) || p[1] > (len - 2))
- return (GSS_S_DEFECTIVE_TOKEN);
- mech_oid.length = p[1];
- p += 2;
- len -= 2;
- mech_oid.elements = p;
+ major_status = choose_mech(input_token, &mech_oid);
+ if (major_status != GSS_S_COMPLETE)
+ return (major_status);
/*
* Now that we have a mechanism, we can find the
@@ -157,6 +224,7 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
}
delegated_mc = GSS_C_NO_CREDENTIAL;
+ mech_ret_flags = 0;
major_status = m->gm_accept_sec_context(minor_status,
&ctx->gc_ctx,
acceptor_mc,
@@ -169,12 +237,12 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
time_rec,
&delegated_mc);
if (major_status != GSS_S_COMPLETE &&
- major_status != GSS_S_CONTINUE_NEEDED)
+ major_status != GSS_S_CONTINUE_NEEDED) {
+ _gss_mg_error(m, major_status, *minor_status);
return (major_status);
+ }
- if (!src_name) {
- m->gm_release_name(minor_status, &src_mn);
- } else {
+ if (src_name && src_mn) {
/*
* Make a new name and mark it as an MN.
*/
@@ -185,6 +253,8 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
return (GSS_S_FAILURE);
}
*src_name = (gss_name_t) name;
+ } else if (src_mn) {
+ m->gm_release_name(minor_status, &src_mn);
}
if (delegated_mc == GSS_C_NO_CREDENTIAL)
@@ -195,29 +265,27 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
m->gm_release_cred(minor_status, &delegated_mc);
mech_ret_flags &= ~GSS_C_DELEG_FLAG;
} else {
- struct _gss_cred *cred;
- struct _gss_mechanism_cred *mc;
+ struct _gss_cred *dcred;
+ struct _gss_mechanism_cred *dmc;
- cred = malloc(sizeof(struct _gss_cred));
- if (!cred) {
+ dcred = malloc(sizeof(struct _gss_cred));
+ if (!dcred) {
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
- SLIST_INIT(&cred->gc_mc);
- mc = malloc(sizeof(struct _gss_mechanism_cred));
- if (!mc) {
- free(cred);
+ SLIST_INIT(&dcred->gc_mc);
+ dmc = malloc(sizeof(struct _gss_mechanism_cred));
+ if (!dmc) {
+ free(dcred);
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
- m->gm_inquire_cred(minor_status, delegated_mc,
- 0, 0, &cred->gc_usage, 0);
- mc->gmc_mech = m;
- mc->gmc_mech_oid = &m->gm_mech_oid;
- mc->gmc_cred = delegated_mc;
- SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
-
- *delegated_cred_handle = (gss_cred_id_t) cred;
+ dmc->gmc_mech = m;
+ dmc->gmc_mech_oid = &m->gm_mech_oid;
+ dmc->gmc_cred = delegated_mc;
+ SLIST_INSERT_HEAD(&dcred->gc_mc, dmc, gmc_link);
+
+ *delegated_cred_handle = (gss_cred_id_t) dcred;
}
}
diff --git a/lib/libgssapi/gss_acquire_cred.c b/lib/libgssapi/gss_acquire_cred.c
index ba8b8b1e4c49..f6ae4d1f700c 100644
--- a/lib/libgssapi/gss_acquire_cred.c
+++ b/lib/libgssapi/gss_acquire_cred.c
@@ -52,14 +52,23 @@ gss_acquire_cred(OM_uint32 *minor_status,
struct _gss_cred *cred;
struct _gss_mechanism_cred *mc;
struct _gss_mechanism_name *mn;
- OM_uint32 min_time, time;
- int i;
+ OM_uint32 min_time, cred_time;
+ size_t i;
+
+ *minor_status = 0;
+ if (output_cred_handle)
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+ if (actual_mechs)
+ *actual_mechs = GSS_C_NO_OID_SET;
+ if (time_rec)
+ *time_rec = 0;
+
+ _gss_load_mech();
/*
* First make sure that at least one of the requested
* mechanisms is one that we support.
*/
- _gss_load_mech();
if (mechs) {
for (i = 0; i < mechs->count; i++) {
int t;
@@ -69,7 +78,6 @@ gss_acquire_cred(OM_uint32 *minor_status,
break;
}
if (i == mechs->count) {
- *output_cred_handle = 0;
*minor_status = 0;
return (GSS_S_BAD_MECH);
}
@@ -91,7 +99,6 @@ gss_acquire_cred(OM_uint32 *minor_status,
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
- cred->gc_usage = cred_usage;
SLIST_INIT(&cred->gc_mc);
set.count = 1;
@@ -102,8 +109,9 @@ gss_acquire_cred(OM_uint32 *minor_status,
continue;
if (desired_name != GSS_C_NO_NAME) {
- mn = _gss_find_mn(name, &mechs->elements[i]);
- if (!mn)
+ major_status = _gss_find_mn(minor_status, name,
+ &mechs->elements[i], &mn);
+ if (major_status != GSS_S_COMPLETE)
continue;
}
@@ -122,13 +130,13 @@ gss_acquire_cred(OM_uint32 *minor_status,
(desired_name != GSS_C_NO_NAME
? mn->gmn_name : GSS_C_NO_NAME),
time_req, &set, cred_usage,
- &mc->gmc_cred, NULL, &time);
+ &mc->gmc_cred, NULL, &cred_time);
if (major_status) {
free(mc);
continue;
}
- if (time < min_time)
- min_time = time;
+ if (cred_time < min_time)
+ min_time = cred_time;
if (actual_mechs) {
major_status = gss_add_oid_set_member(minor_status,
@@ -152,7 +160,6 @@ gss_acquire_cred(OM_uint32 *minor_status,
free(cred);
if (actual_mechs)
gss_release_oid_set(minor_status, actual_mechs);
- *output_cred_handle = 0;
*minor_status = 0;
return (GSS_S_NO_CRED);
}
diff --git a/lib/libgssapi/gss_add_cred.c b/lib/libgssapi/gss_add_cred.c
index 61756078c0e7..4dcca18a3251 100644
--- a/lib/libgssapi/gss_add_cred.c
+++ b/lib/libgssapi/gss_add_cred.c
@@ -33,6 +33,7 @@
#include "mech_switch.h"
#include "cred.h"
#include "name.h"
+#include "utils.h"
static struct _gss_mechanism_cred *
_gss_copy_cred(struct _gss_mechanism_cred *mc)
@@ -48,8 +49,10 @@ _gss_copy_cred(struct _gss_mechanism_cred *mc)
major_status = m->gm_inquire_cred_by_mech(&minor_status,
mc->gmc_cred, mc->gmc_mech_oid,
&name, &initiator_lifetime, &acceptor_lifetime, &cred_usage);
- if (major_status)
+ if (major_status) {
+ _gss_mg_error(m, major_status, minor_status);
return (0);
+ }
major_status = m->gm_add_cred(&minor_status,
GSS_C_NO_CREDENTIAL, name, mc->gmc_mech_oid,
@@ -57,8 +60,10 @@ _gss_copy_cred(struct _gss_mechanism_cred *mc)
&cred, 0, 0, 0);
m->gm_release_name(&minor_status, &name);
- if (major_status)
+ if (major_status) {
+ _gss_mg_error(m, major_status, minor_status);
return (0);
+ }
new_mc = malloc(sizeof(struct _gss_mechanism_cred));
if (!new_mc) {
@@ -87,24 +92,27 @@ gss_add_cred(OM_uint32 *minor_status,
{
OM_uint32 major_status;
struct _gss_mech_switch *m;
- gss_OID_set_desc set;
- struct _gss_name *name = (struct _gss_name *) desired_name;
struct _gss_cred *cred = (struct _gss_cred *) input_cred_handle;
struct _gss_cred *new_cred;
+ gss_cred_id_t release_cred;
struct _gss_mechanism_cred *mc, *target_mc, *copy_mc;
struct _gss_mechanism_name *mn;
- OM_uint32 min_time, time, junk;
- int i;
+ OM_uint32 junk;
- *output_cred_handle = 0;
*minor_status = 0;
+ *output_cred_handle = GSS_C_NO_CREDENTIAL;
+ if (initiator_time_rec)
+ *initiator_time_rec = 0;
+ if (acceptor_time_rec)
+ *acceptor_time_rec = 0;
+ if (actual_mechs)
+ *actual_mechs = GSS_C_NO_OID_SET;
new_cred = malloc(sizeof(struct _gss_cred));
if (!new_cred) {
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
- new_cred->gc_usage = cred_usage;
SLIST_INIT(&new_cred->gc_mc);
/*
@@ -116,12 +124,13 @@ gss_add_cred(OM_uint32 *minor_status,
target_mc = 0;
if (cred) {
SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
- if (_gss_oid_equal(mc->gmc_mech, desired_mech)) {
+ if (gss_oid_equal(mc->gmc_mech_oid, desired_mech)) {
target_mc = mc;
}
copy_mc = _gss_copy_cred(mc);
if (!copy_mc) {
- gss_release_cred(&junk, (gss_cred_id_t*) &new_cred);
+ release_cred = (gss_cred_id_t) new_cred;
+ gss_release_cred(&junk, &release_cred);
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
@@ -133,11 +142,13 @@ gss_add_cred(OM_uint32 *minor_status,
* Figure out a suitable mn, if any.
*/
if (desired_name) {
- mn = _gss_find_mn((struct _gss_name *) desired_name,
- desired_mech);
- if (!mn) {
+ major_status = _gss_find_mn(minor_status,
+ (struct _gss_name *) desired_name,
+ desired_mech,
+ &mn);
+ if (major_status != GSS_S_COMPLETE) {
free(new_cred);
- return (GSS_S_BAD_NAME);
+ return (major_status);
}
} else {
mn = 0;
@@ -147,7 +158,8 @@ gss_add_cred(OM_uint32 *minor_status,
mc = malloc(sizeof(struct _gss_mechanism_cred));
if (!mc) {
- gss_release_cred(&junk, (gss_cred_id_t*) &new_cred);
+ release_cred = (gss_cred_id_t) new_cred;
+ gss_release_cred(&junk, &release_cred);
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
@@ -167,7 +179,9 @@ gss_add_cred(OM_uint32 *minor_status,
acceptor_time_rec);
if (major_status) {
- gss_release_cred(&junk, (gss_cred_id_t*) &new_cred);
+ _gss_mg_error(m, major_status, *minor_status);
+ release_cred = (gss_cred_id_t) new_cred;
+ gss_release_cred(&junk, &release_cred);
free(mc);
return (major_status);
}
diff --git a/lib/libgssapi/gss_buffer_set.c b/lib/libgssapi/gss_buffer_set.c
new file mode 100644
index 000000000000..af62e5c29596
--- /dev/null
+++ b/lib/libgssapi/gss_buffer_set.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* $FreeBSD$ */
+
+#include <gssapi/gssapi.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* RCSID("$Id: gss_buffer_set.c 18885 2006-10-24 21:53:02Z lha $"); */
+
+OM_uint32
+gss_create_empty_buffer_set(OM_uint32 * minor_status,
+ gss_buffer_set_t *buffer_set)
+{
+ gss_buffer_set_t set;
+
+ set = (gss_buffer_set_desc *) malloc(sizeof(*set));
+ if (set == GSS_C_NO_BUFFER_SET) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ set->count = 0;
+ set->elements = NULL;
+
+ *buffer_set = set;
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
+
+OM_uint32
+gss_add_buffer_set_member(OM_uint32 * minor_status,
+ const gss_buffer_t member_buffer, gss_buffer_set_t *buffer_set)
+{
+ gss_buffer_set_t set;
+ gss_buffer_t p;
+ OM_uint32 ret;
+
+ if (*buffer_set == GSS_C_NO_BUFFER_SET) {
+ ret = gss_create_empty_buffer_set(minor_status,
+ buffer_set);
+ if (ret) {
+ return (ret);
+ }
+ }
+
+ set = *buffer_set;
+ set->elements = realloc(set->elements,
+ (set->count + 1) * sizeof(set->elements[0]));
+ if (set->elements == NULL) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ p = &set->elements[set->count];
+
+ p->value = malloc(member_buffer->length);
+ if (p->value == NULL) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ memcpy(p->value, member_buffer->value, member_buffer->length);
+ p->length = member_buffer->length;
+
+ set->count++;
+
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+}
+
+OM_uint32
+gss_release_buffer_set(OM_uint32 * minor_status, gss_buffer_set_t *buffer_set)
+{
+ size_t i;
+ OM_uint32 minor;
+
+ *minor_status = 0;
+
+ if (*buffer_set == GSS_C_NO_BUFFER_SET)
+ return (GSS_S_COMPLETE);
+
+ for (i = 0; i < (*buffer_set)->count; i++)
+ gss_release_buffer(&minor, &((*buffer_set)->elements[i]));
+
+ free((*buffer_set)->elements);
+
+ (*buffer_set)->elements = NULL;
+ (*buffer_set)->count = 0;
+
+ free(*buffer_set);
+ *buffer_set = GSS_C_NO_BUFFER_SET;
+
+ return (GSS_S_COMPLETE);
+}
+
diff --git a/lib/libgssapi/gss_canonicalize_name.c b/lib/libgssapi/gss_canonicalize_name.c
index 098362219769..28940b9dbbba 100644
--- a/lib/libgssapi/gss_canonicalize_name.c
+++ b/lib/libgssapi/gss_canonicalize_name.c
@@ -49,16 +49,17 @@ gss_canonicalize_name(OM_uint32 *minor_status,
*minor_status = 0;
*output_name = 0;
- mn = _gss_find_mn(name, mech_type);
- if (!mn) {
- return (GSS_S_BAD_MECH);
- }
+ major_status = _gss_find_mn(minor_status, name, mech_type, &mn);
+ if (major_status)
+ return (major_status);
m = mn->gmn_mech;
major_status = m->gm_canonicalize_name(minor_status,
mn->gmn_name, mech_type, &new_canonical_name);
- if (major_status)
+ if (major_status) {
+ _gss_mg_error(m, major_status, *minor_status);
return (major_status);
+ }
/*
* Now we make a new name and mark it as an MN.
diff --git a/lib/libgssapi/gss_compare_name.c b/lib/libgssapi/gss_compare_name.c
index 644b4a6ff5ab..05b28f600ac6 100644
--- a/lib/libgssapi/gss_compare_name.c
+++ b/lib/libgssapi/gss_compare_name.c
@@ -27,9 +27,11 @@
*/
#include <gssapi/gssapi.h>
+#include <string.h>
#include "mech_switch.h"
#include "name.h"
+#include "utils.h"
OM_uint32
gss_compare_name(OM_uint32 *minor_status,
@@ -47,7 +49,7 @@ gss_compare_name(OM_uint32 *minor_status,
*/
if (name1->gn_value.value && name2->gn_value.value) {
*name_equal = 1;
- if (!_gss_oid_equal(name1->gn_type, name2->gn_type)) {
+ if (!gss_oid_equal(&name1->gn_type, &name2->gn_type)) {
*name_equal = 0;
} else if (name1->gn_value.length != name2->gn_value.length ||
memcmp(name1->gn_value.value, name1->gn_value.value,
@@ -59,8 +61,11 @@ gss_compare_name(OM_uint32 *minor_status,
struct _gss_mechanism_name *mn2;
SLIST_FOREACH(mn1, &name1->gn_mn, gmn_link) {
- mn2 = _gss_find_mn(name2, mn1->gmn_mech_oid);
- if (mn2) {
+ OM_uint32 major_status;
+
+ major_status = _gss_find_mn(minor_status, name2,
+ mn1->gmn_mech_oid, &mn2);
+ if (major_status == GSS_S_COMPLETE) {
return (mn1->gmn_mech->gm_compare_name(
minor_status,
mn1->gmn_name,
diff --git a/lib/libgssapi/gss_create_empty_oid_set.c b/lib/libgssapi/gss_create_empty_oid_set.c
index 0412817a280f..c35f99f3120d 100644
--- a/lib/libgssapi/gss_create_empty_oid_set.c
+++ b/lib/libgssapi/gss_create_empty_oid_set.c
@@ -37,7 +37,7 @@ gss_create_empty_oid_set(OM_uint32 *minor_status,
gss_OID_set set;
*minor_status = 0;
- *oid_set = 0;
+ *oid_set = GSS_C_NO_OID_SET;
set = malloc(sizeof(gss_OID_set_desc));
if (!set) {
diff --git a/lib/libgssapi/gss_decapsulate_token.c b/lib/libgssapi/gss_decapsulate_token.c
new file mode 100644
index 000000000000..65ff46ab3c1a
--- /dev/null
+++ b/lib/libgssapi/gss_decapsulate_token.c
@@ -0,0 +1,107 @@
+/*-
+ * Copyright (c) 2008 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <gssapi/gssapi.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils.h"
+
+OM_uint32
+gss_decapsulate_token(const gss_buffer_t input_token, gss_OID oid,
+ gss_buffer_t output_token)
+{
+ unsigned char *p = input_token->value;
+ size_t len = input_token->length;
+ size_t a, b;
+ gss_OID_desc mech_oid;
+
+ _gss_buffer_zero(output_token);
+
+ /*
+ * Token must start with [APPLICATION 0] SEQUENCE.
+ */
+ if (len == 0 || *p != 0x60)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ p++;
+ len--;
+
+ /*
+ * Decode the length and make sure it agrees with the
+ * token length.
+ */
+ if (len == 0)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if ((*p & 0x80) == 0) {
+ a = *p;
+ p++;
+ len--;
+ } else {
+ b = *p & 0x7f;
+ p++;
+ len--;
+ if (len < b)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ a = 0;
+ while (b) {
+ a = (a << 8) | *p;
+ p++;
+ len--;
+ b--;
+ }
+ }
+ if (a != len)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ /*
+ * Decode the OID for the mechanism. Simplify life by
+ * assuming that the OID length is less than 128 bytes.
+ */
+ if (len < 2 || *p != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ if ((p[1] & 0x80) || p[1] > (len - 2))
+ return (GSS_S_DEFECTIVE_TOKEN);
+ mech_oid.length = p[1];
+ p += 2;
+ len -= 2;
+ mech_oid.elements = p;
+
+ if (!gss_oid_equal(&mech_oid, oid))
+ return (GSS_S_FAILURE);
+
+ p += mech_oid.length;
+ len -= mech_oid.length;
+
+ output_token->length = len;
+ output_token->value = malloc(len);
+ if (!output_token->value)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ memcpy(output_token->value, p, len);
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/lib/libgssapi/gss_delete_sec_context.c b/lib/libgssapi/gss_delete_sec_context.c
index b1f39c24c0fd..b4b087f93142 100644
--- a/lib/libgssapi/gss_delete_sec_context.c
+++ b/lib/libgssapi/gss_delete_sec_context.c
@@ -32,6 +32,7 @@
#include "mech_switch.h"
#include "context.h"
+#include "utils.h"
OM_uint32
gss_delete_sec_context(OM_uint32 *minor_status,
@@ -41,6 +42,9 @@ gss_delete_sec_context(OM_uint32 *minor_status,
OM_uint32 major_status;
struct _gss_context *ctx = (struct _gss_context *) *context_handle;
+ if (output_token)
+ _gss_buffer_zero(output_token);
+
*minor_status = 0;
if (ctx) {
/*
@@ -50,12 +54,9 @@ gss_delete_sec_context(OM_uint32 *minor_status,
if (ctx->gc_ctx) {
major_status = ctx->gc_mech->gm_delete_sec_context(
minor_status, &ctx->gc_ctx, output_token);
- } else if (output_token != GSS_C_NO_BUFFER) {
- output_token->length = 0;
- output_token->value = 0;
}
free(ctx);
- *context_handle = 0;
+ *context_handle = GSS_C_NO_CONTEXT;
}
return (GSS_S_COMPLETE);
diff --git a/lib/libgssapi/gss_display_name.c b/lib/libgssapi/gss_display_name.c
index 5fe4f1d4b351..61faabac907e 100644
--- a/lib/libgssapi/gss_display_name.c
+++ b/lib/libgssapi/gss_display_name.c
@@ -33,6 +33,7 @@
#include "mech_switch.h"
#include "name.h"
+#include "utils.h"
OM_uint32
gss_display_name(OM_uint32 *minor_status,
@@ -44,6 +45,15 @@ gss_display_name(OM_uint32 *minor_status,
struct _gss_name *name = (struct _gss_name *) input_name;
struct _gss_mechanism_name *mn;
+ _gss_buffer_zero(output_name_buffer);
+ if (output_name_type)
+ *output_name_type = GSS_C_NO_OID;
+
+ if (name == NULL) {
+ *minor_status = 0;
+ return (GSS_S_BAD_NAME);
+ }
+
/*
* If we know it, copy the buffer used to import the name in
* the first place. Otherwise, ask all the MNs in turn if
diff --git a/lib/libgssapi/gss_display_status.c b/lib/libgssapi/gss_display_status.c
index f87cc9eeade7..0374fbd8053d 100644
--- a/lib/libgssapi/gss_display_status.c
+++ b/lib/libgssapi/gss_display_status.c
@@ -57,12 +57,47 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+/*
+ * Copyright (c) 1998 - 2005 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
#include <gssapi/gssapi.h>
+#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <errno.h>
#include "mech_switch.h"
+#include "utils.h"
static const char *
calling_error(OM_uint32 v)
@@ -88,7 +123,7 @@ static const char *
routine_error(OM_uint32 v)
{
static const char *msgs[] = {
- NULL, /* 0 */
+ "Function completed successfully", /* 0 */
"An unsupported mechanism was requested",
"An invalid name was supplied",
"A supplied name was of an unsupported type",
@@ -112,9 +147,7 @@ routine_error(OM_uint32 v)
v >>= GSS_C_ROUTINE_ERROR_OFFSET;
- if (v == 0)
- return "";
- else if (v >= sizeof(msgs)/sizeof(*msgs))
+ if (v >= sizeof(msgs)/sizeof(*msgs))
return "unknown routine error";
else
return msgs[v];
@@ -140,23 +173,119 @@ supplementary_error(OM_uint32 v)
return msgs[v];
}
+#if defined(__sparc64__) || defined(__arm__) || defined(__mips__)
+
+/*
+ * These platforms don't support TLS on FreeBSD - threads will just
+ * have to step on each other's error values for now.
+ */
+#define __thread
+
+#endif
+
+struct mg_thread_ctx {
+ gss_OID mech;
+ OM_uint32 maj_stat;
+ OM_uint32 min_stat;
+ gss_buffer_desc maj_error;
+ gss_buffer_desc min_error;
+};
+static __thread struct mg_thread_ctx last_error_context;
+
+static OM_uint32
+_gss_mg_get_error(const gss_OID mech, OM_uint32 type,
+ OM_uint32 value, gss_buffer_t string)
+{
+ struct mg_thread_ctx *mg;
+
+ mg = &last_error_context;
+
+ if (mech != NULL && gss_oid_equal(mg->mech, mech) == 0)
+ return (GSS_S_BAD_STATUS);
+
+ switch (type) {
+ case GSS_C_GSS_CODE: {
+ if (value != mg->maj_stat || mg->maj_error.length == 0)
+ break;
+ string->value = malloc(mg->maj_error.length);
+ string->length = mg->maj_error.length;
+ memcpy(string->value, mg->maj_error.value,
+ mg->maj_error.length);
+ return (GSS_S_COMPLETE);
+ }
+ case GSS_C_MECH_CODE: {
+ if (value != mg->min_stat || mg->min_error.length == 0)
+ break;
+ string->value = malloc(mg->min_error.length);
+ string->length = mg->min_error.length;
+ memcpy(string->value, mg->min_error.value,
+ mg->min_error.length);
+ return (GSS_S_COMPLETE);
+ }
+ }
+ string->value = NULL;
+ string->length = 0;
+ return (GSS_S_BAD_STATUS);
+}
+
+void
+_gss_mg_error(struct _gss_mech_switch *m, OM_uint32 maj, OM_uint32 min)
+{
+ OM_uint32 major_status, minor_status;
+ OM_uint32 message_content;
+ struct mg_thread_ctx *mg;
+
+ mg = &last_error_context;
+
+ gss_release_buffer(&minor_status, &mg->maj_error);
+ gss_release_buffer(&minor_status, &mg->min_error);
+
+ mg->mech = &m->gm_mech_oid;
+ mg->maj_stat = maj;
+ mg->min_stat = min;
+
+ major_status = m->gm_display_status(&minor_status,
+ maj,
+ GSS_C_GSS_CODE,
+ &m->gm_mech_oid,
+ &message_content,
+ &mg->maj_error);
+ if (GSS_ERROR(major_status)) {
+ mg->maj_error.value = NULL;
+ mg->maj_error.length = 0;
+ }
+ major_status = m->gm_display_status(&minor_status,
+ min,
+ GSS_C_MECH_CODE,
+ &m->gm_mech_oid,
+ &message_content,
+ &mg->min_error);
+ if (GSS_ERROR(major_status)) {
+ mg->min_error.value = NULL;
+ mg->min_error.length = 0;
+ }
+}
+
OM_uint32
gss_display_status(OM_uint32 *minor_status,
OM_uint32 status_value,
int status_type,
- const gss_OID input_mech_type,
+ const gss_OID mech_type,
OM_uint32 *message_content,
gss_buffer_t status_string)
{
OM_uint32 major_status;
- gss_OID mech_type;
-
- mech_type = input_mech_type;
- if (mech_type == GSS_C_NO_OID) {
- _gss_load_mech();
- mech_type = &SLIST_FIRST(&_gss_mechs)->gm_mech_oid;
- if (mech_type == NULL)
- return (GSS_S_BAD_MECH);
+
+ _gss_buffer_zero(status_string);
+ *message_content = 0;
+
+ major_status = _gss_mg_get_error(mech_type, status_type,
+ status_value, status_string);
+ if (major_status == GSS_S_COMPLETE) {
+
+ *message_content = 0;
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
}
*minor_status = 0;
@@ -172,24 +301,40 @@ gss_display_status(OM_uint32 *minor_status,
calling_error(GSS_CALLING_ERROR(status_value)),
routine_error(GSS_ROUTINE_ERROR(status_value)));
+ if (buf == NULL)
+ break;
+
status_string->length = strlen(buf);
status_string->value = buf;
- return GSS_S_COMPLETE;
+ return (GSS_S_COMPLETE);
}
case GSS_C_MECH_CODE: {
- struct _gss_mech_switch *m;
- m = _gss_find_mech_switch(mech_type);
- if (m) {
- major_status = m->gm_display_status(minor_status,
- status_value, status_type, mech_type,
- message_content, status_string);
- if (major_status == GSS_S_COMPLETE)
- return (GSS_S_COMPLETE);
+ OM_uint32 maj_junk, min_junk;
+ gss_buffer_desc oid;
+ char *buf;
+
+ maj_junk = gss_oid_to_str(&min_junk, mech_type, &oid);
+ if (maj_junk != GSS_S_COMPLETE) {
+ oid.value = strdup("unknown");
+ oid.length = 7;
}
+
+ asprintf (&buf, "unknown mech-code %lu for mech %.*s",
+ (unsigned long)status_value,
+ (int)oid.length, (char *)oid.value);
+ if (maj_junk == GSS_S_COMPLETE)
+ gss_release_buffer(&min_junk, &oid);
+
+ if (buf == NULL)
+ break;
+
+ status_string->length = strlen(buf);
+ status_string->value = buf;
+
+ return (GSS_S_COMPLETE);
}
}
- status_string->value = NULL;
- status_string->length = 0;
+ _gss_buffer_zero(status_string);
return (GSS_S_BAD_STATUS);
}
diff --git a/lib/libgssapi/gss_duplicate_name.c b/lib/libgssapi/gss_duplicate_name.c
index f0ce4173d4f7..c6d07ac4e2b4 100644
--- a/lib/libgssapi/gss_duplicate_name.c
+++ b/lib/libgssapi/gss_duplicate_name.c
@@ -44,11 +44,12 @@ OM_uint32 gss_duplicate_name(OM_uint32 *minor_status,
struct _gss_mechanism_name *mn;
*minor_status = 0;
+ *dest_name = GSS_C_NO_NAME;
/*
* If this name has a value (i.e. it didn't come from
* gss_canonicalize_name(), we re-import the thing. Otherwise,
- * we make an empty name to hold the MN copy.
+ * we make a copy of the mechanism names.
*/
if (name->gn_value.value) {
major_status = gss_import_name(minor_status,
@@ -56,6 +57,12 @@ OM_uint32 gss_duplicate_name(OM_uint32 *minor_status,
if (major_status != GSS_S_COMPLETE)
return (major_status);
new_name = (struct _gss_name *) *dest_name;
+
+ SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ struct _gss_mechanism_name *mn2;
+ _gss_find_mn(minor_status, new_name,
+ mn->gmn_mech_oid, &mn2);
+ }
} else {
new_name = malloc(sizeof(struct _gss_name));
if (!new_name) {
@@ -63,17 +70,30 @@ OM_uint32 gss_duplicate_name(OM_uint32 *minor_status,
return (GSS_S_FAILURE);
}
memset(new_name, 0, sizeof(struct _gss_name));
- SLIST_INIT(&name->gn_mn);
+ SLIST_INIT(&new_name->gn_mn);
*dest_name = (gss_name_t) new_name;
- }
- /*
- * Import the new name into any mechanisms listed in the
- * original name. We could probably get away with only doing
- * this if the original was canonical.
- */
- SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
- _gss_find_mn(new_name, mn->gmn_mech_oid);
+ SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
+ struct _gss_mechanism_name *new_mn;
+
+ new_mn = malloc(sizeof(*new_mn));
+ if (!new_mn) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+ new_mn->gmn_mech = mn->gmn_mech;
+ new_mn->gmn_mech_oid = mn->gmn_mech_oid;
+
+ major_status =
+ mn->gmn_mech->gm_duplicate_name(minor_status,
+ mn->gmn_name, &new_mn->gmn_name);
+ if (major_status != GSS_S_COMPLETE) {
+ free(new_mn);
+ continue;
+ }
+ SLIST_INSERT_HEAD(&new_name->gn_mn, new_mn, gmn_link);
+ }
+
}
return (GSS_S_COMPLETE);
diff --git a/lib/libgssapi/gss_duplicate_oid.c b/lib/libgssapi/gss_duplicate_oid.c
new file mode 100644
index 000000000000..591508d8fa58
--- /dev/null
+++ b/lib/libgssapi/gss_duplicate_oid.c
@@ -0,0 +1,65 @@
+/*-
+ * Copyright (c) 2008 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <gssapi/gssapi.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+OM_uint32 gss_duplicate_oid(OM_uint32 *minor_status,
+ const gss_OID src_oid,
+ gss_OID *dest_oid_p)
+{
+ gss_OID dest_oid;
+
+ *minor_status = 0;
+ *dest_oid_p = GSS_C_NO_OID;
+
+ if (src_oid == GSS_C_NO_OID)
+ return (GSS_S_COMPLETE);
+
+ dest_oid = malloc(sizeof(gss_OID_desc));
+ if (!dest_oid) {
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ dest_oid->elements = malloc(src_oid->length);
+ if (!dest_oid->elements) {
+ free(dest_oid);
+ *minor_status = ENOMEM;
+ return (GSS_S_FAILURE);
+ }
+
+ memcpy(dest_oid->elements, src_oid->elements, src_oid->length);
+ dest_oid->length = src_oid->length;
+
+ *dest_oid_p = dest_oid;
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/lib/libgssapi/gss_encapsulate_token.c b/lib/libgssapi/gss_encapsulate_token.c
new file mode 100644
index 000000000000..ed0e217d65be
--- /dev/null
+++ b/lib/libgssapi/gss_encapsulate_token.c
@@ -0,0 +1,131 @@
+/*-
+ * Copyright (c) 2008 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <gssapi/gssapi.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils.h"
+
+OM_uint32
+gss_encapsulate_token(const gss_buffer_t input_token, gss_OID oid,
+ gss_buffer_t output_token)
+{
+ unsigned char *p;
+ size_t len, inside_len;
+ size_t a, b;
+ int i;
+
+ _gss_buffer_zero(output_token);
+
+ /*
+ * First time around, we calculate the size, second time, we
+ * encode the token.
+ */
+ p = 0;
+ for (i = 0; i < 2; i++) {
+ len = 0;
+
+ /*
+ * Token starts with [APPLICATION 0] SEQUENCE.
+ */
+ if (p)
+ *p++ = 0x60;
+ len++;
+
+ /*
+ * The length embedded in the token is the space
+ * needed for the encapsulated oid plus the length of
+ * the inner token.
+ */
+ if (oid->length > 127)
+ return (GSS_S_DEFECTIVE_TOKEN);
+
+ inside_len = 2 + oid->length + input_token->length;
+
+ /*
+ * Figure out how to encode the length
+ */
+ if (inside_len < 128) {
+ if (p)
+ *p++ = inside_len;
+ len++;
+ } else {
+ b = 1;
+ if (inside_len >= 0x100)
+ b++;
+ if (inside_len >= 0x10000)
+ b++;
+ if (inside_len >= 0x1000000)
+ b++;
+ if (p)
+ *p++ = b | 0x80;
+ len++;
+ a = inside_len << 8*(4 - b);
+ while (b) {
+ if (p)
+ *p++ = (a >> 24);
+ a <<= 8;
+ len++;
+ b--;
+ }
+ }
+
+ /*
+ * Encode the OID for the mechanism. Simplify life by
+ * assuming that the OID length is less than 128 bytes.
+ */
+ if (p)
+ *p++ = 0x06;
+ len++;
+ if (p)
+ *p++ = oid->length;
+ len++;
+ if (p) {
+ memcpy(p, oid->elements, oid->length);
+ p += oid->length;
+ }
+ len += oid->length;
+
+ if (p) {
+ memcpy(p, input_token->value, input_token->length);
+ p += input_token->length;
+ }
+ len += input_token->length;
+
+ if (i == 0) {
+ output_token->length = len;
+ output_token->value = malloc(len);
+ if (!output_token->value)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ p = output_token->value;
+ }
+ }
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/lib/libgssapi/gss_export_name.c b/lib/libgssapi/gss_export_name.c
index 6cba2f8c380b..49174bbcafd0 100644
--- a/lib/libgssapi/gss_export_name.c
+++ b/lib/libgssapi/gss_export_name.c
@@ -30,6 +30,7 @@
#include "mech_switch.h"
#include "name.h"
+#include "utils.h"
OM_uint32
gss_export_name(OM_uint32 *minor_status,
@@ -39,8 +40,7 @@ gss_export_name(OM_uint32 *minor_status,
struct _gss_name *name = (struct _gss_name *) input_name;
struct _gss_mechanism_name *mn;
- exported_name->value = NULL;
- exported_name->length = 0;
+ _gss_buffer_zero(exported_name);
/*
* If this name already has any attached MNs, export the first
@@ -48,12 +48,9 @@ gss_export_name(OM_uint32 *minor_status,
* list.
*/
mn = SLIST_FIRST(&name->gn_mn);
- if (!mn)
- mn = _gss_find_mn(name,
- &SLIST_FIRST(&_gss_mechs)->gm_mech_oid);
if (!mn) {
*minor_status = 0;
- return (GSS_S_BAD_MECH);
+ return (GSS_S_NAME_NOT_MN);
}
return mn->gmn_mech->gm_export_name(minor_status,
diff --git a/lib/libgssapi/gss_export_sec_context.c b/lib/libgssapi/gss_export_sec_context.c
index 71c6874e963d..a600f280048f 100644
--- a/lib/libgssapi/gss_export_sec_context.c
+++ b/lib/libgssapi/gss_export_sec_context.c
@@ -33,6 +33,7 @@
#include "mech_switch.h"
#include "context.h"
+#include "utils.h"
OM_uint32
gss_export_sec_context(OM_uint32 *minor_status,
@@ -44,6 +45,8 @@ gss_export_sec_context(OM_uint32 *minor_status,
struct _gss_mech_switch *m = ctx->gc_mech;
gss_buffer_desc buf;
+ _gss_buffer_zero(interprocess_token);
+
major_status = m->gm_export_sec_context(minor_status,
&ctx->gc_ctx, &buf);
@@ -63,6 +66,7 @@ gss_export_sec_context(OM_uint32 *minor_status,
* GSS_C_NO_CONTEXT, which we did above.
* Return GSS_S_FAILURE.
*/
+ _gss_buffer_zero(interprocess_token);
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
@@ -72,6 +76,8 @@ gss_export_sec_context(OM_uint32 *minor_status,
memcpy(p + 2, m->gm_mech_oid.elements, m->gm_mech_oid.length);
memcpy(p + 2 + m->gm_mech_oid.length, buf.value, buf.length);
gss_release_buffer(minor_status, &buf);
+ } else {
+ _gss_mg_error(m, major_status, *minor_status);
}
return (major_status);
diff --git a/lib/libgssapi/gss_get_mic.c b/lib/libgssapi/gss_get_mic.c
index a3495ecfe794..dff3b545f78f 100644
--- a/lib/libgssapi/gss_get_mic.c
+++ b/lib/libgssapi/gss_get_mic.c
@@ -30,6 +30,7 @@
#include "mech_switch.h"
#include "context.h"
+#include "utils.h"
OM_uint32
gss_get_mic(OM_uint32 *minor_status,
@@ -41,6 +42,12 @@ gss_get_mic(OM_uint32 *minor_status,
struct _gss_context *ctx = (struct _gss_context *) context_handle;
struct _gss_mech_switch *m = ctx->gc_mech;
+ _gss_buffer_zero(message_token);
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return (GSS_S_NO_CONTEXT);
+ }
+
return (m->gm_get_mic(minor_status, ctx->gc_ctx, qop_req,
message_buffer, message_token));
}
diff --git a/lib/libgssapi/gss_import_name.c b/lib/libgssapi/gss_import_name.c
index 65820b12874d..3d8079d2dea9 100644
--- a/lib/libgssapi/gss_import_name.c
+++ b/lib/libgssapi/gss_import_name.c
@@ -47,7 +47,6 @@ _gss_import_export_name(OM_uint32 *minor_status,
gss_OID_desc mech_oid;
struct _gss_mech_switch *m;
struct _gss_name *name;
- struct _gss_mechanism_name *mn;
gss_name_t new_canonical_name;
*minor_status = 0;
@@ -126,6 +125,10 @@ _gss_import_export_name(OM_uint32 *minor_status,
*/
major_status = m->gm_import_name(minor_status,
input_name_buffer, GSS_C_NT_EXPORT_NAME, &new_canonical_name);
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
+ return (major_status);
+ }
/*
* Now we make a new name and mark it as an MN.
@@ -152,9 +155,10 @@ gss_import_name(OM_uint32 *minor_status,
OM_uint32 major_status;
struct _gss_name *name;
+ *output_name = GSS_C_NO_NAME;
+
if (input_name_buffer->length == 0) {
*minor_status = 0;
- *output_name = 0;
return (GSS_S_BAD_NAME);
}
@@ -169,7 +173,7 @@ gss_import_name(OM_uint32 *minor_status,
* the mechanism and then import it as an MN. See RFC 2743
* section 3.2 for a description of the format.
*/
- if (_gss_oid_equal(name_type, GSS_C_NT_EXPORT_NAME)) {
+ if (gss_oid_equal(name_type, GSS_C_NT_EXPORT_NAME)) {
return _gss_import_export_name(minor_status,
input_name_buffer, output_name);
}
@@ -179,15 +183,14 @@ gss_import_name(OM_uint32 *minor_status,
* should figure out the list of supported name types using
* gss_inquire_names_for_mech.
*/
- if (!_gss_oid_equal(name_type, GSS_C_NT_USER_NAME)
- && !_gss_oid_equal(name_type, GSS_C_NT_MACHINE_UID_NAME)
- && !_gss_oid_equal(name_type, GSS_C_NT_STRING_UID_NAME)
- && !_gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE_X)
- && !_gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE)
- && !_gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS)
- && !_gss_oid_equal(name_type, GSS_KRB5_NT_PRINCIPAL_NAME)) {
+ if (!gss_oid_equal(name_type, GSS_C_NT_USER_NAME)
+ && !gss_oid_equal(name_type, GSS_C_NT_MACHINE_UID_NAME)
+ && !gss_oid_equal(name_type, GSS_C_NT_STRING_UID_NAME)
+ && !gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE_X)
+ && !gss_oid_equal(name_type, GSS_C_NT_HOSTBASED_SERVICE)
+ && !gss_oid_equal(name_type, GSS_C_NT_ANONYMOUS)
+ && !gss_oid_equal(name_type, GSS_KRB5_NT_PRINCIPAL_NAME)) {
*minor_status = 0;
- *output_name = 0;
return (GSS_S_BAD_NAMETYPE);
}
@@ -209,7 +212,8 @@ gss_import_name(OM_uint32 *minor_status,
major_status = _gss_copy_buffer(minor_status,
input_name_buffer, &name->gn_value);
if (major_status) {
- gss_release_name(minor_status, (gss_name_t*) &name);
+ gss_name_t rname = (gss_name_t)name;
+ gss_release_name(minor_status, &rname);
return (GSS_S_FAILURE);
}
diff --git a/lib/libgssapi/gss_import_sec_context.c b/lib/libgssapi/gss_import_sec_context.c
index ce3ddd10c3f3..0ab138ecae98 100644
--- a/lib/libgssapi/gss_import_sec_context.c
+++ b/lib/libgssapi/gss_import_sec_context.c
@@ -47,7 +47,7 @@ gss_import_sec_context(OM_uint32 *minor_status,
size_t len;
*minor_status = 0;
- *context_handle = 0;
+ *context_handle = GSS_C_NO_CONTEXT;
/*
* We added an oid to the front of the token in
@@ -77,6 +77,7 @@ gss_import_sec_context(OM_uint32 *minor_status,
major_status = m->gm_import_sec_context(minor_status,
&buf, &ctx->gc_ctx);
if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
free(ctx);
} else {
*context_handle = (gss_ctx_id_t) ctx;
diff --git a/lib/libgssapi/gss_indicate_mechs.c b/lib/libgssapi/gss_indicate_mechs.c
index 87a34f4e6dbe..ec4350f8eeb1 100644
--- a/lib/libgssapi/gss_indicate_mechs.c
+++ b/lib/libgssapi/gss_indicate_mechs.c
@@ -37,7 +37,7 @@ gss_indicate_mechs(OM_uint32 *minor_status,
struct _gss_mech_switch *m;
OM_uint32 major_status;
gss_OID_set set;
- int i;
+ size_t i;
_gss_load_mech();
@@ -50,6 +50,12 @@ gss_indicate_mechs(OM_uint32 *minor_status,
major_status = m->gm_indicate_mechs(minor_status, &set);
if (major_status)
continue;
+ if (set == GSS_C_NO_OID_SET) {
+ major_status = gss_add_oid_set_member(
+ minor_status,
+ &m->gm_mech_oid, mech_set);
+ continue;
+ }
for (i = 0; i < set->count; i++)
major_status = gss_add_oid_set_member(minor_status,
&set->elements[i], mech_set);
diff --git a/lib/libgssapi/gss_init_sec_context.c b/lib/libgssapi/gss_init_sec_context.c
index 8b596f3ba892..d8f06ab3e819 100644
--- a/lib/libgssapi/gss_init_sec_context.c
+++ b/lib/libgssapi/gss_init_sec_context.c
@@ -35,13 +35,30 @@
#include "name.h"
#include "cred.h"
#include "context.h"
+#include "utils.h"
+
+static gss_cred_id_t
+_gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
+{
+ struct _gss_cred *cred = (struct _gss_cred *)cred_handle;
+ struct _gss_mechanism_cred *mc;
+
+ if (cred == NULL)
+ return GSS_C_NO_CREDENTIAL;
+
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ if (gss_oid_equal(mech_type, mc->gmc_mech_oid))
+ return mc->gmc_cred;
+ }
+ return GSS_C_NO_CREDENTIAL;
+}
OM_uint32
gss_init_sec_context(OM_uint32 * minor_status,
const gss_cred_id_t initiator_cred_handle,
gss_ctx_id_t * context_handle,
const gss_name_t target_name,
- const gss_OID imech_type,
+ const gss_OID input_mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
const gss_channel_bindings_t input_chan_bindings,
@@ -52,24 +69,23 @@ gss_init_sec_context(OM_uint32 * minor_status,
OM_uint32 * time_rec)
{
OM_uint32 major_status;
- gss_OID mech_type;
struct _gss_mech_switch *m;
struct _gss_name *name = (struct _gss_name *) target_name;
struct _gss_mechanism_name *mn;
struct _gss_context *ctx = (struct _gss_context *) *context_handle;
- struct _gss_cred *cred = (struct _gss_cred *) initiator_cred_handle;
- struct _gss_mechanism_cred *mc;
gss_cred_id_t cred_handle;
int allocated_ctx;
+ gss_OID mech_type = input_mech_type;
*minor_status = 0;
- if ((mech_type = imech_type) == GSS_C_NO_OID) {
- _gss_load_mech();
- mech_type = &SLIST_FIRST(&_gss_mechs)->gm_mech_oid;
- if (mech_type == NULL)
- return (GSS_S_BAD_MECH);
- }
+ _gss_buffer_zero(output_token);
+ if (actual_mech_type)
+ *actual_mech_type = GSS_C_NO_OID;
+ if (ret_flags)
+ *ret_flags = 0;
+ if (time_rec)
+ *time_rec = 0;
/*
* If we haven't allocated a context yet, do so now and lookup
@@ -77,6 +93,14 @@ gss_init_sec_context(OM_uint32 * minor_status,
* sure we use the same mechanism switch as before.
*/
if (!ctx) {
+ if (mech_type == GSS_C_NO_OID) {
+ _gss_load_mech();
+ if (_gss_mech_oids == GSS_C_NO_OID_SET
+ || _gss_mech_oids->count == 0)
+ return (GSS_S_BAD_MECH);
+ mech_type = &_gss_mech_oids->elements[0];
+ }
+
ctx = malloc(sizeof(struct _gss_context));
if (!ctx) {
*minor_status = ENOMEM;
@@ -91,31 +115,24 @@ gss_init_sec_context(OM_uint32 * minor_status,
allocated_ctx = 1;
} else {
m = ctx->gc_mech;
+ mech_type = &ctx->gc_mech->gm_mech_oid;
allocated_ctx = 0;
}
/*
* Find the MN for this mechanism.
*/
- mn = _gss_find_mn(name, mech_type);
- if (mn == NULL) {
+ major_status = _gss_find_mn(minor_status, name, mech_type, &mn);
+ if (major_status != GSS_S_COMPLETE) {
if (allocated_ctx)
free(ctx);
- return GSS_S_BAD_NAME;
+ return (major_status);
}
/*
* If we have a cred, find the cred for this mechanism.
*/
- cred_handle = GSS_C_NO_CREDENTIAL;
- if (cred) {
- SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
- if (_gss_oid_equal(mech_type, mc->gmc_mech_oid)) {
- cred_handle = mc->gmc_cred;
- break;
- }
- }
- }
+ cred_handle = _gss_mech_cred_find(initiator_cred_handle, mech_type);
major_status = m->gm_init_sec_context(minor_status,
cred_handle,
@@ -135,6 +152,8 @@ gss_init_sec_context(OM_uint32 * minor_status,
&& major_status != GSS_S_CONTINUE_NEEDED) {
if (allocated_ctx)
free(ctx);
+ _gss_buffer_zero(output_token);
+ _gss_mg_error(m, major_status, *minor_status);
} else {
*context_handle = (gss_ctx_id_t) ctx;
}
diff --git a/lib/libgssapi/gss_inquire_context.c b/lib/libgssapi/gss_inquire_context.c
index 3f4531d2c428..c9f2a0c545ef 100644
--- a/lib/libgssapi/gss_inquire_context.c
+++ b/lib/libgssapi/gss_inquire_context.c
@@ -49,27 +49,43 @@ gss_inquire_context(OM_uint32 *minor_status,
struct _gss_name *name;
gss_name_t src_mn, targ_mn;
+ if (locally_initiated)
+ *locally_initiated = 0;
+ if (open)
+ *open = 0;
+ if (lifetime_rec)
+ *lifetime_rec = 0;
+
+ if (src_name)
+ *src_name = GSS_C_NO_NAME;
+ if (targ_name)
+ *targ_name = GSS_C_NO_NAME;
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ src_mn = targ_mn = GSS_C_NO_NAME;
+
major_status = m->gm_inquire_context(minor_status,
ctx->gc_ctx,
- src_name ? &src_mn : 0,
- targ_name ? &targ_mn : 0,
+ src_name ? &src_mn : NULL,
+ targ_name ? &targ_mn : NULL,
lifetime_rec,
mech_type,
ctx_flags,
locally_initiated,
open);
- if (src_name) *src_name = 0;
- if (targ_name) *targ_name = 0;
-
if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
return (major_status);
}
if (src_name) {
name = _gss_make_name(m, src_mn);
if (!name) {
- minor_status = 0;
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ m->gm_release_name(minor_status, &src_mn);
+ *minor_status = 0;
return (GSS_S_FAILURE);
}
*src_name = (gss_name_t) name;
@@ -78,6 +94,11 @@ gss_inquire_context(OM_uint32 *minor_status,
if (targ_name) {
name = _gss_make_name(m, targ_mn);
if (!name) {
+ if (mech_type)
+ *mech_type = GSS_C_NO_OID;
+ if (src_name)
+ gss_release_name(minor_status, src_name);
+ m->gm_release_name(minor_status, &src_mn);
minor_status = 0;
return (GSS_S_FAILURE);
}
diff --git a/lib/libgssapi/gss_inquire_cred.c b/lib/libgssapi/gss_inquire_cred.c
index 60b746f53f6f..c51f07e55841 100644
--- a/lib/libgssapi/gss_inquire_cred.c
+++ b/lib/libgssapi/gss_inquire_cred.c
@@ -35,6 +35,20 @@
#include "name.h"
#include "cred.h"
+#define AUSAGE 1
+#define IUSAGE 2
+
+static void
+updateusage(gss_cred_usage_t usage, int *usagemask)
+{
+ if (usage == GSS_C_BOTH)
+ *usagemask |= AUSAGE | IUSAGE;
+ else if (usage == GSS_C_ACCEPT)
+ *usagemask |= AUSAGE;
+ else if (usage == GSS_C_INITIATE)
+ *usagemask |= IUSAGE;
+}
+
OM_uint32
gss_inquire_cred(OM_uint32 *minor_status,
const gss_cred_id_t cred_handle,
@@ -46,29 +60,35 @@ gss_inquire_cred(OM_uint32 *minor_status,
OM_uint32 major_status;
struct _gss_mech_switch *m;
struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
- struct _gss_mechanism_cred *mc;
struct _gss_name *name;
struct _gss_mechanism_name *mn;
OM_uint32 min_lifetime;
+ int found = 0;
+ int usagemask = 0;
+ gss_cred_usage_t usage;
+
+ _gss_load_mech();
*minor_status = 0;
if (name_ret)
- *name_ret = 0;
+ *name_ret = GSS_C_NO_NAME;
if (lifetime)
*lifetime = 0;
if (cred_usage)
*cred_usage = 0;
+ if (mechanisms)
+ *mechanisms = GSS_C_NO_OID_SET;
if (name_ret) {
name = malloc(sizeof(struct _gss_name));
- if (!name) {
+ if (name == NULL) {
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
memset(name, 0, sizeof(struct _gss_name));
SLIST_INIT(&name->gn_mn);
} else {
- name = 0;
+ name = NULL;
}
if (mechanisms) {
@@ -82,16 +102,19 @@ gss_inquire_cred(OM_uint32 *minor_status,
min_lifetime = GSS_C_INDEFINITE;
if (cred) {
+ struct _gss_mechanism_cred *mc;
+
SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
gss_name_t mc_name;
OM_uint32 mc_lifetime;
major_status = mc->gmc_mech->gm_inquire_cred(minor_status,
- mc->gmc_cred, &mc_name, &mc_lifetime, NULL, NULL);
+ mc->gmc_cred, &mc_name, &mc_lifetime, &usage, NULL);
if (major_status)
continue;
- if (name) {
+ updateusage(usage, &usagemask);
+ if (name && mc_name) {
mn = malloc(sizeof(struct _gss_mechanism_name));
if (!mn) {
mc->gmc_mech->gm_release_name(minor_status,
@@ -102,7 +125,7 @@ gss_inquire_cred(OM_uint32 *minor_status,
mn->gmn_mech_oid = mc->gmc_mech_oid;
mn->gmn_name = mc_name;
SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
- } else {
+ } else if (mc_name) {
mc->gmc_mech->gm_release_name(minor_status,
&mc_name);
}
@@ -113,6 +136,7 @@ gss_inquire_cred(OM_uint32 *minor_status,
if (mechanisms)
gss_add_oid_set_member(minor_status,
mc->gmc_mech_oid, mechanisms);
+ found++;
}
} else {
SLIST_FOREACH(m, &_gss_mechs, gm_link) {
@@ -121,24 +145,25 @@ gss_inquire_cred(OM_uint32 *minor_status,
major_status = m->gm_inquire_cred(minor_status,
GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime,
- cred_usage, NULL);
+ &usage, NULL);
if (major_status)
continue;
+ updateusage(usage, &usagemask);
if (name && mc_name) {
mn = malloc(
sizeof(struct _gss_mechanism_name));
if (!mn) {
- mc->gmc_mech->gm_release_name(
+ m->gm_release_name(
minor_status, &mc_name);
continue;
}
- mn->gmn_mech = mc->gmc_mech;
- mn->gmn_mech_oid = mc->gmc_mech_oid;
+ mn->gmn_mech = m;
+ mn->gmn_mech_oid = &m->gm_mech_oid;
mn->gmn_name = mc_name;
SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
} else if (mc_name) {
- mc->gmc_mech->gm_release_name(minor_status,
+ m->gm_release_name(minor_status,
&mc_name);
}
@@ -148,13 +173,17 @@ gss_inquire_cred(OM_uint32 *minor_status,
if (mechanisms)
gss_add_oid_set_member(minor_status,
&m->gm_mech_oid, mechanisms);
+ found++;
}
+ }
- if ((*mechanisms)->count == 0) {
- gss_release_oid_set(minor_status, mechanisms);
- *minor_status = 0;
- return (GSS_S_NO_CRED);
- }
+ if (found == 0) {
+ gss_name_t n = (gss_name_t)name;
+ if (n)
+ gss_release_name(minor_status, &n);
+ gss_release_oid_set(minor_status, mechanisms);
+ *minor_status = 0;
+ return (GSS_S_NO_CRED);
}
*minor_status = 0;
@@ -162,7 +191,13 @@ gss_inquire_cred(OM_uint32 *minor_status,
*name_ret = (gss_name_t) name;
if (lifetime)
*lifetime = min_lifetime;
- if (cred && cred_usage)
- *cred_usage = cred->gc_usage;
+ if (cred_usage) {
+ if ((usagemask & (AUSAGE|IUSAGE)) == (AUSAGE|IUSAGE))
+ *cred_usage = GSS_C_BOTH;
+ else if (usagemask & IUSAGE)
+ *cred_usage = GSS_C_INITIATE;
+ else if (usagemask & AUSAGE)
+ *cred_usage = GSS_C_ACCEPT;
+ }
return (GSS_S_COMPLETE);
}
diff --git a/lib/libgssapi/gss_inquire_cred_by_mech.c b/lib/libgssapi/gss_inquire_cred_by_mech.c
index 2896f77c1e74..d9c21bac2156 100644
--- a/lib/libgssapi/gss_inquire_cred_by_mech.c
+++ b/lib/libgssapi/gss_inquire_cred_by_mech.c
@@ -49,6 +49,14 @@ gss_inquire_cred_by_mech(OM_uint32 *minor_status,
struct _gss_name *name;
*minor_status = 0;
+ if (cred_name)
+ *cred_name = GSS_C_NO_NAME;
+ if (initiator_lifetime)
+ *initiator_lifetime = 0;
+ if (acceptor_lifetime)
+ *acceptor_lifetime = 0;
+ if (cred_usage)
+ *cred_usage = 0;
m = _gss_find_mech_switch(mech_type);
if (!m)
@@ -68,15 +76,21 @@ gss_inquire_cred_by_mech(OM_uint32 *minor_status,
major_status = m->gm_inquire_cred_by_mech(minor_status, mc, mech_type,
&mn, initiator_lifetime, acceptor_lifetime, cred_usage);
- if (major_status != GSS_S_COMPLETE)
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
return (major_status);
+ }
- name = _gss_make_name(m, mn);
- if (!name) {
+ if (cred_name) {
+ name = _gss_make_name(m, mn);
+ if (!name) {
+ m->gm_release_name(minor_status, &mn);
+ return (GSS_S_NO_CRED);
+ }
+ *cred_name = (gss_name_t) name;
+ } else {
m->gm_release_name(minor_status, &mn);
- return (GSS_S_NO_CRED);
}
- *cred_name = (gss_name_t) name;
return (GSS_S_COMPLETE);
}
diff --git a/lib/libgssapi/gss_inquire_cred_by_oid.c b/lib/libgssapi/gss_inquire_cred_by_oid.c
new file mode 100644
index 000000000000..fcb54a1d95bd
--- /dev/null
+++ b/lib/libgssapi/gss_inquire_cred_by_oid.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* $FreeBSD$ */
+
+#include <gssapi/gssapi.h>
+
+#include "mech_switch.h"
+#include "cred.h"
+#include "name.h"
+
+/* RCSID("$Id: gss_inquire_cred_by_oid.c 19960 2007-01-17 15:09:24Z lha $"); */
+
+OM_uint32
+gss_inquire_cred_by_oid (OM_uint32 *minor_status,
+ const gss_cred_id_t cred_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
+ OM_uint32 status = GSS_S_COMPLETE;
+ struct _gss_mechanism_cred *mc;
+ struct _gss_mech_switch *m;
+ gss_buffer_set_t set = GSS_C_NO_BUFFER_SET;
+
+ *minor_status = 0;
+ *data_set = GSS_C_NO_BUFFER_SET;
+
+ if (cred == NULL)
+ return GSS_S_NO_CRED;
+
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ gss_buffer_set_t rset = GSS_C_NO_BUFFER_SET;
+ size_t i;
+
+ m = mc->gmc_mech;
+ if (m == NULL) {
+ gss_release_buffer_set(minor_status, &set);
+ *minor_status = 0;
+ return GSS_S_BAD_MECH;
+ }
+
+ if (m->gm_inquire_cred_by_oid == NULL)
+ continue;
+
+ status = m->gm_inquire_cred_by_oid(minor_status,
+ mc->gmc_cred, desired_object, &rset);
+ if (status != GSS_S_COMPLETE)
+ continue;
+
+ for (i = 0; i < rset->count; i++) {
+ status = gss_add_buffer_set_member(minor_status,
+ &rset->elements[i], &set);
+ if (status != GSS_S_COMPLETE)
+ break;
+ }
+ gss_release_buffer_set(minor_status, &rset);
+ }
+ if (set == GSS_C_NO_BUFFER_SET)
+ status = GSS_S_FAILURE;
+ *data_set = set;
+ *minor_status = 0;
+ return status;
+}
+
diff --git a/lib/libgssapi/gss_inquire_mechs_for_name.c b/lib/libgssapi/gss_inquire_mechs_for_name.c
index 10bdd7fd6314..68918df7fd54 100644
--- a/lib/libgssapi/gss_inquire_mechs_for_name.c
+++ b/lib/libgssapi/gss_inquire_mechs_for_name.c
@@ -44,6 +44,8 @@ gss_inquire_mechs_for_name(OM_uint32 *minor_status,
*minor_status = 0;
+ _gss_load_mech();
+
major_status = gss_create_empty_oid_set(minor_status, mech_types);
if (major_status)
return (major_status);
diff --git a/lib/libgssapi/gss_inquire_names_for_mech.c b/lib/libgssapi/gss_inquire_names_for_mech.c
index 3ebb6328ff69..21f03afb648b 100644
--- a/lib/libgssapi/gss_inquire_names_for_mech.c
+++ b/lib/libgssapi/gss_inquire_names_for_mech.c
@@ -39,6 +39,7 @@ gss_inquire_names_for_mech(OM_uint32 *minor_status,
struct _gss_mech_switch *m = _gss_find_mech_switch(mechanism);
*minor_status = 0;
+ *name_types = GSS_C_NO_OID_SET;
if (!m)
return (GSS_S_BAD_MECH);
@@ -57,15 +58,15 @@ gss_inquire_names_for_mech(OM_uint32 *minor_status,
major_status = gss_add_oid_set_member(minor_status,
GSS_C_NT_HOSTBASED_SERVICE, name_types);
if (major_status) {
- OM_uint32 ms;
- gss_release_oid_set(&ms, name_types);
+ OM_uint32 junk;
+ gss_release_oid_set(&junk, name_types);
return (major_status);
}
major_status = gss_add_oid_set_member(minor_status,
GSS_C_NT_USER_NAME, name_types);
if (major_status) {
- OM_uint32 ms;
- gss_release_oid_set(&ms, name_types);
+ OM_uint32 junk;
+ gss_release_oid_set(&junk, name_types);
return (major_status);
}
}
diff --git a/lib/libgssapi/gss_inquire_sec_context_by_oid.c b/lib/libgssapi/gss_inquire_sec_context_by_oid.c
new file mode 100644
index 000000000000..5a9014210d1b
--- /dev/null
+++ b/lib/libgssapi/gss_inquire_sec_context_by_oid.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 2008 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <gssapi/gssapi.h>
+
+#include "mech_switch.h"
+#include "context.h"
+
+OM_uint32
+gss_inquire_sec_context_by_oid(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *result)
+{
+ OM_uint32 major_status;
+ struct _gss_context *ctx = (struct _gss_context *) context_handle;
+ struct _gss_mech_switch *m;
+
+ *minor_status = 0;
+ *result = GSS_C_NO_BUFFER_SET;
+ if (!ctx)
+ return (GSS_S_NO_CONTEXT);
+
+ m = ctx->gc_mech;
+ if (m->gm_inquire_sec_context_by_oid) {
+ major_status = m->gm_inquire_sec_context_by_oid(
+ minor_status, ctx->gc_ctx, desired_object, result);
+ if (major_status != GSS_S_COMPLETE)
+ _gss_mg_error(m, major_status, *minor_status);
+ } else {
+ major_status = GSS_S_BAD_MECH;
+ }
+
+ return (major_status);
+}
diff --git a/lib/libgssapi/gss_mech_switch.c b/lib/libgssapi/gss_mech_switch.c
index a7528a406e42..f5808c5e411b 100644
--- a/lib/libgssapi/gss_mech_switch.c
+++ b/lib/libgssapi/gss_mech_switch.c
@@ -27,6 +27,7 @@
*/
#include <gssapi/gssapi.h>
+#include <ctype.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdio.h>
@@ -56,6 +57,9 @@ _gss_string_to_oid(const char* s, gss_OID oid)
const char *p, *q;
char *res;
+ oid->length = 0;
+ oid->elements = NULL;
+
/*
* First figure out how many numbers in the oid, then
* calculate the compiled oid size.
@@ -153,23 +157,23 @@ _gss_string_to_oid(const char* s, gss_OID oid)
return (0);
}
-#define SYM(name) \
-do { \
- m->gm_ ## name = dlsym(so, "gss_" #name); \
- if (!m->gm_ ## name) { \
- fprintf(stderr, "can't find symbol gss_" #name "\n"); \
- goto bad; \
- } \
-} while (0)
-#define OPTSYM(name) \
-do { \
- m->gm_ ## name = dlsym(so, "gss_" #name); \
+#define SYM(name) \
+do { \
+ snprintf(buf, sizeof(buf), "%s_%s", \
+ m->gm_name_prefix, #name); \
+ m->gm_ ## name = dlsym(so, buf); \
+ if (!m->gm_ ## name) { \
+ fprintf(stderr, "can't find symbol %s\n", buf); \
+ goto bad; \
+ } \
} while (0)
-#define OPTSYM2(symname, ourname) \
-do { \
- m->ourname = dlsym(so, #symname); \
+#define OPTSYM(name) \
+do { \
+ snprintf(buf, sizeof(buf), "%s_%s", \
+ m->gm_name_prefix, #name); \
+ m->gm_ ## name = dlsym(so, buf); \
} while (0)
/*
@@ -185,8 +189,8 @@ _gss_load_mech(void)
char *name, *oid, *lib, *kobj;
struct _gss_mech_switch *m;
int count;
- char **pp;
void *so;
+ const char *(*prefix_fn)(void);
if (SLIST_FIRST(&_gss_mechs))
return;
@@ -232,6 +236,13 @@ _gss_load_mech(void)
continue;
}
+ prefix_fn = (const char *(*)(void))
+ dlsym(so, "_gss_name_prefix");
+ if (prefix_fn)
+ m->gm_name_prefix = prefix_fn();
+ else
+ m->gm_name_prefix = "gss";
+
major_status = gss_add_oid_set_member(&minor_status,
&m->gm_mech_oid, &_gss_mech_oids);
if (major_status) {
@@ -252,7 +263,7 @@ _gss_load_mech(void)
SYM(wrap);
SYM(unwrap);
SYM(display_status);
- SYM(indicate_mechs);
+ OPTSYM(indicate_mechs);
SYM(compare_name);
SYM(display_name);
SYM(import_name);
@@ -269,10 +280,11 @@ _gss_load_mech(void)
SYM(inquire_mechs_for_name);
SYM(canonicalize_name);
SYM(duplicate_name);
- OPTSYM2(gsskrb5_register_acceptor_identity,
- gm_krb5_register_acceptor_identity);
- OPTSYM(krb5_copy_ccache);
- OPTSYM(krb5_compat_des3_mic);
+ OPTSYM(inquire_sec_context_by_oid);
+ OPTSYM(inquire_cred_by_oid);
+ OPTSYM(set_sec_context_option);
+ OPTSYM(set_cred_option);
+ OPTSYM(pseudo_random);
SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
count++;
@@ -294,7 +306,7 @@ _gss_find_mech_switch(gss_OID mech)
_gss_load_mech();
SLIST_FOREACH(m, &_gss_mechs, gm_link) {
- if (_gss_oid_equal(&m->gm_mech_oid, mech))
+ if (gss_oid_equal(&m->gm_mech_oid, mech))
return m;
}
return (0);
diff --git a/lib/libgssapi/gss_names.c b/lib/libgssapi/gss_names.c
index d10350a9541a..02775ec72db3 100644
--- a/lib/libgssapi/gss_names.c
+++ b/lib/libgssapi/gss_names.c
@@ -33,6 +33,7 @@
#include "mech_switch.h"
#include "name.h"
+#include "utils.h"
/*
* The implementation must reserve static storage for a
@@ -46,7 +47,7 @@
* to that gss_OID_desc.
*/
static gss_OID_desc GSS_C_NT_USER_NAME_storage =
- {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"};
+ {10, (void *)(uintptr_t)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"};
gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_storage;
/*
@@ -61,7 +62,7 @@ gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_storage;
* initialized to point to that gss_OID_desc.
*/
static gss_OID_desc GSS_C_NT_MACHINE_UID_NAME_storage =
- {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"};
+ {10, (void *)(uintptr_t)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"};
gss_OID GSS_C_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_storage;
/*
@@ -76,7 +77,7 @@ gss_OID GSS_C_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_storage;
* initialized to point to that gss_OID_desc.
*/
static gss_OID_desc GSS_C_NT_STRING_UID_NAME_storage =
- {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"};
+ {10, (void *)(uintptr_t)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"};
gss_OID GSS_C_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_storage;
/*
@@ -97,7 +98,7 @@ gss_OID GSS_C_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_storage;
* implementations
*/
static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_X_storage =
- {6, (void *)"\x2b\x06\x01\x05\x06\x02"};
+ {6, (void *)(uintptr_t)"\x2b\x06\x01\x05\x06\x02"};
gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &GSS_C_NT_HOSTBASED_SERVICE_X_storage;
/*
@@ -112,7 +113,7 @@ gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &GSS_C_NT_HOSTBASED_SERVICE_X_storage;
* to point to that gss_OID_desc.
*/
static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_storage =
- {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"};
+ {10, (void *)(uintptr_t)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"};
gss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_storage;
/*
@@ -126,7 +127,7 @@ gss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_storage;
* to that gss_OID_desc.
*/
static gss_OID_desc GSS_C_NT_ANONYMOUS_storage =
- {6, (void *)"\x2b\x06\01\x05\x06\x03"};
+ {6, (void *)(uintptr_t)"\x2b\x06\01\x05\x06\x03"};
gss_OID GSS_C_NT_ANONYMOUS = &GSS_C_NT_ANONYMOUS_storage;
/*
@@ -140,7 +141,7 @@ gss_OID GSS_C_NT_ANONYMOUS = &GSS_C_NT_ANONYMOUS_storage;
* to that gss_OID_desc.
*/
static gss_OID_desc GSS_C_NT_EXPORT_NAME_storage =
- {6, (void *)"\x2b\x06\x01\x05\x06\x04"};
+ {6, (void *)(uintptr_t)"\x2b\x06\x01\x05\x06\x04"};
gss_OID GSS_C_NT_EXPORT_NAME = &GSS_C_NT_EXPORT_NAME_storage;
/*
@@ -150,7 +151,7 @@ gss_OID GSS_C_NT_EXPORT_NAME = &GSS_C_NT_EXPORT_NAME_storage;
* is "GSS_KRB5_NT_PRINCIPAL_NAME".
*/
static gss_OID_desc GSS_KRB5_NT_PRINCIPAL_NAME_storage =
- {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"};
+ {10, (void *)(uintptr_t)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"};
gss_OID GSS_KRB5_NT_PRINCIPAL_NAME = &GSS_KRB5_NT_PRINCIPAL_NAME_storage;
/*
@@ -177,15 +178,18 @@ gss_OID GSS_KRB5_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_storage;
*/
gss_OID GSS_KRB5_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_storage;
-struct _gss_mechanism_name *
-_gss_find_mn(struct _gss_name *name, gss_OID mech)
+OM_uint32
+_gss_find_mn(OM_uint32 *minor_status, struct _gss_name *name, gss_OID mech,
+ struct _gss_mechanism_name **output_mn)
{
- OM_uint32 major_status, minor_status;
+ OM_uint32 major_status;
struct _gss_mech_switch *m;
struct _gss_mechanism_name *mn;
+ *output_mn = NULL;
+
SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {
- if (_gss_oid_equal(mech, mn->gmn_mech_oid))
+ if (gss_oid_equal(mech, mn->gmn_mech_oid))
break;
}
@@ -195,40 +199,42 @@ _gss_find_mn(struct _gss_name *name, gss_OID mech)
* MN but it is from a different mech), give up now.
*/
if (!name->gn_value.value)
- return (0);
+ return (GSS_S_BAD_NAME);
m = _gss_find_mech_switch(mech);
if (!m)
- return (0);
+ return (GSS_S_BAD_MECH);
mn = malloc(sizeof(struct _gss_mechanism_name));
if (!mn)
- return (0);
+ return (GSS_S_FAILURE);
- major_status = m->gm_import_name(&minor_status,
+ major_status = m->gm_import_name(minor_status,
&name->gn_value,
(name->gn_type.elements
? &name->gn_type : GSS_C_NO_OID),
&mn->gmn_name);
- if (major_status) {
+ if (major_status != GSS_S_COMPLETE) {
+ _gss_mg_error(m, major_status, *minor_status);
free(mn);
- return (0);
+ return (major_status);
}
mn->gmn_mech = m;
mn->gmn_mech_oid = &m->gm_mech_oid;
SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
}
- return (mn);
+ *output_mn = mn;
+ return (GSS_S_COMPLETE);
}
+
/*
* Make a name from an MN.
*/
struct _gss_name *
_gss_make_name(struct _gss_mech_switch *m, gss_name_t new_mn)
{
- OM_uint32 minor_status;
struct _gss_name *name;
struct _gss_mechanism_name *mn;
diff --git a/lib/libgssapi/gss_oid_to_str.c b/lib/libgssapi/gss_oid_to_str.c
new file mode 100644
index 000000000000..05e0d73887d8
--- /dev/null
+++ b/lib/libgssapi/gss_oid_to_str.c
@@ -0,0 +1,118 @@
+/*-
+ * Copyright (c) 2000 The Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
+ * All rights reserved, all wrongs reversed.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/* $FreeBSD$ */
+
+#include <gssapi/gssapi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "utils.h"
+
+OM_uint32
+gss_oid_to_str(OM_uint32 *minor_status, gss_OID oid, gss_buffer_t oid_str)
+{
+ char numstr[128];
+ unsigned long number;
+ int numshift;
+ size_t string_length;
+ size_t i;
+ unsigned char *cp;
+ char *bp;
+
+ *minor_status = 0;
+ _gss_buffer_zero(oid_str);
+
+ if (oid == GSS_C_NULL_OID)
+ return (GSS_S_FAILURE);
+
+ /* Decoded according to krb5/gssapi_krb5.c */
+
+ /* First determine the size of the string */
+ string_length = 0;
+ number = 0;
+ numshift = 0;
+ cp = (unsigned char *) oid->elements;
+ number = (unsigned long) cp[0];
+ sprintf(numstr, "%ld ", number/40);
+ string_length += strlen(numstr);
+ sprintf(numstr, "%ld ", number%40);
+ string_length += strlen(numstr);
+ for (i=1; i<oid->length; i++) {
+ if ( (size_t) (numshift+7) < (sizeof(unsigned long)*8)) {
+ number = (number << 7) | (cp[i] & 0x7f);
+ numshift += 7;
+ }
+ else {
+ *minor_status = 0;
+ return(GSS_S_FAILURE);
+ }
+ if ((cp[i] & 0x80) == 0) {
+ sprintf(numstr, "%ld ", number);
+ string_length += strlen(numstr);
+ number = 0;
+ numshift = 0;
+ }
+ }
+ /*
+ * If we get here, we've calculated the length of "n n n ... n ".
+ * Add 4 here for "{ " and "}\0".
+ */
+ string_length += 4;
+ if ((bp = (char *) malloc(string_length))) {
+ strcpy(bp, "{ ");
+ number = (unsigned long) cp[0];
+ sprintf(numstr, "%ld ", number/40);
+ strcat(bp, numstr);
+ sprintf(numstr, "%ld ", number%40);
+ strcat(bp, numstr);
+ number = 0;
+ cp = (unsigned char *) oid->elements;
+ for (i=1; i<oid->length; i++) {
+ number = (number << 7) | (cp[i] & 0x7f);
+ if ((cp[i] & 0x80) == 0) {
+ sprintf(numstr, "%ld ", number);
+ strcat(bp, numstr);
+ number = 0;
+ }
+ }
+ strcat(bp, "}");
+ oid_str->length = strlen(bp)+1;
+ oid_str->value = (void *) bp;
+ *minor_status = 0;
+ return(GSS_S_COMPLETE);
+ }
+ *minor_status = ENOMEM;
+ return(GSS_S_FAILURE);
+}
diff --git a/lib/libgssapi/gss_pseudo_random.c b/lib/libgssapi/gss_pseudo_random.c
new file mode 100644
index 000000000000..72166099512a
--- /dev/null
+++ b/lib/libgssapi/gss_pseudo_random.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* $FreeBSD$ */
+/* $Id: gss_pseudo_random.c 20053 2007-01-24 01:31:35Z lha $ */
+
+#include <gssapi/gssapi.h>
+
+#include "mech_switch.h"
+#include "context.h"
+#include "utils.h"
+
+OM_uint32
+gss_pseudo_random(OM_uint32 *minor_status,
+ gss_ctx_id_t context,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ struct _gss_context *ctx = (struct _gss_context *) context;
+ struct _gss_mech_switch *m = ctx->gc_mech;
+ OM_uint32 major_status;
+
+ _gss_buffer_zero(prf_out);
+ *minor_status = 0;
+
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ if (m->gm_pseudo_random == NULL)
+ return GSS_S_UNAVAILABLE;
+
+ major_status = (*m->gm_pseudo_random)(minor_status, ctx->gc_ctx,
+ prf_key, prf_in, desired_output_len,
+ prf_out);
+ if (major_status != GSS_S_COMPLETE)
+ _gss_mg_error(m, major_status, *minor_status);
+
+ return major_status;
+}
diff --git a/lib/libgssapi/gss_release_buffer.c b/lib/libgssapi/gss_release_buffer.c
index 8e7fa60e5471..7a85745abc5b 100644
--- a/lib/libgssapi/gss_release_buffer.c
+++ b/lib/libgssapi/gss_release_buffer.c
@@ -27,6 +27,9 @@
*/
#include <gssapi/gssapi.h>
+#include <stdlib.h>
+
+#include "utils.h"
OM_uint32
gss_release_buffer(OM_uint32 *minor_status,
@@ -36,8 +39,7 @@ gss_release_buffer(OM_uint32 *minor_status,
*minor_status = 0;
if (buffer->value)
free(buffer->value);
- buffer->length = 0;
- buffer->value = 0;
+ _gss_buffer_zero(buffer);
return (GSS_S_COMPLETE);
}
diff --git a/lib/libgssapi/gss_release_cred.c b/lib/libgssapi/gss_release_cred.c
index cec814c66291..6093acd8f3b7 100644
--- a/lib/libgssapi/gss_release_cred.c
+++ b/lib/libgssapi/gss_release_cred.c
@@ -51,6 +51,6 @@ gss_release_cred(OM_uint32 *minor_status, gss_cred_id_t *cred_handle)
free(cred);
*minor_status = 0;
- *cred_handle = 0;
+ *cred_handle = GSS_C_NO_CREDENTIAL;
return (GSS_S_COMPLETE);
}
diff --git a/lib/libgssapi/gss_release_name.c b/lib/libgssapi/gss_release_name.c
index 4294ad7c4b48..08ae10a26ec3 100644
--- a/lib/libgssapi/gss_release_name.c
+++ b/lib/libgssapi/gss_release_name.c
@@ -38,7 +38,6 @@ gss_release_name(OM_uint32 *minor_status,
gss_name_t *input_name)
{
struct _gss_name *name = (struct _gss_name *) *input_name;
- struct _gss_mech_switch *m;
*minor_status = 0;
if (name) {
@@ -53,7 +52,8 @@ gss_release_name(OM_uint32 *minor_status,
free(mn);
}
gss_release_buffer(minor_status, &name->gn_value);
- *input_name = 0;
+ free(name);
+ *input_name = GSS_C_NO_NAME;
}
return (GSS_S_COMPLETE);
}
diff --git a/lib/libgssapi/gss_release_oid.c b/lib/libgssapi/gss_release_oid.c
new file mode 100644
index 000000000000..a2e7a61a6678
--- /dev/null
+++ b/lib/libgssapi/gss_release_oid.c
@@ -0,0 +1,61 @@
+/*-
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* $FreeBSD$ */
+
+#include <gssapi/gssapi.h>
+#include <stdlib.h>
+
+/* RCSID("$Id: gss_release_oid.c 17747 2006-06-30 09:34:54Z lha $"); */
+
+OM_uint32
+gss_release_oid(OM_uint32 *minor_status, gss_OID *oid)
+{
+ gss_OID o = *oid;
+
+ *oid = GSS_C_NO_OID;
+
+ if (minor_status != NULL)
+ *minor_status = 0;
+
+ if (o == GSS_C_NO_OID)
+ return (GSS_S_COMPLETE);
+
+ if (o->elements != NULL) {
+ free(o->elements);
+ o->elements = NULL;
+ }
+ o->length = 0;
+ free(o);
+
+ return (GSS_S_COMPLETE);
+}
diff --git a/lib/libgssapi/gss_release_oid_set.c b/lib/libgssapi/gss_release_oid_set.c
index 49c17ab8326a..bedb90ba8439 100644
--- a/lib/libgssapi/gss_release_oid_set.c
+++ b/lib/libgssapi/gss_release_oid_set.c
@@ -36,11 +36,11 @@ gss_release_oid_set(OM_uint32 *minor_status,
{
*minor_status = 0;
- if (*set) {
+ if (set && *set) {
if ((*set)->elements)
free((*set)->elements);
free(*set);
- *set = 0;
+ *set = GSS_C_NO_OID_SET;
}
return (GSS_S_COMPLETE);
}
diff --git a/lib/libgssapi/gss_set_cred_option.c b/lib/libgssapi/gss_set_cred_option.c
new file mode 100644
index 000000000000..93b221294651
--- /dev/null
+++ b/lib/libgssapi/gss_set_cred_option.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* $FreeBSD$ */
+/* RCSID("$Id: gss_set_cred_option.c 21126 2007-06-18 20:19:59Z lha $"); */
+
+#include <gssapi/gssapi.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "mech_switch.h"
+#include "cred.h"
+
+OM_uint32
+gss_set_cred_option (OM_uint32 *minor_status,
+ gss_cred_id_t *cred_handle,
+ const gss_OID object,
+ const gss_buffer_t value)
+{
+ struct _gss_cred *cred = (struct _gss_cred *) *cred_handle;
+ OM_uint32 major_status = GSS_S_COMPLETE;
+ struct _gss_mechanism_cred *mc;
+ int one_ok = 0;
+
+ *minor_status = 0;
+
+ _gss_load_mech();
+
+ if (cred == NULL) {
+ struct _gss_mech_switch *m;
+
+ cred = malloc(sizeof(*cred));
+ if (cred == NULL)
+ return GSS_S_FAILURE;
+
+ SLIST_INIT(&cred->gc_mc);
+
+ SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+
+ if (m->gm_set_cred_option == NULL)
+ continue;
+
+ mc = malloc(sizeof(*mc));
+ if (mc == NULL) {
+ *cred_handle = (gss_cred_id_t)cred;
+ gss_release_cred(minor_status, cred_handle);
+ *minor_status = ENOMEM;
+ return GSS_S_FAILURE;
+ }
+
+ mc->gmc_mech = m;
+ mc->gmc_mech_oid = &m->gm_mech_oid;
+ mc->gmc_cred = GSS_C_NO_CREDENTIAL;
+
+ major_status = m->gm_set_cred_option(
+ minor_status, &mc->gmc_cred, object, value);
+
+ if (major_status) {
+ free(mc);
+ continue;
+ }
+ one_ok = 1;
+ SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
+ }
+ *cred_handle = (gss_cred_id_t)cred;
+ if (!one_ok) {
+ OM_uint32 junk;
+ gss_release_cred(&junk, cred_handle);
+ }
+ } else {
+ struct _gss_mech_switch *m;
+
+ SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
+ m = mc->gmc_mech;
+
+ if (m == NULL)
+ return GSS_S_BAD_MECH;
+
+ if (m->gm_set_cred_option == NULL)
+ continue;
+
+ major_status = m->gm_set_cred_option(minor_status,
+ &mc->gmc_cred, object, value);
+ if (major_status == GSS_S_COMPLETE)
+ one_ok = 1;
+ else
+ _gss_mg_error(m, major_status, *minor_status);
+
+ }
+ }
+ if (one_ok) {
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+ }
+ return (major_status);
+}
+
diff --git a/lib/libgssapi/gss_set_sec_context_option.c b/lib/libgssapi/gss_set_sec_context_option.c
new file mode 100644
index 000000000000..4b6bf1bda269
--- /dev/null
+++ b/lib/libgssapi/gss_set_sec_context_option.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2004, PADL Software Pty Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of PADL Software nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* $FreeBSD$ */
+/* RCSID("$Id: gss_set_sec_context_option.c 19928 2007-01-16 10:37:54Z lha $"); */
+
+#include <gssapi/gssapi.h>
+
+#include "mech_switch.h"
+#include "context.h"
+
+OM_uint32
+gss_set_sec_context_option (OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_OID object,
+ const gss_buffer_t value)
+{
+ struct _gss_context *ctx;
+ OM_uint32 major_status;
+ struct _gss_mech_switch *m;
+ int one_ok = 0;
+
+ *minor_status = 0;
+
+ if (context_handle == NULL) {
+ _gss_load_mech();
+ major_status = GSS_S_BAD_MECH;
+ SLIST_FOREACH(m, &_gss_mechs, gm_link) {
+ if (!m->gm_set_sec_context_option)
+ continue;
+ major_status = m->gm_set_sec_context_option(
+ minor_status,
+ NULL, object, value);
+ if (major_status == GSS_S_COMPLETE)
+ one_ok = 1;
+ }
+ if (one_ok) {
+ *minor_status = 0;
+ return (GSS_S_COMPLETE);
+ }
+ return (major_status);
+ }
+
+ ctx = (struct _gss_context *) *context_handle;
+
+ if (ctx == NULL)
+ return (GSS_S_NO_CONTEXT);
+
+ m = ctx->gc_mech;
+
+ if (m == NULL)
+ return (GSS_S_BAD_MECH);
+
+ if (m->gm_set_sec_context_option != NULL) {
+ major_status = m->gm_set_sec_context_option(minor_status,
+ &ctx->gc_ctx, object, value);
+ if (major_status != GSS_S_COMPLETE)
+ _gss_mg_error(m, major_status, *minor_status);
+ } else
+ major_status = (GSS_S_BAD_MECH);
+
+ return (major_status);
+}
+
diff --git a/lib/libgssapi/gss_test_oid_set_member.c b/lib/libgssapi/gss_test_oid_set_member.c
index 62175ca9d365..0421319eb149 100644
--- a/lib/libgssapi/gss_test_oid_set_member.c
+++ b/lib/libgssapi/gss_test_oid_set_member.c
@@ -36,11 +36,11 @@ gss_test_oid_set_member(OM_uint32 *minor_status,
const gss_OID_set set,
int *present)
{
- int i;
+ size_t i;
*present = 0;
for (i = 0; i < set->count; i++)
- if (_gss_oid_equal(member, &set->elements[i]))
+ if (gss_oid_equal(member, &set->elements[i]))
*present = 1;
*minor_status = 0;
diff --git a/lib/libgssapi/gss_unseal.c b/lib/libgssapi/gss_unseal.c
index bc7dc26111c0..c3775103ce4f 100644
--- a/lib/libgssapi/gss_unseal.c
+++ b/lib/libgssapi/gss_unseal.c
@@ -39,5 +39,5 @@ gss_unseal(OM_uint32 *minor_status,
return (gss_unwrap(minor_status,
context_handle, input_message_buffer,
- output_message_buffer, conf_state, qop_state));
+ output_message_buffer, conf_state, (gss_qop_t *)qop_state));
}
diff --git a/lib/libgssapi/gss_utils.c b/lib/libgssapi/gss_utils.c
index 1f8dfab9fe6d..ec582a9bd1a4 100644
--- a/lib/libgssapi/gss_utils.c
+++ b/lib/libgssapi/gss_utils.c
@@ -34,7 +34,7 @@
#include "utils.h"
int
-_gss_oid_equal(const gss_OID oid1, const gss_OID oid2)
+gss_oid_equal(const gss_OID oid1, const gss_OID oid2)
{
if (oid1 == oid2)
@@ -57,6 +57,7 @@ _gss_copy_oid(OM_uint32 *minor_status,
*minor_status = 0;
to_oid->elements = malloc(len);
if (!to_oid->elements) {
+ to_oid->length = 0;
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
@@ -76,6 +77,7 @@ _gss_copy_buffer(OM_uint32 *minor_status,
to_buf->value = malloc(len);
if (!to_buf->value) {
*minor_status = ENOMEM;
+ to_buf->length = 0;
return GSS_S_FAILURE;
}
to_buf->length = len;
diff --git a/lib/libgssapi/gss_verify.c b/lib/libgssapi/gss_verify.c
index 31108750e3dd..0aa3fd67e28b 100644
--- a/lib/libgssapi/gss_verify.c
+++ b/lib/libgssapi/gss_verify.c
@@ -37,5 +37,6 @@ gss_verify(OM_uint32 *minor_status,
{
return (gss_verify_mic(minor_status,
- context_handle, message_buffer, token_buffer, qop_state));
+ context_handle, message_buffer, token_buffer,
+ (gss_qop_t *)qop_state));
}
diff --git a/lib/libgssapi/gss_verify_mic.c b/lib/libgssapi/gss_verify_mic.c
index 4e11ab1e08fc..fa3d68d035fe 100644
--- a/lib/libgssapi/gss_verify_mic.c
+++ b/lib/libgssapi/gss_verify_mic.c
@@ -41,6 +41,13 @@ gss_verify_mic(OM_uint32 *minor_status,
struct _gss_context *ctx = (struct _gss_context *) context_handle;
struct _gss_mech_switch *m = ctx->gc_mech;
+ if (qop_state)
+ *qop_state = 0;
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return (GSS_S_NO_CONTEXT);
+ }
+
return (m->gm_verify_mic(minor_status, ctx->gc_ctx,
message_buffer, token_buffer, qop_state));
}
diff --git a/lib/libgssapi/gss_wrap.c b/lib/libgssapi/gss_wrap.c
index 0d7c74933c31..2f9431694a5f 100644
--- a/lib/libgssapi/gss_wrap.c
+++ b/lib/libgssapi/gss_wrap.c
@@ -30,6 +30,7 @@
#include "mech_switch.h"
#include "context.h"
+#include "utils.h"
OM_uint32
gss_wrap(OM_uint32 *minor_status,
@@ -43,6 +44,14 @@ gss_wrap(OM_uint32 *minor_status,
struct _gss_context *ctx = (struct _gss_context *) context_handle;
struct _gss_mech_switch *m = ctx->gc_mech;
+ if (conf_state)
+ *conf_state = 0;
+ _gss_buffer_zero(output_message_buffer);
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return (GSS_S_NO_CONTEXT);
+ }
+
return (m->gm_wrap(minor_status, ctx->gc_ctx,
conf_req_flag, qop_req, input_message_buffer,
conf_state, output_message_buffer));
diff --git a/lib/libgssapi/gss_wrap_size_limit.c b/lib/libgssapi/gss_wrap_size_limit.c
index 8abd52a12094..15a870676da4 100644
--- a/lib/libgssapi/gss_wrap_size_limit.c
+++ b/lib/libgssapi/gss_wrap_size_limit.c
@@ -42,6 +42,12 @@ gss_wrap_size_limit(OM_uint32 *minor_status,
struct _gss_context *ctx = (struct _gss_context *) context_handle;
struct _gss_mech_switch *m = ctx->gc_mech;
+ *max_input_size = 0;
+ if (ctx == NULL) {
+ *minor_status = 0;
+ return (GSS_S_NO_CONTEXT);
+ }
+
return (m->gm_wrap_size_limit(minor_status, ctx->gc_ctx,
conf_req_flag, qop_req, req_output_size, max_input_size));
}
diff --git a/lib/libgssapi/mech.5 b/lib/libgssapi/mech.5
index 1edcc1a846df..fd17e3a21b04 100644
--- a/lib/libgssapi/mech.5
+++ b/lib/libgssapi/mech.5
@@ -50,11 +50,18 @@ A shared library containing the implementation of this mechanism.
A kernel module containing the implementation of this mechanism (not
yet supported in FreeBSD).
.It Library options (optional)
-Optionsal parameters interpreted by the mechanism. Library options
+Optional parameters interpreted by the mechanism. Library options
must be enclosed in brackets ([ ]) to differentiate them from the
optional kernel module entry.
.El
.Pp
+The first mechanism listed in
+.Pa "/etc/gss/mech"
+is the default mechanism.
+This mechanism will be used by
+.Xr gss_init_sec_context 3
+if the user doesn't specify a specific mechanism.
+.Pp
The
.Pa "/etc/gss/qop"
file contains a list of Quality of Protection values for use with
diff --git a/lib/libgssapi/mech_switch.h b/lib/libgssapi/mech_switch.h
index 4add12d8af10..876adcda9e64 100644
--- a/lib/libgssapi/mech_switch.h
+++ b/lib/libgssapi/mech_switch.h
@@ -26,6 +26,7 @@
* $FreeBSD$
*/
+#include <unistd.h>
#include <sys/queue.h>
typedef OM_uint32 _gss_acquire_cred_t
@@ -266,24 +267,46 @@ typedef OM_uint32 _gss_duplicate_name_t (
gss_name_t * /* dest_name */
);
-typedef OM_uint32 _gsskrb5_register_acceptor_identity (
- const char * /* identity */
+typedef OM_uint32 _gss_inquire_sec_context_by_oid
+ (OM_uint32 *, /* minor_status */
+ const gss_ctx_id_t, /* context_handle */
+ const gss_OID, /* desired_object */
+ gss_buffer_set_t * /* result */
);
-typedef OM_uint32 _gss_krb5_copy_ccache (
- OM_uint32 *, /* minor_status */
- gss_cred_id_t, /* cred_handle */
- struct krb5_ccache_data * /* out */
+typedef OM_uint32 _gss_inquire_cred_by_oid
+ (OM_uint32 *, /* bminor_status */
+ const gss_cred_id_t, /* cred_handle, */
+ const gss_OID, /* desired_object */
+ gss_buffer_set_t * /* data_set */
);
-typedef OM_uint32 _gss_krb5_compat_des3_mic (
- OM_uint32 *, /* minor_status */
- gss_ctx_id_t, /* context_handle */
- int /* flag */
+typedef OM_uint32 _gss_set_sec_context_option
+ (OM_uint32 *, /* minor status */
+ gss_ctx_id_t *, /* context */
+ const gss_OID, /* option to set */
+ const gss_buffer_t /* option value */
+ );
+
+typedef OM_uint32 _gss_set_cred_option
+ (OM_uint32 *, /* minor status */
+ gss_cred_id_t *, /* cred */
+ const gss_OID, /* option to set */
+ const gss_buffer_t /* option value */
+ );
+
+typedef OM_uint32 _gss_pseudo_random
+ (OM_uint32 *, /* minor status */
+ gss_ctx_id_t, /* context */
+ int, /* PRF key */
+ const gss_buffer_t, /* PRF input */
+ ssize_t, /* desired output length */
+ gss_buffer_t /* PRF output */
);
struct _gss_mech_switch {
SLIST_ENTRY(_gss_mech_switch) gm_link;
+ const char *gm_name_prefix;
gss_OID_desc gm_mech_oid;
void *gm_so;
_gss_acquire_cred_t *gm_acquire_cred;
@@ -315,9 +338,11 @@ struct _gss_mech_switch {
_gss_inquire_mechs_for_name_t *gm_inquire_mechs_for_name;
_gss_canonicalize_name_t *gm_canonicalize_name;
_gss_duplicate_name_t *gm_duplicate_name;
- _gsskrb5_register_acceptor_identity *gm_krb5_register_acceptor_identity;
- _gss_krb5_copy_ccache *gm_krb5_copy_ccache;
- _gss_krb5_compat_des3_mic *gm_krb5_compat_des3_mic;
+ _gss_inquire_sec_context_by_oid *gm_inquire_sec_context_by_oid;
+ _gss_inquire_cred_by_oid *gm_inquire_cred_by_oid;
+ _gss_set_sec_context_option *gm_set_sec_context_option;
+ _gss_set_cred_option *gm_set_cred_option;
+ _gss_pseudo_random *gm_pseudo_random;
};
SLIST_HEAD(_gss_mech_switch_list, _gss_mech_switch);
extern struct _gss_mech_switch_list _gss_mechs;
@@ -325,3 +350,5 @@ extern gss_OID_set _gss_mech_oids;
extern void _gss_load_mech(void);
extern struct _gss_mech_switch *_gss_find_mech_switch(gss_OID);
+extern void _gss_mg_error(struct _gss_mech_switch *m, OM_uint32 maj,
+ OM_uint32 min);
diff --git a/lib/libgssapi/name.h b/lib/libgssapi/name.h
index a64d5d91e728..7f54359dc003 100644
--- a/lib/libgssapi/name.h
+++ b/lib/libgssapi/name.h
@@ -42,7 +42,8 @@ struct _gss_name {
struct _gss_mechanism_name_list gn_mn; /* list of MNs */
};
-extern struct _gss_mechanism_name *
- _gss_find_mn(struct _gss_name *name, gss_OID mech);
-struct _gss_name *
+extern OM_uint32
+ _gss_find_mn(OM_uint32 *, struct _gss_name *, gss_OID,
+ struct _gss_mechanism_name **);
+extern struct _gss_name *
_gss_make_name(struct _gss_mech_switch *m, gss_name_t new_mn);
diff --git a/lib/libgssapi/utils.h b/lib/libgssapi/utils.h
index 46edb9d4a25a..a54cb5089c03 100644
--- a/lib/libgssapi/utils.h
+++ b/lib/libgssapi/utils.h
@@ -26,6 +26,8 @@
* $FreeBSD$
*/
+#define _gss_buffer_zero(buffer) \
+ do { (buffer)->value = NULL; (buffer)->length = 0; } while(0)
extern int _gss_oid_equal(const gss_OID, const gss_OID);
extern OM_uint32 _gss_copy_oid(OM_uint32 *, const gss_OID, gss_OID);
extern OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status,