summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2011-05-24 11:12:28 +0200
committerStephen Gallagher <sgallagh@redhat.com>2012-06-21 15:30:21 -0400
commit90fd1bbd6035cdab46faa3a695a2fb2be6508b17 (patch)
tree0586b1b7169069f1eeeefa9778a7dbc015496f8f
parente589442117002ab72e4e129232cde8b31eb71f92 (diff)
downloadsssd-90fd1bbd6035cdab46faa3a695a2fb2be6508b17.tar.gz
sssd-90fd1bbd6035cdab46faa3a695a2fb2be6508b17.tar.xz
sssd-90fd1bbd6035cdab46faa3a695a2fb2be6508b17.zip
PAC client: add krb5 authdata plugin
-rw-r--r--Makefile.am21
-rw-r--r--configure.ac1
-rw-r--r--src/conf_macros.m414
-rw-r--r--src/sss_client/krb5_authdata_int.h185
-rw-r--r--src/sss_client/sssd_pac.c282
5 files changed, 503 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
index fd989c49a..445492e22 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,6 +23,9 @@ ldblibdir = @ldblibdir@
if BUILD_KRB5_LOCATOR_PLUGIN
krb5plugindir = @krb5pluginpath@
endif
+if BUILD_PAC_RESPONDER
+krb5authdata_plugindir = @krb5authdatapluginpath@
+endif
sssdconfdir = $(sysconfdir)/sssd
sssddatadir = $(datadir)/sssd
sssdapiplugindir = $(sssddatadir)/sssd.api.d
@@ -154,6 +157,11 @@ krb5plugin_LTLIBRARIES = \
sssd_krb5_locator_plugin.la
endif
+if BUILD_PAC_RESPONDER
+krb5authdata_plugin_LTLIBRARIES = \
+ sssd_pac_plugin.la
+endif
+
noinst_LTLIBRARIES = \
libsss_crypt.la
@@ -1397,6 +1405,19 @@ sssd_krb5_locator_plugin_la_LDFLAGS = \
-module
endif
+sssd_pac_plugin_la_SOURCES = \
+ src/sss_client/sssd_pac.c \
+ src/sss_client/common.c \
+ src/sss_client/sss_cli.h \
+ src/sss_client/krb5_authdata_int.h
+sssd_pac_plugin_la_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(KRB5_CFLAGS)
+sssd_pac_plugin_la_LDFLAGS = \
+ -lkrb5 \
+ -avoid-version \
+ -module
+
if BUILD_PYTHON_BINDINGS
pysss_la_SOURCES = \
$(SSSD_TOOLS_OBJ) \
diff --git a/configure.ac b/configure.ac
index 7f2420902..0f5391bde 100644
--- a/configure.ac
+++ b/configure.ac
@@ -90,6 +90,7 @@ WITH_MANPAGES
WITH_XML_CATALOG
WITH_KRB5_PLUGIN_PATH
WITH_KRB5_RCACHE_DIR
+WITH_KRB5AUTHDATA_PLUGIN_PATH
WITH_PYTHON_BINDINGS
WITH_SELINUX
WITH_NSCD
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4
index 2e98b84c2..a1da75302 100644
--- a/src/conf_macros.m4
+++ b/src/conf_macros.m4
@@ -277,6 +277,20 @@ AC_DEFUN([WITH_DEFAULT_CCNAME_TEMPLATE],
AC_DEFINE_UNQUOTED(DEFAULT_CCNAME_TEMPLATE, "$config_def_ccname_template", [The default value of krb5_ccname_template])
])
+AC_DEFUN([WITH_KRB5AUTHDATA_PLUGIN_PATH],
+ [ AC_ARG_WITH([krb5authdata-plugin-path],
+ [AC_HELP_STRING([--with-krb5authdata-plugin-path=PATH],
+ [Path to kerberos authdata plugin store [/usr/lib/krb5/plugins/authdata]]
+ )
+ ]
+ )
+ krb5authdatapluginpath="${libdir}/krb5/plugins/authdata"
+ if test x"$with_krb5authdata_plugin_path" != x; then
+ krb5authdatapluginpath=$with_krb5authdata_plugin_path
+ fi
+ AC_SUBST(krb5authdatapluginpath)
+ ])
+
AC_DEFUN([WITH_PYTHON_BINDINGS],
[ AC_ARG_WITH([python-bindings],
[AC_HELP_STRING([--with-python-bindings],
diff --git a/src/sss_client/krb5_authdata_int.h b/src/sss_client/krb5_authdata_int.h
new file mode 100644
index 000000000..5e0cf5e02
--- /dev/null
+++ b/src/sss_client/krb5_authdata_int.h
@@ -0,0 +1,185 @@
+/*
+ SSSD - MIT Kerberos authdata plugin
+
+ This file contains definitions and declarations to build authdata plugins
+ for MIT Kerberos outside of the MIT Kerberos source tree.
+*/
+
+#ifndef _KRB5_AUTHDATA_INT_H
+#define _KRB5_AUTHDATA_INT_H
+
+krb5_error_code KRB5_CALLCONV
+krb5_ser_pack_int32(krb5_int32, krb5_octet **, size_t *);
+
+krb5_error_code KRB5_CALLCONV
+krb5_ser_unpack_int32(krb5_int32 *, krb5_octet **, size_t *);
+
+krb5_error_code KRB5_CALLCONV
+krb5_ser_pack_bytes(krb5_octet *, size_t, krb5_octet **, size_t *);
+
+#define AD_USAGE_AS_REQ 0x01
+#define AD_USAGE_TGS_REQ 0x02
+#define AD_USAGE_AP_REQ 0x04
+#define AD_USAGE_KDC_ISSUED 0x08
+#define AD_USAGE_MASK 0x0F
+#define AD_INFORMATIONAL 0x10
+
+struct _krb5_authdata_context;
+typedef struct _krb5_authdata_context *krb5_authdata_context;
+
+typedef void
+(*authdata_client_plugin_flags_proc)(krb5_context kcontext,
+ void *plugin_context,
+ krb5_authdatatype ad_type,
+ krb5_flags *flags);
+
+typedef krb5_error_code
+(*authdata_client_plugin_init_proc)(krb5_context context,
+ void **plugin_context);
+typedef void
+(*authdata_client_plugin_fini_proc)(krb5_context kcontext,
+ void *plugin_context);
+
+typedef krb5_error_code
+(*authdata_client_request_init_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void **request_context);
+
+typedef void
+(*authdata_client_request_fini_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context);
+
+typedef krb5_error_code
+(*authdata_client_import_authdata_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ krb5_authdata **authdata,
+ krb5_boolean kdc_issued_flag,
+ krb5_const_principal issuer);
+
+typedef krb5_error_code
+(*authdata_client_export_authdata_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ krb5_flags usage,
+ krb5_authdata ***authdata);
+
+typedef krb5_error_code
+(*authdata_client_get_attribute_types_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ krb5_data **attrs);
+
+typedef krb5_error_code
+(*authdata_client_get_attribute_proc)(krb5_context kcontext,
+ struct _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);
+
+typedef krb5_error_code
+(*authdata_client_set_attribute_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ krb5_boolean complete,
+ const krb5_data *attribute,
+ const krb5_data *value);
+
+typedef krb5_error_code
+(*authdata_client_delete_attribute_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ const krb5_data *attribute);
+
+typedef krb5_error_code
+(*authdata_client_export_internal_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ krb5_boolean restrict_authenticated,
+ void **ptr);
+
+typedef void
+(*authdata_client_free_internal_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ void *ptr);
+
+typedef krb5_error_code
+(*authdata_client_verify_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ const krb5_auth_context *auth_context,
+ const krb5_keyblock *key,
+ const krb5_ap_req *req);
+
+typedef krb5_error_code
+(*authdata_client_size_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ size_t *sizep);
+
+typedef krb5_error_code
+(*authdata_client_externalize_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ krb5_octet **buffer,
+ size_t *lenremain);
+
+typedef krb5_error_code
+(*authdata_client_internalize_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ krb5_octet **buffer,
+ size_t *lenremain);
+
+typedef krb5_error_code
+(*authdata_client_copy_proc)(krb5_context kcontext,
+ struct _krb5_authdata_context *context,
+ void *plugin_context,
+ void *request_context,
+ void *dst_plugin_context,
+ void *dst_request_context);
+
+typedef struct krb5plugin_authdata_client_ftable_v0 {
+ char *name;
+ krb5_authdatatype *ad_type_list;
+ authdata_client_plugin_init_proc init;
+ authdata_client_plugin_fini_proc fini;
+ authdata_client_plugin_flags_proc flags;
+ authdata_client_request_init_proc request_init;
+ authdata_client_request_fini_proc request_fini;
+ authdata_client_get_attribute_types_proc get_attribute_types;
+ authdata_client_get_attribute_proc get_attribute;
+ authdata_client_set_attribute_proc set_attribute;
+ authdata_client_delete_attribute_proc delete_attribute;
+ authdata_client_export_authdata_proc export_authdata;
+ authdata_client_import_authdata_proc import_authdata;
+ authdata_client_export_internal_proc export_internal;
+ authdata_client_free_internal_proc free_internal;
+ authdata_client_verify_proc verify;
+ authdata_client_size_proc size;
+ authdata_client_externalize_proc externalize;
+ authdata_client_internalize_proc internalize;
+ authdata_client_copy_proc copy; /* optional */
+} krb5plugin_authdata_client_ftable_v0;
+
+#endif /* _KRB5_AUTHDATA_INT_H */
diff --git a/src/sss_client/sssd_pac.c b/src/sss_client/sssd_pac.c
new file mode 100644
index 000000000..cbcfe1d9e
--- /dev/null
+++ b/src/sss_client/sssd_pac.c
@@ -0,0 +1,282 @@
+/*
+ Authors:
+ Sumit Bose <sbose@redhat.com>
+
+ Copyright (C) 2011 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* A short documentation about authdata plugins can be found in
+ * http://http://k5wiki.kerberos.org/wiki/Projects/VerifyAuthData */
+
+#include <krb5/krb5.h>
+#include <errno.h>
+
+#include "krb5_authdata_int.h"
+#include "sss_cli.h"
+
+
+struct sssd_context {
+ krb5_data data;
+};
+
+static krb5_error_code
+sssdpac_init(krb5_context kcontext, void **plugin_context)
+{
+ *plugin_context = NULL;
+ return 0;
+}
+
+static void
+sssdpac_flags(krb5_context kcontext,
+ void *plugin_context,
+ krb5_authdatatype ad_type,
+ krb5_flags *flags)
+{
+ *flags = AD_USAGE_KDC_ISSUED | AD_INFORMATIONAL | AD_USAGE_TGS_REQ;
+}
+
+static void
+sssdpac_fini(krb5_context kcontext, void *plugin_context)
+{
+ return;
+}
+
+static krb5_error_code
+sssdpac_request_init(krb5_context kcontext,
+ krb5_authdata_context context,
+ void *plugin_context,
+ void **request_context)
+{
+ struct sssd_context *sssdctx;
+
+ sssdctx = (struct sssd_context *)calloc(1, sizeof(*sssdctx));
+ if (sssdctx == NULL) {
+ return ENOMEM;
+ }
+
+ *request_context = sssdctx;
+
+ return 0;
+}
+
+static krb5_error_code
+sssdpac_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 sss_cli_req_data sss_data;
+ int ret;
+ uint8_t *repbuf;
+ size_t replen;
+ int errnop;
+ char *data = NULL;
+ struct sssd_context *sssdctx = (struct sssd_context *)request_context;
+
+ if (authdata[0] == NULL) {
+ return EINVAL;
+ }
+
+ sss_data.len = authdata[0]->length;
+ sss_data.data = authdata[0]->contents;
+
+ ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data,
+ &repbuf, &replen, &errnop);
+ if (ret != 0) {
+ /* Ignore the error */
+ }
+
+ if (authdata[0]->length > 0) {
+ data = malloc(sizeof(char) * authdata[0]->length);
+ if (data == NULL) {
+ return ENOMEM;
+ }
+ memcpy(data, authdata[0]->contents, authdata[0]->length);
+ }
+
+ if (sssdctx->data.data != NULL) {
+ krb5_free_data_contents(kcontext, &sssdctx->data);
+ }
+
+ sssdctx->data.length = authdata[0]->length;
+ sssdctx->data.data = data;
+ return 0;
+}
+
+static void
+sssdpac_request_fini(krb5_context kcontext,
+ krb5_authdata_context context,
+ void *plugin_context,
+ void *request_context)
+{
+ struct sssd_context *sssdctx = (struct sssd_context *)request_context;
+
+ if (sssdctx != NULL) {
+ if (sssdctx->data.data != NULL) {
+ krb5_free_data_contents(kcontext, &sssdctx->data);
+ }
+
+ free(sssdctx);
+ }
+}
+
+static krb5_error_code
+sssdpac_size(krb5_context kcontext,
+ krb5_authdata_context context,
+ void *plugin_context,
+ void *request_context,
+ size_t *sizep)
+{
+ struct sssd_context *sssdctx = (struct sssd_context *)request_context;
+
+ *sizep += sizeof(krb5_int32);
+
+ *sizep += sssdctx->data.length;
+
+ *sizep += sizeof(krb5_int32);
+
+ return 0;
+}
+
+static krb5_error_code
+sssdpac_externalize(krb5_context kcontext,
+ krb5_authdata_context context,
+ void *plugin_context,
+ void *request_context,
+ krb5_octet **buffer,
+ size_t *lenremain)
+{
+ krb5_error_code code = 0;
+ struct sssd_context *sssdctx = (struct sssd_context *)request_context;
+ size_t required = 0;
+ krb5_octet *bp;
+ size_t remain;
+
+ bp = *buffer;
+ remain = *lenremain;
+
+ if (sssdctx->data.data != NULL) {
+ sssdpac_size(kcontext, context, plugin_context,
+ request_context, &required);
+
+ if (required <= remain) {
+ krb5_ser_pack_int32((krb5_int32)sssdctx->data.length,
+ &bp, &remain);
+ krb5_ser_pack_bytes((krb5_octet *)sssdctx->data.data,
+ (size_t)sssdctx->data.length,
+ &bp, &remain);
+ krb5_ser_pack_int32(0,
+ &bp, &remain);
+ } else {
+ code = ENOMEM;
+ }
+ } else {
+ krb5_ser_pack_int32(0, &bp, &remain); /* length */
+ krb5_ser_pack_int32(0, &bp, &remain); /* verified */
+ }
+
+ *buffer = bp;
+ *lenremain = remain;
+
+ return code;
+}
+
+static krb5_error_code
+sssdpac_internalize(krb5_context kcontext,
+ krb5_authdata_context context,
+ void *plugin_context,
+ void *request_context,
+ krb5_octet **buffer,
+ size_t *lenremain)
+{
+ struct sssd_context *sssdctx = (struct sssd_context *)request_context;
+ krb5_error_code code;
+ krb5_int32 ibuf;
+ krb5_octet *bp;
+ size_t remain;
+ krb5_data data;
+
+ bp = *buffer;
+ remain = *lenremain;
+
+ /* length */
+ code = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (code != 0) {
+ return code;
+ }
+
+ if (ibuf != 0) {
+
+ data.length = ibuf;
+ data.data = malloc(sizeof(char) * ibuf);
+ if (data.data == NULL) {
+ return ENOMEM;
+ }
+ memcpy(data.data, bp, ibuf);
+
+ bp += ibuf;
+ remain -= ibuf;
+ } else {
+ data.length = 0;
+ data.data = NULL;
+ }
+
+ /* verified */
+ code = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (code != 0) {
+ return code;
+ }
+
+ if (sssdctx->data.data != NULL) {
+ krb5_free_data_contents(kcontext, &sssdctx->data);
+ }
+
+ sssdctx->data.length = data.length;
+ sssdctx->data.data = data.data;
+
+ *buffer = bp;
+ *lenremain = remain;
+
+ return 0;
+}
+
+static krb5_authdatatype sssdpac_ad_types[] = { KRB5_AUTHDATA_WIN2K_PAC, 0 };
+
+krb5plugin_authdata_client_ftable_v0 authdata_client_0 = {
+ ((void *)((uintptr_t)("sssd_sssdpac"))),
+ sssdpac_ad_types,
+ sssdpac_init,
+ sssdpac_fini,
+ sssdpac_flags,
+ sssdpac_request_init,
+ sssdpac_request_fini,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ sssdpac_import_authdata,
+ NULL,
+ NULL,
+ NULL,
+ sssdpac_size,
+ sssdpac_externalize,
+ sssdpac_internalize,
+ NULL
+};