aboutsummaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorLuke Howard <lukeh@padl.com>2009-11-22 17:11:12 +0000
committerLuke Howard <lukeh@padl.com>2009-11-22 17:11:12 +0000
commit41f1f754dafb1b7e6ccb583c8e28b23b817546a2 (patch)
tree826bc5b191d5bb6fd027a660da1af5a1ee2f7a0a /src/lib
parentc2ff314a8ea2cfffefe608d9a9aeecd5f531038a (diff)
downloadkrb5-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.in3
-rw-r--r--src/lib/gssapi/krb5/gssapiP_krb5.h10
-rw-r--r--src/lib/gssapi/krb5/gssapi_krb5.c2
-rw-r--r--src/lib/gssapi/krb5/store_cred.c188
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;
+}
+