basebuilder_pel7ppc64bebuilder0
7 years ago
62 changed files with 14392 additions and 0 deletions
@ -0,0 +1,994 @@
@@ -0,0 +1,994 @@
|
||||
From f12b57979012f93b339982ba335093d7c0d364f7 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 59a39cd30..241b05b40 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 aacd2f20d..4c722a4a3 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 778a629e5..8cbdf2c5b 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') |
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
From f726fe232a16a51ca277b660c61aa9cfc2f512f1 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) |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
From c099e896f28d8c5ccacc9df086a8f4297c6b484e 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: back out .gitignore] |
||||
--- |
||||
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 77a9bffdf..aecac9d3b 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 |
@ -0,0 +1,419 @@
@@ -0,0 +1,419 @@
|
||||
From 1f7d42707585e552842455857070fff8957fcb7c 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: stub out GSS_KRB5_GET_CRED_IMPERSONATOR] |
||||
--- |
||||
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); |
@ -0,0 +1,90 @@
@@ -0,0 +1,90 @@
|
||||
From fd8ce9e1ed7a8d6cf5ac7d27d6acf40b0453c45e Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Tue, 5 Sep 2017 15:54:31 -0400 |
||||
Subject: [PATCH] Add test cert generation to make-certs.sh |
||||
|
||||
Based on commit 5a1d0388ba2e4ec510ed715ce5fbc7f748941425 but missing |
||||
everything but the make-certs change since infrastructure cannot patch |
||||
binaries. Plan to run make-certs during build, but this will only |
||||
work with openssl < 1.1. |
||||
--- |
||||
src/tests/dejagnu/pkinit-certs/make-certs.sh | 53 +++++++++++++++++++++++++++- |
||||
1 file changed, 52 insertions(+), 1 deletion(-) |
||||
|
||||
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 |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
From dd189f46b9e43392b842c4309c95dc7e71963261 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Thu, 5 Oct 2017 12:54:13 -0400 |
||||
Subject: [PATCH] Add test cert with no extensions |
||||
|
||||
Add commands to make-certs.sh to generate a test client certificate |
||||
with no certificate extensions. Re-run make-certs.sh. |
||||
|
||||
ticket: 8562 |
||||
(cherry-picked from commit 0d23835660ab131d244d395e4568969b5c0dc678) |
||||
[rharwood@redhat.com: only backport the make-certs.sh changes] |
||||
--- |
||||
src/tests/dejagnu/pkinit-certs/make-certs.sh | 9 +++++++++ |
||||
1 file changed, 9 insertions(+) |
||||
|
||||
diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh |
||||
index 0d8c2019a..23426af8a 100755 |
||||
--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh |
||||
+++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh |
||||
@@ -163,5 +163,14 @@ SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_upn3_client \ |
||||
openssl pkcs12 -export -in user-upn3.pem -inkey privkey.pem \ |
||||
-out user-upn3.p12 -passout pass: |
||||
|
||||
+# Generate a client certificate and PKCS#12 bundle with no PKINIT extensions. |
||||
+SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ |
||||
+ -key privkey.pem -out generic.csr |
||||
+SUBJECT=user openssl x509 -set_serial 7 -days $DAYS -req -CA ca.pem \ |
||||
+ -CAkey privkey.pem -out generic.pem -in generic.csr |
||||
+openssl pkcs12 -export -in generic.pem -inkey privkey.pem -out generic.p12 \ |
||||
+ -passout pass: |
||||
+ |
||||
# Clean up. |
||||
rm -f openssl.cnf kdc.csr user.csr user-upn.csr user-upn2.csr user-upn3.csr |
||||
+rm -f generic.csr |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
From aa153bb60c4fdc05adbc88cca578612fce6c8ce0 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 |
@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
|
||||
From 6437685130b68670888db1d0551f5464d56c4cec 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; |
||||
|
||||
/** |
@ -0,0 +1,599 @@
@@ -0,0 +1,599 @@
|
||||
From 47999bb8735f653f06e0eb46e7eced600210b9da 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, ×); |
||||
+ assert(!ret); |
||||
+ |
||||
+ /* Current time is before starttime, but within clock skew. */ |
||||
+ times.starttime = 1100; |
||||
+ ret = krb5int_validate_times(context, ×); |
||||
+ assert(!ret); |
||||
+ |
||||
+ /* Current time is before starttime by more than clock skew. */ |
||||
+ times.starttime = 1400; |
||||
+ ret = krb5int_validate_times(context, ×); |
||||
+ 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, ×); |
||||
+ assert(!ret); |
||||
+ |
||||
+ /* Current time is after end time by more than clock skew. */ |
||||
+ times.endtime = 600; |
||||
+ ret = krb5int_validate_times(context, ×); |
||||
+ 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, ×); |
||||
+ assert(!ret); |
||||
+ |
||||
+ /* Current time is before starttime, but by less than clock skew. */ |
||||
+ times.starttime = BOUNDARY + 100; |
||||
+ ret = krb5int_validate_times(context, ×); |
||||
+ assert(!ret); |
||||
+ |
||||
+ /* Current time is before starttime by more than clock skew. */ |
||||
+ times.starttime = BOUNDARY + 250; |
||||
+ ret = krb5int_validate_times(context, ×); |
||||
+ 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, ×); |
||||
+ assert(!ret); |
||||
+ |
||||
+ /* Current time is after endtime by more than clock skew. */ |
||||
+ times.endtime = BOUNDARY - 300; |
||||
+ ret = krb5int_validate_times(context, ×); |
||||
+ 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 e23c936d7..fa214242f 100755 |
||||
--- a/src/tests/gssapi/t_gssapi.py |
||||
+++ b/src/tests/gssapi/t_gssapi.py |
||||
@@ -220,4 +220,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 185225afa..c0eeb0118 100755 |
||||
--- a/src/tests/t_kdb.py |
||||
+++ b/src/tests/t_kdb.py |
||||
@@ -446,6 +446,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') |
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
From f9702eabc568679f48ea5d0bc7be073582cc52ad 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. |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
From 498b43b1a58795773834c1c5bb2b61dd801b9a03 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Sat, 22 Apr 2017 16:51:23 -0400 |
||||
Subject: [PATCH] Allow clock skew in krb5 gss_context_time() |
||||
|
||||
Commit b496ce4095133536e0ace36b74130e4b9ecb5e11 (ticket #8268) adds |
||||
the clock skew to krb5 acceptor context lifetimes for |
||||
gss_accept_sec_context() and gss_inquire_context(), but not for |
||||
gss_context_time(). Add the clock skew in gss_context_time() as well. |
||||
|
||||
ticket: 8581 (new) |
||||
target_version: 1.14-next |
||||
target_version: 1.15-next |
||||
tags: pullup |
||||
|
||||
(cherry picked from commit b0a072e6431261734e7350996a363801f180e8ea) |
||||
--- |
||||
src/lib/gssapi/krb5/context_time.c | 5 ++++- |
||||
1 file changed, 4 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c |
||||
index a18cfb05b..450593288 100644 |
||||
--- a/src/lib/gssapi/krb5/context_time.c |
||||
+++ b/src/lib/gssapi/krb5/context_time.c |
||||
@@ -51,7 +51,10 @@ krb5_gss_context_time(minor_status, context_handle, time_rec) |
||||
return(GSS_S_FAILURE); |
||||
} |
||||
|
||||
- if ((lifetime = ctx->krb_times.endtime - now) <= 0) { |
||||
+ lifetime = ctx->krb_times.endtime - now; |
||||
+ if (!ctx->initiate) |
||||
+ lifetime += ctx->k5_context->clockskew; |
||||
+ if (lifetime <= 0) { |
||||
*time_rec = 0; |
||||
*minor_status = 0; |
||||
return(GSS_S_CONTEXT_EXPIRED); |
@ -0,0 +1,423 @@
@@ -0,0 +1,423 @@
|
||||
From b4c2212ae7412e21f4965acdb8c10e4a60b65b9b 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) |
||||
(cherry picked from commit 686fa6476eb759532d566794fa8d430774d44cf7) |
||||
--- |
||||
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) \ |
@ -0,0 +1,32 @@
@@ -0,0 +1,32 @@
|
||||
From ca3e61600f1400974c63b2abb30b44f0c94d550b 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; |
@ -0,0 +1,264 @@
@@ -0,0 +1,264 @@
|
||||
From 54c5bec8deb2d4e972795e37273ad17a0b1e2f4f 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) |
||||
(cherry picked from commit 23086ac768a32db1e40a9b63684dbcfd76aba033) |
||||
--- |
||||
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) |
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
From 9c0a06f38189d255575acdae5efb22b76b4c33b3 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Mon, 13 Nov 2017 13:32:37 -0500 |
||||
Subject: [PATCH] Expose context errors in pkinit_server_plugin_init |
||||
|
||||
Commit 3ff426b9048a8024e5c175256c63cd0ad0572320 attempted to display |
||||
an error when OCSP support was requested, but this error message was |
||||
suppressed in pkinit_server_plugin_init(). Add a trace log for each |
||||
realm initialization error, and pass through the realm initialization |
||||
error when the KDC serves only one realm. Other error messages from |
||||
pkinit_init_kdc_profile(), such as missing pkinit_identity or |
||||
pkinit_anchors, are also now exposted. |
||||
|
||||
[ghudson@mit.edu: clarified commit message] |
||||
|
||||
ticket: 8621 (new) |
||||
target_version: 1.16 |
||||
tags: pullup |
||||
|
||||
(cherry picked from commit 225aab3540c13c6289b22022d5e110f6fc26151d) |
||||
--- |
||||
src/plugins/preauth/pkinit/pkinit_srv.c | 19 +++++++++++++------ |
||||
src/plugins/preauth/pkinit/pkinit_trace.h | 3 +++ |
||||
2 files changed, 16 insertions(+), 6 deletions(-) |
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c |
||||
index 8e77606f8..143d331a2 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_srv.c |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c |
||||
@@ -1622,16 +1622,23 @@ pkinit_server_plugin_init(krb5_context context, |
||||
|
||||
for (i = 0, j = 0; i < numrealms; i++) { |
||||
TRACE_PKINIT_SERVER_INIT_REALM(context, realmnames[i]); |
||||
- retval = pkinit_server_plugin_init_realm(context, realmnames[i], &plgctx); |
||||
- if (retval == 0 && plgctx != NULL) |
||||
+ krb5_clear_error_message(context); |
||||
+ retval = pkinit_server_plugin_init_realm(context, realmnames[i], |
||||
+ &plgctx); |
||||
+ if (retval) |
||||
+ TRACE_PKINIT_SERVER_INIT_FAIL(context, realmnames[i], retval); |
||||
+ else |
||||
realm_contexts[j++] = plgctx; |
||||
} |
||||
|
||||
if (j == 0) { |
||||
- retval = EINVAL; |
||||
- krb5_set_error_message(context, retval, |
||||
- _("No realms configured correctly for pkinit " |
||||
- "support")); |
||||
+ if (numrealms == 1) { |
||||
+ k5_prependmsg(context, retval, "PKINIT initialization failed"); |
||||
+ } else { |
||||
+ retval = EINVAL; |
||||
+ k5_setmsg(context, retval, |
||||
+ _("No realms configured correctly for pkinit support")); |
||||
+ } |
||||
goto errout; |
||||
} |
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_trace.h b/src/plugins/preauth/pkinit/pkinit_trace.h |
||||
index 6abe28c0c..8d489469f 100644 |
||||
--- a/src/plugins/preauth/pkinit/pkinit_trace.h |
||||
+++ b/src/plugins/preauth/pkinit/pkinit_trace.h |
||||
@@ -100,6 +100,9 @@ |
||||
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_INIT_FAIL(c, realm, retval) \ |
||||
+ TRACE(c, "PKINIT server initialization failed for realm {str}: {kerr}", \ |
||||
+ realm, retval) |
||||
#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) \ |
@ -0,0 +1,130 @@
@@ -0,0 +1,130 @@
|
||||
From d59b00fd1fdcc473739f3033c0f67eb402f20d9c 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). |
@ -0,0 +1,124 @@
@@ -0,0 +1,124 @@
|
||||
From 41b9111b48e53bf7864ed1f134e0433b070fa900 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 |
@ -0,0 +1,58 @@
@@ -0,0 +1,58 @@
|
||||
From 7e914206a676fb8f972c8021e97fab86a155488b 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)) |
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
From 7221a9f695016d3e4873bb799f06665ec74387f8 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Wed, 6 Sep 2017 12:56:37 -0400 |
||||
Subject: [PATCH] Fix make-certs.sh for OpenSSL 1.1 |
||||
|
||||
The openssl req commands in make-certs.sh contain -subj options which |
||||
were ignored in favor of the config file prior to OpenSSL 1.1. When |
||||
they are used, they remove elements of the subject which are now |
||||
required by t_pkinit.py. |
||||
|
||||
(cherry picked from commit b0473da67d72e43b9f03b703869069348e872efc) |
||||
[rharwood@redhat.com: remove newer sections in make-certs.sh] |
||||
--- |
||||
src/tests/dejagnu/pkinit-certs/make-certs.sh | 19 +++++++++---------- |
||||
1 file changed, 9 insertions(+), 10 deletions(-) |
||||
|
||||
diff --git a/src/tests/dejagnu/pkinit-certs/make-certs.sh b/src/tests/dejagnu/pkinit-certs/make-certs.sh |
||||
index 0f07709b0..0d8c2019a 100755 |
||||
--- a/src/tests/dejagnu/pkinit-certs/make-certs.sh |
||||
+++ b/src/tests/dejagnu/pkinit-certs/make-certs.sh |
||||
@@ -122,15 +122,14 @@ SUBJECT=ca openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ |
||||
-set_serial 1 -days $DAYS -key privkey.pem -out ca.pem |
||||
|
||||
# Generate a KDC certificate. |
||||
-SUBJECT=kdc openssl req -config openssl.cnf -new -subj /CN=kdc \ |
||||
- -key privkey.pem -out kdc.csr |
||||
+SUBJECT=kdc openssl req -config openssl.cnf -new -key privkey.pem -out kdc.csr |
||||
SUBJECT=kdc openssl x509 -extfile openssl.cnf -extensions exts_kdc \ |
||||
-set_serial 2 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ |
||||
-out kdc.pem -in kdc.csr |
||||
|
||||
# Generate a client certificate and PKCS#12 bundles. |
||||
-SUBJECT=user openssl req -config openssl.cnf -new -subj /CN=user \ |
||||
- -key privkey.pem -out user.csr |
||||
+SUBJECT=user openssl req -config openssl.cnf -new -key privkey.pem \ |
||||
+ -out user.csr |
||||
SUBJECT=user openssl x509 -extfile openssl.cnf -extensions exts_client \ |
||||
-set_serial 3 -days $DAYS -req -CA ca.pem -CAkey privkey.pem \ |
||||
-out user.pem -in user.csr |
||||
@@ -140,24 +139,24 @@ 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 req -config openssl.cnf -new -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 req -config openssl.cnf -new -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 req -config openssl.cnf -new -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 |
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
From 006c68f6ed266d5ea7a24512349a931f45160cc6 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; |
@ -0,0 +1,151 @@
@@ -0,0 +1,151 @@
|
||||
From 802cf0263965eef725208f00eccb62df0b082319 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) { |
@ -0,0 +1,203 @@
@@ -0,0 +1,203 @@
|
||||
From 31d5c854198ed91fc2bd0b9fb87ed0dcd5a40eb6 Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Thu, 24 Aug 2017 16:00:33 -0400 |
||||
Subject: [PATCH] Limit ticket lifetime to 2^31-1 seconds |
||||
|
||||
Although timestamps above 2^31-1 are now valid, intervals exceeding |
||||
2^31-1 seconds may be treated incorrectly by comparison operations. |
||||
|
||||
The initially computed interval in kdc_get_ticket_endtime() could be |
||||
negative if the requested end time is far in the future, causing the |
||||
function to yield an incorrect result. (With the new larger value of |
||||
kdc_infinity, this could specifically happen if a KDC-REQ contains a |
||||
zero till field.) Cap the interval at the maximum valid value. |
||||
Reported by Weijun Wang. |
||||
|
||||
Avoid delta comparisons in favor of timestamp comparions in |
||||
krb5int_validate_times(), ksu's krb5_check_exp(), and clockskew |
||||
checks. |
||||
|
||||
Also use a y2038-safe timestamp comparison in set_request_times() when |
||||
comparing the requested renewable end time to the requested ticket end |
||||
time. |
||||
|
||||
ticket: 8352 |
||||
(cherry picked from commit 54e58755368b58ba5894a14c1d02626da42d8003) |
||||
--- |
||||
src/clients/ksu/ccache.c | 2 +- |
||||
src/include/k5-int.h | 7 +++++++ |
||||
src/kdc/kdc_util.c | 7 ++++++- |
||||
src/kdc/replay.c | 2 +- |
||||
src/kdc/t_replay.c | 2 +- |
||||
src/lib/krb5/krb/gc_via_tkt.c | 4 ++-- |
||||
src/lib/krb5/krb/get_in_tkt.c | 6 +++--- |
||||
src/lib/krb5/krb/int-proto.h | 3 --- |
||||
src/lib/krb5/krb/valid_times.c | 4 ++-- |
||||
src/lib/krb5/os/timeofday.c | 2 +- |
||||
10 files changed, 24 insertions(+), 15 deletions(-) |
||||
|
||||
diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c |
||||
index 236313b7b..2a99521d4 100644 |
||||
--- a/src/clients/ksu/ccache.c |
||||
+++ b/src/clients/ksu/ccache.c |
||||
@@ -282,7 +282,7 @@ krb5_error_code krb5_check_exp(context, tkt_time) |
||||
|
||||
} |
||||
|
||||
- if (ts_delta(currenttime, tkt_time.endtime) > context->clockskew) { |
||||
+ if (ts_after(currenttime, ts_incr(tkt_time.endtime, context->clockskew))) { |
||||
retval = KRB5KRB_AP_ERR_TKT_EXPIRED ; |
||||
return retval; |
||||
} |
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h |
||||
index 39ffb9568..e31004a7c 100644 |
||||
--- a/src/include/k5-int.h |
||||
+++ b/src/include/k5-int.h |
||||
@@ -2386,6 +2386,13 @@ ts_after(krb5_timestamp a, krb5_timestamp b) |
||||
return (uint32_t)a > (uint32_t)b; |
||||
} |
||||
|
||||
+/* Return true if a and b are within d seconds. */ |
||||
+static inline krb5_boolean |
||||
+ts_within(krb5_timestamp a, krb5_timestamp b, krb5_deltat d) |
||||
+{ |
||||
+ return !ts_after(a, ts_incr(b, d)) && !ts_after(b, ts_incr(a, d)); |
||||
+} |
||||
+ |
||||
krb5_error_code KRB5_CALLCONV |
||||
krb5_get_credentials_for_user(krb5_context context, krb5_flags options, |
||||
krb5_ccache ccache, |
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c |
||||
index 5455e2a67..770163b94 100644 |
||||
--- a/src/kdc/kdc_util.c |
||||
+++ b/src/kdc/kdc_util.c |
||||
@@ -1759,14 +1759,19 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm, |
||||
krb5_db_entry *server, |
||||
krb5_timestamp *out_endtime) |
||||
{ |
||||
- krb5_timestamp until, life; |
||||
+ krb5_timestamp until; |
||||
+ krb5_deltat life; |
||||
|
||||
if (till == 0) |
||||
till = kdc_infinity; |
||||
|
||||
until = ts_min(till, endtime); |
||||
|
||||
+ /* Determine the requested lifetime, capped at the maximum valid time |
||||
+ * interval. */ |
||||
life = ts_delta(until, starttime); |
||||
+ if (ts_after(until, starttime) && life < 0) |
||||
+ life = INT32_MAX; |
||||
|
||||
if (client != NULL && client->max_life != 0) |
||||
life = min(life, client->max_life); |
||||
diff --git a/src/kdc/replay.c b/src/kdc/replay.c |
||||
index fab39cf88..caca783bf 100644 |
||||
--- a/src/kdc/replay.c |
||||
+++ b/src/kdc/replay.c |
||||
@@ -61,7 +61,7 @@ static size_t total_size = 0; |
||||
static krb5_ui_4 seed; |
||||
|
||||
#define STALE_TIME (2*60) /* two minutes */ |
||||
-#define STALE(ptr, now) (labs(ts_delta((ptr)->timein, now)) >= STALE_TIME) |
||||
+#define STALE(ptr, now) (ts_after(now, ts_incr((ptr)->timein, STALE_TIME))) |
||||
|
||||
/* Return x rotated to the left by r bits. */ |
||||
static inline krb5_ui_4 |
||||
diff --git a/src/kdc/t_replay.c b/src/kdc/t_replay.c |
||||
index 1442e0e8c..bb7e2faff 100644 |
||||
--- a/src/kdc/t_replay.c |
||||
+++ b/src/kdc/t_replay.c |
||||
@@ -903,7 +903,7 @@ test_kdc_insert_lookaside_cache_expire(void **state) |
||||
assert_non_null(e); |
||||
e->num_hits = 5; |
||||
|
||||
- time_return(STALE_TIME, 0); |
||||
+ time_return(STALE_TIME + 1, 0); |
||||
kdc_insert_lookaside(context, &req2, NULL); |
||||
|
||||
assert_null(K5_LIST_FIRST(&hash_table[req_hash1])); |
||||
diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c |
||||
index cf1ea361f..5b9bb9573 100644 |
||||
--- a/src/lib/krb5/krb/gc_via_tkt.c |
||||
+++ b/src/lib/krb5/krb/gc_via_tkt.c |
||||
@@ -306,8 +306,8 @@ krb5int_process_tgs_reply(krb5_context context, |
||||
goto cleanup; |
||||
|
||||
if (!in_cred->times.starttime && |
||||
- !in_clock_skew(context, dec_rep->enc_part2->times.starttime, |
||||
- timestamp)) { |
||||
+ !ts_within(dec_rep->enc_part2->times.starttime, timestamp, |
||||
+ context->clockskew)) { |
||||
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 7178bd87b..ed15550f0 100644 |
||||
--- a/src/lib/krb5/krb/get_in_tkt.c |
||||
+++ b/src/lib/krb5/krb/get_in_tkt.c |
||||
@@ -269,8 +269,8 @@ verify_as_reply(krb5_context context, |
||||
return retval; |
||||
} else { |
||||
if ((request->from == 0) && |
||||
- !in_clock_skew(context, as_reply->enc_part2->times.starttime, |
||||
- time_now)) |
||||
+ !ts_within(as_reply->enc_part2->times.starttime, time_now, |
||||
+ context->clockskew)) |
||||
return (KRB5_KDCREP_SKEW); |
||||
} |
||||
return 0; |
||||
@@ -781,7 +781,7 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx) |
||||
if (ctx->renew_life > 0) { |
||||
/* Don't ask for a smaller renewable time than the lifetime. */ |
||||
ctx->request->rtime = ts_incr(from, ctx->renew_life); |
||||
- if (ctx->request->rtime < ctx->request->till) |
||||
+ if (ts_after(ctx->request->till, ctx->request->rtime)) |
||||
ctx->request->rtime = ctx->request->till; |
||||
ctx->request->kdc_options &= ~KDC_OPT_RENEWABLE_OK; |
||||
} else { |
||||
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h |
||||
index 48bd9f8f7..9c746d05b 100644 |
||||
--- a/src/lib/krb5/krb/int-proto.h |
||||
+++ b/src/lib/krb5/krb/int-proto.h |
||||
@@ -83,9 +83,6 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options, |
||||
krb5_creds *in_creds, krb5_creds *mcreds, |
||||
krb5_flags *fields); |
||||
|
||||
-#define in_clock_skew(context, date, now) \ |
||||
- (labs(ts_delta(date, now)) < (context)->clockskew) |
||||
- |
||||
#define IS_TGS_PRINC(p) ((p)->length == 2 && \ |
||||
data_eq_string((p)->data[0], KRB5_TGS_NAME)) |
||||
|
||||
diff --git a/src/lib/krb5/krb/valid_times.c b/src/lib/krb5/krb/valid_times.c |
||||
index 9e509b2dd..294761a88 100644 |
||||
--- a/src/lib/krb5/krb/valid_times.c |
||||
+++ b/src/lib/krb5/krb/valid_times.c |
||||
@@ -47,10 +47,10 @@ krb5int_validate_times(krb5_context context, krb5_ticket_times *times) |
||||
else |
||||
starttime = times->authtime; |
||||
|
||||
- if (ts_delta(starttime, currenttime) > context->clockskew) |
||||
+ if (ts_after(starttime, ts_incr(currenttime, context->clockskew))) |
||||
return KRB5KRB_AP_ERR_TKT_NYV; /* ticket not yet valid */ |
||||
|
||||
- if (ts_delta(currenttime, times->endtime) > context->clockskew) |
||||
+ if (ts_after(currenttime, ts_incr(times->endtime, context->clockskew))) |
||||
return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */ |
||||
|
||||
return 0; |
||||
diff --git a/src/lib/krb5/os/timeofday.c b/src/lib/krb5/os/timeofday.c |
||||
index 887f24c22..d4e36b1c7 100644 |
||||
--- a/src/lib/krb5/os/timeofday.c |
||||
+++ b/src/lib/krb5/os/timeofday.c |
||||
@@ -60,7 +60,7 @@ krb5_check_clockskew(krb5_context context, krb5_timestamp date) |
||||
retval = krb5_timeofday(context, ¤ttime); |
||||
if (retval) |
||||
return retval; |
||||
- if (labs(ts_delta(date, currenttime)) >= context->clockskew) |
||||
+ if (!ts_within(date, currenttime, context->clockskew)) |
||||
return KRB5KRB_AP_ERR_SKEW; |
||||
|
||||
return 0; |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
From 3b2376b47a9f1fc7dfd138d4ecc70e5d8897dc2b Mon Sep 17 00:00:00 2001 |
||||
From: Greg Hudson <ghudson@mit.edu> |
||||
Date: Thu, 13 Jul 2017 12:14:20 -0400 |
||||
Subject: [PATCH] Prevent KDC unset status assertion failures |
||||
|
||||
Assign status values if S4U2Self padata fails to decode, if an |
||||
S4U2Proxy request uses invalid KDC options, or if an S4U2Proxy request |
||||
uses an evidence ticket which does not match the canonicalized request |
||||
server principal name. Reported by Samuel Cabrero. |
||||
|
||||
If a status value is not assigned during KDC processing, default to |
||||
"UNKNOWN_REASON" rather than failing an assertion. This change will |
||||
prevent future denial of service bugs due to similar mistakes, and |
||||
will allow us to omit assigning status values for unlikely errors such |
||||
as small memory allocation failures. |
||||
|
||||
CVE-2017-11368: |
||||
|
||||
In MIT krb5 1.7 and later, an authenticated attacker can cause an |
||||
assertion failure in krb5kdc by sending an invalid S4U2Self or |
||||
S4U2Proxy request. |
||||
|
||||
CVSSv3 Vector: AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H/E:H/RL:O/RC:C |
||||
|
||||
ticket: 8599 (new) |
||||
target_version: 1.15-next |
||||
target_version: 1.14-next |
||||
tags: pullup |
||||
|
||||
(cherry picked from commit ffb35baac6981f9e8914f8f3bffd37f284b85970) |
||||
--- |
||||
src/kdc/do_as_req.c | 4 ++-- |
||||
src/kdc/do_tgs_req.c | 3 ++- |
||||
src/kdc/kdc_util.c | 10 ++++++++-- |
||||
3 files changed, 12 insertions(+), 5 deletions(-) |
||||
|
||||
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c |
||||
index 241b05b40..f5cf8ad89 100644 |
||||
--- a/src/kdc/do_as_req.c |
||||
+++ b/src/kdc/do_as_req.c |
||||
@@ -372,8 +372,8 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode) |
||||
did_log = 1; |
||||
|
||||
egress: |
||||
- if (errcode != 0) |
||||
- assert (state->status != 0); |
||||
+ if (errcode != 0 && state->status == NULL) |
||||
+ state->status = "UNKNOWN_REASON"; |
||||
|
||||
au_state->status = state->status; |
||||
au_state->reply = &state->reply; |
||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c |
||||
index 4c722a4a3..0009a9319 100644 |
||||
--- a/src/kdc/do_tgs_req.c |
||||
+++ b/src/kdc/do_tgs_req.c |
||||
@@ -829,7 +829,8 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt, |
||||
free(reply.enc_part.ciphertext.data); |
||||
|
||||
cleanup: |
||||
- assert(status != NULL); |
||||
+ if (status == NULL) |
||||
+ status = "UNKNOWN_REASON"; |
||||
if (reply_key) |
||||
krb5_free_keyblock(kdc_context, reply_key); |
||||
if (errcode) |
||||
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c |
||||
index 8cbdf2c5b..5455e2a67 100644 |
||||
--- a/src/kdc/kdc_util.c |
||||
+++ b/src/kdc/kdc_util.c |
||||
@@ -1213,8 +1213,10 @@ kdc_process_for_user(kdc_realm_t *kdc_active_realm, |
||||
req_data.data = (char *)pa_data->contents; |
||||
|
||||
code = decode_krb5_pa_for_user(&req_data, &for_user); |
||||
- if (code) |
||||
+ if (code) { |
||||
+ *status = "DECODE_PA_FOR_USER"; |
||||
return code; |
||||
+ } |
||||
|
||||
code = verify_for_user_checksum(kdc_context, tgs_session, for_user); |
||||
if (code) { |
||||
@@ -1313,8 +1315,10 @@ kdc_process_s4u_x509_user(krb5_context context, |
||||
req_data.data = (char *)pa_data->contents; |
||||
|
||||
code = decode_krb5_pa_s4u_x509_user(&req_data, s4u_x509_user); |
||||
- if (code) |
||||
+ if (code) { |
||||
+ *status = "DECODE_PA_S4U_X509_USER"; |
||||
return code; |
||||
+ } |
||||
|
||||
code = verify_s4u_x509_user_checksum(context, |
||||
tgs_subkey ? tgs_subkey : |
||||
@@ -1617,6 +1621,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, |
||||
* that is validated previously in validate_tgs_request(). |
||||
*/ |
||||
if (request->kdc_options & (NON_TGT_OPTION | KDC_OPT_ENC_TKT_IN_SKEY)) { |
||||
+ *status = "INVALID_S4U2PROXY_OPTIONS"; |
||||
return KRB5KDC_ERR_BADOPTION; |
||||
} |
||||
|
||||
@@ -1624,6 +1629,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, |
||||
if (!krb5_principal_compare(kdc_context, |
||||
server->princ, /* after canon */ |
||||
server_princ)) { |
||||
+ *status = "EVIDENCE_TICKET_MISMATCH"; |
||||
return KRB5KDC_ERR_SERVER_NOMATCH; |
||||
} |
@ -0,0 +1,134 @@
@@ -0,0 +1,134 @@
|
||||
From 9ff3ed399f9a5bb0c6101a986798d80ecc7a1b92 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 13077ecf4..a4b2a5432 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 10b333c38..166e68f9a 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, |
@ -0,0 +1,327 @@
@@ -0,0 +1,327 @@
|
||||
From f181bf6ee4ff66489895a8c543521cbec253d1f9 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 656dddff5..c2cf69169 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 f4a9a2ad2..0d4f0a632 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; |
||||
@@ -1888,7 +1888,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) { |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
From 685698f8d33810ce085da4d75d1d8febe5323fd3 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) |
||||
(cherry picked from commit 6411398e35e343cdc4d2d103b079c4d3b9031f7e) |
||||
--- |
||||
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); |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh |
||||
# |
||||
# Check for error conditions which the init system expects us to check and |
||||
# for other common errors, and exit with the expected status codes. |
||||
# |
||||
kadmind=/usr/sbin/kadmind |
||||
if test -f /var/kerberos/krb5kdc/kpropd.acl ; then |
||||
echo $"Error. This appears to be a slave server, found kpropd.acl" |
||||
exit 6 |
||||
fi |
||||
if ! test -x "$kadmind" ; then |
||||
exit 5 |
||||
fi |
||||
exec "$kadmind" "$@" |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh |
||||
# |
||||
# Check for error conditions which the init system expects us to check and |
||||
# for other common errors, and exit with the expected status codes. |
||||
# |
||||
kpropd=/usr/sbin/kpropd |
||||
if ! test -f /var/kerberos/krb5kdc/kpropd.acl ; then |
||||
echo $"Error. This does not appear to be a slave server, kpropd.acl not found" |
||||
exit 6 |
||||
fi |
||||
if ! test -x "$kpropd" ; then |
||||
exit 5 |
||||
fi |
||||
exec "$kpropd" "$@" |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
[Unit] |
||||
Description=Kerberos 5 Password-changing and Administration |
||||
After=syslog.target network.target |
||||
|
||||
[Service] |
||||
Type=forking |
||||
PIDFile=/var/run/kadmind.pid |
||||
EnvironmentFile=-/etc/sysconfig/kadmin |
||||
ExecStart=/usr/sbin/_kadmind -P /var/run/kadmind.pid $KADMIND_ARGS |
||||
ExecReload=/bin/kill -HUP $MAINPID |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,108 @@
@@ -0,0 +1,108 @@
|
||||
#!/bin/bash |
||||
# |
||||
# kadmind Start and stop the Kerberos 5 administrative server. |
||||
# |
||||
# chkconfig: - 35 65 |
||||
# description: Kerberos 5 is a trusted third-party authentication system. \ |
||||
# This script starts and stops the Kerberos 5 administrative \ |
||||
# server, which should only be run on the master server for a \ |
||||
# realm. |
||||
# processname: kadmind |
||||
# config: /etc/sysconfig/kadmin |
||||
# pidfile: /var/run/kadmind.pid |
||||
# |
||||
|
||||
### BEGIN INIT INFO |
||||
# Provides: kadmin |
||||
# Required-Start: $local_fs $network |
||||
# Required-Stop: $local_fs $network |
||||
# Should-Start: portreserve |
||||
# Default-Start: |
||||
# Default-Stop: 0 1 2 3 4 5 6 |
||||
# Short-Description: start and stop the Kerberos 5 admin server |
||||
# Description: The kadmind service allows administrators to remotely manage \ |
||||
# the Kerberos 5 realm database. It should only be run on a \ |
||||
# master KDC. |
||||
### END INIT INFO |
||||
|
||||
# Get config. |
||||
. /etc/sysconfig/network |
||||
|
||||
# Get config. |
||||
[ -r /etc/sysconfig/kadmin ] && . /etc/sysconfig/kadmin |
||||
|
||||
# Source function library. |
||||
. /etc/init.d/functions |
||||
prog="Kerberos 5 Admin Server" |
||||
kadmind=/usr/sbin/kadmind |
||||
pidfile=/var/run/kadmind.pid |
||||
|
||||
RETVAL=0 |
||||
|
||||
# Shell functions to cut down on useless shell instances. |
||||
start() { |
||||
if [ -f /var/kerberos/krb5kdc/kpropd.acl ] ; then |
||||
echo $"Error. This appears to be a slave server, found kpropd.acl" |
||||
exit 6 |
||||
else |
||||
[ -x $kadmind ] || exit 5 |
||||
fi |
||||
echo -n $"Starting $prog: " |
||||
# tell portreserve to release the kerberos-adm port |
||||
[ -x /sbin/portrelease ] && /sbin/portrelease kerberos-adm &>/dev/null || : |
||||
daemon ${kadmind} ${KRB5REALM:+-r ${KRB5REALM}} -P $pidfile $KADMIND_ARGS |
||||
RETVAL=$? |
||||
echo |
||||
if test $RETVAL -ne 0 ; then |
||||
if status -l kadmin ${kadmind} > /dev/null ; then |
||||
RETVAL=0 |
||||
fi |
||||
fi |
||||
[ $RETVAL = 0 ] && touch /var/lock/subsys/kadmin |
||||
} |
||||
stop() { |
||||
echo -n $"Stopping $prog: " |
||||
killproc ${kadmind} |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/kadmin |
||||
} |
||||
reload() { |
||||
echo -n $"Reopening $prog log file: " |
||||
killproc ${kadmind} -HUP |
||||
RETVAL=$? |
||||
echo |
||||
} |
||||
|
||||
# See how we were called. |
||||
case "$1" in |
||||
start) |
||||
start |
||||
;; |
||||
stop) |
||||
stop |
||||
;; |
||||
restart) |
||||
stop |
||||
start |
||||
;; |
||||
status) |
||||
status -l kadmin ${kadmind} |
||||
RETVAL=$? |
||||
;; |
||||
reload) |
||||
reload |
||||
;; |
||||
condrestart) |
||||
if [ -f /var/lock/subsys/kadmin ] ; then |
||||
stop |
||||
start |
||||
fi |
||||
;; |
||||
*) |
||||
echo $"Usage: $0 {start|stop|status|condrestart|reload|restart}" |
||||
RETVAL=2 |
||||
;; |
||||
esac |
||||
|
||||
exit $RETVAL |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
/var/log/kadmind.log { |
||||
missingok |
||||
notifempty |
||||
monthly |
||||
rotate 12 |
||||
postrotate |
||||
/bin/kill -HUP `cat /var/run/kadmind.pid 2>/dev/null` 2> /dev/null || true |
||||
endscript |
||||
} |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
[kdcdefaults] |
||||
kdc_ports = 88 |
||||
kdc_tcp_ports = 88 |
||||
|
||||
[realms] |
||||
EXAMPLE.COM = { |
||||
#master_key_type = aes256-cts |
||||
acl_file = /var/kerberos/krb5kdc/kadm5.acl |
||||
dict_file = /usr/share/dict/words |
||||
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab |
||||
supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
[Unit] |
||||
Description=Kerberos 5 Propagation |
||||
After=syslog.target network.target |
||||
|
||||
[Service] |
||||
Type=forking |
||||
EnvironmentFile=-/etc/sysconfig/kprop |
||||
ExecStart=/usr/sbin/_kpropd $KPROPD_ARGS |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
#!/bin/bash |
||||
# |
||||
# kpropd.init Start and stop the Kerberos 5 propagation client. |
||||
# |
||||
# chkconfig: - 35 65 |
||||
# description: Kerberos 5 is a trusted third-party authentication system. \ |
||||
# This script starts and stops the service that allows this \ |
||||
# KDC to receive updates from your master KDC. |
||||
# processname: kpropd |
||||
# |
||||
|
||||
### BEGIN INIT INFO |
||||
# Provides: kprop |
||||
# Required-Start: $local_fs $network |
||||
# Required-Stop: $local_fs $network |
||||
# Should-Start: portreserve |
||||
# Default-Start: |
||||
# Default-Stop: 0 1 2 3 4 5 6 |
||||
# Short-Description: start and stop the Kerberos 5 propagation client |
||||
# Description: The kpropd service accepts database updates pushed to it from \ |
||||
# the master KDC. It will never be needed on a master KDC. |
||||
### END INIT INFO |
||||
|
||||
# Get config. |
||||
. /etc/sysconfig/network |
||||
|
||||
# Source function library. |
||||
. /etc/init.d/functions |
||||
|
||||
RETVAL=0 |
||||
prog="Kerberos 5 Propagation Server" |
||||
kpropd=/usr/sbin/kpropd |
||||
|
||||
# Shell functions to cut down on useless shell instances. |
||||
start() { |
||||
[ -f /var/kerberos/krb5kdc/kpropd.acl ] || exit 6 |
||||
[ -x $kpropd ] || exit 5 |
||||
echo -n $"Starting $prog: " |
||||
# tell portreserve to release the krb5_prop port |
||||
[ -x /sbin/portrelease ] && /sbin/portrelease krb5_prop &>/dev/null || : |
||||
daemon ${kpropd} -S |
||||
RETVAL=$? |
||||
echo |
||||
if test $RETVAL -ne 0 ; then |
||||
if status -l kprop ${kpropd} > /dev/null ; then |
||||
RETVAL=0 |
||||
fi |
||||
fi |
||||
[ $RETVAL = 0 ] && touch /var/lock/subsys/kprop |
||||
} |
||||
stop() { |
||||
echo -n $"Stopping $prog: " |
||||
killproc ${kpropd} |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/kprop |
||||
} |
||||
|
||||
# See how we were called. |
||||
case "$1" in |
||||
start) |
||||
start |
||||
;; |
||||
stop) |
||||
stop |
||||
;; |
||||
# We don't really "do" reload, so treat it as a restart. |
||||
restart|force-reload) |
||||
stop |
||||
start |
||||
;; |
||||
reload) |
||||
echo "can't reload configuration, you have to restart it" |
||||
RETVAL=3 |
||||
;; |
||||
status) |
||||
status -l kprop ${kpropd} |
||||
RETVAL=$? |
||||
;; |
||||
condrestart) |
||||
if [ -f /var/lock/subsys/kprop ] ; then |
||||
stop |
||||
start |
||||
fi |
||||
;; |
||||
*) |
||||
echo $"Usage: $0 {start|stop|restart|condrestart|reload|status|force-reload}" |
||||
RETVAL=2 |
||||
;; |
||||
esac |
||||
|
||||
exit $RETVAL |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
From c21187b3a9f37fd88230e963275d3242344f8f82 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 10:03:40 -0400 |
||||
Subject: [PATCH] krb5-1.11-kpasswdtest.patch |
||||
|
||||
--- |
||||
src/kadmin/testing/proto/krb5.conf.proto | 1 + |
||||
1 file changed, 1 insertion(+) |
||||
|
||||
diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto |
||||
index 00c442978..9c4bc1de7 100644 |
||||
--- a/src/kadmin/testing/proto/krb5.conf.proto |
||||
+++ b/src/kadmin/testing/proto/krb5.conf.proto |
||||
@@ -9,6 +9,7 @@ |
||||
__REALM__ = { |
||||
kdc = __KDCHOST__:1750 |
||||
admin_server = __KDCHOST__:1751 |
||||
+ kpasswd_server = __KDCHOST__:1752 |
||||
database_module = foobar_db2_module_blah |
||||
} |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
From b22fe94f6965ebdd2e0cbf2ac002e0e5f9c11789 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 10:03:22 -0400 |
||||
Subject: [PATCH] krb5-1.11-run_user_0.patch |
||||
|
||||
--- |
||||
src/lib/krb5/ccache/cc_dir.c | 14 ++++++++++++++ |
||||
1 file changed, 14 insertions(+) |
||||
|
||||
diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c |
||||
index 73f0fe62d..4850c0d07 100644 |
||||
--- a/src/lib/krb5/ccache/cc_dir.c |
||||
+++ b/src/lib/krb5/ccache/cc_dir.c |
||||
@@ -61,6 +61,8 @@ |
||||
|
||||
#include <dirent.h> |
||||
|
||||
+#define ROOT_SPECIAL_DCC_PARENT "/run/user/0" |
||||
+ |
||||
extern const krb5_cc_ops krb5_dcc_ops; |
||||
extern const krb5_cc_ops krb5_fcc_ops; |
||||
|
||||
@@ -237,6 +239,18 @@ verify_dir(krb5_context context, const char *dirname) |
||||
|
||||
if (stat(dirname, &st) < 0) { |
||||
if (errno == ENOENT) { |
||||
+ if (strncmp(dirname, ROOT_SPECIAL_DCC_PARENT "/", |
||||
+ sizeof(ROOT_SPECIAL_DCC_PARENT)) == 0 && |
||||
+ stat(ROOT_SPECIAL_DCC_PARENT, &st) < 0 && |
||||
+ errno == ENOENT) { |
||||
+#ifdef USE_SELINUX |
||||
+ selabel = krb5int_push_fscreatecon_for(ROOT_SPECIAL_DCC_PARENT); |
||||
+#endif |
||||
+ status = mkdir(ROOT_SPECIAL_DCC_PARENT, S_IRWXU); |
||||
+#ifdef USE_SELINUX |
||||
+ krb5int_pop_fscreatecon(selabel); |
||||
+#endif |
||||
+ } |
||||
#ifdef USE_SELINUX |
||||
selabel = krb5int_push_fscreatecon_for(dirname); |
||||
#endif |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
From a609a605d87b3107de64141cd3d60c2a73c7b38f Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 09:59:22 -0400 |
||||
Subject: [PATCH] krb5-1.12-api.patch |
||||
|
||||
--- |
||||
src/lib/krb5/krb/princ_comp.c | 7 +++++++ |
||||
1 file changed, 7 insertions(+) |
||||
|
||||
diff --git a/src/lib/krb5/krb/princ_comp.c b/src/lib/krb5/krb/princ_comp.c |
||||
index a6936107d..0ed78833b 100644 |
||||
--- a/src/lib/krb5/krb/princ_comp.c |
||||
+++ b/src/lib/krb5/krb/princ_comp.c |
||||
@@ -36,6 +36,10 @@ realm_compare_flags(krb5_context context, |
||||
const krb5_data *realm1 = &princ1->realm; |
||||
const krb5_data *realm2 = &princ2->realm; |
||||
|
||||
+ if (princ1 == NULL || princ2 == NULL) |
||||
+ return FALSE; |
||||
+ if (realm1 == NULL || realm2 == NULL) |
||||
+ return FALSE; |
||||
if (realm1->length != realm2->length) |
||||
return FALSE; |
||||
if (realm1->length == 0) |
||||
@@ -88,6 +92,9 @@ krb5_principal_compare_flags(krb5_context context, |
||||
krb5_principal upn2 = NULL; |
||||
krb5_boolean ret = FALSE; |
||||
|
||||
+ if (princ1 == NULL || princ2 == NULL) |
||||
+ return FALSE; |
||||
+ |
||||
if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) { |
||||
/* Treat UPNs as if they were real principals */ |
||||
if (princ1->type == KRB5_NT_ENTERPRISE_PRINCIPAL) { |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
From fc004dc501c6fc1f1f423a8d87cdc9137d7f6bbf Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 09:57:25 -0400 |
||||
Subject: [PATCH] krb5-1.12-ksu-path.patch |
||||
|
||||
--- |
||||
src/clients/ksu/Makefile.in | 2 +- |
||||
1 file changed, 1 insertion(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in |
||||
index 5755bb58a..9d58f29b5 100644 |
||||
--- a/src/clients/ksu/Makefile.in |
||||
+++ b/src/clients/ksu/Makefile.in |
||||
@@ -1,6 +1,6 @@ |
||||
mydir=clients$(S)ksu |
||||
BUILDTOP=$(REL)..$(S).. |
||||
-DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"' |
||||
+DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"' |
||||
|
||||
KSU_LIBS=@KSU_LIBS@ |
||||
PAM_LIBS=@PAM_LIBS@ |
@ -0,0 +1,363 @@
@@ -0,0 +1,363 @@
|
||||
From 5c9294c37210d01f59c54ea623a66618ed2e0e6e Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 09:58:00 -0400 |
||||
Subject: [PATCH] krb5-1.12-ktany.patch |
||||
|
||||
--- |
||||
src/lib/krb5/keytab/Makefile.in | 3 + |
||||
src/lib/krb5/keytab/kt_any.c | 292 ++++++++++++++++++++++++++++++++++++++++ |
||||
src/lib/krb5/keytab/ktbase.c | 7 +- |
||||
3 files changed, 301 insertions(+), 1 deletion(-) |
||||
create mode 100644 src/lib/krb5/keytab/kt_any.c |
||||
|
||||
diff --git a/src/lib/krb5/keytab/Makefile.in b/src/lib/krb5/keytab/Makefile.in |
||||
index 2a8fceb00..ffd179fb2 100644 |
||||
--- a/src/lib/krb5/keytab/Makefile.in |
||||
+++ b/src/lib/krb5/keytab/Makefile.in |
||||
@@ -12,6 +12,7 @@ STLIBOBJS= \ |
||||
ktfr_entry.o \ |
||||
ktremove.o \ |
||||
ktfns.o \ |
||||
+ kt_any.o \ |
||||
kt_file.o \ |
||||
kt_memory.o \ |
||||
kt_srvtab.o \ |
||||
@@ -24,6 +25,7 @@ OBJS= \ |
||||
$(OUTPRE)ktfr_entry.$(OBJEXT) \ |
||||
$(OUTPRE)ktremove.$(OBJEXT) \ |
||||
$(OUTPRE)ktfns.$(OBJEXT) \ |
||||
+ $(OUTPRE)kt_any.$(OBJEXT) \ |
||||
$(OUTPRE)kt_file.$(OBJEXT) \ |
||||
$(OUTPRE)kt_memory.$(OBJEXT) \ |
||||
$(OUTPRE)kt_srvtab.$(OBJEXT) \ |
||||
@@ -36,6 +38,7 @@ SRCS= \ |
||||
$(srcdir)/ktfr_entry.c \ |
||||
$(srcdir)/ktremove.c \ |
||||
$(srcdir)/ktfns.c \ |
||||
+ $(srcdir)/kt_any.c \ |
||||
$(srcdir)/kt_file.c \ |
||||
$(srcdir)/kt_memory.c \ |
||||
$(srcdir)/kt_srvtab.c \ |
||||
diff --git a/src/lib/krb5/keytab/kt_any.c b/src/lib/krb5/keytab/kt_any.c |
||||
new file mode 100644 |
||||
index 000000000..1b9b7765b |
||||
--- /dev/null |
||||
+++ b/src/lib/krb5/keytab/kt_any.c |
||||
@@ -0,0 +1,292 @@ |
||||
+/* |
||||
+ * lib/krb5/keytab/kt_any.c |
||||
+ * |
||||
+ * Copyright 1998, 1999 by the Massachusetts Institute of Technology. |
||||
+ * All Rights Reserved. |
||||
+ * |
||||
+ * Export of this software from the United States of America may |
||||
+ * require a specific license from the United States Government. |
||||
+ * It is the responsibility of any person or organization contemplating |
||||
+ * export to obtain such a license before exporting. |
||||
+ * |
||||
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and |
||||
+ * distribute this software and its documentation for any purpose and |
||||
+ * without fee is hereby granted, provided that the above copyright |
||||
+ * notice appear in all copies and that both that copyright notice and |
||||
+ * this permission notice appear in supporting documentation, and that |
||||
+ * the name of M.I.T. not be used in advertising or publicity pertaining |
||||
+ * to distribution of the software without specific, written prior |
||||
+ * permission. 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. |
||||
+ * |
||||
+ * |
||||
+ * krb5_kta_ops |
||||
+ */ |
||||
+ |
||||
+#include "k5-int.h" |
||||
+ |
||||
+typedef struct _krb5_ktany_data { |
||||
+ char *name; |
||||
+ krb5_keytab *choices; |
||||
+ int nchoices; |
||||
+} krb5_ktany_data; |
||||
+ |
||||
+typedef struct _krb5_ktany_cursor_data { |
||||
+ int which; |
||||
+ krb5_kt_cursor cursor; |
||||
+} krb5_ktany_cursor_data; |
||||
+ |
||||
+static krb5_error_code krb5_ktany_resolve |
||||
+ (krb5_context, |
||||
+ const char *, |
||||
+ krb5_keytab *); |
||||
+static krb5_error_code krb5_ktany_get_name |
||||
+ (krb5_context context, |
||||
+ krb5_keytab id, |
||||
+ char *name, |
||||
+ unsigned int len); |
||||
+static krb5_error_code krb5_ktany_close |
||||
+ (krb5_context context, |
||||
+ krb5_keytab id); |
||||
+static krb5_error_code krb5_ktany_get_entry |
||||
+ (krb5_context context, |
||||
+ krb5_keytab id, |
||||
+ krb5_const_principal principal, |
||||
+ krb5_kvno kvno, |
||||
+ krb5_enctype enctype, |
||||
+ krb5_keytab_entry *entry); |
||||
+static krb5_error_code krb5_ktany_start_seq_get |
||||
+ (krb5_context context, |
||||
+ krb5_keytab id, |
||||
+ krb5_kt_cursor *cursorp); |
||||
+static krb5_error_code krb5_ktany_next_entry |
||||
+ (krb5_context context, |
||||
+ krb5_keytab id, |
||||
+ krb5_keytab_entry *entry, |
||||
+ krb5_kt_cursor *cursor); |
||||
+static krb5_error_code krb5_ktany_end_seq_get |
||||
+ (krb5_context context, |
||||
+ krb5_keytab id, |
||||
+ krb5_kt_cursor *cursor); |
||||
+static void cleanup |
||||
+ (krb5_context context, |
||||
+ krb5_ktany_data *data, |
||||
+ int nchoices); |
||||
+ |
||||
+struct _krb5_kt_ops krb5_kta_ops = { |
||||
+ 0, |
||||
+ "ANY", /* Prefix -- this string should not appear anywhere else! */ |
||||
+ krb5_ktany_resolve, |
||||
+ krb5_ktany_get_name, |
||||
+ krb5_ktany_close, |
||||
+ krb5_ktany_get_entry, |
||||
+ krb5_ktany_start_seq_get, |
||||
+ krb5_ktany_next_entry, |
||||
+ krb5_ktany_end_seq_get, |
||||
+ NULL, |
||||
+ NULL, |
||||
+ NULL, |
||||
+}; |
||||
+ |
||||
+static krb5_error_code |
||||
+krb5_ktany_resolve(context, name, id) |
||||
+ krb5_context context; |
||||
+ const char *name; |
||||
+ krb5_keytab *id; |
||||
+{ |
||||
+ const char *p, *q; |
||||
+ char *copy; |
||||
+ krb5_error_code kerror; |
||||
+ krb5_ktany_data *data; |
||||
+ int i; |
||||
+ |
||||
+ /* Allocate space for our data and remember a copy of the name. */ |
||||
+ if ((data = (krb5_ktany_data *)malloc(sizeof(krb5_ktany_data))) == NULL) |
||||
+ return(ENOMEM); |
||||
+ if ((data->name = (char *)malloc(strlen(name) + 1)) == NULL) { |
||||
+ free(data); |
||||
+ return(ENOMEM); |
||||
+ } |
||||
+ strcpy(data->name, name); |
||||
+ |
||||
+ /* Count the number of choices and allocate memory for them. */ |
||||
+ data->nchoices = 1; |
||||
+ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) |
||||
+ data->nchoices++; |
||||
+ if ((data->choices = (krb5_keytab *) |
||||
+ malloc(data->nchoices * sizeof(krb5_keytab))) == NULL) { |
||||
+ free(data->name); |
||||
+ free(data); |
||||
+ return(ENOMEM); |
||||
+ } |
||||
+ |
||||
+ /* Resolve each of the choices. */ |
||||
+ i = 0; |
||||
+ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) { |
||||
+ /* Make a copy of the choice name so we can terminate it. */ |
||||
+ if ((copy = (char *)malloc(q - p + 1)) == NULL) { |
||||
+ cleanup(context, data, i); |
||||
+ return(ENOMEM); |
||||
+ } |
||||
+ memcpy(copy, p, q - p); |
||||
+ copy[q - p] = 0; |
||||
+ |
||||
+ /* Try resolving the choice name. */ |
||||
+ kerror = krb5_kt_resolve(context, copy, &data->choices[i]); |
||||
+ free(copy); |
||||
+ if (kerror) { |
||||
+ cleanup(context, data, i); |
||||
+ return(kerror); |
||||
+ } |
||||
+ i++; |
||||
+ } |
||||
+ if ((kerror = krb5_kt_resolve(context, p, &data->choices[i]))) { |
||||
+ cleanup(context, data, i); |
||||
+ return(kerror); |
||||
+ } |
||||
+ |
||||
+ /* Allocate and fill in an ID for the caller. */ |
||||
+ if ((*id = (krb5_keytab)malloc(sizeof(**id))) == NULL) { |
||||
+ cleanup(context, data, i); |
||||
+ return(ENOMEM); |
||||
+ } |
||||
+ (*id)->ops = &krb5_kta_ops; |
||||
+ (*id)->data = (krb5_pointer)data; |
||||
+ (*id)->magic = KV5M_KEYTAB; |
||||
+ |
||||
+ return(0); |
||||
+} |
||||
+ |
||||
+static krb5_error_code |
||||
+krb5_ktany_get_name(context, id, name, len) |
||||
+ krb5_context context; |
||||
+ krb5_keytab id; |
||||
+ char *name; |
||||
+ unsigned int len; |
||||
+{ |
||||
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data; |
||||
+ |
||||
+ if (len < strlen(data->name) + 1) |
||||
+ return(KRB5_KT_NAME_TOOLONG); |
||||
+ strcpy(name, data->name); |
||||
+ return(0); |
||||
+} |
||||
+ |
||||
+static krb5_error_code |
||||
+krb5_ktany_close(context, id) |
||||
+ krb5_context context; |
||||
+ krb5_keytab id; |
||||
+{ |
||||
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data; |
||||
+ |
||||
+ cleanup(context, data, data->nchoices); |
||||
+ id->ops = 0; |
||||
+ free(id); |
||||
+ return(0); |
||||
+} |
||||
+ |
||||
+static krb5_error_code |
||||
+krb5_ktany_get_entry(context, id, principal, kvno, enctype, entry) |
||||
+ krb5_context context; |
||||
+ krb5_keytab id; |
||||
+ krb5_const_principal principal; |
||||
+ krb5_kvno kvno; |
||||
+ krb5_enctype enctype; |
||||
+ krb5_keytab_entry *entry; |
||||
+{ |
||||
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data; |
||||
+ krb5_error_code kerror = KRB5_KT_NOTFOUND; |
||||
+ int i; |
||||
+ |
||||
+ for (i = 0; i < data->nchoices; i++) { |
||||
+ if ((kerror = krb5_kt_get_entry(context, data->choices[i], principal, |
||||
+ kvno, enctype, entry)) != ENOENT) |
||||
+ return kerror; |
||||
+ } |
||||
+ return kerror; |
||||
+} |
||||
+ |
||||
+static krb5_error_code |
||||
+krb5_ktany_start_seq_get(context, id, cursorp) |
||||
+ krb5_context context; |
||||
+ krb5_keytab id; |
||||
+ krb5_kt_cursor *cursorp; |
||||
+{ |
||||
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data; |
||||
+ krb5_ktany_cursor_data *cdata; |
||||
+ krb5_error_code kerror = ENOENT; |
||||
+ int i; |
||||
+ |
||||
+ if ((cdata = (krb5_ktany_cursor_data *) |
||||
+ malloc(sizeof(krb5_ktany_cursor_data))) == NULL) |
||||
+ return(ENOMEM); |
||||
+ |
||||
+ /* Find a choice which can handle the serialization request. */ |
||||
+ for (i = 0; i < data->nchoices; i++) { |
||||
+ if ((kerror = krb5_kt_start_seq_get(context, data->choices[i], |
||||
+ &cdata->cursor)) == 0) |
||||
+ break; |
||||
+ else if (kerror != ENOENT) { |
||||
+ free(cdata); |
||||
+ return(kerror); |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ if (i == data->nchoices) { |
||||
+ /* Everyone returned ENOENT, so no go. */ |
||||
+ free(cdata); |
||||
+ return(kerror); |
||||
+ } |
||||
+ |
||||
+ cdata->which = i; |
||||
+ *cursorp = (krb5_kt_cursor)cdata; |
||||
+ return(0); |
||||
+} |
||||
+ |
||||
+static krb5_error_code |
||||
+krb5_ktany_next_entry(context, id, entry, cursor) |
||||
+ krb5_context context; |
||||
+ krb5_keytab id; |
||||
+ krb5_keytab_entry *entry; |
||||
+ krb5_kt_cursor *cursor; |
||||
+{ |
||||
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data; |
||||
+ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor; |
||||
+ krb5_keytab choice_id; |
||||
+ |
||||
+ choice_id = data->choices[cdata->which]; |
||||
+ return(krb5_kt_next_entry(context, choice_id, entry, &cdata->cursor)); |
||||
+} |
||||
+ |
||||
+static krb5_error_code |
||||
+krb5_ktany_end_seq_get(context, id, cursor) |
||||
+ krb5_context context; |
||||
+ krb5_keytab id; |
||||
+ krb5_kt_cursor *cursor; |
||||
+{ |
||||
+ krb5_ktany_data *data = (krb5_ktany_data *)id->data; |
||||
+ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor; |
||||
+ krb5_keytab choice_id; |
||||
+ krb5_error_code kerror; |
||||
+ |
||||
+ choice_id = data->choices[cdata->which]; |
||||
+ kerror = krb5_kt_end_seq_get(context, choice_id, &cdata->cursor); |
||||
+ free(cdata); |
||||
+ return(kerror); |
||||
+} |
||||
+ |
||||
+static void |
||||
+cleanup(context, data, nchoices) |
||||
+ krb5_context context; |
||||
+ krb5_ktany_data *data; |
||||
+ int nchoices; |
||||
+{ |
||||
+ int i; |
||||
+ |
||||
+ free(data->name); |
||||
+ for (i = 0; i < nchoices; i++) |
||||
+ krb5_kt_close(context, data->choices[i]); |
||||
+ free(data->choices); |
||||
+ free(data); |
||||
+} |
||||
diff --git a/src/lib/krb5/keytab/ktbase.c b/src/lib/krb5/keytab/ktbase.c |
||||
index 0d39b2940..6534d7c52 100644 |
||||
--- a/src/lib/krb5/keytab/ktbase.c |
||||
+++ b/src/lib/krb5/keytab/ktbase.c |
||||
@@ -57,14 +57,19 @@ extern const krb5_kt_ops krb5_ktf_ops; |
||||
extern const krb5_kt_ops krb5_ktf_writable_ops; |
||||
extern const krb5_kt_ops krb5_kts_ops; |
||||
extern const krb5_kt_ops krb5_mkt_ops; |
||||
+extern const krb5_kt_ops krb5_kta_ops; |
||||
|
||||
struct krb5_kt_typelist { |
||||
const krb5_kt_ops *ops; |
||||
const struct krb5_kt_typelist *next; |
||||
}; |
||||
+static struct krb5_kt_typelist krb5_kt_typelist_any = { |
||||
+ &krb5_kta_ops, |
||||
+ NULL |
||||
+}; |
||||
const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = { |
||||
&krb5_kts_ops, |
||||
- NULL |
||||
+ &krb5_kt_typelist_any |
||||
}; |
||||
const static struct krb5_kt_typelist krb5_kt_typelist_memory = { |
||||
&krb5_mkt_ops, |
@ -0,0 +1,757 @@
@@ -0,0 +1,757 @@
|
||||
From 9a6c3d9c1f4286a1a17cd89a1225712606863da8 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Mon, 18 Apr 2016 15:57:38 -0400 |
||||
Subject: [PATCH] krb5-1.12.1-pam.patch |
||||
|
||||
--- |
||||
src/aclocal.m4 | 67 ++++++++ |
||||
src/clients/ksu/Makefile.in | 8 +- |
||||
src/clients/ksu/main.c | 88 +++++++++- |
||||
src/clients/ksu/pam.c | 389 ++++++++++++++++++++++++++++++++++++++++++++ |
||||
src/clients/ksu/pam.h | 57 +++++++ |
||||
src/configure.in | 2 + |
||||
6 files changed, 608 insertions(+), 3 deletions(-) |
||||
create mode 100644 src/clients/ksu/pam.c |
||||
create mode 100644 src/clients/ksu/pam.h |
||||
|
||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4 |
||||
index 9c46da4b5..508e5fe90 100644 |
||||
--- a/src/aclocal.m4 |
||||
+++ b/src/aclocal.m4 |
||||
@@ -1675,3 +1675,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[ |
||||
])) |
||||
])dnl |
||||
dnl |
||||
+dnl |
||||
+dnl Use PAM instead of local crypt() compare for checking local passwords, |
||||
+dnl and perform PAM account, session management, and password-changing where |
||||
+dnl appropriate. |
||||
+dnl |
||||
+AC_DEFUN(KRB5_WITH_PAM,[ |
||||
+AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])], |
||||
+ withpam="$withval",withpam=auto) |
||||
+AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])], |
||||
+ withksupamservice="$withval",withksupamservice=ksu) |
||||
+old_LIBS="$LIBS" |
||||
+if test "$withpam" != no ; then |
||||
+ AC_MSG_RESULT([checking for PAM...]) |
||||
+ PAM_LIBS= |
||||
+ |
||||
+ AC_CHECK_HEADERS(security/pam_appl.h) |
||||
+ if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then |
||||
+ if test "$withpam" = auto ; then |
||||
+ AC_MSG_RESULT([Unable to locate security/pam_appl.h.]) |
||||
+ withpam=no |
||||
+ else |
||||
+ AC_MSG_ERROR([Unable to locate security/pam_appl.h.]) |
||||
+ fi |
||||
+ fi |
||||
+ |
||||
+ LIBS= |
||||
+ unset ac_cv_func_pam_start |
||||
+ AC_CHECK_FUNCS(putenv pam_start) |
||||
+ if test "x$ac_cv_func_pam_start" = xno ; then |
||||
+ unset ac_cv_func_pam_start |
||||
+ AC_CHECK_LIB(dl,dlopen) |
||||
+ AC_CHECK_FUNCS(pam_start) |
||||
+ if test "x$ac_cv_func_pam_start" = xno ; then |
||||
+ AC_CHECK_LIB(pam,pam_start) |
||||
+ unset ac_cv_func_pam_start |
||||
+ unset ac_cv_func_pam_getenvlist |
||||
+ AC_CHECK_FUNCS(pam_start pam_getenvlist) |
||||
+ if test "x$ac_cv_func_pam_start" = xyes ; then |
||||
+ PAM_LIBS="$LIBS" |
||||
+ else |
||||
+ if test "$withpam" = auto ; then |
||||
+ AC_MSG_RESULT([Unable to locate libpam.]) |
||||
+ withpam=no |
||||
+ else |
||||
+ AC_MSG_ERROR([Unable to locate libpam.]) |
||||
+ fi |
||||
+ fi |
||||
+ fi |
||||
+ fi |
||||
+ if test "$withpam" != no ; then |
||||
+ AC_MSG_NOTICE([building with PAM support]) |
||||
+ AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM]) |
||||
+ AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice", |
||||
+ [Define to the name of the PAM service name to be used by ksu.]) |
||||
+ PAM_LIBS="$LIBS" |
||||
+ NON_PAM_MAN=".\\\" " |
||||
+ PAM_MAN= |
||||
+ else |
||||
+ PAM_MAN=".\\\" " |
||||
+ NON_PAM_MAN= |
||||
+ fi |
||||
+fi |
||||
+LIBS="$old_LIBS" |
||||
+AC_SUBST(PAM_LIBS) |
||||
+AC_SUBST(PAM_MAN) |
||||
+AC_SUBST(NON_PAM_MAN) |
||||
+])dnl |
||||
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in |
||||
index b2fcbf240..5755bb58a 100644 |
||||
--- a/src/clients/ksu/Makefile.in |
||||
+++ b/src/clients/ksu/Makefile.in |
||||
@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S).. |
||||
DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"' |
||||
|
||||
KSU_LIBS=@KSU_LIBS@ |
||||
+PAM_LIBS=@PAM_LIBS@ |
||||
|
||||
SRCS = \ |
||||
$(srcdir)/krb_auth_su.c \ |
||||
$(srcdir)/ccache.c \ |
||||
$(srcdir)/authorization.c \ |
||||
$(srcdir)/main.c \ |
||||
+ $(srcdir)/pam.c \ |
||||
$(srcdir)/heuristic.c \ |
||||
$(srcdir)/xmalloc.c \ |
||||
$(srcdir)/setenv.c |
||||
@@ -17,13 +19,17 @@ OBJS = \ |
||||
ccache.o \ |
||||
authorization.o \ |
||||
main.o \ |
||||
+ pam.o \ |
||||
heuristic.o \ |
||||
xmalloc.o @SETENVOBJ@ |
||||
|
||||
all: ksu |
||||
|
||||
ksu: $(OBJS) $(KRB5_BASE_DEPLIBS) |
||||
- $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) |
||||
+ $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS) |
||||
+ |
||||
+pam.o: pam.c |
||||
+ $(CC) $(ALL_CFLAGS) -c $< |
||||
|
||||
clean: |
||||
$(RM) ksu |
||||
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c |
||||
index 28342c2d7..cab0c1806 100644 |
||||
--- a/src/clients/ksu/main.c |
||||
+++ b/src/clients/ksu/main.c |
||||
@@ -26,6 +26,7 @@ |
||||
* KSU was writen by: Ari Medvinsky, ari@isi.edu |
||||
*/ |
||||
|
||||
+#include "autoconf.h" |
||||
#include "ksu.h" |
||||
#include "adm_proto.h" |
||||
#include <sys/types.h> |
||||
@@ -33,6 +34,10 @@ |
||||
#include <signal.h> |
||||
#include <grp.h> |
||||
|
||||
+#ifdef USE_PAM |
||||
+#include "pam.h" |
||||
+#endif |
||||
+ |
||||
/* globals */ |
||||
char * prog_name; |
||||
int auth_debug =0; |
||||
@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN]; |
||||
char k5users_path[MAXPATHLEN]; |
||||
char * gb_err = NULL; |
||||
int quiet = 0; |
||||
+int force_fork = 0; |
||||
/***********/ |
||||
|
||||
#define KS_TEMPORARY_CACHE "MEMORY:_ksu" |
||||
@@ -515,6 +521,23 @@ main (argc, argv) |
||||
prog_name,target_user,client_name, |
||||
source_user,ontty()); |
||||
|
||||
+#ifdef USE_PAM |
||||
+ if (appl_pam_enabled(ksu_context, "ksu")) { |
||||
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL, |
||||
+ NULL, source_user, |
||||
+ ttyname(STDERR_FILENO)) != 0) { |
||||
+ fprintf(stderr, "Access denied for %s.\n", target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+ if (appl_pam_requires_chauthtok()) { |
||||
+ fprintf(stderr, "Password change required for %s.\n", |
||||
+ target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+ force_fork++; |
||||
+ } |
||||
+#endif |
||||
+ |
||||
/* Run authorization as target.*/ |
||||
if (krb5_seteuid(target_uid)) { |
||||
com_err(prog_name, errno, _("while switching to target for " |
||||
@@ -575,6 +598,24 @@ main (argc, argv) |
||||
|
||||
exit(1); |
||||
} |
||||
+#ifdef USE_PAM |
||||
+ } else { |
||||
+ /* we always do PAM account management, even for root */ |
||||
+ if (appl_pam_enabled(ksu_context, "ksu")) { |
||||
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL, |
||||
+ NULL, source_user, |
||||
+ ttyname(STDERR_FILENO)) != 0) { |
||||
+ fprintf(stderr, "Access denied for %s.\n", target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+ if (appl_pam_requires_chauthtok()) { |
||||
+ fprintf(stderr, "Password change required for %s.\n", |
||||
+ target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+ force_fork++; |
||||
+ } |
||||
+#endif |
||||
} |
||||
|
||||
if( some_rest_copy){ |
||||
@@ -632,6 +673,30 @@ main (argc, argv) |
||||
exit(1); |
||||
} |
||||
|
||||
+#ifdef USE_PAM |
||||
+ if (appl_pam_enabled(ksu_context, "ksu")) { |
||||
+ if (appl_pam_session_open() != 0) { |
||||
+ fprintf(stderr, "Error opening session for %s.\n", target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+#ifdef DEBUG |
||||
+ if (auth_debug){ |
||||
+ printf(" Opened PAM session.\n"); |
||||
+ } |
||||
+#endif |
||||
+ if (appl_pam_cred_init()) { |
||||
+ fprintf(stderr, "Error initializing credentials for %s.\n", |
||||
+ target_user); |
||||
+ exit(1); |
||||
+ } |
||||
+#ifdef DEBUG |
||||
+ if (auth_debug){ |
||||
+ printf(" Initialized PAM credentials.\n"); |
||||
+ } |
||||
+#endif |
||||
+ } |
||||
+#endif |
||||
+ |
||||
/* set permissions */ |
||||
if (setgid(target_pwd->pw_gid) < 0) { |
||||
perror("ksu: setgid"); |
||||
@@ -729,7 +794,7 @@ main (argc, argv) |
||||
fprintf(stderr, "program to be execed %s\n",params[0]); |
||||
} |
||||
|
||||
- if( keep_target_cache ) { |
||||
+ if( keep_target_cache && !force_fork ) { |
||||
execv(params[0], params); |
||||
com_err(prog_name, errno, _("while trying to execv %s"), params[0]); |
||||
sweep_up(ksu_context, cc_target); |
||||
@@ -759,16 +824,35 @@ main (argc, argv) |
||||
if (ret_pid == -1) { |
||||
com_err(prog_name, errno, _("while calling waitpid")); |
||||
} |
||||
- sweep_up(ksu_context, cc_target); |
||||
+ if( !keep_target_cache ) { |
||||
+ sweep_up(ksu_context, cc_target); |
||||
+ } |
||||
exit (statusp); |
||||
case -1: |
||||
com_err(prog_name, errno, _("while trying to fork.")); |
||||
sweep_up(ksu_context, cc_target); |
||||
exit (1); |
||||
case 0: |
||||
+#ifdef USE_PAM |
||||
+ if (appl_pam_enabled(ksu_context, "ksu")) { |
||||
+ if (appl_pam_setenv() != 0) { |
||||
+ fprintf(stderr, "Error setting up environment for %s.\n", |
||||
+ target_user); |
||||
+ exit (1); |
||||
+ } |
||||
+#ifdef DEBUG |
||||
+ if (auth_debug){ |
||||
+ printf(" Set up PAM environment.\n"); |
||||
+ } |
||||
+#endif |
||||
+ } |
||||
+#endif |
||||
execv(params[0], params); |
||||
com_err(prog_name, errno, _("while trying to execv %s"), |
||||
params[0]); |
||||
+ if( keep_target_cache ) { |
||||
+ sweep_up(ksu_context, cc_target); |
||||
+ } |
||||
exit (1); |
||||
} |
||||
} |
||||
diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c |
||||
new file mode 100644 |
||||
index 000000000..cbfe48704 |
||||
--- /dev/null |
||||
+++ b/src/clients/ksu/pam.c |
||||
@@ -0,0 +1,389 @@ |
||||
+/* |
||||
+ * src/clients/ksu/pam.c |
||||
+ * |
||||
+ * Copyright 2007,2009,2010 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. |
||||
+ * |
||||
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be |
||||
+ * used to endorse or promote products derived from this software without |
||||
+ * specific prior written permission. |
||||
+ * |
||||
+ * 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 OWNER 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. |
||||
+ * |
||||
+ * Convenience wrappers for using PAM. |
||||
+ */ |
||||
+ |
||||
+#include "autoconf.h" |
||||
+#ifdef USE_PAM |
||||
+#include <sys/types.h> |
||||
+#include <stdio.h> |
||||
+#include <stdlib.h> |
||||
+#include <string.h> |
||||
+#include <unistd.h> |
||||
+#include "k5-int.h" |
||||
+#include "pam.h" |
||||
+ |
||||
+#ifndef MAXPWSIZE |
||||
+#define MAXPWSIZE 128 |
||||
+#endif |
||||
+ |
||||
+static int appl_pam_started; |
||||
+static pid_t appl_pam_starter = -1; |
||||
+static int appl_pam_session_opened; |
||||
+static int appl_pam_creds_initialized; |
||||
+static int appl_pam_pwchange_required; |
||||
+static pam_handle_t *appl_pamh; |
||||
+static struct pam_conv appl_pam_conv; |
||||
+static char *appl_pam_user; |
||||
+struct appl_pam_non_interactive_args { |
||||
+ const char *user; |
||||
+ const char *password; |
||||
+}; |
||||
+ |
||||
+int |
||||
+appl_pam_enabled(krb5_context context, const char *section) |
||||
+{ |
||||
+ int enabled = 1; |
||||
+ if ((context != NULL) && (context->profile != NULL)) { |
||||
+ if (profile_get_boolean(context->profile, |
||||
+ section, |
||||
+ USE_PAM_CONFIGURATION_KEYWORD, |
||||
+ NULL, |
||||
+ enabled, &enabled) != 0) { |
||||
+ enabled = 1; |
||||
+ } |
||||
+ } |
||||
+ return enabled; |
||||
+} |
||||
+ |
||||
+void |
||||
+appl_pam_cleanup(void) |
||||
+{ |
||||
+ if (getpid() != appl_pam_starter) { |
||||
+ return; |
||||
+ } |
||||
+#ifdef DEBUG |
||||
+ printf("Called to clean up PAM.\n"); |
||||
+#endif |
||||
+ if (appl_pam_creds_initialized) { |
||||
+#ifdef DEBUG |
||||
+ printf("Deleting PAM credentials.\n"); |
||||
+#endif |
||||
+ pam_setcred(appl_pamh, PAM_DELETE_CRED); |
||||
+ appl_pam_creds_initialized = 0; |
||||
+ } |
||||
+ if (appl_pam_session_opened) { |
||||
+#ifdef DEBUG |
||||
+ printf("Closing PAM session.\n"); |
||||
+#endif |
||||
+ pam_close_session(appl_pamh, 0); |
||||
+ appl_pam_session_opened = 0; |
||||
+ } |
||||
+ appl_pam_pwchange_required = 0; |
||||
+ if (appl_pam_started) { |
||||
+#ifdef DEBUG |
||||
+ printf("Shutting down PAM.\n"); |
||||
+#endif |
||||
+ pam_end(appl_pamh, 0); |
||||
+ appl_pam_started = 0; |
||||
+ appl_pam_starter = -1; |
||||
+ free(appl_pam_user); |
||||
+ appl_pam_user = NULL; |
||||
+ } |
||||
+} |
||||
+static int |
||||
+appl_pam_interactive_converse(int num_msg, const struct pam_message **msg, |
||||
+ struct pam_response **presp, void *appdata_ptr) |
||||
+{ |
||||
+ const struct pam_message *message; |
||||
+ struct pam_response *resp; |
||||
+ int i, code; |
||||
+ char *pwstring, pwbuf[MAXPWSIZE]; |
||||
+ unsigned int pwsize; |
||||
+ resp = malloc(sizeof(struct pam_response) * num_msg); |
||||
+ if (resp == NULL) { |
||||
+ return PAM_BUF_ERR; |
||||
+ } |
||||
+ memset(resp, 0, sizeof(struct pam_response) * num_msg); |
||||
+ code = PAM_SUCCESS; |
||||
+ for (i = 0; i < num_msg; i++) { |
||||
+ message = &(msg[0][i]); /* XXX */ |
||||
+ message = msg[i]; /* XXX */ |
||||
+ pwstring = NULL; |
||||
+ switch (message->msg_style) { |
||||
+ case PAM_TEXT_INFO: |
||||
+ case PAM_ERROR_MSG: |
||||
+ printf("[%s]\n", message->msg ? message->msg : ""); |
||||
+ fflush(stdout); |
||||
+ resp[i].resp = NULL; |
||||
+ resp[i].resp_retcode = PAM_SUCCESS; |
||||
+ break; |
||||
+ case PAM_PROMPT_ECHO_ON: |
||||
+ case PAM_PROMPT_ECHO_OFF: |
||||
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) { |
||||
+ if (fgets(pwbuf, sizeof(pwbuf), |
||||
+ stdin) != NULL) { |
||||
+ pwbuf[strcspn(pwbuf, "\r\n")] = '\0'; |
||||
+ pwstring = pwbuf; |
||||
+ } |
||||
+ } else { |
||||
+ pwstring = getpass(message->msg ? |
||||
+ message->msg : |
||||
+ ""); |
||||
+ } |
||||
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) { |
||||
+ pwsize = strlen(pwstring); |
||||
+ resp[i].resp = malloc(pwsize + 1); |
||||
+ if (resp[i].resp == NULL) { |
||||
+ resp[i].resp_retcode = PAM_BUF_ERR; |
||||
+ } else { |
||||
+ memcpy(resp[i].resp, pwstring, pwsize); |
||||
+ resp[i].resp[pwsize] = '\0'; |
||||
+ resp[i].resp_retcode = PAM_SUCCESS; |
||||
+ } |
||||
+ } else { |
||||
+ resp[i].resp_retcode = PAM_CONV_ERR; |
||||
+ code = PAM_CONV_ERR; |
||||
+ } |
||||
+ break; |
||||
+ default: |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ *presp = resp; |
||||
+ return code; |
||||
+} |
||||
+static int |
||||
+appl_pam_non_interactive_converse(int num_msg, |
||||
+ const struct pam_message **msg, |
||||
+ struct pam_response **presp, |
||||
+ void *appdata_ptr) |
||||
+{ |
||||
+ const struct pam_message *message; |
||||
+ struct pam_response *resp; |
||||
+ int i, code; |
||||
+ unsigned int pwsize; |
||||
+ struct appl_pam_non_interactive_args *args; |
||||
+ const char *pwstring; |
||||
+ resp = malloc(sizeof(struct pam_response) * num_msg); |
||||
+ if (resp == NULL) { |
||||
+ return PAM_BUF_ERR; |
||||
+ } |
||||
+ args = appdata_ptr; |
||||
+ memset(resp, 0, sizeof(struct pam_response) * num_msg); |
||||
+ code = PAM_SUCCESS; |
||||
+ for (i = 0; i < num_msg; i++) { |
||||
+ message = &((*msg)[i]); |
||||
+ message = msg[i]; |
||||
+ pwstring = NULL; |
||||
+ switch (message->msg_style) { |
||||
+ case PAM_TEXT_INFO: |
||||
+ case PAM_ERROR_MSG: |
||||
+ break; |
||||
+ case PAM_PROMPT_ECHO_ON: |
||||
+ case PAM_PROMPT_ECHO_OFF: |
||||
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) { |
||||
+ /* assume "user" */ |
||||
+ pwstring = args->user; |
||||
+ } else { |
||||
+ /* assume "password" */ |
||||
+ pwstring = args->password; |
||||
+ } |
||||
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) { |
||||
+ pwsize = strlen(pwstring); |
||||
+ resp[i].resp = malloc(pwsize + 1); |
||||
+ if (resp[i].resp == NULL) { |
||||
+ resp[i].resp_retcode = PAM_BUF_ERR; |
||||
+ } else { |
||||
+ memcpy(resp[i].resp, pwstring, pwsize); |
||||
+ resp[i].resp[pwsize] = '\0'; |
||||
+ resp[i].resp_retcode = PAM_SUCCESS; |
||||
+ } |
||||
+ } else { |
||||
+ resp[i].resp_retcode = PAM_CONV_ERR; |
||||
+ code = PAM_CONV_ERR; |
||||
+ } |
||||
+ break; |
||||
+ default: |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ *presp = resp; |
||||
+ return code; |
||||
+} |
||||
+static int |
||||
+appl_pam_start(const char *service, int interactive, |
||||
+ const char *login_username, |
||||
+ const char *non_interactive_password, |
||||
+ const char *hostname, |
||||
+ const char *ruser, |
||||
+ const char *tty) |
||||
+{ |
||||
+ static int exit_handler_registered; |
||||
+ static struct appl_pam_non_interactive_args args; |
||||
+ int ret = 0; |
||||
+ if (appl_pam_started && |
||||
+ (strcmp(login_username, appl_pam_user) != 0)) { |
||||
+ appl_pam_cleanup(); |
||||
+ appl_pam_user = NULL; |
||||
+ } |
||||
+ if (!appl_pam_started) { |
||||
+#ifdef DEBUG |
||||
+ printf("Starting PAM up (service=\"%s\",user=\"%s\").\n", |
||||
+ service, login_username); |
||||
+#endif |
||||
+ memset(&appl_pam_conv, 0, sizeof(appl_pam_conv)); |
||||
+ appl_pam_conv.conv = interactive ? |
||||
+ &appl_pam_interactive_converse : |
||||
+ &appl_pam_non_interactive_converse; |
||||
+ memset(&args, 0, sizeof(args)); |
||||
+ args.user = strdup(login_username); |
||||
+ args.password = non_interactive_password ? |
||||
+ strdup(non_interactive_password) : |
||||
+ NULL; |
||||
+ appl_pam_conv.appdata_ptr = &args; |
||||
+ ret = pam_start(service, login_username, |
||||
+ &appl_pam_conv, &appl_pamh); |
||||
+ if (ret == 0) { |
||||
+ if (hostname != NULL) { |
||||
+#ifdef DEBUG |
||||
+ printf("Setting PAM_RHOST to \"%s\".\n", hostname); |
||||
+#endif |
||||
+ pam_set_item(appl_pamh, PAM_RHOST, hostname); |
||||
+ } |
||||
+ if (ruser != NULL) { |
||||
+#ifdef DEBUG |
||||
+ printf("Setting PAM_RUSER to \"%s\".\n", ruser); |
||||
+#endif |
||||
+ pam_set_item(appl_pamh, PAM_RUSER, ruser); |
||||
+ } |
||||
+ if (tty != NULL) { |
||||
+#ifdef DEBUG |
||||
+ printf("Setting PAM_TTY to \"%s\".\n", tty); |
||||
+#endif |
||||
+ pam_set_item(appl_pamh, PAM_TTY, tty); |
||||
+ } |
||||
+ if (!exit_handler_registered && |
||||
+ (atexit(appl_pam_cleanup) != 0)) { |
||||
+ pam_end(appl_pamh, 0); |
||||
+ appl_pamh = NULL; |
||||
+ ret = -1; |
||||
+ } else { |
||||
+ appl_pam_started = 1; |
||||
+ appl_pam_starter = getpid(); |
||||
+ appl_pam_user = strdup(login_username); |
||||
+ exit_handler_registered = 1; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+int |
||||
+appl_pam_acct_mgmt(const char *service, int interactive, |
||||
+ const char *login_username, |
||||
+ const char *non_interactive_password, |
||||
+ const char *hostname, |
||||
+ const char *ruser, |
||||
+ const char *tty) |
||||
+{ |
||||
+ int ret; |
||||
+ appl_pam_pwchange_required = 0; |
||||
+ ret = appl_pam_start(service, interactive, login_username, |
||||
+ non_interactive_password, hostname, ruser, tty); |
||||
+ if (ret == 0) { |
||||
+#ifdef DEBUG |
||||
+ printf("Calling pam_acct_mgmt().\n"); |
||||
+#endif |
||||
+ ret = pam_acct_mgmt(appl_pamh, 0); |
||||
+ switch (ret) { |
||||
+ case PAM_IGNORE: |
||||
+ ret = 0; |
||||
+ break; |
||||
+ case PAM_NEW_AUTHTOK_REQD: |
||||
+ appl_pam_pwchange_required = 1; |
||||
+ ret = 0; |
||||
+ break; |
||||
+ default: |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+int |
||||
+appl_pam_requires_chauthtok(void) |
||||
+{ |
||||
+ return appl_pam_pwchange_required; |
||||
+} |
||||
+int |
||||
+appl_pam_session_open(void) |
||||
+{ |
||||
+ int ret = 0; |
||||
+ if (appl_pam_started) { |
||||
+#ifdef DEBUG |
||||
+ printf("Opening PAM session.\n"); |
||||
+#endif |
||||
+ ret = pam_open_session(appl_pamh, 0); |
||||
+ if (ret == 0) { |
||||
+ appl_pam_session_opened = 1; |
||||
+ } |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+int |
||||
+appl_pam_setenv(void) |
||||
+{ |
||||
+ int ret = 0; |
||||
+#ifdef HAVE_PAM_GETENVLIST |
||||
+#ifdef HAVE_PUTENV |
||||
+ int i; |
||||
+ char **list; |
||||
+ if (appl_pam_started) { |
||||
+ list = pam_getenvlist(appl_pamh); |
||||
+ for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) { |
||||
+#ifdef DEBUG |
||||
+ printf("Setting \"%s\" in environment.\n", list[i]); |
||||
+#endif |
||||
+ putenv(list[i]); |
||||
+ } |
||||
+ } |
||||
+#endif |
||||
+#endif |
||||
+ return ret; |
||||
+} |
||||
+int |
||||
+appl_pam_cred_init(void) |
||||
+{ |
||||
+ int ret = 0; |
||||
+ if (appl_pam_started) { |
||||
+#ifdef DEBUG |
||||
+ printf("Initializing PAM credentials.\n"); |
||||
+#endif |
||||
+ ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED); |
||||
+ if (ret == 0) { |
||||
+ appl_pam_creds_initialized = 1; |
||||
+ } |
||||
+ } |
||||
+ return ret; |
||||
+} |
||||
+#endif |
||||
diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h |
||||
new file mode 100644 |
||||
index 000000000..0ab76569c |
||||
--- /dev/null |
||||
+++ b/src/clients/ksu/pam.h |
||||
@@ -0,0 +1,57 @@ |
||||
+/* |
||||
+ * src/clients/ksu/pam.h |
||||
+ * |
||||
+ * Copyright 2007,2009,2010 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. |
||||
+ * |
||||
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be |
||||
+ * used to endorse or promote products derived from this software without |
||||
+ * specific prior written permission. |
||||
+ * |
||||
+ * 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 OWNER 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. |
||||
+ * |
||||
+ * Convenience wrappers for using PAM. |
||||
+ */ |
||||
+ |
||||
+#include <krb5.h> |
||||
+#ifdef HAVE_SECURITY_PAM_APPL_H |
||||
+#include <security/pam_appl.h> |
||||
+#endif |
||||
+ |
||||
+#define USE_PAM_CONFIGURATION_KEYWORD "use_pam" |
||||
+ |
||||
+#ifdef USE_PAM |
||||
+int appl_pam_enabled(krb5_context context, const char *section); |
||||
+int appl_pam_acct_mgmt(const char *service, int interactive, |
||||
+ const char *local_username, |
||||
+ const char *non_interactive_password, |
||||
+ const char *hostname, |
||||
+ const char *ruser, |
||||
+ const char *tty); |
||||
+int appl_pam_requires_chauthtok(void); |
||||
+int appl_pam_session_open(void); |
||||
+int appl_pam_setenv(void); |
||||
+int appl_pam_cred_init(void); |
||||
+void appl_pam_cleanup(void); |
||||
+#endif |
||||
diff --git a/src/configure.in b/src/configure.in |
||||
index 037c9f316..daabd12c8 100644 |
||||
--- a/src/configure.in |
||||
+++ b/src/configure.in |
||||
@@ -1336,6 +1336,8 @@ AC_SUBST([VERTO_VERSION]) |
||||
|
||||
AC_PATH_PROG(GROFF, groff) |
||||
|
||||
+KRB5_WITH_PAM |
||||
+ |
||||
# Make localedir work in autoconf 2.5x. |
||||
if test "${localedir+set}" != set; then |
||||
localedir='$(datadir)/locale' |
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
From f8404b502015b4a9806894d212462c63c3307fa8 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 10:01:15 -0400 |
||||
Subject: [PATCH] krb5-1.13-dirsrv-accountlock.patch |
||||
|
||||
--- |
||||
src/aclocal.m4 | 9 +++++++++ |
||||
src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c | 17 +++++++++++++++++ |
||||
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c | 3 +++ |
||||
3 files changed, 29 insertions(+) |
||||
|
||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4 |
||||
index f5667c35f..2bfb99496 100644 |
||||
--- a/src/aclocal.m4 |
||||
+++ b/src/aclocal.m4 |
||||
@@ -1656,6 +1656,15 @@ if test "$with_ldap" = yes; then |
||||
AC_MSG_NOTICE(enabling OpenLDAP database backend module support) |
||||
OPENLDAP_PLUGIN=yes |
||||
fi |
||||
+AC_ARG_WITH([dirsrv-account-locking], |
||||
+[ --with-dirsrv-account-locking compile 389/Red Hat/Fedora/Netscape Directory Server database backend module], |
||||
+[case "$withval" in |
||||
+ yes | no) ;; |
||||
+ *) AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;; |
||||
+esac], with_dirsrv_account_locking=no) |
||||
+if test $with_dirsrv_account_locking = yes; then |
||||
+ AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.]) |
||||
+fi |
||||
])dnl |
||||
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 |
||||
--- 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, |
||||
ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data); |
||||
if (ret) |
||||
goto cleanup; |
||||
+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING |
||||
+ { |
||||
+ krb5_timestamp expiretime=0; |
||||
+ char *is_login_disabled=NULL; |
||||
+ |
||||
+ /* LOGIN DISABLED */ |
||||
+ ret = krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled, |
||||
+ &attr_present); |
||||
+ if (ret) |
||||
+ goto cleanup; |
||||
+ if (attr_present == TRUE) { |
||||
+ if (strcasecmp(is_login_disabled, "TRUE")== 0) |
||||
+ entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX; |
||||
+ free (is_login_disabled); |
||||
+ } |
||||
+ } |
||||
+#endif |
||||
|
||||
ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname); |
||||
if (ret) |
||||
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c |
||||
index d722dbfa6..5e8e9a897 100644 |
||||
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c |
||||
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c |
||||
@@ -54,6 +54,9 @@ char *principal_attributes[] = { "krbprincipalname", |
||||
"krbLastFailedAuth", |
||||
"krbLoginFailedCount", |
||||
"krbLastSuccessfulAuth", |
||||
+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING |
||||
+ "nsAccountLock", |
||||
+#endif |
||||
"krbLastPwdChange", |
||||
"krbLastAdminUnlock", |
||||
"krbPrincipalAuthInd", |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
From eda215b5fdf43de6d5e0ee3641bb4bb42728ab11 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Wed, 4 Jan 2017 13:18:18 -0500 |
||||
Subject: [PATCH] krb5-1.15-beta1-buildconf.patch |
||||
|
||||
--- |
||||
src/build-tools/krb5-config.in | 7 +++++++ |
||||
src/config/pre.in | 2 +- |
||||
src/config/shlib.conf | 5 +++-- |
||||
3 files changed, 11 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in |
||||
index c17cb5eb5..1891dea99 100755 |
||||
--- a/src/build-tools/krb5-config.in |
||||
+++ b/src/build-tools/krb5-config.in |
||||
@@ -226,6 +226,13 @@ if test -n "$do_libs"; then |
||||
-e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \ |
||||
-e 's#\$(CFLAGS)##'` |
||||
|
||||
+ if test `dirname $libdir` = /usr ; then |
||||
+ lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"` |
||||
+ fi |
||||
+ lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"` |
||||
+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"` |
||||
+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"` |
||||
+ |
||||
if test $library = 'kdb'; then |
||||
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 |
||||
--- a/src/config/pre.in |
||||
+++ b/src/config/pre.in |
||||
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP) |
||||
INSTALL_SCRIPT=@INSTALL_PROGRAM@ |
||||
INSTALL_DATA=@INSTALL_DATA@ |
||||
INSTALL_SHLIB=@INSTALL_SHLIB@ |
||||
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root |
||||
+INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 |
||||
## This is needed because autoconf will sometimes define @exec_prefix@ to be |
||||
## ${prefix}. |
||||
prefix=@prefix@ |
||||
diff --git a/src/config/shlib.conf b/src/config/shlib.conf |
||||
index 3e4af6c02..2b20c3fda 100644 |
||||
--- a/src/config/shlib.conf |
||||
+++ b/src/config/shlib.conf |
||||
@@ -423,7 +423,7 @@ mips-*-netbsd*) |
||||
# Linux ld doesn't default to stuffing the SONAME field... |
||||
# Use objdump -x to examine the fields of the library |
||||
# UNDEF_CHECK is suppressed by --enable-asan |
||||
- LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK)' |
||||
+ LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT) $(UNDEF_CHECK) -Wl,-z,relro -Wl,--warn-shared-textrel' |
||||
UNDEF_CHECK='-Wl,--no-undefined' |
||||
# $(EXPORT_CHECK) runs export-check.pl when in maintainer mode. |
||||
LDCOMBINE_TAIL='-Wl,--version-script binutils.versions $(EXPORT_CHECK)' |
||||
@@ -435,7 +435,8 @@ mips-*-netbsd*) |
||||
SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' |
||||
PROFFLAGS=-pg |
||||
PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' |
||||
- CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' |
||||
+ CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)' |
||||
+ INSTALL_SHLIB='${INSTALL} -m755' |
||||
CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' |
||||
CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' |
||||
CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
From e48799ea02841461af9a97a8f490bcf4f4ac5666 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 09:59:05 -0400 |
||||
Subject: [PATCH] krb5-1.3.1-dns.patch |
||||
|
||||
--- |
||||
src/aclocal.m4 | 1 + |
||||
1 file changed, 1 insertion(+) |
||||
|
||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4 |
||||
index 607859f17..f5667c35f 100644 |
||||
--- a/src/aclocal.m4 |
||||
+++ b/src/aclocal.m4 |
||||
@@ -703,6 +703,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library), |
||||
LIBS="$LIBS $withval" |
||||
AC_MSG_RESULT("netlib will use \'$withval\'") |
||||
fi |
||||
+ KRB5_AC_ENABLE_DNS |
||||
],dnl |
||||
[AC_LIBRARY_NET] |
||||
)])dnl |
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
From 502177c9256aa52ee3f7812f5127619475b3c7a5 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 10:02:40 -0400 |
||||
Subject: [PATCH] krb5-1.9-debuginfo.patch |
||||
|
||||
--- |
||||
src/kadmin/cli/Makefile.in | 5 +++++ |
||||
src/plugins/kdb/ldap/ldap_util/Makefile.in | 2 +- |
||||
2 files changed, 6 insertions(+), 1 deletion(-) |
||||
|
||||
diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in |
||||
index adfea6e2b..d1327e400 100644 |
||||
--- a/src/kadmin/cli/Makefile.in |
||||
+++ b/src/kadmin/cli/Makefile.in |
||||
@@ -37,3 +37,8 @@ clean-unix:: |
||||
# CC_LINK is not meant for compilation and this use may break in the future. |
||||
datetest: getdate.c |
||||
$(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c |
||||
+ |
||||
+%.c: %.y |
||||
+ $(RM) y.tab.c $@ |
||||
+ $(YACC.y) $< |
||||
+ $(CP) y.tab.c $@ |
||||
diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in |
||||
index 8669c2436..a22f23c02 100644 |
||||
--- a/src/plugins/kdb/ldap/ldap_util/Makefile.in |
||||
+++ b/src/plugins/kdb/ldap/ldap_util/Makefile.in |
||||
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIB) $(GETDATE) |
||||
getdate.c: $(GETDATE) |
||||
$(RM) getdate.c y.tab.c |
||||
$(YACC) $(GETDATE) |
||||
- $(MV) y.tab.c getdate.c |
||||
+ $(CP) y.tab.c getdate.c |
||||
|
||||
install: |
||||
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG) |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
d /var/run/krb5kdc 0755 root root |
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
From 16c9dd3d2f8d74958495674f4906626a74ef8c12 Mon Sep 17 00:00:00 2001 |
||||
From: Robbie Harwood <rharwood@redhat.com> |
||||
Date: Fri, 22 Apr 2016 10:03:07 -0400 |
||||
Subject: [PATCH] krb5-kvno-230379.patch |
||||
|
||||
--- |
||||
src/kadmin/ktutil/ktutil.c | 5 +++-- |
||||
src/lib/krb5/keytab/kt_file.c | 2 +- |
||||
2 files changed, 4 insertions(+), 3 deletions(-) |
||||
|
||||
diff --git a/src/kadmin/ktutil/ktutil.c b/src/kadmin/ktutil/ktutil.c |
||||
index ef16d37a5..64a6d6ab1 100644 |
||||
--- a/src/kadmin/ktutil/ktutil.c |
||||
+++ b/src/kadmin/ktutil/ktutil.c |
||||
@@ -140,7 +140,7 @@ void ktutil_add_entry(argc, argv) |
||||
char *princ = NULL; |
||||
char *enctype = NULL; |
||||
krb5_kvno kvno = 0; |
||||
- int use_pass = 0, use_key = 0, i; |
||||
+ int use_pass = 0, use_key = 0, use_kvno = 0, i; |
||||
|
||||
for (i = 1; i < argc; i++) { |
||||
if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) { |
||||
@@ -149,6 +149,7 @@ void ktutil_add_entry(argc, argv) |
||||
} |
||||
if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { |
||||
kvno = (krb5_kvno) atoi(argv[++i]); |
||||
+ use_kvno++; |
||||
continue; |
||||
} |
||||
if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { |
||||
@@ -165,7 +166,7 @@ void ktutil_add_entry(argc, argv) |
||||
} |
||||
} |
||||
|
||||
- if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) { |
||||
+ if (argc != 8 || !(princ && use_kvno && enctype) || (use_pass+use_key != 1)) { |
||||
fprintf(stderr, _("usage: %s (-key | -password) -p principal " |
||||
"-k kvno -e enctype\n"), argv[0]); |
||||
return; |
||||
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c |
||||
index 674d88bab..131549ffe 100644 |
||||
--- a/src/lib/krb5/keytab/kt_file.c |
||||
+++ b/src/lib/krb5/keytab/kt_file.c |
||||
@@ -377,7 +377,7 @@ krb5_ktfile_get_entry(krb5_context context, krb5_keytab id, |
||||
* Otherwise, remember that we were here so we can return the right |
||||
* error, and free the new. |
||||
*/ |
||||
- if (new_entry.vno == kvno) { |
||||
+ if (new_entry.vno == kvno || new_entry.vno == IGNORE_VNO) { |
||||
krb5_kt_free_entry(context, &cur_entry); |
||||
cur_entry = new_entry; |
||||
if (new_entry.vno == kvno) |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
# Configuration snippets may be placed in this directory as well |
||||
includedir /etc/krb5.conf.d/ |
||||
|
||||
[logging] |
||||
default = FILE:/var/log/krb5libs.log |
||||
kdc = FILE:/var/log/krb5kdc.log |
||||
admin_server = FILE:/var/log/kadmind.log |
||||
|
||||
[libdefaults] |
||||
dns_lookup_realm = false |
||||
ticket_lifetime = 24h |
||||
renew_lifetime = 7d |
||||
forwardable = true |
||||
rdns = false |
||||
# default_realm = EXAMPLE.COM |
||||
|
||||
[realms] |
||||
# EXAMPLE.COM = { |
||||
# kdc = kerberos.example.com |
||||
# admin_server = kerberos.example.com |
||||
# } |
||||
|
||||
[domain_realm] |
||||
# .example.com = EXAMPLE.COM |
||||
# example.com = EXAMPLE.COM |
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
#!/bin/bash |
||||
# |
||||
# krb5kdc Start and stop the Kerberos 5 servers. |
||||
# |
||||
# chkconfig: - 35 65 |
||||
# description: Kerberos 5 is a trusted third-party authentication system. \ |
||||
# This script starts and stops the server that Kerberos 5 \ |
||||
# clients need to connect to in order to obtain credentials. |
||||
# processname: krb5kdc |
||||
# config: /etc/sysconfig/krb5kdc |
||||
# pidfile: /var/run/krb5kdc.pid |
||||
# |
||||
|
||||
### BEGIN INIT INFO |
||||
# Provides: krb5kdc |
||||
# Required-Start: $local_fs $network |
||||
# Required-Stop: $local_fs $network |
||||
# Should-Start: portreserve |
||||
# Default-Start: |
||||
# Default-Stop: 0 1 2 3 4 5 6 |
||||
# Short-Description: start and stop the Kerberos 5 KDC |
||||
# Description: The krb5kdc is the Kerberos 5 key distribution center, which \ |
||||
# issues credentials to Kerberos 5 clients. |
||||
### END INIT INFO |
||||
|
||||
# Get config. |
||||
. /etc/sysconfig/network |
||||
|
||||
# Get config. |
||||
[ -r /etc/sysconfig/krb5kdc ] && . /etc/sysconfig/krb5kdc |
||||
|
||||
# Source function library. |
||||
. /etc/rc.d/init.d/functions |
||||
|
||||
RETVAL=0 |
||||
prog="Kerberos 5 KDC" |
||||
krb5kdc=/usr/sbin/krb5kdc |
||||
pidfile=/var/run/krb5kdc.pid |
||||
PATH=/usr/lib64/krb5:/usr/lib/krb5:"$PATH" |
||||
|
||||
# Shell functions to cut down on useless shell instances. |
||||
start() { |
||||
[ -x $krb5kdc ] || exit 5 |
||||
echo -n $"Starting $prog: " |
||||
# tell portreserve to release the kerberos-iv port |
||||
[ -x /sbin/portrelease ] && /sbin/portrelease kerberos-iv &>/dev/null || : |
||||
daemon ${krb5kdc} ${KRB5REALM:+-r ${KRB5REALM}} -P $pidfile $KRB5KDC_ARGS |
||||
RETVAL=$? |
||||
echo |
||||
if test $RETVAL -ne 0 ; then |
||||
if status ${krb5kdc} > /dev/null ; then |
||||
RETVAL=0 |
||||
fi |
||||
fi |
||||
[ $RETVAL = 0 ] && touch /var/lock/subsys/krb5kdc |
||||
} |
||||
stop() { |
||||
echo -n $"Stopping $prog: " |
||||
killproc ${krb5kdc} |
||||
RETVAL=$? |
||||
echo |
||||
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/krb5kdc |
||||
} |
||||
reload() { |
||||
echo -n $"Reopening $prog log file: " |
||||
killproc ${krb5kdc} -HUP |
||||
RETVAL=$? |
||||
echo |
||||
} |
||||
|
||||
# See how we were called. |
||||
case "$1" in |
||||
start) |
||||
start |
||||
;; |
||||
stop) |
||||
stop |
||||
;; |
||||
restart) |
||||
stop |
||||
start |
||||
;; |
||||
reload) |
||||
reload |
||||
;; |
||||
status) |
||||
status ${krb5kdc} |
||||
RETVAL=$? |
||||
;; |
||||
condrestart) |
||||
if [ -f /var/lock/subsys/krb5kdc ] ; then |
||||
stop |
||||
start |
||||
fi |
||||
;; |
||||
*) |
||||
echo $"Usage: $0 {start|stop|status|reload|restart|condrestart}" |
||||
RETVAL=2 |
||||
;; |
||||
esac |
||||
|
||||
exit $RETVAL |
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
/var/log/krb5kdc.log { |
||||
missingok |
||||
notifempty |
||||
monthly |
||||
rotate 12 |
||||
postrotate |
||||
/bin/kill -HUP `cat /var/run/krb5kdc.pid 2>/dev/null` 2> /dev/null || true |
||||
endscript |
||||
} |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
[Unit] |
||||
Description=Kerberos 5 KDC |
||||
After=syslog.target network.target |
||||
|
||||
[Service] |
||||
Type=forking |
||||
PIDFile=/var/run/krb5kdc.pid |
||||
EnvironmentFile=-/etc/sysconfig/krb5kdc |
||||
ExecStart=/usr/sbin/krb5kdc -P /var/run/krb5kdc.pid $KRB5KDC_ARGS |
||||
ExecReload=/bin/kill -HUP $MAINPID |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
#%PAM-1.0 |
||||
auth include su |
||||
account include su |
||||
session include su |
@ -0,0 +1,111 @@
@@ -0,0 +1,111 @@
|
||||
#define _GNU_SOURCE |
||||
#include <sys/socket.h> |
||||
#include <dlfcn.h> |
||||
#include <errno.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <netinet/in.h> |
||||
|
||||
static int |
||||
port_is_okay(unsigned short port) |
||||
{ |
||||
char *p, *q; |
||||
long l; |
||||
|
||||
p = getenv("NOPORT"); |
||||
while ((p != NULL) && (*p != '\0')) { |
||||
l = strtol(p, &q, 10); |
||||
if ((q == NULL) || (q == p)) { |
||||
break; |
||||
} |
||||
if ((*q == '\0') || (*q == ',')) { |
||||
if (port == l) { |
||||
errno = ECONNREFUSED; |
||||
return -1; |
||||
} |
||||
} |
||||
p = q; |
||||
p += strspn(p, ","); |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
int |
||||
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) |
||||
{ |
||||
unsigned short port; |
||||
static int (*next_connect)(int, const struct sockaddr *, socklen_t); |
||||
|
||||
if (next_connect == NULL) { |
||||
next_connect = dlsym(RTLD_NEXT, "connect"); |
||||
if (next_connect == NULL) { |
||||
errno = ENOSYS; |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
if (getenv("NOPORT") == NULL) { |
||||
return next_connect(sockfd, addr, addrlen); |
||||
} |
||||
|
||||
switch (addr->sa_family) { |
||||
case AF_INET: |
||||
port = ntohs(((struct sockaddr_in *)addr)->sin_port); |
||||
if (port_is_okay(port) != 0) { |
||||
return -1; |
||||
} |
||||
break; |
||||
case AF_INET6: |
||||
port = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); |
||||
if (port_is_okay(port) != 0) { |
||||
return -1; |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
return next_connect(sockfd, addr, addrlen); |
||||
} |
||||
|
||||
ssize_t |
||||
sendto(int sockfd, const void *buf, size_t len, int flags, |
||||
const struct sockaddr *dest_addr, socklen_t addrlen) |
||||
{ |
||||
unsigned short port; |
||||
static int (*next_sendto)(int, const void *, size_t, int, |
||||
const struct sockaddr *, socklen_t); |
||||
|
||||
if (next_sendto == NULL) { |
||||
next_sendto = dlsym(RTLD_NEXT, "sendto"); |
||||
if (next_sendto == NULL) { |
||||
errno = ENOSYS; |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
if (getenv("NOPORT") == NULL) { |
||||
return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen); |
||||
} |
||||
|
||||
if (dest_addr != NULL) { |
||||
switch (dest_addr->sa_family) { |
||||
case AF_INET: |
||||
port = ((struct sockaddr_in *)dest_addr)->sin_port; |
||||
port = ntohs(port); |
||||
if (port_is_okay(port) != 0) { |
||||
return -1; |
||||
} |
||||
break; |
||||
case AF_INET6: |
||||
port = ((struct sockaddr_in6 *)dest_addr)->sin6_port; |
||||
port = ntohs(port); |
||||
if (port_is_okay(port) != 0) { |
||||
return -1; |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen); |
||||
} |
Loading…
Reference in new issue