diff options
| author | Greg Hudson <ghudson@mit.edu> | 2009-12-17 04:49:27 +0000 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2009-12-17 04:49:27 +0000 |
| commit | 00784193904880a9e7f73ff477d287cd22d4e158 (patch) | |
| tree | f04c444af920a28dcbbe4f1730db6021301211b7 /src/lib/gssapi | |
| parent | 09b6eb4836a4ec82fc2145db185737a9e7d4b9e1 (diff) | |
| download | krb5-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.hin | 25 | ||||
| -rw-r--r-- | src/lib/gssapi/krb5/Makefile.in | 6 | ||||
| -rw-r--r-- | src/lib/gssapi/krb5/gssapiP_krb5.h | 18 | ||||
| -rw-r--r-- | src/lib/gssapi/krb5/gssapi_err_krb5.et | 1 | ||||
| -rw-r--r-- | src/lib/gssapi/krb5/gssapi_krb5.c | 3 | ||||
| -rw-r--r-- | src/lib/gssapi/krb5/prf.c | 139 | ||||
| -rw-r--r-- | src/lib/gssapi/krb5/store_cred.c | 188 | ||||
| -rw-r--r-- | src/lib/gssapi/libgssapi_krb5.exports | 2 | ||||
| -rw-r--r-- | src/lib/gssapi/mechglue/Makefile.in | 3 | ||||
| -rw-r--r-- | src/lib/gssapi/mechglue/g_initialize.c | 2 | ||||
| -rw-r--r-- | src/lib/gssapi/mechglue/g_prf.c | 84 | ||||
| -rw-r--r-- | src/lib/gssapi/mechglue/g_store_cred.c | 2 | ||||
| -rw-r--r-- | src/lib/gssapi/mechglue/mglueP.h | 10 | ||||
| -rw-r--r-- | src/lib/gssapi/spnego/gssapiP_spnego.h | 11 | ||||
| -rw-r--r-- | src/lib/gssapi/spnego/spnego_mech.c | 19 |
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 |
