summaryrefslogtreecommitdiffstats
path: root/src/lib/gssapi
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2009-12-17 04:49:27 +0000
committerGreg Hudson <ghudson@mit.edu>2009-12-17 04:49:27 +0000
commit00784193904880a9e7f73ff477d287cd22d4e158 (patch)
treef04c444af920a28dcbbe4f1730db6021301211b7 /src/lib/gssapi
parent09b6eb4836a4ec82fc2145db185737a9e7d4b9e1 (diff)
downloadkrb5-00784193904880a9e7f73ff477d287cd22d4e158.tar.gz
krb5-00784193904880a9e7f73ff477d287cd22d4e158.tar.xz
krb5-00784193904880a9e7f73ff477d287cd22d4e158.zip
Add GSS extensions to store credentials, generate random bits
Merge /users/lhoward/gssextras-no-cqa to trunk. Adds gss_pseudo_random and gss_store_cred. ticket: 6597 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@23479 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/gssapi')
-rw-r--r--src/lib/gssapi/generic/gssapi.hin25
-rw-r--r--src/lib/gssapi/krb5/Makefile.in6
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h18
-rw-r--r--src/lib/gssapi/krb5/gssapi_err_krb5.et1
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.c3
-rw-r--r--src/lib/gssapi/krb5/prf.c139
-rw-r--r--src/lib/gssapi/krb5/store_cred.c188
-rw-r--r--src/lib/gssapi/libgssapi_krb5.exports2
-rw-r--r--src/lib/gssapi/mechglue/Makefile.in3
-rw-r--r--src/lib/gssapi/mechglue/g_initialize.c2
-rw-r--r--src/lib/gssapi/mechglue/g_prf.c84
-rw-r--r--src/lib/gssapi/mechglue/g_store_cred.c2
-rw-r--r--src/lib/gssapi/mechglue/mglueP.h10
-rw-r--r--src/lib/gssapi/spnego/gssapiP_spnego.h11
-rw-r--r--src/lib/gssapi/spnego/spnego_mech.c19
15 files changed, 511 insertions, 2 deletions
diff --git a/src/lib/gssapi/generic/gssapi.hin b/src/lib/gssapi/generic/gssapi.hin
index 422b4dbef..e60d04d87 100644
--- a/src/lib/gssapi/generic/gssapi.hin
+++ b/src/lib/gssapi/generic/gssapi.hin
@@ -780,6 +780,31 @@ gss_canonicalize_name(
const gss_OID, /* mech_type */
gss_name_t *); /* output_name */
+/* RFC 4401 */
+
+#define GSS_C_PRF_KEY_FULL 0
+#define GSS_C_PRF_KEY_PARTIAL 1
+
+OM_uint32 KRB5_CALLCONV
+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 */
+
+OM_uint32 KRB5_CALLCONV
+gss_store_cred(
+ OM_uint32 *, /* minor_status */
+ const gss_cred_id_t,/* input_cred_handle */
+ gss_cred_usage_t, /* input_usage */
+ const gss_OID, /* desired_mech */
+ OM_uint32, /* overwrite_cred */
+ OM_uint32, /* default_cred */
+ gss_OID_set *, /* elements_stored */
+ gss_cred_usage_t *);/* cred_usage_stored */
+
#if TARGET_OS_MAC
# pragma pack(pop)
#endif
diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in
index 6dee42367..01591b2c0 100644
--- a/src/lib/gssapi/krb5/Makefile.in
+++ b/src/lib/gssapi/krb5/Makefile.in
@@ -68,6 +68,7 @@ SRCS = \
$(srcdir)/krb5_gss_glue.c \
$(srcdir)/lucid_context.c \
$(srcdir)/naming_exts.c \
+ $(srcdir)/prf.c \
$(srcdir)/process_context_token.c \
$(srcdir)/rel_cred.c \
$(srcdir)/rel_oid.c \
@@ -78,6 +79,7 @@ SRCS = \
$(srcdir)/ser_sctx.c \
$(srcdir)/set_ccache.c \
$(srcdir)/sign.c \
+ $(srcdir)/store_cred.c \
$(srcdir)/unseal.c \
$(srcdir)/util_cksum.c \
$(srcdir)/util_crypt.c \
@@ -120,6 +122,7 @@ OBJS = \
$(OUTPRE)krb5_gss_glue.$(OBJEXT) \
$(OUTPRE)lucid_context.$(OBJEXT) \
$(OUTPRE)naming_exts.$(OBJEXT) \
+ $(OUTPRE)prf.$(OBJEXT) \
$(OUTPRE)process_context_token.$(OBJEXT) \
$(OUTPRE)rel_cred.$(OBJEXT) \
$(OUTPRE)rel_oid.$(OBJEXT) \
@@ -130,6 +133,7 @@ OBJS = \
$(OUTPRE)ser_sctx.$(OBJEXT) \
$(OUTPRE)set_ccache.$(OBJEXT) \
$(OUTPRE)sign.$(OBJEXT) \
+ $(OUTPRE)store_cred.$(OBJEXT) \
$(OUTPRE)unseal.$(OBJEXT) \
$(OUTPRE)util_cksum.$(OBJEXT) \
$(OUTPRE)util_crypt.$(OBJEXT) \
@@ -175,6 +179,7 @@ STLIBOBJS = \
krb5_gss_glue.o \
lucid_context.o \
naming_exts.o \
+ prf.o \
process_context_token.o \
rel_cred.o \
rel_oid.o \
@@ -185,6 +190,7 @@ STLIBOBJS = \
ser_sctx.o \
set_ccache.o \
sign.o \
+ store_cred.o \
unseal.o \
util_cksum.o \
util_crypt.o \
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 0127e8ccb..2ac4b3ae2 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -909,6 +909,24 @@ krb5_gss_release_any_name_mapping(OM_uint32 *minor_status,
gss_buffer_t type_id,
gss_any_t *input);
+OM_uint32
+krb5_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);
+
+OM_uint32
+krb5_gss_store_cred(OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ gss_cred_usage_t cred_usage,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored);
+
/* s4u_gss_glue.c */
OM_uint32
kg_compose_deleg_cred(OM_uint32 *minor_status,
diff --git a/src/lib/gssapi/krb5/gssapi_err_krb5.et b/src/lib/gssapi/krb5/gssapi_err_krb5.et
index c2a705c84..4cfd68a00 100644
--- a/src/lib/gssapi/krb5/gssapi_err_krb5.et
+++ b/src/lib/gssapi/krb5/gssapi_err_krb5.et
@@ -37,4 +37,5 @@ error_code KG_BAD_SEQ, "Sequence number in token is corrupt"
error_code KG_EMPTY_CCACHE, "Credential cache is empty"
error_code KG_NO_CTYPES, "Acceptor and Initiator share no checksum types"
error_code KG_LUCID_VERSION, "Requested lucid context version not supported"
+error_code KG_INPUT_TOO_LONG, "PRF input too long"
end
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index 2892e7885..b68bc9a73 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -671,7 +671,7 @@ static struct gss_config krb5_mechanism = {
krb5_gss_internal_release_oid,
krb5_gss_wrap_size_limit,
krb5_gss_export_name,
- NULL, /* store_cred */
+ krb5_gss_store_cred,
krb5_gss_inquire_sec_context_by_oid,
krb5_gss_inquire_cred_by_oid,
krb5_gss_set_sec_context_option,
@@ -693,6 +693,7 @@ static struct gss_config krb5_mechanism = {
krb5_gss_export_name_composite,
krb5_gss_map_name_to_any,
krb5_gss_release_any_name_mapping,
+ krb5_gss_pseudo_random,
};
diff --git a/src/lib/gssapi/krb5/prf.c b/src/lib/gssapi/krb5/prf.c
new file mode 100644
index 000000000..f87c6b0c1
--- /dev/null
+++ b/src/lib/gssapi/krb5/prf.c
@@ -0,0 +1,139 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * lib/gssapi/krb5/prf.c
+ *
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ */
+
+#include <assert.h>
+#include "k5-int.h" /* for zap() */
+#include "gssapiP_krb5.h"
+#include <stdarg.h>
+
+OM_uint32
+krb5_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)
+{
+ krb5_error_code code;
+ krb5_key key = NULL;
+ krb5_gss_ctx_id_t ctx;
+ int i;
+ OM_uint32 minor;
+ size_t prflen;
+ krb5_data t, ns;
+ unsigned char *p;
+
+ prf_out->length = 0;
+ prf_out->value = NULL;
+
+ if (!kg_validate_ctx_id(context)) {
+ *minor_status = G_VALIDATE_FAILED;
+ return GSS_S_NO_CONTEXT;
+ }
+
+ t.length = 0;
+ t.data = NULL;
+
+ ns.length = 0;
+ ns.data = NULL;
+
+ ctx = (krb5_gss_ctx_id_t)context;
+
+ switch (prf_key) {
+ case GSS_C_PRF_KEY_FULL:
+ if (ctx->have_acceptor_subkey) {
+ key = ctx->acceptor_subkey;
+ break;
+ }
+ /* fallthrough */
+ case GSS_C_PRF_KEY_PARTIAL:
+ key = ctx->subkey;
+ break;
+ default:
+ code = EINVAL;
+ goto cleanup;
+ }
+
+ if (key == NULL) {
+ code = EINVAL;
+ goto cleanup;
+ }
+
+ prf_out->value = k5alloc(desired_output_len, &code);
+ if (prf_out->value == NULL) {
+ code = KG_INPUT_TOO_LONG;
+ goto cleanup;
+ }
+ prf_out->length = desired_output_len;
+
+ code = krb5_c_prf_length(ctx->k5_context,
+ krb5_k_key_enctype(ctx->k5_context, key),
+ &prflen);
+ if (code != 0)
+ goto cleanup;
+
+ ns.length = 4 + prf_in->length;
+ ns.data = k5alloc(ns.length, &code);
+ if (ns.data == NULL) {
+ code = KG_INPUT_TOO_LONG;
+ goto cleanup;
+ }
+
+ t.length = prflen;
+ t.data = k5alloc(t.length, &code);
+ if (t.data == NULL)
+ goto cleanup;
+
+ memcpy(ns.data + 4, prf_in->value, prf_in->length);
+ i = 0;
+ p = (unsigned char *)prf_out->value;
+ while (desired_output_len > 0) {
+ store_32_be(i, ns.data);
+
+ code = krb5_k_prf(ctx->k5_context, key, &ns, &t);
+ if (code != 0)
+ goto cleanup;
+
+ memcpy(p, t.data, MIN(t.length, desired_output_len));
+
+ p += t.length;
+ desired_output_len -= t.length;
+ i++;
+ }
+
+cleanup:
+ if (code != 0)
+ gss_release_buffer(&minor, prf_out);
+ krb5_free_data_contents(ctx->k5_context, &ns);
+ krb5_free_data_contents(ctx->k5_context, &t);
+
+ *minor_status = (OM_uint32)code;
+ return (code == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
+}
+
diff --git a/src/lib/gssapi/krb5/store_cred.c b/src/lib/gssapi/krb5/store_cred.c
new file mode 100644
index 000000000..a8ed6ffbb
--- /dev/null
+++ b/src/lib/gssapi/krb5/store_cred.c
@@ -0,0 +1,188 @@
+/* -*- mode: c; indent-tabs-mode: nil -*- */
+/*
+ * lib/gssapi/krb5/store_cred.c
+ *
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+ */
+
+#include <assert.h>
+#include "k5-int.h" /* for zap() */
+#include "gssapiP_krb5.h"
+#include <stdarg.h>
+
+static int
+has_unexpired_creds(krb5_gss_cred_id_t kcred,
+ const gss_OID desired_mech,
+ int default_cred)
+{
+ OM_uint32 major_status, minor;
+ gss_name_t cred_name;
+ gss_OID_set_desc desired_mechs;
+ gss_cred_id_t tmp_cred = GSS_C_NO_CREDENTIAL;
+ OM_uint32 time_rec;
+
+ desired_mechs.count = 1;
+ desired_mechs.elements = (gss_OID)desired_mech;
+
+ if (default_cred)
+ cred_name = GSS_C_NO_NAME;
+ else
+ cred_name = (gss_name_t)kcred->name;
+
+ major_status = krb5_gss_acquire_cred(&minor, cred_name, 0,
+ &desired_mechs, GSS_C_INITIATE,
+ &tmp_cred, NULL, &time_rec);
+
+ krb5_gss_release_cred(&minor, &tmp_cred);
+
+ return (GSS_ERROR(major_status) || time_rec);
+}
+
+static OM_uint32
+copy_initiator_creds(OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred)
+{
+ OM_uint32 major_status;
+ krb5_error_code code;
+ krb5_gss_cred_id_t kcred = NULL;
+ krb5_context context = NULL;
+ krb5_ccache ccache = NULL;
+
+ if (!default_cred) {
+ *minor_status = G_STORE_NON_DEFAULT_CRED_NOSUPP;
+ major_status = GSS_S_FAILURE;
+ goto cleanup;
+ }
+
+ code = krb5_gss_init_context(&context);
+ if (code != 0) {
+ *minor_status = code;
+ major_status = GSS_S_FAILURE;
+ goto cleanup;
+ }
+
+ major_status = krb5_gss_validate_cred_1(minor_status,
+ input_cred_handle,
+ context);
+ if (GSS_ERROR(major_status))
+ goto cleanup;
+
+ kcred = (krb5_gss_cred_id_t)input_cred_handle;
+
+ if (kcred->ccache == NULL || kcred->proxy_cred) {
+ *minor_status = KG_CCACHE_NOMATCH;
+ major_status = GSS_S_DEFECTIVE_CREDENTIAL;
+ goto cleanup;
+ }
+
+ if (!overwrite_cred &&
+ has_unexpired_creds(kcred, desired_mech, default_cred)) {
+ major_status = GSS_S_DUPLICATE_ELEMENT;
+ goto cleanup;
+ }
+
+ code = krb5int_cc_default(context, &ccache);
+ if (code != 0) {
+ *minor_status = code;
+ major_status = GSS_S_FAILURE;
+ goto cleanup;
+ }
+
+ code = krb5_cc_copy_creds(context, kcred->ccache, ccache);
+ if (code != 0) {
+ *minor_status = code;
+ major_status = GSS_S_FAILURE;
+ goto cleanup;
+ }
+
+ *minor_status = 0;
+ major_status = GSS_S_COMPLETE;
+
+cleanup:
+ if (kcred != NULL)
+ k5_mutex_unlock(&kcred->lock);
+
+ krb5_cc_close(context, ccache);
+ krb5_free_context(context);
+
+ return major_status;
+}
+
+OM_uint32
+krb5_gss_store_cred(OM_uint32 *minor_status,
+ gss_cred_id_t input_cred_handle,
+ gss_cred_usage_t cred_usage,
+ const gss_OID desired_mech,
+ OM_uint32 overwrite_cred,
+ OM_uint32 default_cred,
+ gss_OID_set *elements_stored,
+ gss_cred_usage_t *cred_usage_stored)
+{
+ OM_uint32 major_status;
+ gss_cred_usage_t actual_usage;
+ OM_uint32 lifetime;
+
+ if (input_cred_handle == GSS_C_NO_CREDENTIAL)
+ return GSS_S_NO_CRED;
+
+ major_status = GSS_S_FAILURE;
+
+ if (cred_usage == GSS_C_ACCEPT) {
+ *minor_status = G_STORE_ACCEPTOR_CRED_NOSUPP;
+ return GSS_S_FAILURE;
+ } else if (cred_usage != GSS_C_INITIATE && cred_usage != GSS_C_BOTH) {
+ *minor_status = G_BAD_USAGE;
+ return GSS_S_FAILURE;
+ }
+
+ major_status = krb5_gss_inquire_cred(minor_status, input_cred_handle,
+ NULL, &lifetime,
+ &actual_usage, elements_stored);
+ if (GSS_ERROR(major_status))
+ return major_status;
+
+ if (lifetime == 0)
+ return GSS_S_CREDENTIALS_EXPIRED;
+
+ if (actual_usage != GSS_C_INITIATE && actual_usage != GSS_C_BOTH) {
+ *minor_status = G_BAD_USAGE;
+ return GSS_S_FAILURE;
+ }
+
+ major_status = copy_initiator_creds(minor_status, input_cred_handle,
+ desired_mech, overwrite_cred,
+ default_cred);
+ if (GSS_ERROR(major_status))
+ return major_status;
+
+ if (cred_usage_stored != NULL)
+ *cred_usage_stored = GSS_C_INITIATE;
+
+ return GSS_S_COMPLETE;
+}
+
diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports
index 60754df7a..e7f7b3609 100644
--- a/src/lib/gssapi/libgssapi_krb5.exports
+++ b/src/lib/gssapi/libgssapi_krb5.exports
@@ -68,6 +68,7 @@ gss_nt_service_name_v2
gss_nt_string_uid_name
gss_nt_user_name
gss_oid_to_str
+gss_pseudo_random
gss_process_context_token
gss_release_any_name_mapping
gss_release_buffer_set
@@ -81,6 +82,7 @@ gss_seal
gss_set_name_attribute
gss_set_sec_context_option
gss_sign
+gss_store_cred
gss_str_to_oid
gss_test_oid_set_member
gss_unseal
diff --git a/src/lib/gssapi/mechglue/Makefile.in b/src/lib/gssapi/mechglue/Makefile.in
index adb5c8adf..0858a4a98 100644
--- a/src/lib/gssapi/mechglue/Makefile.in
+++ b/src/lib/gssapi/mechglue/Makefile.in
@@ -43,6 +43,7 @@ SRCS = \
$(srcdir)/g_mech_invoke.c \
$(srcdir)/g_mechname.c \
$(srcdir)/g_oid_ops.c \
+ $(srcdir)/g_prf.c \
$(srcdir)/g_process_context.c \
$(srcdir)/g_rel_buffer.c \
$(srcdir)/g_rel_cred.c \
@@ -96,6 +97,7 @@ OBJS = \
$(OUTPRE)g_mech_invoke.$(OBJEXT) \
$(OUTPRE)g_mechname.$(OBJEXT) \
$(OUTPRE)g_oid_ops.$(OBJEXT) \
+ $(OUTPRE)g_prf.$(OBJEXT) \
$(OUTPRE)g_process_context.$(OBJEXT) \
$(OUTPRE)g_rel_buffer.$(OBJEXT) \
$(OUTPRE)g_rel_cred.$(OBJEXT) \
@@ -149,6 +151,7 @@ STLIBOBJS = \
g_mech_invoke.o \
g_mechname.o \
g_oid_ops.o \
+ g_prf.o \
g_process_context.o \
g_rel_buffer.o \
g_rel_cred.o \
diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
index 3929f761b..e01d17474 100644
--- a/src/lib/gssapi/mechglue/g_initialize.c
+++ b/src/lib/gssapi/mechglue/g_initialize.c
@@ -773,6 +773,8 @@ build_dynamicMech(void *dl, const gss_OID mech_type)
GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_export_name_composite);
GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_map_name_to_any);
GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_release_any_name_mapping);
+ /* RFC 4401 (introduced in 1.8) */
+ GSS_ADD_DYNAMIC_METHOD(dl, mech, gss_pseudo_random);
assert(mech_type != GSS_C_NO_OID);
diff --git a/src/lib/gssapi/mechglue/g_prf.c b/src/lib/gssapi/mechglue/g_prf.c
new file mode 100644
index 000000000..74a3a21b6
--- /dev/null
+++ b/src/lib/gssapi/mechglue/g_prf.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2009 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+/*
+ * glue routine for gss_pseudo_random
+ */
+
+#include "mglueP.h"
+
+OM_uint32 KRB5_CALLCONV
+gss_pseudo_random (OM_uint32 *minor_status,
+ gss_ctx_id_t context_handle,
+ int prf_key,
+ const gss_buffer_t prf_in,
+ ssize_t desired_output_len,
+ gss_buffer_t prf_out)
+{
+ OM_uint32 status;
+ gss_union_ctx_id_t ctx;
+ gss_mechanism mech;
+
+ if (minor_status == NULL)
+ return GSS_S_CALL_INACCESSIBLE_WRITE;
+
+ if (context_handle == GSS_C_NO_CONTEXT)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT;
+
+ if (prf_in == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_READ | GSS_S_NO_CONTEXT;
+
+ if (prf_out == GSS_C_NO_BUFFER)
+ return GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CONTEXT;
+
+ prf_out->length = 0;
+ prf_out->value = NULL;
+
+ /*
+ * select the approprate underlying mechanism routine and
+ * call it.
+ */
+
+ ctx = (gss_union_ctx_id_t) context_handle;
+ mech = gssint_get_mechanism (ctx->mech_type);
+
+ if (mech != NULL) {
+ if (mech->gss_pseudo_random != NULL) {
+ status = mech->gss_pseudo_random(minor_status,
+ ctx->internal_ctx_id,
+ prf_key,
+ prf_in,
+ desired_output_len,
+ prf_out);
+ if (status != GSS_S_COMPLETE)
+ map_error(minor_status, mech);
+ } else
+ status = GSS_S_UNAVAILABLE;
+
+ return status;
+ }
+
+ return GSS_S_BAD_MECH;
+}
diff --git a/src/lib/gssapi/mechglue/g_store_cred.c b/src/lib/gssapi/mechglue/g_store_cred.c
index 1d438c4b9..3b286ecd4 100644
--- a/src/lib/gssapi/mechglue/g_store_cred.c
+++ b/src/lib/gssapi/mechglue/g_store_cred.c
@@ -63,7 +63,7 @@ OM_uint32 gss_store_cred(minor_status,
cred_usage_stored)
OM_uint32 *minor_status;
-const gss_cred_id_t input_cred_handle;
+gss_cred_id_t input_cred_handle;
gss_cred_usage_t cred_usage;
const gss_OID desired_mech;
OM_uint32 overwrite_cred;
diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h
index f35ac1447..517ca481b 100644
--- a/src/lib/gssapi/mechglue/mglueP.h
+++ b/src/lib/gssapi/mechglue/mglueP.h
@@ -573,6 +573,16 @@ typedef struct gss_config {
gss_any_t * /* input */
/* */);
+ 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 */
+ /* */);
+
} *gss_mechanism;
/* This structure MUST NOT be used by any code outside libgss */
diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h
index 43b004931..80c23e283 100644
--- a/src/lib/gssapi/spnego/gssapiP_spnego.h
+++ b/src/lib/gssapi/spnego/gssapiP_spnego.h
@@ -519,6 +519,17 @@ spnego_gss_release_any_name_mapping
gss_any_t *input
);
+OM_uint32
+spnego_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
+);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index 2aa8ad5dd..e0f53d579 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -268,6 +268,7 @@ static struct gss_config spnego_mechanism =
spnego_gss_export_name_composite,
spnego_gss_map_name_to_any,
spnego_gss_release_any_name_mapping,
+ spnego_gss_pseudo_random,
};
#ifdef _GSS_STATIC_LINK
@@ -2485,6 +2486,24 @@ spnego_gss_release_any_name_mapping(OM_uint32 *minor_status,
return (ret);
}
+OM_uint32
+spnego_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)
+{
+ OM_uint32 ret;
+ ret = gss_pseudo_random(minor_status,
+ context,
+ prf_key,
+ prf_in,
+ desired_output_len,
+ prf_out);
+ return (ret);
+}
+
/*
* We will release everything but the ctx_handle so that it
* can be passed back to init/accept context. This routine should