aboutsummaryrefslogtreecommitdiff
path: root/src/kdc/kdc_authdata.c
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2008-08-25 19:43:03 +0000
committerKen Raeburn <raeburn@mit.edu>2008-08-25 19:43:03 +0000
commit2f2343584826983a4920fbad2a0248a42b584cf8 (patch)
treefb1dac3ca2b6bbd66bb701336d5fa52498b5b78e /src/kdc/kdc_authdata.c
parent57bd520a5037c2194adefb80cc7c13a06dbee42d (diff)
downloadkrb5-2f2343584826983a4920fbad2a0248a42b584cf8.zip
krb5-2f2343584826983a4920fbad2a0248a42b584cf8.tar.gz
krb5-2f2343584826983a4920fbad2a0248a42b584cf8.tar.bz2
Incorporate Apple's patch
Add a test authorization data scheme, in both built-in and plugin forms; built-in version is #ifdef'ed out. Update configury to create the build directory for the plugin, but don't build or install it by default. Create the new (and normally empty) authorization data plugin directory at install time. Add some (normally disabled) code to log authz data from rd_req. Fix up some comments that still refer to preauth plugins. Add some details in comments on the API, and why it's private for now. Make the plugin init context support work, by not passing null pointers. ticket: 5565 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@20691 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/kdc/kdc_authdata.c')
-rw-r--r--src/kdc/kdc_authdata.c298
1 files changed, 298 insertions, 0 deletions
diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
new file mode 100644
index 0000000..9c7fdfa
--- /dev/null
+++ b/src/kdc/kdc_authdata.c
@@ -0,0 +1,298 @@
+/*
+ * kdc/kdc_authdata.c
+ *
+ * Copyright (C) 2007 Apple Inc. 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.
+ *
+ * AuthorizationData routines for the KDC.
+ */
+
+#include "k5-int.h"
+#include "kdc_util.h"
+#include "extern.h"
+#include <stdio.h>
+#include "adm_proto.h"
+
+#include <syslog.h>
+
+#include <assert.h>
+#include "../include/krb5/authdata_plugin.h"
+
+#if TARGET_OS_MAC
+static const char *objdirs[] = { KRB5_AUTHDATA_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/plugins/authdata", NULL }; /* should be a list */
+#else
+static const char *objdirs[] = { LIBDIR "/krb5/plugins/authdata", NULL };
+#endif
+
+typedef krb5_error_code (*authdata_proc)
+ (krb5_context, krb5_db_entry *client,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_enc_tkt_part * enc_tkt_reply);
+
+typedef krb5_error_code (*init_proc)
+ (krb5_context, void **);
+typedef void (*fini_proc)
+ (krb5_context, void *);
+
+typedef struct _krb5_authdata_systems {
+ const char *name;
+ int type;
+ int flags;
+ void *plugin_context;
+ init_proc init;
+ fini_proc fini;
+ authdata_proc handle_authdata;
+} krb5_authdata_systems;
+
+#undef GREET_PREAUTH
+
+#ifdef GREET_PREAUTH
+static krb5_error_code
+greet_init(krb5_context ctx, void **blob)
+{
+ *blob = "hello";
+ return 0;
+}
+
+static void
+greet_fini(krb5_context ctx, void *blob)
+{
+}
+
+static krb5_error_code
+greet_authdata(krb5_context ctx, krb5_db_entry *client,
+ krb5_data *req_pkt,
+ krb5_kdc_req *request,
+ krb5_enc_tkt_part * enc_tkt_reply)
+{
+#define GREET_SIZE (20)
+
+ char *p;
+ krb5_authdata *a;
+ size_t count;
+ krb5_authdata **new_ad;
+
+ krb5_klog_syslog (LOG_DEBUG, "in greet_authdata");
+
+ p = calloc(1, GREET_SIZE);
+ a = calloc(1, sizeof(*a));
+
+ if (p == NULL || a == NULL) {
+ free(p);
+ free(a);
+ return ENOMEM;
+ }
+ strcpy(p, "hello");
+ a->magic = KV5M_AUTHDATA;
+ a->ad_type = -42;
+ a->length = GREET_SIZE;
+ a->contents = p;
+ if (enc_tkt_reply->authorization_data == 0) {
+ count = 0;
+ } else {
+ for (count = 0; enc_tkt_reply->authorization_data[count] != 0; count++)
+ ;
+ }
+ new_ad = realloc(enc_tkt_reply->authorization_data,
+ (count+2) * sizeof(krb5_authdata *));
+ if (new_ad == NULL) {
+ free(p);
+ free(a);
+ return ENOMEM;
+ }
+ enc_tkt_reply->authorization_data = new_ad;
+ new_ad[count] = a;
+ new_ad[count+1] = NULL;
+ return 0;
+}
+#endif
+
+static krb5_authdata_systems static_authdata_systems[] = {
+#ifdef GREET_PREAUTH
+ { "greeting", 0, 0, 0, greet_init, greet_fini, greet_authdata },
+#endif
+ { "[end]", -1,}
+};
+
+static krb5_authdata_systems *authdata_systems;
+static int n_authdata_systems;
+static struct plugin_dir_handle authdata_plugins;
+
+krb5_error_code
+load_authdata_plugins(krb5_context context)
+{
+ struct errinfo err;
+ void **authdata_plugins_ftables = NULL;
+ struct krb5plugin_authdata_ftable_v0 *ftable = NULL;
+ size_t module_count;
+ int i, k;
+ init_proc server_init_proc = NULL;
+
+ memset(&err, 0, sizeof(err));
+
+ /* Attempt to load all of the authdata plugins we can find. */
+ PLUGIN_DIR_INIT(&authdata_plugins);
+ if (PLUGIN_DIR_OPEN(&authdata_plugins) == 0) {
+ if (krb5int_open_plugin_dirs(objdirs, NULL,
+ &authdata_plugins, &err) != 0) {
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+ }
+
+ /* Get the method tables provided by the loaded plugins. */
+ authdata_plugins_ftables = NULL;
+ n_authdata_systems = 0;
+ if (krb5int_get_plugin_dir_data(&authdata_plugins,
+ "authdata_server_0",
+ &authdata_plugins_ftables, &err) != 0) {
+ return KRB5_PLUGIN_NO_HANDLE;
+ }
+
+ /* Count the valid modules. */
+ module_count = sizeof(static_authdata_systems)
+ / sizeof(static_authdata_systems[0]);
+ if (authdata_plugins_ftables != NULL) {
+ for (i = 0; authdata_plugins_ftables[i] != NULL; i++) {
+ ftable = authdata_plugins_ftables[i];
+ if ((ftable->authdata_proc != NULL)) {
+ module_count++;
+ }
+ }
+ }
+
+ /* Build the complete list of supported authdata options, and
+ * leave room for a terminator entry. */
+ authdata_systems = calloc(module_count + 1, sizeof(krb5_authdata_systems));
+ if (authdata_systems == NULL) {
+ krb5int_free_plugin_dir_data(authdata_plugins_ftables);
+ return ENOMEM;
+ }
+
+ /* Add the locally-supplied mechanisms to the dynamic list first. */
+ for (i = 0, k = 0;
+ i < sizeof(static_authdata_systems) / sizeof(static_authdata_systems[0]);
+ i++) {
+ if (static_authdata_systems[i].type == -1)
+ break;
+ authdata_systems[k] = static_authdata_systems[i];
+ /* Try to initialize the authdata system. If it fails, we'll remove it
+ * from the list of systems we'll be using. */
+ server_init_proc = static_authdata_systems[i].init;
+ if ((server_init_proc != NULL) &&
+ ((*server_init_proc)(context, &authdata_systems[k].plugin_context) != 0)) {
+ memset(&authdata_systems[k], 0, sizeof(authdata_systems[k]));
+ continue;
+ }
+ k++;
+ }
+
+ /* Now add the dynamically-loaded mechanisms to the list. */
+ if (authdata_plugins_ftables != NULL) {
+ for (i = 0; authdata_plugins_ftables[i] != NULL; i++) {
+ krb5_error_code initerr;
+ void *pctx = NULL;
+
+ ftable = authdata_plugins_ftables[i];
+ if ((ftable->authdata_proc == NULL)) {
+ continue;
+ }
+ server_init_proc = ftable->init_proc;
+ if ((server_init_proc != NULL) &&
+ ((initerr = (*server_init_proc)(context, &pctx)) != 0)) {
+ const char *emsg;
+ emsg = krb5_get_error_message(context, initerr);
+ if (emsg) {
+ krb5_klog_syslog(LOG_ERR,
+ "authdata %s failed to initialize: %s",
+ ftable->name, emsg);
+ krb5_free_error_message(context, emsg);
+ }
+ memset(&authdata_systems[k], 0, sizeof(authdata_systems[k]));
+
+ continue;
+ }
+
+ authdata_systems[k].name = ftable->name;
+ authdata_systems[k].init = server_init_proc;
+ authdata_systems[k].fini = ftable->fini_proc;
+ authdata_systems[k].handle_authdata = ftable->authdata_proc;
+ authdata_systems[k].plugin_context = pctx;
+ k++;
+ }
+ }
+ n_authdata_systems = k;
+ /* Add the end-of-list marker. */
+ authdata_systems[k].name = "[end]";
+ authdata_systems[k].type = -1;
+ return 0;
+}
+
+krb5_error_code
+unload_authdata_plugins(krb5_context context)
+{
+ int i;
+ if (authdata_systems != NULL) {
+ for (i = 0; i < n_authdata_systems; i++) {
+ if (authdata_systems[i].fini != NULL) {
+ (*authdata_systems[i].fini)(context,
+ authdata_systems[i].plugin_context);
+ }
+ memset(&authdata_systems[i], 0, sizeof(authdata_systems[i]));
+ }
+ free(authdata_systems);
+ authdata_systems = NULL;
+ n_authdata_systems = 0;
+ krb5int_close_plugin_dirs(&authdata_plugins);
+ }
+ return 0;
+}
+
+krb5_error_code
+handle_authdata (krb5_context context, krb5_db_entry *client,
+ krb5_data *req_pkt, krb5_kdc_req *request,
+ krb5_enc_tkt_part *enc_tkt_reply)
+{
+ krb5_error_code retval = 0;
+ int i;
+ const char *emsg;
+
+ krb5_klog_syslog (LOG_DEBUG, "handling authdata");
+
+ for (i = 0; i < n_authdata_systems; i++) {
+ const krb5_authdata_systems *asys = &authdata_systems[i];
+ if (asys->handle_authdata && asys->type != -1) {
+ retval = asys->handle_authdata(context, client, req_pkt,
+ request, enc_tkt_reply);
+ if (retval) {
+ emsg = krb5_get_error_message (context, retval);
+ krb5_klog_syslog (LOG_INFO,
+ "authdata (%s) handling failure: %s",
+ asys->name, emsg);
+ krb5_free_error_message (context, emsg);
+ } else {
+ krb5_klog_syslog (LOG_DEBUG, ".. .. ok");
+ }
+ }
+ }
+
+ return 0;
+}