New upstream prerelease (1.16-beta1)

This commit is contained in:
Robbie Harwood 2017-10-05 15:10:47 -04:00
parent 0c7302b5bc
commit 533a73fdd1
46 changed files with 66 additions and 21916 deletions

3
.gitignore vendored
View File

@ -154,3 +154,6 @@ krb5-1.8.3-pdf.tar.gz
/krb5-1.15.2-pdfs.tar
/krb5-1.15.2.tar.gz
/krb5-1.15.2.tar.gz.asc
/krb5-1.16-beta1-pdfs.tar
/krb5-1.16-beta1.tar.gz
/krb5-1.16-beta1.tar.gz.asc

File diff suppressed because it is too large Load Diff

View File

@ -1,994 +0,0 @@
From 78a1f155701f94a228c4f58f98846195a39991c4 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 27 Jun 2017 17:15:39 -0400
Subject: [PATCH] Add KDC policy pluggable interface
Add the header include/krb5/kdcpolicy_plugin.h, defining a pluggable
interface for modules to deny AS and TGS requests and set maximum
ticket lifetimes. This interface replaces the policy.c stub functions.
Add check_kdcpolicy_as() and check_kdcpolicy_tgs() as entry functions.
Call them after auth indicators and ticket lifetimes have been
determined.
Add a test module and a test script with basic kdcpolicy tests. Add
plugin interface documentation in doc/plugindev/policy.rst.
Also authored by Matt Rogers <mrogers@redhat.com>.
ticket: 8606 (new)
(cherry picked from commit d0969f6a8170344031ef58fd2a161190f1edfb96)
[rharwood@redhat.com: mention but do not use kadm_auth]
---
doc/plugindev/index.rst | 1 +
doc/plugindev/kdcpolicy.rst | 24 +++
src/Makefile.in | 1 +
src/configure.in | 1 +
src/include/Makefile.in | 1 +
src/include/k5-int.h | 4 +-
src/include/k5-trace.h | 5 +
src/include/krb5/kdcpolicy_plugin.h | 128 ++++++++++++
src/kdc/do_as_req.c | 7 +
src/kdc/do_tgs_req.c | 6 +
src/kdc/kdc_util.c | 7 -
src/kdc/kdc_util.h | 11 -
src/kdc/main.c | 8 +
src/kdc/policy.c | 267 +++++++++++++++++++++----
src/kdc/policy.h | 19 +-
src/kdc/tgs_policy.c | 6 -
src/lib/krb5/krb/plugin.c | 4 +-
src/plugins/kdcpolicy/test/Makefile.in | 20 ++
src/plugins/kdcpolicy/test/deps | 0
src/plugins/kdcpolicy/test/main.c | 111 ++++++++++
src/plugins/kdcpolicy/test/policy_test.exports | 1 +
src/tests/Makefile.in | 1 +
src/tests/t_kdcpolicy.py | 57 ++++++
23 files changed, 616 insertions(+), 74 deletions(-)
create mode 100644 doc/plugindev/kdcpolicy.rst
create mode 100644 src/include/krb5/kdcpolicy_plugin.h
create mode 100644 src/plugins/kdcpolicy/test/Makefile.in
create mode 100644 src/plugins/kdcpolicy/test/deps
create mode 100644 src/plugins/kdcpolicy/test/main.c
create mode 100644 src/plugins/kdcpolicy/test/policy_test.exports
create mode 100644 src/tests/t_kdcpolicy.py
diff --git a/doc/plugindev/index.rst b/doc/plugindev/index.rst
index 67dbc2790..0a012b82b 100644
--- a/doc/plugindev/index.rst
+++ b/doc/plugindev/index.rst
@@ -32,5 +32,6 @@ Contents
gssapi.rst
internal.rst
certauth.rst
+ kdcpolicy.rst
.. TODO: GSSAPI mechanism plugins
diff --git a/doc/plugindev/kdcpolicy.rst b/doc/plugindev/kdcpolicy.rst
new file mode 100644
index 000000000..74f21f08f
--- /dev/null
+++ b/doc/plugindev/kdcpolicy.rst
@@ -0,0 +1,24 @@
+.. _kdcpolicy_plugin:
+
+KDC policy interface (kdcpolicy)
+================================
+
+The kdcpolicy interface was first introduced in release 1.16. It
+allows modules to veto otherwise valid AS and TGS requests or restrict
+the lifetime and renew time of the resulting ticket. For a detailed
+description of the kdcpolicy interface, see the header file
+``<krb5/kdcpolicy_plugin.h>``.
+
+The optional **check_as** and **check_tgs** functions allow the module
+to perform access control. Additionally, a module can create and
+destroy module data with the **init** and **fini** methods. Module
+data objects last for the lifetime of the KDC process, and are
+provided to all other methods. The data has the type
+krb5_kdcpolicy_moddata, which should be cast to the appropriate
+internal type.
+
+kdcpolicy modules can optionally inspect principal entries. To do
+this, the module must also include ``<kdb.h>`` to gain access to the
+principal entry structure definition. As the KDB interface is
+explicitly not as stable as other public interfaces, modules which do
+this may not retain compatibility across releases.
diff --git a/src/Makefile.in b/src/Makefile.in
index ad8565056..e47bddcb1 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -21,6 +21,7 @@ SUBDIRS=util include lib \
plugins/kdb/db2 \
@ldap_plugin_dir@ \
plugins/kdb/test \
+ plugins/kdcpolicy/test \
plugins/preauth/otp \
plugins/preauth/pkinit \
plugins/preauth/test \
diff --git a/src/configure.in b/src/configure.in
index 4ae2c07d5..ee1983043 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1470,6 +1470,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test
plugins/kdb/db2/libdb2/recno
plugins/kdb/db2/libdb2/test
plugins/kdb/test
+ plugins/kdcpolicy/test
plugins/preauth/otp
plugins/preauth/test
plugins/authdata/greet_client
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index 0239338a1..6a3fa8242 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -144,6 +144,7 @@ install-headers-unix install: krb5/krb5.h profile.h
$(INSTALL_DATA) $(srcdir)/krb5/ccselect_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)ccselect_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/clpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)clpreauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/hostrealm_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)hostrealm_plugin.h
+ $(INSTALL_DATA) $(srcdir)/krb5/kdcpolicy_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpolicy_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/kdcpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpreauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/localauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)localauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/locate_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)locate_plugin.h
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index ed9c7bf75..39ffb9568 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -1157,7 +1157,9 @@ struct plugin_interface {
#define PLUGIN_INTERFACE_TLS 8
#define PLUGIN_INTERFACE_KDCAUTHDATA 9
#define PLUGIN_INTERFACE_CERTAUTH 10
-#define PLUGIN_NUM_INTERFACES 11
+#define PLUGIN_INTERFACE_KADM5_AUTH 11
+#define PLUGIN_INTERFACE_KDCPOLICY 12
+#define PLUGIN_NUM_INTERFACES 13
/* Retrieve the plugin module of type interface_id and name modname,
* storing the result into module. */
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
index c75e264e0..2885408a2 100644
--- a/src/include/k5-trace.h
+++ b/src/include/k5-trace.h
@@ -454,4 +454,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_GET_CRED_VIA_TKT_EXT_RETURN(c, ret) \
TRACE(c, "Got cred; {kerr}", ret)
+#define TRACE_KDCPOLICY_VTINIT_FAIL(c, ret) \
+ TRACE(c, "KDC policy module failed to init vtable: {kerr}", ret)
+#define TRACE_KDCPOLICY_INIT_SKIP(c, name) \
+ TRACE(c, "kadm5_auth module {str} declined to initialize", name)
+
#endif /* K5_TRACE_H */
diff --git a/src/include/krb5/kdcpolicy_plugin.h b/src/include/krb5/kdcpolicy_plugin.h
new file mode 100644
index 000000000..c7592c5db
--- /dev/null
+++ b/src/include/krb5/kdcpolicy_plugin.h
@@ -0,0 +1,128 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/*
+ * Declarations for kdcpolicy plugin module implementors.
+ *
+ * The kdcpolicy pluggable interface currently has only one supported major
+ * version, which is 1. Major version 1 has a current minor version number of
+ * 1.
+ *
+ * kdcpolicy plugin modules should define a function named
+ * kdcpolicy_<modulename>_initvt, matching the signature:
+ *
+ * krb5_error_code
+ * kdcpolicy_modname_initvt(krb5_context context, int maj_ver, int min_ver,
+ * krb5_plugin_vtable vtable);
+ *
+ * The initvt function should:
+ *
+ * - Check that the supplied maj_ver number is supported by the module, or
+ * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
+ *
+ * - Cast the vtable pointer as appropriate for maj_ver:
+ * maj_ver == 1: Cast to krb5_kdcpolicy_vtable
+ *
+ * - Initialize the methods of the vtable, stopping as appropriate for the
+ * supplied min_ver. Optional methods may be left uninitialized.
+ *
+ * Memory for the vtable is allocated by the caller, not by the module.
+ */
+
+#ifndef KRB5_POLICY_PLUGIN_H
+#define KRB5_POLICY_PLUGIN_H
+
+#include <krb5/krb5.h>
+
+/* Abstract module datatype. */
+typedef struct krb5_kdcpolicy_moddata_st *krb5_kdcpolicy_moddata;
+
+/* A module can optionally include kdb.h to inspect principal entries when
+ * authorizing requests. */
+struct _krb5_db_entry_new;
+
+/*
+ * Optional: Initialize module data. Return 0 on success,
+ * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for
+ * example), and any other error code to abort KDC startup. Optionally set
+ * *data_out to a module data object to be passed to future calls.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_init_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata *data_out);
+
+/* Optional: Clean up module data. */
+typedef krb5_error_code
+(*krb5_kdcpolicy_fini_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata);
+
+/*
+ * Optional: return an error code and set status to an appropriate string
+ * literal to deny an AS request; otherwise return 0. lifetime_out, if set,
+ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the
+ * ticket renewable lifetime.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_check_as_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata,
+ const krb5_kdc_req *request,
+ const struct _krb5_db_entry_new *client,
+ const struct _krb5_db_entry_new *server,
+ const char *const *auth_indicators,
+ const char **status, krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out);
+
+/*
+ * Optional: return an error code and set status to an appropriate string
+ * literal to deny a TGS request; otherwise return 0. lifetime_out, if set,
+ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the
+ * ticket renewable lifetime.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_check_tgs_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata,
+ const krb5_kdc_req *request,
+ const struct _krb5_db_entry_new *server,
+ const krb5_ticket *ticket,
+ const char *const *auth_indicators,
+ const char **status, krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out);
+
+typedef struct krb5_kdcpolicy_vtable_st {
+ const char *name;
+ krb5_kdcpolicy_init_fn init;
+ krb5_kdcpolicy_fini_fn fini;
+ krb5_kdcpolicy_check_as_fn check_as;
+ krb5_kdcpolicy_check_tgs_fn check_tgs;
+} *krb5_kdcpolicy_vtable;
+
+#endif /* KRB5_POLICY_PLUGIN_H */
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index f85da6da6..f5cf8ad89 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -207,6 +207,13 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
state->ticket_reply.enc_part2 = &state->enc_tkt_reply;
+ errcode = check_kdcpolicy_as(kdc_context, state->request, state->client,
+ state->server, state->auth_indicators,
+ state->kdc_time, &state->enc_tkt_reply.times,
+ &state->status);
+ if (errcode)
+ goto egress;
+
/*
* Find the server key
*/
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index ac5864603..0009a9319 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -518,6 +518,12 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
kdc_get_ticket_renewtime(kdc_active_realm, request, header_enc_tkt, client,
server, &enc_tkt_reply);
+ errcode = check_kdcpolicy_tgs(kdc_context, request, server, header_ticket,
+ auth_indicators, kdc_time,
+ &enc_tkt_reply.times, &status);
+ if (errcode)
+ goto cleanup;
+
/*
* Set authtime to be the same as header or evidence ticket's
*/
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index b710aefe4..5455e2a67 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -642,7 +642,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
krb5_db_entry server, krb5_timestamp kdc_time,
const char **status, krb5_pa_data ***e_data)
{
- int errcode;
krb5_error_code ret;
/*
@@ -750,12 +749,6 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
return errcode_to_protocol(ret);
- /* Check against local policy. */
- errcode = against_local_policy_as(request, client, server,
- kdc_time, status, e_data);
- if (errcode)
- return errcode;
-
return 0;
}
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 672f94380..dcedfd538 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -166,17 +166,6 @@ kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...)
#endif
;
-/* policy.c */
-int
-against_local_policy_as (krb5_kdc_req *, krb5_db_entry,
- krb5_db_entry, krb5_timestamp,
- const char **, krb5_pa_data ***);
-
-int
-against_local_policy_tgs (krb5_kdc_req *, krb5_db_entry,
- krb5_ticket *, const char **,
- krb5_pa_data ***);
-
/* kdc_preauth.c */
krb5_boolean
enctype_requires_etype_info_2(krb5_enctype enctype);
diff --git a/src/kdc/main.c b/src/kdc/main.c
index a4dffb29a..ccac3a759 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -31,6 +31,7 @@
#include "kdc_util.h"
#include "kdc_audit.h"
#include "extern.h"
+#include "policy.h"
#include "kdc5_err.h"
#include "kdb_kt.h"
#include "net-server.h"
@@ -986,6 +987,12 @@ int main(int argc, char **argv)
load_preauth_plugins(&shandle, kcontext, ctx);
load_authdata_plugins(kcontext);
+ retval = load_kdcpolicy_plugins(kcontext);
+ if (retval) {
+ kdc_err(kcontext, retval, _("while loading KDC policy plugin"));
+ finish_realms();
+ return 1;
+ }
retval = setup_sam();
if (retval) {
@@ -1068,6 +1075,7 @@ int main(int argc, char **argv)
krb5_klog_syslog(LOG_INFO, _("shutting down"));
unload_preauth_plugins(kcontext);
unload_authdata_plugins(kcontext);
+ unload_kdcpolicy_plugins(kcontext);
unload_audit_modules(kcontext);
krb5_klog_close(kcontext);
finish_realms();
diff --git a/src/kdc/policy.c b/src/kdc/policy.c
index 6cba4303f..e49644e06 100644
--- a/src/kdc/policy.c
+++ b/src/kdc/policy.c
@@ -1,67 +1,246 @@
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* kdc/policy.c - Policy decision routines for KDC */
/*
- * Copyright 1990 by the Massachusetts Institute of Technology.
+ * Copyright (C) 2017 by Red Hat, 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.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
*
- * 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.
+ * * 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 "kdc_util.h"
#include "extern.h"
+#include "policy.h"
+#include "adm_proto.h"
+#include <krb5/kdcpolicy_plugin.h>
+#include <syslog.h>
-int
-against_local_policy_as(register krb5_kdc_req *request, krb5_db_entry client,
- krb5_db_entry server, krb5_timestamp kdc_time,
- const char **status, krb5_pa_data ***e_data)
+typedef struct kdcpolicy_handle_st {
+ struct krb5_kdcpolicy_vtable_st vt;
+ krb5_kdcpolicy_moddata moddata;
+} *kdcpolicy_handle;
+
+static kdcpolicy_handle *handles;
+
+static void
+free_indicators(char **ais)
{
-#if 0
- /* An AS request must include the addresses field */
- if (request->addresses == 0) {
- *status = "NO ADDRESS";
- return KRB5KDC_ERR_POLICY;
- }
-#endif
+ size_t i;
- return 0; /* not against policy */
+ if (ais == NULL)
+ return;
+ for (i = 0; ais[i] != NULL; i++)
+ free(ais[i]);
+ free(ais);
+}
+
+/* Convert inds to a null-terminated list of C strings. */
+static krb5_error_code
+authind_strings(krb5_data *const *inds, char ***strs_out)
+{
+ krb5_error_code ret;
+ char **list = NULL;
+ size_t i, count;
+
+ *strs_out = NULL;
+
+ for (count = 0; inds != NULL && inds[count] != NULL; count++);
+ list = k5calloc(count + 1, sizeof(*list), &ret);
+ if (list == NULL)
+ goto error;
+
+ for (i = 0; i < count; i++) {
+ list[i] = k5memdup0(inds[i]->data, inds[i]->length, &ret);
+ if (list[i] == NULL)
+ goto error;
+ }
+
+ *strs_out = list;
+ return 0;
+
+error:
+ free_indicators(list);
+ return ret;
+}
+
+/* Constrain times->endtime to life and times->renew_till to rlife, relative to
+ * now. */
+static void
+update_ticket_times(krb5_ticket_times *times, krb5_timestamp now,
+ krb5_deltat life, krb5_deltat rlife)
+{
+ if (life)
+ times->endtime = ts_min(ts_incr(now, life), times->endtime);
+ if (rlife)
+ times->renew_till = ts_min(ts_incr(now, rlife), times->renew_till);
+}
+
+/* Check an AS request against kdcpolicy modules, updating times with any
+ * module endtime constraints. Set an appropriate status string on error. */
+krb5_error_code
+check_kdcpolicy_as(krb5_context context, const krb5_kdc_req *request,
+ const krb5_db_entry *client, const krb5_db_entry *server,
+ krb5_data *const *auth_indicators, krb5_timestamp kdc_time,
+ krb5_ticket_times *times, const char **status)
+{
+ krb5_deltat life, rlife;
+ krb5_error_code ret;
+ kdcpolicy_handle *hp, h;
+ char **ais = NULL;
+
+ *status = NULL;
+
+ ret = authind_strings(auth_indicators, &ais);
+ if (ret)
+ goto done;
+
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+ if (h->vt.check_as == NULL)
+ continue;
+
+ ret = h->vt.check_as(context, h->moddata, request, client, server,
+ (const char **)ais, status, &life, &rlife);
+ if (ret)
+ goto done;
+
+ update_ticket_times(times, kdc_time, life, rlife);
+ }
+
+done:
+ free_indicators(ais);
+ return ret;
}
/*
- * This is where local policy restrictions for the TGS should placed.
+ * Check the TGS request against the local TGS policy. Accepts an
+ * authentication indicator for the module policy decisions. Returns 0 and a
+ * NULL status string on success.
*/
krb5_error_code
-against_local_policy_tgs(register krb5_kdc_req *request, krb5_db_entry server,
- krb5_ticket *ticket, const char **status,
- krb5_pa_data ***e_data)
+check_kdcpolicy_tgs(krb5_context context, const krb5_kdc_req *request,
+ const krb5_db_entry *server, const krb5_ticket *ticket,
+ krb5_data *const *auth_indicators, krb5_timestamp kdc_time,
+ krb5_ticket_times *times, const char **status)
{
-#if 0
- /*
- * For example, if your site wants to disallow ticket forwarding,
- * you might do something like this:
- */
+ krb5_deltat life, rlife;
+ krb5_error_code ret;
+ kdcpolicy_handle *hp, h;
+ char **ais = NULL;
- if (isflagset(request->kdc_options, KDC_OPT_FORWARDED)) {
- *status = "FORWARD POLICY";
- return KRB5KDC_ERR_POLICY;
+ *status = NULL;
+
+ ret = authind_strings(auth_indicators, &ais);
+ if (ret)
+ goto done;
+
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+ if (h->vt.check_tgs == NULL)
+ continue;
+
+ ret = h->vt.check_tgs(context, h->moddata, request, server, ticket,
+ (const char **)ais, status, &life, &rlife);
+ if (ret)
+ goto done;
+
+ update_ticket_times(times, kdc_time, life, rlife);
}
-#endif
- return 0; /* not against policy */
+done:
+ free_indicators(ais);
+ return ret;
+}
+
+void
+unload_kdcpolicy_plugins(krb5_context context)
+{
+ kdcpolicy_handle *hp, h;
+
+ for (hp = handles; *hp != NULL; hp++) {
+ h = *hp;
+ if (h->vt.fini != NULL)
+ h->vt.fini(context, h->moddata);
+ free(h);
+ }
+ free(handles);
+ handles = NULL;
+}
+
+krb5_error_code
+load_kdcpolicy_plugins(krb5_context context)
+{
+ krb5_error_code ret;
+ krb5_plugin_initvt_fn *modules = NULL, *mod;
+ kdcpolicy_handle h;
+ size_t count;
+
+ ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_KDCPOLICY, &modules);
+ if (ret)
+ goto cleanup;
+
+ for (count = 0; modules[count] != NULL; count++);
+ handles = k5calloc(count + 1, sizeof(*handles), &ret);
+ if (handles == NULL)
+ goto cleanup;
+
+ count = 0;
+ for (mod = modules; *mod != NULL; mod++) {
+ h = k5calloc(1, sizeof(*h), &ret);
+ if (h == NULL)
+ goto cleanup;
+
+ ret = (*mod)(context, 1, 1, (krb5_plugin_vtable)&h->vt);
+ if (ret) { /* Version mismatch. */
+ TRACE_KDCPOLICY_VTINIT_FAIL(context, ret);
+ free(h);
+ continue;
+ }
+ if (h->vt.init != NULL) {
+ ret = h->vt.init(context, &h->moddata);
+ if (ret == KRB5_PLUGIN_NO_HANDLE) {
+ TRACE_KADM5_AUTH_INIT_SKIP(context, h->vt.name);
+ free(h);
+ continue;
+ }
+ if (ret) {
+ kdc_err(context, ret, _("while loading policy module %s"),
+ h->vt.name);
+ free(h);
+ goto cleanup;
+ }
+ }
+ handles[count++] = h;
+ }
+
+ ret = 0;
+
+cleanup:
+ if (ret)
+ unload_kdcpolicy_plugins(context);
+ k5_plugin_free_modules(context, modules);
+ return ret;
}
diff --git a/src/kdc/policy.h b/src/kdc/policy.h
index 6b000dc90..2a57b0a01 100644
--- a/src/kdc/policy.h
+++ b/src/kdc/policy.h
@@ -26,11 +26,22 @@
#ifndef __KRB5_KDC_POLICY__
#define __KRB5_KDC_POLICY__
-extern int against_postdate_policy (krb5_timestamp);
+krb5_error_code
+load_kdcpolicy_plugins(krb5_context context);
-extern int against_flag_policy_as (const krb5_kdc_req *);
+void
+unload_kdcpolicy_plugins(krb5_context context);
-extern int against_flag_policy_tgs (const krb5_kdc_req *,
- const krb5_ticket *);
+krb5_error_code
+check_kdcpolicy_as(krb5_context context, const krb5_kdc_req *request,
+ const krb5_db_entry *client, const krb5_db_entry *server,
+ krb5_data *const *auth_indicators, krb5_timestamp kdc_time,
+ krb5_ticket_times *times, const char **status);
+
+krb5_error_code
+check_kdcpolicy_tgs(krb5_context context, const krb5_kdc_req *request,
+ const krb5_db_entry *server, const krb5_ticket *ticket,
+ krb5_data *const *auth_indicators, krb5_timestamp kdc_time,
+ krb5_ticket_times *times, const char **status);
#endif /* __KRB5_KDC_POLICY__ */
diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c
index d0f25d1b7..33cfbcd81 100644
--- a/src/kdc/tgs_policy.c
+++ b/src/kdc/tgs_policy.c
@@ -375,11 +375,5 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm,
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
return errcode_to_protocol(ret);
- /* Check local policy. */
- errcode = against_local_policy_tgs(request, server, ticket,
- status, e_data);
- if (errcode)
- return errcode;
-
return 0;
}
diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c
index 17dd6bd30..31aaf661d 100644
--- a/src/lib/krb5/krb/plugin.c
+++ b/src/lib/krb5/krb/plugin.c
@@ -58,7 +58,9 @@ const char *interface_names[] = {
"audit",
"tls",
"kdcauthdata",
- "certauth"
+ "certauth",
+ "kadm5_auth",
+ "kdcpolicy",
};
/* Return the context's interface structure for id, or NULL if invalid. */
diff --git a/src/plugins/kdcpolicy/test/Makefile.in b/src/plugins/kdcpolicy/test/Makefile.in
new file mode 100644
index 000000000..b81f1a7ce
--- /dev/null
+++ b/src/plugins/kdcpolicy/test/Makefile.in
@@ -0,0 +1,20 @@
+mydir=plugins$(S)policy$(S)test
+BUILDTOP=$(REL)..$(S)..$(S)..
+
+LIBBASE=policy_test
+LIBMAJOR=0
+LIBMINOR=0
+RELDIR=../plugins/kdcpolicy/test
+SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS)
+SHLIB_EXPLIBS=$(KRB5_BASE_LIBS)
+
+STLIBOBJS=main.o
+
+SRCS=$(srcdir)/main.c
+
+all-unix: all-libs
+install-unix:
+clean-unix:: clean-libs clean-libobjs
+
+@libnover_frag@
+@libobj_frag@
diff --git a/src/plugins/kdcpolicy/test/deps b/src/plugins/kdcpolicy/test/deps
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/plugins/kdcpolicy/test/main.c b/src/plugins/kdcpolicy/test/main.c
new file mode 100644
index 000000000..eb8fde053
--- /dev/null
+++ b/src/plugins/kdcpolicy/test/main.c
@@ -0,0 +1,111 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */
+/*
+ * Copyright (C) 2017 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 "kdb.h"
+#include <krb5/kdcpolicy_plugin.h>
+
+static krb5_error_code
+output_from_indicator(const char *const *auth_indicators,
+ krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out,
+ const char **status)
+{
+ if (auth_indicators[0] == NULL) {
+ *status = NULL;
+ return 0;
+ }
+
+ if (strcmp(auth_indicators[0], "ONE_HOUR") == 0) {
+ *lifetime_out = 3600;
+ *renew_lifetime_out = *lifetime_out * 2;
+ return 0;
+ } else if (strcmp(auth_indicators[0], "SEVEN_HOURS") == 0) {
+ *lifetime_out = 7 * 3600;
+ *renew_lifetime_out = *lifetime_out * 2;
+ return 0;
+ }
+
+ *status = "LOCAL_POLICY";
+ return KRB5KDC_ERR_POLICY;
+}
+
+static krb5_error_code
+test_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
+ const krb5_kdc_req *request, const krb5_db_entry *client,
+ const krb5_db_entry *server, const char *const *auth_indicators,
+ const char **status, krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out)
+{
+ if (request->client != NULL && request->client->length >= 1 &&
+ data_eq_string(request->client->data[0], "fail")) {
+ *status = "LOCAL_POLICY";
+ return KRB5KDC_ERR_POLICY;
+ }
+ return output_from_indicator(auth_indicators, lifetime_out,
+ renew_lifetime_out, status);
+}
+
+static krb5_error_code
+test_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata,
+ const krb5_kdc_req *request, const krb5_db_entry *server,
+ const krb5_ticket *ticket, const char *const *auth_indicators,
+ const char **status, krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out)
+{
+ if (request->server != NULL && request->server->length >= 1 &&
+ data_eq_string(request->server->data[0], "fail")) {
+ *status = "LOCAL_POLICY";
+ return KRB5KDC_ERR_POLICY;
+ }
+ return output_from_indicator(auth_indicators, lifetime_out,
+ renew_lifetime_out, status);
+}
+
+krb5_error_code
+kdcpolicy_test_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable);
+krb5_error_code
+kdcpolicy_test_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable)
+{
+ krb5_kdcpolicy_vtable vt;
+
+ if (maj_ver != 1)
+ return KRB5_PLUGIN_VER_NOTSUPP;
+
+ vt = (krb5_kdcpolicy_vtable)vtable;
+ vt->name = "test";
+ vt->check_as = test_check_as;
+ vt->check_tgs = test_check_tgs;
+ return 0;
+}
diff --git a/src/plugins/kdcpolicy/test/policy_test.exports b/src/plugins/kdcpolicy/test/policy_test.exports
new file mode 100644
index 000000000..9682ec74f
--- /dev/null
+++ b/src/plugins/kdcpolicy/test/policy_test.exports
@@ -0,0 +1 @@
+kdcpolicy_test_initvt
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index 2b3112537..a2093108b 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -169,6 +169,7 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter
$(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS)
+ $(RUNPYTEST) $(srcdir)/t_kdcpolicy.py $(PYTESTFLAGS)
clean:
$(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest
diff --git a/src/tests/t_kdcpolicy.py b/src/tests/t_kdcpolicy.py
new file mode 100644
index 000000000..6a745b959
--- /dev/null
+++ b/src/tests/t_kdcpolicy.py
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+from k5test import *
+from datetime import datetime
+import re
+
+testpreauth = os.path.join(buildtop, 'plugins', 'preauth', 'test', 'test.so')
+testpolicy = os.path.join(buildtop, 'plugins', 'kdcpolicy', 'test',
+ 'policy_test.so')
+krb5_conf = {'plugins': {'kdcpreauth': {'module': 'test:' + testpreauth},
+ 'clpreauth': {'module': 'test:' + testpreauth},
+ 'kdcpolicy': {'module': 'test:' + testpolicy}}}
+kdc_conf = {'realms': {'$realm': {'default_principal_flags': '+preauth',
+ 'max_renewable_life': '1d'}}}
+realm = K5Realm(krb5_conf=krb5_conf, kdc_conf=kdc_conf)
+
+realm.run([kadminl, 'addprinc', '-pw', password('fail'), 'fail'])
+
+def verify_time(out, target_time):
+ times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out)
+ times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times]
+ while len(times) > 0:
+ starttime = times.pop(0)
+ endtime = times.pop(0)
+ renewtime = times.pop(0)
+
+ if str(endtime - starttime) != target_time:
+ fail('unexpected lifetime value')
+ if str(renewtime - endtime) != target_time:
+ fail('unexpected renewable value')
+
+rflags = ['-r', '1d', '-l', '12h']
+
+# Test AS+TGS success path.
+realm.kinit(realm.user_princ, password('user'),
+ rflags + ['-X', 'indicators=SEVEN_HOURS'])
+realm.run([kvno, realm.host_princ])
+realm.run(['./adata', realm.host_princ], expected_msg='+97: [SEVEN_HOURS]')
+out = realm.run([klist, realm.ccache, '-e'])
+verify_time(out, '7:00:00')
+
+# Test AS+TGS success path with different values.
+realm.kinit(realm.user_princ, password('user'),
+ rflags + ['-X', 'indicators=ONE_HOUR'])
+realm.run([kvno, realm.host_princ])
+realm.run(['./adata', realm.host_princ], expected_msg='+97: [ONE_HOUR]')
+out = realm.run([klist, realm.ccache, '-e'])
+verify_time(out, '1:00:00')
+
+# Test TGS failure path (using previous creds).
+realm.run([kvno, 'fail@%s' % realm.realm], expected_code=1,
+ expected_msg='KDC policy rejects request')
+
+# Test AS failure path.
+realm.kinit('fail@%s' % realm.realm, password('fail'),
+ expected_code=1, expected_msg='KDC policy rejects request')
+
+success('kdcpolicy tests')

View File

@ -1,101 +0,0 @@
From 6ce3a9416ee73fee41d0190e3fd0fde0a097c774 Mon Sep 17 00:00:00 2001
From: Matt Rogers <mrogers@redhat.com>
Date: Fri, 9 Dec 2016 11:43:27 -0500
Subject: [PATCH] Add PKINIT UPN tests to t_pkinit.py
[ghudson@mit.edu: simplify and explain tests; add test for
id-pkinit-san match against canonicalized client principal]
ticket: 8528
(cherry picked from commit d520fd3f032121b61b22681838af96ee505fe44d)
---
src/tests/t_pkinit.py | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index 526473b42..ac4d326b6 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -23,6 +23,9 @@ privkey_pem = os.path.join(certs, 'privkey.pem')
privkey_enc_pem = os.path.join(certs, 'privkey-enc.pem')
user_p12 = os.path.join(certs, 'user.p12')
user_enc_p12 = os.path.join(certs, 'user-enc.p12')
+user_upn_p12 = os.path.join(certs, 'user-upn.p12')
+user_upn2_p12 = os.path.join(certs, 'user-upn2.p12')
+user_upn3_p12 = os.path.join(certs, 'user-upn3.p12')
path = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs')
path_enc = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs-enc')
@@ -36,6 +39,20 @@ pkinit_kdc_conf = {'realms': {'$realm': {
restrictive_kdc_conf = {'realms': {'$realm': {
'restrict_anonymous_to_tgt': 'true' }}}
+testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'},
+ 'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
+ 'user2': {'keys': 'aes128-cts', 'flags': '+preauth'}}
+alias_kdc_conf = {'realms': {'$realm': {
+ 'default_principal_flags': '+preauth',
+ 'pkinit_eku_checking': 'none',
+ 'pkinit_allow_upn': 'true',
+ 'pkinit_identity': 'FILE:%s,%s' % (kdc_pem, privkey_pem),
+ 'database_module': 'test'}},
+ 'dbmodules': {'test': {
+ 'db_library': 'test',
+ 'alias': {'user@krbtest.com': 'user'},
+ 'princs': testprincs}}}
+
file_identity = 'FILE:%s,%s' % (user_pem, privkey_pem)
file_enc_identity = 'FILE:%s,%s' % (user_pem, privkey_enc_pem)
dir_identity = 'DIR:%s' % path
@@ -45,11 +62,51 @@ dir_file_identity = 'FILE:%s,%s' % (os.path.join(path, 'user.crt'),
dir_file_enc_identity = 'FILE:%s,%s' % (os.path.join(path_enc, 'user.crt'),
os.path.join(path_enc, 'user.key'))
p12_identity = 'PKCS12:%s' % user_p12
+p12_upn_identity = 'PKCS12:%s' % user_upn_p12
+p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12
+p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12
p12_enc_identity = 'PKCS12:%s' % user_enc_p12
p11_identity = 'PKCS11:soft-pkcs11.so'
p11_token_identity = ('PKCS11:module_name=soft-pkcs11.so:'
'slotid=1:token=SoftToken (token)')
+# Start a realm with the test kdb module for the following UPN SAN tests.
+realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=alias_kdc_conf,
+ create_kdb=False)
+realm.start_kdc()
+
+# Compatibility check: cert contains UPN "user", which matches the
+# request principal user@KRBTEST.COM if parsed as a normal principal.
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % p12_upn2_identity])
+
+# Compatibility check: cert contains UPN "user@KRBTEST.COM", which matches
+# the request principal user@KRBTEST.COM if parsed as a normal principal.
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % p12_upn3_identity])
+
+# Cert contains UPN "user@krbtest.com" which is aliased to the request
+# principal.
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % p12_upn_identity])
+
+# Test an id-pkinit-san match to a post-canonical principal.
+realm.kinit('user@krbtest.com',
+ flags=['-E', '-X', 'X509_user_identity=%s' % p12_identity])
+
+# Test a UPN match to a post-canonical principal. (This only works
+# for the cert with the UPN containing just "user", as we don't allow
+# UPN reparsing when comparing to the canonicalized client principal.)
+realm.kinit('user@krbtest.com',
+ flags=['-E', '-X', 'X509_user_identity=%s' % p12_upn2_identity])
+
+# Test a mismatch.
+out = realm.run([kinit, '-X', 'X509_user_identity=%s' % p12_upn2_identity,
+ 'user2'], expected_code=1)
+if 'kinit: Client name mismatch while getting initial credentials' not in out:
+ fail('Wrong error for UPN SAN mismatch')
+realm.stop()
+
realm = K5Realm(krb5_conf=pkinit_krb5_conf, kdc_conf=pkinit_kdc_conf,
get_creds=False)

View File

@ -1,51 +0,0 @@
From e267849bcc3813989470c03565b22d25c71af91e Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 25 Aug 2017 12:39:14 -0400
Subject: [PATCH] Add PKINIT test case for generic client cert
In t_pkinit.py, add a test case where a client cert with no extensions
is authorized via subject and issuer using a pkinit_cert_match string
attribute.
ticket: 8562
(cherry picked from commit 8c5d50888aab554239fd51306e79c5213833c898)
[rharwood@redhat.com: backport around dbmatch module]
---
src/tests/t_pkinit.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index e943f4974..fa5c5199e 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -26,6 +26,7 @@ user_enc_p12 = os.path.join(certs, 'user-enc.p12')
user_upn_p12 = os.path.join(certs, 'user-upn.p12')
user_upn2_p12 = os.path.join(certs, 'user-upn2.p12')
user_upn3_p12 = os.path.join(certs, 'user-upn3.p12')
+generic_p12 = os.path.join(certs, 'generic.p12')
path = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs')
path_enc = os.path.join(os.getcwd(), 'testdir', 'tmp-pkinit-certs-enc')
@@ -65,6 +66,7 @@ p12_identity = 'PKCS12:%s' % user_p12
p12_upn_identity = 'PKCS12:%s' % user_upn_p12
p12_upn2_identity = 'PKCS12:%s' % user_upn2_p12
p12_upn3_identity = 'PKCS12:%s' % user_upn3_p12
+p12_generic_identity = 'PKCS12:%s' % generic_p12
p12_enc_identity = 'PKCS12:%s' % user_enc_p12
p11_identity = 'PKCS11:soft-pkcs11.so'
p11_token_identity = ('PKCS11:module_name=soft-pkcs11.so:'
@@ -284,6 +286,14 @@ realm.run(['./responder', '-X', 'X509_user_identity=%s' % p12_enc_identity,
realm.klist(realm.user_princ)
realm.run([kvno, realm.host_princ])
+# Authorize a client cert with no PKINIT extensions using subject and
+# issuer. (Relies on EKU checking being turned off.)
+rule = '&&<SUBJECT>CN=user$<ISSUER>O=MIT,'
+realm.run([kadminl, 'setstr', realm.user_princ, 'pkinit_cert_match', rule])
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % p12_generic_identity])
+realm.klist(realm.user_princ)
+
if not have_soft_pkcs11:
skip_rest('PKINIT PKCS11 tests', 'soft-pkcs11.so not found')

File diff suppressed because it is too large Load Diff

View File

@ -1,293 +0,0 @@
From 632575ab12fc5d6c9bdc83cb8200fb8f4f422b83 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 23 Aug 2017 17:25:17 -0400
Subject: [PATCH] Add hostname-based ccselect module
The hostname module selects the ccache whose realm is the longest
parent domain tail of the uppercase server hostname.
[ghudson@mit.edu: minor edits]
ticket: 8613 (new)
(cherry picked from commit a4ddc6cf576b4155e6b994307902567f26f752b2)
---
doc/admin/conf_files/krb5_conf.rst | 4 +
src/lib/krb5/ccache/Makefile.in | 3 +
src/lib/krb5/ccache/cc-int.h | 4 +
src/lib/krb5/ccache/ccselect.c | 5 ++
src/lib/krb5/ccache/ccselect_hostname.c | 146 ++++++++++++++++++++++++++++++++
src/tests/gssapi/t_ccselect.py | 9 ++
6 files changed, 171 insertions(+)
create mode 100644 src/lib/krb5/ccache/ccselect_hostname.c
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 1d9bc9e34..9c1ee94a4 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -745,6 +745,10 @@ disabled with the disable tag):
Uses the service realm to guess an appropriate cache from the
collection
+**hostname**
+ If the service principal is host-based, uses the service hostname
+ to guess an appropriate cache from the collection
+
.. _pwqual:
pwqual interface
diff --git a/src/lib/krb5/ccache/Makefile.in b/src/lib/krb5/ccache/Makefile.in
index 5ac870728..f84cf793e 100644
--- a/src/lib/krb5/ccache/Makefile.in
+++ b/src/lib/krb5/ccache/Makefile.in
@@ -34,6 +34,7 @@ STLIBOBJS= \
ccdefops.o \
ccmarshal.o \
ccselect.o \
+ ccselect_hostname.o \
ccselect_k5identity.o \
ccselect_realm.o \
cc_dir.o \
@@ -52,6 +53,7 @@ OBJS= $(OUTPRE)ccbase.$(OBJEXT) \
$(OUTPRE)ccdefops.$(OBJEXT) \
$(OUTPRE)ccmarshal.$(OBJEXT) \
$(OUTPRE)ccselect.$(OBJEXT) \
+ $(OUTPRE)ccselect_hostname.$(OBJEXT) \
$(OUTPRE)ccselect_k5identity.$(OBJEXT) \
$(OUTPRE)ccselect_realm.$(OBJEXT) \
$(OUTPRE)cc_dir.$(OBJEXT) \
@@ -70,6 +72,7 @@ SRCS= $(srcdir)/ccbase.c \
$(srcdir)/ccdefops.c \
$(srcdir)/ccmarshal.c \
$(srcdir)/ccselect.c \
+ $(srcdir)/ccselect_hostname.c \
$(srcdir)/ccselect_k5identity.c \
$(srcdir)/ccselect_realm.c \
$(srcdir)/cc_dir.c \
diff --git a/src/lib/krb5/ccache/cc-int.h b/src/lib/krb5/ccache/cc-int.h
index ee9b5e0e9..d920367ce 100644
--- a/src/lib/krb5/ccache/cc-int.h
+++ b/src/lib/krb5/ccache/cc-int.h
@@ -123,6 +123,10 @@ k5_cccol_force_unlock(void);
krb5_error_code
krb5int_fcc_new_unique(krb5_context context, char *template, krb5_ccache *id);
+krb5_error_code
+ccselect_hostname_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable);
+
krb5_error_code
ccselect_realm_initvt(krb5_context context, int maj_ver, int min_ver,
krb5_plugin_vtable vtable);
diff --git a/src/lib/krb5/ccache/ccselect.c b/src/lib/krb5/ccache/ccselect.c
index ee4b83a9b..393d39733 100644
--- a/src/lib/krb5/ccache/ccselect.c
+++ b/src/lib/krb5/ccache/ccselect.c
@@ -71,6 +71,11 @@ load_modules(krb5_context context)
if (ret != 0)
goto cleanup;
+ ret = k5_plugin_register(context, PLUGIN_INTERFACE_CCSELECT, "hostname",
+ ccselect_hostname_initvt);
+ if (ret != 0)
+ goto cleanup;
+
ret = k5_plugin_load_all(context, PLUGIN_INTERFACE_CCSELECT, &modules);
if (ret != 0)
goto cleanup;
diff --git a/src/lib/krb5/ccache/ccselect_hostname.c b/src/lib/krb5/ccache/ccselect_hostname.c
new file mode 100644
index 000000000..475cfabae
--- /dev/null
+++ b/src/lib/krb5/ccache/ccselect_hostname.c
@@ -0,0 +1,146 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/krb5/ccache/ccselect_hostname.c - hostname ccselect module */
+/*
+ * Copyright (C) 2017 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 "cc-int.h"
+#include <ctype.h>
+#include <krb5/ccselect_plugin.h>
+
+/* Swap a and b, using tmp as an intermediate. */
+#define SWAP(a, b, tmp) \
+ tmp = a; \
+ a = b; \
+ b = tmp;
+
+static krb5_error_code
+hostname_init(krb5_context context, krb5_ccselect_moddata *data_out,
+ int *priority_out)
+{
+ *data_out = NULL;
+ *priority_out = KRB5_CCSELECT_PRIORITY_HEURISTIC;
+ return 0;
+}
+
+static krb5_error_code
+hostname_choose(krb5_context context, krb5_ccselect_moddata data,
+ krb5_principal server, krb5_ccache *ccache_out,
+ krb5_principal *princ_out)
+{
+ krb5_error_code ret;
+ char *p, *host = NULL;
+ size_t hostlen;
+ krb5_cccol_cursor col_cursor;
+ krb5_ccache ccache, tmp_ccache, best_ccache = NULL;
+ krb5_principal princ, tmp_princ, best_princ = NULL;
+ krb5_data domain;
+
+ *ccache_out = NULL;
+ *princ_out = NULL;
+
+ if (server->type != KRB5_NT_SRV_HST || server->length < 2)
+ return KRB5_PLUGIN_NO_HANDLE;
+
+ /* Compute upper-case hostname. */
+ hostlen = server->data[1].length;
+ host = k5memdup0(server->data[1].data, hostlen, &ret);
+ if (host == NULL)
+ return ret;
+ for (p = host; *p != '\0'; p++) {
+ if (islower(*p))
+ *p = toupper(*p);
+ }
+
+ /* Scan the collection for a cache with a client principal whose realm is
+ * the longest tail of the server hostname. */
+ ret = krb5_cccol_cursor_new(context, &col_cursor);
+ if (ret)
+ goto done;
+
+ for (ret = krb5_cccol_cursor_next(context, col_cursor, &ccache);
+ ret == 0 && ccache != NULL;
+ ret = krb5_cccol_cursor_next(context, col_cursor, &ccache)) {
+ ret = krb5_cc_get_principal(context, ccache, &princ);
+ if (ret) {
+ krb5_cc_close(context, ccache);
+ break;
+ }
+
+ /* Check for a longer match than we have. */
+ domain = make_data(host, hostlen);
+ while (best_princ == NULL ||
+ best_princ->realm.length < domain.length) {
+ if (data_eq(princ->realm, domain)) {
+ SWAP(best_ccache, ccache, tmp_ccache);
+ SWAP(best_princ, princ, tmp_princ);
+ break;
+ }
+
+ /* Try the next parent domain. */
+ p = memchr(domain.data, '.', domain.length);
+ if (p == NULL)
+ break;
+ domain = make_data(p + 1, hostlen - (p + 1 - host));
+ }
+
+ if (ccache != NULL)
+ krb5_cc_close(context, ccache);
+ krb5_free_principal(context, princ);
+ }
+
+ krb5_cccol_cursor_free(context, &col_cursor);
+
+ if (best_ccache != NULL) {
+ *ccache_out = best_ccache;
+ *princ_out = best_princ;
+ } else {
+ ret = KRB5_PLUGIN_NO_HANDLE;
+ }
+
+done:
+ free(host);
+ return ret;
+}
+
+krb5_error_code
+ccselect_hostname_initvt(krb5_context context, int maj_ver, int min_ver,
+ krb5_plugin_vtable vtable)
+{
+ krb5_ccselect_vtable vt;
+
+ if (maj_ver != 1)
+ return KRB5_PLUGIN_VER_NOTSUPP;
+ vt = (krb5_ccselect_vtable)vtable;
+ vt->name = "hostname";
+ vt->init = hostname_init;
+ vt->choose = hostname_choose;
+ return 0;
+}
diff --git a/src/tests/gssapi/t_ccselect.py b/src/tests/gssapi/t_ccselect.py
index 668a2cc62..3503f9269 100755
--- a/src/tests/gssapi/t_ccselect.py
+++ b/src/tests/gssapi/t_ccselect.py
@@ -33,6 +33,7 @@ host1 = 'p:' + r1.host_princ
host2 = 'p:' + r2.host_princ
foo = 'foo.krbtest.com'
foo2 = 'foo.krbtest2.com'
+foobar = "foo.bar.krbtest.com"
# These strings specify the target as a GSS name. The resulting
# principal will have the host-based type, with the referral realm
@@ -42,6 +43,7 @@ foo2 = 'foo.krbtest2.com'
# single component.
gssserver = 'h:host@' + foo
gssserver2 = 'h:host@' + foo2
+gssserver_bar = 'h:host@' + foobar
gsslocal = 'h:host@localhost'
# refserver specifies the target as a principal in the referral realm.
@@ -77,10 +79,12 @@ r1.addprinc('host/localhost')
r2.addprinc('host/localhost')
r1.addprinc('host/' + foo)
r2.addprinc('host/' + foo2)
+r1.addprinc('host/' + foobar)
r1.extract_keytab('host/localhost', r1.keytab)
r2.extract_keytab('host/localhost', r2.keytab)
r1.extract_keytab('host/' + foo, r1.keytab)
r2.extract_keytab('host/' + foo2, r2.keytab)
+r1.extract_keytab('host/' + foobar, r1.keytab)
# Get tickets for one user in each realm (zaphod will be primary).
r1.kinit(alice, password('alice'))
@@ -128,6 +132,11 @@ output = r2.run(['./t_ccselect', gsslocal])
if output != (zaphod + '\n'):
fail('zaphod not chosen via default realm fallback')
+# Check that realm ccselect fallback works correctly
+r1.run(['./t_ccselect', gssserver_bar], expected_msg=alice)
+r2.kinit(zaphod, password('zaphod'))
+r1.run(['./t_ccselect', gssserver_bar], expected_msg=alice)
+
# Get a second cred in r1 (bob will be primary).
r1.kinit(bob, password('bob'))

View File

@ -1,96 +0,0 @@
From 9c6f61e30e11eca5c04daa3f0dce398602ef5801 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 17 Jan 2017 11:24:41 -0500
Subject: [PATCH] Add k5test expected_msg, expected_trace
In k5test.py, add the optional keyword argument "expected_msg" to
methods that run commands, to make it easier to look for substrings in
the command output. Add the optional keyword "expected_trace" to run
the command with KRB5_TRACE enabled and look for an ordered series of
substrings in the trace output.
(cherry picked from commit 8bb5fce69a4aa6c3082fa7def66a93974e10e17a)
[rharwood@redhat.com: Removed .gitignore change]
---
src/config/post.in | 2 +-
src/util/k5test.py | 37 ++++++++++++++++++++++++++++++++++---
2 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/src/config/post.in b/src/config/post.in
index 7c7d86dc9..3643abad1 100644
--- a/src/config/post.in
+++ b/src/config/post.in
@@ -156,7 +156,7 @@ clean: clean-$(WHAT)
clean-unix::
$(RM) $(OBJS) $(DEPTARGETS_CLEAN) $(EXTRA_FILES)
- $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog
+ $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog testtrace
-$(RM) -r testdir
clean-windows::
diff --git a/src/util/k5test.py b/src/util/k5test.py
index c3d026377..4d30baf40 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -223,8 +223,11 @@ Scripts may use the following realm methods and attributes:
command-line debugging options. Fail if the command does not return
0. Log the command output appropriately, and return it as a single
multi-line string. Keyword arguments can contain input='string' to
- send an input string to the command, and expected_code=N to expect a
- return code other than 0.
+ send an input string to the command, expected_code=N to expect a
+ return code other than 0, expected_msg=MSG to expect a substring in
+ the command output, and expected_trace=('a', 'b', ...) to expect an
+ ordered series of line substrings in the command's KRB5_TRACE
+ output.
* realm.kprop_port(): Returns a port number based on realm.portbase
intended for use by kprop and kpropd.
@@ -647,10 +650,31 @@ def _stop_or_shell(stop, shell, env, ind):
subprocess.call(os.getenv('SHELL'), env=env)
-def _run_cmd(args, env, input=None, expected_code=0):
+# Read tracefile and look for the expected strings in successive lines.
+def _check_trace(tracefile, expected):
+ output('*** Trace output for previous command:\n')
+ i = 0
+ with open(tracefile, 'r') as f:
+ for line in f:
+ output(line)
+ if i < len(expected) and expected[i] in line:
+ i += 1
+ if i < len(expected):
+ fail('Expected string not found in trace output: ' + expected[i])
+
+
+def _run_cmd(args, env, input=None, expected_code=0, expected_msg=None,
+ expected_trace=None):
global null_input, _cmd_index, _last_cmd, _last_cmd_output, _debug
global _stop_before, _stop_after, _shell_before, _shell_after
+ if expected_trace is not None:
+ tracefile = 'testtrace'
+ if os.path.exists(tracefile):
+ os.remove(tracefile)
+ env = env.copy()
+ env['KRB5_TRACE'] = tracefile
+
if (_match_cmdnum(_debug, _cmd_index)):
return _debug_cmd(args, env, input)
@@ -679,6 +703,13 @@ def _run_cmd(args, env, input=None, expected_code=0):
# Check the return code and return the output.
if code != expected_code:
fail('%s failed with code %d.' % (args[0], code))
+
+ if expected_msg is not None and expected_msg not in outdata:
+ fail('Expected string not found in command output: ' + expected_msg)
+
+ if expected_trace is not None:
+ _check_trace(tracefile, expected_trace)
+
return outdata

View File

@ -1,419 +0,0 @@
From a3408731e3d73f99028f20c3f33caa5a411b430c Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Thu, 30 Mar 2017 11:27:09 -0400
Subject: [PATCH] Add support to query the SSF of a GSS context
Cyrus SASL provides a Security Strength Factor number to assess the
relative "strength" of the negotiated mechanism, and applications
sometimes make access control decisions based on it.
Add a call that allows us to query the mechanism that established the
GSS security context to ask what is the current SSF, based on the
enctype of the session key.
ticket: 8569 (new)
(cherry picked from commit 7feb7da54c0321b5a3eeb6c3797846a3cf7eda28)
[rharwood@redhat.com: hide GSS_KRB5_GET_CRED_IMPERSONATOR symbol]
---
src/include/k5-int.h | 1 +
src/lib/crypto/krb/crypto_int.h | 1 +
src/lib/crypto/krb/enctype_util.c | 16 ++++++++++++++++
src/lib/crypto/krb/etypes.c | 33 ++++++++++++++++++---------------
src/lib/crypto/libk5crypto.exports | 1 +
src/lib/gssapi/generic/gssapi_ext.h | 11 +++++++++++
src/lib/gssapi/generic/gssapi_generic.c | 9 +++++++++
src/lib/gssapi/krb5/gssapiP_krb5.h | 6 ++++++
src/lib/gssapi/krb5/gssapi_krb5.c | 4 ++++
src/lib/gssapi/krb5/inq_context.c | 27 +++++++++++++++++++++++++++
src/lib/gssapi/libgssapi_krb5.exports | 1 +
src/lib/gssapi32.def | 3 +++
src/lib/krb5_32.def | 3 +++
src/tests/gssapi/t_enctypes.c | 14 ++++++++++++++
14 files changed, 115 insertions(+), 15 deletions(-)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index cea644d0a..06ca2b66d 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -2114,6 +2114,7 @@ krb5_get_tgs_ktypes(krb5_context, krb5_const_principal, krb5_enctype **);
krb5_boolean krb5_is_permitted_enctype(krb5_context, krb5_enctype);
krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype);
+krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out);
krb5_error_code krb5_kdc_rep_decrypt_proc(krb5_context, const krb5_keyblock *,
krb5_const_pointer, krb5_kdc_rep *);
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index d75b49c69..e5099291e 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -111,6 +111,7 @@ struct krb5_keytypes {
prf_func prf;
krb5_cksumtype required_ctype;
krb5_flags flags;
+ unsigned int ssf;
};
#define ETYPE_WEAK 1
diff --git a/src/lib/crypto/krb/enctype_util.c b/src/lib/crypto/krb/enctype_util.c
index 0ed74bd6e..b1b40e7ec 100644
--- a/src/lib/crypto/krb/enctype_util.c
+++ b/src/lib/crypto/krb/enctype_util.c
@@ -131,3 +131,19 @@ krb5_enctype_to_name(krb5_enctype enctype, krb5_boolean shortest,
return ENOMEM;
return 0;
}
+
+/* The security of a mechanism cannot be summarized with a simple integer
+ * value, but we provide a per-enctype value for Cyrus SASL's SSF. */
+krb5_error_code
+k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out)
+{
+ const struct krb5_keytypes *ktp;
+
+ *ssf_out = 0;
+
+ ktp = find_enctype(enctype);
+ if (ktp == NULL)
+ return EINVAL;
+ *ssf_out = ktp->ssf;
+ return 0;
+}
diff --git a/src/lib/crypto/krb/etypes.c b/src/lib/crypto/krb/etypes.c
index 0e5e977d4..53d4a5c79 100644
--- a/src/lib/crypto/krb/etypes.c
+++ b/src/lib/crypto/krb/etypes.c
@@ -42,7 +42,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD5_DES,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
{ ENCTYPE_DES_CBC_MD4,
"des-cbc-md4", { 0 }, "DES cbc mode with RSA-MD4",
&krb5int_enc_des, &krb5int_hash_md4,
@@ -51,7 +51,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD4_DES,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
{ ENCTYPE_DES_CBC_MD5,
"des-cbc-md5", { "des" }, "DES cbc mode with RSA-MD5",
&krb5int_enc_des, &krb5int_hash_md5,
@@ -60,7 +60,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
CKSUMTYPE_RSA_MD5_DES,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
{ ENCTYPE_DES_CBC_RAW,
"des-cbc-raw", { 0 }, "DES cbc mode raw",
&krb5int_enc_des, NULL,
@@ -69,7 +69,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_des_string_to_key, k5_rand2key_des,
krb5int_des_prf,
0,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
{ ENCTYPE_DES3_CBC_RAW,
"des3-cbc-raw", { 0 }, "Triple DES cbc mode raw",
&krb5int_enc_des3, NULL,
@@ -78,7 +78,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des3,
NULL, /*PRF*/
0,
- ETYPE_WEAK },
+ ETYPE_WEAK, 112 },
{ ENCTYPE_DES3_CBC_SHA1,
"des3-cbc-sha1", { "des3-hmac-sha1", "des3-cbc-sha1-kd" },
@@ -89,7 +89,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des3,
krb5int_dk_prf,
CKSUMTYPE_HMAC_SHA1_DES3,
- 0 /*flags*/ },
+ 0 /*flags*/, 112 },
{ ENCTYPE_DES_HMAC_SHA1,
"des-hmac-sha1", { 0 }, "DES with HMAC/sha1",
@@ -99,7 +99,10 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_dk_string_to_key, k5_rand2key_des,
NULL, /*PRF*/
0,
- ETYPE_WEAK },
+ ETYPE_WEAK, 56 },
+
+ /* rc4-hmac uses a 128-bit key, but due to weaknesses in the RC4 cipher, we
+ * consider its strength degraded and assign it an SSF value of 64. */
{ ENCTYPE_ARCFOUR_HMAC,
"arcfour-hmac", { "rc4-hmac", "arcfour-hmac-md5" },
"ArcFour with HMAC/md5",
@@ -110,7 +113,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
k5_rand2key_direct, krb5int_arcfour_prf,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
- 0 /*flags*/ },
+ 0 /*flags*/, 64 },
{ ENCTYPE_ARCFOUR_HMAC_EXP,
"arcfour-hmac-exp", { "rc4-hmac-exp", "arcfour-hmac-md5-exp" },
"Exportable ArcFour with HMAC/md5",
@@ -121,7 +124,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_arcfour_decrypt, krb5int_arcfour_string_to_key,
k5_rand2key_direct, krb5int_arcfour_prf,
CKSUMTYPE_HMAC_MD5_ARCFOUR,
- ETYPE_WEAK
+ ETYPE_WEAK, 40
},
{ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
@@ -133,7 +136,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_aes_string_to_key, k5_rand2key_direct,
krb5int_dk_prf,
CKSUMTYPE_HMAC_SHA1_96_AES128,
- 0 /*flags*/ },
+ 0 /*flags*/, 128 },
{ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
"aes256-cts-hmac-sha1-96", { "aes256-cts", "aes256-sha1" },
"AES-256 CTS mode with 96-bit SHA-1 HMAC",
@@ -143,7 +146,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_aes_string_to_key, k5_rand2key_direct,
krb5int_dk_prf,
CKSUMTYPE_HMAC_SHA1_96_AES256,
- 0 /*flags*/ },
+ 0 /*flags*/, 256 },
{ ENCTYPE_CAMELLIA128_CTS_CMAC,
"camellia128-cts-cmac", { "camellia128-cts" },
@@ -155,7 +158,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_camellia_string_to_key, k5_rand2key_direct,
krb5int_dk_cmac_prf,
CKSUMTYPE_CMAC_CAMELLIA128,
- 0 /*flags*/ },
+ 0 /*flags*/, 128 },
{ ENCTYPE_CAMELLIA256_CTS_CMAC,
"camellia256-cts-cmac", { "camellia256-cts" },
"Camellia-256 CTS mode with CMAC",
@@ -166,7 +169,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_camellia_string_to_key, k5_rand2key_direct,
krb5int_dk_cmac_prf,
CKSUMTYPE_CMAC_CAMELLIA256,
- 0 /*flags */ },
+ 0 /*flags */, 256 },
{ ENCTYPE_AES128_CTS_HMAC_SHA256_128,
"aes128-cts-hmac-sha256-128", { "aes128-sha2" },
@@ -177,7 +180,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_aes2_string_to_key, k5_rand2key_direct,
krb5int_aes2_prf,
CKSUMTYPE_HMAC_SHA256_128_AES128,
- 0 /*flags*/ },
+ 0 /*flags*/, 128 },
{ ENCTYPE_AES256_CTS_HMAC_SHA384_192,
"aes256-cts-hmac-sha384-192", { "aes256-sha2" },
"AES-256 CTS mode with 192-bit SHA-384 HMAC",
@@ -187,7 +190,7 @@ const struct krb5_keytypes krb5int_enctypes_list[] = {
krb5int_aes2_string_to_key, k5_rand2key_direct,
krb5int_aes2_prf,
CKSUMTYPE_HMAC_SHA384_192_AES256,
- 0 /*flags*/ },
+ 0 /*flags*/, 256 },
};
const int krb5int_enctypes_length =
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index 447e45644..82eb5f30c 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -108,3 +108,4 @@ krb5int_nfold
k5_allow_weak_pbkdf2iter
krb5_c_prfplus
krb5_c_derive_prfplus
+k5_enctype_to_ssf
diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h
index 9ad44216d..9d3a7e736 100644
--- a/src/lib/gssapi/generic/gssapi_ext.h
+++ b/src/lib/gssapi/generic/gssapi_ext.h
@@ -575,4 +575,15 @@ gss_import_cred(
}
#endif
+/*
+ * When used with gss_inquire_sec_context_by_oid(), return a buffer set with
+ * the first member containing an unsigned 32-bit integer in network byte
+ * order. This is the Security Strength Factor (SSF) associated with the
+ * secure channel established by the security context. NOTE: This value is
+ * made available solely as an indication for use by APIs like Cyrus SASL that
+ * classify the strength of a secure channel via this number. The strength of
+ * a channel cannot necessarily be represented by a simple number.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_SEC_CONTEXT_SASL_SSF;
+
#endif /* GSSAPI_EXT_H_ */
diff --git a/src/lib/gssapi/generic/gssapi_generic.c b/src/lib/gssapi/generic/gssapi_generic.c
index 5496aa335..fa144c2bf 100644
--- a/src/lib/gssapi/generic/gssapi_generic.c
+++ b/src/lib/gssapi/generic/gssapi_generic.c
@@ -157,6 +157,13 @@ static const gss_OID_desc const_oids[] = {
{7, (void *)"\x2b\x06\x01\x05\x05\x0d\x19"},
{7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1a"},
{7, (void *)"\x2b\x06\x01\x05\x05\x0d\x1b"},
+
+ /*
+ * GSS_SEC_CONTEXT_SASL_SSF_OID 1.2.840.113554.1.2.2.5.15
+ * iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) krb5(2) krb5-gssapi-ext(5) sasl-ssf(15)
+ */
+ {11, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f"},
};
/* Here are the constants which point to the static structure above.
@@ -218,6 +225,8 @@ GSS_DLLIMP gss_const_OID GSS_C_MA_PFS = oids+33;
GSS_DLLIMP gss_const_OID GSS_C_MA_COMPRESS = oids+34;
GSS_DLLIMP gss_const_OID GSS_C_MA_CTX_TRANS = oids+35;
+GSS_DLLIMP gss_OID GSS_C_SEC_CONTEXT_SASL_SSF = oids+36;
+
static gss_OID_set_desc gss_ma_known_attrs_desc = { 27, oids+9 };
gss_OID_set gss_ma_known_attrs = &gss_ma_known_attrs_desc;
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index d7bdef7e2..ef030707e 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1144,6 +1144,12 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *,
const gss_OID,
gss_buffer_set_t *);
+#define GET_SEC_CONTEXT_SASL_SSF_OID_LENGTH 11
+#define GET_SEC_CONTEXT_SASL_SSF_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0f"
+OM_uint32
+gss_krb5int_sec_context_sasl_ssf(OM_uint32 *, const gss_ctx_id_t,
+ const gss_OID, gss_buffer_set_t *);
+
#define GSS_KRB5_IMPORT_CRED_OID_LENGTH 11
#define GSS_KRB5_IMPORT_CRED_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0d"
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
index 99092ccab..de4131980 100644
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
@@ -352,6 +352,10 @@ static struct {
{
{GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID},
gss_krb5int_extract_authtime_from_sec_context
+ },
+ {
+ {GET_SEC_CONTEXT_SASL_SSF_OID_LENGTH, GET_SEC_CONTEXT_SASL_SSF_OID},
+ gss_krb5int_sec_context_sasl_ssf
}
};
diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
index 9024b3c7e..d2e466e60 100644
--- a/src/lib/gssapi/krb5/inq_context.c
+++ b/src/lib/gssapi/krb5/inq_context.c
@@ -310,3 +310,30 @@ gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status,
return generic_gss_add_buffer_set_member(minor_status, &rep, data_set);
}
+
+OM_uint32
+gss_krb5int_sec_context_sasl_ssf(OM_uint32 *minor_status,
+ const gss_ctx_id_t context_handle,
+ const gss_OID desired_object,
+ gss_buffer_set_t *data_set)
+{
+ krb5_gss_ctx_id_rec *ctx;
+ krb5_key key;
+ krb5_error_code code;
+ gss_buffer_desc ssfbuf;
+ unsigned int ssf;
+ uint8_t buf[4];
+
+ ctx = (krb5_gss_ctx_id_rec *)context_handle;
+ key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey;
+
+ code = k5_enctype_to_ssf(key->keyblock.enctype, &ssf);
+ if (code)
+ return GSS_S_FAILURE;
+
+ store_32_be(ssf, buf);
+ ssfbuf.value = buf;
+ ssfbuf.length = sizeof(buf);
+
+ return generic_gss_add_buffer_set_member(minor_status, &ssfbuf, data_set);
+}
diff --git a/src/lib/gssapi/libgssapi_krb5.exports b/src/lib/gssapi/libgssapi_krb5.exports
index 9facb3f42..936540e41 100644
--- a/src/lib/gssapi/libgssapi_krb5.exports
+++ b/src/lib/gssapi/libgssapi_krb5.exports
@@ -37,6 +37,7 @@ GSS_C_MA_CBINDINGS
GSS_C_MA_PFS
GSS_C_MA_COMPRESS
GSS_C_MA_CTX_TRANS
+GSS_C_SEC_CONTEXT_SASL_SSF
gss_accept_sec_context
gss_acquire_cred
gss_acquire_cred_with_password
diff --git a/src/lib/gssapi32.def b/src/lib/gssapi32.def
index 362b9bce8..dff057754 100644
--- a/src/lib/gssapi32.def
+++ b/src/lib/gssapi32.def
@@ -182,3 +182,6 @@ EXPORTS
gss_verify_mic_iov @146
; Added in 1.14
GSS_KRB5_CRED_NO_CI_FLAGS_X @147 DATA
+; Added in 1.16
+; GSS_KRB5_GET_CRED_IMPERSONATOR @148 DATA
+ GSS_C_SEC_CONTEXT_SASL_SSF @149 DATA
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
index e5b560dfc..f7b428e16 100644
--- a/src/lib/krb5_32.def
+++ b/src/lib/krb5_32.def
@@ -470,3 +470,6 @@ EXPORTS
krb5_get_init_creds_opt_set_pac_request @435
krb5int_trace @436 ; PRIVATE GSSAPI
krb5_expand_hostname @437
+
+; new in 1.16
+ k5_enctype_to_ssf @438 ; PRIVATE GSSAPI
diff --git a/src/tests/gssapi/t_enctypes.c b/src/tests/gssapi/t_enctypes.c
index a2ad18f47..3fd31e2f8 100644
--- a/src/tests/gssapi/t_enctypes.c
+++ b/src/tests/gssapi/t_enctypes.c
@@ -32,6 +32,7 @@
#include "k5-int.h"
#include "common.h"
+#include "gssapi_ext.h"
/*
* This test program establishes contexts with the krb5 mech, the default
@@ -86,6 +87,9 @@ main(int argc, char *argv[])
gss_krb5_lucid_context_v1_t *ilucid, *alucid;
gss_krb5_rfc1964_keydata_t *i1964, *a1964;
gss_krb5_cfx_keydata_t *icfx, *acfx;
+ gss_buffer_set_t bufset = GSS_C_NO_BUFFER_SET;
+ gss_OID ssf_oid = GSS_C_SEC_CONTEXT_SASL_SSF;
+ unsigned int ssf;
size_t count;
void *lptr;
int c;
@@ -139,6 +143,16 @@ main(int argc, char *argv[])
establish_contexts(&mech_krb5, icred, acred, tname, flags, &ictx, &actx,
NULL, NULL, NULL);
+ /* Query the SSF value and range-check the result. */
+ major = gss_inquire_sec_context_by_oid(&minor, ictx, ssf_oid, &bufset);
+ check_gsserr("gss_inquire_sec_context_by_oid(ssf)", major, minor);
+ if (bufset->elements[0].length != 4)
+ errout("SSF buffer has unexpected length");
+ ssf = load_32_be(bufset->elements[0].value);
+ if (ssf < 56 || ssf > 256)
+ errout("SSF value not within acceptable range (56-256)");
+ (void)gss_release_buffer_set(&minor, &bufset);
+
/* Export to lucid contexts. */
major = gss_krb5_export_lucid_sec_context(&minor, &ictx, 1, &lptr);
check_gsserr("gss_export_lucid_sec_context(initiator)", major, minor);

View File

@ -1,45 +0,0 @@
From 5faadd66bb278bcc1c618e199444e3012eeec215 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 11 Jan 2017 10:49:30 -0500
Subject: [PATCH] Add test case for PKINIT DH renegotiation
In t_pkinit.py, add a PKINIT test case where the KDC sends
KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED and the client retries with the
KDC's TD_DH_PARAMETERS value, using the clpreauth tryagain method.
Use the trace log to verify that the renegotiation actually takes
place.
(cherry picked from commit 7ad7eb7fd591e6c789ea24b94eccbf74ee4d79f8)
---
src/tests/t_pkinit.py | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index ac4d326b6..183977750 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -174,6 +174,24 @@ realm.kinit(realm.user_princ,
'-X', 'flag_RSA_PROTOCOL=yes'])
realm.klist(realm.user_princ)
+# Test a DH parameter renegotiation by temporarily setting a 4096-bit
+# minimum on the KDC.
+tracefile = os.path.join(realm.testdir, 'trace')
+minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}}
+minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf)
+realm.stop_kdc()
+realm.start_kdc(env=minbits_env)
+realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-X',
+ 'X509_user_identity=' + file_identity, realm.user_princ])
+with open(tracefile, 'r') as f:
+ trace = f.read()
+if ('Key parameters not accepted' not in trace or
+ 'Preauth tryagain input types' not in trace or
+ 'trying again with KDC-provided parameters' not in trace):
+ fail('DH renegotiation steps not found in kinit trace log')
+realm.stop_kdc()
+realm.start_kdc()
+
# Run the basic test - PKINIT with FILE: identity, with a password on the key,
# supplied by the prompter.
# Expect failure if the responder does nothing, and we have no prompter.

View File

@ -1,968 +0,0 @@
From 5e3885e9d7c7cd2a19a291cdb1e54312ca7f7e1f Mon Sep 17 00:00:00 2001
From: Matt Rogers <mrogers@redhat.com>
Date: Mon, 5 Dec 2016 12:22:45 -0500
Subject: [PATCH] Add test cert generation to make-certs.sh
Add additional test certificates for UPN matching. Run make-certs.sh
to regenerate certs.
ticket: 8528
(cherry picked from commit 5a1d0388ba2e4ec510ed715ce5fbc7f748941425)
---
src/tests/dejagnu/pkinit-certs/ca.pem | 54 ++++++++++++------------
src/tests/dejagnu/pkinit-certs/kdc.pem | 50 ++++++++++++----------
src/tests/dejagnu/pkinit-certs/make-certs.sh | 53 ++++++++++++++++++++++-
src/tests/dejagnu/pkinit-certs/privkey-enc.pem | 52 +++++++++++------------
src/tests/dejagnu/pkinit-certs/privkey.pem | 50 +++++++++++-----------
src/tests/dejagnu/pkinit-certs/user-enc.p12 | Bin 3029 -> 2837 bytes
src/tests/dejagnu/pkinit-certs/user-upn.p12 | Bin 0 -> 2829 bytes
src/tests/dejagnu/pkinit-certs/user-upn.pem | 28 +++++++++++++
src/tests/dejagnu/pkinit-certs/user-upn2.p12 | Bin 0 -> 2813 bytes
src/tests/dejagnu/pkinit-certs/user-upn2.pem | 28 +++++++++++++
src/tests/dejagnu/pkinit-certs/user-upn3.csr | 16 +++++++
src/tests/dejagnu/pkinit-certs/user-upn3.p12 | Bin 0 -> 2829 bytes
src/tests/dejagnu/pkinit-certs/user-upn3.pem | 28 +++++++++++++
src/tests/dejagnu/pkinit-certs/user.p12 | Bin 3104 -> 2837 bytes
src/tests/dejagnu/pkinit-certs/user.pem | 56 ++++++++++++-------------
15 files changed, 283 insertions(+), 132 deletions(-)
create mode 100644 src/tests/dejagnu/pkinit-certs/user-upn.p12
create mode 100644 src/tests/dejagnu/pkinit-certs/user-upn.pem
create mode 100644 src/tests/dejagnu/pkinit-certs/user-upn2.p12
create mode 100644 src/tests/dejagnu/pkinit-certs/user-upn2.pem
create mode 100644 src/tests/dejagnu/pkinit-certs/user-upn3.csr
create mode 100644 src/tests/dejagnu/pkinit-certs/user-upn3.p12
create mode 100644 src/tests/dejagnu/pkinit-certs/user-upn3.pem
diff --git a/src/tests/dejagnu/pkinit-certs/ca.pem b/src/tests/dejagnu/pkinit-certs/ca.pem
index 55fe02c92..44c917687 100644
--- a/src/tests/dejagnu/pkinit-certs/ca.pem
+++ b/src/tests/dejagnu/pkinit-certs/ca.pem
@@ -1,29 +1,29 @@
-----BEGIN CERTIFICATE-----
-MIIE5TCCA82gAwIBAgIJANsFDWp1HgAaMA0GCSqGSIb3DQEBBQUAMIGnMQswCQYD
-VQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAGA1UEBxMJQ2FtYnJp
-ZGdlMQwwCgYDVQQKEwNNSVQxKTAnBgNVBAsTIEluc2VjdXJlIFBraW5pdCBLZXJi
-ZXJvcyB0ZXN0IENBMTMwMQYDVQQDFCpwa2luaXQgdGVzdCBzdWl0ZSBDQTsgZG8g
-bm90IHVzZSBvdGhlcndpc2UwHhcNMTAwMTA2MTQ1MTI3WhcNMjMwOTE1MTQ1MTI3
-WjCBpzELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNV
-BAcTCUNhbWJyaWRnZTEMMAoGA1UEChMDTUlUMSkwJwYDVQQLEyBJbnNlY3VyZSBQ
-a2luaXQgS2VyYmVyb3MgdGVzdCBDQTEzMDEGA1UEAxQqcGtpbml0IHRlc3Qgc3Vp
-dGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlMIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEAnYLMe58ny00MgskJP7tZ3PIQRpQkXGLJZKI0HfntCRbIuvmn
-ZejPSKdNMyejzRIyjdw1FDJUAnpXYcic3TD5817G5H63UrllAGuy+lhQWNzE6c6K
-ueerevR3pMaqHXonaflVasUu5e2AAWVnFbz4x04uLlQejqPwm5sR1xTeLUnVfSY7
-5NbXGIE488iDV0wW8nqGoVWn/TsRd+7KuQUIkJpt8+V6Jk6hPIcPqe6h7mXNGsgc
-5dBSqBwVcjU9DbeT4xxxEmgQdLt7qdNwV1ZPLQnTQpogNrT5uf3oSbOTsyM02GOW
-riIRmsqq81sfMrpviTRRDwoqTUEhoCSor0UmcwIDAQABo4IBEDCCAQwwHQYDVR0O
-BBYEFFn82RUKgTvkFn0cgwyCQpNeWCxYMIHcBgNVHSMEgdQwgdGAFFn82RUKgTvk
-Fn0cgwyCQpNeWCxYoYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFz
-c2FjaHVzZXR0czESMBAGA1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxKTAn
-BgNVBAsTIEluc2VjdXJlIFBraW5pdCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQD
-FCpwa2luaXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCCQDb
-BQ1qdR4AGjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBVL2Q6Xubs
-gm881cAy6esku17/BSTZur7hCLHTGof1ZKNcCXALjmwNYNC3tl6owqpX8CSdBdsD
-Bw/Vs9p3mqnaVEoZc8uW8zS6LoAQbcqiYdQHdEXMh3ec8uvAfmdlQsIsm5Ux8q8L
-NM6bKnUOqOFOHme+RC4FGOLb8JqnnuQdwyIZaUyQP6hXbw4zyDphfgo1ZlZn20xh
-I555kPfAZKEi/d3WY0oN4k+sfCs9tWRNjmqZfKkH1OqRpjCFGG0b0vY77MFRMuPz
-YtN2iD3plgla7KkUMljp9th/Z8Ok79uA1TNLYKzoBjlAX0vToxfa8rrSNo1dHFKT
-e5Tj7+29DE4I
+MIIE5TCCA82gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx
+FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG
+A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz
+dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug
+b3RoZXJ3aXNlMB4XDTE2MTIxMjE0NDYzOVoXDTI3MTEyNTE0NDYzOVowgacxCzAJ
+BgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNldHRzMRIwEAYDVQQHDAlDYW1i
+cmlkZ2UxDDAKBgNVBAoMA01JVDEpMCcGA1UECwwgSW5zZWN1cmUgUEtJTklUIEtl
+cmJlcm9zIHRlc3QgQ0ExMzAxBgNVBAMMKnBraW5pdCB0ZXN0IHN1aXRlIENBOyBk
+byBub3QgdXNlIG90aGVyd2lzZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBANOWvXDyubZ/Kf8QYdPSRk/rsogzqS0rycNEJp/6rPpTS40UxGae5MyLHfmN
+l2mSevRoHSqhb7cfT6n9kR2kb3HB0qhhhecHey4sGwd+m7WMhBQgVtYaiWkuEQDC
+7/SWkRYzmYX8J41vrQulXU2/2pOQCmG4NKPsNo+vcKoT2SHl6qr3lflUaIG0wDu4
+bFrWszkxcuSkU7SSXDf2xTTTJ8QftO6WQY3g0+dAhbjZFKxRO5uipxURez5EemVs
+Re86vXEILka85tiVS4maCn3l3FWMqcBHRFNa+/osTb0J/OmvvdQ3bzvscG7KDRtM
+bRUnpWClr5R+AbGVvKocj5I1+G0CAwEAAaOCARgwggEUMB0GA1UdDgQWBBRrwMkO
+fMoN3ofjotSWjK0c27fYYjCB1AYDVR0jBIHMMIHJgBRrwMkOfMoN3ofjotSWjK0c
+27fYYqGBraSBqjCBpzELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0
+dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoGA1UECgwDTUlUMSkwJwYDVQQLDCBJ
+bnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVzdCBDQTEzMDEGA1UEAwwqcGtpbml0
+IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQE
+AwIB/jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAN82zurZwM
+TugUG6b1symxXxOdDqwinwIlQjzXJ8mTRv31q+YwNdYvdWn1aex8v44qjFDjEP80
+83y18CjjBHznwxsHll80QmFHjpy6xtRrUC/Ak7jfKnDiTKQYBdgmF4/UiVQu354e
+QI6jPMQlrWZXThlRuBjM55hs4tgRYeTgbd4VSZzVQXdm2ViZkg8SGqw0R2ZRnG91
+dfXkhu/tTruguPAT3MQ2pTK/CoHHA4W2piQbBDqIl83fphRhYxyW/cCF2mvZZUhE
+AfWhgYDeTDxHKG3Jfmm+ujMo5HscgeUpJ7XjZdobNhkQjD1piyuGzFkUfo2XzA6m
+kMz4Jq4cnvpz
-----END CERTIFICATE-----
diff --git a/src/tests/dejagnu/pkinit-certs/kdc.pem b/src/tests/dejagnu/pkinit-certs/kdc.pem
index 5575ab579..8820ad447 100644
--- a/src/tests/dejagnu/pkinit-certs/kdc.pem
+++ b/src/tests/dejagnu/pkinit-certs/kdc.pem
@@ -1,25 +1,29 @@
-----BEGIN CERTIFICATE-----
-MIIEMjCCAxqgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBpzELMAkGA1UEBhMCVVMx
-FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG
-A1UEChMDTUlUMSkwJwYDVQQLEyBJbnNlY3VyZSBQa2luaXQgS2VyYmVyb3MgdGVz
-dCBDQTEzMDEGA1UEAxQqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug
-b3RoZXJ3aXNlMB4XDTEwMDEwNjE0NTgwOFoXDTIzMDkxNTE0NTgwOFowSjELMAkG
-A1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxFTATBgNVBAoTDEtSQlRF
-U1QuQ09NIDEMMAoGA1UECxMDS0RDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
-CgKCAQEAnYLMe58ny00MgskJP7tZ3PIQRpQkXGLJZKI0HfntCRbIuvmnZejPSKdN
-MyejzRIyjdw1FDJUAnpXYcic3TD5817G5H63UrllAGuy+lhQWNzE6c6KueerevR3
-pMaqHXonaflVasUu5e2AAWVnFbz4x04uLlQejqPwm5sR1xTeLUnVfSY75NbXGIE4
-88iDV0wW8nqGoVWn/TsRd+7KuQUIkJpt8+V6Jk6hPIcPqe6h7mXNGsgc5dBSqBwV
-cjU9DbeT4xxxEmgQdLt7qdNwV1ZPLQnTQpogNrT5uf3oSbOTsyM02GOWriIRmsqq
-81sfMrpviTRRDwoqTUEhoCSor0UmcwIDAQABo4HEMIHBMAkGA1UdEwQCMAAwCwYD
-VR0PBAQDAgPoMBIGA1UdJQQLMAkGBysGAQUCAwUwHQYDVR0OBBYEFFn82RUKgTvk
-Fn0cgwyCQpNeWCxYMB8GA1UdIwQYMBaAFFn82RUKgTvkFn0cgwyCQpNeWCxYMAkG
-A1UdEgQCMAAwSAYDVR0RBEEwP6A9BgYrBgEFAgKgMzAxoA0bC0tSQlRFU1QuQ09N
-oSAwHqADAgEBoRcwFRsGa3JidGd0GwtLUkJURVNULkNPTTANBgkqhkiG9w0BAQUF
-AAOCAQEAP0byILHLWPyGlv/1HN34DfIpLdVkgGar2yceMtZ2v/7UjeA5PlZc8DFM
-20bTq/vIN0eWDTPLI57e+MzQTMxs2UHsic4su0m5DG0cvQTsBXRK51CW/qUF+4n0
-qSEORULiDF6LNoo8akoLukNBhzBh+aqYt4aB46hhsmDmNZTDP1CXsNGHQI9/L52l
-oqpUGx8tBpKIFos95PSajXrQn2u66rSMMi4aawitM2igurHPDMbC+XvEYMtXpOS5
-3PEzXEYiSV3TWLTzIE9ytswHeZyHCbp7XHx0LVZFxzqtIe4qmwJJOGhlbH21Izr4
-feF5h5e2ZrOVREY4cKkJmJhEwsqBVA==
+MIIE4TCCA8mgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx
+FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG
+A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz
+dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug
+b3RoZXJ3aXNlMB4XDTE2MTIxMjE0NDYzOVoXDTI3MTEyNTE0NDYzOVowSTELMAkG
+A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF
+U1QuQ09NMQwwCgYDVQQDDANLREMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQDTlr1w8rm2fyn/EGHT0kZP67KIM6ktK8nDRCaf+qz6U0uNFMRmnuTMix35
+jZdpknr0aB0qoW+3H0+p/ZEdpG9xwdKoYYXnB3suLBsHfpu1jIQUIFbWGolpLhEA
+wu/0lpEWM5mF/CeNb60LpV1Nv9qTkAphuDSj7DaPr3CqE9kh5eqq95X5VGiBtMA7
+uGxa1rM5MXLkpFO0klw39sU00yfEH7TulkGN4NPnQIW42RSsUTuboqcVEXs+RHpl
+bEXvOr1xCC5GvObYlUuJmgp95dxVjKnAR0RTWvv6LE29Cfzpr73UN2877HBuyg0b
+TG0VJ6Vgpa+UfgGxlbyqHI+SNfhtAgMBAAGjggFzMIIBbzAdBgNVHQ4EFgQUa8DJ
+DnzKDd6H46LUloytHNu32GIwgdQGA1UdIwSBzDCByYAUa8DJDnzKDd6H46LUloyt
+HNu32GKhga2kgaowgacxCzAJBgNVBAYTAlVTMRYwFAYDVQQIDA1NYXNzYWNodXNl
+dHRzMRIwEAYDVQQHDAlDYW1icmlkZ2UxDDAKBgNVBAoMA01JVDEpMCcGA1UECwwg
+SW5zZWN1cmUgUEtJTklUIEtlcmJlcm9zIHRlc3QgQ0ExMzAxBgNVBAMMKnBraW5p
+dCB0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZYIBATALBgNVHQ8E
+BAMCA+gwDAYDVR0TAQH/BAIwADBIBgNVHREEQTA/oD0GBisGAQUCAqAzMDGgDRsL
+S1JCVEVTVC5DT02hIDAeoAMCAQGhFzAVGwZrcmJ0Z3QbC0tSQlRFU1QuQ09NMBIG
+A1UdJQQLMAkGBysGAQUCAwUwDQYJKoZIhvcNAQELBQADggEBABJpKRfoFxyOUp9i
+Z/fWql5anJuZElgBSbEC5sL2mMcmL/1vqkiYF3uF6/Z9g4X1LX4QDuvaXCJSdQ+b
+JpmhklSyFN+E/agxZtSim+AjTgYJ0y+jwNvX6kZQ8fW3VLNJZ+zbb4n4txfgSROn
+7ub+02mo4DYajyD9TE/qLzmVaiKLEKW0osjxX3fB1RN/d7zm//NDPsezzUzmKkgz
+u0ML7HGYUNY3+/SC4ShF/But1IoY3/I46lB6BMrIn9X6fsVKlipqrRFniUk0qDlJ
+fbKVB+MvGEFoqFNlMoGiufmDjnJl4PQZCVEmXO8wAVGeK8NpTBCjltAAsoVJVnjq
+AC5jSAM=
-----END CERTIFICATE-----
diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh
index b82ef6f83..0f07709b0 100755
--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh
+++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh
@@ -4,7 +4,9 @@ NAMETYPE=1
KEYSIZE=2048
DAYS=4000
REALM=KRBTEST.COM
+LOWREALM=krbtest.com
KRB5_PRINCIPAL_SAN=1.3.6.1.5.2.2
+KRB5_UPN_SAN=1.3.6.1.4.1.311.20.2.3
PKINIT_KDC_EKU=1.3.6.1.5.2.3.5
PKINIT_CLIENT_EKU=1.3.6.1.5.2.3.4
TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1
@@ -85,6 +87,30 @@ keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
basicConstraints = critical,CA:FALSE
subjectAltName = otherName:$KRB5_PRINCIPAL_SAN;SEQUENCE:krb5princ_client
extendedKeyUsage = $CLIENT_EKU_LIST
+
+[exts_upn_client]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
+basicConstraints = critical,CA:FALSE
+subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$LOWREALM
+extendedKeyUsage = $CLIENT_EKU_LIST
+
+[exts_upn2_client]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
+basicConstraints = critical,CA:FALSE
+subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user
+extendedKeyUsage = $CLIENT_EKU_LIST
+
+[exts_upn3_client]
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid:always,issuer:always
+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement
+basicConstraints = critical,CA:FALSE
+subjectAltName = otherName:$KRB5_UPN_SAN;UTF8:user@$REALM
+extendedKeyUsage = $CLIENT_EKU_LIST
EOF
# Generate a private key.
@@ -113,5 +139,30 @@ openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user.p12 \
openssl pkcs12 -export -in user.pem -inkey privkey.pem -out user-enc.p12 \
-passout pass:encrypted
+# Generate a client certificate and PKCS#12 bundles with a UPN SAN.
+SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \
+ -key privkey.pem -out user-upn.csr
+SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn_client \
+ -set_serial 4 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \
+ -out user-upn.pem -in user-upn.csr
+openssl pkcs12 -export -in user-upn.pem -inkey privkey.pem -out user-upn.p12 \
+ -passout pass:
+
+SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \
+ -key privkey.pem -out user-upn2.csr
+SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn2_client \
+ -set_serial 5 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \
+ -out user-upn2.pem -in user-upn2.csr
+openssl pkcs12 -export -in user-upn2.pem -inkey privkey.pem \
+ -out user-upn2.p12 -passout pass:
+
+SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \
+ -key privkey.pem -out user-upn3.csr
+SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \
+ -set_serial 6 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \
+ -out user-upn3.pem -in user-upn3.csr
+openssl pkcs12 -export -in user-upn3.pem -inkey privkey.pem \
+ -out user-upn3.p12 -passout pass:
+
# Clean up.
-rm -f openssl.cnf kdc.csr user.csr
+rm -f openssl.cnf kdc.csr user.csr user-upn.csr user-upn2.csr user-upn3.csr
diff --git a/src/tests/dejagnu/pkinit-certs/privkey-enc.pem b/src/tests/dejagnu/pkinit-certs/privkey-enc.pem
index 9f7816f17..837fd0b01 100644
--- a/src/tests/dejagnu/pkinit-certs/privkey-enc.pem
+++ b/src/tests/dejagnu/pkinit-certs/privkey-enc.pem
@@ -1,30 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,91CA660D6286E453
+DEK-Info: DES-EDE3-CBC,19FEC334A4D4391D
-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
+S6pSicLj30Jlnu2OnYM0eXCvwAHR3xMhhl2N0gheWUGkjicqTdW6ft1qCmGBre9b
+/aTSF1ajvFC+YQ/iABznWNmRNZKCzTK1dQ6P73p83uNqWt/cfe+pVYdeHw3u8NKA
+fscciBtxnHNaAs16GX5/j1XXRPb+zmUe18A+VFMRgctbaurk+KbxO8qVUkzt9NNa
+v5zHkXnaJf6ixL6zR3cOCJWPGy4GmGeFIytQos5Jgn23Pjn8BHAXf39GMs2n6g5V
+eE5RAGDeXqPv/tO1kN0/RSKDeIPvKW6REklXraRUle0PNN5g5l3umSkg4fkplusp
+nTsQCRWkqyVcMpxcf0wy7F2ZPOYIWDt1/pzAHC7y/fl0uCQPz0Qd1smwt0ABKcZv
+m9zaMq6lkKYnBOxPiYIlWVlQi3RLDiQyAWQz/nF0SKsE88SUlB83quySJsZsLKzk
+MR/C+ccSiHqMiDKVj5Ts1go+gbj8Vhlto8jH6ynQj6lrOIczyMmgUa0v0dFH3i3/
+WL/8ydJ0otY67A8w5yH3hMzRChXQZlpTmH2dDhAv6EzKBi8eIiB0Em+laz5lDv6C
+SfNxZa1/+bSAvXr7LwllUu+Gzbu7MNLwfB2ieTqdFQGA659DjnMqyBGLFzni4Ir0
+Hi6Uh6yQubTm07oqyUHAsChGFE4Efh4O0rCbKKPZuSVfimUZcE6JM9IjRC/0DIwr
+LZSYqsFgn44byrc62qV2JAE2ua+/4aHHI28hIZ3MDLwyYpCQL/FAUZtqZvni+zgw
+yoHLRDbdrqPps6P71T6Pw6OQzAYC7AL/FsZnLJK78nI+Yai0dpyv/QWiFSXoDEVN
+6vQoDv/VZbNIctr31OE4XyjIMiTpn3FPa3VSbKM4/h7SthjwEV2ONNfR8XQF+siz
+3NhOjEFrZ6UGHvT06wo/hp4CM7u580fNu5HvyCyIwkx9CZRLHvG6Vu0emlzDfQhE
+qxQs6L7IM8A46/LPSTtmEA8Rrn51YY9NChMdY6j3rLe4NLxxOCE6JYaGWVWBBawK
+k3y9z6L9gWRwxEfCgWIutDrYtmA2aj6y/vRS6LrotCNeN5qBx+TdRnh6uCqbi1T8
+4rF20TVhNZ/l+pkH/ehY9OJ/zpwdbTq4FlE0wWQZB/vwbYP5CZKF+rU6IXnCZEjt
+Ak6Bka9mFm9Z/TvnKIRYiXELq32zOJAuEOQ576tkDX2rAuIQAfE9biX2qo0gbsJo
+1RIfXekRurD/HX54blv5mNqUV34gl+ngPpV5nNDy7RuTAdP77Mu7/ynaPfnM7nqu
+rECbZVv1HZSgTi+7G9SUjn4Bg36p4NiF0/dZ2W70byYIQvNPNqU1kyeSrZk/43te
+NwFgpoAKVbMD1rZ+0xM2YCFFKQZZMN1a5tn8/1TWPlPU28Tu3ZliGeWMdeKd4/MP
+vfH1pE58qVcyOngjLqGkk0L5A7WOAgu+vibKrxGxywwVLx/GfDFqnNr6H0buwXrk
+vuKBTo0r3pcbaZt3kaYBm0d3zznQI1O/pX+eGiNr/rI86j4KC+jUSoKi4BdUeuDN
+p1x6qyEK37kgVXiUyiEXO7e1arLBZMfFRTNKVsN5ewL441eCIgs5gA==
-----END RSA PRIVATE KEY-----
diff --git a/src/tests/dejagnu/pkinit-certs/privkey.pem b/src/tests/dejagnu/pkinit-certs/privkey.pem
index 1825dec4e..7e9beb09a 100644
--- a/src/tests/dejagnu/pkinit-certs/privkey.pem
+++ b/src/tests/dejagnu/pkinit-certs/privkey.pem
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
-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
+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
-----END RSA PRIVATE KEY-----
diff --git a/src/tests/dejagnu/pkinit-certs/user-enc.p12 b/src/tests/dejagnu/pkinit-certs/user-enc.p12
index 107480c6d2564a2e60655f29a9984f3009c35a11..049602939def4be1fa9164649b39a801f417e74e 100644
GIT binary patch
delta 2772
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
ahH{=a^W;wfxC97gAc%ero&l@^0tf)CvO~uJ
delta 2966
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
M3X5P3IRXL*0PAOtl>h($
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn.p12 b/src/tests/dejagnu/pkinit-certs/user-upn.p12
new file mode 100644
index 0000000000000000000000000000000000000000..7a184f651e50d1443e5fe907b5a11455d69bc0d1
GIT binary patch
literal 2829
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
literal 0
HcmV?d00001
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn.pem b/src/tests/dejagnu/pkinit-certs/user-upn.pem
new file mode 100644
index 000000000..6ce095692
--- /dev/null
+++ b/src/tests/dejagnu/pkinit-certs/user-upn.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIExTCCA62gAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx
+FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG
+A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz
+dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug
+b3RoZXJ3aXNlMB4XDTE2MTIxMjE0NDYzOVoXDTI3MTEyNTE0NDYzOVowSjELMAkG
+A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF
+U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA05a9cPK5tn8p/xBh09JGT+uyiDOpLSvJw0Qmn/qs+lNLjRTEZp7kzIsd
++Y2XaZJ69GgdKqFvtx9Pqf2RHaRvccHSqGGF5wd7LiwbB36btYyEFCBW1hqJaS4R
+AMLv9JaRFjOZhfwnjW+tC6VdTb/ak5AKYbg0o+w2j69wqhPZIeXqqveV+VRogbTA
+O7hsWtazOTFy5KRTtJJcN/bFNNMnxB+07pZBjeDT50CFuNkUrFE7m6KnFRF7PkR6
+ZWxF7zq9cQguRrzm2JVLiZoKfeXcVYypwEdEU1r7+ixNvQn86a+91DdvO+xwbsoN
+G0xtFSelYKWvlH4BsZW8qhyPkjX4bQIDAQABo4IBVjCCAVIwHQYDVR0OBBYEFGvA
+yQ58yg3eh+Oi1JaMrRzbt9hiMIHUBgNVHSMEgcwwgcmAFGvAyQ58yg3eh+Oi1JaM
+rRzbt9hioYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz
+ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM
+IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu
+aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P
+BAQDAgPoMAwGA1UdEwEB/wQCMAAwKwYDVR0RBCQwIqAgBgorBgEEAYI3FAIDoBIM
+EHVzZXJAa3JidGVzdC5jb20wEgYDVR0lBAswCQYHKwYBBQIDBDANBgkqhkiG9w0B
+AQsFAAOCAQEADpj2VeHFvGVzb2o+qUL00+1RfpNsGRxrkXpolkjGn8LNIHoMfxAR
+utnL41Jd1wQQ0FpbgR1fIXgCDfdMNWWIE0SPO6WVHVUVaDb2kjgYZ2bvR3FvTIaQ
+thj3jyG5Qn/hJZ2WZdJ1kavUQzCcGKxcIQHObcX0x2wXWPKlO1S8XDS8olsi9KPj
+y1nWUvLgxhtp4vwRuVwKtgFusgaTJOOaJ+yKS8SHr1v89GRPmff/tQzMgf/nqRNP
+lmQ5uHLeo35DvS5akdw0Izi0m5zwMvOAGBY8lyHgpx8jshourr078Swy/SNdaMGd
+fwDCc7tFD2dw3jRC1O5jWBxOuDTmUL0cVw==
+-----END CERTIFICATE-----
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn2.p12 b/src/tests/dejagnu/pkinit-certs/user-upn2.p12
new file mode 100644
index 0000000000000000000000000000000000000000..6691b8c72aa60d647c4993d3972a7bc39865901f
GIT binary patch
literal 2813
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
NjEEGCzWl$H{1*d>HH`oO
literal 0
HcmV?d00001
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn2.pem b/src/tests/dejagnu/pkinit-certs/user-upn2.pem
new file mode 100644
index 000000000..3a5094c84
--- /dev/null
+++ b/src/tests/dejagnu/pkinit-certs/user-upn2.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIEuTCCA6GgAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx
+FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG
+A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz
+dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug
+b3RoZXJ3aXNlMB4XDTE2MTIxMjE0NDYzOVoXDTI3MTEyNTE0NDYzOVowSjELMAkG
+A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF
+U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA05a9cPK5tn8p/xBh09JGT+uyiDOpLSvJw0Qmn/qs+lNLjRTEZp7kzIsd
++Y2XaZJ69GgdKqFvtx9Pqf2RHaRvccHSqGGF5wd7LiwbB36btYyEFCBW1hqJaS4R
+AMLv9JaRFjOZhfwnjW+tC6VdTb/ak5AKYbg0o+w2j69wqhPZIeXqqveV+VRogbTA
+O7hsWtazOTFy5KRTtJJcN/bFNNMnxB+07pZBjeDT50CFuNkUrFE7m6KnFRF7PkR6
+ZWxF7zq9cQguRrzm2JVLiZoKfeXcVYypwEdEU1r7+ixNvQn86a+91DdvO+xwbsoN
+G0xtFSelYKWvlH4BsZW8qhyPkjX4bQIDAQABo4IBSjCCAUYwHQYDVR0OBBYEFGvA
+yQ58yg3eh+Oi1JaMrRzbt9hiMIHUBgNVHSMEgcwwgcmAFGvAyQ58yg3eh+Oi1JaM
+rRzbt9hioYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz
+ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM
+IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu
+aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P
+BAQDAgPoMAwGA1UdEwEB/wQCMAAwHwYDVR0RBBgwFqAUBgorBgEEAYI3FAIDoAYM
+BHVzZXIwEgYDVR0lBAswCQYHKwYBBQIDBDANBgkqhkiG9w0BAQsFAAOCAQEAElYM
+786mUr91z82s6QC0TwP380ze8yJQiaWifHYXiqIPay19M+QG91PvSm7LLZw+ersC
+gEl/mPKrC89XlAFp8b+hJnGq6t6YmeC7OI+FapEMxpxX/X8eqAOQLrGnoq7Pm9/8
+QtWaKgo09i7rmyykKl3xSU1VktBsmlhNPPNh3x+N4bxea9OIbZonPdDtr5/Yt87/
+6kBPsGgvUUoIxLw03OmLu8AmKAwJja0FWyu93uCUP4UZWLEGpUhSYC1uUCpAZDNy
+2AtPnxfGUDtvI9eMmyeXVGYXTfkfGZyvB3m9lyIj3VVmhbvr7qLAGQn00dbOHz16
+r6w2aye0Me0GcU0grg==
+-----END CERTIFICATE-----
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn3.csr b/src/tests/dejagnu/pkinit-certs/user-upn3.csr
new file mode 100644
index 000000000..958c1e043
--- /dev/null
+++ b/src/tests/dejagnu/pkinit-certs/user-upn3.csr
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIICjzCCAXcCAQAwSjELMAkGA1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0
+dHMxFDASBgNVBAoMC0tSQlRFU1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA05a9cPK5tn8p/xBh09JGT+uyiDOpLSvJ
+w0Qmn/qs+lNLjRTEZp7kzIsd+Y2XaZJ69GgdKqFvtx9Pqf2RHaRvccHSqGGF5wd7
+LiwbB36btYyEFCBW1hqJaS4RAMLv9JaRFjOZhfwnjW+tC6VdTb/ak5AKYbg0o+w2
+j69wqhPZIeXqqveV+VRogbTAO7hsWtazOTFy5KRTtJJcN/bFNNMnxB+07pZBjeDT
+50CFuNkUrFE7m6KnFRF7PkR6ZWxF7zq9cQguRrzm2JVLiZoKfeXcVYypwEdEU1r7
++ixNvQn86a+91DdvO+xwbsoNG0xtFSelYKWvlH4BsZW8qhyPkjX4bQIDAQABoAAw
+DQYJKoZIhvcNAQELBQADggEBAEMxNp5md+jV5dFC1iSKh2CYl3P4g3UMQ9NjLcyq
+upjJmFiEGkEg/LpH4CoXI03BaD885S7akKPA1J/sG2YIrbl3TpjUJKZoJ8BjNT0L
+tYc+JIODZJEONR34Fh6/1uRU7UkRcJ8Crc83+ML+71O2SRZRJDEOS3tVbdzjEOTj
+HIed6Ia3cu0XeAvhoqRSjh8J0ufoIv3CRRCtRU8ChkmMD64p3kOTlORxWspAF8sm
+Xa53bWIpyuyz/vWwpWfr+fL+Q+BQ1TU39xvy+46AYuQIIKzK9vKZdCElQwFXZs26
+f53OyZpFjcsT9jJAM54XUxLv5rE3fqZQiBhatPZa2ThHt08=
+-----END CERTIFICATE REQUEST-----
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn3.p12 b/src/tests/dejagnu/pkinit-certs/user-upn3.p12
new file mode 100644
index 0000000000000000000000000000000000000000..a9d4780c47d33cd4d409d6ee657a7911381fe753
GIT binary patch
literal 2829
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
literal 0
HcmV?d00001
diff --git a/src/tests/dejagnu/pkinit-certs/user-upn3.pem b/src/tests/dejagnu/pkinit-certs/user-upn3.pem
new file mode 100644
index 000000000..ffedb0d1a
--- /dev/null
+++ b/src/tests/dejagnu/pkinit-certs/user-upn3.pem
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE-----
+MIIExTCCA62gAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx
+FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG
+A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz
+dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug
+b3RoZXJ3aXNlMB4XDTE2MTIxMjE0NDYzOVoXDTI3MTEyNTE0NDYzOVowSjELMAkG
+A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF
+U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA05a9cPK5tn8p/xBh09JGT+uyiDOpLSvJw0Qmn/qs+lNLjRTEZp7kzIsd
++Y2XaZJ69GgdKqFvtx9Pqf2RHaRvccHSqGGF5wd7LiwbB36btYyEFCBW1hqJaS4R
+AMLv9JaRFjOZhfwnjW+tC6VdTb/ak5AKYbg0o+w2j69wqhPZIeXqqveV+VRogbTA
+O7hsWtazOTFy5KRTtJJcN/bFNNMnxB+07pZBjeDT50CFuNkUrFE7m6KnFRF7PkR6
+ZWxF7zq9cQguRrzm2JVLiZoKfeXcVYypwEdEU1r7+ixNvQn86a+91DdvO+xwbsoN
+G0xtFSelYKWvlH4BsZW8qhyPkjX4bQIDAQABo4IBVjCCAVIwHQYDVR0OBBYEFGvA
+yQ58yg3eh+Oi1JaMrRzbt9hiMIHUBgNVHSMEgcwwgcmAFGvAyQ58yg3eh+Oi1JaM
+rRzbt9hioYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz
+ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM
+IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu
+aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P
+BAQDAgPoMAwGA1UdEwEB/wQCMAAwKwYDVR0RBCQwIqAgBgorBgEEAYI3FAIDoBIM
+EHVzZXJAS1JCVEVTVC5DT00wEgYDVR0lBAswCQYHKwYBBQIDBDANBgkqhkiG9w0B
+AQsFAAOCAQEARVeLPouequn86P3LgOZQ9LpP6IHpY2ZQwvNviiA8Zk0hsqFXnmwx
+wr3JtESim3EPuwQtJ3jXp0rxQB02r5r8sg21OjCeAB+vOz3IoF/y6WEYlz67LjMB
+XCB6Fuq80IHhVXWRi7w8dVI8xcADwIOh6fgzwbbk8qV2Lgn2Giivstp+76PnRtEn
+tavWlWW7bQlXkiROYh6u3Y8IvYYoIdlDsXQBFSRE80Rc2jR2XGKAz5CDEZNC7RAH
+Z7ON9HH6IRBOX1ijmXhBl/39QQ5t+ZYgKk8OJpL1RAZlJZtGMBwJtA1aGiAFvqTr
+aCREHZfn9NAFE/szItH7hxWJv9RISUXYmA==
+-----END CERTIFICATE-----
diff --git a/src/tests/dejagnu/pkinit-certs/user.p12 b/src/tests/dejagnu/pkinit-certs/user.p12
index a7c2baddf67f5a8c6ad97b661f6ff285ecd5bf37..67c3fa2eb01c9fdd543af9172dc63a3955987ed6 100644
GIT binary patch
delta 2825
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
by5{;I{o2EAUPuH8o2f}+U#knW0s;sCTvk7E
delta 3072
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
OZhODsvxM#f0tf(M+PpOY
diff --git a/src/tests/dejagnu/pkinit-certs/user.pem b/src/tests/dejagnu/pkinit-certs/user.pem
index e6beefcde..f6d35f370 100644
--- a/src/tests/dejagnu/pkinit-certs/user.pem
+++ b/src/tests/dejagnu/pkinit-certs/user.pem
@@ -1,32 +1,28 @@
-----BEGIN CERTIFICATE-----
-MIIFkjCCBHqgAwIBAgIIYo5oQQ6iySowDQYJKoZIhvcNAQEFBQAwgacxCzAJBgNV
-BAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMRIwEAYDVQQHEwlDYW1icmlk
-Z2UxDDAKBgNVBAoTA01JVDEpMCcGA1UECxMgSW5zZWN1cmUgUGtpbml0IEtlcmJl
-cm9zIHRlc3QgQ0ExMzAxBgNVBAMUKnBraW5pdCB0ZXN0IHN1aXRlIENBOyBkbyBu
-b3QgdXNlIG90aGVyd2lzZTAeFw0xMzAxMTcxODU5MDVaFw0yMzEyMzExODU5MDVa
-MIGhMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAGA1UE
-BxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxKTAnBgNVBAsTIEluc2VjdXJlIFBr
-aW5pdCBLZXJiZXJvcyB0ZXN0IENBMS0wKwYDVQQDFCRwa2luaXQgdGVzdCBzdWl0
-ZSBjbGllbnQ7IGRvIG5vdCB1c2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
-AoIBAQCdgsx7nyfLTQyCyQk/u1nc8hBGlCRcYslkojQd+e0JFsi6+adl6M9Ip00z
-J6PNEjKN3DUUMlQCeldhyJzdMPnzXsbkfrdSuWUAa7L6WFBY3MTpzoq556t69Hek
-xqodeidp+VVqxS7l7YABZWcVvPjHTi4uVB6Oo/CbmxHXFN4tSdV9Jjvk1tcYgTjz
-yINXTBbyeoahVaf9OxF37sq5BQiQmm3z5XomTqE8hw+p7qHuZc0ayBzl0FKoHBVy
-NT0Nt5PjHHESaBB0u3up03BXVk8tCdNCmiA2tPm5/ehJs5OzIzTYY5auIhGayqrz
-Wx8yum+JNFEPCipNQSGgJKivRSZzAgMBAAGjggHEMIIBwDAdBgNVHQ4EFgQUWfzZ
-FQqBO+QWfRyDDIJCk15YLFgwgdwGA1UdIwSB1DCB0YAUWfzZFQqBO+QWfRyDDIJC
-k15YLFihga2kgaowgacxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNl
-dHRzMRIwEAYDVQQHEwlDYW1icmlkZ2UxDDAKBgNVBAoTA01JVDEpMCcGA1UECxMg
-SW5zZWN1cmUgUGtpbml0IEtlcmJlcm9zIHRlc3QgQ0ExMzAxBgNVBAMUKnBraW5p
-dCB0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZYIJANsFDWp1HgAa
-MA4GA1UdDwEB/wQEAwIE8DB9BgNVHREEdjB0oC4GBisGAQUCAqAkMCKgDRsLS1JC
-VEVTVC5DT02hETAPoAMCAQGhCDAGGwR1c2VyoCAGCisGAQQBgjcUAgOgEgwQdXNl
-ckBrcmJ0ZXN0LmNvbaAgBgorBgEEAYI3FAIDoBIMEHVzZXJAS1JCVEVTVC5DT00w
-JgYDVR0lBB8wHQYHKwYBBQIDBAYIKwYBBQUHAwQGCCsGAQUFBwMCMAkGA1UdEwQC
-MAAwDQYJKoZIhvcNAQEFBQADggEBAJZ+5CMbEj9anyH/b/jxUT8yGgYB3KGj7qL+
-RdU2zjgsQUMSdnlqQzpuEcY3z1wK94dYQVsPaYBv+zHl0rXFMfKlm97nVdCJi0ep
-vplNAaUlhkma3D8rkPN5LmIdHslpJD6pwbV+o69aCEsrwm38flmEnBX0OUynULod
-icDvxOxhmYG2kXmUmF7wZXI+XWX8b/TloDNLAnYfjKytMa3SQdp6wtj76BCk+ZZQ
-GAF3D0BS36lkNQ/8buHFhVv/tC/rFvql8DRbFzk6W02Ymq2OhcP0uz67rFZ2KjZ5
-Z0WP1REC8Cv7yoqOKPk8S+1FK+8RdKHjT1n/n+Mws72F72bxQWQ=
+MIIE0zCCA7ugAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBpzELMAkGA1UEBhMCVVMx
+FjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcMCUNhbWJyaWRnZTEMMAoG
+A1UECgwDTUlUMSkwJwYDVQQLDCBJbnNlY3VyZSBQS0lOSVQgS2VyYmVyb3MgdGVz
+dCBDQTEzMDEGA1UEAwwqcGtpbml0IHRlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ug
+b3RoZXJ3aXNlMB4XDTE2MTIxMjE0NDYzOVoXDTI3MTEyNTE0NDYzOVowSjELMAkG
+A1UEBhMCVVMxFjAUBgNVBAgMDU1hc3NhY2h1c2V0dHMxFDASBgNVBAoMC0tSQlRF
+U1QuQ09NMQ0wCwYDVQQDDAR1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA05a9cPK5tn8p/xBh09JGT+uyiDOpLSvJw0Qmn/qs+lNLjRTEZp7kzIsd
++Y2XaZJ69GgdKqFvtx9Pqf2RHaRvccHSqGGF5wd7LiwbB36btYyEFCBW1hqJaS4R
+AMLv9JaRFjOZhfwnjW+tC6VdTb/ak5AKYbg0o+w2j69wqhPZIeXqqveV+VRogbTA
+O7hsWtazOTFy5KRTtJJcN/bFNNMnxB+07pZBjeDT50CFuNkUrFE7m6KnFRF7PkR6
+ZWxF7zq9cQguRrzm2JVLiZoKfeXcVYypwEdEU1r7+ixNvQn86a+91DdvO+xwbsoN
+G0xtFSelYKWvlH4BsZW8qhyPkjX4bQIDAQABo4IBZDCCAWAwHQYDVR0OBBYEFGvA
+yQ58yg3eh+Oi1JaMrRzbt9hiMIHUBgNVHSMEgcwwgcmAFGvAyQ58yg3eh+Oi1JaM
+rRzbt9hioYGtpIGqMIGnMQswCQYDVQQGEwJVUzEWMBQGA1UECAwNTWFzc2FjaHVz
+ZXR0czESMBAGA1UEBwwJQ2FtYnJpZGdlMQwwCgYDVQQKDANNSVQxKTAnBgNVBAsM
+IEluc2VjdXJlIFBLSU5JVCBLZXJiZXJvcyB0ZXN0IENBMTMwMQYDVQQDDCpwa2lu
+aXQgdGVzdCBzdWl0ZSBDQTsgZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0P
+BAQDAgPoMAwGA1UdEwEB/wQCMAAwOQYDVR0RBDIwMKAuBgYrBgEFAgKgJDAioA0b
+C0tSQlRFU1QuQ09NoREwD6ADAgEBoQgwBhsEdXNlcjASBgNVHSUECzAJBgcrBgEF
+AgMEMA0GCSqGSIb3DQEBCwUAA4IBAQAzbpwzIFJk3a1BsrL7KT3B6aYNs5Z4bnwm
+9dG3D2S1OFSQAbQt/ap5Tjz1RWabqWaSb6ufAKudQ6Ab2uKT8QhtmVByQYKDLYvn
+bIGgoSeAcvWHWsTeReSADr2b0E9+UT8znvBDQGED39C1AgiVUWHgIExYU0kBrP3G
+1CgWQLb7nZC5rKOkcK/Nm4XL7Oe+neiCr4j9adbGxeNHmt8HPuLuNL9TWkMAkcFo
+5INHHFzNmW2aHdvO+7lDbK8/E0QwiES6UbBvQOkTyhC4W5u2Yy7qbpsQleu6jOEz
+l8b05sf4FxhHevHtYUVuyhMOg8DPmfclnGX0Dms7aLf0s3oeSVt+
-----END CERTIFICATE-----

File diff suppressed because it is too large Load Diff

View File

@ -1,58 +0,0 @@
From 42469712239d3eb0e47d9aa306567464dd1f392a Mon Sep 17 00:00:00 2001
From: Matt Rogers <mrogers@redhat.com>
Date: Tue, 4 Apr 2017 16:54:56 -0400
Subject: [PATCH] Add the client_name() kdcpreauth callback
Add a kdcpreauth callback to returns the canonicalized client principal.
ticket: 8570 (new)
(cherry picked from commit a84f39ec30f3deeda7836da6e8b3d8dcf7a045b1)
---
src/include/krb5/kdcpreauth_plugin.h | 6 ++++++
src/kdc/kdc_preauth.c | 9 ++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h
index 92aa5a5a5..fa4436b83 100644
--- a/src/include/krb5/kdcpreauth_plugin.h
+++ b/src/include/krb5/kdcpreauth_plugin.h
@@ -232,6 +232,12 @@ typedef struct krb5_kdcpreauth_callbacks_st {
krb5_kdcpreauth_rock rock,
krb5_principal princ);
+ /*
+ * Get an alias to the client DB entry principal (possibly canonicalized).
+ */
+ krb5_principal (*client_name)(krb5_context context,
+ krb5_kdcpreauth_rock rock);
+
/* End of version 4 kdcpreauth callbacks. */
} *krb5_kdcpreauth_callbacks;
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 0ce79c667..81d0b8cff 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -591,6 +591,12 @@ match_client(krb5_context context, krb5_kdcpreauth_rock rock,
return match;
}
+static krb5_principal
+client_name(krb5_context context, krb5_kdcpreauth_rock rock)
+{
+ return rock->client->princ;
+}
+
static struct krb5_kdcpreauth_callbacks_st callbacks = {
4,
max_time_skew,
@@ -607,7 +613,8 @@ static struct krb5_kdcpreauth_callbacks_st callbacks = {
add_auth_indicator,
get_cookie,
set_cookie,
- match_client
+ match_client,
+ client_name
};
static krb5_error_code

View File

@ -1,80 +0,0 @@
From 9b50a75e97cbe9cc8c0a4e37158b56b58e966f25 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 22 Apr 2017 09:49:12 -0400
Subject: [PATCH] Add timestamp helper functions
Add k5-int.h helper functions to manipulate krb5_timestamp values,
avoiding undefined behavior and treating negative timestamp values as
times between 2038 and 2106. Add a doxygen comment for krb5_timestamp
indicating how third-party code should use it safely.
ticket: 8352
(cherry picked from commit 58e9155060cd93b1a7557e37fbc9b077b76465c2)
---
src/include/k5-int.h | 31 +++++++++++++++++++++++++++++++
src/include/krb5/krb5.hin | 9 +++++++++
2 files changed, 40 insertions(+)
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 06ca2b66d..82ee20760 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -2353,6 +2353,37 @@ k5memdup0(const void *in, size_t len, krb5_error_code *code)
return ptr;
}
+/* Convert a krb5_timestamp to a time_t value, treating the negative range of
+ * krb5_timestamp as times between 2038 and 2106 (if time_t is 64-bit). */
+static inline time_t
+ts2tt(krb5_timestamp timestamp)
+{
+ return (time_t)(uint32_t)timestamp;
+}
+
+/* Return the delta between two timestamps (a - b) as a signed 32-bit value,
+ * without relying on undefined behavior. */
+static inline krb5_deltat
+ts_delta(krb5_timestamp a, krb5_timestamp b)
+{
+ return (krb5_deltat)((uint32_t)a - (uint32_t)b);
+}
+
+/* Increment a timestamp by a signed 32-bit interval, without relying on
+ * undefined behavior. */
+static inline krb5_timestamp
+ts_incr(krb5_timestamp ts, krb5_deltat delta)
+{
+ return (krb5_timestamp)((uint32_t)ts + (uint32_t)delta);
+}
+
+/* Return true if a comes after b. */
+static inline krb5_boolean
+ts_after(krb5_timestamp a, krb5_timestamp b)
+{
+ return (uint32_t)a > (uint32_t)b;
+}
+
krb5_error_code KRB5_CALLCONV
krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
krb5_ccache ccache,
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index cf60d6c41..53ad85384 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -187,7 +187,16 @@ typedef krb5_int32 krb5_cryptotype;
typedef krb5_int32 krb5_preauthtype; /* This may change, later on */
typedef krb5_int32 krb5_flags;
+
+/**
+ * Represents a timestamp in seconds since the POSIX epoch. This legacy type
+ * is used frequently in the ABI, but cannot represent timestamps after 2038 as
+ * a positive number. Code which uses this type should cast values of it to
+ * uint32_t so that negative values are treated as timestamps between 2038 and
+ * 2106 on platforms with 64-bit time_t.
+ */
typedef krb5_int32 krb5_timestamp;
+
typedef krb5_int32 krb5_deltat;
/**

View File

@ -1,599 +0,0 @@
From 3a06f6a3cfad62da6dd8878d3446003f8293c3ae Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 29 Apr 2017 17:30:36 -0400
Subject: [PATCH] Add timestamp tests
Add a test program for krb5int_validate_times() covering cases before
and across the y2038 boundary. Add a GSSAPI test program to exercise
lifetime queries, and tests using it in t_gssapi.py for ticket end
times after y2038. Add a new test script t_y2038.py which only runs
on platforms with 64-bit time_t to exercise end-user operations across
and after y2038. Add an LDAP test case to test storage of post-y2038
timestamps.
ticket: 8352
(cherry picked from commit 8ca62e54e89e2fbd6a089e8ab20b4e374a486003)
[rharwood@redhat.com: prune gitignore]
---
src/Makefile.in | 1 +
src/config/pre.in | 2 +
src/configure.in | 3 +
src/lib/krb5/krb/Makefile.in | 14 ++--
src/lib/krb5/krb/t_valid_times.c | 109 ++++++++++++++++++++++++++++++
src/tests/Makefile.in | 1 +
src/tests/gssapi/Makefile.in | 27 ++++----
src/tests/gssapi/t_gssapi.py | 32 +++++++++
src/tests/gssapi/t_lifetime.c | 140 +++++++++++++++++++++++++++++++++++++++
src/tests/t_kdb.py | 7 ++
src/tests/t_y2038.py | 75 +++++++++++++++++++++
11 files changed, 395 insertions(+), 16 deletions(-)
create mode 100644 src/lib/krb5/krb/t_valid_times.c
create mode 100644 src/tests/gssapi/t_lifetime.c
create mode 100644 src/tests/t_y2038.py
diff --git a/src/Makefile.in b/src/Makefile.in
index b0249778c..ad8565056 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -521,6 +521,7 @@ pyrunenv.vals: Makefile
done > $@
echo "tls_impl = '$(TLS_IMPL)'" >> $@
echo "have_sasl = '$(HAVE_SASL)'" >> $@
+ echo "sizeof_time_t = $(SIZEOF_TIME_T)" >> $@
runenv.py: pyrunenv.vals
echo 'env = {}' > $@
diff --git a/src/config/pre.in b/src/config/pre.in
index d961b5621..f23c07d9d 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -452,6 +452,8 @@ HAVE_SASL = @HAVE_SASL@
# Whether we have libresolv 1.1.5 for URI discovery tests
HAVE_RESOLV_WRAPPER = @HAVE_RESOLV_WRAPPER@
+SIZEOF_TIME_T = @SIZEOF_TIME_T@
+
# error table rules
#
### /* these are invoked as $(...) foo.et, which works, but could be better */
diff --git a/src/configure.in b/src/configure.in
index 24f653f0d..4ae2c07d5 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -744,6 +744,9 @@ fi
AC_HEADER_TIME
AC_CHECK_TYPE(time_t, long)
+AC_CHECK_SIZEOF(time_t)
+SIZEOF_TIME_T=$ac_cv_sizeof_time_t
+AC_SUBST(SIZEOF_TIME_T)
# Determine where to put the replay cache.
diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in
index 0fe02a95d..55f82b147 100644
--- a/src/lib/krb5/krb/Makefile.in
+++ b/src/lib/krb5/krb/Makefile.in
@@ -364,6 +364,7 @@ SRCS= $(srcdir)/addr_comp.c \
$(srcdir)/t_in_ccache.c \
$(srcdir)/t_response_items.c \
$(srcdir)/t_sname_match.c \
+ $(srcdir)/t_valid_times.c \
$(srcdir)/t_vfy_increds.c
# Someday, when we have a "maintainer mode", do this right:
@@ -457,9 +458,12 @@ t_response_items: t_response_items.o response_items.o $(KRB5_BASE_DEPLIBS)
t_sname_match: t_sname_match.o sname_match.o $(KRB5_BASE_DEPLIBS)
$(CC_LINK) -o $@ t_sname_match.o sname_match.o $(KRB5_BASE_LIBS)
+t_valid_times: t_valid_times.o valid_times.o $(KRB5_BASE_DEPLIBS)
+ $(CC_LINK) -o $@ t_valid_times.o valid_times.o $(KRB5_BASE_LIBS)
+
TEST_PROGS= t_walk_rtree t_kerb t_ser t_deltat t_expand t_authdata t_pac \
- t_in_ccache t_cc_config t_copy_context \
- t_princ t_etypes t_vfy_increds t_response_items t_sname_match
+ t_in_ccache t_cc_config t_copy_context t_princ t_etypes t_vfy_increds \
+ t_response_items t_sname_match t_valid_times
check-unix: $(TEST_PROGS)
$(RUN_TEST_LOCAL_CONF) ./t_kerb \
@@ -496,6 +500,7 @@ check-unix: $(TEST_PROGS)
$(RUN_TEST) ./t_response_items
$(RUN_TEST) ./t_copy_context
$(RUN_TEST) ./t_sname_match
+ $(RUN_TEST) ./t_valid_times
check-pytests: t_expire_warn t_vfy_increds
$(RUNPYTEST) $(srcdir)/t_expire_warn.py $(PYTESTFLAGS)
@@ -522,8 +527,9 @@ clean:
$(OUTPRE)t_ad_fx_armor$(EXEEXT) $(OUTPRE)t_ad_fx_armor.$(OBJEXT) \
$(OUTPRE)t_vfy_increds$(EXEEXT) $(OUTPRE)t_vfy_increds.$(OBJEXT) \
$(OUTPRE)t_response_items$(EXEEXT) \
- $(OUTPRE)t_response_items.$(OBJEXT) $(OUTPRE)t_sname_match$(EXEEXT) \
- $(OUTPRE)t_sname_match.$(OBJEXT) \
+ $(OUTPRE)t_response_items.$(OBJEXT) \
+ $(OUTPRE)t_sname_match$(EXEEXT) $(OUTPRE)t_sname_match.$(OBJEXT) \
+ $(OUTPRE)t_valid_times$(EXEEXT) $(OUTPRE)t_valid_times.$(OBJECT) \
$(OUTPRE)t_parse_host_string$(EXEEXT) \
$(OUTPRE)t_parse_host_string.$(OBJEXT)
diff --git a/src/lib/krb5/krb/t_valid_times.c b/src/lib/krb5/krb/t_valid_times.c
new file mode 100644
index 000000000..1b469ffc2
--- /dev/null
+++ b/src/lib/krb5/krb/t_valid_times.c
@@ -0,0 +1,109 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* lib/krb5/krb/t_valid_times.c - test program for krb5int_validate_times() */
+/*
+ * Copyright (C) 2017 by the Massachusetts Institute of Technology.
+ * 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 "int-proto.h"
+
+#define BOUNDARY (uint32_t)INT32_MIN
+
+int
+main()
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ticket_times times = { 0, 0, 0, 0 };
+
+ ret = krb5_init_context(&context);
+ assert(!ret);
+
+ /* Current time is within authtime and end time. */
+ ret = krb5_set_debugging_time(context, 1000, 0);
+ times.authtime = 500;
+ times.endtime = 1500;
+ ret = krb5int_validate_times(context, &times);
+ assert(!ret);
+
+ /* Current time is before starttime, but within clock skew. */
+ times.starttime = 1100;
+ ret = krb5int_validate_times(context, &times);
+ assert(!ret);
+
+ /* Current time is before starttime by more than clock skew. */
+ times.starttime = 1400;
+ ret = krb5int_validate_times(context, &times);
+ assert(ret == KRB5KRB_AP_ERR_TKT_NYV);
+
+ /* Current time is after end time, but within clock skew. */
+ times.starttime = 500;
+ times.endtime = 800;
+ ret = krb5int_validate_times(context, &times);
+ assert(!ret);
+
+ /* Current time is after end time by more than clock skew. */
+ times.endtime = 600;
+ ret = krb5int_validate_times(context, &times);
+ assert(ret == KRB5KRB_AP_ERR_TKT_EXPIRED);
+
+ /* Current time is within starttime and endtime; current time and
+ * endtime are across y2038 boundary. */
+ ret = krb5_set_debugging_time(context, BOUNDARY - 100, 0);
+ assert(!ret);
+ times.starttime = BOUNDARY - 200;
+ times.endtime = BOUNDARY + 500;
+ ret = krb5int_validate_times(context, &times);
+ assert(!ret);
+
+ /* Current time is before starttime, but by less than clock skew. */
+ times.starttime = BOUNDARY + 100;
+ ret = krb5int_validate_times(context, &times);
+ assert(!ret);
+
+ /* Current time is before starttime by more than clock skew. */
+ times.starttime = BOUNDARY + 250;
+ ret = krb5int_validate_times(context, &times);
+ assert(ret == KRB5KRB_AP_ERR_TKT_NYV);
+
+ /* Current time is after endtime, but by less than clock skew. */
+ ret = krb5_set_debugging_time(context, BOUNDARY + 100, 0);
+ assert(!ret);
+ times.starttime = BOUNDARY - 1000;
+ times.endtime = BOUNDARY - 100;
+ ret = krb5int_validate_times(context, &times);
+ assert(!ret);
+
+ /* Current time is after endtime by more than clock skew. */
+ times.endtime = BOUNDARY - 300;
+ ret = krb5int_validate_times(context, &times);
+ assert(ret == KRB5KRB_AP_ERR_TKT_EXPIRED);
+
+ return 0;
+}
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index 0e93d6b59..2b3112537 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -168,6 +168,7 @@ check-pytests: localauth plugorder rdreq responder s2p s4u2proxy unlockiter
$(RUNPYTEST) $(srcdir)/t_princflags.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_tabdump.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_certauth.py $(PYTESTFLAGS)
+ $(RUNPYTEST) $(srcdir)/t_y2038.py $(PYTESTFLAGS)
clean:
$(RM) adata etinfo forward gcred hist hooks hrealm icred kdbtest
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
index 6c1464297..604f926de 100644
--- a/src/tests/gssapi/Makefile.in
+++ b/src/tests/gssapi/Makefile.in
@@ -15,15 +15,16 @@ SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
$(srcdir)/t_gssexts.c $(srcdir)/t_imp_cred.c $(srcdir)/t_imp_name.c \
$(srcdir)/t_invalid.c $(srcdir)/t_inq_cred.c $(srcdir)/t_inq_ctx.c \
$(srcdir)/t_inq_mechs_name.c $(srcdir)/t_iov.c \
- $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c $(srcdir)/t_pcontok.c \
- $(srcdir)/t_prf.c $(srcdir)/t_s4u.c $(srcdir)/t_s4u2proxy_krb5.c \
- $(srcdir)/t_saslname.c $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c
+ $(srcdir)/t_lifetime.c $(srcdir)/t_namingexts.c $(srcdir)/t_oid.c \
+ $(srcdir)/t_pcontok.c $(srcdir)/t_prf.c $(srcdir)/t_s4u.c \
+ $(srcdir)/t_s4u2proxy_krb5.c $(srcdir)/t_saslname.c \
+ $(srcdir)/t_spnego.c $(srcdir)/t_srcattrs.c
OBJS= ccinit.o ccrefresh.o common.o t_accname.o t_ccselect.o t_ciflags.o \
t_credstore.o t_enctypes.o t_err.o t_export_cred.o t_export_name.o \
t_gssexts.o t_imp_cred.o t_imp_name.o t_invalid.o t_inq_cred.o \
- t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_namingexts.o t_oid.o \
- t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \
+ t_inq_ctx.o t_inq_mechs_name.o t_iov.o t_lifetime.o t_namingexts.o \
+ t_oid.o t_pcontok.o t_prf.o t_s4u.o t_s4u2proxy_krb5.o t_saslname.o \
t_spnego.o t_srcattrs.o
COMMON_DEPS= common.o $(GSS_DEPLIBS) $(KRB5_BASE_DEPLIBS)
@@ -31,9 +32,9 @@ COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS)
all: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore t_enctypes \
t_err t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name \
- t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_namingexts \
- t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname t_spnego \
- t_srcattrs
+ t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime \
+ t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5 t_saslname \
+ t_spnego t_srcattrs
check-unix: t_oid
$(RUN_TEST) ./t_invalid
@@ -42,8 +43,8 @@ check-unix: t_oid
check-pytests: ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore \
t_enctypes t_err t_export_cred t_export_name t_imp_cred t_inq_cred \
- t_inq_ctx t_inq_mechs_name t_iov t_pcontok t_s4u t_s4u2proxy_krb5 \
- t_spnego t_srcattrs
+ t_inq_ctx t_inq_mechs_name t_iov t_lifetime t_pcontok t_s4u \
+ t_s4u2proxy_krb5 t_spnego t_srcattrs
$(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS)
@@ -88,6 +89,8 @@ t_inq_mechs_name: t_inq_mechs_name.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_inq_mechs_name.o $(COMMON_LIBS)
t_iov: t_iov.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_iov.o $(COMMON_LIBS)
+t_lifetime: t_lifetime.o $(COMMON_DEPS)
+ $(CC_LINK) -o $@ t_lifetime.o $(COMMON_LIBS)
t_namingexts: t_namingexts.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_namingexts.o $(COMMON_LIBS)
t_pcontok: t_pcontok.o $(COMMON_DEPS)
@@ -111,5 +114,5 @@ clean:
$(RM) ccinit ccrefresh t_accname t_ccselect t_ciflags t_credstore
$(RM) t_enctypes t_err t_export_cred t_export_name t_gssexts t_imp_cred
$(RM) t_imp_name t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov
- $(RM) t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5
- $(RM) t_saslname t_spnego t_srcattrs
+ $(RM) t_lifetime t_namingexts t_oid t_pcontok t_prf t_s4u
+ $(RM) t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
index 397e58962..98c8df25c 100755
--- a/src/tests/gssapi/t_gssapi.py
+++ b/src/tests/gssapi/t_gssapi.py
@@ -185,4 +185,36 @@ realm.run(['./t_ciflags', 'p:' + realm.host_princ])
# contexts.
realm.run(['./t_inq_ctx', 'user', password('user'), 'p:%s' % realm.host_princ])
+# Test lifetime results, using a realm with a large maximum lifetime
+# so that we can test ticket end dates after y2038. There are no
+# time_t conversions involved, so we can run these tests on platforms
+# with 32-bit time_t.
+realm.stop()
+conf = {'realms': {'$realm': {'max_life': '9000d'}}}
+realm = K5Realm(kdc_conf=conf, get_creds=False)
+
+# Check a lifetime string result against an expected number value (or None).
+# Allow some variance due to time elapsed during the tests.
+def check_lifetime(msg, val, expected):
+ if expected is None and val != 'indefinite':
+ fail('%s: expected indefinite, got %s' % (msg, val))
+ if expected is not None and val == 'indefinite':
+ fail('%s: expected %d, got indefinite' % (msg, expected))
+ if expected is not None and abs(int(val) - expected) > 100:
+ fail('%s: expected %d, got %s' % (msg, expected, val))
+
+realm.kinit(realm.user_princ, password('user'), flags=['-l', '8500d'])
+out = realm.run(['./t_lifetime', 'p:' + realm.host_princ, str(8000 * 86400)])
+ln = out.split('\n')
+check_lifetime('icred gss_acquire_cred', ln[0], 8500 * 86400)
+check_lifetime('icred gss_inquire_cred', ln[1], 8500 * 86400)
+check_lifetime('acred gss_acquire_cred', ln[2], None)
+check_lifetime('acred gss_inquire_cred', ln[3], None)
+check_lifetime('ictx gss_init_sec_context', ln[4], 8000 * 86400)
+check_lifetime('ictx gss_inquire_context', ln[5], 8000 * 86400)
+check_lifetime('ictx gss_context_time', ln[6], 8000 * 86400)
+check_lifetime('actx gss_accept_sec_context', ln[7], 8000 * 86400 + 300)
+check_lifetime('actx gss_inquire_context', ln[8], 8000 * 86400 + 300)
+check_lifetime('actx gss_context_time', ln[9], 8000 * 86400 + 300)
+
success('GSSAPI tests')
diff --git a/src/tests/gssapi/t_lifetime.c b/src/tests/gssapi/t_lifetime.c
new file mode 100644
index 000000000..8dcf18621
--- /dev/null
+++ b/src/tests/gssapi/t_lifetime.c
@@ -0,0 +1,140 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* tests/gssapi/t_lifetime.c - display cred and context lifetimes */
+/*
+ * Copyright (C) 2017 by the Massachusetts Institute of Technology.
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "common.h"
+
+/*
+ * Using the default credential, exercise the GSS functions which accept or
+ * produce lifetimes. Display the following results, one per line, as ASCII
+ * integers or the string "indefinite":
+ *
+ * initiator cred lifetime according to gss_acquire_cred()
+ * initiator cred lifetime according to gss_inquire_cred()
+ * acceptor cred lifetime according to gss_acquire_cred()
+ * acceptor cred lifetime according to gss_inquire_cred()
+ * initiator context lifetime according to gss_init_sec_context()
+ * initiator context lifetime according to gss_inquire_context()
+ * initiator context lifetime according to gss_context_time()
+ * acceptor context lifetime according to gss_init_sec_context()
+ * acceptor context lifetime according to gss_inquire_context()
+ * acceptor context lifetime according to gss_context_time()
+ */
+
+static void
+display_time(OM_uint32 tval)
+{
+ if (tval == GSS_C_INDEFINITE)
+ puts("indefinite");
+ else
+ printf("%u\n", (unsigned int)tval);
+}
+
+int
+main(int argc, char *argv[])
+{
+ OM_uint32 minor, major;
+ gss_cred_id_t icred, acred;
+ gss_name_t tname;
+ gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT;
+ gss_buffer_desc itok = GSS_C_EMPTY_BUFFER, atok = GSS_C_EMPTY_BUFFER;
+ OM_uint32 time_req = GSS_C_INDEFINITE, time_rec;
+
+ if (argc < 2 || argc > 3) {
+ fprintf(stderr, "Usage: %s targetname [time_req]\n", argv[0]);
+ return 1;
+ }
+ tname = import_name(argv[1]);
+ if (argc >= 3)
+ time_req = atoll(argv[2]);
+
+ /* Get initiator cred and display its lifetime according to
+ * gss_acquire_cred and gss_inquire_cred. */
+ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5,
+ GSS_C_INITIATE, &icred, NULL, &time_rec);
+ check_gsserr("gss_acquire_cred(initiate)", major, minor);
+ display_time(time_rec);
+ major = gss_inquire_cred(&minor, icred, NULL, &time_rec, NULL, NULL);
+ check_gsserr("gss_inquire_cred(initiate)", major, minor);
+ display_time(time_rec);
+
+ /* Get acceptor cred and display its lifetime according to gss_acquire_cred
+ * and gss_inquire_cred. */
+ major = gss_acquire_cred(&minor, GSS_C_NO_NAME, time_req, &mechset_krb5,
+ GSS_C_ACCEPT, &acred, NULL, &time_rec);
+ check_gsserr("gss_acquire_cred(accept)", major, minor);
+ display_time(time_rec);
+ major = gss_inquire_cred(&minor, acred, NULL, &time_rec, NULL, NULL);
+ check_gsserr("gss_inquire_cred(accept)", major, minor);
+ display_time(time_rec);
+
+ /* Make an initiator context and display its lifetime according to
+ * gss_init_sec_context, gss_inquire_context, and gss_context_time. */
+ major = gss_init_sec_context(&minor, icred, &ictx, tname, &mech_krb5, 0,
+ time_req, GSS_C_NO_CHANNEL_BINDINGS, &atok,
+ NULL, &itok, NULL, &time_rec);
+ check_gsserr("gss_init_sec_context", major, minor);
+ assert(major == GSS_S_COMPLETE);
+ display_time(time_rec);
+ major = gss_inquire_context(&minor, ictx, NULL, NULL, &time_rec, NULL,
+ NULL, NULL, NULL);
+ check_gsserr("gss_inquire_context(initiate)", major, minor);
+ display_time(time_rec);
+ major = gss_context_time(&minor, ictx, &time_rec);
+ check_gsserr("gss_context_time(initiate)", major, minor);
+ display_time(time_rec);
+
+ major = gss_accept_sec_context(&minor, &actx, acred, &itok,
+ GSS_C_NO_CHANNEL_BINDINGS, NULL,
+ NULL, &atok, NULL, &time_rec, NULL);
+ check_gsserr("gss_accept_sec_context", major, minor);
+ assert(major == GSS_S_COMPLETE);
+ display_time(time_rec);
+ major = gss_inquire_context(&minor, actx, NULL, NULL, &time_rec, NULL,
+ NULL, NULL, NULL);
+ check_gsserr("gss_inquire_context(accept)", major, minor);
+ display_time(time_rec);
+ major = gss_context_time(&minor, actx, &time_rec);
+ check_gsserr("gss_context_time(accept)", major, minor);
+ display_time(time_rec);
+
+ (void)gss_release_buffer(&minor, &itok);
+ (void)gss_release_buffer(&minor, &atok);
+ (void)gss_release_name(&minor, &tname);
+ (void)gss_release_cred(&minor, &icred);
+ (void)gss_release_cred(&minor, &acred);
+ (void)gss_delete_sec_context(&minor, &ictx, NULL);
+ (void)gss_delete_sec_context(&minor, &actx, NULL);
+ return 0;
+}
diff --git a/src/tests/t_kdb.py b/src/tests/t_kdb.py
index 44635b089..ffc043709 100755
--- a/src/tests/t_kdb.py
+++ b/src/tests/t_kdb.py
@@ -414,6 +414,13 @@ realm.run([kadminl, 'addprinc', '-policy', 'keepoldpasspol', '-pw', 'aaaa',
for p in ('bbbb', 'cccc', 'aaaa'):
realm.run([kadminl, 'cpw', '-keepold', '-pw', p, 'keepoldpassprinc'])
+if runenv.sizeof_time_t <= 4:
+ skipped('y2038 LDAP test', 'platform has 32-bit time_t')
+else:
+ # Test storage of timestamps after y2038.
+ realm.run([kadminl, 'modprinc', '-pwexpire', '2040-02-03', 'user'])
+ realm.run([kadminl, 'getprinc', 'user'], expected_msg=' 2040\n')
+
realm.stop()
# Briefly test dump and load.
diff --git a/src/tests/t_y2038.py b/src/tests/t_y2038.py
new file mode 100644
index 000000000..02e946df4
--- /dev/null
+++ b/src/tests/t_y2038.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+from k5test import *
+
+# These tests will become much less important after the y2038 boundary
+# has elapsed, and may start exhibiting problems around the year 2075.
+
+if runenv.sizeof_time_t <= 4:
+ skip_rest('y2038 timestamp tests', 'platform has 32-bit time_t')
+
+# Start a KDC running roughly 21 years in the future, after the y2038
+# boundary. Set long maximum lifetimes for later tests.
+conf = {'realms': {'$realm': {'max_life': '9000d',
+ 'max_renewable_life': '9000d'}}}
+realm = K5Realm(start_kdc=False, kdc_conf=conf)
+realm.start_kdc(['-T', '662256000'])
+
+# kinit without preauth should succeed with clock skew correction, but
+# will result in an expired ticket, because we sent an absolute end
+# time and didn't get a chance to correct it..
+realm.kinit(realm.user_princ, password('user'))
+realm.run([kvno, realm.host_princ], expected_code=1,
+ expected_msg='Ticket expired')
+
+# kinit with preauth should succeed and result in a valid ticket, as
+# we get a chance to correct the end time based on the KDC time. Try
+# with encrypted timestamp and encrypted challenge.
+realm.run([kadminl, 'modprinc', '+requires_preauth', 'user'])
+realm.kinit(realm.user_princ, password('user'))
+realm.run([kvno, realm.host_princ])
+realm.kinit(realm.user_princ, password('user'), flags=['-T', realm.ccache])
+realm.run([kvno, realm.host_princ])
+
+# Test that expiration warning works after y2038, by setting a
+# password expiration time ten minutes after the KDC time.
+realm.run([kadminl, 'modprinc', '-pwexpire', '662256600 seconds', 'user'])
+out = realm.kinit(realm.user_princ, password('user'))
+if 'will expire in less than one hour' not in out:
+ fail('password expiration message')
+year = int(out.split()[-1])
+if year < 2038 or year > 9999:
+ fail('password expiration year')
+
+realm.stop_kdc()
+realm.start_kdc()
+realm.start_kadmind()
+realm.prep_kadmin()
+
+# Test getdate parsing of absolute timestamps after 2038 and
+# marshalling over the kadmin protocol. The local time zone will
+# affect the display time by a little bit, so just look for the year.
+realm.run_kadmin(['modprinc', '-pwexpire', '2040-02-03', realm.host_princ])
+realm.run_kadmin(['getprinc', realm.host_princ], expected_msg=' 2040\n')
+
+# Get a ticket whose lifetime crosses the y2038 boundary and
+# range-check the expiration year as reported by klist.
+realm.kinit(realm.user_princ, password('user'),
+ flags=['-l', '8000d', '-r', '8500d'])
+realm.run([kvno, realm.host_princ])
+out = realm.run([klist])
+if int(out.split('\n')[4].split()[2].split('/')[2]) < 39:
+ fail('unexpected tgt expiration year')
+if int(out.split('\n')[5].split()[2].split('/')[2]) < 40:
+ fail('unexpected tgt rtill year')
+if int(out.split('\n')[6].split()[2].split('/')[2]) < 39:
+ fail('unexpected service ticket expiration year')
+if int(out.split('\n')[7].split()[2].split('/')[2]) < 40:
+ fail('unexpected service ticket rtill year')
+realm.kinit(realm.user_princ, None, ['-R'])
+out = realm.run([klist])
+if int(out.split('\n')[4].split()[2].split('/')[2]) < 39:
+ fail('unexpected renewed tgt expiration year')
+if int(out.split('\n')[5].split()[2].split('/')[2]) < 40:
+ fail('unexpected renewed tgt rtill year')
+
+success('y2038 tests')

View File

@ -1,59 +0,0 @@
From 69ca5ff168f24792924b3cab0a9f27ada3eb4c4b Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 4 May 2017 17:03:35 -0400
Subject: [PATCH] Add y2038 documentation
ticket: 8352
(cherry picked from commit 85d64c43dbf7a7faa56a1999494cdfa49e8bd2c9)
---
doc/appdev/index.rst | 1 +
doc/appdev/y2038.rst | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 doc/appdev/y2038.rst
diff --git a/doc/appdev/index.rst b/doc/appdev/index.rst
index 3d62045ca..961bb1e9e 100644
--- a/doc/appdev/index.rst
+++ b/doc/appdev/index.rst
@@ -5,6 +5,7 @@ For application developers
:maxdepth: 1
gssapi.rst
+ y2038.rst
h5l_mit_apidiff.rst
init_creds.rst
princ_handle.rst
diff --git a/doc/appdev/y2038.rst b/doc/appdev/y2038.rst
new file mode 100644
index 000000000..bc4122dad
--- /dev/null
+++ b/doc/appdev/y2038.rst
@@ -0,0 +1,28 @@
+Year 2038 considerations for uses of krb5_timestamp
+===================================================
+
+POSIX time values, which measure the number of seconds since January 1
+1970, will exceed the maximum value representable in a signed 32-bit
+integer in January 2038. This documentation describes considerations
+for consumers of the MIT krb5 libraries.
+
+Applications or libraries which use libkrb5 and consume the timestamps
+included in credentials or other structures make use of the
+:c:type:`krb5_timestamp` type. For historical reasons, krb5_timestamp
+is a signed 32-bit integer, even on platforms where a larger type is
+natively used to represent time values. To behave properly for time
+values after January 2038, calling code should cast krb5_timestamp
+values to uint32_t, and then to time_t::
+
+ (time_t)(uint32_t)timestamp
+
+Used in this way, krb5_timestamp values can represent time values up
+until February 2106, provided that the platform uses a 64-bit or
+larger time_t type. This usage will also remain safe if a later
+version of MIT krb5 changes krb5_timestamp to an unsigned 32-bit
+integer.
+
+The GSSAPI only uses representations of time intervals, not absolute
+times. Callers of the GSSAPI should require no changes to behave
+correctly after January 2038, provided that they use MIT krb5 release
+1.16 or later.

View File

@ -1,23 +0,0 @@
From 5f2ea38f7ecd60184e510558bdb551d0153432e0 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 10 Nov 2016 13:20:49 -0500
Subject: [PATCH] Build with -Werror-implicit-int where supported
(cherry picked from commit 873d864230c9c64c65ff12a24199bac3adf3bc2f)
---
src/aclocal.m4 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 2bfb99496..da1d6d8b4 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -529,7 +529,7 @@ if test "$GCC" = yes ; then
TRY_WARN_CC_FLAG(-Wno-format-zero-length)
# Other flags here may not be supported on some versions of
# gcc that people want to use.
- for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers ; do
+ for flag in overflow strict-overflow missing-format-attribute missing-prototypes return-type missing-braces parentheses switch unused-function unused-label unused-variable unused-value unknown-pragmas sign-compare newline-eof error=uninitialized error=pointer-arith error=int-conversion error=incompatible-pointer-types error=discarded-qualifiers error=implicit-int ; do
TRY_WARN_CC_FLAG(-W$flag)
done
# old-style-definition? generates many, many warnings

View File

@ -1,422 +0,0 @@
From 686fa6476eb759532d566794fa8d430774d44cf7 Mon Sep 17 00:00:00 2001
From: Matt Rogers <mrogers@redhat.com>
Date: Wed, 29 Mar 2017 10:35:13 -0400
Subject: [PATCH] Convert some pkiDebug messages to TRACE macros
ticket: 8568 (new)
(cherry picked from commit 9852862a83952a94300adfafa3e333f43396ec33)
---
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 46 ++++++---------
src/plugins/preauth/pkinit/pkinit_identity.c | 3 -
src/plugins/preauth/pkinit/pkinit_matching.c | 1 +
src/plugins/preauth/pkinit/pkinit_srv.c | 24 ++++----
src/plugins/preauth/pkinit/pkinit_trace.h | 68 +++++++++++++++++++++-
5 files changed, 97 insertions(+), 45 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 90c30dbf5..70e230ec2 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -2320,7 +2320,6 @@ crypto_check_cert_eku(krb5_context context,
X509_NAME_oneline(X509_get_subject_name(reqctx->received_cert),
buf, sizeof(buf));
- pkiDebug("%s: looking for EKUs in cert = %s\n", __FUNCTION__, buf);
if ((i = X509_get_ext_by_NID(reqctx->received_cert,
NID_ext_key_usage, -1)) >= 0) {
@@ -2354,7 +2353,6 @@ crypto_check_cert_eku(krb5_context context,
if (found_eku) {
ASN1_BIT_STRING *usage = NULL;
- pkiDebug("%s: found acceptable EKU, checking for digitalSignature\n", __FUNCTION__);
/* check that digitalSignature KeyUsage is present */
X509_check_ca(reqctx->received_cert);
@@ -2363,12 +2361,10 @@ crypto_check_cert_eku(krb5_context context,
if (!ku_reject(reqctx->received_cert,
X509v3_KU_DIGITAL_SIGNATURE)) {
- pkiDebug("%s: found digitalSignature KU\n",
- __FUNCTION__);
+ TRACE_PKINIT_EKU(context);
*valid_eku = 1;
} else
- pkiDebug("%s: didn't find digitalSignature KU\n",
- __FUNCTION__);
+ TRACE_PKINIT_EKU_NO_KU(context);
}
ASN1_BIT_STRING_free(usage);
}
@@ -4317,8 +4313,7 @@ pkinit_get_certs_pkcs12(krb5_context context,
fp = fopen(idopts->cert_filename, "rb");
if (fp == NULL) {
- pkiDebug("Failed to open PKCS12 file '%s', error %d\n",
- idopts->cert_filename, errno);
+ TRACE_PKINIT_PKCS_OPEN_FAIL(context, idopts->cert_filename, errno);
goto cleanup;
}
set_cloexec_file(fp);
@@ -4326,8 +4321,7 @@ pkinit_get_certs_pkcs12(krb5_context context,
p12 = d2i_PKCS12_fp(fp, NULL);
fclose(fp);
if (p12 == NULL) {
- pkiDebug("Failed to decode PKCS12 file '%s' contents\n",
- idopts->cert_filename);
+ TRACE_PKINIT_PKCS_DECODE_FAIL(context, idopts->cert_filename);
goto cleanup;
}
/*
@@ -4345,7 +4339,7 @@ pkinit_get_certs_pkcs12(krb5_context context,
char *p12name = reassemble_pkcs12_name(idopts->cert_filename);
const char *tmp;
- pkiDebug("Initial PKCS12_parse with no password failed\n");
+ TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(context);
if (id_cryptoctx->defer_id_prompt) {
/* Supply the identity name to be passed to the responder. */
@@ -4386,14 +4380,14 @@ pkinit_get_certs_pkcs12(krb5_context context,
NULL, NULL, 1, &kprompt);
k5int_set_prompt_types(context, 0);
if (r) {
- pkiDebug("Failed to prompt for PKCS12 password");
+ TRACE_PKINIT_PKCS_PROMPT_FAIL(context);
goto cleanup;
}
}
ret = PKCS12_parse(p12, rdat.data, &y, &x, NULL);
if (ret == 0) {
- pkiDebug("Second PKCS12_parse with password failed\n");
+ TRACE_PKINIT_PKCS_PARSE_FAIL_SECOND(context);
goto cleanup;
}
}
@@ -4516,8 +4510,7 @@ pkinit_get_certs_fs(krb5_context context,
}
if (idopts->key_filename == NULL) {
- pkiDebug("%s: failed to get user's private key location\n",
- __FUNCTION__);
+ TRACE_PKINIT_NO_PRIVKEY(context);
goto cleanup;
}
@@ -4545,8 +4538,7 @@ pkinit_get_certs_dir(krb5_context context,
char *dirname, *suf;
if (idopts->cert_filename == NULL) {
- pkiDebug("%s: failed to get user's certificate directory location\n",
- __FUNCTION__);
+ TRACE_PKINIT_NO_CERT(context);
return ENOENT;
}
@@ -4590,8 +4582,7 @@ pkinit_get_certs_dir(krb5_context context,
retval = pkinit_load_fs_cert_and_key(context, id_cryptoctx,
certname, keyname, i);
if (retval == 0) {
- pkiDebug("%s: Successfully loaded cert (and key) for %s\n",
- __FUNCTION__, dentry->d_name);
+ TRACE_PKINIT_LOADED_CERT(context, dentry->d_name);
i++;
}
else
@@ -4599,8 +4590,7 @@ pkinit_get_certs_dir(krb5_context context,
}
if (!id_cryptoctx->defer_id_prompt && i == 0) {
- pkiDebug("%s: No cert/key pairs found in directory '%s'\n",
- __FUNCTION__, idopts->cert_filename);
+ TRACE_PKINIT_NO_CERT_AND_KEY(context, idopts->cert_filename);
retval = ENOENT;
goto cleanup;
}
@@ -5370,9 +5360,7 @@ crypto_cert_select_default(krb5_context context,
goto errout;
}
if (cert_count != 1) {
- pkiDebug("%s: ERROR: There are %d certs to choose from, "
- "but there must be exactly one.\n",
- __FUNCTION__, cert_count);
+ TRACE_PKINIT_NO_DEFAULT_CERT(context, cert_count);
retval = EINVAL;
goto errout;
}
@@ -5520,7 +5508,7 @@ load_cas_and_crls(krb5_context context,
switch(catype) {
case CATYPE_ANCHORS:
if (sk_X509_num(ca_certs) == 0) {
- pkiDebug("no anchors in file, %s\n", filename);
+ TRACE_PKINIT_NO_CA_ANCHOR(context, filename);
if (id_cryptoctx->trustedCAs == NULL)
sk_X509_free(ca_certs);
} else {
@@ -5530,7 +5518,7 @@ load_cas_and_crls(krb5_context context,
break;
case CATYPE_INTERMEDIATES:
if (sk_X509_num(ca_certs) == 0) {
- pkiDebug("no intermediates in file, %s\n", filename);
+ TRACE_PKINIT_NO_CA_INTERMEDIATE(context, filename);
if (id_cryptoctx->intermediateCAs == NULL)
sk_X509_free(ca_certs);
} else {
@@ -5540,7 +5528,7 @@ load_cas_and_crls(krb5_context context,
break;
case CATYPE_CRLS:
if (sk_X509_CRL_num(ca_crls) == 0) {
- pkiDebug("no crls in file, %s\n", filename);
+ TRACE_PKINIT_NO_CRL(context, filename);
if (id_cryptoctx->revoked == NULL)
sk_X509_CRL_free(ca_crls);
} else {
@@ -5626,14 +5614,14 @@ crypto_load_cas_and_crls(krb5_context context,
int catype,
char *id)
{
- pkiDebug("%s: called with idtype %s and catype %s\n",
- __FUNCTION__, idtype2string(idtype), catype2string(catype));
switch (idtype) {
case IDTYPE_FILE:
+ TRACE_PKINIT_LOAD_FROM_FILE(context);
return load_cas_and_crls(context, plg_cryptoctx, req_cryptoctx,
id_cryptoctx, catype, id);
break;
case IDTYPE_DIR:
+ TRACE_PKINIT_LOAD_FROM_DIR(context);
return load_cas_and_crls_dir(context, plg_cryptoctx, req_cryptoctx,
id_cryptoctx, catype, id);
break;
diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c
index a897efa25..737552e85 100644
--- a/src/plugins/preauth/pkinit/pkinit_identity.c
+++ b/src/plugins/preauth/pkinit/pkinit_identity.c
@@ -608,7 +608,6 @@ pkinit_identity_prompt(krb5_context context,
retval = pkinit_cert_matching(context, plg_cryptoctx,
req_cryptoctx, id_cryptoctx, princ);
if (retval) {
- pkiDebug("%s: No matching certificate found\n", __FUNCTION__);
crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
id_cryptoctx);
goto errout;
@@ -621,8 +620,6 @@ pkinit_identity_prompt(krb5_context context,
retval = crypto_cert_select_default(context, plg_cryptoctx,
req_cryptoctx, id_cryptoctx);
if (retval) {
- pkiDebug("%s: Failed while selecting default certificate\n",
- __FUNCTION__);
crypto_free_cert_info(context, plg_cryptoctx, req_cryptoctx,
id_cryptoctx);
goto errout;
diff --git a/src/plugins/preauth/pkinit/pkinit_matching.c b/src/plugins/preauth/pkinit/pkinit_matching.c
index a50c50c8d..cad4c2b9a 100644
--- a/src/plugins/preauth/pkinit/pkinit_matching.c
+++ b/src/plugins/preauth/pkinit/pkinit_matching.c
@@ -812,6 +812,7 @@ pkinit_cert_matching(krb5_context context,
goto cleanup;
}
} else {
+ TRACE_PKINIT_NO_MATCHING_CERT(context);
retval = ENOENT; /* XXX */
goto cleanup;
}
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index 32ca122f2..9c6e96c9e 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -188,6 +188,7 @@ verify_client_san(krb5_context context,
plgctx->opts->allow_upn ? &upns : NULL,
NULL);
if (retval == ENOENT) {
+ TRACE_PKINIT_SERVER_NO_SAN(context);
goto out;
} else if (retval) {
pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__);
@@ -224,7 +225,7 @@ verify_client_san(krb5_context context,
krb5_free_unparsed_name(context, san_string);
#endif
if (cb->match_client(context, rock, princs[i])) {
- pkiDebug("%s: pkinit san match found\n", __FUNCTION__);
+ TRACE_PKINIT_SERVER_MATCHING_SAN_FOUND(context);
*valid_san = 1;
retval = 0;
goto out;
@@ -252,7 +253,7 @@ verify_client_san(krb5_context context,
krb5_free_unparsed_name(context, san_string);
#endif
if (cb->match_client(context, rock, upns[i])) {
- pkiDebug("%s: upn san match found\n", __FUNCTION__);
+ TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(context);
*valid_san = 1;
retval = 0;
goto out;
@@ -300,7 +301,7 @@ verify_client_eku(krb5_context context,
*eku_accepted = 0;
if (plgctx->opts->require_eku == 0) {
- pkiDebug("%s: configuration requests no EKU checking\n", __FUNCTION__);
+ TRACE_PKINIT_SERVER_EKU_SKIP(context);
*eku_accepted = 1;
retval = 0;
goto out;
@@ -364,6 +365,7 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules,
ret = KRB5_PLUGIN_NO_HANDLE;
for (i = 0; certauth_modules != NULL && certauth_modules[i] != NULL; i++) {
h = certauth_modules[i];
+ TRACE_PKINIT_SERVER_CERT_AUTH(context, h->vt.name);
ret = h->vt.authorize(context, h->moddata, cert, cert_len, client,
&opts, db_ent, &ais);
if (ret == 0)
@@ -449,7 +451,7 @@ pkinit_server_verify_padata(krb5_context context,
switch ((int)data->pa_type) {
case KRB5_PADATA_PK_AS_REQ:
- pkiDebug("processing KRB5_PADATA_PK_AS_REQ\n");
+ TRACE_PKINIT_SERVER_PADATA_VERIFY(context);
retval = k5int_decode_krb5_pa_pk_as_req(&k5data, &reqp);
if (retval) {
pkiDebug("decode_krb5_pa_pk_as_req failed\n");
@@ -472,7 +474,7 @@ pkinit_server_verify_padata(krb5_context context,
break;
case KRB5_PADATA_PK_AS_REP_OLD:
case KRB5_PADATA_PK_AS_REQ_OLD:
- pkiDebug("processing KRB5_PADATA_PK_AS_REQ_OLD\n");
+ TRACE_PKINIT_SERVER_PADATA_VERIFY_OLD(context);
retval = k5int_decode_krb5_pa_pk_as_req_draft9(&k5data, &reqp9);
if (retval) {
pkiDebug("decode_krb5_pa_pk_as_req_draft9 failed\n");
@@ -500,7 +502,7 @@ pkinit_server_verify_padata(krb5_context context,
goto cleanup;
}
if (retval) {
- pkiDebug("pkcs7_signeddata_verify failed\n");
+ TRACE_PKINIT_SERVER_PADATA_VERIFY_FAIL(context);
goto cleanup;
}
if (is_signed) {
@@ -830,7 +832,7 @@ pkinit_server_return_padata(krb5_context context,
return ENOENT;
}
- pkiDebug("pkinit_return_padata: entered!\n");
+ TRACE_PKINIT_SERVER_RETURN_PADATA(context);
reqctx = (pkinit_kdc_req_context)modreq;
if (encrypting_key->contents) {
@@ -1463,8 +1465,7 @@ pkinit_san_authorize(krb5_context context, krb5_certauth_moddata moddata,
return ret;
if (!valid_san) {
- pkiDebug("%s: did not find an acceptable SAN in user certificate\n",
- __FUNCTION__);
+ TRACE_PKINIT_SERVER_SAN_REJECT(context);
return KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
}
@@ -1490,8 +1491,7 @@ pkinit_eku_authorize(krb5_context context, krb5_certauth_moddata moddata,
return ret;
if (!valid_eku) {
- pkiDebug("%s: did not find an acceptable EKU in user certificate\n",
- __FUNCTION__);
+ TRACE_PKINIT_SERVER_EKU_REJECT(context);
return KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE;
}
@@ -1617,7 +1617,7 @@ pkinit_server_plugin_init(krb5_context context,
return ENOMEM;
for (i = 0, j = 0; i < numrealms; i++) {
- pkiDebug("%s: processing realm '%s'\n", __FUNCTION__, realmnames[i]);
+ TRACE_PKINIT_SERVER_INIT_REALM(context, realmnames[i]);
retval = pkinit_server_plugin_init_realm(context, realmnames[i], &plgctx);
if (retval == 0 && plgctx != NULL)
realm_contexts[j++] = plgctx;
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h
index 458d0961e..6abe28c0c 100644
--- a/src/plugins/preauth/pkinit/pkinit_trace.h
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h
@@ -52,7 +52,7 @@
#define TRACE_PKINIT_CLIENT_REP_CHECKSUM_FAIL(c, expected, received) \
TRACE(c, "PKINIT client checksum mismatch: expected {cksum}, " \
"received {cksum}", expected, received)
-#define TRACE_PKINIT_CLIENT_REP_DH(c) \
+#define TRACE_PKINIT_CLIENT_REP_DH(c) \
TRACE(c, "PKINIT client verified DH reply")
#define TRACE_PKINIT_CLIENT_REP_DH_FAIL(c) \
TRACE(c, "PKINIT client could not verify DH reply")
@@ -91,6 +91,72 @@
#define TRACE_PKINIT_OPENSSL_ERROR(c, msg) \
TRACE(c, "PKINIT OpenSSL error: {str}", msg)
+#define TRACE_PKINIT_SERVER_CERT_AUTH(c, modname) \
+ TRACE(c, "PKINIT server authorizing cert with module {str}", \
+ modname)
+#define TRACE_PKINIT_SERVER_EKU_REJECT(c) \
+ TRACE(c, "PKINIT server found no acceptable EKU in client cert")
+#define TRACE_PKINIT_SERVER_EKU_SKIP(c) \
+ TRACE(c, "PKINIT server skipping EKU check due to configuration")
+#define TRACE_PKINIT_SERVER_INIT_REALM(c, realm) \
+ TRACE(c, "PKINIT server initializing realm {str}", realm)
+#define TRACE_PKINIT_SERVER_MATCHING_UPN_FOUND(c) \
+ TRACE(c, "PKINIT server found a matching UPN SAN in client cert")
+#define TRACE_PKINIT_SERVER_MATCHING_SAN_FOUND(c) \
+ TRACE(c, "PKINIT server found a matching SAN in client cert")
+#define TRACE_PKINIT_SERVER_NO_SAN(c) \
+ TRACE(c, "PKINIT server found no SAN in client cert")
+#define TRACE_PKINIT_SERVER_PADATA_VERIFY(c) \
+ TRACE(c, "PKINIT server verifying KRB5_PADATA_PK_AS_REQ")
+#define TRACE_PKINIT_SERVER_PADATA_VERIFY_OLD(c) \
+ TRACE(c, "PKINIT server verifying KRB5_PADATA_PK_AS_REQ_OLD")
+#define TRACE_PKINIT_SERVER_PADATA_VERIFY_FAIL(c) \
+ TRACE(c, "PKINIT server failed to verify PA data")
+#define TRACE_PKINIT_SERVER_RETURN_PADATA(c) \
+ TRACE(c, "PKINIT server returning PA data")
+#define TRACE_PKINIT_SERVER_SAN_REJECT(c) \
+ TRACE(c, "PKINIT server found no acceptable SAN in client cert")
+
+#define TRACE_PKINIT_EKU(c) \
+ TRACE(c, "PKINIT found acceptable EKU and digitalSignature KU")
+#define TRACE_PKINIT_EKU_NO_KU(c) \
+ TRACE(c, "PKINIT found acceptable EKU but no digitalSignature KU")
+#define TRACE_PKINIT_LOADED_CERT(c, name) \
+ TRACE(c, "PKINIT loaded cert and key for {str}", name)
+#define TRACE_PKINIT_LOAD_FROM_FILE(c) \
+ TRACE(c, "PKINIT loading CA certs and CRLs from FILE")
+#define TRACE_PKINIT_LOAD_FROM_DIR(c) \
+ TRACE(c, "PKINIT loading CA certs and CRLs from DIR")
+#define TRACE_PKINIT_NO_CA_ANCHOR(c, file) \
+ TRACE(c, "PKINIT no anchor CA in file {str}", file)
+#define TRACE_PKINIT_NO_CA_INTERMEDIATE(c, file) \
+ TRACE(c, "PKINIT no intermediate CA in file {str}", file)
+#define TRACE_PKINIT_NO_CERT(c) \
+ TRACE(c, "PKINIT no certificate provided")
+#define TRACE_PKINIT_NO_CERT_AND_KEY(c, dirname) \
+ TRACE(c, "PKINIT no cert and key pair found in directory {str}", \
+ dirname)
+#define TRACE_PKINIT_NO_CRL(c, file) \
+ TRACE(c, "PKINIT no CRL in file {str}", file)
+#define TRACE_PKINIT_NO_DEFAULT_CERT(c, count) \
+ TRACE(c, "PKINIT error: There are {int} certs, but there must " \
+ "be exactly one.", count)
+#define TRACE_PKINIT_NO_MATCHING_CERT(c) \
+ TRACE(c, "PKINIT no matching certificate found")
+#define TRACE_PKINIT_NO_PRIVKEY(c) \
+ TRACE(c, "PKINIT no private key provided")
+#define TRACE_PKINIT_PKCS_DECODE_FAIL(c, name) \
+ TRACE(c, "PKINIT failed to decode PKCS12 file {str} contents", name)
+#define TRACE_PKINIT_PKCS_OPEN_FAIL(c, name, err) \
+ TRACE(c, "PKINIT failed to open PKCS12 file {str}: err {errno}", \
+ name, err)
+#define TRACE_PKINIT_PKCS_PARSE_FAIL_FIRST(c) \
+ TRACE(c, "PKINIT initial PKCS12_parse with no password failed")
+#define TRACE_PKINIT_PKCS_PARSE_FAIL_SECOND(c) \
+ TRACE(c, "PKINIT second PKCS12_parse with password failed")
+#define TRACE_PKINIT_PKCS_PROMPT_FAIL(c) \
+ TRACE(c, "PKINIT failed to prompt for PKCS12 password")
+
#define TRACE_CERTAUTH_VTINIT_FAIL(c, ret) \
TRACE(c, "certauth module failed to init vtable: {kerr}", ret)
#define TRACE_CERTAUTH_INIT_FAIL(c, name, ret) \

View File

@ -1,32 +0,0 @@
From 08d995aaf48e75c174525ae0b47e12c3170b3f5f Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 23 Mar 2017 13:42:55 -0400
Subject: [PATCH] Correct error handling bug in prior commit
In crypto_encode_der_cert(), if the second i2d_X509() invocation
fails, make sure to free the allocated pointer and not the
possibly-modified alias.
ticket: 8561
(cherry picked from commit 7fdaef7c3280c86b5df25ae061fb04cc56d8620c)
---
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index a5b010b26..90c30dbf5 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -6196,10 +6196,10 @@ crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx,
if (len <= 0)
return EINVAL;
p = der = malloc(len);
- if (p == NULL)
+ if (der == NULL)
return ENOMEM;
if (i2d_X509(reqctx->received_cert, &p) <= 0) {
- free(p);
+ free(der);
return EINVAL;
}
*der_out = der;

View File

@ -1,263 +0,0 @@
From d5462c96c9918ffa7d3f05de310c5aed34181941 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 4 Jan 2017 11:33:57 -0500
Subject: [PATCH] Deindent crypto_retrieve_X509_sans()
Fix some long lines in crypto_retrieve_X509_sans() by returning early
if X509_get_ext_by_NID() returns a negative result. Also ensure that
return parameters are always initialized.
(cherry picked from commit c6b772523db9d7791ee1c56eb512c4626556a4e7)
---
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 224 +++++++++++----------
1 file changed, 114 insertions(+), 110 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index bc6e7662e..8def8c542 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -2101,11 +2101,21 @@ crypto_retrieve_X509_sans(krb5_context context,
{
krb5_error_code retval = EINVAL;
char buf[DN_BUF_LEN];
- int p = 0, u = 0, d = 0, l;
+ int p = 0, u = 0, d = 0, ret = 0, l;
krb5_principal *princs = NULL;
krb5_principal *upns = NULL;
unsigned char **dnss = NULL;
- unsigned int i, num_found = 0;
+ unsigned int i, num_found = 0, num_sans = 0;
+ X509_EXTENSION *ext = NULL;
+ GENERAL_NAMES *ialt = NULL;
+ GENERAL_NAME *gen = NULL;
+
+ if (princs_ret != NULL)
+ *princs_ret = NULL;
+ if (upn_ret != NULL)
+ *upn_ret = NULL;
+ if (dns_ret != NULL)
+ *dns_ret = NULL;
if (princs_ret == NULL && upn_ret == NULL && dns_ret == NULL) {
pkiDebug("%s: nowhere to return any values!\n", __FUNCTION__);
@@ -2121,118 +2131,112 @@ crypto_retrieve_X509_sans(krb5_context context,
buf, sizeof(buf));
pkiDebug("%s: looking for SANs in cert = %s\n", __FUNCTION__, buf);
- if ((l = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1)) >= 0) {
- X509_EXTENSION *ext = NULL;
- GENERAL_NAMES *ialt = NULL;
- GENERAL_NAME *gen = NULL;
- int ret = 0;
- unsigned int num_sans = 0;
+ l = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
+ if (l < 0)
+ return 0;
- if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) {
- pkiDebug("%s: found no subject alt name extensions\n",
- __FUNCTION__);
+ if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) {
+ pkiDebug("%s: found no subject alt name extensions\n", __FUNCTION__);
+ goto cleanup;
+ }
+ num_sans = sk_GENERAL_NAME_num(ialt);
+
+ pkiDebug("%s: found %d subject alt name extension(s)\n", __FUNCTION__,
+ num_sans);
+
+ /* OK, we're likely returning something. Allocate return values */
+ if (princs_ret != NULL) {
+ princs = calloc(num_sans + 1, sizeof(krb5_principal));
+ if (princs == NULL) {
+ retval = ENOMEM;
goto cleanup;
}
- num_sans = sk_GENERAL_NAME_num(ialt);
-
- pkiDebug("%s: found %d subject alt name extension(s)\n",
- __FUNCTION__, num_sans);
-
- /* OK, we're likely returning something. Allocate return values */
- if (princs_ret != NULL) {
- princs = calloc(num_sans + 1, sizeof(krb5_principal));
- if (princs == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
- }
- if (upn_ret != NULL) {
- upns = calloc(num_sans + 1, sizeof(krb5_principal));
- if (upns == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
- }
- if (dns_ret != NULL) {
- dnss = calloc(num_sans + 1, sizeof(*dnss));
- if (dnss == NULL) {
- retval = ENOMEM;
- goto cleanup;
- }
- }
-
- for (i = 0; i < num_sans; i++) {
- krb5_data name = { 0, 0, NULL };
-
- gen = sk_GENERAL_NAME_value(ialt, i);
- switch (gen->type) {
- case GEN_OTHERNAME:
- name.length = gen->d.otherName->value->value.sequence->length;
- name.data = (char *)gen->d.otherName->value->value.sequence->data;
- if (princs != NULL
- && OBJ_cmp(plgctx->id_pkinit_san,
- gen->d.otherName->type_id) == 0) {
-#ifdef DEBUG_ASN1
- print_buffer_bin((unsigned char *)name.data, name.length,
- "/tmp/pkinit_san");
-#endif
- ret = k5int_decode_krb5_principal_name(&name, &princs[p]);
- if (ret) {
- pkiDebug("%s: failed decoding pkinit san value\n",
- __FUNCTION__);
- } else {
- p++;
- num_found++;
- }
- } else if (upns != NULL
- && OBJ_cmp(plgctx->id_ms_san_upn,
- gen->d.otherName->type_id) == 0) {
- /* Prevent abuse of embedded null characters. */
- if (memchr(name.data, '\0', name.length))
- break;
- ret = krb5_parse_name_flags(context, name.data,
- KRB5_PRINCIPAL_PARSE_ENTERPRISE,
- &upns[u]);
- if (ret) {
- pkiDebug("%s: failed parsing ms-upn san value\n",
- __FUNCTION__);
- } else {
- u++;
- num_found++;
- }
- } else {
- pkiDebug("%s: unrecognized othername oid in SAN\n",
- __FUNCTION__);
- continue;
- }
-
- break;
- case GEN_DNS:
- if (dnss != NULL) {
- /* Prevent abuse of embedded null characters. */
- if (memchr(gen->d.dNSName->data, '\0',
- gen->d.dNSName->length))
- break;
- pkiDebug("%s: found dns name = %s\n",
- __FUNCTION__, gen->d.dNSName->data);
- dnss[d] = (unsigned char *)
- strdup((char *)gen->d.dNSName->data);
- if (dnss[d] == NULL) {
- pkiDebug("%s: failed to duplicate dns name\n",
- __FUNCTION__);
- } else {
- d++;
- num_found++;
- }
- }
- break;
- default:
- pkiDebug("%s: SAN type = %d expecting %d\n",
- __FUNCTION__, gen->type, GEN_OTHERNAME);
- }
- }
- sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
}
+ if (upn_ret != NULL) {
+ upns = calloc(num_sans + 1, sizeof(krb5_principal));
+ if (upns == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
+ if (dns_ret != NULL) {
+ dnss = calloc(num_sans + 1, sizeof(*dnss));
+ if (dnss == NULL) {
+ retval = ENOMEM;
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < num_sans; i++) {
+ krb5_data name = { 0, 0, NULL };
+
+ gen = sk_GENERAL_NAME_value(ialt, i);
+ switch (gen->type) {
+ case GEN_OTHERNAME:
+ name.length = gen->d.otherName->value->value.sequence->length;
+ name.data = (char *)gen->d.otherName->value->value.sequence->data;
+ if (princs != NULL &&
+ OBJ_cmp(plgctx->id_pkinit_san,
+ gen->d.otherName->type_id) == 0) {
+#ifdef DEBUG_ASN1
+ print_buffer_bin((unsigned char *)name.data, name.length,
+ "/tmp/pkinit_san");
+#endif
+ ret = k5int_decode_krb5_principal_name(&name, &princs[p]);
+ if (ret) {
+ pkiDebug("%s: failed decoding pkinit san value\n",
+ __FUNCTION__);
+ } else {
+ p++;
+ num_found++;
+ }
+ } else if (upns != NULL &&
+ OBJ_cmp(plgctx->id_ms_san_upn,
+ gen->d.otherName->type_id) == 0) {
+ /* Prevent abuse of embedded null characters. */
+ if (memchr(name.data, '\0', name.length))
+ break;
+ ret = krb5_parse_name_flags(context, name.data,
+ KRB5_PRINCIPAL_PARSE_ENTERPRISE,
+ &upns[u]);
+ if (ret) {
+ pkiDebug("%s: failed parsing ms-upn san value\n",
+ __FUNCTION__);
+ } else {
+ u++;
+ num_found++;
+ }
+ } else {
+ pkiDebug("%s: unrecognized othername oid in SAN\n",
+ __FUNCTION__);
+ continue;
+ }
+
+ break;
+ case GEN_DNS:
+ if (dnss != NULL) {
+ /* Prevent abuse of embedded null characters. */
+ if (memchr(gen->d.dNSName->data, '\0', gen->d.dNSName->length))
+ break;
+ pkiDebug("%s: found dns name = %s\n", __FUNCTION__,
+ gen->d.dNSName->data);
+ dnss[d] = (unsigned char *)
+ strdup((char *)gen->d.dNSName->data);
+ if (dnss[d] == NULL) {
+ pkiDebug("%s: failed to duplicate dns name\n",
+ __FUNCTION__);
+ } else {
+ d++;
+ num_found++;
+ }
+ }
+ break;
+ default:
+ pkiDebug("%s: SAN type = %d expecting %d\n", __FUNCTION__,
+ gen->type, GEN_OTHERNAME);
+ }
+ }
+ sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
retval = 0;
if (princs)

View File

@ -1,130 +0,0 @@
From c8c704cdaaa15a0908024f0917344048c0df5940 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 19 Aug 2017 19:09:24 -0400
Subject: [PATCH] Fix bugs in kdcpolicy commit
Commit d0969f6a8170344031ef58fd2a161190f1edfb96 added tests using
"klist ccachname -e", which does not work with a POSIX-conformant
getopt() implementation such as the one in Solaris. Fix
t_kdcpolicy.py to use "klist -e ccachename" instead.
The tests could fail if the clock second rolled over between kinit and
kvno. Divide service ticket maximum lifetimes by 2 in the test module
to correctly exercise TGS policy restrictions and ensure that service
tickets are not constrained by the TGT end time.
Also use the correct trace macro when a kdcpolicy module declines to
initialize (my mistake when revising the commit, noted by rharwood).
ticket: 8606
(cherry picked from commit 09acbd91efc6df54e1572285ffc94c6acb3a9113)
---
src/kdc/policy.c | 2 +-
src/plugins/kdcpolicy/test/main.c | 10 +++++-----
src/tests/t_kdcpolicy.py | 13 +++++++++----
3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/src/kdc/policy.c b/src/kdc/policy.c
index e49644e06..26c16f97c 100644
--- a/src/kdc/policy.c
+++ b/src/kdc/policy.c
@@ -222,7 +222,7 @@ load_kdcpolicy_plugins(krb5_context context)
if (h->vt.init != NULL) {
ret = h->vt.init(context, &h->moddata);
if (ret == KRB5_PLUGIN_NO_HANDLE) {
- TRACE_KADM5_AUTH_INIT_SKIP(context, h->vt.name);
+ TRACE_KDCPOLICY_INIT_SKIP(context, h->vt.name);
free(h);
continue;
}
diff --git a/src/plugins/kdcpolicy/test/main.c b/src/plugins/kdcpolicy/test/main.c
index eb8fde053..86c808958 100644
--- a/src/plugins/kdcpolicy/test/main.c
+++ b/src/plugins/kdcpolicy/test/main.c
@@ -35,7 +35,7 @@
#include <krb5/kdcpolicy_plugin.h>
static krb5_error_code
-output_from_indicator(const char *const *auth_indicators,
+output_from_indicator(const char *const *auth_indicators, int divisor,
krb5_deltat *lifetime_out,
krb5_deltat *renew_lifetime_out,
const char **status)
@@ -46,11 +46,11 @@ output_from_indicator(const char *const *auth_indicators,
}
if (strcmp(auth_indicators[0], "ONE_HOUR") == 0) {
- *lifetime_out = 3600;
+ *lifetime_out = 3600 / divisor;
*renew_lifetime_out = *lifetime_out * 2;
return 0;
} else if (strcmp(auth_indicators[0], "SEVEN_HOURS") == 0) {
- *lifetime_out = 7 * 3600;
+ *lifetime_out = 7 * 3600 / divisor;
*renew_lifetime_out = *lifetime_out * 2;
return 0;
}
@@ -71,7 +71,7 @@ test_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
*status = "LOCAL_POLICY";
return KRB5KDC_ERR_POLICY;
}
- return output_from_indicator(auth_indicators, lifetime_out,
+ return output_from_indicator(auth_indicators, 1, lifetime_out,
renew_lifetime_out, status);
}
@@ -87,7 +87,7 @@ test_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata,
*status = "LOCAL_POLICY";
return KRB5KDC_ERR_POLICY;
}
- return output_from_indicator(auth_indicators, lifetime_out,
+ return output_from_indicator(auth_indicators, 2, lifetime_out,
renew_lifetime_out, status);
}
diff --git a/src/tests/t_kdcpolicy.py b/src/tests/t_kdcpolicy.py
index 6a745b959..b5d308461 100644
--- a/src/tests/t_kdcpolicy.py
+++ b/src/tests/t_kdcpolicy.py
@@ -18,16 +18,21 @@ realm.run([kadminl, 'addprinc', '-pw', password('fail'), 'fail'])
def verify_time(out, target_time):
times = re.findall(r'\d\d/\d\d/\d\d \d\d:\d\d:\d\d', out)
times = [datetime.strptime(t, '%m/%d/%y %H:%M:%S') for t in times]
+ divisor = 1
while len(times) > 0:
starttime = times.pop(0)
endtime = times.pop(0)
renewtime = times.pop(0)
- if str(endtime - starttime) != target_time:
+ if str((endtime - starttime) * divisor) != target_time:
fail('unexpected lifetime value')
- if str(renewtime - endtime) != target_time:
+ if str((renewtime - endtime) * divisor) != target_time:
fail('unexpected renewable value')
+ # Service tickets should have half the lifetime of initial
+ # tickets.
+ divisor = 2
+
rflags = ['-r', '1d', '-l', '12h']
# Test AS+TGS success path.
@@ -35,7 +40,7 @@ realm.kinit(realm.user_princ, password('user'),
rflags + ['-X', 'indicators=SEVEN_HOURS'])
realm.run([kvno, realm.host_princ])
realm.run(['./adata', realm.host_princ], expected_msg='+97: [SEVEN_HOURS]')
-out = realm.run([klist, realm.ccache, '-e'])
+out = realm.run([klist, '-e', realm.ccache])
verify_time(out, '7:00:00')
# Test AS+TGS success path with different values.
@@ -43,7 +48,7 @@ realm.kinit(realm.user_princ, password('user'),
rflags + ['-X', 'indicators=ONE_HOUR'])
realm.run([kvno, realm.host_princ])
realm.run(['./adata', realm.host_princ], expected_msg='+97: [ONE_HOUR]')
-out = realm.run([klist, realm.ccache, '-e'])
+out = realm.run([klist, '-e', realm.ccache])
verify_time(out, '1:00:00')
# Test TGS failure path (using previous creds).

View File

@ -1,124 +0,0 @@
From 0d93e336e2cb8319bfd3e0fa096e5ee8ea3bbbbf Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 24 Aug 2017 11:11:46 -0400
Subject: [PATCH] Fix certauth built-in module returns
The PKINIT certauth eku module should never authoritatively authorize
a certificate, because an extended key usage does not establish a
relationship between the certificate and any specific user; it only
establishes that the certificate was created for PKINIT client
authentication. Therefore, pkinit_eku_authorize() should return
KRB5_PLUGIN_NO_HANDLE on success, not 0.
The certauth san module should pass if it does not find any SANs of
the types it can match against; the presence of other types of SANs
should not cause it to explicitly deny a certificate. Check for an
empty result from crypto_retrieve_cert_sans() in verify_client_san(),
instead of returning ENOENT from crypto_retrieve_cert_sans() when
there are no SANs at all.
ticket: 8561
(cherry picked from commit 07243f85a760fb37f0622d7ff0177db3f19ab025)
---
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 39 ++++++++++------------
src/plugins/preauth/pkinit/pkinit_srv.c | 14 +++++---
2 files changed, 27 insertions(+), 26 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 70e230ec2..7fa2efd21 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -2137,7 +2137,6 @@ crypto_retrieve_X509_sans(krb5_context context,
if (!(ext = X509_get_ext(cert, l)) || !(ialt = X509V3_EXT_d2i(ext))) {
pkiDebug("%s: found no subject alt name extensions\n", __FUNCTION__);
- retval = ENOENT;
goto cleanup;
}
num_sans = sk_GENERAL_NAME_num(ialt);
@@ -2240,31 +2239,29 @@ crypto_retrieve_X509_sans(krb5_context context,
sk_GENERAL_NAME_pop_free(ialt, GENERAL_NAME_free);
retval = 0;
- if (princs)
+ if (princs != NULL && *princs != NULL) {
*princs_ret = princs;
- if (upns)
+ princs = NULL;
+ }
+ if (upns != NULL && *upns != NULL) {
*upn_ret = upns;
- if (dnss)
+ upns = NULL;
+ }
+ if (dnss != NULL && *dnss != NULL) {
*dns_ret = dnss;
+ dnss = NULL;
+ }
cleanup:
- if (retval) {
- if (princs != NULL) {
- for (i = 0; princs[i] != NULL; i++)
- krb5_free_principal(context, princs[i]);
- free(princs);
- }
- if (upns != NULL) {
- for (i = 0; upns[i] != NULL; i++)
- krb5_free_principal(context, upns[i]);
- free(upns);
- }
- if (dnss != NULL) {
- for (i = 0; dnss[i] != NULL; i++)
- free(dnss[i]);
- free(dnss);
- }
- }
+ for (i = 0; princs != NULL && princs[i] != NULL; i++)
+ krb5_free_principal(context, princs[i]);
+ free(princs);
+ for (i = 0; upns != NULL && upns[i] != NULL; i++)
+ krb5_free_principal(context, upns[i]);
+ free(upns);
+ for (i = 0; dnss != NULL && dnss[i] != NULL; i++)
+ free(dnss[i]);
+ free(dnss);
return retval;
}
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index 9c6e96c9e..8e77606f8 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -187,14 +187,18 @@ verify_client_san(krb5_context context,
&princs,
plgctx->opts->allow_upn ? &upns : NULL,
NULL);
- if (retval == ENOENT) {
- TRACE_PKINIT_SERVER_NO_SAN(context);
- goto out;
- } else if (retval) {
+ if (retval) {
pkiDebug("%s: error from retrieve_certificate_sans()\n", __FUNCTION__);
retval = KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
goto out;
}
+
+ if (princs == NULL && upns == NULL) {
+ TRACE_PKINIT_SERVER_NO_SAN(context);
+ retval = ENOENT;
+ goto out;
+ }
+
/* XXX Verify this is consistent with client side XXX */
#if 0
retval = call_san_checking_plugins(context, plgctx, reqctx, princs,
@@ -1495,7 +1499,7 @@ pkinit_eku_authorize(krb5_context context, krb5_certauth_moddata moddata,
return KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE;
}
- return 0;
+ return KRB5_PLUGIN_NO_HANDLE;
}
static krb5_error_code

View File

@ -1,58 +0,0 @@
From e2d34698687c00504b83e1c0deb56dc6232bef42 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 24 Apr 2017 02:02:36 -0400
Subject: [PATCH] Fix in_clock_skew() and use it in AS client code
Add a context parameter to the in_clock_skew() macro so that it isn't
implicitly relying on a local variable. Use it in
get_in_tkt.c:verify_as_reply().
(cherry picked from commit 28a07a6461bb443b7fa75cc5cb859ad0db4cbb5a)
---
src/lib/krb5/krb/gc_via_tkt.c | 2 +-
src/lib/krb5/krb/get_in_tkt.c | 4 ++--
src/lib/krb5/krb/int-proto.h | 3 ++-
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c
index 4c0a1a461..c85d8b8d8 100644
--- a/src/lib/krb5/krb/gc_via_tkt.c
+++ b/src/lib/krb5/krb/gc_via_tkt.c
@@ -305,7 +305,7 @@ krb5int_process_tgs_reply(krb5_context context,
goto cleanup;
if (!in_cred->times.starttime &&
- !in_clock_skew(dec_rep->enc_part2->times.starttime,
+ !in_clock_skew(context, dec_rep->enc_part2->times.starttime,
timestamp)) {
retval = KRB5_KDCREP_SKEW;
goto cleanup;
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 54badbbc3..a058f5bd7 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -287,8 +287,8 @@ verify_as_reply(krb5_context context,
return retval;
} else {
if ((request->from == 0) &&
- (labs(as_reply->enc_part2->times.starttime - time_now)
- > context->clockskew))
+ !in_clock_skew(context, as_reply->enc_part2->times.starttime,
+ time_now))
return (KRB5_KDCREP_SKEW);
}
return 0;
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
index 6da74858e..44eca359f 100644
--- a/src/lib/krb5/krb/int-proto.h
+++ b/src/lib/krb5/krb/int-proto.h
@@ -83,7 +83,8 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options,
krb5_creds *in_creds, krb5_creds *mcreds,
krb5_flags *fields);
-#define in_clock_skew(date, now) (labs((date)-(now)) < context->clockskew)
+#define in_clock_skew(context, date, now) \
+ (labs((date) - (now)) < (context)->clockskew)
#define IS_TGS_PRINC(p) ((p)->length == 2 && \
data_eq_string((p)->data[0], KRB5_TGS_NAME))

View File

@ -1,83 +0,0 @@
From 7b28a408650c58d0ea98fddab5034642af32fdaf Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 17 May 2017 14:52:09 -0400
Subject: [PATCH] Fix more time manipulations for y2038
Use timestamp helper functions to ensure that more operations are safe
after y2038, and display the current timestamp as unsigned in
krb5int_trace().
ticket: 8352
(cherry picked from commit a60db180211a383bd382afe729e9309acb8dcf53)
---
src/kadmin/server/misc.c | 2 +-
src/kdc/dispatch.c | 2 +-
src/lib/krb5/os/c_ustime.c | 8 ++++----
src/lib/krb5/os/trace.c | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/kadmin/server/misc.c b/src/kadmin/server/misc.c
index 27a6376af..a75b65a26 100644
--- a/src/kadmin/server/misc.c
+++ b/src/kadmin/server/misc.c
@@ -184,7 +184,7 @@ check_min_life(void *server_handle, krb5_principal principal,
(void) kadm5_free_principal_ent(handle->lhandle, &princ);
return (ret == KADM5_UNK_POLICY) ? 0 : ret;
}
- if((now - princ.last_pwd_change) < pol.pw_min_life &&
+ if(ts_delta(now, princ.last_pwd_change) < pol.pw_min_life &&
!(princ.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) {
if (msg_ret != NULL) {
time_t until;
diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c
index 3a169ebc7..16a35d2be 100644
--- a/src/kdc/dispatch.c
+++ b/src/kdc/dispatch.c
@@ -104,7 +104,7 @@ reseed_random(krb5_context kdc_err_context)
if (last_os_random == 0)
last_os_random = now;
/* Grab random data from OS every hour*/
- if (now-last_os_random >= 60 * 60) {
+ if (ts_delta(now, last_os_random) >= 60 * 60) {
krb5_c_random_os_entropy(kdc_err_context, 0, NULL);
last_os_random = now;
}
diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c
index 871d72183..68fb381f4 100644
--- a/src/lib/krb5/os/c_ustime.c
+++ b/src/lib/krb5/os/c_ustime.c
@@ -102,17 +102,17 @@ krb5_crypto_us_timeofday(krb5_int32 *seconds, krb5_int32 *microseconds)
putting now.sec in the past. But don't just use '<' because we
need to properly handle the case where the administrator intentionally
adjusted time backwards. */
- if ((now.sec == last_time.sec-1) ||
- ((now.sec == last_time.sec) && (now.usec <= last_time.usec))) {
+ if (now.sec == ts_incr(last_time.sec, -1) ||
+ (now.sec == last_time.sec && !ts_after(last_time.usec, now.usec))) {
/* Correct 'now' to be exactly one microsecond later than 'last_time'.
Note that _because_ we perform this hack, 'now' may be _earlier_
than 'last_time', even though the system time is monotonically
increasing. */
now.sec = last_time.sec;
- now.usec = ++last_time.usec;
+ now.usec = ts_incr(last_time.usec, 1);
if (now.usec >= 1000000) {
- ++now.sec;
+ now.sec = ts_incr(now.sec, 1);
now.usec = 0;
}
}
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
index a19246128..74c315c90 100644
--- a/src/lib/krb5/os/trace.c
+++ b/src/lib/krb5/os/trace.c
@@ -350,7 +350,7 @@ krb5int_trace(krb5_context context, const char *fmt, ...)
goto cleanup;
if (krb5_crypto_us_timeofday(&sec, &usec) != 0)
goto cleanup;
- if (asprintf(&msg, "[%d] %d.%d: %s\n", (int) getpid(), (int) sec,
+ if (asprintf(&msg, "[%d] %u.%d: %s\n", (int) getpid(), (unsigned int) sec,
(int) usec, str) < 0)
goto cleanup;
info.message = msg;

View File

@ -1,151 +0,0 @@
From 03265620488b84238c31170356b5f41c80f0e9d9 Mon Sep 17 00:00:00 2001
From: Matt Rogers <mrogers@redhat.com>
Date: Mon, 5 Dec 2016 12:17:59 -0500
Subject: [PATCH] Improve PKINIT UPN SAN matching
Add the match_client() kdcpreauth callback and use it in
verify_client_san(). match_client() preserves the direct UPN to
request principal comparison and adds a direct comparison to the
client principal, falling back to an alias DB search and comparison
against the client principal. Change crypto_retreive_X509_sans() to
parse UPN values as enterprise principals.
[ghudson@mit.edu: use match_client for both kinds of SANs]
ticket: 8528 (new)
(cherry picked from commit 46ff765e1fb8cbec2bb602b43311269e695dbedc)
---
src/include/krb5/kdcpreauth_plugin.h | 13 ++++++++++
src/kdc/kdc_preauth.c | 28 ++++++++++++++++++++--
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 4 +++-
src/plugins/preauth/pkinit/pkinit_srv.c | 10 ++++----
4 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h
index f455effae..92aa5a5a5 100644
--- a/src/include/krb5/kdcpreauth_plugin.h
+++ b/src/include/krb5/kdcpreauth_plugin.h
@@ -221,6 +221,19 @@ typedef struct krb5_kdcpreauth_callbacks_st {
/* End of version 3 kdcpreauth callbacks. */
+ /*
+ * Return true if princ matches the principal named in the request or the
+ * client principal (possibly canonicalized). If princ does not match,
+ * attempt a database lookup of princ with aliases allowed and compare the
+ * result to the client principal, returning true if it matches.
+ * Otherwise, return false.
+ */
+ krb5_boolean (*match_client)(krb5_context context,
+ krb5_kdcpreauth_rock rock,
+ krb5_principal princ);
+
+ /* End of version 4 kdcpreauth callbacks. */
+
} *krb5_kdcpreauth_callbacks;
/* Optional: preauth plugin initialization function. */
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 605fcb7ad..0ce79c667 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -568,8 +568,31 @@ set_cookie(krb5_context context, krb5_kdcpreauth_rock rock,
return kdc_fast_set_cookie(rock->rstate, pa_type, data);
}
+static krb5_boolean
+match_client(krb5_context context, krb5_kdcpreauth_rock rock,
+ krb5_principal princ)
+{
+ krb5_db_entry *ent;
+ krb5_boolean match = FALSE;
+ krb5_principal req_client = rock->request->client;
+ krb5_principal client = rock->client->princ;
+
+ /* Check for a direct match against the request principal or
+ * the post-canon client principal. */
+ if (krb5_principal_compare_flags(context, princ, req_client,
+ KRB5_PRINCIPAL_COMPARE_ENTERPRISE) ||
+ krb5_principal_compare(context, princ, client))
+ return TRUE;
+
+ if (krb5_db_get_principal(context, princ, KRB5_KDB_FLAG_ALIAS_OK, &ent))
+ return FALSE;
+ match = krb5_principal_compare(context, ent->princ, client);
+ krb5_db_free_principal(context, ent);
+ return match;
+}
+
static struct krb5_kdcpreauth_callbacks_st callbacks = {
- 3,
+ 4,
max_time_skew,
client_keys,
free_keys,
@@ -583,7 +606,8 @@ static struct krb5_kdcpreauth_callbacks_st callbacks = {
client_keyblock,
add_auth_indicator,
get_cookie,
- set_cookie
+ set_cookie,
+ match_client
};
static krb5_error_code
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 74fffbf32..bc6e7662e 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -2190,7 +2190,9 @@ crypto_retrieve_X509_sans(krb5_context context,
/* Prevent abuse of embedded null characters. */
if (memchr(name.data, '\0', name.length))
break;
- ret = krb5_parse_name(context, name.data, &upns[u]);
+ ret = krb5_parse_name_flags(context, name.data,
+ KRB5_PRINCIPAL_PARSE_ENTERPRISE,
+ &upns[u]);
if (ret) {
pkiDebug("%s: failed parsing ms-upn san value\n",
__FUNCTION__);
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index 295be25e1..b5638a367 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -121,6 +121,8 @@ static krb5_error_code
verify_client_san(krb5_context context,
pkinit_kdc_context plgctx,
pkinit_kdc_req_context reqctx,
+ krb5_kdcpreauth_callbacks cb,
+ krb5_kdcpreauth_rock rock,
krb5_principal client,
int *valid_san)
{
@@ -171,7 +173,7 @@ verify_client_san(krb5_context context,
__FUNCTION__, client_string, san_string);
krb5_free_unparsed_name(context, san_string);
#endif
- if (krb5_principal_compare(context, princs[i], client)) {
+ if (cb->match_client(context, rock, princs[i])) {
pkiDebug("%s: pkinit san match found\n", __FUNCTION__);
*valid_san = 1;
retval = 0;
@@ -199,7 +201,7 @@ verify_client_san(krb5_context context,
__FUNCTION__, client_string, san_string);
krb5_free_unparsed_name(context, san_string);
#endif
- if (krb5_principal_compare(context, upns[i], client)) {
+ if (cb->match_client(context, rock, upns[i])) {
pkiDebug("%s: upn san match found\n", __FUNCTION__);
*valid_san = 1;
retval = 0;
@@ -387,8 +389,8 @@ pkinit_server_verify_padata(krb5_context context,
}
if (is_signed) {
- retval = verify_client_san(context, plgctx, reqctx, request->client,
- &valid_san);
+ retval = verify_client_san(context, plgctx, reqctx, cb, rock,
+ request->client, &valid_san);
if (retval)
goto cleanup;
if (!valid_san) {

File diff suppressed because it is too large Load Diff

View File

@ -1,134 +0,0 @@
From 466d09c9b2c456d663672cb6d5f661ef86e8536e Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Mon, 31 Jul 2017 16:03:41 -0400
Subject: [PATCH] Remove incomplete PKINIT OCSP support
pkinit_kdc_ocsp is non-functional in the PKINIT OpenSSL crypto
implementation, so remove most traces of it, including its man page
entry. If it is present in kdc.conf, error out of PKINIT
initialization instead of silently ignoring the realm entirely.
ticket: 8603 (new)
(cherry picked from commit 3ff426b9048a8024e5c175256c63cd0ad0572320)
---
doc/admin/conf_files/kdc_conf.rst | 3 ---
src/man/kdc.conf.man | 3 ---
src/plugins/preauth/pkinit/pkinit.h | 2 +-
src/plugins/preauth/pkinit/pkinit_identity.c | 11 -----------
src/plugins/preauth/pkinit/pkinit_srv.c | 12 ++++++++++--
5 files changed, 11 insertions(+), 20 deletions(-)
diff --git a/doc/admin/conf_files/kdc_conf.rst b/doc/admin/conf_files/kdc_conf.rst
index 4e54f7e1d..d00e7926c 100644
--- a/doc/admin/conf_files/kdc_conf.rst
+++ b/doc/admin/conf_files/kdc_conf.rst
@@ -765,9 +765,6 @@ For information about the syntax of some of these options, see
pkinit is used to authenticate. This option may be specified
multiple times. (New in release 1.14.)
-**pkinit_kdc_ocsp**
- Specifies the location of the KDC's OCSP.
-
**pkinit_pool**
Specifies the location of intermediate certificates which may be
used by the KDC to complete the trust chain between a client's
diff --git a/src/man/kdc.conf.man b/src/man/kdc.conf.man
index d207ebd7f..c47da0117 100644
--- a/src/man/kdc.conf.man
+++ b/src/man/kdc.conf.man
@@ -886,9 +886,6 @@ Specifies an authentication indicator to include in the ticket if
pkinit is used to authenticate. This option may be specified
multiple times. (New in release 1.14.)
.TP
-.B \fBpkinit_kdc_ocsp\fP
-Specifies the location of the KDC\(aqs OCSP.
-.TP
.B \fBpkinit_pool\fP
Specifies the location of intermediate certificates which may be
used by the KDC to complete the trust chain between a client\(aqs
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
index 876db94c3..a49f3078e 100644
--- a/src/plugins/preauth/pkinit/pkinit.h
+++ b/src/plugins/preauth/pkinit/pkinit.h
@@ -73,6 +73,7 @@
#define KRB5_CONF_PKINIT_IDENTITIES "pkinit_identities"
#define KRB5_CONF_PKINIT_IDENTITY "pkinit_identity"
#define KRB5_CONF_PKINIT_KDC_HOSTNAME "pkinit_kdc_hostname"
+/* pkinit_kdc_ocsp has been removed */
#define KRB5_CONF_PKINIT_KDC_OCSP "pkinit_kdc_ocsp"
#define KRB5_CONF_PKINIT_POOL "pkinit_pool"
#define KRB5_CONF_PKINIT_REQUIRE_CRL_CHECKING "pkinit_require_crl_checking"
@@ -173,7 +174,6 @@ typedef struct _pkinit_identity_opts {
char **anchors;
char **intermediates;
char **crls;
- char *ocsp;
int idtype;
char *cert_filename;
char *key_filename;
diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c
index 177a2cad8..a897efa25 100644
--- a/src/plugins/preauth/pkinit/pkinit_identity.c
+++ b/src/plugins/preauth/pkinit/pkinit_identity.c
@@ -125,7 +125,6 @@ pkinit_init_identity_opts(pkinit_identity_opts **idopts)
opts->anchors = NULL;
opts->intermediates = NULL;
opts->crls = NULL;
- opts->ocsp = NULL;
opts->cert_filename = NULL;
opts->key_filename = NULL;
@@ -174,12 +173,6 @@ pkinit_dup_identity_opts(pkinit_identity_opts *src_opts,
if (retval)
goto cleanup;
- if (src_opts->ocsp != NULL) {
- newopts->ocsp = strdup(src_opts->ocsp);
- if (newopts->ocsp == NULL)
- goto cleanup;
- }
-
if (src_opts->cert_filename != NULL) {
newopts->cert_filename = strdup(src_opts->cert_filename);
if (newopts->cert_filename == NULL)
@@ -674,10 +667,6 @@ pkinit_identity_prompt(krb5_context context,
if (retval)
goto errout;
}
- if (idopts->ocsp != NULL) {
- retval = ENOTSUP;
- goto errout;
- }
errout:
return retval;
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index 731d14eb8..32ca122f2 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -1252,7 +1252,7 @@ static krb5_error_code
pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx)
{
krb5_error_code retval;
- char *eku_string = NULL;
+ char *eku_string = NULL, *ocsp_check = NULL;
pkiDebug("%s: entered for realm %s\n", __FUNCTION__, plgctx->realmname);
retval = pkinit_kdcdefault_string(context, plgctx->realmname,
@@ -1287,7 +1287,15 @@ pkinit_init_kdc_profile(krb5_context context, pkinit_kdc_context plgctx)
pkinit_kdcdefault_string(context, plgctx->realmname,
KRB5_CONF_PKINIT_KDC_OCSP,
- &plgctx->idopts->ocsp);
+ &ocsp_check);
+ if (ocsp_check != NULL) {
+ free(ocsp_check);
+ retval = ENOTSUP;
+ krb5_set_error_message(context, retval,
+ _("OCSP is not supported: (realm: %s)"),
+ plgctx->realmname);
+ goto errout;
+ }
pkinit_kdcdefault_integer(context, plgctx->realmname,
KRB5_CONF_PKINIT_DH_MIN_BITS,

View File

@ -1,4 +1,4 @@
From 6d0b40b26e7fea1cd394618c1ab6d5e366bbc069 Mon Sep 17 00:00:00 2001
From 697f19c5bfd4470c167d35c7af43c82a32660b82 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 1 Mar 2017 17:46:22 -0500
Subject: [PATCH] Use GSSAPI fallback skiptest

File diff suppressed because it is too large Load Diff

View File

@ -1,75 +0,0 @@
From 35a00879008457d21ccc6e623835976a21f5000b Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 17 Jan 2017 11:25:22 -0500
Subject: [PATCH] Use expected_trace in test scripts
(cherry picked from commit 7b7e5d964e5d020fdda3fb9843d9b8cf8b29a6f8)
---
src/tests/t_general.py | 24 ++++++++----------------
src/tests/t_pkinit.py | 15 ++++++---------
2 files changed, 14 insertions(+), 25 deletions(-)
diff --git a/src/tests/t_general.py b/src/tests/t_general.py
index 6d523fe45..16bf6c5e3 100755
--- a/src/tests/t_general.py
+++ b/src/tests/t_general.py
@@ -47,21 +47,13 @@ if 'not found in Kerberos database' not in out:
fail('Expected error message not seen in kinit -C output')
# Spot-check KRB5_TRACE output
-tracefile = os.path.join(realm.testdir, 'trace')
-realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, realm.user_princ],
- input=(password('user') + "\n"))
-f = open(tracefile, 'r')
-trace = f.read()
-f.close()
-expected = ('Sending initial UDP request',
- 'Received answer',
- 'Selected etype info',
- 'AS key obtained',
- 'Decrypted AS reply',
- 'FAST negotiation: available',
- 'Storing user@KRBTEST.COM')
-for e in expected:
- if e not in trace:
- fail('Expected output not in kinit trace log')
+expected_trace = ('Sending initial UDP request',
+ 'Received answer',
+ 'Selected etype info',
+ 'AS key obtained',
+ 'Decrypted AS reply',
+ 'FAST negotiation: available',
+ 'Storing user@KRBTEST.COM')
+realm.kinit(realm.user_princ, password('user'), expected_trace=expected_trace)
success('FAST kinit, trace logging')
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index 183977750..f56141564 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -176,19 +176,16 @@ realm.klist(realm.user_princ)
# Test a DH parameter renegotiation by temporarily setting a 4096-bit
# minimum on the KDC.
-tracefile = os.path.join(realm.testdir, 'trace')
minbits_kdc_conf = {'realms': {'$realm': {'pkinit_dh_min_bits': '4096'}}}
minbits_env = realm.special_env('restrict', True, kdc_conf=minbits_kdc_conf)
realm.stop_kdc()
realm.start_kdc(env=minbits_env)
-realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-X',
- 'X509_user_identity=' + file_identity, realm.user_princ])
-with open(tracefile, 'r') as f:
- trace = f.read()
-if ('Key parameters not accepted' not in trace or
- 'Preauth tryagain input types' not in trace or
- 'trying again with KDC-provided parameters' not in trace):
- fail('DH renegotiation steps not found in kinit trace log')
+expected_trace = ('Key parameters not accepted',
+ 'Preauth tryagain input types',
+ 'trying again with KDC-provided parameters')
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % file_identity],
+ expected_trace=expected_trace)
realm.stop_kdc()
realm.start_kdc()

View File

@ -1,185 +0,0 @@
From feee4c633a7db348ef99f1f0c99a5c2e6cb70f92 Mon Sep 17 00:00:00 2001
From: Matt Rogers <mrogers@redhat.com>
Date: Fri, 10 Feb 2017 12:53:42 -0500
Subject: [PATCH] Use fallback realm for GSSAPI ccache selection
In krb5_cc_select(), if the server principal has an empty realm, use
krb5_get_fallback_host_realm() and set the server realm to the first
fallback found. This helps with the selection of a non-default ccache
when there is no [domain_realms] configuration for the server domain.
Modify t_ccselect.py tests to account for fallback behavior.
ticket: 8549 (new)
(cherry picked from commit 234b64bd6139d5b75dadd5abbd5bef5a162e298a)
---
src/lib/krb5/ccache/ccselect.c | 37 ++++++++++++++++++++++++++-----
src/tests/gssapi/t_ccselect.py | 50 +++++++++++++++++++++++++++++++++---------
2 files changed, 72 insertions(+), 15 deletions(-)
diff --git a/src/lib/krb5/ccache/ccselect.c b/src/lib/krb5/ccache/ccselect.c
index 2f3071a27..ee4b83a9b 100644
--- a/src/lib/krb5/ccache/ccselect.c
+++ b/src/lib/krb5/ccache/ccselect.c
@@ -132,6 +132,8 @@ krb5_cc_select(krb5_context context, krb5_principal server,
struct ccselect_module_handle **hp, *h;
krb5_ccache cache;
krb5_principal princ;
+ krb5_principal srvcp = NULL;
+ char **fbrealms = NULL;
*cache_out = NULL;
*princ_out = NULL;
@@ -139,7 +141,27 @@ krb5_cc_select(krb5_context context, krb5_principal server,
if (context->ccselect_handles == NULL) {
ret = load_modules(context);
if (ret)
- return ret;
+ goto cleanup;
+ }
+
+ /* Try to use the fallback host realm for the server if there is no
+ * authoritative realm. */
+ if (krb5_is_referral_realm(&server->realm) &&
+ server->type == KRB5_NT_SRV_HST && server->length == 2) {
+ ret = krb5_get_fallback_host_realm(context, &server->data[1],
+ &fbrealms);
+ if (ret)
+ goto cleanup;
+
+ /* Make a copy with the first fallback realm. */
+ ret = krb5_copy_principal(context, server, &srvcp);
+ if (ret)
+ goto cleanup;
+ ret = krb5_set_principal_realm(context, srvcp, fbrealms[0]);
+ if (ret)
+ goto cleanup;
+
+ server = srvcp;
}
/* Consult authoritative modules first, then heuristic ones. */
@@ -155,20 +177,25 @@ krb5_cc_select(krb5_context context, krb5_principal server,
princ);
*cache_out = cache;
*princ_out = princ;
- return 0;
+ goto cleanup;
} else if (ret == KRB5_CC_NOTFOUND) {
TRACE_CCSELECT_MODNOTFOUND(context, h->vt.name, server, princ);
*princ_out = princ;
- return ret;
+ goto cleanup;
} else if (ret != KRB5_PLUGIN_NO_HANDLE) {
TRACE_CCSELECT_MODFAIL(context, h->vt.name, ret, server);
- return ret;
+ goto cleanup;
}
}
}
TRACE_CCSELECT_NOTFOUND(context, server);
- return KRB5_CC_NOTFOUND;
+ ret = KRB5_CC_NOTFOUND;
+
+cleanup:
+ krb5_free_principal(context, srvcp);
+ krb5_free_host_realm(context, fbrealms);
+ return ret;
}
void
diff --git a/src/tests/gssapi/t_ccselect.py b/src/tests/gssapi/t_ccselect.py
index 1ea614d30..668a2cc62 100755
--- a/src/tests/gssapi/t_ccselect.py
+++ b/src/tests/gssapi/t_ccselect.py
@@ -31,12 +31,18 @@ r2 = K5Realm(create_user=False, realm='KRBTEST2.COM', portbase=62000,
host1 = 'p:' + r1.host_princ
host2 = 'p:' + r2.host_princ
+foo = 'foo.krbtest.com'
+foo2 = 'foo.krbtest2.com'
-# gsserver specifies the target as a GSS name. The resulting
-# principal will have the host-based type, but the realm won't be
-# known before the client cache is selected (since k5test realms have
-# no domain-realm mapping by default).
-gssserver = 'h:host@' + hostname
+# These strings specify the target as a GSS name. The resulting
+# principal will have the host-based type, with the referral realm
+# (since k5test realms have no domain-realm mapping by default).
+# krb5_cc_select() will use the fallback realm, which is either the
+# uppercased parent domain, or the default realm if the hostname is a
+# single component.
+gssserver = 'h:host@' + foo
+gssserver2 = 'h:host@' + foo2
+gsslocal = 'h:host@localhost'
# refserver specifies the target as a principal in the referral realm.
# The principal won't be treated as a host principal by the
@@ -66,6 +72,16 @@ r1.addprinc(alice, password('alice'))
r1.addprinc(bob, password('bob'))
r2.addprinc(zaphod, password('zaphod'))
+# Create host principals and keytabs for fallback realm tests.
+r1.addprinc('host/localhost')
+r2.addprinc('host/localhost')
+r1.addprinc('host/' + foo)
+r2.addprinc('host/' + foo2)
+r1.extract_keytab('host/localhost', r1.keytab)
+r2.extract_keytab('host/localhost', r2.keytab)
+r1.extract_keytab('host/' + foo, r1.keytab)
+r2.extract_keytab('host/' + foo2, r2.keytab)
+
# Get tickets for one user in each realm (zaphod will be primary).
r1.kinit(alice, password('alice'))
r2.kinit(zaphod, password('zaphod'))
@@ -93,10 +109,24 @@ if output != (zaphod + '\n'):
fail('zaphod not chosen as default initiator name for server in r1')
# Check that primary cache is used if server realm is unknown.
-output = r2.run(['./t_ccselect', gssserver])
+output = r2.run(['./t_ccselect', refserver])
if output != (zaphod + '\n'):
fail('zaphod not chosen via primary cache for unknown server realm')
-r1.run(['./t_ccselect', gssserver], expected_code=1)
+r1.run(['./t_ccselect', gssserver2], expected_code=1)
+# Check ccache selection using a fallback realm.
+output = r1.run(['./t_ccselect', gssserver])
+if output != (alice + '\n'):
+ fail('alice not chosen via parent domain fallback')
+output = r2.run(['./t_ccselect', gssserver2])
+if output != (zaphod + '\n'):
+ fail('zaphod not chosen via parent domain fallback')
+# Check ccache selection using a fallback realm (default realm).
+output = r1.run(['./t_ccselect', gsslocal])
+if output != (alice + '\n'):
+ fail('alice not chosen via default realm fallback')
+output = r2.run(['./t_ccselect', gsslocal])
+if output != (zaphod + '\n'):
+ fail('zaphod not chosen via default realm fallback')
# Get a second cred in r1 (bob will be primary).
r1.kinit(bob, password('bob'))
@@ -104,19 +134,19 @@ r1.kinit(bob, password('bob'))
# Try some cache selections using .k5identity.
k5id = open(os.path.join(r1.testdir, '.k5identity'), 'w')
k5id.write('%s realm=%s\n' % (alice, r1.realm))
-k5id.write('%s service=ho*t host=%s\n' % (zaphod, hostname))
+k5id.write('%s service=ho*t host=localhost\n' % zaphod)
k5id.write('noprinc service=bogus')
k5id.close()
output = r1.run(['./t_ccselect', host1])
if output != (alice + '\n'):
fail('alice not chosen via .k5identity realm line.')
-output = r2.run(['./t_ccselect', gssserver])
+output = r2.run(['./t_ccselect', gsslocal])
if output != (zaphod + '\n'):
fail('zaphod not chosen via .k5identity service/host line.')
output = r1.run(['./t_ccselect', refserver])
if output != (bob + '\n'):
fail('bob not chosen via primary cache when no .k5identity line matches.')
-r1.run(['./t_ccselect', 'h:bogus@' + hostname], expected_code=1,
+r1.run(['./t_ccselect', 'h:bogus@' + foo2], expected_code=1,
expected_msg="Can't find client principal noprinc")
success('GSSAPI credential selection tests')

View File

@ -1,327 +0,0 @@
From 0ae9141d53a8d9fe048542f89d17760990bd5bc4 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 17 May 2017 15:14:15 -0400
Subject: [PATCH] Use krb5_timestamp where appropriate
Where krb5_int32 is used to hold the number of seconds since the
epoch, use krb5_timestamp instead.
(cherry picked from commit ae25f6ec5558140a546db34fea389412d81c0631)
---
src/clients/klist/klist.c | 2 +-
src/include/k5-int.h | 2 +-
src/kadmin/server/misc.c | 2 +-
src/kdc/dispatch.c | 4 ++--
src/lib/kadm5/srv/server_acl.c | 2 +-
src/lib/kadm5/srv/server_kdb.c | 2 +-
src/lib/kadm5/srv/svr_principal.c | 10 +++++-----
src/lib/krb5/krb/gen_save_subkey.c | 3 ++-
src/lib/krb5/krb/get_in_tkt.c | 2 +-
src/lib/krb5/krb/init_ctx.c | 3 ++-
src/lib/krb5/os/c_ustime.c | 7 +++++--
src/lib/krb5/os/toffset.c | 3 ++-
src/lib/krb5/os/trace.c | 3 ++-
src/lib/krb5/os/ustime.c | 3 ++-
src/lib/krb5/rcache/rc_dfl.c | 10 +++++-----
src/tests/create/kdb5_mkdums.c | 2 +-
16 files changed, 34 insertions(+), 26 deletions(-)
diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c
index ffeecc394..4334415be 100644
--- a/src/clients/klist/klist.c
+++ b/src/clients/klist/klist.c
@@ -56,7 +56,7 @@ int show_adtype = 0, show_all = 0, list_all = 0, use_client_keytab = 0;
int show_config = 0;
char *defname;
char *progname;
-krb5_int32 now;
+krb5_timestamp now;
unsigned int timestamp_width;
krb5_context kcontext;
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 82ee20760..ed9c7bf75 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -721,7 +721,7 @@ krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context,
const krb5_keyblock *from,
krb5_keyblock *to);
-krb5_error_code krb5_crypto_us_timeofday(krb5_int32 *, krb5_int32 *);
+krb5_error_code krb5_crypto_us_timeofday(krb5_timestamp *, krb5_int32 *);
/*
* End "los-proto.h"
diff --git a/src/kadmin/server/misc.c b/src/kadmin/server/misc.c
index a75b65a26..ba672d714 100644
--- a/src/kadmin/server/misc.c
+++ b/src/kadmin/server/misc.c
@@ -159,7 +159,7 @@ kadm5_ret_t
check_min_life(void *server_handle, krb5_principal principal,
char *msg_ret, unsigned int msg_len)
{
- krb5_int32 now;
+ krb5_timestamp now;
kadm5_ret_t ret;
kadm5_policy_ent_rec pol;
kadm5_principal_ent_rec princ;
diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c
index 16a35d2be..4ecc23481 100644
--- a/src/kdc/dispatch.c
+++ b/src/kdc/dispatch.c
@@ -94,8 +94,8 @@ static void
reseed_random(krb5_context kdc_err_context)
{
krb5_error_code retval;
- krb5_int32 now, now_usec;
- krb5_int32 usec_difference;
+ krb5_timestamp now;
+ krb5_int32 now_usec, usec_difference;
krb5_data data;
retval = krb5_crypto_us_timeofday(&now, &now_usec);
diff --git a/src/lib/kadm5/srv/server_acl.c b/src/lib/kadm5/srv/server_acl.c
index c4bb16dc7..679fc7c41 100644
--- a/src/lib/kadm5/srv/server_acl.c
+++ b/src/lib/kadm5/srv/server_acl.c
@@ -375,7 +375,7 @@ kadm5int_acl_impose_restrictions(kcontext, recp, maskp, rp)
restriction_t *rp;
{
krb5_error_code code;
- krb5_int32 now;
+ krb5_timestamp now;
DPRINT(DEBUG_CALLS, acl_debug_level,
("* kadm5int_acl_impose_restrictions(..., *maskp=0x%08x, rp=0x%08x)\n",
diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c
index 612553ba3..f4b8aef2b 100644
--- a/src/lib/kadm5/srv/server_kdb.c
+++ b/src/lib/kadm5/srv/server_kdb.c
@@ -365,7 +365,7 @@ kdb_put_entry(kadm5_server_handle_t handle,
krb5_db_entry *kdb, osa_princ_ent_rec *adb)
{
krb5_error_code ret;
- krb5_int32 now;
+ krb5_timestamp now;
XDR xdrs;
krb5_tl_data tl_data;
diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
index 137e1fb64..89f34482b 100644
--- a/src/lib/kadm5/srv/svr_principal.c
+++ b/src/lib/kadm5/srv/svr_principal.c
@@ -296,7 +296,7 @@ kadm5_create_principal_3(void *server_handle,
osa_princ_ent_rec adb;
kadm5_policy_ent_rec polent;
krb5_boolean have_polent = FALSE;
- krb5_int32 now;
+ krb5_timestamp now;
krb5_tl_data *tl_data_tail;
unsigned int ret;
kadm5_server_handle_t handle = server_handle;
@@ -1322,7 +1322,7 @@ kadm5_chpass_principal_3(void *server_handle,
int n_ks_tuple, krb5_key_salt_tuple *ks_tuple,
char *password)
{
- krb5_int32 now;
+ krb5_timestamp now;
kadm5_policy_ent_rec pol;
osa_princ_ent_rec adb;
krb5_db_entry *kdb;
@@ -1544,7 +1544,7 @@ kadm5_randkey_principal_3(void *server_handle,
{
krb5_db_entry *kdb;
osa_princ_ent_rec adb;
- krb5_int32 now;
+ krb5_timestamp now;
kadm5_policy_ent_rec pol;
int ret, last_pwd, n_new_keys;
krb5_boolean have_pol = FALSE;
@@ -1686,7 +1686,7 @@ kadm5_setv4key_principal(void *server_handle,
{
krb5_db_entry *kdb;
osa_princ_ent_rec adb;
- krb5_int32 now;
+ krb5_timestamp now;
kadm5_policy_ent_rec pol;
krb5_keysalt keysalt;
int i, kvno, ret;
@@ -1891,7 +1891,7 @@ kadm5_setkey_principal_4(void *server_handle, krb5_principal principal,
{
krb5_db_entry *kdb;
osa_princ_ent_rec adb;
- krb5_int32 now;
+ krb5_timestamp now;
kadm5_policy_ent_rec pol;
krb5_key_data *new_key_data = NULL;
int i, j, ret, n_new_key_data = 0;
diff --git a/src/lib/krb5/krb/gen_save_subkey.c b/src/lib/krb5/krb/gen_save_subkey.c
index 61f36aa36..bc2c46d30 100644
--- a/src/lib/krb5/krb/gen_save_subkey.c
+++ b/src/lib/krb5/krb/gen_save_subkey.c
@@ -38,7 +38,8 @@ k5_generate_and_save_subkey(krb5_context context,
to guarantee randomness, but to make it less likely that multiple
sessions could pick the same subkey. */
struct {
- krb5_int32 sec, usec;
+ krb5_timestamp sec;
+ krb5_int32 usec;
} rnd_data;
krb5_data d;
krb5_error_code retval;
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 40aba1905..7178bd87b 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1788,7 +1788,7 @@ k5_populate_gic_opt(krb5_context context, krb5_get_init_creds_opt **out,
krb5_creds *creds)
{
int i;
- krb5_int32 starttime;
+ krb5_timestamp starttime;
krb5_deltat lifetime;
krb5_get_init_creds_opt *opt;
krb5_error_code retval;
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index cf226fdba..4246c5dd2 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -139,7 +139,8 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
krb5_context ctx = 0;
krb5_error_code retval;
struct {
- krb5_int32 now, now_usec;
+ krb5_timestamp now;
+ krb5_int32 now_usec;
long pid;
} seed_data;
krb5_data seed;
diff --git a/src/lib/krb5/os/c_ustime.c b/src/lib/krb5/os/c_ustime.c
index 68fb381f4..f69f2ea4c 100644
--- a/src/lib/krb5/os/c_ustime.c
+++ b/src/lib/krb5/os/c_ustime.c
@@ -29,7 +29,10 @@
k5_mutex_t krb5int_us_time_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
-struct time_now { krb5_int32 sec, usec; };
+struct time_now {
+ krb5_timestamp sec;
+ krb5_int32 usec;
+};
#if defined(_WIN32)
@@ -73,7 +76,7 @@ get_time_now(struct time_now *n)
static struct time_now last_time;
krb5_error_code
-krb5_crypto_us_timeofday(krb5_int32 *seconds, krb5_int32 *microseconds)
+krb5_crypto_us_timeofday(krb5_timestamp *seconds, krb5_int32 *microseconds)
{
struct time_now now;
krb5_error_code err;
diff --git a/src/lib/krb5/os/toffset.c b/src/lib/krb5/os/toffset.c
index 37bc69f49..4bbcdde52 100644
--- a/src/lib/krb5/os/toffset.c
+++ b/src/lib/krb5/os/toffset.c
@@ -40,7 +40,8 @@ krb5_error_code KRB5_CALLCONV
krb5_set_real_time(krb5_context context, krb5_timestamp seconds, krb5_int32 microseconds)
{
krb5_os_context os_ctx = &context->os_context;
- krb5_int32 sec, usec;
+ krb5_timestamp sec;
+ krb5_int32 usec;
krb5_error_code retval;
retval = krb5_crypto_us_timeofday(&sec, &usec);
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
index 74c315c90..8750b7650 100644
--- a/src/lib/krb5/os/trace.c
+++ b/src/lib/krb5/os/trace.c
@@ -340,7 +340,8 @@ krb5int_trace(krb5_context context, const char *fmt, ...)
va_list ap;
krb5_trace_info info;
char *str = NULL, *msg = NULL;
- krb5_int32 sec, usec;
+ krb5_timestamp sec;
+ krb5_int32 usec;
if (context == NULL || context->trace_callback == NULL)
return;
diff --git a/src/lib/krb5/os/ustime.c b/src/lib/krb5/os/ustime.c
index 1c1b571eb..a80fdf68c 100644
--- a/src/lib/krb5/os/ustime.c
+++ b/src/lib/krb5/os/ustime.c
@@ -40,7 +40,8 @@ krb5_error_code
k5_time_with_offset(krb5_timestamp offset, krb5_int32 offset_usec,
krb5_timestamp *time_out, krb5_int32 *usec_out)
{
- krb5_int32 sec, usec;
+ krb5_timestamp sec;
+ krb5_int32 usec;
krb5_error_code retval;
retval = krb5_crypto_us_timeofday(&sec, &usec);
diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c
index 6b043844d..41ebf94da 100644
--- a/src/lib/krb5/rcache/rc_dfl.c
+++ b/src/lib/krb5/rcache/rc_dfl.c
@@ -93,7 +93,7 @@ cmp(krb5_donot_replay *old, krb5_donot_replay *new1, krb5_deltat t)
}
static int
-alive(krb5_int32 mytime, krb5_donot_replay *new1, krb5_deltat t)
+alive(krb5_timestamp mytime, krb5_donot_replay *new1, krb5_deltat t)
{
if (mytime == 0)
return CMP_HOHUM; /* who cares? */
@@ -129,7 +129,7 @@ struct authlist
static int
rc_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep,
- krb5_int32 now, krb5_boolean fromfile)
+ krb5_timestamp now, krb5_boolean fromfile)
{
struct dfl_data *t = (struct dfl_data *)id->data;
unsigned int rephash;
@@ -536,7 +536,7 @@ krb5_rc_dfl_recover_locked(krb5_context context, krb5_rcache id)
krb5_error_code retval;
long max_size;
int expired_entries = 0;
- krb5_int32 now;
+ krb5_timestamp now;
if ((retval = krb5_rc_io_open(context, &t->d, t->name))) {
return retval;
@@ -706,7 +706,7 @@ krb5_rc_dfl_store(krb5_context context, krb5_rcache id, krb5_donot_replay *rep)
{
krb5_error_code ret;
struct dfl_data *t;
- krb5_int32 now;
+ krb5_timestamp now;
ret = krb5_timeofday(context, &now);
if (ret)
@@ -762,7 +762,7 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
struct authlist **qt;
struct authlist *r;
struct authlist *rt;
- krb5_int32 now;
+ krb5_timestamp now;
if (krb5_timestamp(context, &now))
now = 0;
diff --git a/src/tests/create/kdb5_mkdums.c b/src/tests/create/kdb5_mkdums.c
index 622f549f9..7c0666601 100644
--- a/src/tests/create/kdb5_mkdums.c
+++ b/src/tests/create/kdb5_mkdums.c
@@ -247,7 +247,7 @@ add_princ(context, str_newprinc)
{
/* Add mod princ to db entry */
- krb5_int32 now;
+ krb5_timestamp now;
retval = krb5_timeofday(context, &now);
if (retval) {

View File

@ -1,28 +0,0 @@
From 7998de0b9ccd0c8813159cc3f1d49fe107e3e0ba Mon Sep 17 00:00:00 2001
From: Matt Rogers <mrogers@redhat.com>
Date: Wed, 5 Apr 2017 16:48:55 -0400
Subject: [PATCH] Use the canonical client principal name for OTP
In the OTP module, when constructing the RADIUS request, use the
canonicalized client principal (using the new client_name kdcpreauth
callback) instead of the request client principal.
ticket: 8571 (new)
---
src/plugins/preauth/otp/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/plugins/preauth/otp/main.c b/src/plugins/preauth/otp/main.c
index 2649e9a90..a1b681682 100644
--- a/src/plugins/preauth/otp/main.c
+++ b/src/plugins/preauth/otp/main.c
@@ -331,7 +331,8 @@ otp_verify(krb5_context context, krb5_data *req_pkt, krb5_kdc_req *request,
/* Send the request. */
otp_state_verify((otp_state *)moddata, cb->event_context(context, rock),
- request->client, config, req, on_response, rs);
+ cb->client_name(context, rock), config, req, on_response,
+ rs);
cb->free_string(context, rock, config);
k5_free_pa_otp_req(context, req);

View File

@ -1,4 +1,4 @@
From fb8f32ebdf3293d8a6bdb9478fe1f902a399ba7a Mon Sep 17 00:00:00 2001
From 3e94cf1accf2b33bd0c8cf54eb58b4777f411cc6 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:52:01 -0400
Subject: [PATCH] krb5-1.11-kpasswdtest.patch

View File

@ -1,4 +1,4 @@
From 9c45f66fbc6afb472589dbeb5166f46ad266d319 Mon Sep 17 00:00:00 2001
From 9e7e92ae1dcd242044f2dfe3b89926ddddb6a221 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:57 -0400
Subject: [PATCH] krb5-1.11-run_user_0.patch

View File

@ -1,4 +1,4 @@
From 107a2b8728f1b76feb16df9201919444482e3981 Mon Sep 17 00:00:00 2001
From 9a6cfaaecd1a37e74dba285decd03bb4a3382f9a Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:47:00 -0400
Subject: [PATCH] krb5-1.12-api.patch

View File

@ -1,4 +1,4 @@
From 93b86d94b871aed49b14d7fc1a2a9f23c16cbe0f Mon Sep 17 00:00:00 2001
From 7b3bdbc0ca882325291caad391c4d328f174a614 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:32:09 -0400
Subject: [PATCH] krb5-1.12-ksu-path.patch

View File

@ -1,4 +1,4 @@
From efee9f8598ba84f2be0983fc1d07a9a72d0ff1b7 Mon Sep 17 00:00:00 2001
From 1ede8564105568182e3cf6f273ab820453e2f025 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:33:53 -0400
Subject: [PATCH] krb5-1.12-ktany.patch

View File

@ -1,4 +1,4 @@
From e0924e10dd431a898c9c95faa04b51edbe59c5ef Mon Sep 17 00:00:00 2001
From 385194db1a08c1b923f9eb75e9602b56720fd50e Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:29:58 -0400
Subject: [PATCH] krb5-1.12.1-pam.patch
@ -28,10 +28,10 @@ changes we're proposing for how it handles cache collections.
create mode 100644 src/clients/ksu/pam.h
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 9c46da4b5..508e5fe90 100644
index d6d1279c3..5c9c13e5f 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1675,3 +1675,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[
@@ -1696,3 +1696,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[
]))
])dnl
dnl
@ -141,7 +141,7 @@ index b2fcbf240..5755bb58a 100644
clean:
$(RM) ksu
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index 28342c2d7..cab0c1806 100644
index 7ff676ca7..c6321c01b 100644
--- a/src/clients/ksu/main.c
+++ b/src/clients/ksu/main.c
@@ -26,6 +26,7 @@
@ -756,10 +756,10 @@ index 000000000..0ab76569c
+void appl_pam_cleanup(void);
+#endif
diff --git a/src/configure.in b/src/configure.in
index 037c9f316..daabd12c8 100644
index 10f45eb12..7288a71ec 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1336,6 +1336,8 @@ AC_SUBST([VERTO_VERSION])
@@ -1306,6 +1306,8 @@ AC_SUBST([VERTO_VERSION])
AC_PATH_PROG(GROFF, groff)

View File

@ -1,4 +1,4 @@
From f2df0b75dfbc9796bf8e1477f4661dfb7cdcf8d4 Mon Sep 17 00:00:00 2001
From 850689009f9aeddc0b63051a3e2883d02b05387e Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:47:44 -0400
Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch
@ -12,10 +12,10 @@ original version filed as RT#5891.
3 files changed, 29 insertions(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index f5667c35f..2bfb99496 100644
index 5eeaa2d8a..1fd243094 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1656,6 +1656,15 @@ if test "$with_ldap" = yes; then
@@ -1677,6 +1677,15 @@ if test "$with_ldap" = yes; then
AC_MSG_NOTICE(enabling OpenLDAP database backend module support)
OPENLDAP_PLUGIN=yes
fi
@ -32,10 +32,10 @@ index f5667c35f..2bfb99496 100644
dnl
dnl If libkeyutils exists (on Linux) include it and use keyring ccache
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
index 32efc4f54..af8b2db7b 100644
index 5b9d1e9fa..4e7270065 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
@@ -1674,6 +1674,23 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context,
@@ -1652,6 +1652,23 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context,
ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data);
if (ret)
goto cleanup;

View File

@ -1,4 +1,4 @@
From ae5bb11c0f06fdf92f51d237e94c1d410c59aa04 Mon Sep 17 00:00:00 2001
From 285eaffa69e9c2ff7f0adf017d192b5e7afb7002 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:45:26 -0400
Subject: [PATCH] krb5-1.15-beta1-buildconf.patch
@ -33,7 +33,7 @@ index c17cb5eb5..1891dea99 100755
lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
library=krb5
diff --git a/src/config/pre.in b/src/config/pre.in
index fcea229bd..d961b5621 100644
index d4714d29a..03f5c8890 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)

View File

@ -1,4 +1,4 @@
From aaf74b66a51cbda90ba40f73eb8def9b192ab262 Mon Sep 17 00:00:00 2001
From d38588a165302d915eb6b4da0c2755601547bcd1 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:30:53 -0400
Subject: [PATCH] krb5-1.15.1-selinux-label.patch
@ -66,7 +66,7 @@ which we used earlier, is some improvement.
create mode 100644 src/util/support/selinux.c
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 508e5fe90..607859f17 100644
index 5c9c13e5f..6257dba40 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -89,6 +89,7 @@ AC_SUBST_FILE(libnodeps_frag)
@ -77,7 +77,7 @@ index 508e5fe90..607859f17 100644
KRB5_LIB_PARAMS
KRB5_AC_INITFINI
KRB5_AC_ENABLE_THREADS
@@ -1742,3 +1743,51 @@ AC_SUBST(PAM_LIBS)
@@ -1763,3 +1764,51 @@ AC_SUBST(PAM_LIBS)
AC_SUBST(PAM_MAN)
AC_SUBST(NON_PAM_MAN)
])dnl
@ -151,7 +151,7 @@ index f6184da3f..c17cb5eb5 100755
echo $lib_flags
diff --git a/src/config/pre.in b/src/config/pre.in
index e0626320c..fcea229bd 100644
index 3f267eb1f..d4714d29a 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -177,6 +177,7 @@ LD = $(PURE) @LD@
@ -170,12 +170,12 @@ index e0626320c..fcea229bd 100644
+KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS)
GSS_LIBS = $(GSS_KRB5_LIB)
# needs fixing if ever used on Mac OS X!
# needs fixing if ever used on macOS!
diff --git a/src/configure.in b/src/configure.in
index daabd12c8..acf3a458b 100644
index 7288a71ec..2b6d5baa7 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1338,6 +1338,8 @@ AC_PATH_PROG(GROFF, groff)
@@ -1308,6 +1308,8 @@ AC_PATH_PROG(GROFF, groff)
KRB5_WITH_PAM
@ -185,7 +185,7 @@ index daabd12c8..acf3a458b 100644
if test "${localedir+set}" != set; then
localedir='$(datadir)/locale'
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 64991738a..173cb0264 100644
index e1b1cb040..9378ae047 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -128,6 +128,7 @@ typedef unsigned char u_char;
@ -235,7 +235,7 @@ index 000000000..dfaaa847c
+#endif
+#endif
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index ac22f4c55..cf60d6c41 100644
index c86e78274..e81bb0a6d 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -87,6 +87,12 @@
@ -252,7 +252,7 @@ index ac22f4c55..cf60d6c41 100644
#include <stdlib.h>
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
index f7889bd23..cad53cfbf 100644
index aca136f0b..22e926ae4 100644
--- a/src/kadmin/dbutil/dump.c
+++ b/src/kadmin/dbutil/dump.c
@@ -148,12 +148,21 @@ create_ofile(char *ofile, char **tmpname)
@ -287,10 +287,10 @@ index f7889bd23..cad53cfbf 100644
com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
exit_status++;
diff --git a/src/kdc/main.c b/src/kdc/main.c
index ebc852bba..a4dffb29a 100644
index f2226da25..ccac3a759 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -872,7 +872,7 @@ write_pid_file(const char *path)
@@ -873,7 +873,7 @@ write_pid_file(const char *path)
FILE *file;
unsigned long pid;
@ -385,10 +385,10 @@ index bba64e516..73f0fe62d 100644
_("Credential cache directory %s does not exist"),
dirname);
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
index 6a42f267d..674d88bab 100644
index 091f2c43f..ecc97ee2f 100644
--- a/src/lib/krb5/keytab/kt_file.c
+++ b/src/lib/krb5/keytab/kt_file.c
@@ -1022,14 +1022,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
@@ -1024,14 +1024,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
KTCHECKLOCK(id);
errno = 0;
@ -406,10 +406,10 @@ index 6a42f267d..674d88bab 100644
goto report_errno;
writevno = 1;
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
index 83c8d4db8..a19246128 100644
index e97ce5fe5..779f184cb 100644
--- a/src/lib/krb5/os/trace.c
+++ b/src/lib/krb5/os/trace.c
@@ -397,7 +397,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
@@ -398,7 +398,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
fd = malloc(sizeof(*fd));
if (fd == NULL)
return ENOMEM;
@ -419,10 +419,10 @@ index 83c8d4db8..a19246128 100644
free(fd);
return errno;
diff --git a/src/lib/krb5/rcache/rc_dfl.c b/src/lib/krb5/rcache/rc_dfl.c
index c4d2c744d..c0f12ed9d 100644
index 1e0cb22c9..f5e93b1ab 100644
--- a/src/lib/krb5/rcache/rc_dfl.c
+++ b/src/lib/krb5/rcache/rc_dfl.c
@@ -794,6 +794,9 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
@@ -793,6 +793,9 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
krb5_error_code retval = 0;
krb5_rcache tmp;
krb5_deltat lifespan = t->lifespan; /* save original lifespan */
@ -432,7 +432,7 @@ index c4d2c744d..c0f12ed9d 100644
if (! t->recovering) {
name = t->name;
@@ -815,7 +818,17 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
@@ -814,7 +817,17 @@ krb5_rc_dfl_expunge_locked(krb5_context context, krb5_rcache id)
retval = krb5_rc_resolve(context, tmp, 0);
if (retval)
goto cleanup;
@ -464,7 +464,7 @@ index 7db30a33b..2b9d01921 100644
* maybe someone took away write permission so we could only
* get shared locks?
diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c
index 4c4036eb4..d90bdeaba 100644
index d23587a59..e2825650b 100644
--- a/src/plugins/kdb/db2/kdb_db2.c
+++ b/src/plugins/kdb/db2/kdb_db2.c
@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc)
@ -500,7 +500,7 @@ index 2977b17f3..d5809a5a9 100644
} else {
diff --git a/src/plugins/kdb/db2/libdb2/hash/hash.c b/src/plugins/kdb/db2/libdb2/hash/hash.c
index 76f5d4709..1fa8b8389 100644
index 862dbb164..686a960c9 100644
--- a/src/plugins/kdb/db2/libdb2/hash/hash.c
+++ b/src/plugins/kdb/db2/libdb2/hash/hash.c
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 (Berkeley) 11/7/95";
@ -511,7 +511,7 @@ index 76f5d4709..1fa8b8389 100644
#include "db-int.h"
#include "hash.h"
#include "page.h"
@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info, dflags)
@@ -129,7 +130,7 @@ __kdb2_hash_open(file, flags, mode, info, dflags)
new_table = 1;
}
if (file) {
@ -580,10 +580,10 @@ index 022156a5e..3d6994c67 100644
if (newfile == NULL) {
com_err(me, errno, _("Error creating file %s"), tmp_file);
diff --git a/src/slave/kpropd.c b/src/slave/kpropd.c
index 056c31a42..b78c3d9e5 100644
index d621f108f..99676cc97 100644
--- a/src/slave/kpropd.c
+++ b/src/slave/kpropd.c
@@ -464,6 +464,9 @@ doit(int fd)
@@ -488,6 +488,9 @@ doit(int fd)
krb5_enctype etype;
int database_fd;
char host[INET6_ADDRSTRLEN + 1];
@ -593,7 +593,7 @@ index 056c31a42..b78c3d9e5 100644
signal_wrapper(SIGALRM, alarm_handler);
alarm(params.iprop_resync_timeout);
@@ -520,9 +523,15 @@ doit(int fd)
@@ -543,9 +546,15 @@ doit(int fd)
free(name);
exit(1);
}
@ -631,7 +631,7 @@ index 907c119bb..0f5462aea 100644
retval = errno;
if (retval == 0)
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
index 6239e4176..17bcd2a67 100644
index 0bf0b7a87..58ac2e333 100644
--- a/src/util/support/Makefile.in
+++ b/src/util/support/Makefile.in
@@ -69,6 +69,7 @@ IPC_SYMS= \
@ -642,7 +642,7 @@ index 6239e4176..17bcd2a67 100644
init-addrinfo.o \
plugins.o \
errors.o \
@@ -148,7 +149,7 @@ SRCS=\
@@ -149,7 +150,7 @@ SRCS=\
SHLIB_EXPDEPS =
# Add -lm if dumping thread stats, for sqrt.

View File

@ -1,4 +1,4 @@
From 1b95f8a488d1e70bf7698c8b49412306a1b8aba0 Mon Sep 17 00:00:00 2001
From 4bc124bfff119d436eeb1af7b9d5726e17284d67 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:46:21 -0400
Subject: [PATCH] krb5-1.3.1-dns.patch
@ -9,10 +9,10 @@ We want to be able to use --with-netlib and --enable-dns at the same time.
1 file changed, 1 insertion(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 607859f17..f5667c35f 100644
index 6257dba40..5eeaa2d8a 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -703,6 +703,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
@@ -726,6 +726,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
LIBS="$LIBS $withval"
AC_MSG_RESULT("netlib will use \'$withval\'")
fi

View File

@ -1,4 +1,4 @@
From e1d7fcf9713fe322ad5740045650dac86427e6ae Mon Sep 17 00:00:00 2001
From 82f8b63ae3955423456adf15790c10eb1145ec52 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:25 -0400
Subject: [PATCH] krb5-1.9-debuginfo.patch

View File

@ -9,21 +9,21 @@
%global configured_default_ccache_name KEYRING:persistent:%%{uid}
# leave empty or set to e.g., -beta2
%global prerelease %{nil}
%global prerelease -beta1
# Should be in form 5.0, 6.1, etc.
%global kdbversion 6.1
Summary: The Kerberos network authentication system
Name: krb5
Version: 1.15.2
# for prerelease, should be e.g., 0.3.beta2% { ?dist } (without spaces)
Release: 2%{?dist}
Version: 1.16
# for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces)
Release: 0.beta1.1%{?dist}
# lookaside-cached sources; two downloads and a build artifact
Source0: https://web.mit.edu/kerberos/dist/krb5/1.15/krb5-%{version}%{prerelease}.tar.gz
Source0: https://web.mit.edu/kerberos/dist/krb5/1.16/krb5-%{version}%{prerelease}.tar.gz
# rharwood has trust path to signing key and verifies on check-in
Source1: https://web.mit.edu/kerberos/dist/krb5/1.15/krb5-%{version}%{prerelease}.tar.gz.asc
Source1: https://web.mit.edu/kerberos/dist/krb5/1.16/krb5-%{version}%{prerelease}.tar.gz.asc
# This source is generated during the build because it is documentation.
# To override this behavior (e.g., new upstream version), do:
# tar cfT krb5-1.15.2-pdfs.tar /dev/null
@ -60,38 +60,7 @@ Patch33: krb5-1.13-dirsrv-accountlock.patch
Patch34: krb5-1.9-debuginfo.patch
Patch35: krb5-1.11-run_user_0.patch
Patch36: krb5-1.11-kpasswdtest.patch
Patch37: Build-with-Werror-implicit-int-where-supported.patch
Patch38: Add-PKINIT-UPN-tests-to-t_pkinit.py.patch
Patch39: Add-test-case-for-PKINIT-DH-renegotiation.patch
Patch40: Use-expected_trace-in-test-scripts.patch
Patch41: Use-expected_msg-in-test-scripts.patch
Patch42: Use-fallback-realm-for-GSSAPI-ccache-selection.patch
Patch43: Use-GSSAPI-fallback-skiptest.patch
Patch44: Improve-PKINIT-UPN-SAN-matching.patch
Patch45: Add-test-cert-generation-to-make-certs.sh.patch
Patch46: Deindent-crypto_retrieve_X509_sans.patch
Patch47: Add-the-client_name-kdcpreauth-callback.patch
Patch48: Use-the-canonical-client-principal-name-for-OTP.patch
Patch49: Add-certauth-pluggable-interface.patch
Patch50: Correct-error-handling-bug-in-prior-commit.patch
Patch51: Add-k5test-expected_msg-expected_trace.patch
Patch53: Add-support-to-query-the-SSF-of-a-GSS-context.patch
Patch55: Remove-incomplete-PKINIT-OCSP-support.patch
Patch57: Fix-in_clock_skew-and-use-it-in-AS-client-code.patch
Patch58: Add-timestamp-helper-functions.patch
Patch59: Make-timestamp-manipulations-y2038-safe.patch
Patch60: Add-timestamp-tests.patch
Patch61: Add-y2038-documentation.patch
Patch62: Fix-more-time-manipulations-for-y2038.patch
Patch63: Use-krb5_timestamp-where-appropriate.patch
Patch64: Add-KDC-policy-pluggable-interface.patch
Patch65: Fix-bugs-in-kdcpolicy-commit.patch
Patch66: Convert-some-pkiDebug-messages-to-TRACE-macros.patch
Patch67: Fix-certauth-built-in-module-returns.patch
Patch68: Add-test-cert-with-no-extensions.patch
Patch69: Add-PKINIT-test-case-for-generic-client-cert.patch
Patch70: Add-hostname-based-ccselect-module.patch
Patch71: Add-German-translation.patch
License: MIT
URL: http://web.mit.edu/kerberos/www/
@ -381,7 +350,7 @@ for pdf in admin appdev basic build plugindev user ; do
test -s build-pdf/$pdf.pdf || make -C build-pdf
done
# new krb5-%{version}-pdf
tar -cf "krb5-%{version}-pdfs.tar.new" build-pdf/*.pdf
tar -cf "krb5-%{version}%{prerelease}-pdfs.tar.new" build-pdf/*.pdf
# We need to cut off any access to locally-running nameservers, too.
%{__cc} -fPIC -shared -o noport.so -Wall -Wextra $RPM_SOURCE_DIR/noport.c
@ -745,6 +714,9 @@ exit 0
%{_libdir}/libkadm5srv_mit.so.*
%changelog
* Thu Oct 05 2017 Robbie Harwood <rharwood@redhat.com> - 1.16-0.beta1.1
- New upstream prerelease (1.16-beta1)
* Thu Sep 28 2017 Robbie Harwood <rharwood@redhat.com> - 1.15.2-2
- Add German translation

View File

@ -1,3 +1,3 @@
SHA512 (krb5-1.15.2-pdfs.tar) = 5875efde7ed88dcccd6f624a5252c5c70844fe94015ce4acfdf7f6ccabf52c86965c5a661b161c73e37b46e51aa5e9ea19602ab32e8b50682ecb0a450f0553b6
SHA512 (krb5-1.15.2.tar.gz) = e5814bb66384b13637c37918df694c6b9933c29c2d952da0ed0dcd2e623b269060b4c16b6c02162039dadebdab99ff1085e37e7621ae4748dafb036424e612c2
SHA512 (krb5-1.15.2.tar.gz.asc) = 37cee442de29229fa821539c3f1724eb4d37fa9ce5eee644869a7311c8fe10218dac36da3a5297d45168d8fb1ad64dbd614f10d3384d54e4070e56e7fe8a1e63
SHA512 (krb5-1.16-beta1-pdfs.tar) = 79329b7978101723a5c9f55773ac69bd1986c716e6d8b4cd42cbf17a8e85cd49f13b376e0b4b0ccca485b5a5a79d6bce8ace0c22df79b6f0a47a74c387f83ffd
SHA512 (krb5-1.16-beta1.tar.gz) = 68dba5212d2dd28ed0bc4961931af8d291bcdf2805baa4e930b0218f7749dc1e4dfe696aacca0529787f274b99fe5a8297f3e13877f724ee983483b399daf2c9
SHA512 (krb5-1.16-beta1.tar.gz.asc) = 342272496897b4a4452d73186b7d19bbc3155e38fe39e0e852e03ce4757a3284baefbb1c49653e53d36e96ab587a7acb718e14c8281ccca85cb0de4c7d0b730e