krb5 commit: Add auth indicator authdata module

Greg Hudson ghudson at mit.edu
Mon Jun 20 11:54:14 EDT 2016


https://github.com/krb5/krb5/commit/365ac06e3d70f48e6dbfff4dfe259e2725a9f6c1
commit 365ac06e3d70f48e6dbfff4dfe259e2725a9f6c1
Author: Matt Rogers <mrogers at redhat.com>
Date:   Thu May 12 20:06:42 2016 -0400

    Add auth indicator authdata module
    
    This authdata module makes the 'auth-indicator' attribute available to
    the GSSAPI name extension functions.  The auth indicator values are UTF8
    strings imported during AP_REQ processing.
    
    ticket: 8425

 src/lib/krb5/krb/Makefile.in   |    5 +-
 src/lib/krb5/krb/ai_authdata.c |  340 ++++++++++++++++++++++++++++++++++++++++
 src/lib/krb5/krb/authdata.c    |    1 +
 src/lib/krb5/krb/authdata.h    |    1 +
 src/lib/krb5/krb/deps          |   12 ++
 5 files changed, 358 insertions(+), 1 deletions(-)

diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index 2c6ea5c..ad5ef93 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -17,6 +17,7 @@ STLIBOBJS= \
 	addr_srch.o	\
 	allow_weak.o	\
 	appdefault.o	\
+	ai_authdata.o   \
 	auth_con.o	\
 	cammac_util.o	\
 	authdata.o	\
@@ -128,6 +129,7 @@ OBJS=	$(OUTPRE)addr_comp.$(OBJEXT)	\
 	$(OUTPRE)addr_srch.$(OBJEXT)	\
 	$(OUTPRE)allow_weak.$(OBJEXT)	\
 	$(OUTPRE)appdefault.$(OBJEXT)	\
+	$(OUTPRE)ai_authdata.$(OBJEXT)  \
 	$(OUTPRE)auth_con.$(OBJEXT)	\
 	$(OUTPRE)cammac_util.$(OBJEXT)	\
 	$(OUTPRE)authdata.$(OBJEXT)	\
@@ -240,6 +242,7 @@ SRCS=	$(srcdir)/addr_comp.c	\
 	$(srcdir)/appdefault.c	\
 	$(srcdir)/auth_con.c	\
 	$(srcdir)/cammac_util.c	\
+	$(srcdir)/ai_authdata.c \
 	$(srcdir)/authdata.c	\
 	$(srcdir)/authdata_exp.c	\
 	$(srcdir)/authdata_enc.c	\
@@ -385,7 +388,7 @@ T_KERB_OBJS= t_kerb.o conv_princ.o unparse.o set_realm.o str_conv.o
 
 T_SER_OBJS= t_ser.o ser_actx.o ser_adata.o ser_addr.o ser_auth.o ser_cksum.o \
 	ser_ctx.o ser_key.o ser_princ.o serialize.o authdata.o pac.o \
-	pac_sign.o authdata_exp.o s4u_authdata.o copy_data.o etype_list.o
+	pac_sign.o ai_authdata.o authdata_exp.o s4u_authdata.o copy_data.o etype_list.o
 
 T_DELTAT_OBJS= t_deltat.o deltat.o
 
diff --git a/src/lib/krb5/krb/ai_authdata.c b/src/lib/krb5/krb/ai_authdata.c
new file mode 100644
index 0000000..45a3ac6
--- /dev/null
+++ b/src/lib/krb5/krb/ai_authdata.c
@@ -0,0 +1,340 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* src/lib/krb5/krb/ai_authdata.c - auth-indicator authdata module */
+/*
+ * Copyright (C) 2016 by Red Hat, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * 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 COPYRIGHT HOLDERS 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
+ * COPYRIGHT HOLDER 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 "k5-int.h"
+#include "authdata.h"
+#include "auth_con.h"
+#include "int-proto.h"
+
+struct authind_context {
+    krb5_data **indicators;
+    int count;
+};
+
+static krb5_error_code
+authind_init(krb5_context kcontext, void **plugin_context)
+{
+    *plugin_context = NULL;
+    return 0;
+}
+
+static void
+authind_flags(krb5_context kcontext, void *plugin_context,
+              krb5_authdatatype ad_type, krb5_flags *flags)
+{
+    *flags = AD_CAMMAC_PROTECTED;
+}
+
+static krb5_error_code
+authind_request_init(krb5_context kcontext, krb5_authdata_context context,
+                     void *plugin_context, void **request_context)
+{
+    krb5_error_code ret = 0;
+    struct authind_context *aictx;
+
+    *request_context = NULL;
+
+    aictx = k5alloc(sizeof(*aictx), &ret);
+    if (aictx == NULL)
+        return ret;
+    aictx->indicators = NULL;
+    aictx->count = 0;
+    *request_context = aictx;
+    return ret;
+}
+
+static krb5_error_code
+authind_import_authdata(krb5_context kcontext, krb5_authdata_context context,
+                        void *plugin_context, void *request_context,
+                        krb5_authdata **authdata, krb5_boolean kdc_issued,
+                        krb5_const_principal kdc_issuer)
+{
+    struct authind_context *aictx = request_context;
+    krb5_error_code ret = 0;
+    krb5_data **indps = NULL;
+    int count, i;
+
+    for (i = 0; authdata != NULL && authdata[i] != NULL; i++) {
+        ret = k5_authind_decode(authdata[i], &indps);
+        if (ret)
+            goto cleanup;
+    }
+
+    for (count = 0; indps != NULL && indps[count] != NULL; count++);
+    if (count != 0) {
+        aictx->indicators = indps;
+        aictx->count = count;
+        indps = NULL;
+    }
+
+cleanup:
+    k5_free_data_ptr_list(indps);
+    return ret;
+}
+
+static void
+authind_request_fini(krb5_context kcontext, krb5_authdata_context context,
+                     void *plugin_context, void *request_context)
+{
+    struct authind_context *aictx = request_context;
+
+    if (aictx != NULL) {
+        k5_free_data_ptr_list(aictx->indicators);
+        free(aictx);
+    }
+}
+
+/* This is a non-URI "local attribute" that is implementation defined. */
+static krb5_data authind_attr = {
+    KV5M_DATA,
+    sizeof("auth-indicators") - 1,
+    "auth-indicators"
+};
+
+static krb5_error_code
+authind_get_attribute_types(krb5_context kcontext,
+                            krb5_authdata_context context,
+                            void *plugin_context, void *request_context,
+                            krb5_data **out_attrs)
+{
+    struct authind_context *aictx = (struct authind_context *)request_context;
+    krb5_error_code ret;
+    krb5_data *attrs;
+
+    *out_attrs = NULL;
+
+    if (aictx->count == 0)
+        return ENOENT;
+
+    attrs = k5calloc(2, sizeof(*attrs), &ret);
+    if (attrs == NULL)
+        return ENOMEM;
+
+    ret = krb5int_copy_data_contents(kcontext, &authind_attr, &attrs[0]);
+    if (ret)
+        goto cleanup;
+
+    attrs[1].data = NULL;
+    attrs[1].length = 0;
+
+    *out_attrs = attrs;
+    attrs = NULL;
+
+cleanup:
+    krb5int_free_data_list(kcontext, attrs);
+    return ret;
+}
+
+static krb5_error_code
+authind_get_attribute(krb5_context kcontext, krb5_authdata_context context,
+                      void *plugin_context, void *request_context,
+                      const krb5_data *attribute, krb5_boolean *authenticated,
+                      krb5_boolean *complete, krb5_data *value,
+                      krb5_data *display_value, int *more)
+{
+    struct authind_context *aictx = (struct authind_context *)request_context;
+    krb5_error_code ret;
+    krb5_data *value_out;
+    int left;
+
+    if (!data_eq(*attribute, authind_attr))
+        return ENOENT;
+
+    /* The caller should set more to -1 before the first call.  Successive
+     * calls return the number of indicators left, ending at 0. */
+    left = (*more < 0) ? aictx->count : *more;
+    if (left <= 0)
+        return ENOENT;
+    else if (left > aictx->count)
+        return EINVAL;
+
+    ret = krb5_copy_data(kcontext, aictx->indicators[aictx->count - left],
+                         &value_out);
+    if (ret)
+        return ret;
+
+    *more = left - 1;
+    *value = *value_out;
+    /* Indicators are delivered in a CAMMAC verified outside of this module,
+     * so these are authenticated values. */
+    *authenticated = TRUE;
+    *complete = TRUE;
+
+    free(value_out);
+    return ret;
+}
+
+static krb5_error_code
+authind_set_attribute(krb5_context kcontext, krb5_authdata_context context,
+                      void *plugin_context, void *request_context,
+                      krb5_boolean complete, const krb5_data *attribute,
+                      const krb5_data *value)
+{
+    /* Indicators are imported from ticket authdata, not set by this module. */
+    if (!data_eq(*attribute, authind_attr))
+        return ENOENT;
+
+    return EPERM;
+}
+
+static krb5_error_code
+authind_size(krb5_context kcontext, krb5_authdata_context context,
+             void *plugin_context, void *request_context, size_t *sizep)
+{
+    struct authind_context *aictx = (struct authind_context *)request_context;
+    int i;
+
+    /* Add the indicator count. */
+    *sizep += sizeof(int32_t);
+
+    /* Add each indicator's length and value. */
+    for (i = 0; i < aictx->count; i++)
+        *sizep += sizeof(int32_t) + aictx->indicators[i]->length;
+
+    return 0;
+}
+
+static krb5_error_code
+authind_externalize(krb5_context kcontext, krb5_authdata_context context,
+                    void *plugin_context, void *request_context,
+                    uint8_t **buffer, size_t *lenremain)
+{
+    struct authind_context *aictx = (struct authind_context *)request_context;
+    krb5_error_code ret = 0;
+    uint8_t *bp = *buffer;
+    size_t remain = *lenremain;
+    int i;
+
+    /* Serialize the indicator count. */
+    krb5_ser_pack_int32(aictx->count, &bp, &remain);
+
+    for (i = 0; i < aictx->count; i++) {
+        /* Serialize the length and indicator value. */
+        krb5_ser_pack_int32(aictx->indicators[i]->length, &bp, &remain);
+        ret = krb5_ser_pack_bytes((uint8_t *)aictx->indicators[i]->data,
+                                  aictx->indicators[i]->length, &bp, &remain);
+        if (ret)
+            return ret;
+    }
+
+    *buffer = bp;
+    *lenremain = remain;
+    return ret;
+}
+
+
+static krb5_error_code
+authind_internalize(krb5_context kcontext, krb5_authdata_context context,
+                    void *plugin_context, void *request_context,
+                    uint8_t **buffer, size_t *lenremain)
+{
+    struct authind_context *aictx = (struct authind_context *)request_context;
+    krb5_error_code ret;
+    int32_t count, len, i;
+    uint8_t *bp = *buffer;
+    size_t remain = *lenremain;
+    krb5_data **inds = NULL;
+
+    /* Get the count. */
+    ret = krb5_ser_unpack_int32(&count, &bp, &remain);
+    if (ret)
+        return ret;
+
+    if ((size_t)count > remain)
+        return ERANGE;
+
+    inds = k5calloc(count, sizeof(*inds), &ret);
+    if (inds == NULL)
+        return errno;
+
+    for (i = 0; i < count; i++) {
+        /* Get the length. */
+        ret = krb5_ser_unpack_int32(&len, &bp, &remain);
+        if (ret)
+            goto cleanup;
+        if ((size_t)len > remain) {
+            ret = ERANGE;
+            goto cleanup;
+        }
+
+        /* Get the indicator. */
+        inds[i] = k5alloc(sizeof(*inds[i]), &ret);
+        if (inds[i] == NULL)
+            goto cleanup;
+        ret = alloc_data(inds[i], len);
+        if (ret)
+            goto cleanup;
+        ret = krb5_ser_unpack_bytes((uint8_t *)inds[i]->data, len, &bp,
+                                    &remain);
+        if (ret)
+            goto cleanup;
+    }
+
+    k5_free_data_ptr_list(aictx->indicators);
+    aictx->count = count;
+    aictx->indicators = inds;
+    inds = NULL;
+
+    *buffer = bp;
+    *lenremain = remain;
+
+cleanup:
+    k5_free_data_ptr_list(inds);
+    return ret;
+}
+
+static krb5_authdatatype authind_ad_types[] = {
+    KRB5_AUTHDATA_AUTH_INDICATOR, 0
+};
+
+krb5plugin_authdata_client_ftable_v0 k5_authind_ad_client_ftable = {
+    "authentication-indicators",
+    authind_ad_types,
+    authind_init,
+    NULL, /* fini */
+    authind_flags,
+    authind_request_init,
+    authind_request_fini,
+    authind_get_attribute_types,
+    authind_get_attribute,
+    authind_set_attribute,
+    NULL, /* delete_attribute_proc */
+    NULL, /* export_authdata */
+    authind_import_authdata,
+    NULL, /* export_internal */
+    NULL, /* free_internal */
+    NULL, /* verify */
+    authind_size,
+    authind_externalize,
+    authind_internalize,
+    NULL /* authind_copy */
+};
diff --git a/src/lib/krb5/krb/authdata.c b/src/lib/krb5/krb/authdata.c
index f2c66bd..047128a 100644
--- a/src/lib/krb5/krb/authdata.c
+++ b/src/lib/krb5/krb/authdata.c
@@ -45,6 +45,7 @@ static const char *objdirs[] = {
 static krb5plugin_authdata_client_ftable_v0 *authdata_systems[] = {
     &krb5int_mspac_authdata_client_ftable,
     &krb5int_s4u2proxy_authdata_client_ftable,
+    &k5_authind_ad_client_ftable,
     NULL
 };
 
diff --git a/src/lib/krb5/krb/authdata.h b/src/lib/krb5/krb/authdata.h
index 46b699c..b193f6a 100644
--- a/src/lib/krb5/krb/authdata.h
+++ b/src/lib/krb5/krb/authdata.h
@@ -78,6 +78,7 @@ struct krb5_pac_data {
 
 extern krb5plugin_authdata_client_ftable_v0 krb5int_mspac_authdata_client_ftable;
 extern krb5plugin_authdata_client_ftable_v0 krb5int_s4u2proxy_authdata_client_ftable;
+extern krb5plugin_authdata_client_ftable_v0 k5_authind_ad_client_ftable;
 
 krb5_error_code
 k5_pac_locate_buffer(krb5_context context,
diff --git a/src/lib/krb5/krb/deps b/src/lib/krb5/krb/deps
index d08d533..09e7771 100644
--- a/src/lib/krb5/krb/deps
+++ b/src/lib/krb5/krb/deps
@@ -45,6 +45,18 @@ appdefault.so appdefault.po $(OUTPRE)appdefault.$(OBJEXT): \
   $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
   $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
   appdefault.c
+ai_authdata.so ai_authdata.po $(OUTPRE)ai_authdata.$(OBJEXT): \
+  $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
+  $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
+  $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
+  $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
+  $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
+  $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
+  $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \
+  $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
+  $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
+  $(top_srcdir)/include/socket-utils.h auth_con.h authdata.h \
+  int-proto.h ai_authdata.c
 auth_con.so auth_con.po $(OUTPRE)auth_con.$(OBJEXT): \
   $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
   $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \


More information about the cvs-krb5 mailing list