diff options
author | Luke Howard <lukeh@padl.com> | 2009-11-22 17:11:12 +0000 |
---|---|---|
committer | Luke Howard <lukeh@padl.com> | 2009-11-22 17:11:12 +0000 |
commit | 41f1f754dafb1b7e6ccb583c8e28b23b817546a2 (patch) | |
tree | 826bc5b191d5bb6fd027a660da1af5a1ee2f7a0a /src/lib | |
parent | c2ff314a8ea2cfffefe608d9a9aeecd5f531038a (diff) | |
download | krb5-41f1f754dafb1b7e6ccb583c8e28b23b817546a2.zip krb5-41f1f754dafb1b7e6ccb583c8e28b23b817546a2.tar.gz krb5-41f1f754dafb1b7e6ccb583c8e28b23b817546a2.tar.bz2 |
gss_store_cred implementation
git-svn-id: svn://anonsvn.mit.edu/krb5/users/lhoward/gssextras@23307 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/gssapi/krb5/Makefile.in | 3 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/gssapiP_krb5.h | 10 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/gssapi_krb5.c | 2 | ||||
-rw-r--r-- | src/lib/gssapi/krb5/store_cred.c | 188 |
4 files changed, 202 insertions, 1 deletions
diff --git a/src/lib/gssapi/krb5/Makefile.in b/src/lib/gssapi/krb5/Makefile.in index 70bea38..601acc5 100644 --- a/src/lib/gssapi/krb5/Makefile.in +++ b/src/lib/gssapi/krb5/Makefile.in @@ -81,6 +81,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 \ @@ -134,6 +135,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) \ @@ -190,6 +192,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 14ad126..fae3c83 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -917,6 +917,16 @@ krb5_gss_pseudo_random(OM_uint32 *minor_status, 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_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c index 35ba777..a6a9fad 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, diff --git a/src/lib/gssapi/krb5/store_cred.c b/src/lib/gssapi/krb5/store_cred.c new file mode 100644 index 0000000..a8ed6ff --- /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; +} + |