New upstream version (1.19-beta1)

This commit is contained in:
Robbie Harwood 2020-12-16 16:06:50 +00:00
parent 58924baeb4
commit 0da55d6175
42 changed files with 162 additions and 6557 deletions

2
.gitignore vendored
View File

@ -189,3 +189,5 @@ krb5-1.8.3-pdf.tar.gz
/krb5-1.18.2.tar.gz.asc
/krb5-1.18.3.tar.gz
/krb5-1.18.3.tar.gz.asc
/krb5-1.19-beta1.tar.gz
/krb5-1.19-beta1.tar.gz.asc

View File

@ -1,427 +0,0 @@
From b9ca222798a52ef3a28185ed44f3dfe19579d8fc Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Fri, 20 Mar 2020 00:17:28 +0100
Subject: [PATCH] Add channel bindings tests
[ghudson@mit.edu: adjusted test program to output channel-bound state
instead of optionally enforcing it; adjusted tests to check program
output; split out tests into separate Python script; made cosmetic
changes]
ticket: 8900
(cherry picked from commit b0b21b6d25b06f3e2b365dfe9dd4c99b3d43bf57)
[rharwood@redhat.com: slush around upstream not backporting reload,
gitignore]
---
src/plugins/gssapi/negoextest/main.c | 18 +++++
src/tests/gssapi/Makefile.in | 57 +++++++-------
src/tests/gssapi/common.c | 25 ++++--
src/tests/gssapi/common.h | 9 +++
src/tests/gssapi/deps | 4 +
src/tests/gssapi/t_bindings.c | 111 +++++++++++++++++++++++++++
src/tests/gssapi/t_bindings.py | 43 +++++++++++
src/tests/gssapi/t_negoex.py | 7 ++
8 files changed, 242 insertions(+), 32 deletions(-)
create mode 100644 src/tests/gssapi/t_bindings.c
create mode 100644 src/tests/gssapi/t_bindings.py
diff --git a/src/plugins/gssapi/negoextest/main.c b/src/plugins/gssapi/negoextest/main.c
index 6c340f41b..72fc5273a 100644
--- a/src/plugins/gssapi/negoextest/main.c
+++ b/src/plugins/gssapi/negoextest/main.c
@@ -57,6 +57,15 @@ gss_init_sec_context(OM_uint32 *minor_status,
const char *envstr;
uint8_t hops, mech_last_octet;
+ envstr = getenv("GSS_INIT_BINDING");
+ if (envstr != NULL) {
+ assert(strlen(envstr) > 0);
+ assert(input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS);
+ assert(strlen(envstr) == input_chan_bindings->application_data.length);
+ assert(strcmp((char *)input_chan_bindings->application_data.value,
+ envstr) == 0);
+ }
+
if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {
envstr = getenv("HOPS");
hops = (envstr != NULL) ? atoi(envstr) : 1;
@@ -112,6 +121,15 @@ gss_accept_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle,
uint8_t hops, mech_last_octet;
const char *envstr;
+ envstr = getenv("GSS_ACCEPT_BINDING");
+ if (envstr != NULL) {
+ assert(strlen(envstr) > 0);
+ assert(input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS);
+ assert(strlen(envstr) == input_chan_bindings->application_data.length);
+ assert(strcmp((char *)input_chan_bindings->application_data.value,
+ envstr) == 0);
+ }
+
/*
* The unwrapped token sits at the end and is just one byte giving the
* remaining number of hops. The final octet of the mech encoding should
diff --git a/src/tests/gssapi/Makefile.in b/src/tests/gssapi/Makefile.in
index 22a2f9480..cf7bcf451 100644
--- a/src/tests/gssapi/Makefile.in
+++ b/src/tests/gssapi/Makefile.in
@@ -8,34 +8,36 @@ LOCALINCLUDES = -I$(srcdir)/../../lib/gssapi/mechglue \
-I$(srcdir)/../../lib/gssapi/generic -I../../lib/gssapi/krb5 \
-I../../lib/gssapi/generic
-SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c $(srcdir)/reload.c \
- $(srcdir)/t_accname.c $(srcdir)/t_add_cred.c $(srcdir)/t_ccselect.c \
- $(srcdir)/t_ciflags.c $(srcdir)/t_context.c $(srcdir)/t_credstore.c \
- $(srcdir)/t_enctypes.c $(srcdir)/t_err.c $(srcdir)/t_export_cred.c \
- $(srcdir)/t_export_name.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 \
+SRCS= $(srcdir)/ccinit.c $(srcdir)/ccrefresh.c $(srcdir)/common.c \
+ $(srcdir)/reload.c $(srcdir)/t_accname.c $(srcdir)/t_add_cred.c \
+ $(srcdir)/t_bindings.c $(srcdir)/t_ccselect.c $(srcdir)/t_ciflags.c \
+ $(srcdir)/t_context.c $(srcdir)/t_credstore.c $(srcdir)/t_enctypes.c \
+ $(srcdir)/t_err.c $(srcdir)/t_export_cred.c $(srcdir)/t_export_name.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_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 reload.o t_accname.o t_add_cred.o t_ccselect.o \
- t_ciflags.o t_context.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_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
+
+OBJS= ccinit.o ccrefresh.o common.o reload.o t_accname.o t_add_cred.o \
+ t_bindings.o t_ccselect.o t_ciflags.o t_context.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_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)
COMMON_LIBS= common.o $(GSS_LIBS) $(KRB5_BASE_LIBS)
-all: ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags t_context \
- 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_lifetime t_namingexts t_oid t_pcontok t_prf t_s4u \
- t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs
+all: ccinit ccrefresh t_accname t_add_cred t_bindings t_ccselect t_ciflags \
+ t_context 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_lifetime t_namingexts t_oid t_pcontok t_prf \
+ t_s4u t_s4u2proxy_krb5 t_saslname t_spnego t_srcattrs
check-unix: t_oid reload
$(RUN_TEST) ./t_invalid
@@ -44,11 +46,12 @@ check-unix: t_oid reload
$(RUN_TEST) ./t_imp_name
if [ -r $(TOPLIBD)/libgssapi_krb5.so ]; then $(RUN_TEST) ./reload; fi
-check-pytests: ccinit ccrefresh t_accname t_add_cred t_ccselect t_ciflags \
- t_context 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_lifetime \
- t_pcontok t_s4u t_s4u2proxy_krb5 t_spnego t_srcattrs
+check-pytests: ccinit ccrefresh t_accname t_add_cred t_bindings t_ccselect \
+ t_ciflags t_context 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_lifetime t_pcontok t_s4u t_s4u2proxy_krb5 t_spnego t_srcattrs
$(RUNPYTEST) $(srcdir)/t_gssapi.py $(PYTESTFLAGS)
+ $(RUNPYTEST) $(srcdir)/t_bindings.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_ccselect.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_client_keytab.py $(PYTESTFLAGS)
$(RUNPYTEST) $(srcdir)/t_enctypes.py $(PYTESTFLAGS)
@@ -67,6 +70,8 @@ t_accname: t_accname.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_accname.o $(COMMON_LIBS)
t_add_cred: t_add_cred.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_add_cred.o $(COMMON_LIBS)
+t_bindings: t_bindings.o $(COMMON_DEPS)
+ $(CC_LINK) -o $@ t_bindings.o $(COMMON_LIBS)
t_ccselect: t_ccselect.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_ccselect.o $(COMMON_LIBS)
t_ciflags: t_ciflags.o $(COMMON_DEPS)
@@ -121,9 +126,9 @@ t_srcattrs: t_srcattrs.o $(COMMON_DEPS)
$(CC_LINK) -o $@ t_srcattrs.o $(COMMON_LIBS)
clean:
- $(RM) ccinit ccrefresh reload t_accname t_add_cred t_ccselect t_ciflags
- $(RM) t_context t_credstore t_enctypes t_err t_export_cred
- $(RM) t_export_name t_gssexts t_imp_cred t_imp_name t_invalid
- $(RM) t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime
+ $(RM) ccinit ccrefresh reload t_accname t_add_cred t_bindings
+ $(RM) t_ccselect t_ciflags t_context t_credstore t_enctypes t_err
+ $(RM) t_export_cred t_export_name t_gssexts t_imp_cred t_imp_name
+ $(RM) t_invalid t_inq_cred t_inq_ctx t_inq_mechs_name t_iov t_lifetime
$(RM) t_namingexts t_oid t_pcontok t_prf t_s4u t_s4u2proxy_krb5
$(RM) t_saslname t_spnego t_srcattrs
diff --git a/src/tests/gssapi/common.c b/src/tests/gssapi/common.c
index 83e9d9bb8..7ba72f7b2 100644
--- a/src/tests/gssapi/common.c
+++ b/src/tests/gssapi/common.c
@@ -115,6 +115,20 @@ establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,
gss_ctx_id_t *actx, gss_name_t *src_name, gss_OID *amech,
gss_cred_id_t *deleg_cred)
+{
+ return establish_contexts_ex(imech, icred, acred, tname, flags, ictx, actx,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ GSS_C_NO_CHANNEL_BINDINGS, NULL, src_name,
+ amech, deleg_cred);
+}
+
+void
+establish_contexts_ex(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
+ gss_name_t tname, OM_uint32 flags, gss_ctx_id_t *ictx,
+ gss_ctx_id_t *actx, gss_channel_bindings_t icb,
+ gss_channel_bindings_t acb, OM_uint32 *aret_flags,
+ gss_name_t *src_name, gss_OID *amech,
+ gss_cred_id_t *deleg_cred)
{
OM_uint32 minor, imaj, amaj;
gss_buffer_desc itok, atok;
@@ -126,17 +140,16 @@ establish_contexts(gss_OID imech, gss_cred_id_t icred, gss_cred_id_t acred,
for (;;) {
(void)gss_release_buffer(&minor, &itok);
imaj = gss_init_sec_context(&minor, icred, ictx, tname, imech, flags,
- GSS_C_INDEFINITE,
- GSS_C_NO_CHANNEL_BINDINGS, &atok, NULL,
- &itok, NULL, NULL);
+ GSS_C_INDEFINITE, icb, &atok, NULL, &itok,
+ NULL, NULL);
check_gsserr("gss_init_sec_context", imaj, minor);
if (amaj == GSS_S_COMPLETE)
break;
(void)gss_release_buffer(&minor, &atok);
- amaj = gss_accept_sec_context(&minor, actx, acred, &itok,
- GSS_C_NO_CHANNEL_BINDINGS, src_name,
- amech, &atok, NULL, NULL, deleg_cred);
+ amaj = gss_accept_sec_context(&minor, actx, acred, &itok, acb,
+ src_name, amech, &atok, aret_flags, NULL,
+ deleg_cred);
check_gsserr("gss_accept_sec_context", amaj, minor);
(void)gss_release_buffer(&minor, &itok);
if (imaj == GSS_S_COMPLETE)
diff --git a/src/tests/gssapi/common.h b/src/tests/gssapi/common.h
index ae11b51d4..a5c8f87e6 100644
--- a/src/tests/gssapi/common.h
+++ b/src/tests/gssapi/common.h
@@ -62,6 +62,15 @@ void establish_contexts(gss_OID imech, gss_cred_id_t icred,
gss_name_t *src_name, gss_OID *amech,
gss_cred_id_t *deleg_cred);
+/* Establish contexts with channel bindings. */
+void establish_contexts_ex(gss_OID imech, gss_cred_id_t icred,
+ gss_cred_id_t acred, gss_name_t tname,
+ OM_uint32 flags, gss_ctx_id_t *ictx,
+ gss_ctx_id_t *actx, gss_channel_bindings_t icb,
+ gss_channel_bindings_t acb, OM_uint32 *aret_flags,
+ gss_name_t *src_name, gss_OID *amech,
+ gss_cred_id_t *deleg_cred);
+
/* Export *cred to a token, then release *cred and replace it by re-importing
* the token. */
void export_import_cred(gss_cred_id_t *cred);
diff --git a/src/tests/gssapi/deps b/src/tests/gssapi/deps
index 55586de53..ca1d6e22a 100644
--- a/src/tests/gssapi/deps
+++ b/src/tests/gssapi/deps
@@ -35,6 +35,10 @@ $(OUTPRE)t_add_cred.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
$(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
$(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
common.h t_add_cred.c
+$(OUTPRE)t_bindings.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
+ $(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
+ $(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
+ common.h t_bindings.c
$(OUTPRE)t_ccselect.$(OBJEXT): $(BUILDTOP)/include/gssapi/gssapi.h \
$(BUILDTOP)/include/gssapi/gssapi_ext.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \
$(BUILDTOP)/include/krb5/krb5.h $(COM_ERR_DEPS) $(top_srcdir)/include/krb5.h \
diff --git a/src/tests/gssapi/t_bindings.c b/src/tests/gssapi/t_bindings.c
new file mode 100644
index 000000000..e8906715b
--- /dev/null
+++ b/src/tests/gssapi/t_bindings.c
@@ -0,0 +1,111 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2020 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 <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "common.h"
+
+/*
+ * Establish contexts (without and with GSS_C_DCE_STYLE) with the default
+ * initiator name, a specified principal name as target name, initiator
+ * bindings, and acceptor bindings. If any call is unsuccessful, display an
+ * error message. Output "yes" or "no" to indicate whether the contexts were
+ * reported as channel-bound on the acceptor. Exit with status 0 if all
+ * operations are successful, or 1 if not.
+ *
+ * Usage: ./t_bindings [-s] targetname icb acb
+ *
+ * An icb or abc value of "-" will not specify channel bindings.
+ */
+
+int
+main(int argc, char *argv[])
+{
+ OM_uint32 minor, flags1, flags2;
+ gss_name_t target_name;
+ gss_ctx_id_t ictx, actx;
+ struct gss_channel_bindings_struct icb_data = {0}, acb_data = {0};
+ gss_channel_bindings_t icb = GSS_C_NO_CHANNEL_BINDINGS;
+ gss_channel_bindings_t acb = GSS_C_NO_CHANNEL_BINDINGS;
+ gss_OID_desc *mech;
+
+ argv++;
+ argc--;
+ if (*argv != NULL && strcmp(*argv, "-s") == 0) {
+ mech = &mech_spnego;
+ argv++;
+ argc--;
+ } else {
+ mech = &mech_krb5;
+ }
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: t_bindings [-s] targetname icb acb\n");
+ return 1;
+ }
+
+ target_name = import_name(argv[0]);
+
+ if (strcmp(argv[1], "-") != 0) {
+ icb_data.application_data.length = strlen(argv[1]);
+ icb_data.application_data.value = argv[1];
+ icb = &icb_data;
+ }
+
+ if (strcmp(argv[2], "-") != 0) {
+ acb_data.application_data.length = strlen(argv[2]);
+ acb_data.application_data.value = argv[2];
+ acb = &acb_data;
+ }
+
+ establish_contexts_ex(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
+ target_name, 0, &ictx, &actx, icb, acb, &flags1,
+ NULL, NULL, NULL);
+
+ /* Try again with GSS_C_DCE_STYLE */
+ (void)gss_delete_sec_context(&minor, &ictx, NULL);
+ (void)gss_delete_sec_context(&minor, &actx, NULL);
+
+ establish_contexts_ex(mech, GSS_C_NO_CREDENTIAL, GSS_C_NO_CREDENTIAL,
+ target_name, GSS_C_DCE_STYLE, &ictx, &actx, icb, acb,
+ &flags2, NULL, NULL, NULL);
+ assert((flags1 & GSS_C_CHANNEL_BOUND_FLAG) ==
+ (flags2 & GSS_C_CHANNEL_BOUND_FLAG));
+ printf("%s\n", (flags1 & GSS_C_CHANNEL_BOUND_FLAG) ? "yes" : "no");
+
+ (void)gss_delete_sec_context(&minor, &ictx, NULL);
+ (void)gss_delete_sec_context(&minor, &actx, NULL);
+ (void)gss_release_name(&minor, &target_name);
+
+ return 0;
+}
diff --git a/src/tests/gssapi/t_bindings.py b/src/tests/gssapi/t_bindings.py
new file mode 100644
index 000000000..f377977b6
--- /dev/null
+++ b/src/tests/gssapi/t_bindings.py
@@ -0,0 +1,43 @@
+from k5test import *
+
+realm = K5Realm()
+server = 'p:' + realm.host_princ
+
+mark('krb5 channel bindings')
+realm.run(['./t_bindings', server, '-', '-'], expected_msg='no')
+realm.run(['./t_bindings', server, 'a', '-'], expected_msg='no')
+realm.run(['./t_bindings', server, 'a', 'a'], expected_msg='yes')
+realm.run(['./t_bindings', server, '-', 'a'], expected_msg='no')
+realm.run(['./t_bindings', server, 'a', 'x'],
+ expected_code=1, expected_msg='Incorrect channel bindings')
+
+mark('SPNEGO channel bindings')
+realm.run(['./t_bindings', '-s', server, '-', '-'], expected_msg='no')
+realm.run(['./t_bindings', '-s', server, 'a', '-'], expected_msg='no')
+realm.run(['./t_bindings', '-s', server, 'a', 'a'], expected_msg='yes')
+realm.run(['./t_bindings', '-s', server, '-', 'a'], expected_msg='no')
+realm.run(['./t_bindings', '-s', server, 'a', 'x'],
+ expected_code=1, expected_msg='Incorrect channel bindings')
+
+client_aware_conf = {'libdefaults': {'client_aware_channel_bindings': 'true'}}
+e = realm.special_env('cb_aware', False, krb5_conf=client_aware_conf)
+
+mark('krb5 client_aware_channel_bindings')
+realm.run(['./t_bindings', server, '-', '-'], env=e, expected_msg='no')
+realm.run(['./t_bindings', server, 'a', '-'], env=e, expected_msg='no')
+realm.run(['./t_bindings', server, 'a', 'a'], env=e, expected_msg='yes')
+realm.run(['./t_bindings', server, '-', 'a'], env=e,
+ expected_code=1, expected_msg='Incorrect channel bindings')
+realm.run(['./t_bindings', server, 'a', 'x'], env=e,
+ expected_code=1, expected_msg='Incorrect channel bindings')
+
+mark('SPNEGO client_aware_channel_bindings')
+realm.run(['./t_bindings', '-s', server, '-', '-'], env=e, expected_msg='no')
+realm.run(['./t_bindings', '-s', server, 'a', '-'], env=e, expected_msg='no')
+realm.run(['./t_bindings', '-s', server, 'a', 'a'], env=e, expected_msg='yes')
+realm.run(['./t_bindings', '-s', server, '-', 'a'], env=e,
+ expected_code=1, expected_msg='Incorrect channel bindings')
+realm.run(['./t_bindings', '-s', server, 'a', 'x'], env=e,
+ expected_code=1, expected_msg='Incorrect channel bindings')
+
+success('channel bindings tests')
diff --git a/src/tests/gssapi/t_negoex.py b/src/tests/gssapi/t_negoex.py
index 88470d2fa..a218899c4 100644
--- a/src/tests/gssapi/t_negoex.py
+++ b/src/tests/gssapi/t_negoex.py
@@ -139,4 +139,11 @@ msgs = ('sending [3]AP_REQUEST', 'sending [7]CHALLENGE', 'sending [8]VERIFY',
'sending [11]CHALLENGE', 'sending [12]VERIFY', 'sending [13]VERIFY')
test({'HOPS': '4', 'KEY': 'accept-always'}, expected_trace=())
+mark('channel bindings')
+e = realm.env.copy()
+e.update({'HOPS': '1', 'GSS_INIT_BINDING': 'a', 'GSS_ACCEPT_BINDING': 'b'})
+# The test mech will verify that the bindings are communicated to the
+# mech, but does not set the channel-bound flag.
+realm.run(['./t_bindings', '-s', 'h:host', 'a', 'b'], env=e, expected_msg='no')
+
success('NegoEx tests')

View File

@ -1,264 +0,0 @@
From 032c7f496c9b327752dda33bf85e74c66d3a93cf Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Tue, 10 Mar 2020 13:13:17 +0100
Subject: [PATCH] Add client_aware_channel_bindings option
Add client support for KERB_AP_OPTIONS_CBT in the form of a profile
option "client_aware_gss_bindings". Adjust the make_etype_list()
helper so that enctype negotiation and AP_OPTIONS can be included in
the same IF-RELEVANT wrapper.
[ghudson@mit.edu: refactored; edited documentation; wrote commit
message]
ticket: 8900
(cherry picked from commit 225e6ef7f021cd1a8ef2a054af0ca58b7288fd81)
---
doc/admin/conf_files/krb5_conf.rst | 6 +
src/include/k5-int.h | 1 +
src/lib/krb5/krb/mk_req_ext.c | 177 +++++++++++++++--------------
3 files changed, 98 insertions(+), 86 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 38f450367..da5ad00f2 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -388,6 +388,12 @@ The libdefaults section may contain any of the following relations:
credentials will fail if the client machine does not have a
keytab. The default value is false.
+**client_aware_channel_bindings**
+ If this flag is true, then all application protocol authentication
+ requests will be flagged to indicate that the application supports
+ channel bindings when operating over a secure channel. The
+ default value is false.
+
.. _realms:
[realms]
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 0d9af3d95..eb18a4cd6 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -299,6 +299,7 @@ typedef unsigned char u_char;
#define KRB5_CONF_V4_INSTANCE_CONVERT "v4_instance_convert"
#define KRB5_CONF_V4_REALM "v4_realm"
#define KRB5_CONF_VERIFY_AP_REQ_NOFAIL "verify_ap_req_nofail"
+#define KRB5_CONF_CLIENT_AWARE_GSS_BINDINGS "client_aware_channel_bindings"
/* Cache configuration variables */
#define KRB5_CC_CONF_FAST_AVAIL "fast_avail"
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
index 9fc6a0e52..08504860c 100644
--- a/src/lib/krb5/krb/mk_req_ext.c
+++ b/src/lib/krb5/krb/mk_req_ext.c
@@ -68,10 +68,9 @@
*/
static krb5_error_code
-make_etype_list(krb5_context context,
- krb5_enctype *desired_etypes,
- krb5_enctype tkt_enctype,
- krb5_authdata ***authdata);
+make_ap_authdata(krb5_context context, krb5_enctype *desired_enctypes,
+ krb5_enctype tkt_enctype, krb5_boolean client_aware_cb,
+ krb5_authdata ***authdata_out);
static krb5_error_code
generate_authenticator(krb5_context,
@@ -263,7 +262,8 @@ generate_authenticator(krb5_context context, krb5_authenticator *authent,
krb5_enctype tkt_enctype)
{
krb5_error_code retval;
- krb5_authdata **ext_authdata = NULL;
+ krb5_authdata **ext_authdata = NULL, **ap_authdata, **combined;
+ int client_aware_cb;
authent->client = client;
authent->checksum = cksum;
@@ -297,99 +297,104 @@ generate_authenticator(krb5_context context, krb5_authenticator *authent,
krb5_free_authdata(context, ext_authdata);
}
- /* Only send EtypeList if we prefer another enctype to tkt_enctype */
- if (desired_etypes != NULL && desired_etypes[0] != tkt_enctype) {
- TRACE_MK_REQ_ETYPES(context, desired_etypes);
- retval = make_etype_list(context, desired_etypes, tkt_enctype,
- &authent->authorization_data);
+ retval = profile_get_boolean(context->profile, KRB5_CONF_LIBDEFAULTS,
+ KRB5_CONF_CLIENT_AWARE_GSS_BINDINGS, NULL,
+ FALSE, &client_aware_cb);
+ if (retval)
+ return retval;
+
+ /* Add etype negotiation or channel-binding awareness authdata to the
+ * front, if appropriate. */
+ retval = make_ap_authdata(context, desired_etypes, tkt_enctype,
+ client_aware_cb, &ap_authdata);
+ if (retval)
+ return retval;
+ if (ap_authdata != NULL) {
+ retval = krb5_merge_authdata(context, ap_authdata,
+ authent->authorization_data, &combined);
+ krb5_free_authdata(context, ap_authdata);
if (retval)
return retval;
+ krb5_free_authdata(context, authent->authorization_data);
+ authent->authorization_data = combined;
}
return(krb5_us_timeofday(context, &authent->ctime, &authent->cusec));
}
-/* RFC 4537 */
+/* Set *out to a DER-encoded RFC 4537 etype list, or to NULL if no etype list
+ * should be sent. */
static krb5_error_code
-make_etype_list(krb5_context context,
- krb5_enctype *desired_etypes,
- krb5_enctype tkt_enctype,
- krb5_authdata ***authdata)
+make_etype_list(krb5_context context, krb5_enctype *desired_enctypes,
+ krb5_enctype tkt_enctype, krb5_data **out)
{
- krb5_error_code code;
- krb5_etype_list etypes;
- krb5_data *enc_etype_list;
- krb5_data *ad_if_relevant;
- krb5_authdata *etype_adata[2], etype_adatum, **adata;
- int i;
+ krb5_etype_list etlist;
+ int count;
- etypes.etypes = desired_etypes;
+ *out = NULL;
- for (etypes.length = 0;
- etypes.etypes[etypes.length] != ENCTYPE_NULL;
- etypes.length++)
- {
- /*
- * RFC 4537:
- *
- * If the enctype of the ticket session key is included in the enctype
- * list sent by the client, it SHOULD be the last on the list;
- */
- if (etypes.length && etypes.etypes[etypes.length - 1] == tkt_enctype)
+ /* Only send a list if we prefer another enctype to tkt_enctype. */
+ if (desired_enctypes == NULL || desired_enctypes[0] == tkt_enctype)
+ return 0;
+
+ /* Count elements of desired_etypes, stopping at tkt_enctypes if present.
+ * (Per RFC 4537, it must be the last option if it is included.) */
+ for (count = 0; desired_enctypes[count] != ENCTYPE_NULL; count++) {
+ if (count > 0 && desired_enctypes[count - 1] == tkt_enctype)
break;
}
- code = encode_krb5_etype_list(&etypes, &enc_etype_list);
- if (code) {
- return code;
- }
-
- etype_adatum.magic = KV5M_AUTHDATA;
- etype_adatum.ad_type = KRB5_AUTHDATA_ETYPE_NEGOTIATION;
- etype_adatum.length = enc_etype_list->length;
- etype_adatum.contents = (krb5_octet *)enc_etype_list->data;
-
- etype_adata[0] = &etype_adatum;
- etype_adata[1] = NULL;
-
- /* Wrap in AD-IF-RELEVANT container */
- code = encode_krb5_authdata(etype_adata, &ad_if_relevant);
- if (code) {
- krb5_free_data(context, enc_etype_list);
- return code;
- }
-
- krb5_free_data(context, enc_etype_list);
-
- adata = *authdata;
- if (adata == NULL) {
- adata = (krb5_authdata **)calloc(2, sizeof(krb5_authdata *));
- i = 0;
- } else {
- for (i = 0; adata[i] != NULL; i++)
- ;
-
- adata = (krb5_authdata **)realloc(*authdata,
- (i + 2) * sizeof(krb5_authdata *));
- }
- if (adata == NULL) {
- krb5_free_data(context, ad_if_relevant);
- return ENOMEM;
- }
- *authdata = adata;
-
- adata[i] = (krb5_authdata *)malloc(sizeof(krb5_authdata));
- if (adata[i] == NULL) {
- krb5_free_data(context, ad_if_relevant);
- return ENOMEM;
- }
- adata[i]->magic = KV5M_AUTHDATA;
- adata[i]->ad_type = KRB5_AUTHDATA_IF_RELEVANT;
- adata[i]->length = ad_if_relevant->length;
- adata[i]->contents = (krb5_octet *)ad_if_relevant->data;
- free(ad_if_relevant); /* contents owned by adata[i] */
-
- adata[i + 1] = NULL;
-
- return 0;
+ etlist.etypes = desired_enctypes;
+ etlist.length = count;
+ return encode_krb5_etype_list(&etlist, out);
+}
+
+/* Set *authdata_out to appropriate authenticator authdata for the request,
+ * encoded in a single AD_IF_RELEVANT element. */
+static krb5_error_code
+make_ap_authdata(krb5_context context, krb5_enctype *desired_enctypes,
+ krb5_enctype tkt_enctype, krb5_boolean client_aware_cb,
+ krb5_authdata ***authdata_out)
+{
+ krb5_error_code ret;
+ krb5_authdata etypes_ad, flags_ad, *list[3];
+ krb5_data *der_etypes = NULL;
+ size_t count = 0;
+ uint8_t flagbuf[4];
+ const uint32_t KERB_AP_OPTIONS_CBT = 0x4000;
+
+ *authdata_out = NULL;
+
+ /* Include an ETYPE_NEGOTIATION element if appropriate. */
+ ret = make_etype_list(context, desired_enctypes, tkt_enctype, &der_etypes);
+ if (ret)
+ goto cleanup;
+ if (der_etypes != NULL) {
+ etypes_ad.magic = KV5M_AUTHDATA;
+ etypes_ad.ad_type = KRB5_AUTHDATA_ETYPE_NEGOTIATION;
+ etypes_ad.length = der_etypes->length;
+ etypes_ad.contents = (uint8_t *)der_etypes->data;
+ list[count++] = &etypes_ad;
+ }
+
+ /* Include an AP_OPTIONS element if the CBT flag is configured. */
+ if (client_aware_cb != 0) {
+ store_32_le(KERB_AP_OPTIONS_CBT, flagbuf);
+ flags_ad.magic = KV5M_AUTHDATA;
+ flags_ad.ad_type = KRB5_AUTHDATA_AP_OPTIONS;
+ flags_ad.length = 4;
+ flags_ad.contents = flagbuf;
+ list[count++] = &flags_ad;
+ }
+
+ if (count > 0) {
+ list[count] = NULL;
+ ret = krb5_encode_authdata_container(context,
+ KRB5_AUTHDATA_IF_RELEVANT,
+ list, authdata_out);
+ }
+
+cleanup:
+ krb5_free_data(context, der_etypes);
+ return ret;
}

View File

@ -1,53 +0,0 @@
From 903fc418db4f5819c507cb0d42c0d4a12217c22f Mon Sep 17 00:00:00 2001
From: Jiri Sasek <Jiri.Sasek@Oracle.COM>
Date: Fri, 13 Mar 2020 19:02:58 +0100
Subject: [PATCH] Add finalization safety check to com_err
If the linker erroneously runs the libkrb5 finalizer after the
libcom_err finalizer, the consequent remove_error_table() calls could
crash due to accessing a destroyed mutex or an invalid et_list
pointer. Add an unsynchronized check on finalized in
remove_error_table(), and set et_list to null in com_err_terminate()
after destroying the list.
[ghudson@mit.edu: minimized code hanges; rewrote comment and commit
message]
ticket: 8890 (new)
(cherry picked from commit 9d654aa05e26bbf22f140abde3436afeff2fdf8d)
---
src/util/et/error_message.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/util/et/error_message.c b/src/util/et/error_message.c
index d7069a9df..7dc02a34e 100644
--- a/src/util/et/error_message.c
+++ b/src/util/et/error_message.c
@@ -26,7 +26,7 @@
static struct et_list *et_list;
static k5_mutex_t et_list_lock = K5_MUTEX_PARTIAL_INITIALIZER;
-static int terminated = 0; /* for debugging shlib fini sequence errors */
+static int terminated = 0; /* for safety and finalization debugging */
MAKE_INIT_FUNCTION(com_err_initialize);
MAKE_FINI_FUNCTION(com_err_terminate);
@@ -69,6 +69,7 @@ void com_err_terminate(void)
enext = e->next;
free(e);
}
+ et_list = NULL;
k5_mutex_unlock(&et_list_lock);
k5_mutex_destroy(&et_list_lock);
terminated = 1;
@@ -280,6 +281,10 @@ remove_error_table(const struct error_table *et)
{
struct et_list **ep, *e;
+ /* Safety check in case libraries are finalized in the wrong order. */
+ if (terminated)
+ return ENOENT;
+
if (CALL_INIT_FUNCTION(com_err_initialize))
return 0;
k5_mutex_lock(&et_list_lock);

View File

@ -1,404 +0,0 @@
From ea2ad3330aa39ef4e62d8856ea7e8eed2843b3f2 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 17 Jun 2020 20:48:38 -0400
Subject: [PATCH] Add three kvno options from Heimdal kgetcred
Add the flags --cached-only and --no-store, which pass the
corresponding options to krb5_get_credentials(). Add the option
--out-cache to write the retrieved credentials to a specified output
cache.
Add a Python test script for kvno command-line options, including
tests for the new options.
ticket: 8917 (new)
(cherry picked from commit 876bab8418d7dd134c9d9db812ee2118d5ad58f0)
[rharwood@redhat.com: slush around option unification]
---
doc/user/user_commands/kvno.rst | 13 ++++
src/clients/kvno/Makefile.in | 3 +
src/clients/kvno/kvno.c | 112 +++++++++++++++++++++++---------
src/clients/kvno/t_kvno.py | 75 +++++++++++++++++++++
src/man/kvno.man | 13 ++++
5 files changed, 185 insertions(+), 31 deletions(-)
create mode 100644 src/clients/kvno/t_kvno.py
diff --git a/doc/user/user_commands/kvno.rst b/doc/user/user_commands/kvno.rst
index 53e569651..6fd8577a5 100644
--- a/doc/user/user_commands/kvno.rst
+++ b/doc/user/user_commands/kvno.rst
@@ -75,6 +75,19 @@ OPTIONS
client principal with the X.509 certificate in *cert_file*. The
certificate file must be in PEM format.
+**--cached-only**
+ Only retrieve credentials already present in the cache, not from
+ the KDC.
+
+**--no-store**
+ Do not store retrieved credentials in the cache. If
+ **--out-cache** is also specified, credentials will still be
+ stored into the output credential cache.
+
+**--out-cache** *ccache*
+ Initialize *ccache* and store all retrieved credentials into it.
+ Do not store acquired credentials in the input cache.
+
**--u2u** *ccache*
Requests a user-to-user ticket. *ccache* must contain a local
krbtgt ticket for the server principal. The reported version
diff --git a/src/clients/kvno/Makefile.in b/src/clients/kvno/Makefile.in
index 1c3f79392..5ba877271 100644
--- a/src/clients/kvno/Makefile.in
+++ b/src/clients/kvno/Makefile.in
@@ -26,6 +26,9 @@ kvno: kvno.o $(KRB5_BASE_DEPLIBS)
##WIN32## link $(EXE_LINKOPTS) /out:$@ $**
##WIN32## $(_VC_MANIFEST_EMBED_EXE)
+check-pytests: kvno
+ $(RUNPYTEST) $(srcdir)/t_kvno.py $(PYTESTFLAGS)
+
clean-unix::
$(RM) kvno.o kvno
diff --git a/src/clients/kvno/kvno.c b/src/clients/kvno/kvno.c
index 8edd97361..c5f6bf700 100644
--- a/src/clients/kvno/kvno.c
+++ b/src/clients/kvno/kvno.c
@@ -47,15 +47,17 @@ xusage()
"[-u | -S sname]" XUSAGE_BREAK
"[[{-F cert_file | {-I | -U} for_user} [-P]] | "
"--u2u ccache]" XUSAGE_BREAK
+ "[--cached-only] [--no-store] [--out-cache] "
"service1 service2 ...\n"),
prog);
exit(1);
}
static void do_v5_kvno(int argc, char *argv[], char *ccachestr, char *etypestr,
- char *keytab_name, char *sname, int canon, int unknown,
- char *for_user, int for_user_enterprise,
- char *for_user_cert_file, int proxy,
+ char *keytab_name, char *sname, int cached_only,
+ int canon, int no_store, int unknown, char *for_user,
+ int for_user_enterprise, char *for_user_cert_file,
+ int proxy, const char *out_ccname,
const char *u2u_ccname);
#include <com_err.h>
@@ -65,18 +67,21 @@ static void extended_com_err_fn(const char *myprog, errcode_t code,
int
main(int argc, char *argv[])
{
- enum { OPTION_U2U = 256 };
- struct option lopts[] = {
- { "u2u", 1, NULL, OPTION_U2U },
- { NULL, 0, NULL, 0 }
- };
+ enum { OPTION_U2U = 256, OPTION_OUT_CACHE = 257 };
const char *shopts = "uCc:e:hk:qPS:I:U:F:";
int option;
char *etypestr = NULL, *ccachestr = NULL, *keytab_name = NULL;
char *sname = NULL, *for_user = NULL, *u2u_ccname = NULL;
- char *for_user_cert_file = NULL;
+ char *for_user_cert_file = NULL, *out_ccname = NULL;
int canon = 0, unknown = 0, proxy = 0, for_user_enterprise = 0;
- int impersonate = 0;
+ int impersonate = 0, cached_only = 0, no_store = 0;
+ struct option lopts[] = {
+ { "cached-only", 0, &cached_only, 1 },
+ { "no-store", 0, &no_store, 1 },
+ { "out-cache", 1, NULL, OPTION_OUT_CACHE },
+ { "u2u", 1, NULL, OPTION_U2U },
+ { NULL, 0, NULL, 0 }
+ };
setlocale(LC_ALL, "");
set_com_err_hook(extended_com_err_fn);
@@ -139,6 +144,12 @@ main(int argc, char *argv[])
case OPTION_U2U:
u2u_ccname = optarg;
break;
+ case OPTION_OUT_CACHE:
+ out_ccname = optarg;
+ break;
+ case 0:
+ /* If this option set a flag, do nothing else now. */
+ break;
default:
xusage();
break;
@@ -163,8 +174,9 @@ main(int argc, char *argv[])
xusage();
do_v5_kvno(argc - optind, argv + optind, ccachestr, etypestr, keytab_name,
- sname, canon, unknown, for_user, for_user_enterprise,
- for_user_cert_file, proxy, u2u_ccname);
+ sname, cached_only, canon, no_store, unknown, for_user,
+ for_user_enterprise, for_user_cert_file, proxy, out_ccname,
+ u2u_ccname);
return 0;
}
@@ -278,14 +290,16 @@ static krb5_error_code
kvno(const char *name, krb5_ccache ccache, krb5_principal me,
krb5_enctype etype, krb5_keytab keytab, const char *sname,
krb5_flags options, int unknown, krb5_principal for_user_princ,
- krb5_data *for_user_cert, int proxy, krb5_data *u2u_ticket)
+ krb5_data *for_user_cert, int proxy, krb5_data *u2u_ticket,
+ krb5_creds **creds_out)
{
krb5_error_code ret;
krb5_principal server = NULL;
krb5_ticket *ticket = NULL;
- krb5_creds in_creds, *out_creds = NULL;
+ krb5_creds in_creds, *creds = NULL;
char *princ = NULL;
+ *creds_out = NULL;
memset(&in_creds, 0, sizeof(in_creds));
if (sname != NULL) {
@@ -325,13 +339,12 @@ kvno(const char *name, krb5_ccache ccache, krb5_principal me,
in_creds.client = for_user_princ;
in_creds.server = me;
ret = krb5_get_credentials_for_user(context, options, ccache,
- &in_creds, for_user_cert,
- &out_creds);
+ &in_creds, for_user_cert, &creds);
} else {
in_creds.client = me;
in_creds.server = server;
ret = krb5_get_credentials(context, options, ccache, &in_creds,
- &out_creds);
+ &creds);
}
if (ret) {
@@ -340,7 +353,7 @@ kvno(const char *name, krb5_ccache ccache, krb5_principal me,
}
/* We need a native ticket. */
- ret = krb5_decode_ticket(&out_creds->ticket, &ticket);
+ ret = krb5_decode_ticket(&creds->ticket, &ticket);
if (ret) {
com_err(prog, ret, _("while decoding ticket for %s"), princ);
goto cleanup;
@@ -366,15 +379,15 @@ kvno(const char *name, krb5_ccache ccache, krb5_principal me,
}
if (proxy) {
- in_creds.client = out_creds->client;
- out_creds->client = NULL;
- krb5_free_creds(context, out_creds);
- out_creds = NULL;
+ in_creds.client = creds->client;
+ creds->client = NULL;
+ krb5_free_creds(context, creds);
+ creds = NULL;
in_creds.server = server;
ret = krb5_get_credentials_for_proxy(context, KRB5_GC_CANONICALIZE,
ccache, &in_creds, ticket,
- &out_creds);
+ &creds);
krb5_free_principal(context, in_creds.client);
if (ret) {
com_err(prog, ret, _("%s: constrained delegation failed"),
@@ -383,10 +396,13 @@ kvno(const char *name, krb5_ccache ccache, krb5_principal me,
}
}
+ *creds_out = creds;
+ creds = NULL;
+
cleanup:
krb5_free_principal(context, server);
krb5_free_ticket(context, ticket);
- krb5_free_creds(context, out_creds);
+ krb5_free_creds(context, creds);
krb5_free_unparsed_name(context, princ);
return ret;
}
@@ -432,19 +448,28 @@ cleanup:
static void
do_v5_kvno(int count, char *names[], char * ccachestr, char *etypestr,
- char *keytab_name, char *sname, int canon, int unknown,
- char *for_user, int for_user_enterprise,
- char *for_user_cert_file, int proxy, const char *u2u_ccname)
+ char *keytab_name, char *sname, int cached_only, int canon,
+ int no_store, int unknown, char *for_user, int for_user_enterprise,
+ char *for_user_cert_file, int proxy, const char *out_ccname,
+ const char *u2u_ccname)
{
krb5_error_code ret;
- int i, errors, flags;
+ int i, errors, flags, initialized = 0;
krb5_enctype etype;
- krb5_ccache ccache;
+ krb5_ccache ccache, out_ccache = NULL;
krb5_principal me;
krb5_keytab keytab = NULL;
krb5_principal for_user_princ = NULL;
- krb5_flags options = canon ? KRB5_GC_CANONICALIZE : 0;
+ krb5_flags options = 0;
krb5_data cert_data = empty_data(), *user_cert = NULL, *u2u_ticket = NULL;
+ krb5_creds *creds;
+
+ if (canon)
+ options |= KRB5_GC_CANONICALIZE;
+ if (cached_only)
+ options |= KRB5_GC_CACHED;
+ if (no_store || out_ccname != NULL)
+ options |= KRB5_GC_NO_STORE;
ret = krb5_init_context(&context);
if (ret) {
@@ -471,6 +496,14 @@ do_v5_kvno(int count, char *names[], char * ccachestr, char *etypestr,
exit(1);
}
+ if (out_ccname != NULL) {
+ ret = krb5_cc_resolve(context, out_ccname, &out_ccache);
+ if (ret) {
+ com_err(prog, ret, _("while resolving output ccache"));
+ exit(1);
+ }
+ }
+
if (keytab_name != NULL) {
ret = krb5_kt_resolve(context, keytab_name, &keytab);
if (ret) {
@@ -517,8 +550,25 @@ do_v5_kvno(int count, char *names[], char * ccachestr, char *etypestr,
errors = 0;
for (i = 0; i < count; i++) {
if (kvno(names[i], ccache, me, etype, keytab, sname, options, unknown,
- for_user_princ, user_cert, proxy, u2u_ticket) != 0)
+ for_user_princ, user_cert, proxy, u2u_ticket, &creds) != 0) {
errors++;
+ } else if (out_ccache != NULL) {
+ if (!initialized) {
+ ret = krb5_cc_initialize(context, out_ccache, creds->client);
+ if (ret) {
+ com_err(prog, ret, _("while initializing output ccache"));
+ exit(1);
+ }
+ initialized = 1;
+ }
+ ret = krb5_cc_store_cred(context, out_ccache, creds);
+ if (ret) {
+ com_err(prog, ret, _("while storing creds in output ccache"));
+ exit(1);
+ }
+ }
+
+ krb5_free_creds(context, creds);
}
if (keytab != NULL)
diff --git a/src/clients/kvno/t_kvno.py b/src/clients/kvno/t_kvno.py
new file mode 100644
index 000000000..e98b90e8a
--- /dev/null
+++ b/src/clients/kvno/t_kvno.py
@@ -0,0 +1,75 @@
+from k5test import *
+
+realm = K5Realm()
+
+def check_cache(ccache, expected_services):
+ # Fetch the klist output and skip past the header.
+ lines = realm.run([klist, '-c', ccache]).splitlines()
+ lines = lines[4:]
+
+ # For each line not beginning with an indent, match against the
+ # expected service principals.
+ svcs = {x: True for x in expected_services}
+ for l in lines:
+ if not l.startswith('\t'):
+ svcprinc = l.split()[4]
+ if svcprinc in svcs:
+ del svcs[svcprinc]
+ else:
+ fail('unexpected service princ ' + svcprinc)
+
+ if svcs:
+ fail('services not found in klist output: ' + ' '.join(svcs.keys()))
+
+
+mark('no options')
+realm.run([kvno, realm.user_princ], expected_msg='user@KRBTEST.COM: kvno = 1')
+check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ])
+
+mark('-e')
+msgs = ('etypes requested in TGS request: camellia128-cts',
+ '/KDC has no support for encryption type')
+realm.run([kvno, '-e', 'camellia128-cts', realm.host_princ],
+ expected_code=1, expected_trace=msgs)
+
+mark('--cached-only')
+realm.run([kvno, '--cached-only', realm.user_princ], expected_msg='kvno = 1')
+realm.run([kvno, '--cached-only', realm.host_princ],
+ expected_code=1, expected_msg='Matching credential not found')
+check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ])
+
+mark('--no-store')
+realm.run([kvno, '--no-store', realm.host_princ], expected_msg='kvno = 1')
+check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ])
+
+mark('--out-cache') # and multiple services
+out_ccache = os.path.join(realm.testdir, 'ccache.out')
+realm.run([kvno, '--out-cache', out_ccache,
+ realm.host_princ, realm.admin_princ])
+check_cache(realm.ccache, [realm.krbtgt_princ, realm.user_princ])
+check_cache(out_ccache, [realm.host_princ, realm.admin_princ])
+
+mark('--out-cache --cached-only') # tests out-cache overwriting, and -q
+realm.run([kvno, '--out-cache', out_ccache, '--cached-only', realm.host_princ],
+ expected_code=1, expected_msg='Matching credential not found')
+out = realm.run([kvno, '-q', '--out-cache', out_ccache, '--cached-only',
+ realm.user_princ])
+if out:
+ fail('unexpected kvno output with -q')
+check_cache(out_ccache, [realm.user_princ])
+
+mark('-U') # and -c
+svc_ccache = os.path.join(realm.testdir, 'ccache.svc')
+realm.run([kinit, '-k', '-c', svc_ccache, realm.host_princ])
+realm.run([kvno, '-c', svc_ccache, '-U', 'user', realm.host_princ])
+realm.run([klist, '-c', svc_ccache], expected_msg='for client user@')
+realm.run([kvno, '-c', svc_ccache, '-U', 'user', '--out-cache', out_ccache,
+ realm.host_princ])
+out = realm.run([klist, '-c', out_ccache])
+if ('Default principal: user@KRBTEST.COM' not in out):
+ fail('wrong default principal in klist output')
+
+# More S4U options are tested in tests/gssapi/t_s4u.py.
+# --u2u is tested in tests/t_u2u.py.
+
+success('kvno tests')
diff --git a/src/man/kvno.man b/src/man/kvno.man
index 9eb9e1852..7c9565bdb 100644
--- a/src/man/kvno.man
+++ b/src/man/kvno.man
@@ -96,6 +96,19 @@ Specifies that protocol transition is to be used, identifying the
client principal with the X.509 certificate in \fIcert_file\fP\&. The
certificate file must be in PEM format.
.TP
+\fB\-\-cached\-only\fP
+Only retrieve credentials already present in the cache, not from
+the KDC.
+.TP
+\fB\-\-no\-store\fP
+Do not store retrieved credentials in the cache. If
+\fB\-\-out\-cache\fP is also specified, credentials will still be
+stored into the output credential cache.
+.TP
+\fB\-\-out\-cache\fP \fIccache\fP
+Initialize \fIccache\fP and store all retrieved credentials into it.
+Do not store acquired credentials in the input cache.
+.TP
\fB\-\-u2u\fP \fIccache\fP
Requests a user\-to\-user ticket. \fIccache\fP must contain a local
krbtgt ticket for the server principal. The reported version

View File

@ -1,80 +0,0 @@
From d27cef7eb6f099fb1ec4e2d49625aee0d8dc1007 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Tue, 22 Sep 2020 01:11:39 +0300
Subject: [PATCH] Adjust KDC alias helper function contract
Change the name of is_client_alias() to is_client_db_alias(), and
change the contract so that the already-canonical principal name comes
from a DB entry (which is less flexible, but clearer since DB entries
always contain canonical principal names). Make the function
available outside of kdc_util.c.
[ghudson@mit.edu: clarified commit message]
(cherry picked from commit 9fb5f572dd6ce808b234cb60a573eac48136d7ca)
---
src/kdc/kdc_util.c | 14 +++++++-------
src/kdc/kdc_util.h | 4 ++++
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index dcb2df8dc..6330387d0 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1463,10 +1463,10 @@ cleanup:
return code;
}
-/* Return true if princ canonicalizes to the same principal as canon. */
-static krb5_boolean
-is_client_alias(krb5_context context, krb5_const_principal canon,
- krb5_const_principal princ)
+/* Return true if princ canonicalizes to the same principal as entry's. */
+krb5_boolean
+is_client_db_alias(krb5_context context, const krb5_db_entry *entry,
+ krb5_const_principal princ)
{
krb5_error_code ret;
krb5_db_entry *self;
@@ -1475,7 +1475,7 @@ is_client_alias(krb5_context context, krb5_const_principal canon,
ret = krb5_db_get_principal(context, princ,
KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY, &self);
if (!ret) {
- is_self = krb5_principal_compare(context, canon, self->princ);
+ is_self = krb5_principal_compare(context, entry->princ, self->princ);
krb5_db_free_principal(context, self);
}
@@ -1535,7 +1535,7 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
/* If the server is local, check that the request is for self. */
if (!isflagset(c_flags, KRB5_KDB_FLAG_ISSUING_REFERRAL) &&
- !is_client_alias(kdc_context, server->princ, client_princ)) {
+ !is_client_db_alias(kdc_context, server, client_princ)) {
*status = "INVALID_S4U2SELF_REQUEST_SERVER_MISMATCH";
return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; /* match Windows error */
}
@@ -1728,7 +1728,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, unsigned int flags,
}
client_princ = *stkt_authdata_client;
- } else if (!is_client_alias(kdc_context, server->princ, server_princ)) {
+ } else if (!is_client_db_alias(kdc_context, server, server_princ)) {
*status = "EVIDENCE_TICKET_MISMATCH";
return KRB5KDC_ERR_SERVER_NOMATCH;
}
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 384b21ad2..2c9d8cf69 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -344,6 +344,10 @@ log_tgs_badtrans(krb5_context ctx, krb5_principal cprinc,
void
log_tgs_alt_tgt(krb5_context context, krb5_principal p);
+krb5_boolean
+is_client_db_alias(krb5_context context, const krb5_db_entry *entry,
+ krb5_const_principal princ);
+
/* FAST*/
enum krb5_fast_kdc_flags {
KRB5_FAST_REPLY_KEY_USED = 0x1,

View File

@ -1,65 +0,0 @@
From 69e45f51b466219bde15b11c8539ea3841281f2b Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Tue, 22 Sep 2020 01:17:11 +0300
Subject: [PATCH] Allow aliases when matching U2U second ticket
In process_tgs_req() when verifying the user-to-user second ticket,
compare the canonical names of the request server and the second
ticket client.
[ghudson@mit.edu: expanded commit message; trimmed tests]
ticket: 8951 (new)
(cherry picked from commit afc494ef9418e6be7fbb887364efa6606b10034a)
---
src/kdc/do_tgs_req.c | 2 +-
src/tests/t_u2u.py | 25 +++++++++++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 463a9c0dd..74cd19e96 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -666,7 +666,7 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
*/
krb5_enc_tkt_part *t2enc = request->second_ticket[st_idx]->enc_part2;
krb5_principal client2 = t2enc->client;
- if (!krb5_principal_compare(kdc_context, request->server, client2)) {
+ if (!is_client_db_alias(kdc_context, server, client2)) {
altcprinc = client2;
errcode = KRB5KDC_ERR_SERVER_NOMATCH;
status = "2ND_TKT_MISMATCH";
diff --git a/src/tests/t_u2u.py b/src/tests/t_u2u.py
index 1ca6ac87e..4b8a82a2f 100644
--- a/src/tests/t_u2u.py
+++ b/src/tests/t_u2u.py
@@ -32,4 +32,29 @@ realm.run([kvno, '--u2u', realm.ccache, realm.user_princ])
realm.run([klist])
+realm.stop()
+
+# Load the test KDB module to test aliases
+testprincs = {'krbtgt/KRBTEST.COM': {'keys': 'aes128-cts'},
+ 'user': {'keys': 'aes128-cts', 'flags': '+preauth'},
+ 'WIN10': {'keys': 'aes128-cts'}}
+kdcconf = {'realms': {'$realm': {'database_module': 'test'}},
+ 'dbmodules': {'test': {'db_library': 'test',
+ 'princs': testprincs,
+ 'alias': {'HOST/win10': 'WIN10'}}}}
+
+realm = K5Realm(kdc_conf=kdcconf, create_kdb=False)
+realm.start_kdc()
+
+# Create a second user principal and get tickets for it.
+u2u_ccache = 'FILE:' + os.path.join(realm.testdir, 'ccu2u')
+realm.extract_keytab('WIN10', realm.keytab)
+realm.kinit('WIN10', None, ['-k', '-c', u2u_ccache])
+
+realm.extract_keytab(realm.user_princ, realm.keytab)
+realm.kinit(realm.user_princ, None, ['-k'])
+
+realm.run([kvno, '--u2u', u2u_ccache, 'HOST/win10'], expected_msg='kvno = 0')
+realm.run([kvno, '--u2u', u2u_ccache, 'WIN10'], expected_msg='kvno = 0')
+
success('user-to-user tests')

View File

@ -1,241 +0,0 @@
From b581e106c65957f48ee088d9243b985d3e9a0be8 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 24 Feb 2020 15:58:59 -0500
Subject: [PATCH] Allow certauth modules to set hw-authent flag
In PKINIT, if a certauth module returns KRB5_CERTAUTH_HWAUTH from its
authorize method, set the hw-authent flag in the ticket.
ticket: 8879 (new)
(cherry picked from commit 50fb43b4a2d97ce2cd53e1ced30e8e8224fede70)
---
doc/plugindev/certauth.rst | 7 +++++--
src/include/krb5/certauth_plugin.h | 9 ++++++---
src/lib/krb5/error_tables/k5e1_err.et | 1 +
src/plugins/certauth/test/Makefile.in | 4 ++--
src/plugins/certauth/test/main.c | 11 +++++++++--
src/plugins/preauth/pkinit/pkinit_srv.c | 24 ++++++++++++++++--------
src/tests/t_certauth.py | 13 +++++++++++++
7 files changed, 52 insertions(+), 17 deletions(-)
diff --git a/doc/plugindev/certauth.rst b/doc/plugindev/certauth.rst
index 8a7f7c5eb..3b715f738 100644
--- a/doc/plugindev/certauth.rst
+++ b/doc/plugindev/certauth.rst
@@ -15,8 +15,11 @@ principal. **authorize** receives the DER-encoded certificate, the
requested client principal, and a pointer to the client's
krb5_db_entry (for modules that link against libkdb5). It returns the
authorization status and optionally outputs a list of authentication
-indicator strings to be added to the ticket. A module must use its
-own internal or library-provided ASN.1 certificate decoder.
+indicator strings to be added to the ticket. Beginning in release
+1.19, the authorize method can request that the hardware
+authentication bit be set in the ticket by returning
+**KRB5_CERTAUTH_HWAUTH**. A module must use its own internal or
+library-provided ASN.1 certificate decoder.
A module can optionally create and destroy module data with the
**init** and **fini** methods. Module data objects last for the
diff --git a/src/include/krb5/certauth_plugin.h b/src/include/krb5/certauth_plugin.h
index 3074790f8..3466cf345 100644
--- a/src/include/krb5/certauth_plugin.h
+++ b/src/include/krb5/certauth_plugin.h
@@ -85,14 +85,17 @@ typedef void
(*krb5_certauth_fini_fn)(krb5_context context, krb5_certauth_moddata moddata);
/*
- * Mandatory:
- * Return 0 if the DER-encoded cert is authorized for PKINIT authentication by
- * princ; otherwise return one of the following error codes:
+ * Mandatory: return 0 or KRB5_CERTAUTH_HWAUTH if the DER-encoded cert is
+ * authorized for PKINIT authentication by princ; otherwise return one of the
+ * following error codes:
* - KRB5KDC_ERR_CLIENT_NAME_MISMATCH - incorrect SAN value
* - KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE - incorrect EKU
* - KRB5KDC_ERR_CERTIFICATE_MISMATCH - other extension error
* - KRB5_PLUGIN_NO_HANDLE - the module has no opinion about cert
*
+ * Returning KRB5_CERTAUTH_HWAUTH will cause the hw-authent flag to be set in
+ * the issued ticket (new in release 1.19).
+ *
* - opts is used by built-in modules to receive internal data, and must be
* ignored by other modules.
* - db_entry receives the client principal database entry, and can be ignored
diff --git a/src/lib/krb5/error_tables/k5e1_err.et b/src/lib/krb5/error_tables/k5e1_err.et
index ade5caecf..abd9f3bfe 100644
--- a/src/lib/krb5/error_tables/k5e1_err.et
+++ b/src/lib/krb5/error_tables/k5e1_err.et
@@ -42,4 +42,5 @@ error_code KRB5_KCM_MALFORMED_REPLY, "Malformed reply from KCM daemon"
error_code KRB5_KCM_RPC_ERROR, "Mach RPC error communicating with KCM daemon"
error_code KRB5_KCM_REPLY_TOO_BIG, "KCM daemon reply too big"
error_code KRB5_KCM_NO_SERVER, "No KCM server found"
+error_code KRB5_CERTAUTH_HWAUTH, "Authorize and set hw-authent ticket flag"
end
diff --git a/src/plugins/certauth/test/Makefile.in b/src/plugins/certauth/test/Makefile.in
index d3524084c..e94c13845 100644
--- a/src/plugins/certauth/test/Makefile.in
+++ b/src/plugins/certauth/test/Makefile.in
@@ -5,8 +5,8 @@ LIBBASE=certauth_test
LIBMAJOR=0
LIBMINOR=0
RELDIR=../plugins/certauth/test
-SHLIB_EXPDEPS=$(KRB5_BASE_DEPLIBS)
-SHLIB_EXPLIBS=$(KRB5_BASE_LIBS)
+SHLIB_EXPDEPS=$(KDB5_DEPLIBS) $(KRB5_BASE_DEPLIBS)
+SHLIB_EXPLIBS=$(KDB5_LIBS) $(KRB5_BASE_LIBS)
STLIBOBJS=main.o
diff --git a/src/plugins/certauth/test/main.c b/src/plugins/certauth/test/main.c
index 77641230c..d4633b8cd 100644
--- a/src/plugins/certauth/test/main.c
+++ b/src/plugins/certauth/test/main.c
@@ -31,6 +31,7 @@
*/
#include <k5-int.h>
+#include <kdb.h>
#include "krb5/certauth_plugin.h"
struct krb5_certauth_moddata_st {
@@ -131,7 +132,8 @@ has_cn(krb5_context context, const uint8_t *cert, size_t cert_len,
/*
* Test module 2 returns OK if princ matches the CN part of the subject name,
- * and returns indicators of the module name and princ.
+ * and returns indicators of the module name and princ. If the "hwauth" string
+ * attribute is set on db_entry, it returns KRB5_CERTAUTH_HWAUTH.
*/
static krb5_error_code
test2_authorize(krb5_context context, krb5_certauth_moddata moddata,
@@ -141,7 +143,7 @@ test2_authorize(krb5_context context, krb5_certauth_moddata moddata,
char ***authinds_out)
{
krb5_error_code ret;
- char *name = NULL, **ais = NULL;
+ char *name = NULL, *strval = NULL, **ais = NULL;
*authinds_out = NULL;
@@ -167,6 +169,11 @@ test2_authorize(krb5_context context, krb5_certauth_moddata moddata,
ais = NULL;
+ ret = krb5_dbe_get_string(context, (krb5_db_entry *)db_entry, "hwauth",
+ &strval);
+ ret = (strval != NULL) ? KRB5_CERTAUTH_HWAUTH : 0;
+ krb5_dbe_free_string(context, strval);
+
cleanup:
krb5_free_unparsed_name(context, name);
return ret;
diff --git a/src/plugins/preauth/pkinit/pkinit_srv.c b/src/plugins/preauth/pkinit/pkinit_srv.c
index feca11806..3ae56c064 100644
--- a/src/plugins/preauth/pkinit/pkinit_srv.c
+++ b/src/plugins/preauth/pkinit/pkinit_srv.c
@@ -320,12 +320,12 @@ static krb5_error_code
authorize_cert(krb5_context context, certauth_handle *certauth_modules,
pkinit_kdc_context plgctx, pkinit_kdc_req_context reqctx,
krb5_kdcpreauth_callbacks cb, krb5_kdcpreauth_rock rock,
- krb5_principal client)
+ krb5_principal client, krb5_boolean *hwauth_out)
{
krb5_error_code ret;
certauth_handle h;
struct certauth_req_opts opts;
- krb5_boolean accepted = FALSE;
+ krb5_boolean accepted = FALSE, hwauth = FALSE;
uint8_t *cert;
size_t i, cert_len;
void *db_ent = NULL;
@@ -347,9 +347,10 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules,
/*
* Check the certificate against each certauth module. For the certificate
- * to be authorized at least one module must return 0, and no module can an
- * error code other than KRB5_PLUGIN_NO_HANDLE (pass). Add indicators from
- * modules that return 0 or pass.
+ * to be authorized at least one module must return 0 or
+ * KRB5_CERTAUTH_HWAUTH, and no module can return an error code other than
+ * KRB5_PLUGIN_NO_HANDLE (pass). Add indicators from modules that return 0
+ * or pass.
*/
ret = KRB5_PLUGIN_NO_HANDLE;
for (i = 0; certauth_modules != NULL && certauth_modules[i] != NULL; i++) {
@@ -359,6 +360,8 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules,
&opts, db_ent, &ais);
if (ret == 0)
accepted = TRUE;
+ else if (ret == KRB5_CERTAUTH_HWAUTH)
+ accepted = hwauth = TRUE;
else if (ret != KRB5_PLUGIN_NO_HANDLE)
goto cleanup;
@@ -374,6 +377,7 @@ authorize_cert(krb5_context context, certauth_handle *certauth_modules,
}
}
+ *hwauth_out = hwauth;
ret = accepted ? 0 : KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
cleanup:
@@ -430,7 +434,7 @@ pkinit_server_verify_padata(krb5_context context,
int is_signed = 1;
krb5_pa_data **e_data = NULL;
krb5_kdcpreauth_modreq modreq = NULL;
- krb5_boolean valid_freshness_token = FALSE;
+ krb5_boolean valid_freshness_token = FALSE, hwauth = FALSE;
char **sp;
pkiDebug("pkinit_verify_padata: entered!\n");
@@ -494,7 +498,7 @@ pkinit_server_verify_padata(krb5_context context,
}
if (is_signed) {
retval = authorize_cert(context, moddata->certauth_modules, plgctx,
- reqctx, cb, rock, request->client);
+ reqctx, cb, rock, request->client, &hwauth);
if (retval)
goto cleanup;
@@ -613,6 +617,8 @@ pkinit_server_verify_padata(krb5_context context,
/* remember to set the PREAUTH flag in the reply */
enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
+ if (hwauth)
+ enc_tkt_reply->flags |= TKT_FLG_HW_AUTH;
modreq = (krb5_kdcpreauth_modreq)reqctx;
reqctx = NULL;
@@ -1044,7 +1050,9 @@ pkinit_server_get_flags(krb5_context kcontext, krb5_preauthtype patype)
{
if (patype == KRB5_PADATA_PKINIT_KX)
return PA_INFO;
- return PA_SUFFICIENT | PA_REPLACES_KEY | PA_TYPED_E_DATA;
+ /* PKINIT does not normally set the hw-authent ticket flag, but a
+ * certauth module can cause it to do so. */
+ return PA_SUFFICIENT | PA_REPLACES_KEY | PA_TYPED_E_DATA | PA_HARDWARE;
}
static krb5_preauthtype supported_server_pa_types[] = {
diff --git a/src/tests/t_certauth.py b/src/tests/t_certauth.py
index 9c7094525..0fe0fdb4a 100644
--- a/src/tests/t_certauth.py
+++ b/src/tests/t_certauth.py
@@ -43,4 +43,17 @@ out = realm.kinit("user2@KRBTEST.COM",
expected_code=1,
expected_msg='kinit: Certificate mismatch')
+# Test the KRB5_CERTAUTH_HWAUTH return code.
+mark('hw-authent flag tests')
+# First test +requires_hwauth without causing the hw-authent ticket
+# flag to be set. This currently results in a preauth loop.
+realm.run([kadminl, 'modprinc', '+requires_hwauth', realm.user_princ])
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % file_identity],
+ expected_code=1, expected_msg='Looping detected')
+# Cause the test2 module to return KRB5_CERTAUTH_HWAUTH and try again.
+realm.run([kadminl, 'setstr', realm.user_princ, 'hwauth', 'x'])
+realm.kinit(realm.user_princ,
+ flags=['-X', 'X509_user_identity=%s' % file_identity])
+
success("certauth tests")

View File

@ -1,298 +0,0 @@
From aad7ffc2cdc5b1c55a5967612730daa2f493fa6e Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 30 Sep 2020 02:12:00 -0400
Subject: [PATCH] Avoid passing DB entry structures in KDC
When validating AS or TGS requests, pass pointers to DB entry
structures, not the structures themselves.
(cherry picked from commit 7ccc08a889b40693b2ce7f108f2cdda51bc04bff)
---
src/kdc/do_as_req.c | 4 ++--
src/kdc/do_tgs_req.c | 2 +-
src/kdc/kdc_util.c | 34 +++++++++++++++++-----------------
src/kdc/kdc_util.h | 6 +++---
src/kdc/tgs_policy.c | 35 ++++++++++++++++++-----------------
5 files changed, 41 insertions(+), 40 deletions(-)
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index 9ae7b0a5e..c2dfea9b8 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -663,8 +663,8 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
au_state->stage = VALIDATE_POL;
if ((errcode = validate_as_request(kdc_active_realm,
- state->request, *state->client,
- *state->server, state->kdc_time,
+ state->request, state->client,
+ state->server, state->kdc_time,
&state->status, &state->e_data))) {
errcode += ERROR_TABLE_BASE_krb5;
goto errout;
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 74cd19e96..d345797c4 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -260,7 +260,7 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
goto cleanup;
if ((retval = validate_tgs_request(kdc_active_realm,
- request, *server, header_ticket,
+ request, server, header_ticket,
kdc_time, &status, &e_data))) {
if (retval == KDC_ERR_POLICY || retval == KDC_ERR_BADOPTION)
au_state->violation = PROT_CONSTRAINT;
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index a4a05b9fa..b2042862a 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -612,8 +612,8 @@ check_anon(kdc_realm_t *kdc_active_realm,
KDC_OPT_ENC_TKT_IN_SKEY | KDC_OPT_CNAME_IN_ADDL_TKT)
int
validate_as_request(kdc_realm_t *kdc_active_realm,
- krb5_kdc_req *request, krb5_db_entry client,
- krb5_db_entry server, krb5_timestamp kdc_time,
+ krb5_kdc_req *request, krb5_db_entry *client,
+ krb5_db_entry *server, krb5_timestamp kdc_time,
const char **status, krb5_pa_data ***e_data)
{
krb5_error_code ret;
@@ -627,7 +627,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
}
/* The client must not be expired */
- if (client.expiration && ts_after(kdc_time, client.expiration)) {
+ if (client->expiration && ts_after(kdc_time, client->expiration)) {
*status = "CLIENT EXPIRED";
if (vague_errors)
return(KRB_ERR_GENERIC);
@@ -637,8 +637,8 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
/* The client's password must not be expired, unless the server is
a KRB5_KDC_PWCHANGE_SERVICE. */
- if (client.pw_expiration && ts_after(kdc_time, client.pw_expiration) &&
- !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
+ if (client->pw_expiration && ts_after(kdc_time, client->pw_expiration) &&
+ !isflagset(server->attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
*status = "CLIENT KEY EXPIRED";
if (vague_errors)
return(KRB_ERR_GENERIC);
@@ -647,7 +647,7 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
}
/* The server must not be expired */
- if (server.expiration && ts_after(kdc_time, server.expiration)) {
+ if (server->expiration && ts_after(kdc_time, server->expiration)) {
*status = "SERVICE EXPIRED";
return(KDC_ERR_SERVICE_EXP);
}
@@ -656,8 +656,8 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
* If the client requires password changing, then only allow the
* pwchange service.
*/
- if (isflagset(client.attributes, KRB5_KDB_REQUIRES_PWCHANGE) &&
- !isflagset(server.attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
+ if (isflagset(client->attributes, KRB5_KDB_REQUIRES_PWCHANGE) &&
+ !isflagset(server->attributes, KRB5_KDB_PWCHANGE_SERVICE)) {
*status = "REQUIRED PWCHANGE";
return(KDC_ERR_KEY_EXP);
}
@@ -665,37 +665,37 @@ validate_as_request(kdc_realm_t *kdc_active_realm,
/* Client and server must allow postdating tickets */
if ((isflagset(request->kdc_options, KDC_OPT_ALLOW_POSTDATE) ||
isflagset(request->kdc_options, KDC_OPT_POSTDATED)) &&
- (isflagset(client.attributes, KRB5_KDB_DISALLOW_POSTDATED) ||
- isflagset(server.attributes, KRB5_KDB_DISALLOW_POSTDATED))) {
+ (isflagset(client->attributes, KRB5_KDB_DISALLOW_POSTDATED) ||
+ isflagset(server->attributes, KRB5_KDB_DISALLOW_POSTDATED))) {
*status = "POSTDATE NOT ALLOWED";
return(KDC_ERR_CANNOT_POSTDATE);
}
/* Check to see if client is locked out */
- if (isflagset(client.attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
+ if (isflagset(client->attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
*status = "CLIENT LOCKED OUT";
return(KDC_ERR_CLIENT_REVOKED);
}
/* Check to see if server is locked out */
- if (isflagset(server.attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
+ if (isflagset(server->attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
*status = "SERVICE LOCKED OUT";
return(KDC_ERR_S_PRINCIPAL_UNKNOWN);
}
/* Check to see if server is allowed to be a service */
- if (isflagset(server.attributes, KRB5_KDB_DISALLOW_SVR)) {
+ if (isflagset(server->attributes, KRB5_KDB_DISALLOW_SVR)) {
*status = "SERVICE NOT ALLOWED";
return(KDC_ERR_MUST_USE_USER2USER);
}
- if (check_anon(kdc_active_realm, client.princ, request->server) != 0) {
+ if (check_anon(kdc_active_realm, client->princ, request->server) != 0) {
*status = "ANONYMOUS NOT ALLOWED";
return(KDC_ERR_POLICY);
}
/* Perform KDB module policy checks. */
- ret = krb5_db_check_policy_as(kdc_context, request, &client, &server,
+ ret = krb5_db_check_policy_as(kdc_context, request, client, server,
kdc_time, status, e_data);
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
return errcode_to_protocol(ret);
@@ -1568,8 +1568,8 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
princ->pw_expiration = 0;
clear(princ->attributes, KRB5_KDB_REQUIRES_PWCHANGE);
- code = validate_as_request(kdc_active_realm, request, *princ,
- no_server, kdc_time, status, &e_data);
+ code = validate_as_request(kdc_active_realm, request, princ,
+ &no_server, kdc_time, status, &e_data);
if (code) {
krb5_db_free_principal(kdc_context, princ);
krb5_free_pa_data(kdc_context, e_data);
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 42b7ee208..04007a8f5 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -76,12 +76,12 @@ get_local_tgt(krb5_context context, const krb5_data *realm,
krb5_db_entry **storage_out, krb5_keyblock *kb_out);
int
-validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
- krb5_db_entry, krb5_timestamp,
+validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry *,
+ krb5_db_entry *, krb5_timestamp,
const char **, krb5_pa_data ***);
int
-validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry,
+validate_tgs_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry *,
krb5_ticket *, krb5_timestamp,
const char **, krb5_pa_data ***);
diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c
index 554345ba5..3f4fa8499 100644
--- a/src/kdc/tgs_policy.c
+++ b/src/kdc/tgs_policy.c
@@ -48,7 +48,7 @@ struct tgsflagrule {
};
/* Service principal TGS policy checking functions */
-typedef int (check_tgs_svc_pol_fn)(krb5_kdc_req *, krb5_db_entry,
+typedef int (check_tgs_svc_pol_fn)(krb5_kdc_req *, krb5_db_entry *,
krb5_ticket *, krb5_timestamp,
const char **);
@@ -110,7 +110,7 @@ static const struct tgsflagrule svcdenyrules[] = {
* A service principal can forbid some TGS-REQ options.
*/
static int
-check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server,
+check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry *server,
krb5_ticket *tkt, krb5_timestamp kdc_time,
const char **status)
{
@@ -122,7 +122,7 @@ check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server,
r = &svcdenyrules[i];
if (!(r->reqflags & req->kdc_options))
continue;
- if (r->checkflag & server.attributes) {
+ if (r->checkflag & server->attributes) {
*status = r->status;
return r->err;
}
@@ -134,20 +134,20 @@ check_tgs_svc_deny_opts(krb5_kdc_req *req, krb5_db_entry server,
* A service principal can deny all TGS-REQs for it.
*/
static int
-check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry server,
+check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry *server,
krb5_ticket *tkt, krb5_timestamp kdc_time,
const char **status)
{
- if (server.attributes & KRB5_KDB_DISALLOW_ALL_TIX) {
+ if (server->attributes & KRB5_KDB_DISALLOW_ALL_TIX) {
*status = "SERVER LOCKED OUT";
return KDC_ERR_S_PRINCIPAL_UNKNOWN;
}
- if ((server.attributes & KRB5_KDB_DISALLOW_SVR) &&
+ if ((server->attributes & KRB5_KDB_DISALLOW_SVR) &&
!(req->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY)) {
*status = "SERVER NOT ALLOWED";
return KDC_ERR_MUST_USE_USER2USER;
}
- if (server.attributes & KRB5_KDB_DISALLOW_TGT_BASED) {
+ if (server->attributes & KRB5_KDB_DISALLOW_TGT_BASED) {
if (krb5_is_tgs_principal(tkt->server)) {
*status = "TGT BASED NOT ALLOWED";
return KDC_ERR_POLICY;
@@ -160,17 +160,17 @@ check_tgs_svc_deny_all(krb5_kdc_req *req, krb5_db_entry server,
* A service principal can require certain TGT flags.
*/
static int
-check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry server,
+check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry *server,
krb5_ticket *tkt,
krb5_timestamp kdc_time, const char **status)
{
- if (server.attributes & KRB5_KDB_REQUIRES_HW_AUTH) {
+ if (server->attributes & KRB5_KDB_REQUIRES_HW_AUTH) {
if (!(tkt->enc_part2->flags & TKT_FLG_HW_AUTH)) {
*status = "NO HW PREAUTH";
return KRB_ERR_GENERIC;
}
}
- if (server.attributes & KRB5_KDB_REQUIRES_PRE_AUTH) {
+ if (server->attributes & KRB5_KDB_REQUIRES_PRE_AUTH) {
if (!(tkt->enc_part2->flags & TKT_FLG_PRE_AUTH)) {
*status = "NO PREAUTH";
return KRB_ERR_GENERIC;
@@ -180,10 +180,10 @@ check_tgs_svc_reqd_flags(krb5_kdc_req *req, krb5_db_entry server,
}
static int
-check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
+check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry *server, krb5_ticket *tkt,
krb5_timestamp kdc_time, const char **status)
{
- if (server.expiration && ts_after(kdc_time, server.expiration)) {
+ if (server->expiration && ts_after(kdc_time, server->expiration)) {
*status = "SERVICE EXPIRED";
return KDC_ERR_SERVICE_EXP;
}
@@ -191,8 +191,9 @@ check_tgs_svc_time(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
}
static int
-check_tgs_svc_policy(krb5_kdc_req *req, krb5_db_entry server, krb5_ticket *tkt,
- krb5_timestamp kdc_time, const char **status)
+check_tgs_svc_policy(krb5_kdc_req *req, krb5_db_entry *server,
+ krb5_ticket *tkt, krb5_timestamp kdc_time,
+ const char **status)
{
int errcode;
size_t i;
@@ -317,7 +318,7 @@ check_tgs_tgt(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
int
validate_tgs_request(kdc_realm_t *kdc_active_realm,
- krb5_kdc_req *request, krb5_db_entry server,
+ krb5_kdc_req *request, krb5_db_entry *server,
krb5_ticket *ticket, krb5_timestamp kdc_time,
const char **status, krb5_pa_data ***e_data)
{
@@ -367,8 +368,8 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm,
}
/* Perform KDB module policy checks. */
- ret = krb5_db_check_policy_tgs(kdc_context, request, &server,
- ticket, status, e_data);
+ ret = krb5_db_check_policy_tgs(kdc_context, request, server, ticket,
+ status, e_data);
if (ret && ret != KRB5_PLUGIN_OP_NOTSUPP)
return errcode_to_protocol(ret);

View File

@ -1,52 +0,0 @@
From 5a0900dc3f0ce7569db2ed6d14da3f97b47bd120 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Mon, 30 Mar 2020 15:26:02 -0400
Subject: [PATCH] Correctly import "service@" GSS host-based name
The intended way to specify only a service in a GSS host-based name is
to omit the "@" separator. Some applications include the separator
but no hostname, and this happened to yield wildcard hostname behavior
prior to commit 996353767fe8afa7f67a3b5b465e4d70e18bad7c when
shortname qualification was added. To restore this behavior, check in
parse_hostbased() that at least one character is present after the "@"
separator before copying the hostname. Add a test case to t_gssapi.py.
ticket: 8892
tags: pullup
target_version: 1.18-next
(cherry picked from commit a2f047af0400ba8080dc26033fae2b17534501e2)
---
src/lib/gssapi/krb5/import_name.c | 4 ++--
src/tests/gssapi/t_gssapi.py | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/lib/gssapi/krb5/import_name.c b/src/lib/gssapi/krb5/import_name.c
index da2ab1423..21023dd76 100644
--- a/src/lib/gssapi/krb5/import_name.c
+++ b/src/lib/gssapi/krb5/import_name.c
@@ -102,8 +102,8 @@ parse_hostbased(const char *str, size_t len,
memcpy(service, str, servicelen);
service[servicelen] = '\0';
- /* If present, copy the hostname. */
- if (at != NULL) {
+ /* Copy the hostname if present (at least one character after '@'). */
+ if (len - servicelen > 1) {
hostlen = len - servicelen - 1;
host = malloc(hostlen + 1);
if (host == NULL) {
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
index 54d5cf549..ecf982604 100755
--- a/src/tests/gssapi/t_gssapi.py
+++ b/src/tests/gssapi/t_gssapi.py
@@ -47,6 +47,9 @@ realm.run(['./t_accname', 'p:service2/calvin', 'h:service2'],
expected_msg='service2/calvin')
realm.run(['./t_accname', 'p:service2/calvin', 'h:service1'], expected_code=1,
expected_msg=' found in keytab but does not match server principal')
+# Regression test for #8892 (trailing @ in name).
+realm.run(['./t_accname', 'p:service1/andrew', 'h:service1@'],
+ expected_msg='service1/abraham')
# Test with acceptor name containing service and host. Use the
# client's un-canonicalized hostname as acceptor input to mirror what

View File

@ -1,371 +0,0 @@
From bec1b3601b15397df07b3464959da92915eb45b5 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 27 May 2020 18:48:35 -0400
Subject: [PATCH] Default dns_canonicalize_hostname to "fallback"
This change should mitigate some of the pain caused by the rdns=true
default (generally associated with unwanted PTR records that cannot
easily be changed), with a minimum of fallout.
Update the documentation and tests accordingly. In test environments,
disable qualify_shortname and use the uncanonicalized system hostname
(lowercased) to match the initial sn2princ result.
ticket: 8911 (new)
---
doc/admin/appl_servers.rst | 14 +++---
doc/admin/conf_files/krb5_conf.rst | 9 ++--
doc/admin/princ_dns.rst | 44 +++++++++++--------
src/kadmin/testing/proto/krb5.conf.proto | 8 ++--
src/kadmin/testing/scripts/env-setup.shin | 4 +-
src/kadmin/testing/scripts/init_db | 3 +-
src/kadmin/testing/scripts/start_servers | 3 +-
.../testing/scripts/start_servers_local | 2 +-
.../kadm5/unit-test/api.current/init-v2.exp | 6 +--
src/lib/krb5/krb/init_ctx.c | 2 +-
src/tests/dejagnu/config/default.exp | 5 +--
src/tests/t_sn2princ.py | 5 ++-
src/util/k5test.py | 25 +++--------
13 files changed, 58 insertions(+), 72 deletions(-)
diff --git a/doc/admin/appl_servers.rst b/doc/admin/appl_servers.rst
index 5232db9af..afdf30297 100644
--- a/doc/admin/appl_servers.rst
+++ b/doc/admin/appl_servers.rst
@@ -115,14 +115,12 @@ Getting DNS information correct
-------------------------------
Several aspects of Kerberos rely on name service. When a hostname is
-used to name a service, the Kerberos library canonicalizes the
-hostname using forward and reverse name resolution. (The reverse name
-resolution step can be turned off using the **rdns** variable in
-:ref:`libdefaults`.) The result of this canonicalization must match
-the principal entry in the host's keytab, or authentication will fail.
-
-Each host's canonical name must be the fully-qualified host name
-(including the domain), and each host's IP address must
+used to name a service, clients may canonicalize the hostname using
+forward and possibly reverse name resolution. The result of this
+canonicalization must match the principal entry in the host's keytab,
+or authentication will fail. To work with all client canonicalization
+configurations, each host's canonical name must be the fully-qualified
+host name (including the domain), and each host's IP address must
reverse-resolve to the canonical name.
Configuration of hostnames varies by operating system. On the
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 3a8b9cf47..38f450367 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -188,11 +188,10 @@ The libdefaults section may contain any of the following relations:
hostnames for use in service principal names. Setting this flag
to false can improve security by reducing reliance on DNS, but
means that short hostnames will not be canonicalized to
- fully-qualified hostnames. The default value is true.
-
- If this option is set to ``fallback`` (new in release 1.18), DNS
- canonicalization will only be performed the server hostname is not
- found with the original name when requesting credentials.
+ fully-qualified hostnames. If this option is set to ``fallback`` (new
+ in release 1.18), DNS canonicalization will only be performed the
+ server hostname is not found with the original name when
+ requesting credentials. The default value is ``fallback``.
**dns_lookup_kdc**
Indicate whether DNS SRV records should be used to locate the KDCs
diff --git a/doc/admin/princ_dns.rst b/doc/admin/princ_dns.rst
index e1d823f27..32a269afc 100644
--- a/doc/admin/princ_dns.rst
+++ b/doc/admin/princ_dns.rst
@@ -31,27 +31,35 @@ based on rotating ``CNAME`` records in DNS.
Service principal canonicalization
----------------------------------
-MIT Kerberos clients currently always do forward resolution (looking
-up the IPv4 and possibly IPv6 addresses using ``getaddrinfo()``) of
-the hostname part of a host-based service principal to canonicalize
-the hostname. They obtain the "canonical" name of the host when doing
-so. By default, MIT Kerberos clients will also then do reverse DNS
-resolution (looking up the hostname associated with the IPv4 or IPv6
-address using ``getnameinfo()``) of the hostname. Using the
-:ref:`krb5.conf(5)` setting::
+In the MIT krb5 client library, canonicalization of host-based service
+principals is controlled by the **dns_canonicalize_hostname**,
+**rnds**, and **qualify_shortname** variables in :ref:`libdefaults`.
- [libdefaults]
- rdns = false
+If **dns_canonicalize_hostname** is set to ``true`` (the default value
+before release 1.19), the client performs forward resolution by
+looking up the IPv4 and/or IPv6 addresses of the hostname using
+``getaddrinfo()``. This process will typically add a domain suffix to
+the hostname if needed, and follow CNAME records in the DNS. If
+**rdns** is also set to ``true`` (the default), the client will then
+perform a reverse lookup of the first returned Internet address using
+``getnameinfo()``, finding the name associated with the PTR record.
-will disable reverse DNS lookup on clients. The default setting is
-"true".
+If **dns_canonicalize_hostname** is set to ``false``, the hostname is
+not canonicalized using DNS. If the hostname has only one component
+(i.e. it contains no "." characters), the host's primary DNS search
+domain will be appended, if there is one. The **qualify_shortname**
+variable can be used to override or disable this suffix.
+
+If **dns_canonicalize_hostname** is set to ``fallback`` (the default
+value in release 1.19 and later), the hostname is initially treated
+according to the rules for ``dns_canonicalize_hostname=false``. If a
+ticket request fails because the service principal is unknown, it the
+hostname will be canonicalized according to the rules for
+``dns_canonicalize_hostname=true`` and the request will be retried.
+
+In all cases, the hostname is converted to lowercase, and any trailing
+dot is removed.
-Operating system bugs may prevent a setting of ``rdns = false`` from
-disabling reverse DNS lookup. Some versions of GNU libc have a bug in
-``getaddrinfo()`` that cause them to look up ``PTR`` records even when
-not required. MIT Kerberos releases krb5-1.10.2 and newer have a
-workaround for this problem, as does the krb5-1.9.x series as of
-release krb5-1.9.4.
Reverse DNS mismatches
diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto
index e710852d4..c0af716a5 100644
--- a/src/kadmin/testing/proto/krb5.conf.proto
+++ b/src/kadmin/testing/proto/krb5.conf.proto
@@ -2,19 +2,19 @@
default_realm = __REALM__
default_keytab_name = FILE:__K5ROOT__/keytab
dns_fallback = no
+ qualify_shortname = ""
plugin_base_dir = __PLUGIN_DIR__
allow_weak_crypto = true
[realms]
__REALM__ = {
- kdc = __KDCHOST__:1750
- admin_server = __KDCHOST__:1751
+ kdc = __HOSTNAME__:1750
+ admin_server = __HOSTNAME__:1751
database_module = foobar_db2_module_blah
}
[domain_realm]
- __LOCALHOST__ = __REALM__
- __KDCHOST__ = __REALM__
+ __HOSTNAME__ = __REALM__
[logging]
admin_server = FILE:__K5ROOT__/syslog
diff --git a/src/kadmin/testing/scripts/env-setup.shin b/src/kadmin/testing/scripts/env-setup.shin
index 969c5340c..88f8ad1aa 100755
--- a/src/kadmin/testing/scripts/env-setup.shin
+++ b/src/kadmin/testing/scripts/env-setup.shin
@@ -71,8 +71,8 @@ BSDDB_DUMP=$TESTDIR/util/bsddb_dump; export BSDDB_DUMP
CLNTTCL=$TESTDIR/util/kadm5_clnt_tcl; export CLNTTCL
SRVTCL=$TESTDIR/util/kadm5_srv_tcl; export SRVTCL
-QUALNAME=`$BUILDTOP/tests/resolve/resolve -q | tr '[A-Z]' '[a-z]'`
-export QUALNAME
+HOSTNAME=`hostname | tr '[A-Z]' '[a-z]'`
+export HOSTNAME
KRB5_CONFIG=$K5ROOT/krb5.conf; export KRB5_CONFIG
KRB5_KDC_PROFILE=$K5ROOT/kdc.conf; export KRB5_KDC_PROFILE
diff --git a/src/kadmin/testing/scripts/init_db b/src/kadmin/testing/scripts/init_db
index e65826c96..216f62793 100755
--- a/src/kadmin/testing/scripts/init_db
+++ b/src/kadmin/testing/scripts/init_db
@@ -79,8 +79,7 @@ fi
# done
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
- -e "s/__KDCHOST__/$QUALNAME/g" \
- -e "s/__LOCALHOST__/$QUALNAME/g" \
+ -e "s/__HOSTNAME__/$HOSTNAME/g" \
-e "s#__MODDIR__#$MODDIR#g" \
< $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
diff --git a/src/kadmin/testing/scripts/start_servers b/src/kadmin/testing/scripts/start_servers
index f23df0682..05519e4ee 100755
--- a/src/kadmin/testing/scripts/start_servers
+++ b/src/kadmin/testing/scripts/start_servers
@@ -36,8 +36,7 @@ if [ $local = 0 ]; then
# Fix up the local krb5.conf to point to the remote
sed -e "s/__REALM__/$REALM/g" -e "s#__K5ROOT__#$K5ROOT#g" \
- -e "s/__KDCHOST__/$hostname/g" \
- -e "s/__LOCALHOST__/$QUALNAME/g" \
+ -e "s/__HOSTNAME__/$HOSTNAME/g" \
-e "s#__MODDIR__#$TOP/../plugins/kdb#g"\
-e "s#__PLUGIN_DIR__#$TOP/../plugins#g"\
< $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf
diff --git a/src/kadmin/testing/scripts/start_servers_local b/src/kadmin/testing/scripts/start_servers_local
index 998ef9164..858e88031 100755
--- a/src/kadmin/testing/scripts/start_servers_local
+++ b/src/kadmin/testing/scripts/start_servers_local
@@ -79,7 +79,7 @@ cat - > /tmp/start_servers_local$$ <<\EOF
if { [catch {
source $env(STOP)/testing/tcl/util.t
set r $env(REALM)
- set q $env(QUALNAME)
+ set q $env(HOSTNAME)
puts stdout [kadm5_init $env(SRVTCL) mrroot null \
[config_params {KADM5_CONFIG_REALM} $r] \
$KADM5_STRUCT_VERSION $KADM5_API_VERSION_3 server_handle]
diff --git a/src/lib/kadm5/unit-test/api.current/init-v2.exp b/src/lib/kadm5/unit-test/api.current/init-v2.exp
index 7a353d4e9..47764c212 100644
--- a/src/lib/kadm5/unit-test/api.current/init-v2.exp
+++ b/src/lib/kadm5/unit-test/api.current/init-v2.exp
@@ -3,18 +3,14 @@ load_lib lib.t
api_exit
api_start
-if ![info exists RESOLVE] {
- set RESOLVE [findfile $objdir/../../../tests/resolve/resolve]
-}
proc get_hostname { } {
- global RESOLVE
global hostname
if {[info exists hostname]} {
return 1
}
- catch "exec $RESOLVE -q >myname" exec_output
+ catch "exec hostname >myname" exec_output
if ![string match "" $exec_output] {
send_log "$exec_output\n"
verbose $exec_output
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 9a4741fa6..0b8ae6714 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -237,7 +237,7 @@ krb5_init_context_profile(profile_t profile, krb5_flags flags,
ctx->enforce_ok_as_delegate = tmp;
retval = get_tristate(ctx, KRB5_CONF_DNS_CANONICALIZE_HOSTNAME, "fallback",
- CANONHOST_FALLBACK, 1, &tmp);
+ CANONHOST_FALLBACK, CANONHOST_FALLBACK, &tmp);
if (retval)
goto cleanup;
ctx->dns_canonicalize_hostname = tmp;
diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp
index 4d8c917cd..1e7777f1e 100644
--- a/src/tests/dejagnu/config/default.exp
+++ b/src/tests/dejagnu/config/default.exp
@@ -268,7 +268,6 @@ foreach i {
{KTUTIL $objdir/../../kadmin/ktutil/ktutil}
{KLIST $objdir/../../clients/klist/klist}
{KDESTROY $objdir/../../clients/kdestroy/kdestroy}
- {RESOLVE $objdir/../resolve/resolve}
{T_INETD $objdir/t_inetd}
{KPROPLOG $objdir/../../kprop/kproplog}
{KPASSWD $objdir/../../clients/kpasswd/kpasswd}
@@ -462,7 +461,6 @@ proc setup_runtime_env { } {
# 0 on failure.
proc get_hostname { } {
- global RESOLVE
global hostname
global tmppwd
@@ -472,7 +470,7 @@ proc get_hostname { } {
envstack_push
setup_runtime_env
- catch "exec $RESOLVE -q >$tmppwd/hostname" exec_output
+ catch "exec hostname >$tmppwd/hostname" exec_output
envstack_pop
if ![string match "" $exec_output] {
verbose -log $exec_output
@@ -710,6 +708,7 @@ proc setup_krb5_conf { {type client} } {
puts $conffile "\[libdefaults\]"
puts $conffile " default_realm = $REALMNAME"
puts $conffile " dns_lookup_kdc = false"
+ puts $conffile " qualify_shortname = \"\""
if [info exists allow_weak_crypto($type)] {
puts $conffile " allow_weak_crypto = $allow_weak_crypto($type)"
} else {
diff --git a/src/tests/t_sn2princ.py b/src/tests/t_sn2princ.py
index 26dcb91c2..f3e187286 100755
--- a/src/tests/t_sn2princ.py
+++ b/src/tests/t_sn2princ.py
@@ -2,7 +2,8 @@ from k5test import *
offline = (len(args) > 0 and args[0] != "no")
-conf = {'domain_realm': {'kerberos.org': 'R1',
+conf = {'libdefaults': {'dns_canonicalize_hostname': 'true'},
+ 'domain_realm': {'kerberos.org': 'R1',
'example.com': 'R2',
'mit.edu': 'R3'}}
no_rdns_conf = {'libdefaults': {'rdns': 'false'}}
@@ -28,7 +29,7 @@ def testbase(host, nametype, princhost, princrealm, env=None):
fail('Expected %s, got %s' % (expected, out))
def test(host, princhost, princrealm):
- # Test with the host-based name type in the default environment.
+ # Test with the host-based name type with canonicalization enabled.
testbase(host, 'srv-hst', princhost, princrealm)
def testnc(host, princhost, princrealm):
diff --git a/src/util/k5test.py b/src/util/k5test.py
index eea92275d..5196cfa43 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -193,7 +193,10 @@ Scripts may use the following functions and variables:
* plugins: The plugin directory in the build tree (absolute path).
-* hostname: This machine's fully-qualified domain name.
+* hostname: The local hostname as it will initially appear in
+ krb5_sname_to_principal() results. (Shortname qualification is
+ turned off in the test environment to make this value easy to
+ discover from Python.)
* null_input: A file opened to read /dev/null.
@@ -525,23 +528,6 @@ def _find_srctop():
return os.path.abspath(root)
-# Return the local hostname as it will be canonicalized by
-# krb5_sname_to_principal. We can't simply use socket.getfqdn()
-# because it explicitly prefers results containing periods and
-# krb5_sname_to_principal doesn't care.
-def _get_hostname():
- hostname = socket.gethostname()
- try:
- ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME)
- except socket.gaierror as e:
- fail('Local hostname "%s" does not resolve: %s.' % (hostname, e[1]))
- (family, socktype, proto, canonname, sockaddr) = ai[0]
- try:
- name = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
- except socket.gaierror:
- return canonname.lower()
- return name[0].lower()
-
# Parse command line arguments, setting global option variables. Also
# sets the global variable args to the positional arguments, which may
# be used by the test script.
@@ -1263,6 +1249,7 @@ _default_krb5_conf = {
'libdefaults': {
'default_realm': '$realm',
'dns_lookup_kdc': 'false',
+ 'qualify_shortname': '',
'plugin_base_dir': '$plugins'},
'realms': {'$realm': {
'kdc': '$hostname:$port0',
@@ -1356,7 +1343,7 @@ buildtop = _find_buildtop()
srctop = _find_srctop()
plugins = os.path.join(buildtop, 'plugins')
runenv = _import_runenv()
-hostname = _get_hostname()
+hostname = socket.gethostname().lower()
null_input = open(os.devnull, 'r')
# A DB pass is a tuple of: name, kdc_conf.

View File

@ -1,425 +0,0 @@
From 4369b03968131b005acbafd043465899da50e1dc Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 28 Feb 2020 10:11:49 +0100
Subject: [PATCH] Do expiration warnings for all init_creds APIs
Move the password expiration warning code from gic_pwd.c to
get_in_tkt.c. Call it from init_creds_step_reply() on successful
completion.
[ghudson@mit.edu: added test case; simplified doc comment; moved call
site to init_creds_step_reply(); rewrote commit message]
ticket: 8893 (new)
(cherry picked from commit e1efb890f7ac31b32c68ab816ef118dbfb5a8c7e)
---
src/include/krb5/krb5.hin | 9 ++-
src/lib/krb5/krb/get_in_tkt.c | 112 ++++++++++++++++++++++++++++++
src/lib/krb5/krb/gic_pwd.c | 110 -----------------------------
src/lib/krb5/krb/t_expire_warn.c | 47 +++++++++----
src/lib/krb5/krb/t_expire_warn.py | 22 ++++--
5 files changed, 165 insertions(+), 135 deletions(-)
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 6355e6540..f8269fb17 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -7174,11 +7174,10 @@ typedef void
*
* Set a callback to receive password and account expiration times.
*
- * This option only applies to krb5_get_init_creds_password(). @a cb will be
- * invoked if and only if credentials are successfully acquired. The callback
- * will receive the @a context from the krb5_get_init_creds_password() call and
- * the @a data argument supplied with this API. The remaining arguments should
- * be interpreted as follows:
+ * @a cb will be invoked if and only if credentials are successfully acquired.
+ * The callback will receive the @a context from the calling function and the
+ * @a data argument supplied with this API. The remaining arguments should be
+ * interpreted as follows:
*
* If @a is_last_req is true, then the KDC reply contained last-req entries
* which unambiguously indicated the password expiration, account expiration,
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index 870df62a1..cc0f70e83 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1482,6 +1482,116 @@ accept_method_data(krb5_context context, krb5_init_creds_context ctx)
ctx->method_padata);
}
+/* Return the password expiry time indicated by enc_part2. Set *is_last_req
+ * if the information came from a last_req value. */
+static void
+get_expiry_times(krb5_enc_kdc_rep_part *enc_part2, krb5_timestamp *pw_exp,
+ krb5_timestamp *acct_exp, krb5_boolean *is_last_req)
+{
+ krb5_last_req_entry **last_req;
+ krb5_int32 lr_type;
+
+ *pw_exp = 0;
+ *acct_exp = 0;
+ *is_last_req = FALSE;
+
+ /* Look for last-req entries for password or account expiration. */
+ if (enc_part2->last_req) {
+ for (last_req = enc_part2->last_req; *last_req; last_req++) {
+ lr_type = (*last_req)->lr_type;
+ if (lr_type == KRB5_LRQ_ALL_PW_EXPTIME ||
+ lr_type == KRB5_LRQ_ONE_PW_EXPTIME) {
+ *is_last_req = TRUE;
+ *pw_exp = (*last_req)->value;
+ } else if (lr_type == KRB5_LRQ_ALL_ACCT_EXPTIME ||
+ lr_type == KRB5_LRQ_ONE_ACCT_EXPTIME) {
+ *is_last_req = TRUE;
+ *acct_exp = (*last_req)->value;
+ }
+ }
+ }
+
+ /* If we didn't find any, use the ambiguous key_exp field. */
+ if (*is_last_req == FALSE)
+ *pw_exp = enc_part2->key_exp;
+}
+
+/*
+ * Send an appropriate warning prompter if as_reply indicates that the password
+ * is going to expire soon. If an expire callback was provided, use that
+ * instead.
+ */
+static void
+warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
+ krb5_prompter_fct prompter, void *data,
+ const char *in_tkt_service, krb5_kdc_rep *as_reply)
+{
+ krb5_error_code ret;
+ krb5_expire_callback_func expire_cb;
+ void *expire_data;
+ krb5_timestamp pw_exp, acct_exp, now;
+ krb5_boolean is_last_req;
+ krb5_deltat delta;
+ char ts[256], banner[1024];
+
+ if (as_reply == NULL || as_reply->enc_part2 == NULL)
+ return;
+
+ get_expiry_times(as_reply->enc_part2, &pw_exp, &acct_exp, &is_last_req);
+
+ k5_gic_opt_get_expire_cb(options, &expire_cb, &expire_data);
+ if (expire_cb != NULL) {
+ /* Invoke the expire callback and don't send prompter warnings. */
+ (*expire_cb)(context, expire_data, pw_exp, acct_exp, is_last_req);
+ return;
+ }
+
+ /* Don't warn if no password expiry value was sent. */
+ if (pw_exp == 0)
+ return;
+
+ /* Don't warn if the password is being changed. */
+ if (in_tkt_service && strcmp(in_tkt_service, "kadmin/changepw") == 0)
+ return;
+
+ /*
+ * If the expiry time came from a last_req field, assume the KDC wants us
+ * to warn. Otherwise, warn only if the expiry time is less than a week
+ * from now.
+ */
+ ret = krb5_timeofday(context, &now);
+ if (ret != 0)
+ return;
+ if (!is_last_req &&
+ (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60))
+ return;
+
+ if (!prompter)
+ return;
+
+ ret = krb5_timestamp_to_string(pw_exp, ts, sizeof(ts));
+ if (ret != 0)
+ return;
+
+ delta = ts_delta(pw_exp, now);
+ if (delta < 3600) {
+ snprintf(banner, sizeof(banner),
+ _("Warning: Your password will expire in less than one hour "
+ "on %s"), ts);
+ } else if (delta < 86400 * 2) {
+ snprintf(banner, sizeof(banner),
+ _("Warning: Your password will expire in %d hour%s on %s"),
+ delta / 3600, delta < 7200 ? "" : "s", ts);
+ } else {
+ snprintf(banner, sizeof(banner),
+ _("Warning: Your password will expire in %d days on %s"),
+ delta / 86400, ts);
+ }
+
+ /* PROMPTER_INVOCATION */
+ (*prompter)(context, data, 0, banner, 0, 0);
+}
+
static krb5_error_code
init_creds_step_reply(krb5_context context,
krb5_init_creds_context ctx,
@@ -1693,6 +1803,8 @@ init_creds_step_reply(krb5_context context,
/* success */
ctx->complete = TRUE;
+ warn_pw_expiry(context, ctx->opt, ctx->prompter, ctx->prompter_data,
+ ctx->in_tkt_service, ctx->reply);
cleanup:
krb5_free_pa_data(context, kdc_padata);
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
index 14ce23ba4..54e0a8ebe 100644
--- a/src/lib/krb5/krb/gic_pwd.c
+++ b/src/lib/krb5/krb/gic_pwd.c
@@ -133,113 +133,6 @@ krb5_init_creds_set_password(krb5_context context,
return 0;
}
-/* Return the password expiry time indicated by enc_part2. Set *is_last_req
- * if the information came from a last_req value. */
-static void
-get_expiry_times(krb5_enc_kdc_rep_part *enc_part2, krb5_timestamp *pw_exp,
- krb5_timestamp *acct_exp, krb5_boolean *is_last_req)
-{
- krb5_last_req_entry **last_req;
- krb5_int32 lr_type;
-
- *pw_exp = 0;
- *acct_exp = 0;
- *is_last_req = FALSE;
-
- /* Look for last-req entries for password or account expiration. */
- if (enc_part2->last_req) {
- for (last_req = enc_part2->last_req; *last_req; last_req++) {
- lr_type = (*last_req)->lr_type;
- if (lr_type == KRB5_LRQ_ALL_PW_EXPTIME ||
- lr_type == KRB5_LRQ_ONE_PW_EXPTIME) {
- *is_last_req = TRUE;
- *pw_exp = (*last_req)->value;
- } else if (lr_type == KRB5_LRQ_ALL_ACCT_EXPTIME ||
- lr_type == KRB5_LRQ_ONE_ACCT_EXPTIME) {
- *is_last_req = TRUE;
- *acct_exp = (*last_req)->value;
- }
- }
- }
-
- /* If we didn't find any, use the ambiguous key_exp field. */
- if (*is_last_req == FALSE)
- *pw_exp = enc_part2->key_exp;
-}
-
-/*
- * Send an appropriate warning prompter if as_reply indicates that the password
- * is going to expire soon. If an expire callback was provided, use that
- * instead.
- */
-static void
-warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
- krb5_prompter_fct prompter, void *data,
- const char *in_tkt_service, krb5_kdc_rep *as_reply)
-{
- krb5_error_code ret;
- krb5_expire_callback_func expire_cb;
- void *expire_data;
- krb5_timestamp pw_exp, acct_exp, now;
- krb5_boolean is_last_req;
- krb5_deltat delta;
- char ts[256], banner[1024];
-
- get_expiry_times(as_reply->enc_part2, &pw_exp, &acct_exp, &is_last_req);
-
- k5_gic_opt_get_expire_cb(options, &expire_cb, &expire_data);
- if (expire_cb != NULL) {
- /* Invoke the expire callback and don't send prompter warnings. */
- (*expire_cb)(context, expire_data, pw_exp, acct_exp, is_last_req);
- return;
- }
-
- /* Don't warn if no password expiry value was sent. */
- if (pw_exp == 0)
- return;
-
- /* Don't warn if the password is being changed. */
- if (in_tkt_service && strcmp(in_tkt_service, "kadmin/changepw") == 0)
- return;
-
- /*
- * If the expiry time came from a last_req field, assume the KDC wants us
- * to warn. Otherwise, warn only if the expiry time is less than a week
- * from now.
- */
- ret = krb5_timeofday(context, &now);
- if (ret != 0)
- return;
- if (!is_last_req &&
- (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60))
- return;
-
- if (!prompter)
- return;
-
- ret = krb5_timestamp_to_string(pw_exp, ts, sizeof(ts));
- if (ret != 0)
- return;
-
- delta = ts_delta(pw_exp, now);
- if (delta < 3600) {
- snprintf(banner, sizeof(banner),
- _("Warning: Your password will expire in less than one hour "
- "on %s"), ts);
- } else if (delta < 86400*2) {
- snprintf(banner, sizeof(banner),
- _("Warning: Your password will expire in %d hour%s on %s"),
- delta / 3600, delta < 7200 ? "" : "s", ts);
- } else {
- snprintf(banner, sizeof(banner),
- _("Warning: Your password will expire in %d days on %s"),
- delta / 86400, ts);
- }
-
- /* PROMPTER_INVOCATION */
- (*prompter)(context, data, 0, banner, 0, 0);
-}
-
/*
* Create a temporary options structure for getting a kadmin/changepw ticket,
* based on the appplication-specified options. Propagate all application
@@ -496,9 +389,6 @@ krb5_get_init_creds_password(krb5_context context,
goto cleanup;
cleanup:
- if (ret == 0)
- warn_pw_expiry(context, options, prompter, data, in_tkt_service,
- as_reply);
free(chpw_opts);
zapfree(gakpw.storage.data, gakpw.storage.length);
memset(pw0array, 0, sizeof(pw0array));
diff --git a/src/lib/krb5/krb/t_expire_warn.c b/src/lib/krb5/krb/t_expire_warn.c
index 1e59acba1..dc8dc8fb3 100644
--- a/src/lib/krb5/krb/t_expire_warn.c
+++ b/src/lib/krb5/krb/t_expire_warn.c
@@ -28,6 +28,13 @@
static int exp_dummy, prompt_dummy;
+static void
+check(krb5_error_code code)
+{
+ if (code != 0)
+ abort();
+}
+
static krb5_error_code
prompter_cb(krb5_context ctx, void *data, const char *name,
const char *banner, int num_prompts, krb5_prompt prompts[])
@@ -52,36 +59,48 @@ int
main(int argc, char **argv)
{
krb5_context ctx;
+ krb5_init_creds_context icctx;
krb5_get_init_creds_opt *opt;
char *user, *password, *service = NULL;
- krb5_boolean use_cb;
+ krb5_boolean use_cb, stepwise;
krb5_principal client;
krb5_creds creds;
- if (argc < 4) {
- fprintf(stderr, "Usage: %s username password {1|0} [service]\n",
+ if (argc < 5) {
+ fprintf(stderr, "Usage: %s username password {1|0} {1|0} [service]\n",
argv[0]);
return 1;
}
user = argv[1];
password = argv[2];
use_cb = atoi(argv[3]);
- if (argc >= 5)
- service = argv[4];
+ stepwise = atoi(argv[4]);
+ if (argc >= 6)
+ service = argv[5];
- assert(krb5_init_context(&ctx) == 0);
- assert(krb5_get_init_creds_opt_alloc(ctx, &opt) == 0);
+ check(krb5_init_context(&ctx));
+ check(krb5_get_init_creds_opt_alloc(ctx, &opt));
if (use_cb) {
- assert(krb5_get_init_creds_opt_set_expire_callback(ctx, opt, expire_cb,
- &exp_dummy) == 0);
+ check(krb5_get_init_creds_opt_set_expire_callback(ctx, opt, expire_cb,
+ &exp_dummy));
+ }
+ check(krb5_parse_name(ctx, user, &client));
+ if (stepwise) {
+ check(krb5_init_creds_init(ctx, client, prompter_cb, &prompt_dummy, 0,
+ opt, &icctx));
+ krb5_init_creds_set_password(ctx, icctx, password);
+ if (service != NULL)
+ check(krb5_init_creds_set_service(ctx, icctx, service));
+ check(krb5_init_creds_get(ctx, icctx));
+ krb5_init_creds_free(ctx, icctx);
+ } else {
+ check(krb5_get_init_creds_password(ctx, &creds, client, password,
+ prompter_cb, &prompt_dummy, 0,
+ service, opt));
+ krb5_free_cred_contents(ctx, &creds);
}
- assert(krb5_parse_name(ctx, user, &client) == 0);
- assert(krb5_get_init_creds_password(ctx, &creds, client, password,
- prompter_cb, &prompt_dummy, 0, service,
- opt) == 0);
krb5_get_init_creds_opt_free(ctx, opt);
krb5_free_principal(ctx, client);
- krb5_free_cred_contents(ctx, &creds);
krb5_free_context(ctx);
return 0;
}
diff --git a/src/lib/krb5/krb/t_expire_warn.py b/src/lib/krb5/krb/t_expire_warn.py
index 781f2728a..e163cc7e4 100755
--- a/src/lib/krb5/krb/t_expire_warn.py
+++ b/src/lib/krb5/krb/t_expire_warn.py
@@ -34,23 +34,33 @@ realm.run([kadminl, 'addprinc', '-pw', 'pass', '-pwexpire', '12 hours',
realm.run([kadminl, 'addprinc', '-pw', 'pass', '-pwexpire', '3 days', 'days'])
# Check for expected prompter warnings when no expire callback is used.
-output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '0'])
+output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '0', '0'])
if output:
fail('Unexpected output for noexpire')
-realm.run(['./t_expire_warn', 'minutes', 'pass', '0'],
+realm.run(['./t_expire_warn', 'minutes', 'pass', '0', '0'],
expected_msg=' less than one hour on ')
-realm.run(['./t_expire_warn', 'hours', 'pass', '0'], expected_msg=' hours on ')
-realm.run(['./t_expire_warn', 'days', 'pass', '0'], expected_msg=' days on ')
+realm.run(['./t_expire_warn', 'hours', 'pass', '0', '0'],
+ expected_msg=' hours on ')
+realm.run(['./t_expire_warn', 'days', 'pass', '0', '0'],
+ expected_msg=' days on ')
+# Try one case with the stepwise interface.
+realm.run(['./t_expire_warn', 'days', 'pass', '0', '1'],
+ expected_msg=' days on ')
# Check for expected expire callback behavior. These tests are
# carefully agnostic about whether the KDC supports last_req fields,
# and could be made more specific if last_req support is added.
-output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '1'])
+output = realm.run(['./t_expire_warn', 'noexpire', 'pass', '1', '0'])
if 'password_expiration = 0\n' not in output or \
'account_expiration = 0\n' not in output or \
'is_last_req = ' not in output:
fail('Expected callback output not seen for noexpire')
-output = realm.run(['./t_expire_warn', 'days', 'pass', '1'])
+output = realm.run(['./t_expire_warn', 'days', 'pass', '1', '0'])
+if 'password_expiration = ' not in output or \
+ 'password_expiration = 0\n' in output:
+ fail('Expected non-zero password expiration not seen for days')
+# Try one case with the stepwise interface.
+output = realm.run(['./t_expire_warn', 'days', 'pass', '1', '1'])
if 'password_expiration = ' not in output or \
'password_expiration = 0\n' in output:
fail('Expected non-zero password expiration not seen for days')

View File

@ -1,4 +1,4 @@
From 588d964f59356373353dfd31d4fdcba95e508385 Mon Sep 17 00:00:00 2001
From b401a1127f27f8cd564e32411f799648a8fd5481 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 24 Nov 2020 12:52:02 -0500
Subject: [PATCH] Document -k option in kvno(1) synopsis
@ -13,7 +13,7 @@ synopsis, option descriptions, and xusage(), but missed one option.
2 files changed, 2 insertions(+)
diff --git a/doc/user/user_commands/kvno.rst b/doc/user/user_commands/kvno.rst
index 6fd8577a5..1e273e26e 100644
index 65c44e1c0..93a5132b2 100644
--- a/doc/user/user_commands/kvno.rst
+++ b/doc/user/user_commands/kvno.rst
@@ -9,6 +9,7 @@ SYNOPSIS
@ -25,7 +25,7 @@ index 6fd8577a5..1e273e26e 100644
[**-u** | **-S** *sname*]
[**-P**]
diff --git a/src/man/kvno.man b/src/man/kvno.man
index 7c9565bdb..dc9847e99 100644
index 953d168e6..ebdd6e8ca 100644
--- a/src/man/kvno.man
+++ b/src/man/kvno.man
@@ -35,6 +35,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]

View File

@ -1,59 +0,0 @@
From 5106d0b7ea10d1faa21f6dfb542a46eb74e78d40 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 24 Jul 2020 16:05:24 -0400
Subject: [PATCH] Fix leak in KERB_AP_OPTIONS_CBT server support
In check_cbt(), use a local variable to hold the retrieved authdata
list, and free it before returning.
ticket: 8900
(cherry picked from commit bf2ddff13c178e0c291f8fb382b040080d159e4f)
---
src/lib/gssapi/krb5/accept_sec_context.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 175a24c4e..3d5b84b15 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -433,27 +433,30 @@ static const uint8_t null_cb[CB_MD5_LEN];
/* Look for AP_OPTIONS in authdata. If present and the options include
* KERB_AP_OPTIONS_CBT, set *cbt_out to true. */
static krb5_error_code
-check_cbt(krb5_context context, krb5_authdata **authdata,
+check_cbt(krb5_context context, krb5_authdata *const *authdata,
krb5_boolean *cbt_out)
{
krb5_error_code code;
+ krb5_authdata **ad;
uint32_t ad_ap_options;
const uint32_t KERB_AP_OPTIONS_CBT = 0x4000;
*cbt_out = FALSE;
code = krb5_find_authdata(context, NULL, authdata,
- KRB5_AUTHDATA_AP_OPTIONS, &authdata);
- if (code || authdata == NULL)
+ KRB5_AUTHDATA_AP_OPTIONS, &ad);
+ if (code || ad == NULL)
return code;
- if (authdata[1] != NULL || authdata[0]->length != 4)
- return KRB5KRB_AP_ERR_MSG_TYPE;
+ if (ad[1] != NULL || ad[0]->length != 4) {
+ code = KRB5KRB_AP_ERR_MSG_TYPE;
+ } else {
+ ad_ap_options = load_32_le(ad[0]->contents);
+ if (ad_ap_options & KERB_AP_OPTIONS_CBT)
+ *cbt_out = TRUE;
+ }
- ad_ap_options = load_32_le(authdata[0]->contents);
- if (ad_ap_options & KERB_AP_OPTIONS_CBT)
- *cbt_out = TRUE;
-
- return 0;
+ krb5_free_authdata(context, ad);
+ return code;
}
/*

View File

@ -1,106 +0,0 @@
From a33dc1cfb0ebecb67cc7f38258303492a552cb73 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 15 Oct 2020 18:15:29 -0400
Subject: [PATCH] Fix minor static analysis defects
Remove an unused variable in krb5_ldap_create(). Handle the return
value from krb5_dbe_get_string() in the certauth test plugin module.
Handle the return value from k5_expand_path_tokens() in
k5_rc_default(). Remove dead assignments in
krb5_get_credentials_for_user() and kg_accept_krb5().
[ghudson@mit.edu: squashed and edited commit message; simplified
k5_rc_default() change]
(cherry picked from commit b27461141810fddd299764928649148c5d0e99f3)
---
src/lib/gssapi/krb5/accept_sec_context.c | 4 +---
src/lib/krb5/krb/s4u_creds.c | 1 -
src/lib/krb5/rcache/rc_base.c | 2 ++
src/plugins/certauth/test/main.c | 3 +++
src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c | 4 ----
5 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 3d5b84b15..e2c5e2b59 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -671,7 +671,7 @@ kg_accept_krb5(minor_status, context_handle,
krb5_auth_context auth_context = NULL;
krb5_ticket * ticket = NULL;
const gss_OID_desc *mech_used = NULL;
- OM_uint32 major_status = GSS_S_FAILURE;
+ OM_uint32 major_status;
OM_uint32 tmp_minor_status;
krb5_error krb_error_data;
krb5_data scratch;
@@ -878,8 +878,6 @@ kg_accept_krb5(minor_status, context_handle,
if (major_status != GSS_S_COMPLETE)
goto fail;
- major_status = GSS_S_FAILURE;
-
if (exts->iakerb.conv && !exts->iakerb.verified) {
major_status = GSS_S_BAD_SIG;
goto fail;
diff --git a/src/lib/krb5/krb/s4u_creds.c b/src/lib/krb5/krb/s4u_creds.c
index d8f486dc6..35a8843e5 100644
--- a/src/lib/krb5/krb/s4u_creds.c
+++ b/src/lib/krb5/krb/s4u_creds.c
@@ -714,7 +714,6 @@ krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
} else if (code != KRB5_CC_NOTFOUND && code != KRB5_CC_NOT_KTYPE) {
goto cleanup;
}
- code = 0;
}
/* Note the authdata we asked for in the output creds. */
diff --git a/src/lib/krb5/rcache/rc_base.c b/src/lib/krb5/rcache/rc_base.c
index 5f456d1f3..f9a482318 100644
--- a/src/lib/krb5/rcache/rc_base.c
+++ b/src/lib/krb5/rcache/rc_base.c
@@ -56,6 +56,8 @@ k5_rc_default(krb5_context context, krb5_rcache *rc_out)
&profstr) == 0 && profstr != NULL) {
ret = k5_expand_path_tokens(context, profstr, &rcname);
profile_release_string(profstr);
+ if (ret)
+ return ret;
ret = k5_rc_resolve(context, rcname, rc_out);
free(rcname);
return ret;
diff --git a/src/plugins/certauth/test/main.c b/src/plugins/certauth/test/main.c
index d4633b8cd..7e7a3ef4c 100644
--- a/src/plugins/certauth/test/main.c
+++ b/src/plugins/certauth/test/main.c
@@ -171,6 +171,9 @@ test2_authorize(krb5_context context, krb5_certauth_moddata moddata,
ret = krb5_dbe_get_string(context, (krb5_db_entry *)db_entry, "hwauth",
&strval);
+ if (ret)
+ goto cleanup;
+
ret = (strval != NULL) ? KRB5_CERTAUTH_HWAUTH : 0;
krb5_dbe_free_string(context, strval);
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c
index 5b57c799a..2d6605666 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_create.c
@@ -55,7 +55,6 @@ krb5_ldap_create(krb5_context context, char *conf_section, char **db_args)
krb5_error_code status = 0;
krb5_ldap_realm_params *rparams = NULL;
krb5_ldap_context *ldap_context=NULL;
- krb5_boolean realm_obj_created = FALSE;
int mask = 0;
/* Clear the global error string */
@@ -109,9 +108,6 @@ krb5_ldap_create(krb5_context context, char *conf_section, char **db_args)
if ((status = krb5_ldap_create_realm(context, rparams, mask)))
goto cleanup;
- /* We just created the Realm container. Here starts our transaction tracking */
- realm_obj_created = TRUE;
-
/* verify realm object */
if ((status = krb5_ldap_read_realm_params(context,
rparams->realm_name,

View File

@ -1,37 +0,0 @@
From 5952a06a594c4dc0f20f7ba2854b25f76734aa27 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Thu, 14 May 2020 15:01:18 -0400
Subject: [PATCH] Fix typo ("in in") in the ksu man page
(cherry picked from commit 1011841acdc1020f308ef4f569c6622f279d8c3f)
---
doc/user/user_commands/ksu.rst | 2 +-
src/man/ksu.man | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/user/user_commands/ksu.rst b/doc/user/user_commands/ksu.rst
index 8d6c7ef79..933738229 100644
--- a/doc/user/user_commands/ksu.rst
+++ b/doc/user/user_commands/ksu.rst
@@ -155,7 +155,7 @@ wrong password is typed in, ksu fails.
.. note::
During authentication, only the tickets that could be
- obtained without providing a password are cached in in the
+ obtained without providing a password are cached in the
source cache.
diff --git a/src/man/ksu.man b/src/man/ksu.man
index a1972518c..b07a4b05d 100644
--- a/src/man/ksu.man
+++ b/src/man/ksu.man
@@ -176,7 +176,7 @@ wrong password is typed in, ksu fails.
.INDENT 0.0
.INDENT 3.5
During authentication, only the tickets that could be
-obtained without providing a password are cached in in the
+obtained without providing a password are cached in the
source cache.
.UNINDENT
.UNINDENT

View File

@ -1,37 +0,0 @@
From cc572c5b6f8a3269c24c0f21f5799e60014635fb Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 15 Jul 2020 15:42:20 -0400
Subject: [PATCH] Ignore bad enctypes in krb5_string_to_keysalts()
Fixes a problem where the presence of legacy/unrecognized keysalts in
supported_enctypes would prevent the kadmin programs from starting.
[ghudson@mit.edu: ideally we would put a warning in the kadmind log,
but that is difficult to do when the parsing is done inside a library.
Even adding a trace log is difficult because the kadm5 str_conv
functions do not accept contexts.]
ticket: 8929 (new)
(cherry picked from commit be5396ada0e8dabd68bd0aceb733cfca39a609bc)
---
src/lib/kadm5/str_conv.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/lib/kadm5/str_conv.c b/src/lib/kadm5/str_conv.c
index 7cf51d316..798295606 100644
--- a/src/lib/kadm5/str_conv.c
+++ b/src/lib/kadm5/str_conv.c
@@ -340,9 +340,10 @@ krb5_string_to_keysalts(const char *string, const char *tupleseps,
while ((ksp = strtok_r(p, tseps, &tlasts)) != NULL) {
/* Pass a null pointer to subsequent calls to strtok_r(). */
p = NULL;
- ret = string_to_keysalt(ksp, ksaltseps, &etype, &stype);
- if (ret)
- goto cleanup;
+
+ /* Discard unrecognized keysalts. */
+ if (string_to_keysalt(ksp, ksaltseps, &etype, &stype) != 0)
+ continue;
/* Ignore duplicate keysalts if caller asks. */
if (!dups && krb5_keysalt_is_present(ksalts, nksalts, etype, stype))

View File

@ -1,91 +0,0 @@
From e0a702b6e5f0665cca88723f7b17ff90ea218e45 Mon Sep 17 00:00:00 2001
From: Alexander Scheel <ascheel@redhat.com>
Date: Wed, 5 Jul 2017 11:38:30 -0400
Subject: [PATCH] Implement GSS_C_CHANNEL_BOUND_FLAG
Define a new channel-bound GSS return flag, and set it in the krb5
mech if the initiator sent channel bindings matching the acceptor's.
Do not error out if the acceptor specifies channel bindings and the
initiator does not send them.
[ghudson@mit.edu: simplified code changes; fleshed out commit message]
[iboukris: cherry-picked from another PR and reduced in scope]
ticket: 8899 (new)
(cherry picked from commit 429a31146083fac21958631c2af572b08ec91022)
---
src/lib/gssapi/generic/gssapi_ext.h | 2 ++
src/lib/gssapi/krb5/accept_sec_context.c | 18 +++++++++++++-----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/src/lib/gssapi/generic/gssapi_ext.h b/src/lib/gssapi/generic/gssapi_ext.h
index 218456e44..c675e8ebb 100644
--- a/src/lib/gssapi/generic/gssapi_ext.h
+++ b/src/lib/gssapi/generic/gssapi_ext.h
@@ -595,6 +595,8 @@ gss_store_cred_into(
* attribute (along with any applicable RFC 5587 attributes).
*/
+#define GSS_C_CHANNEL_BOUND_FLAG 2048 /* 0x00000800 */
+
OM_uint32 KRB5_CALLCONV
gssspi_query_meta_data(
OM_uint32 *minor_status,
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 70dd7fc0c..9d3e2f4fe 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -427,6 +427,9 @@ kg_process_extension(krb5_context context,
GSS_C_SEQUENCE_FLAG | GSS_C_DCE_STYLE | \
GSS_C_IDENTIFY_FLAG | GSS_C_EXTENDED_ERROR_FLAG)
+/* A zero-value channel binding, for comparison */
+static const uint8_t null_cb[CB_MD5_LEN];
+
/*
* The krb5 GSS mech appropriates the authenticator checksum field from RFC
* 4120 to store structured data instead of a checksum, indicated with checksum
@@ -435,9 +438,10 @@ kg_process_extension(krb5_context context,
*
* Interpret the checksum. Read delegated creds into *deleg_out if it is not
* NULL. Set *flags_out to the allowed subset of token flags, plus
- * GSS_C_DELEG_FLAG if a delegated credential was present. Process any
- * extensions found using exts. On error, set *code_out to a krb5_error code
- * for use as a minor status value.
+ * GSS_C_DELEG_FLAG if a delegated credential was present and
+ * GSS_C_CHANNEL_BOUND_FLAG if matching channel bindings are present. Process
+ * any extensions found using exts. On error, set *code_out to a krb5_error
+ * code for use as a minor status value.
*/
static OM_uint32
process_checksum(OM_uint32 *minor_status, krb5_context context,
@@ -450,7 +454,7 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
krb5_error_code code = 0;
OM_uint32 status, option_id, token_flags;
size_t cb_len, option_len;
- krb5_boolean valid;
+ krb5_boolean valid, token_cb_present = FALSE, cb_match = FALSE;
krb5_key subkey;
krb5_data option, empty = empty_data();
krb5_checksum cb_cksum;
@@ -516,7 +520,9 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
goto fail;
}
assert(cb_cksum.length == cb_len);
- if (k5_bcmp(token_cb, cb_cksum.contents, cb_len) != 0) {
+ token_cb_present = (k5_bcmp(token_cb, null_cb, cb_len) != 0);
+ cb_match = (k5_bcmp(token_cb, cb_cksum.contents, cb_len) == 0);
+ if (token_cb_present && !cb_match) {
status = GSS_S_BAD_BINDINGS;
goto fail;
}
@@ -525,6 +531,8 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
/* Read the token flags and accept some of them as context flags. */
token_flags = k5_input_get_uint32_le(&in);
*flags_out = token_flags & INITIATOR_FLAGS;
+ if (cb_match)
+ *flags_out |= GSS_C_CHANNEL_BOUND_FLAG;
/* Read the delegated credential if present. */
if (in.len >= 4 && (token_flags & GSS_C_DELEG_FLAG)) {

View File

@ -1,102 +0,0 @@
From 323329d9033f32f49266921910124fe4f2a9124c Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Mon, 9 Mar 2020 16:04:21 +0100
Subject: [PATCH] Implement KERB_AP_OPTIONS_CBT (server side)
Add server support for Microsoft's KERB_AP_OPTIONS_CBT as described in
MS-KILE. If the client includes the AP option in the authenticator
authdata and the server passed channel bindings, require the bindings
to match.
[ghudson@mit.edu: refactored to put more logic in the helper function;
added a comment; clarified commit message]
ticket: 8900 (new)
(cherry picked from commit 4f7c77b64a048ca5e3199b26b31493698c777a9c)
---
src/include/krb5/krb5.hin | 1 +
src/lib/gssapi/krb5/accept_sec_context.c | 45 +++++++++++++++++++++++-
2 files changed, 45 insertions(+), 1 deletion(-)
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index f8269fb17..9264bede1 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -1915,6 +1915,7 @@ krb5_verify_checksum(krb5_context context, krb5_cksumtype ctype,
#define KRB5_AUTHDATA_SIGNTICKET 512 /**< formerly 142 in krb5 1.8 */
#define KRB5_AUTHDATA_FX_ARMOR 71
#define KRB5_AUTHDATA_AUTH_INDICATOR 97
+#define KRB5_AUTHDATA_AP_OPTIONS 143
/** @} */ /* end of KRB5_AUTHDATA group */
/* password change constants */
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index 9d3e2f4fe..175a24c4e 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -430,6 +430,32 @@ kg_process_extension(krb5_context context,
/* A zero-value channel binding, for comparison */
static const uint8_t null_cb[CB_MD5_LEN];
+/* Look for AP_OPTIONS in authdata. If present and the options include
+ * KERB_AP_OPTIONS_CBT, set *cbt_out to true. */
+static krb5_error_code
+check_cbt(krb5_context context, krb5_authdata **authdata,
+ krb5_boolean *cbt_out)
+{
+ krb5_error_code code;
+ uint32_t ad_ap_options;
+ const uint32_t KERB_AP_OPTIONS_CBT = 0x4000;
+
+ *cbt_out = FALSE;
+
+ code = krb5_find_authdata(context, NULL, authdata,
+ KRB5_AUTHDATA_AP_OPTIONS, &authdata);
+ if (code || authdata == NULL)
+ return code;
+ if (authdata[1] != NULL || authdata[0]->length != 4)
+ return KRB5KRB_AP_ERR_MSG_TYPE;
+
+ ad_ap_options = load_32_le(authdata[0]->contents);
+ if (ad_ap_options & KERB_AP_OPTIONS_CBT)
+ *cbt_out = TRUE;
+
+ return 0;
+}
+
/*
* The krb5 GSS mech appropriates the authenticator checksum field from RFC
* 4120 to store structured data instead of a checksum, indicated with checksum
@@ -454,7 +480,7 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
krb5_error_code code = 0;
OM_uint32 status, option_id, token_flags;
size_t cb_len, option_len;
- krb5_boolean valid, token_cb_present = FALSE, cb_match = FALSE;
+ krb5_boolean valid, client_cbt, token_cb_present = FALSE, cb_match = FALSE;
krb5_key subkey;
krb5_data option, empty = empty_data();
krb5_checksum cb_cksum;
@@ -582,6 +608,23 @@ process_checksum(OM_uint32 *minor_status, krb5_context context,
}
}
+ /*
+ * If the client asserts the KERB_AP_OPTIONS_CBT flag (from MS-KILE) in the
+ * authenticator authdata, and the acceptor passed channel bindings,
+ * require matching channel bindings from the client. The intent is to
+ * prevent an authenticator generated for use outside of a TLS channel from
+ * being used inside of one.
+ */
+ code = check_cbt(context, authenticator->authorization_data, &client_cbt);
+ if (code) {
+ status = GSS_S_FAILURE;
+ goto fail;
+ }
+ if (client_cbt && acceptor_cb != GSS_C_NO_CHANNEL_BINDINGS && !cb_match) {
+ status = GSS_S_BAD_BINDINGS;
+ goto fail;
+ }
+
status = GSS_S_COMPLETE;
fail:

View File

@ -1,124 +0,0 @@
From d80afa1396c3a6605338e4eaaf5bc44f8ad3eacc Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Fri, 4 Sep 2020 14:05:50 +0300
Subject: [PATCH] Improve KDC alias checking for S4U requests
When processing an S4U2Self request, check for DB aliases when
matching the TGT client against the request server. When processing
an S4U2Proxy request, check for DB aliases when matching the TGT
client against the evidence ticket server.
[ghudson@mit.edu: minor edits; rewrote commit message]
ticket: 8946 (new)
(cherry picked from commit 05deeebfc096970b5d9aa67a48b14106cf1b9b56)
---
src/kdc/kdc_util.c | 74 ++++++++++++++++------------------------------
1 file changed, 25 insertions(+), 49 deletions(-)
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index e3352f9cc..dcb2df8dc 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1463,6 +1463,25 @@ cleanup:
return code;
}
+/* Return true if princ canonicalizes to the same principal as canon. */
+static krb5_boolean
+is_client_alias(krb5_context context, krb5_const_principal canon,
+ krb5_const_principal princ)
+{
+ krb5_error_code ret;
+ krb5_db_entry *self;
+ krb5_boolean is_self = FALSE;
+
+ ret = krb5_db_get_principal(context, princ,
+ KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY, &self);
+ if (!ret) {
+ is_self = krb5_principal_compare(context, canon, self->princ);
+ krb5_db_free_principal(context, self);
+ }
+
+ return is_self;
+}
+
/*
* Protocol transition (S4U2Self)
*/
@@ -1481,7 +1500,6 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
{
krb5_error_code code;
krb5_pa_data *pa_data;
- int flags;
krb5_db_entry *princ;
krb5_s4u_userid *id;
@@ -1515,51 +1533,11 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
}
id = &(*s4u_x509_user)->user_id;
- /*
- * We need to compare the client name in the TGT with the requested
- * server name. Supporting server name aliases without assuming a
- * global name service makes this difficult to do.
- *
- * The comparison below handles the following cases (note that the
- * term "principal name" below excludes the realm).
- *
- * (1) The requested service is a host-based service with two name
- * components, in which case we assume the principal name to
- * contain sufficient qualifying information. The realm is
- * ignored for the purpose of comparison.
- *
- * (2) The requested service name is an enterprise principal name:
- * the service principal name is compared with the unparsed
- * form of the client name (including its realm).
- *
- * (3) The requested service is some other name type: an exact
- * match is required.
- *
- * An alternative would be to look up the server once again with
- * FLAG_CANONICALIZE | FLAG_CLIENT_REFERRALS_ONLY set, do an exact
- * match between the returned name and client_princ. However, this
- * assumes that the client set FLAG_CANONICALIZE when requesting
- * the TGT and that we have a global name service.
- */
- flags = 0;
- switch (krb5_princ_type(kdc_context, request->server)) {
- case KRB5_NT_SRV_HST: /* (1) */
- if (krb5_princ_size(kdc_context, request->server) == 2)
- flags |= KRB5_PRINCIPAL_COMPARE_IGNORE_REALM;
- break;
- case KRB5_NT_ENTERPRISE_PRINCIPAL: /* (2) */
- flags |= KRB5_PRINCIPAL_COMPARE_ENTERPRISE;
- break;
- default: /* (3) */
- break;
- }
-
- if (!krb5_principal_compare_flags(kdc_context,
- request->server,
- client_princ,
- flags)) {
- *status = "INVALID_S4U2SELF_REQUEST";
- return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; /* match Windows error code */
+ /* If the server is local, check that the request is for self. */
+ if (!isflagset(c_flags, KRB5_KDB_FLAG_ISSUING_REFERRAL) &&
+ !is_client_alias(kdc_context, server->princ, client_princ)) {
+ *status = "INVALID_S4U2SELF_REQUEST_SERVER_MISMATCH";
+ return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; /* match Windows error */
}
/*
@@ -1750,9 +1728,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, unsigned int flags,
}
client_princ = *stkt_authdata_client;
- } else if (!krb5_principal_compare(kdc_context,
- server->princ, /* after canon */
- server_princ)) {
+ } else if (!is_client_alias(kdc_context, server->princ, server_princ)) {
*status = "EVIDENCE_TICKET_MISMATCH";
return KRB5KDC_ERR_SERVER_NOMATCH;
}

View File

@ -1,30 +0,0 @@
From 9596a341d99e3af1438ad215ed0fb5496cb59ff0 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 9 Jun 2020 16:23:37 -0400
Subject: [PATCH] Improve negoex_parse_token() code hygiene
If the while loop in negoex_parse_token() runs for zero iterations,
major will be used initialized. Currently this cannot happen, but
only because both of the call sites check for zero-length tokens.
Initialize major for safety.
[ghudson@mit.edu: rewrote commit message]
(cherry picked from commit 4f91b6f8fa6fe1de662b3fdac0d59b7758ec642a)
---
src/lib/gssapi/spnego/negoex_util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lib/gssapi/spnego/negoex_util.c b/src/lib/gssapi/spnego/negoex_util.c
index 700368456..99580fd79 100644
--- a/src/lib/gssapi/spnego/negoex_util.c
+++ b/src/lib/gssapi/spnego/negoex_util.c
@@ -454,7 +454,7 @@ negoex_parse_token(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
gss_const_buffer_t token,
struct negoex_message **messages_out, size_t *count_out)
{
- OM_uint32 major;
+ OM_uint32 major = GSS_S_COMPLETE;
size_t count = 0;
struct k5input in;
struct negoex_message *messages = NULL, *newptr;

View File

@ -1,42 +0,0 @@
From b3c6667d7f98cf0347642c7927618fd40cd6f904 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:45:26 -0400
Subject: [PATCH] Install shared libraries as executable
RPM expects this behavior, and systems with contrary policies (like
Debian) address permissions at the packaging layer. Most other build
systems appear to install shared libraries as executable.
[ghudson@mit.edu: edited commit message]
ticket: 8965 (new)
(cherry picked from commit 1bc5f76d2e7013b8771e3bd9960c82642ba0b467)
---
src/config/shlib.conf | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/config/shlib.conf b/src/config/shlib.conf
index 3e4af6c02..75b7cc3af 100644
--- a/src/config/shlib.conf
+++ b/src/config/shlib.conf
@@ -22,8 +22,10 @@ SHLIBVEXT=.so.v-nobuild
SHLIBSEXT=.so.s-nobuild
# Most systems support profiled libraries.
PFLIBEXT=_p.a
-# Most systems install shared libs as mode 644, etc. while hpux wants 755
-INSTALL_SHLIB='$(INSTALL_DATA)'
+# Install libraries executable. Some systems (e.g., RPM-based ones) require
+# this for package dependency generation, while others are ambivalent or will
+# strip it during packaging.
+INSTALL_SHLIB='$(INSTALL)'
# Most systems use the same objects for shared libraries and dynamically
# loadable objects.
DYNOBJEXT='$(SHLIBEXT)'
@@ -118,7 +120,6 @@ alpha*-dec-osf*)
# -O +dpv should display any routines eliminated as unused, but -b
# apparently turns that off
*-*-hpux*)
- INSTALL_SHLIB='$(INSTALL)'
case $host_cpu in
hppa*)
SHLIBEXT=.sl

View File

@ -1,316 +0,0 @@
From 6e82fd67034eef7f99b901f417782a3786a02069 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 25 Sep 2020 11:12:34 -0400
Subject: [PATCH] Minimize usage of tgs_server in KDC
Where possible, use the realm of the request server principal
(canonicalized via KDB lookup, if available) in preference to
tgs_server. This change facilitates alias realm support and potential
future support for serving multiple realms from the same KDB.
S4U2Self local user testing currently uses the uncanonicalized request
realm after this change, which will require attention for alias realm
support.
FAST armor ticket checking is unaffected by this change (it still
compares against tgs_server). This check poses no issue for realm
aliases, as both tgs_server and the armor ticket server should have
canonical realms, but it will require attention for multi-realm KDB
support.
Remove is_local_principal() as it is no longer used. Add an
is_local_tgs_principal() helper and shorten is_cross_tgs_principal().
Move the header ticket lineage check from kdc_process_tgs_req() to
process_tgs_req(), where we have the canonical request server name and
a more natural indication of whether the request was an S4U2Self
request.
(cherry picked from commit 90fedf8188fc47aa5a476a969af34671555df389)
---
src/kdc/do_as_req.c | 21 ++++++--------
src/kdc/do_tgs_req.c | 16 ++++++++---
src/kdc/kdc_util.c | 68 ++++++++++----------------------------------
src/kdc/kdc_util.h | 3 +-
src/kdc/tgs_policy.c | 16 ++++++-----
5 files changed, 46 insertions(+), 78 deletions(-)
diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c
index c2dfea9b8..e0ac33649 100644
--- a/src/kdc/do_as_req.c
+++ b/src/kdc/do_as_req.c
@@ -620,18 +620,6 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
}
state->rock.client = state->client;
- /*
- * If the backend returned a principal that is not in the local
- * realm, then we need to refer the client to that realm.
- */
- if (!is_local_principal(kdc_active_realm, state->client->princ)) {
- /* Entry is a referral to another realm */
- state->status = "REFERRAL";
- au_state->cl_realm = &state->client->princ->realm;
- errcode = KRB5KDC_ERR_WRONG_REALM;
- goto errout;
- }
-
au_state->stage = SRVC_PRINC;
s_flags = 0;
@@ -651,6 +639,15 @@ process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
goto errout;
}
+ /* If the KDB module returned a different realm for the client and server,
+ * we need to issue a client realm referral. */
+ if (!data_eq(state->server->princ->realm, state->client->princ->realm)) {
+ state->status = "REFERRAL";
+ au_state->cl_realm = &state->client->princ->realm;
+ errcode = KRB5KDC_ERR_WRONG_REALM;
+ goto errout;
+ }
+
errcode = get_local_tgt(kdc_context, &state->request->server->realm,
state->server, &state->local_tgt,
&state->local_tgt_storage, &state->local_tgt_key);
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index d345797c4..8ea418e43 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -268,7 +268,7 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
goto cleanup;
}
- if (!is_local_principal(kdc_active_realm, header_ticket->server))
+ if (!data_eq(header_server->princ->realm, sprinc->realm))
setflag(c_flags, KRB5_KDB_FLAG_CROSS_REALM);
if (is_referral)
setflag(c_flags, KRB5_KDB_FLAG_ISSUING_REFERRAL);
@@ -295,6 +295,15 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
au_state->s4u2self_user = NULL;
}
+ /* Aside from cross-realm S4U2Self requests, do not accept header tickets
+ * for local users issued by foreign realms. */
+ if (s4u_x509_user == NULL && data_eq(cprinc->realm, sprinc->realm) &&
+ isflagset(c_flags, KRB5_KDB_FLAG_CROSS_REALM)) {
+ krb5_klog_syslog(LOG_INFO, _("PROCESS_TGS: failed lineage check"));
+ retval = KRB5KDC_ERR_POLICY;
+ goto cleanup;
+ }
+
if (errcode)
goto cleanup;
@@ -583,13 +592,12 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
/*
* Only add the realm of the presented tgt to the transited list if
- * it is different than the local realm (cross-realm) and it is different
+ * it is different than the server realm (cross-realm) and it is different
* than the realm of the client (since the realm of the client is already
* implicitly part of the transited list and should not be explicitly
* listed).
*/
- /* realm compare is like strcmp, but knows how to deal with these args */
- if (krb5_realm_compare(kdc_context, header_ticket->server, tgs_server) ||
+ if (!isflagset(c_flags, KRB5_KDB_FLAG_CROSS_REALM) ||
krb5_realm_compare(kdc_context, header_ticket->server,
enc_tkt_reply.client)) {
/* tgt issued by local realm or issued by realm of client */
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index b2042862a..e0b65a87c 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -78,12 +78,6 @@ static krb5_error_code find_server_key(krb5_context,
krb5_kvno, krb5_keyblock **,
krb5_kvno *);
-krb5_boolean
-is_local_principal(kdc_realm_t *kdc_active_realm, krb5_const_principal princ1)
-{
- return krb5_realm_compare(kdc_context, princ1, tgs_server);
-}
-
/*
* Returns TRUE if the kerberos principal is the name of a Kerberos ticket
* service.
@@ -104,13 +98,16 @@ krb5_is_tgs_principal(krb5_const_principal principal)
krb5_boolean
is_cross_tgs_principal(krb5_const_principal principal)
{
- if (!krb5_is_tgs_principal(principal))
- return FALSE;
- if (!data_eq(*krb5_princ_component(kdc_context, principal, 1),
- *krb5_princ_realm(kdc_context, principal)))
- return TRUE;
- else
- return FALSE;
+ return krb5_is_tgs_principal(principal) &&
+ !data_eq(principal->data[1], principal->realm);
+}
+
+/* Return true if princ is the name of a local TGS for any realm. */
+krb5_boolean
+is_local_tgs_principal(krb5_const_principal principal)
+{
+ return krb5_is_tgs_principal(principal) &&
+ data_eq(principal->data[1], principal->realm);
}
/*
@@ -143,17 +140,6 @@ comp_cksum(krb5_context kcontext, krb5_data *source, krb5_ticket *ticket,
return(0);
}
-/* Return true if padata contains an entry of either S4U2Self type. */
-static inline krb5_boolean
-has_s4u2self_padata(krb5_pa_data **padata)
-{
- if (krb5int_find_pa_data(NULL, padata, KRB5_PADATA_FOR_USER) != NULL)
- return TRUE;
- if (krb5int_find_pa_data(NULL, padata, KRB5_PADATA_S4U_X509_USER) != NULL)
- return TRUE;
- return FALSE;
-}
-
/* If a header ticket is decrypted, *ticket_out is filled in even on error. */
krb5_error_code
kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
@@ -170,7 +156,6 @@ kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
krb5_authdata **authdata = NULL;
krb5_data scratch1;
krb5_data * scratch = NULL;
- krb5_boolean foreign_server = FALSE;
krb5_auth_context auth_context = NULL;
krb5_authenticator * authenticator = NULL;
krb5_checksum * his_cksum = NULL;
@@ -199,19 +184,6 @@ kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
goto cleanup;
}
- /* If the "server" principal in the ticket is not something
- in the local realm, then we must refuse to service the request
- if the client claims to be from the local realm.
-
- If we don't do this, then some other realm's nasty KDC can
- claim to be authenticating a client from our realm, and we'll
- give out tickets concurring with it!
-
- we set a flag here for checking below.
- */
- foreign_server = !is_local_principal(kdc_active_realm,
- apreq->ticket->server);
-
if ((retval = krb5_auth_con_init(kdc_context, &auth_context)))
goto cleanup;
@@ -265,15 +237,6 @@ kdc_process_tgs_req(kdc_realm_t *kdc_active_realm,
goto cleanup_authenticator;
}
- /* make sure the client is of proper lineage (see above) */
- if (foreign_server && !has_s4u2self_padata(request->padata) &&
- is_local_principal(kdc_active_realm, ticket->enc_part2->client)) {
- /* someone in a foreign realm claiming to be local */
- krb5_klog_syslog(LOG_INFO, _("PROCESS_TGS: failed lineage check"));
- retval = KRB5KDC_ERR_POLICY;
- goto cleanup_authenticator;
- }
-
/*
* Check application checksum vs. tgs request
*
@@ -591,12 +554,12 @@ int
check_anon(kdc_realm_t *kdc_active_realm,
krb5_principal client, krb5_principal server)
{
- /* If restrict_anon is set, reject requests from anonymous to principals
- * other than the local TGT. */
+ /* If restrict_anon is set, reject requests from anonymous clients to
+ * server principals other than local TGTs. */
if (kdc_active_realm->realm_restrict_anon &&
krb5_principal_compare_any_realm(kdc_context, client,
krb5_anonymous_principal()) &&
- !krb5_principal_compare(kdc_context, server, tgs_server))
+ !is_local_tgs_principal(server))
return -1;
return 0;
}
@@ -1527,7 +1490,7 @@ kdc_process_s4u2self_req(kdc_realm_t *kdc_active_realm,
/*
* Do not attempt to lookup principals in foreign realms.
*/
- if (is_local_principal(kdc_active_realm, id->user)) {
+ if (data_eq(server->princ->realm, id->user->realm)) {
krb5_db_entry no_server;
krb5_pa_data **e_data = NULL;
@@ -1663,8 +1626,7 @@ kdc_process_s4u2proxy_req(kdc_realm_t *kdc_active_realm, unsigned int flags,
*/
if (isflagset(flags, KRB5_KDB_FLAG_ISSUING_REFERRAL) ||
!is_cross_tgs_principal(server->princ) ||
- !krb5_principal_compare_any_realm(kdc_context, server->princ,
- tgs_server) ||
+ !data_eq(server->princ->data[1], proxy->princ->realm) ||
!krb5_principal_compare(kdc_context, client_princ, server_princ)) {
*status = "XREALM_EVIDENCE_TICKET_MISMATCH";
return KRB5KDC_ERR_BADOPTION;
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 04007a8f5..a6bac4388 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -37,10 +37,9 @@
#include "reqstate.h"
krb5_error_code check_hot_list (krb5_ticket *);
-krb5_boolean is_local_principal(kdc_realm_t *kdc_active_realm,
- krb5_const_principal princ1);
krb5_boolean krb5_is_tgs_principal (krb5_const_principal);
krb5_boolean is_cross_tgs_principal(krb5_const_principal);
+krb5_boolean is_local_tgs_principal(krb5_const_principal);
krb5_error_code
add_to_transited (krb5_data *,
krb5_data *,
diff --git a/src/kdc/tgs_policy.c b/src/kdc/tgs_policy.c
index 3f4fa8499..a5a00f0cc 100644
--- a/src/kdc/tgs_policy.c
+++ b/src/kdc/tgs_policy.c
@@ -252,19 +252,21 @@ check_tgs_s4u2proxy(kdc_realm_t *kdc_active_realm,
}
static int
-check_tgs_u2u(kdc_realm_t *kdc_active_realm,
- krb5_kdc_req *req, const char **status)
+check_tgs_u2u(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
+ krb5_const_principal server_princ, const char **status)
{
+ krb5_const_principal second_server_princ;
+
if (req->kdc_options & KDC_OPT_ENC_TKT_IN_SKEY) {
/* Check that second ticket is in request. */
if (!req->second_ticket || !req->second_ticket[0]) {
*status = "NO_2ND_TKT";
return KDC_ERR_BADOPTION;
}
- /* Check that second ticket is a TGT. */
- if (!krb5_principal_compare(kdc_context,
- req->second_ticket[0]->server,
- tgs_server)) {
+ /* Check that second ticket is a TGT to the server realm. */
+ second_server_princ = req->second_ticket[0]->server;
+ if (!is_local_tgs_principal(second_server_princ) ||
+ !data_eq(second_server_princ->data[1], server_princ->realm)) {
*status = "2ND_TKT_NOT_TGS";
return KDC_ERR_POLICY;
}
@@ -353,7 +355,7 @@ validate_tgs_request(kdc_realm_t *kdc_active_realm,
return(KRB_AP_ERR_REPEAT);
}
- errcode = check_tgs_u2u(kdc_active_realm, request, status);
+ errcode = check_tgs_u2u(kdc_active_realm, request, server->princ, status);
if (errcode != 0)
return errcode;

View File

@ -1,48 +0,0 @@
From cd99c7829a43074cec8afe5c7021778a5a2ebd31 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 6 May 2020 16:03:13 -0400
Subject: [PATCH] Omit KDC indicator check for S4U2Self requests
As there was no initial ticket exchange from the client for an
S4U2Self request, the auth indicator check is inapplicable (and would
always fail if any auth indicators are required).
ticket: 8902 (new)
(cherry picked from commit 183631fbf72351c2d5fc7d60b2d9fc4d09fe7465)
---
src/kdc/do_tgs_req.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 241f34e2a..463a9c0dd 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -392,8 +392,8 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
}
authtime = subject_tkt->times.authtime;
- /* Extract auth indicators from the subject ticket, except for S4U2Self
- * requests (where the client didn't authenticate). */
+ /* Extract and check auth indicators from the subject ticket, except for
+ * S4U2Self requests (where the client didn't authenticate). */
if (s4u_x509_user == NULL) {
errcode = get_auth_indicators(kdc_context, subject_tkt, local_tgt,
&local_tgt_key, &auth_indicators);
@@ -401,12 +401,12 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
status = "GET_AUTH_INDICATORS";
goto cleanup;
}
- }
- errcode = check_indicators(kdc_context, server, auth_indicators);
- if (errcode) {
- status = "HIGHER_AUTHENTICATION_REQUIRED";
- goto cleanup;
+ errcode = check_indicators(kdc_context, server, auth_indicators);
+ if (errcode) {
+ status = "HIGHER_AUTHENTICATION_REQUIRED";
+ goto cleanup;
+ }
}
if (is_referral)

View File

@ -1,34 +0,0 @@
From 6b81d2d9913d91a4cc48d04f123fc71cc1022432 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Sat, 6 Jun 2020 11:03:37 +0200
Subject: [PATCH] Omit PA_FOR_USER if we can't compute its checksum
OpenSSL in FIPS mode will refuse to perform hmac-md5. Omit the legacy
PA_FOR_USER element in this case rather than failing out.
[ghudson@mit.edu: minor code and comment edits; wrote commit message]
ticket: 8912 (new)
(cherry picked from commit 03f122bdb22cfa53c7d855ed929c9541e56365e0)
---
src/lib/krb5/krb/s4u_creds.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/lib/krb5/krb/s4u_creds.c b/src/lib/krb5/krb/s4u_creds.c
index fc5c886d6..d8f486dc6 100644
--- a/src/lib/krb5/krb/s4u_creds.c
+++ b/src/lib/krb5/krb/s4u_creds.c
@@ -534,6 +534,13 @@ krb5_get_self_cred_from_kdc(krb5_context context,
if (s4u_user.user_id.user != NULL && s4u_user.user_id.user->length) {
code = build_pa_for_user(context, tgtptr, &s4u_user.user_id,
&in_padata[1]);
+ /*
+ * If we couldn't compute the hmac-md5 checksum, send only the
+ * KRB5_PADATA_S4U_X509_USER; this will still work against modern
+ * Windows and MIT KDCs.
+ */
+ if (code == KRB5_CRYPTO_INTERNAL)
+ code = 0;
if (code != 0) {
krb5_free_pa_data(context, in_padata);
goto cleanup;

View File

@ -1,256 +0,0 @@
From a5588aae21d44f5a6eed4bdfeae992a709b92959 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Tue, 28 Apr 2020 18:15:55 +0200
Subject: [PATCH] Pass channel bindings through SPNEGO
ticket: 8907 (new)
(cherry picked from commit d16325a24c34ec9a5f6fb4910987f162e0d4d9cd)
---
src/lib/gssapi/spnego/gssapiP_negoex.h | 8 ++---
src/lib/gssapi/spnego/negoex_ctx.c | 34 +++++++++++----------
src/lib/gssapi/spnego/spnego_mech.c | 41 +++++++++++++-------------
3 files changed, 43 insertions(+), 40 deletions(-)
diff --git a/src/lib/gssapi/spnego/gssapiP_negoex.h b/src/lib/gssapi/spnego/gssapiP_negoex.h
index 44b08f523..489ab7c42 100644
--- a/src/lib/gssapi/spnego/gssapiP_negoex.h
+++ b/src/lib/gssapi/spnego/gssapiP_negoex.h
@@ -201,10 +201,10 @@ negoex_restrict_auth_schemes(spnego_gss_ctx_id_t ctx,
OM_uint32
negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req,
- gss_buffer_t input_token, gss_buffer_t output_token,
- OM_uint32 *time_rec);
+ gss_buffer_t input_token, gss_channel_bindings_t bindings,
+ gss_buffer_t output_token, OM_uint32 *time_rec);
OM_uint32
negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
- gss_buffer_t input_token, gss_buffer_t output_token,
- OM_uint32 *time_rec);
+ gss_buffer_t input_token, gss_channel_bindings_t bindings,
+ gss_buffer_t output_token, OM_uint32 *time_rec);
diff --git a/src/lib/gssapi/spnego/negoex_ctx.c b/src/lib/gssapi/spnego/negoex_ctx.c
index 18d9d4147..8848ee4db 100644
--- a/src/lib/gssapi/spnego/negoex_ctx.c
+++ b/src/lib/gssapi/spnego/negoex_ctx.c
@@ -276,7 +276,8 @@ static OM_uint32
mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
gss_name_t target, OM_uint32 req_flags, OM_uint32 time_req,
struct negoex_message *messages, size_t nmessages,
- gss_buffer_t output_token, OM_uint32 *time_rec)
+ gss_channel_bindings_t bindings, gss_buffer_t output_token,
+ OM_uint32 *time_rec)
{
OM_uint32 major, first_major = 0, first_minor = 0;
struct negoex_auth_mech *mech = NULL;
@@ -316,10 +317,9 @@ mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
mech = K5_TAILQ_FIRST(&ctx->negoex_mechs);
major = gss_init_sec_context(minor, cred, &mech->mech_context, target,
- mech->oid, req_flags, time_req,
- GSS_C_NO_CHANNEL_BINDINGS, input_token,
- &ctx->actual_mech, output_token,
- &ctx->ctx_flags, time_rec);
+ mech->oid, req_flags, time_req, bindings,
+ input_token, &ctx->actual_mech,
+ output_token, &ctx->ctx_flags, time_rec);
if (major == GSS_S_COMPLETE)
mech->complete = 1;
@@ -351,7 +351,8 @@ mech_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
static OM_uint32
mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
gss_cred_id_t cred, struct negoex_message *messages,
- size_t nmessages, gss_buffer_t output_token, OM_uint32 *time_rec)
+ size_t nmessages, gss_channel_bindings_t bindings,
+ gss_buffer_t output_token, OM_uint32 *time_rec)
{
OM_uint32 major, tmpmin;
struct negoex_auth_mech *mech;
@@ -395,10 +396,10 @@ mech_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
gss_release_cred(&tmpmin, &ctx->deleg_cred);
major = gss_accept_sec_context(minor, &mech->mech_context, cred,
- &msg->token, GSS_C_NO_CHANNEL_BINDINGS,
- &ctx->internal_name, &ctx->actual_mech,
- output_token, &ctx->ctx_flags,
- time_rec, &ctx->deleg_cred);
+ &msg->token, bindings, &ctx->internal_name,
+ &ctx->actual_mech, output_token,
+ &ctx->ctx_flags, time_rec,
+ &ctx->deleg_cred);
if (major == GSS_S_COMPLETE)
mech->complete = 1;
@@ -609,8 +610,8 @@ make_output_token(OM_uint32 *minor, spnego_gss_ctx_id_t ctx,
OM_uint32
negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
gss_name_t target_name, OM_uint32 req_flags, OM_uint32 time_req,
- gss_buffer_t input_token, gss_buffer_t output_token,
- OM_uint32 *time_rec)
+ gss_buffer_t input_token, gss_channel_bindings_t bindings,
+ gss_buffer_t output_token, OM_uint32 *time_rec)
{
OM_uint32 major, tmpmin;
gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER;
@@ -663,7 +664,8 @@ negoex_init(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
/* Process the input token and/or produce an output token. This may prune
* the mech list, but on success there will be at least one mech entry. */
major = mech_init(minor, ctx, cred, target_name, req_flags, time_req,
- messages, nmessages, &mech_output_token, time_rec);
+ messages, nmessages, bindings, &mech_output_token,
+ time_rec);
if (major != GSS_S_COMPLETE)
goto cleanup;
assert(!K5_TAILQ_EMPTY(&ctx->negoex_mechs));
@@ -701,8 +703,8 @@ cleanup:
OM_uint32
negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
- gss_buffer_t input_token, gss_buffer_t output_token,
- OM_uint32 *time_rec)
+ gss_buffer_t input_token, gss_channel_bindings_t bindings,
+ gss_buffer_t output_token, OM_uint32 *time_rec)
{
OM_uint32 major, tmpmin;
gss_buffer_desc mech_output_token = GSS_C_EMPTY_BUFFER;
@@ -754,7 +756,7 @@ negoex_accept(OM_uint32 *minor, spnego_gss_ctx_id_t ctx, gss_cred_id_t cred,
* prune the list to a single mech. Continue on error if an output token
* is generated, so that we send the token to the initiator.
*/
- major = mech_accept(minor, ctx, cred, messages, nmessages,
+ major = mech_accept(minor, ctx, cred, messages, nmessages, bindings,
&mech_output_token, time_rec);
if (major != GSS_S_COMPLETE && mech_output_token.length == 0)
goto cleanup;
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index f4a042478..2327cd927 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -130,6 +130,7 @@ init_ctx_reselect(OM_uint32 *, spnego_gss_ctx_id_t, OM_uint32,
static OM_uint32
init_ctx_call_init(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t,
OM_uint32, gss_name_t, OM_uint32, OM_uint32, gss_buffer_t,
+ gss_channel_bindings_t,
gss_buffer_t, OM_uint32 *, send_token_flag *);
static OM_uint32
@@ -144,8 +145,8 @@ acc_ctx_vfy_oid(OM_uint32 *, spnego_gss_ctx_id_t, gss_OID,
OM_uint32 *, send_token_flag *);
static OM_uint32
acc_ctx_call_acc(OM_uint32 *, spnego_gss_ctx_id_t, spnego_gss_cred_id_t,
- gss_buffer_t, gss_buffer_t, OM_uint32 *, OM_uint32 *,
- send_token_flag *);
+ gss_buffer_t, gss_channel_bindings_t, gss_buffer_t,
+ OM_uint32 *, OM_uint32 *, send_token_flag *);
static gss_OID
negotiate_mech(spnego_gss_ctx_id_t, gss_OID_set, OM_uint32 *);
@@ -906,6 +907,7 @@ init_ctx_call_init(OM_uint32 *minor_status,
OM_uint32 req_flags,
OM_uint32 time_req,
gss_buffer_t mechtok_in,
+ gss_channel_bindings_t bindings,
gss_buffer_t mechtok_out,
OM_uint32 *time_rec,
send_token_flag *send_token)
@@ -922,15 +924,14 @@ init_ctx_call_init(OM_uint32 *minor_status,
if (gss_oid_equal(sc->internal_mech, &negoex_mech)) {
ret = negoex_init(minor_status, sc, mcred, target_name,
mech_req_flags, time_req, mechtok_in,
- mechtok_out, time_rec);
+ bindings, mechtok_out, time_rec);
} else {
ret = gss_init_sec_context(minor_status, mcred,
&sc->ctx_handle, target_name,
sc->internal_mech, mech_req_flags,
- time_req, GSS_C_NO_CHANNEL_BINDINGS,
- mechtok_in, &sc->actual_mech,
- mechtok_out, &sc->ctx_flags,
- time_rec);
+ time_req, bindings, mechtok_in,
+ &sc->actual_mech, mechtok_out,
+ &sc->ctx_flags, time_rec);
}
/* Bail out if the acceptor gave us an error token but the mech didn't
@@ -982,8 +983,8 @@ init_ctx_call_init(OM_uint32 *minor_status,
gss_delete_sec_context(&tmpmin, &sc->ctx_handle, GSS_C_NO_BUFFER);
tmpret = init_ctx_call_init(&tmpmin, sc, spcred, acc_negState,
target_name, req_flags, time_req,
- mechtok_in, mechtok_out, time_rec,
- send_token);
+ mechtok_in, bindings, mechtok_out,
+ time_rec, send_token);
if (HARD_ERROR(tmpret))
goto fail;
*minor_status = tmpmin;
@@ -1005,7 +1006,7 @@ spnego_gss_init_sec_context(
gss_OID mech_type,
OM_uint32 req_flags,
OM_uint32 time_req,
- gss_channel_bindings_t input_chan_bindings,
+ gss_channel_bindings_t bindings,
gss_buffer_t input_token,
gss_OID *actual_mech,
gss_buffer_t output_token,
@@ -1085,8 +1086,8 @@ spnego_gss_init_sec_context(
if (!spnego_ctx->mech_complete) {
ret = init_ctx_call_init(minor_status, spnego_ctx, spcred,
acc_negState, target_name, req_flags,
- time_req, mechtok_in, &mechtok_out,
- time_rec, &send_token);
+ time_req, mechtok_in, bindings,
+ &mechtok_out, time_rec, &send_token);
if (ret != GSS_S_COMPLETE)
goto cleanup;
@@ -1543,8 +1544,9 @@ cleanup:
static OM_uint32
acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
spnego_gss_cred_id_t spcred, gss_buffer_t mechtok_in,
- gss_buffer_t mechtok_out, OM_uint32 *time_rec,
- OM_uint32 *negState, send_token_flag *tokflag)
+ gss_channel_bindings_t bindings, gss_buffer_t mechtok_out,
+ OM_uint32 *time_rec, OM_uint32 *negState,
+ send_token_flag *tokflag)
{
OM_uint32 ret, tmpmin;
gss_OID_desc mechoid;
@@ -1569,13 +1571,12 @@ acc_ctx_call_acc(OM_uint32 *minor_status, spnego_gss_ctx_id_t sc,
mcred = (spcred == NULL) ? GSS_C_NO_CREDENTIAL : spcred->mcred;
if (negoex) {
ret = negoex_accept(minor_status, sc, mcred, mechtok_in,
- mechtok_out, time_rec);
+ bindings, mechtok_out, time_rec);
} else {
(void) gss_release_name(&tmpmin, &sc->internal_name);
(void) gss_release_cred(&tmpmin, &sc->deleg_cred);
ret = gss_accept_sec_context(minor_status, &sc->ctx_handle,
- mcred, mechtok_in,
- GSS_C_NO_CHANNEL_BINDINGS,
+ mcred, mechtok_in, bindings,
&sc->internal_name,
&sc->actual_mech, mechtok_out,
&sc->ctx_flags, time_rec,
@@ -1621,7 +1622,7 @@ spnego_gss_accept_sec_context(
gss_ctx_id_t *context_handle,
gss_cred_id_t verifier_cred_handle,
gss_buffer_t input_token,
- gss_channel_bindings_t input_chan_bindings,
+ gss_channel_bindings_t bindings,
gss_name_t *src_name,
gss_OID *mech_type,
gss_buffer_t output_token,
@@ -1735,8 +1736,8 @@ spnego_gss_accept_sec_context(
*/
if (negState != REQUEST_MIC && mechtok_in != GSS_C_NO_BUFFER) {
ret = acc_ctx_call_acc(minor_status, sc, spcred, mechtok_in,
- &mechtok_out, time_rec, &negState,
- &return_token);
+ bindings, &mechtok_out, time_rec,
+ &negState, &return_token);
}
/* Step 3: process or generate the MIC, if the negotiated mech is

View File

@ -1,58 +0,0 @@
From 723f4c746293f064a32961ad77b57f901dd54a67 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sun, 26 Apr 2020 19:55:54 -0400
Subject: [PATCH] Pass gss_localname() through SPNEGO
ticket: 8897 (new)
(cherry picked from commit f7b8a6432bd289bdc528017be122305f95b8e285)
---
src/lib/gssapi/spnego/gssapiP_spnego.h | 8 ++++++++
src/lib/gssapi/spnego/spnego_mech.c | 9 ++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h
index a93763314..066ec736f 100644
--- a/src/lib/gssapi/spnego/gssapiP_spnego.h
+++ b/src/lib/gssapi/spnego/gssapiP_spnego.h
@@ -357,6 +357,14 @@ OM_uint32 KRB5_CALLCONV spnego_gss_wrap_size_limit
OM_uint32 *max_input_size
);
+OM_uint32 KRB5_CALLCONV spnego_gss_localname
+(
+ OM_uint32 *minor_status,
+ const gss_name_t pname,
+ const gss_const_OID mech_type,
+ gss_buffer_t localname
+);
+
OM_uint32 KRB5_CALLCONV spnego_gss_get_mic
(
OM_uint32 *minor_status,
diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
index b3010c201..f4a042478 100644
--- a/src/lib/gssapi/spnego/spnego_mech.c
+++ b/src/lib/gssapi/spnego/spnego_mech.c
@@ -237,7 +237,7 @@ static struct gss_config spnego_mechanism =
spnego_gss_inquire_context, /* gss_inquire_context */
NULL, /* gss_internal_release_oid */
spnego_gss_wrap_size_limit, /* gss_wrap_size_limit */
- NULL, /* gssd_pname_to_uid */
+ spnego_gss_localname,
NULL, /* gss_userok */
NULL, /* gss_export_name */
spnego_gss_duplicate_name, /* gss_duplicate_name */
@@ -2372,6 +2372,13 @@ spnego_gss_wrap_size_limit(
return (ret);
}
+OM_uint32 KRB5_CALLCONV
+spnego_gss_localname(OM_uint32 *minor_status, const gss_name_t pname,
+ const gss_const_OID mech_type, gss_buffer_t localname)
+{
+ return gss_localname(minor_status, pname, GSS_C_NO_OID, localname);
+}
+
OM_uint32 KRB5_CALLCONV
spnego_gss_get_mic(
OM_uint32 *minor_status,

View File

@ -1,335 +0,0 @@
From 17093468190706e241d2a6ef2bb5607be7021640 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 5 Feb 2020 18:46:11 -0500
Subject: [PATCH] Refactor KDC authdata list management helpers
Remove the unused concat_authorization_data(). Split merge_authdata()
into two helpers, one to destructively merge without filtering and one
to add copied elements while filtering out KDC-only authdata types.
Remove context parameters where they aren't needed (taking advantage
of knowledge that some libkrb5 functions don't use their context
parameters).
(cherry picked from commit b2190fdc253de6024001e0f1ff9fe56c31042bb7)
---
src/kdc/kdc_authdata.c | 138 +++++++++++++++++++----------------------
src/kdc/kdc_util.c | 50 ---------------
src/kdc/kdc_util.h | 5 --
3 files changed, 64 insertions(+), 129 deletions(-)
diff --git a/src/kdc/kdc_authdata.c b/src/kdc/kdc_authdata.c
index 1ebe87246..010922c27 100644
--- a/src/kdc/kdc_authdata.c
+++ b/src/kdc/kdc_authdata.c
@@ -108,7 +108,7 @@ unload_authdata_plugins(krb5_context context)
/* Return true if authdata should be filtered when copying from untrusted
* authdata. If desired_type is non-zero, look only for that type. */
static krb5_boolean
-is_kdc_issued_authdatum(krb5_context context, krb5_authdata *authdata,
+is_kdc_issued_authdatum(krb5_authdata *authdata,
krb5_authdatatype desired_type)
{
krb5_boolean result = FALSE;
@@ -117,7 +117,7 @@ is_kdc_issued_authdatum(krb5_context context, krb5_authdata *authdata,
krb5_authdatatype *ad_types, *containee_types = NULL;
if (authdata->ad_type == KRB5_AUTHDATA_IF_RELEVANT) {
- if (krb5int_get_authdata_containee_types(context, authdata, &count,
+ if (krb5int_get_authdata_containee_types(NULL, authdata, &count,
&containee_types) != 0)
goto cleanup;
ad_types = containee_types;
@@ -152,7 +152,7 @@ cleanup:
/* Return true if authdata contains any elements which should only come from
* the KDC. If desired_type is non-zero, look only for that type. */
static krb5_boolean
-has_kdc_issued_authdata(krb5_context context, krb5_authdata **authdata,
+has_kdc_issued_authdata(krb5_authdata **authdata,
krb5_authdatatype desired_type)
{
int i;
@@ -160,7 +160,7 @@ has_kdc_issued_authdata(krb5_context context, krb5_authdata **authdata,
if (authdata == NULL)
return FALSE;
for (i = 0; authdata[i] != NULL; i++) {
- if (is_kdc_issued_authdatum(context, authdata[i], desired_type))
+ if (is_kdc_issued_authdatum(authdata[i], desired_type))
return TRUE;
}
return FALSE;
@@ -181,66 +181,71 @@ has_mandatory_for_kdc_authdata(krb5_context context, krb5_authdata **authdata)
return FALSE;
}
-/*
- * Add the elements of in_authdata to out_authdata. If copy is false,
- * in_authdata is invalid on successful return. If ignore_kdc_issued is true,
- * KDC-issued authdata is not copied.
- */
+/* Add elements from *new_elements to *existing_list, reallocating as
+ * necessary. On success, release *new_elements and set it to NULL. */
static krb5_error_code
-merge_authdata(krb5_context context, krb5_authdata **in_authdata,
- krb5_authdata ***out_authdata, krb5_boolean copy,
- krb5_boolean ignore_kdc_issued)
+merge_authdata(krb5_authdata ***existing_list, krb5_authdata ***new_elements)
{
- krb5_error_code ret;
- size_t i, j, nadata = 0;
- krb5_authdata **in_copy = NULL, **authdata = *out_authdata;
+ size_t count = 0, ncount = 0;
+ krb5_authdata **list = *existing_list, **nlist = *new_elements;
- if (in_authdata == NULL || in_authdata[0] == NULL)
+ if (nlist == NULL)
return 0;
- if (authdata != NULL) {
- for (nadata = 0; authdata[nadata] != NULL; nadata++)
- ;
- }
+ for (count = 0; list != NULL && list[count] != NULL; count++);
+ for (ncount = 0; nlist[ncount] != NULL; ncount++);
- for (i = 0; in_authdata[i] != NULL; i++)
- ;
-
- if (copy) {
- ret = krb5_copy_authdata(context, in_authdata, &in_copy);
- if (ret)
- return ret;
- in_authdata = in_copy;
- }
-
- authdata = realloc(authdata, (nadata + i + 1) * sizeof(krb5_authdata *));
- if (authdata == NULL) {
- krb5_free_authdata(context, in_copy);
+ list = realloc(list, (count + ncount + 1) * sizeof(*list));
+ if (list == NULL)
return ENOMEM;
+
+ memcpy(list + count, nlist, ncount * sizeof(*nlist));
+ list[count + ncount] = NULL;
+ free(nlist);
+
+ if (list[0] == NULL) {
+ free(list);
+ list = NULL;
}
- for (i = 0, j = 0; in_authdata[i] != NULL; i++) {
- if (ignore_kdc_issued &&
- is_kdc_issued_authdatum(context, in_authdata[i], 0)) {
- free(in_authdata[i]->contents);
- free(in_authdata[i]);
+ *new_elements = NULL;
+ *existing_list = list;
+ return 0;
+}
+
+/* Add a copy of new_elements to *existing_list, omitting KDC-issued
+ * authdata. */
+static krb5_error_code
+add_filtered_authdata(krb5_authdata ***existing_list,
+ krb5_authdata **new_elements)
+{
+ krb5_error_code ret;
+ krb5_authdata **copy;
+ size_t i, j;
+
+ if (new_elements == NULL)
+ return 0;
+
+ ret = krb5_copy_authdata(NULL, new_elements, &copy);
+ if (ret)
+ return ret;
+
+ /* Remove KDC-issued elements from copy. */
+ j = 0;
+ for (i = 0; copy[i] != NULL; i++) {
+ if (is_kdc_issued_authdatum(copy[i], 0)) {
+ free(copy[i]->contents);
+ free(copy[i]);
} else {
- authdata[nadata + j++] = in_authdata[i];
+ copy[j++] = copy[i];
}
}
+ copy[j] = NULL;
- authdata[nadata + j] = NULL;
-
- free(in_authdata);
-
- if (authdata[0] == NULL) {
- free(authdata);
- authdata = NULL;
- }
-
- *out_authdata = authdata;
-
- return 0;
+ /* Destructively merge the filtered copy into existing_list. */
+ ret = merge_authdata(existing_list, &copy);
+ krb5_free_authdata(NULL, copy);
+ return ret;
}
/* Copy TGS-REQ authorization data into the ticket authdata. */
@@ -289,10 +294,7 @@ copy_request_authdata(krb5_context context, krb5_keyblock *client_key,
goto cleanup;
}
- /* Add a copy of the requested authdata to the ticket, ignoring KDC-issued
- * types. */
- ret = merge_authdata(context, req->unenc_authdata, tkt_authdata, TRUE,
- TRUE);
+ ret = add_filtered_authdata(tkt_authdata, req->unenc_authdata);
cleanup:
free(plaintext.data);
@@ -307,9 +309,7 @@ copy_tgt_authdata(krb5_context context, krb5_kdc_req *request,
if (has_mandatory_for_kdc_authdata(context, tgt_authdata))
return KRB5KDC_ERR_POLICY;
- /* Add a copy of the TGT authdata to the ticket, ignoring KDC-issued
- * types. */
- return merge_authdata(context, tgt_authdata, tkt_authdata, TRUE, TRUE);
+ return add_filtered_authdata(tkt_authdata, tgt_authdata);
}
/* Fetch authorization data from KDB module. */
@@ -374,8 +374,7 @@ fetch_kdb_authdata(krb5_context context, unsigned int flags,
/* Put the KDB authdata first in the ticket. A successful merge places the
* combined list in db_authdata and releases the old ticket authdata. */
- ret = merge_authdata(context, enc_tkt_reply->authorization_data,
- &db_authdata, FALSE, FALSE);
+ ret = merge_authdata(&db_authdata, &enc_tkt_reply->authorization_data);
if (ret)
krb5_free_authdata(context, db_authdata);
else
@@ -404,8 +403,7 @@ make_signedpath_data(krb5_context context, krb5_const_principal client,
return ret;
for (i = 0, j = 0; authdata[i] != NULL; i++) {
- if (is_kdc_issued_authdatum(context, authdata[i],
- KRB5_AUTHDATA_SIGNTICKET))
+ if (is_kdc_issued_authdatum(authdata[i], KRB5_AUTHDATA_SIGNTICKET))
continue;
sign_authdata[j++] = authdata[i];
@@ -635,12 +633,8 @@ make_signedpath(krb5_context context, krb5_const_principal for_user_princ,
if (ret)
goto cleanup;
- /* Add the authdata to the ticket, without copying or filtering. */
- ret = merge_authdata(context, if_relevant,
- &enc_tkt_reply->authorization_data, FALSE, FALSE);
- if (ret)
- goto cleanup;
- if_relevant = NULL; /* merge_authdata() freed */
+ /* Add the signedpath authdata to the ticket. */
+ ret = merge_authdata(&enc_tkt_reply->authorization_data, &if_relevant);
cleanup:
free(sp.delegated);
@@ -665,7 +659,7 @@ free_deleg_path(krb5_context context, krb5_principal *deleg_path)
static krb5_boolean
has_pac(krb5_context context, krb5_authdata **authdata)
{
- return has_kdc_issued_authdata(context, authdata, KRB5_AUTHDATA_WIN2K_PAC);
+ return has_kdc_issued_authdata(authdata, KRB5_AUTHDATA_WIN2K_PAC);
}
/* Verify AD-SIGNTICKET authdata if we need to, and insert an AD-SIGNEDPATH
@@ -746,11 +740,7 @@ add_auth_indicators(krb5_context context, krb5_data *const *auth_indicators,
goto cleanup;
/* Add the wrapped authdata to the ticket, without copying or filtering. */
- ret = merge_authdata(context, cammac, &enc_tkt_reply->authorization_data,
- FALSE, FALSE);
- if (ret)
- goto cleanup;
- cammac = NULL; /* merge_authdata() freed */
+ ret = merge_authdata(&enc_tkt_reply->authorization_data, &cammac);
cleanup:
krb5_free_data(context, der_indicators);
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index 6330387d0..a4a05b9fa 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -78,56 +78,6 @@ static krb5_error_code find_server_key(krb5_context,
krb5_kvno, krb5_keyblock **,
krb5_kvno *);
-/*
- * concatenate first two authdata arrays, returning an allocated replacement.
- * The replacement should be freed with krb5_free_authdata().
- */
-krb5_error_code
-concat_authorization_data(krb5_context context,
- krb5_authdata **first, krb5_authdata **second,
- krb5_authdata ***output)
-{
- int i, j;
- krb5_authdata **ptr, **retdata;
-
- /* count up the entries */
- i = 0;
- if (first)
- for (ptr = first; *ptr; ptr++)
- i++;
- if (second)
- for (ptr = second; *ptr; ptr++)
- i++;
-
- retdata = (krb5_authdata **)malloc((i+1)*sizeof(*retdata));
- if (!retdata)
- return ENOMEM;
- retdata[i] = 0; /* null-terminated array */
- for (i = 0, j = 0, ptr = first; j < 2 ; ptr = second, j++)
- while (ptr && *ptr) {
- /* now walk & copy */
- retdata[i] = (krb5_authdata *)malloc(sizeof(*retdata[i]));
- if (!retdata[i]) {
- krb5_free_authdata(context, retdata);
- return ENOMEM;
- }
- *retdata[i] = **ptr;
- if (!(retdata[i]->contents =
- (krb5_octet *)malloc(retdata[i]->length))) {
- free(retdata[i]);
- retdata[i] = 0;
- krb5_free_authdata(context, retdata);
- return ENOMEM;
- }
- memcpy(retdata[i]->contents, (*ptr)->contents, retdata[i]->length);
-
- ptr++;
- i++;
- }
- *output = retdata;
- return 0;
-}
-
krb5_boolean
is_local_principal(kdc_realm_t *kdc_active_realm, krb5_const_principal princ1)
{
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index 2c9d8cf69..42b7ee208 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -52,11 +52,6 @@ compress_transited (krb5_data *,
krb5_principal,
krb5_data *);
krb5_error_code
-concat_authorization_data (krb5_context,
- krb5_authdata **,
- krb5_authdata **,
- krb5_authdata ***);
-krb5_error_code
fetch_last_req_info (krb5_db_entry *, krb5_last_req_entry ***);
krb5_error_code

View File

@ -1,479 +0,0 @@
From 8412a1611290da9705730c9e473a5b122c55e9fd Mon Sep 17 00:00:00 2001
From: Alexander Scheel <ascheel@redhat.com>
Date: Fri, 30 Jun 2017 16:03:01 -0400
Subject: [PATCH] Refactor krb5 GSS checksum handling
Separate out checksum handling from kg_accept_krb5() into a new helper
process_checksum().
[ghudson@mit.edu: simplified checksum processing and made it use
k5-input.h instead of TREAD_ macros; moved more flag handling into
helper]
[iboukris: adjusted helper function arguments, allowing access to the
full authenticator for subsequent changes]
(cherry picked from commit 64d56233f9816a2a93f6e8d3030c8ed6ce397735)
[rharwood@redhat.com: problem with typo fix commit, I think]
---
src/lib/gssapi/krb5/accept_sec_context.c | 383 +++++++++++------------
1 file changed, 179 insertions(+), 204 deletions(-)
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index c5bddb1e8..70dd7fc0c 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -98,6 +98,7 @@
*/
#include "k5-int.h"
+#include "k5-input.h"
#include "gssapiP_krb5.h"
#ifdef HAVE_MEMORY_H
#include <memory.h>
@@ -413,6 +414,174 @@ kg_process_extension(krb5_context context,
return code;
}
+/* The length of the MD5 channel bindings in an 0x8003 checksum */
+#define CB_MD5_LEN 16
+
+/* The minimum length of an 0x8003 checksum value (4-byte channel bindings
+ * length, 16-byte channel bindings, 4-byte flags) */
+#define MIN_8003_LEN (4 + CB_MD5_LEN + 4)
+
+/* The flags we accept from the initiator's authenticator checksum. */
+#define INITIATOR_FLAGS (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG | \
+ GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \
+ GSS_C_SEQUENCE_FLAG | GSS_C_DCE_STYLE | \
+ GSS_C_IDENTIFY_FLAG | GSS_C_EXTENDED_ERROR_FLAG)
+
+/*
+ * The krb5 GSS mech appropriates the authenticator checksum field from RFC
+ * 4120 to store structured data instead of a checksum, indicated with checksum
+ * type 0x8003 (see RFC 4121 section 4.1.1). Some implementations instead send
+ * no checksum, or a regular checksum over empty data.
+ *
+ * Interpret the checksum. Read delegated creds into *deleg_out if it is not
+ * NULL. Set *flags_out to the allowed subset of token flags, plus
+ * GSS_C_DELEG_FLAG if a delegated credential was present. Process any
+ * extensions found using exts. On error, set *code_out to a krb5_error code
+ * for use as a minor status value.
+ */
+static OM_uint32
+process_checksum(OM_uint32 *minor_status, krb5_context context,
+ gss_channel_bindings_t acceptor_cb,
+ krb5_auth_context auth_context, krb5_flags ap_req_options,
+ krb5_authenticator *authenticator, krb5_gss_ctx_ext_t exts,
+ krb5_gss_cred_id_t *deleg_out, krb5_ui_4 *flags_out,
+ krb5_error_code *code_out)
+{
+ krb5_error_code code = 0;
+ OM_uint32 status, option_id, token_flags;
+ size_t cb_len, option_len;
+ krb5_boolean valid;
+ krb5_key subkey;
+ krb5_data option, empty = empty_data();
+ krb5_checksum cb_cksum;
+ const uint8_t *token_cb, *option_bytes;
+ struct k5input in;
+ const krb5_checksum *cksum = authenticator->checksum;
+
+ cb_cksum.contents = NULL;
+
+ if (cksum == NULL) {
+ /*
+ * Some SMB client implementations use handcrafted GSSAPI code that
+ * does not provide a checksum. MS-KILE documents that the Microsoft
+ * implementation considers a missing checksum acceptable; the server
+ * assumes all flags are unset in this case, and does not check channel
+ * bindings.
+ */
+ *flags_out = 0;
+ } else if (cksum->checksum_type != CKSUMTYPE_KG_CB) {
+ /* Samba sends a regular checksum. */
+ code = krb5_auth_con_getkey_k(context, auth_context, &subkey);
+ if (code) {
+ status = GSS_S_FAILURE;
+ goto fail;
+ }
+
+ /* Verifying the checksum ensures that this authenticator wasn't
+ * replayed from one with a checksum over actual data. */
+ code = krb5_k_verify_checksum(context, subkey,
+ KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, &empty,
+ cksum, &valid);
+ krb5_k_free_key(context, subkey);
+ if (code || !valid) {
+ status = GSS_S_BAD_SIG;
+ goto fail;
+ }
+
+ /* Use ap_options from the request to guess the mutual flag. */
+ *flags_out = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
+ if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED)
+ *flags_out |= GSS_C_MUTUAL_FLAG;
+ } else {
+ /* The checksum must contain at least a fixed 24-byte part. */
+ if (cksum->length < MIN_8003_LEN) {
+ status = GSS_S_BAD_BINDINGS;
+ goto fail;
+ }
+
+ k5_input_init(&in, cksum->contents, cksum->length);
+ cb_len = k5_input_get_uint32_le(&in);
+ if (cb_len != CB_MD5_LEN) {
+ code = KG_BAD_LENGTH;
+ status = GSS_S_FAILURE;
+ goto fail;
+ }
+
+ token_cb = k5_input_get_bytes(&in, cb_len);
+ if (acceptor_cb != GSS_C_NO_CHANNEL_BINDINGS) {
+ code = kg_checksum_channel_bindings(context, acceptor_cb,
+ &cb_cksum);
+ if (code) {
+ status = GSS_S_BAD_BINDINGS;
+ goto fail;
+ }
+ assert(cb_cksum.length == cb_len);
+ if (k5_bcmp(token_cb, cb_cksum.contents, cb_len) != 0) {
+ status = GSS_S_BAD_BINDINGS;
+ goto fail;
+ }
+ }
+
+ /* Read the token flags and accept some of them as context flags. */
+ token_flags = k5_input_get_uint32_le(&in);
+ *flags_out = token_flags & INITIATOR_FLAGS;
+
+ /* Read the delegated credential if present. */
+ if (in.len >= 4 && (token_flags & GSS_C_DELEG_FLAG)) {
+ option_id = k5_input_get_uint16_le(&in);
+ option_len = k5_input_get_uint16_le(&in);
+ option_bytes = k5_input_get_bytes(&in, option_len);
+ option = make_data((uint8_t *)option_bytes, option_len);
+ if (in.status) {
+ code = KG_BAD_LENGTH;
+ status = GSS_S_FAILURE;
+ goto fail;
+ }
+ if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
+ status = GSS_S_FAILURE;
+ goto fail;
+ }
+
+ /* Store the delegated credential. */
+ code = rd_and_store_for_creds(context, auth_context, &option,
+ deleg_out);
+ if (code) {
+ status = GSS_S_FAILURE;
+ goto fail;
+ }
+ *flags_out |= GSS_C_DELEG_FLAG;
+ }
+
+ /* Process any extensions at the end of the checksum. Extensions use
+ * 4-byte big-endian tag and length instead of 2-byte little-endian. */
+ while (in.len > 0) {
+ option_id = k5_input_get_uint32_be(&in);
+ option_len = k5_input_get_uint32_be(&in);
+ option_bytes = k5_input_get_bytes(&in, option_len);
+ option = make_data((uint8_t *)option_bytes, option_len);
+ if (in.status) {
+ code = KG_BAD_LENGTH;
+ status = GSS_S_FAILURE;
+ goto fail;
+ }
+
+ code = kg_process_extension(context, auth_context, option_id,
+ &option, exts);
+ if (code) {
+ status = GSS_S_FAILURE;
+ goto fail;
+ }
+ }
+ }
+
+ status = GSS_S_COMPLETE;
+
+fail:
+ free(cb_cksum.contents);
+ *code_out = code;
+ return status;
+}
+
static OM_uint32
kg_accept_krb5(minor_status, context_handle,
verifier_cred_handle, input_token,
@@ -433,17 +602,13 @@ kg_accept_krb5(minor_status, context_handle,
krb5_gss_ctx_ext_t exts;
{
krb5_context context;
- unsigned char *ptr, *ptr2;
+ unsigned char *ptr;
char *sptr;
- OM_uint32 tmp;
- size_t md5len;
krb5_gss_cred_id_t cred = 0;
krb5_data ap_rep, ap_req;
- unsigned int i;
krb5_error_code code;
krb5_address addr, *paddr;
krb5_authenticator *authdat = 0;
- krb5_checksum reqcksum;
krb5_gss_name_t name = NULL;
krb5_ui_4 gss_flags = 0;
krb5_gss_ctx_id_rec *ctx = NULL;
@@ -451,8 +616,6 @@ kg_accept_krb5(minor_status, context_handle,
gss_buffer_desc token;
krb5_auth_context auth_context = NULL;
krb5_ticket * ticket = NULL;
- int option_id;
- krb5_data option;
const gss_OID_desc *mech_used = NULL;
OM_uint32 major_status = GSS_S_FAILURE;
OM_uint32 tmp_minor_status;
@@ -463,7 +626,6 @@ kg_accept_krb5(minor_status, context_handle,
krb5int_access kaccess;
int cred_rcache = 0;
int no_encap = 0;
- int token_deleg_flag = 0;
krb5_flags ap_req_options = 0;
krb5_enctype negotiated_etype;
krb5_authdata_context ad_context = NULL;
@@ -489,7 +651,6 @@ kg_accept_krb5(minor_status, context_handle,
output_token->length = 0;
output_token->value = NULL;
token.value = 0;
- reqcksum.contents = 0;
ap_req.data = 0;
ap_rep.data = 0;
@@ -654,195 +815,16 @@ kg_accept_krb5(minor_status, context_handle,
krb5_auth_con_getauthenticator(context, auth_context, &authdat);
- if (authdat->checksum == NULL) {
- /*
- * Some SMB client implementations use handcrafted GSSAPI code that
- * does not provide a checksum. MS-KILE documents that the Microsoft
- * implementation considers a missing checksum acceptable; the server
- * assumes all flags are unset in this case, and does not check channel
- * bindings.
- */
- gss_flags = 0;
- } else if (authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) {
- /* Samba does not send 0x8003 GSS-API checksums */
- krb5_boolean valid;
- krb5_key subkey;
- krb5_data zero;
+ major_status = process_checksum(minor_status, context, input_chan_bindings,
+ auth_context, ap_req_options,
+ authdat, exts,
+ delegated_cred_handle ? &deleg_cred : NULL,
+ &gss_flags, &code);
- code = krb5_auth_con_getkey_k(context, auth_context, &subkey);
- if (code) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
+ if (major_status != GSS_S_COMPLETE)
+ goto fail;
- zero.length = 0;
- zero.data = "";
-
- code = krb5_k_verify_checksum(context,
- subkey,
- KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM,
- &zero,
- authdat->checksum,
- &valid);
- krb5_k_free_key(context, subkey);
- if (code || !valid) {
- major_status = GSS_S_BAD_SIG;
- goto fail;
- }
-
- /* Use ap_options from the request to guess the mutual flag. */
- gss_flags = GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG;
- if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED)
- gss_flags |= GSS_C_MUTUAL_FLAG;
- } else {
- /* gss krb5 v1 */
-
- /* stash this now, for later. */
- code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &md5len);
- if (code) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- /* verify that the checksum is correct */
-
- /*
- The checksum may be either exactly 24 bytes, in which case
- no options are specified, or greater than 24 bytes, in which case
- one or more options are specified. Currently, the only valid
- option is KRB5_GSS_FOR_CREDS_OPTION ( = 1 ).
- */
-
- if ((authdat->checksum->checksum_type != CKSUMTYPE_KG_CB) ||
- (authdat->checksum->length < 24)) {
- code = 0;
- major_status = GSS_S_BAD_BINDINGS;
- goto fail;
- }
-
- ptr = (unsigned char *) authdat->checksum->contents;
-
- TREAD_INT(ptr, tmp, 0);
-
- if (tmp != md5len) {
- code = KG_BAD_LENGTH;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- /*
- The following section of code attempts to implement the
- optional channel binding facility as described in RFC2743.
-
- Since this facility is optional channel binding may or may
- not have been provided by either the client or the server.
-
- If the server has specified input_chan_bindings equal to
- GSS_C_NO_CHANNEL_BINDINGS then we skip the check. If
- the server does provide channel bindings then we compute
- a checksum and compare against those provided by the
- client. */
-
- if ((code = kg_checksum_channel_bindings(context,
- input_chan_bindings,
- &reqcksum))) {
- major_status = GSS_S_BAD_BINDINGS;
- goto fail;
- }
-
- /* Always read the clients bindings - eventhough we might ignore them */
- TREAD_STR(ptr, ptr2, reqcksum.length);
-
- if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS ) {
- if (memcmp(ptr2, reqcksum.contents, reqcksum.length) != 0) {
- xfree(reqcksum.contents);
- reqcksum.contents = 0;
- code = 0;
- major_status = GSS_S_BAD_BINDINGS;
- goto fail;
- }
-
- }
-
- xfree(reqcksum.contents);
- reqcksum.contents = 0;
-
- /* Read the token flags. Remember if GSS_C_DELEG_FLAG was set, but
- * mask it out until we actually read a delegated credential. */
- TREAD_INT(ptr, gss_flags, 0);
- token_deleg_flag = (gss_flags & GSS_C_DELEG_FLAG);
- gss_flags &= ~GSS_C_DELEG_FLAG;
-
- /* if the checksum length > 24, there are options to process */
-
- i = authdat->checksum->length - 24;
- if (i && token_deleg_flag) {
- if (i >= 4) {
- TREAD_INT16(ptr, option_id, 0);
- TREAD_INT16(ptr, option.length, 0);
- i -= 4;
-
- if (i < option.length) {
- code = KG_BAD_LENGTH;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- /* have to use ptr2, since option.data is wrong type and
- macro uses ptr as both lvalue and rvalue */
-
- TREAD_STR(ptr, ptr2, option.length);
- option.data = (char *) ptr2;
-
- i -= option.length;
-
- if (option_id != KRB5_GSS_FOR_CREDS_OPTION) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- /* store the delegated credential */
-
- code = rd_and_store_for_creds(context, auth_context, &option,
- (delegated_cred_handle) ?
- &deleg_cred : NULL);
- if (code) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
-
- gss_flags |= GSS_C_DELEG_FLAG;
- } /* if i >= 4 */
- /* ignore any additional trailing data, for now */
- }
- while (i > 0) {
- /* Process Type-Length-Data options */
- if (i < 8) {
- code = KG_BAD_LENGTH;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
- TREAD_INT(ptr, option_id, 1);
- TREAD_INT(ptr, option.length, 1);
- i -= 8;
- if (i < option.length) {
- code = KG_BAD_LENGTH;
- major_status = GSS_S_FAILURE;
- goto fail;
- }
- TREAD_STR(ptr, ptr2, option.length);
- option.data = (char *)ptr2;
-
- i -= option.length;
-
- code = kg_process_extension(context, auth_context,
- option_id, &option, exts);
- if (code != 0) {
- major_status = GSS_S_FAILURE;
- goto fail;
- }
- }
- }
+ major_status = GSS_S_FAILURE;
if (exts->iakerb.conv && !exts->iakerb.verified) {
major_status = GSS_S_BAD_SIG;
@@ -869,12 +851,7 @@ kg_accept_krb5(minor_status, context_handle,
ctx->mech_used = (gss_OID) mech_used;
ctx->auth_context = auth_context;
ctx->initiate = 0;
- ctx->gss_flags = (GSS_C_TRANS_FLAG |
- ((gss_flags) & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG |
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
- GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG |
- GSS_C_DCE_STYLE | GSS_C_IDENTIFY_FLAG |
- GSS_C_EXTENDED_ERROR_FLAG)));
+ ctx->gss_flags = gss_flags | GSS_C_TRANS_FLAG;
ctx->seed_init = 0;
ctx->cred_rcache = cred_rcache;
@@ -1161,8 +1138,6 @@ fail:
krb5_auth_con_free(context, auth_context);
}
- if (reqcksum.contents)
- xfree(reqcksum.contents);
if (ap_rep.data)
krb5_free_data_contents(context, &ap_rep);
if (major_status == GSS_S_COMPLETE ||

View File

@ -1,78 +0,0 @@
From 43fe1f948059ad79d95dbf41f2206de65238d892 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Wed, 26 Feb 2020 18:27:17 -0500
Subject: [PATCH] Refresh manually acquired creds from client keytab
If a client keytab is present but credentials are acquired manually,
the credentials would not be refreshed because no refresh_time config
var is set in the cache. Change kg_cred_time_to_refresh() to attempt
a refresh from the client keytab on any credentials which will expire
in the next 30 seconds.
[ghudson@mit.edu: adjused code and added test case]
ticket: 7976
(cherry picked from commit 729896467e3c77904666019d6cbbda583ae49b95)
---
src/lib/gssapi/krb5/acquire_cred.c | 14 +++++++++++---
src/tests/gssapi/t_client_keytab.py | 18 ++++++++++++++++++
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index acc1868f8..4062f4741 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -557,15 +557,23 @@ set_refresh_time(krb5_context context, krb5_ccache ccache,
krb5_boolean
kg_cred_time_to_refresh(krb5_context context, krb5_gss_cred_id_rec *cred)
{
- krb5_timestamp now;
+ krb5_timestamp now, soon;
if (krb5_timeofday(context, &now))
return FALSE;
+ soon = ts_incr(now, 30);
if (cred->refresh_time != 0 && !ts_after(cred->refresh_time, now)) {
- set_refresh_time(context, cred->ccache,
- ts_incr(cred->refresh_time, 30));
+ set_refresh_time(context, cred->ccache, soon);
return TRUE;
}
+
+ /* If the creds will expire soon, try to refresh even if they weren't
+ * acquired with a client keytab. */
+ if (ts_after(soon, cred->expire)) {
+ set_refresh_time(context, cred->ccache, soon);
+ return TRUE;
+ }
+
return FALSE;
}
diff --git a/src/tests/gssapi/t_client_keytab.py b/src/tests/gssapi/t_client_keytab.py
index e474a27c7..7847b3ecd 100755
--- a/src/tests/gssapi/t_client_keytab.py
+++ b/src/tests/gssapi/t_client_keytab.py
@@ -124,4 +124,22 @@ realm.kinit(realm.user_princ, password('user'))
realm.run(['./t_ccselect', phost], env=bad_cktname,
expected_msg=realm.user_princ)
+mark('refresh of manually acquired creds')
+
+# Test 17: no name/ccache specified, manually acquired creds which
+# will expire soon. Verify that creds are refreshed using the current
+# client name, with refresh_time set in the refreshed ccache.
+realm.kinit('bob', password('bob'), ['-l', '15s'])
+realm.run(['./t_ccselect', phost], expected_msg='bob')
+realm.run([klist, '-C'], expected_msg='refresh_time = ')
+
+# Test 18: no name/ccache specified, manually acquired creds with a
+# client principal not present in the client keytab. A refresh is
+# attempted but fails, and an expired ticket error results.
+realm.kinit(realm.admin_princ, password('admin'), ['-l', '-1s'])
+msgs = ('Getting initial credentials for user/admin@KRBTEST.COM',
+ '/Matching credential not found')
+realm.run(['./t_ccselect', phost], expected_code=1,
+ expected_msg='Ticket expired', expected_trace=msgs)
+
success('Client keytab tests')

View File

@ -1,547 +0,0 @@
From 6d2dbd0378c92ea13363f2536ab0062bdfda076e Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Thu, 28 May 2020 18:41:02 -0400
Subject: [PATCH] Remove resolver test utility
tests/resolve is no longer used after the previous commit.
[rharwood@redhat.com: .gitignore]
---
src/configure.ac | 5 +-
src/tests/Makefile.in | 4 +-
src/tests/resolve/Makefile.in | 28 ---
src/tests/resolve/addrinfo-test.c | 306 -------------------------
src/tests/resolve/deps | 14 --
src/tests/resolve/fake-addrinfo-test.c | 3 -
src/tests/resolve/resolve.c | 115 ----------
7 files changed, 4 insertions(+), 471 deletions(-)
delete mode 100644 src/tests/resolve/Makefile.in
delete mode 100644 src/tests/resolve/addrinfo-test.c
delete mode 100644 src/tests/resolve/deps
delete mode 100644 src/tests/resolve/fake-addrinfo-test.c
delete mode 100644 src/tests/resolve/resolve.c
diff --git a/src/configure.ac b/src/configure.ac
index aafc462f9..00b5ea4c5 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1540,7 +1540,6 @@ V5_AC_OUTPUT_MAKEFILE(.
appl/simple appl/simple/client appl/simple/server
appl/gss-sample appl/user_user
- tests tests/resolve tests/asn.1 tests/create tests/hammer
- tests/verify tests/gssapi tests/dejagnu tests/threads tests/shlib
- tests/gss-threads tests/misc
+ tests tests/asn.1 tests/create tests/hammer tests/verify tests/gssapi
+ tests/dejagnu tests/threads tests/shlib tests/gss-threads tests/misc
)
diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in
index 3f88f1713..6b7749129 100644
--- a/src/tests/Makefile.in
+++ b/src/tests/Makefile.in
@@ -1,7 +1,7 @@
mydir=tests
BUILDTOP=$(REL)..
-SUBDIRS = resolve asn.1 create hammer verify gssapi dejagnu shlib \
- gss-threads misc threads softpkcs11
+SUBDIRS = asn.1 create hammer verify gssapi dejagnu shlib gss-threads misc \
+ threads softpkcs11
RUN_DB_TEST = $(RUN_SETUP) KRB5_KDC_PROFILE=kdc.conf KRB5_CONFIG=krb5.conf \
GSS_MECH_CONFIG=mech.conf LC_ALL=C $(VALGRIND)
diff --git a/src/tests/resolve/Makefile.in b/src/tests/resolve/Makefile.in
deleted file mode 100644
index 1f5954089..000000000
--- a/src/tests/resolve/Makefile.in
+++ /dev/null
@@ -1,28 +0,0 @@
-mydir=tests$(S)resolve
-BUILDTOP=$(REL)..$(S)..
-
-OBJS=resolve.o addrinfo-test.o fake-addrinfo-test.o
-SRCS=$(srcdir)/resolve.c $(srcdir)/addrinfo-test.c \
- $(srcdir)/fake-addrinfo-test.c
-
-all: resolve addrinfo-test fake-addrinfo-test
-
-resolve: resolve.o
- $(CC_LINK) -o $@ resolve.o $(SUPPORT_LIB) $(LIBS)
-
-addrinfo-test: addrinfo-test.o
- $(CC_LINK) -o $@ addrinfo-test.o $(SUPPORT_LIB) $(LIBS)
-
-fake-addrinfo-test: fake-addrinfo-test.o
- $(CC_LINK) -o $@ fake-addrinfo-test.o $(SUPPORT_LIB) $(LIBS)
-
-check: resolve addrinfo-test fake-addrinfo-test
- $(RUN_TEST) ./resolve
- $(RUN_TEST) ./addrinfo-test -p telnet
- $(RUN_TEST) ./fake-addrinfo-test -p telnet
-
-install:
-
-clean:
- $(RM) resolve addrinfo-test fake-addrinfo-test
-
diff --git a/src/tests/resolve/addrinfo-test.c b/src/tests/resolve/addrinfo-test.c
deleted file mode 100644
index e77640b62..000000000
--- a/src/tests/resolve/addrinfo-test.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/* tests/resolve/addrinfo-test.c */
-/*
- * Copyright 2004 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. 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.
- */
-
-/*
- * A simple program to test the functionality of the getaddrinfo function.
- *
- * Usage:
- * addrinfo-test [-t|-u|-R|-I] [-d|-s|-r] [-p port] [-P] [hostname]
- *
- * When invoked with no arguments, NULL is used for the node name,
- * which (at least with a non-null "port") means a socket address
- * is desired that can be used with connect() or bind() (depending
- * on whether "-P" is given).
- */
-
-#include <k5-platform.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h> /* needed for IPPROTO_* on NetBSD */
-#ifdef USE_FAKE_ADDRINFO
-#include "fake-addrinfo.h"
-#endif
-
-static const char *protoname (int p) {
- static char buf[30];
-
-#define X(N) if (p == IPPROTO_ ## N) return #N
-
- X(TCP);
- X(UDP);
- X(ICMP);
-#ifdef IPPROTO_IPV6
- X(IPV6);
-#endif
-#ifdef IPPROTO_GRE
- X(GRE);
-#endif
-#ifdef IPPROTO_NONE
- X(NONE);
-#endif
- X(RAW);
-#ifdef IPPROTO_COMP
- X(COMP);
-#endif
-
- snprintf(buf, sizeof(buf), " %-2d", p);
- return buf;
-}
-
-static const char *socktypename (int t) {
- static char buf[30];
- switch (t) {
- case SOCK_DGRAM: return "DGRAM";
- case SOCK_STREAM: return "STREAM";
- case SOCK_RAW: return "RAW";
- case SOCK_RDM: return "RDM";
- case SOCK_SEQPACKET: return "SEQPACKET";
- }
- snprintf(buf, sizeof(buf), " %-2d", t);
- return buf;
-}
-
-static char *whoami;
-
-static void usage () {
- fprintf(stderr,
- "usage:\n"
- "\t%s [ options ] [host]\n"
- "options:\n"
- "\t-t\tspecify protocol IPPROTO_TCP\n"
- "\t-u\tspecify protocol IPPROTO_UDP\n"
- "\t-R\tspecify protocol IPPROTO_RAW\n"
- "\t-I\tspecify protocol IPPROTO_ICMP\n"
- "\n"
- "\t-d\tspecify socket type SOCK_DGRAM\n"
- "\t-s\tspecify socket type SOCK_STREAM\n"
- "\t-r\tspecify socket type SOCK_RAW\n"
- "\n"
- "\t-4\tspecify address family AF_INET\n"
-#ifdef AF_INET6
- "\t-6\tspecify address family AF_INET6\n"
-#endif
- "\n"
- "\t-p P\tspecify port P (service name or port number)\n"
- "\t-N\thostname is numeric, skip DNS query\n"
- "\t-n\tservice/port is numeric (sets AI_NUMERICSERV)\n"
- "\t-P\tset AI_PASSIVE\n"
- "\n"
- "default: protocol 0, socket type 0, address family 0, null port\n"
- ,
- whoami);
- /* [ -t | -u | -R | -I ] [ -d | -s | -r ] [ -p port ] */
- exit (1);
-}
-
-static const char *familyname (int f) {
- static char buf[30];
- switch (f) {
- default:
- snprintf(buf, sizeof(buf), "AF %d", f);
- return buf;
- case AF_INET: return "AF_INET";
-#ifdef AF_INET6
- case AF_INET6: return "AF_INET6";
-#endif
- }
-}
-
-#define eaistr(X) (X == EAI_SYSTEM ? strerror(errno) : gai_strerror(X))
-
-int main (int argc, char *argv[])
-{
- struct addrinfo *ap, *ap2;
- int err, numerichost = 0, numericserv = 0;
- char *hname, *port = 0, *sep;
- struct addrinfo hints;
-
- whoami = strrchr(argv[0], '/');
- if (whoami == 0)
- whoami = argv[0];
- else
- whoami = whoami+1;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = 0;
- hints.ai_socktype = 0;
-
- hname = 0;
- hints.ai_family = 0;
-
- if (argc == 1)
- usage ();
-
- while (++argv, --argc > 0) {
- char *arg;
- arg = *argv;
-
- if (*arg != '-')
- hname = arg;
- else if (arg[1] == 0 || arg[2] != 0)
- usage ();
- else
- switch (arg[1]) {
- case 'u':
- hints.ai_protocol = IPPROTO_UDP;
- break;
- case 't':
- hints.ai_protocol = IPPROTO_TCP;
- break;
- case 'R':
- hints.ai_protocol = IPPROTO_RAW;
- break;
- case 'I':
- hints.ai_protocol = IPPROTO_ICMP;
- break;
- case 'd':
- hints.ai_socktype = SOCK_DGRAM;
- break;
- case 's':
- hints.ai_socktype = SOCK_STREAM;
- break;
- case 'r':
- hints.ai_socktype = SOCK_RAW;
- break;
- case 'p':
- if (argv[1] == 0 || argv[1][0] == 0 || argv[1][0] == '-')
- usage ();
- port = argv[1];
- argc--, argv++;
- break;
- case '4':
- hints.ai_family = AF_INET;
- break;
-#ifdef AF_INET6
- case '6':
- hints.ai_family = AF_INET6;
- break;
-#endif
- case 'N':
- numerichost = 1;
- break;
- case 'n':
- numericserv = 1;
- break;
- case 'P':
- hints.ai_flags |= AI_PASSIVE;
- break;
- default:
- usage ();
- }
- }
-
- if (hname && !numerichost)
- hints.ai_flags |= AI_CANONNAME;
- if (numerichost) {
-#ifdef AI_NUMERICHOST
- hints.ai_flags |= AI_NUMERICHOST;
-#else
- fprintf(stderr, "AI_NUMERICHOST not defined on this platform\n");
- exit(1);
-#endif
- }
- if (numericserv) {
-#ifdef AI_NUMERICSERV
- hints.ai_flags |= AI_NUMERICSERV;
-#else
- fprintf(stderr, "AI_NUMERICSERV not defined on this platform\n");
- exit(1);
-#endif
- }
-
- printf("getaddrinfo(hostname %s, service %s,\n"
- " hints { ",
- hname ? hname : "(null)", port ? port : "(null)");
- sep = "";
-#define Z(FLAG) if (hints.ai_flags & AI_##FLAG) printf("%s%s", sep, #FLAG), sep = "|"
- Z(CANONNAME);
- Z(PASSIVE);
-#ifdef AI_NUMERICHOST
- Z(NUMERICHOST);
-#endif
-#ifdef AI_NUMERICSERV
- Z(NUMERICSERV);
-#endif
- if (sep[0] == 0)
- printf ("no-flags");
- if (hints.ai_family)
- printf(" %s", familyname(hints.ai_family));
- if (hints.ai_socktype)
- printf(" SOCK_%s", socktypename(hints.ai_socktype));
- if (hints.ai_protocol)
- printf(" IPPROTO_%s", protoname(hints.ai_protocol));
- printf(" }):\n");
-
- err = getaddrinfo(hname, port, &hints, &ap);
- if (err) {
- printf("\terror => %s\n", eaistr(err));
- return 1;
- }
-
- for (ap2 = ap; ap2; ap2 = ap2->ai_next) {
- char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
- /* If we don't do this, even AIX's own getnameinfo will reject
- the sockaddr structures. The sa_len field doesn't get set
- either, on AIX, but getnameinfo won't complain. */
- if (ap2->ai_addr->sa_family == 0) {
- printf("BAD: sa_family zero! fixing...\n");
- ap2->ai_addr->sa_family = ap2->ai_family;
- } else if (ap2->ai_addr->sa_family != ap2->ai_family) {
- printf("BAD: sa_family != ai_family! fixing...\n");
- ap2->ai_addr->sa_family = ap2->ai_family;
- }
- if (getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof(hbuf),
- pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
- strlcpy(hbuf, "...", sizeof(hbuf));
- strlcpy(pbuf, "...", sizeof(pbuf));
- }
- printf("%p:\n"
- "\tfamily = %s\tproto = %-4s\tsocktype = %s\n",
- (void *) ap2, familyname(ap2->ai_family),
- protoname (ap2->ai_protocol),
- socktypename (ap2->ai_socktype));
- if (ap2->ai_canonname) {
- if (ap2->ai_canonname[0])
- printf("\tcanonname = %s\n", ap2->ai_canonname);
- else
- printf("BAD: ai_canonname is set but empty!\n");
- } else if (ap2 == ap && (hints.ai_flags & AI_CANONNAME)) {
- printf("BAD: first ai_canonname is null!\n");
- }
- printf("\taddr = %-28s\tport = %s\n", hbuf, pbuf);
-
- err = getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof (hbuf),
- pbuf, sizeof(pbuf), NI_NAMEREQD);
- if (err)
- printf("\tgetnameinfo(NI_NAMEREQD): %s\n", eaistr(err));
- else
- printf("\tgetnameinfo => %s, %s\n", hbuf, pbuf);
- }
- freeaddrinfo(ap);
- return 0;
-}
diff --git a/src/tests/resolve/deps b/src/tests/resolve/deps
deleted file mode 100644
index 762d9adab..000000000
--- a/src/tests/resolve/deps
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Generated makefile dependencies follow.
-#
-$(OUTPRE)resolve.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
- resolve.c
-$(OUTPRE)addrinfo-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-thread.h \
- addrinfo-test.c
-$(OUTPRE)fake-addrinfo-test.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(top_srcdir)/include/fake-addrinfo.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h addrinfo-test.c \
- fake-addrinfo-test.c
diff --git a/src/tests/resolve/fake-addrinfo-test.c b/src/tests/resolve/fake-addrinfo-test.c
deleted file mode 100644
index 86365a5ba..000000000
--- a/src/tests/resolve/fake-addrinfo-test.c
+++ /dev/null
@@ -1,3 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-#define USE_FAKE_ADDRINFO
-#include "addrinfo-test.c"
diff --git a/src/tests/resolve/resolve.c b/src/tests/resolve/resolve.c
deleted file mode 100644
index ea0239113..000000000
--- a/src/tests/resolve/resolve.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-/* tests/resolve/resolve.c */
-/*
- * Copyright 1995 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. 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.
- */
-
-/*
- * A simple program to test the functionality of the resolver library.
- * It simply will try to get the IP address of the host, and then look
- * up the name from the address. If the resulting name does not contain the
- * domain name, then the resolve library is broken.
- *
- * Warning: It is possible to fool this program into thinking everything is
- * alright by a clever use of /etc/hosts - but this is better than nothing.
- *
- * Usage:
- * resolve [hostname]
- *
- * When invoked with no arguments, gethostname is used for the local host.
- *
- */
-
-/* This program tests the resolve library and sees if it is broken... */
-
-#include "k5-platform.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-
-int
-main(int argc, char **argv)
-{
- struct addrinfo *ai = NULL, hint;
- char myname[MAXHOSTNAMELEN + 1], namebuf[NI_MAXHOST], abuf[256];
- const char *addrstr;
- int err, quiet = 0;
-
- argc--; argv++;
- while (argc) {
- if ((strcmp(*argv, "--quiet") == 0) ||
- (strcmp(*argv, "-q") == 0)) {
- quiet++;
- } else
- break;
- argc--; argv++;
- }
-
- if (argc >= 1) {
- strlcpy(myname, *argv, sizeof(myname));
- } else {
- if(gethostname(myname, MAXHOSTNAMELEN)) {
- perror("gethostname failure");
- exit(1);
- }
- }
-
- myname[MAXHOSTNAMELEN] = '\0'; /* for safety */
-
- /* Look up the address... */
- if (!quiet)
- printf("Hostname: %s\n", myname);
-
- memset(&hint, 0, sizeof(hint));
- hint.ai_flags = AI_CANONNAME;
- err = getaddrinfo(myname, 0, &hint, &ai);
- if (err) {
- fprintf(stderr,
- "Could not look up address for hostname '%s' - fatal\n",
- myname);
- exit(2);
- }
-
- if (!quiet) {
- addrstr = inet_ntop(ai->ai_family, ai->ai_addr, abuf, sizeof(abuf));
- if (addrstr != NULL)
- printf("Host address: %s\n", addrstr);
- }
-
- err = getnameinfo(ai->ai_addr, ai->ai_addrlen, namebuf, sizeof(namebuf),
- NULL, 0, NI_NAMEREQD);
- if (err && !quiet)
- fprintf(stderr, "Error looking up IP address\n");
-
- printf("%s%s\n", quiet ? "" : "FQDN: ", err ? ai->ai_canonname : namebuf);
-
- if (!quiet)
- printf("Resolve library appears to have passed the test\n");
-
- freeaddrinfo(ai);
- return 0;
-}

View File

@ -1,861 +0,0 @@
From 1de586b414104a447a50ffb6f81c2f57ed3d3a34 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Sat, 15 Feb 2020 20:34:23 -0500
Subject: [PATCH] Replace gssrpc tests with a Python script
Replace the dejagnu RPC test framework with a short Python script to
do the same tests as fullrun.exp and gsserr.exp. Modify the server
test program to facilitate use by k5test.py.
expire.exp, together with a comment in the client test program, was
designed to test a libdb2 btree bug via the gssrpc server-side
authentication code. That code was subsequently changed not to use
libdb2, before it was merged into the main krb5 tree (in revision 1.23
of svc_auth_gssapi.c, according to the changelog removed in commit
2a43d772be1e45faa8e488d436b6e867371563fb). Remove the comment and do
not replace that test sequence.
[rharwood@redhat.com: .gitignore]
---
src/configure.ac | 2 -
src/lib/rpc/unit-test/Makefile.in | 36 +--
src/lib/rpc/unit-test/client.c | 26 ---
src/lib/rpc/unit-test/config/unix.exp | 176 --------------
src/lib/rpc/unit-test/lib/helpers.exp | 234 -------------------
src/lib/rpc/unit-test/rpc_test.0/expire.exp | 49 ----
src/lib/rpc/unit-test/rpc_test.0/fullrun.exp | 91 --------
src/lib/rpc/unit-test/rpc_test.0/gsserr.exp | 30 ---
src/lib/rpc/unit-test/server.c | 13 +-
src/lib/rpc/unit-test/t_rpc.py | 29 +++
10 files changed, 41 insertions(+), 645 deletions(-)
delete mode 100644 src/lib/rpc/unit-test/config/unix.exp
delete mode 100644 src/lib/rpc/unit-test/lib/helpers.exp
delete mode 100644 src/lib/rpc/unit-test/rpc_test.0/expire.exp
delete mode 100644 src/lib/rpc/unit-test/rpc_test.0/fullrun.exp
delete mode 100644 src/lib/rpc/unit-test/rpc_test.0/gsserr.exp
create mode 100644 src/lib/rpc/unit-test/t_rpc.py
diff --git a/src/configure.ac b/src/configure.ac
index 29be532cb..aafc462f9 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1102,8 +1102,6 @@ extern void endrpcent();],
AC_MSG_RESULT($k5_cv_type_endrpcent)
AC_DEFINE_UNQUOTED(ENDRPCENT_TYPE, $k5_cv_type_endrpcent, [Define as return type of endrpcent])
K5_GEN_FILE(include/gssrpc/types.h:include/gssrpc/types.hin)
-PASS=tcp
-AC_SUBST(PASS)
# for pkinit
AC_ARG_ENABLE([pkinit],
diff --git a/src/lib/rpc/unit-test/Makefile.in b/src/lib/rpc/unit-test/Makefile.in
index 0b6e5203d..309ae2b21 100644
--- a/src/lib/rpc/unit-test/Makefile.in
+++ b/src/lib/rpc/unit-test/Makefile.in
@@ -16,10 +16,6 @@ server: server.o rpc_test_svc.o $(GSSRPC_DEPLIBS) $(KRB5_BASE_DEPLIBS)
client.o server.o: rpc_test.h
-runenv.exp: Makefile
- $(RUN_SETUP); for i in $(RUN_VARS); do \
- eval echo "set env\($$i\) \$$$$i"; done > runenv.exp
-
# If rpc_test.h and rpc_test_*.c do not work on your system, you can
# try using rpcgen by uncommenting these lines (be sure to uncomment
# then in the generated not Makefile.in).
@@ -34,37 +30,9 @@ runenv.exp: Makefile
# rm -f rpc_test.h rpc_test_clnt.c rpc_test_svc.c
#
-check unit-test: unit-test-@DO_TEST@
-
-unit-test-:
- @echo "+++"
- @echo "+++ WARNING: lib/rpc unit tests not run."
- @echo "+++ Either tcl, runtest, or Perl is unavailable."
- @echo "+++"
- @echo 'Skipped rpc tests: runtest or Perl not found' >> $(SKIPTESTS)
-
-unit-test-ok: unit-test-body
-
-PASS=@PASS@
-unit-test-body: runenv.sh runenv.exp
- $(RM) krb5cc_rpc_test_*
- $(ENV_SETUP) $(VALGRIND) $(START_SERVERS)
- RPC_TEST_KEYTAB=/tmp/rpc_test_keytab.$$$$ ; export RPC_TEST_KEYTAB ; \
- trap "echo Failed, cleaning up... ; rm -f $$RPC_TEST_KEYTAB ; $(ENV_SETUP) $(STOP_SERVERS) ; trap '' 0 ; exit 1" 0 1 2 3 14 15 ; \
- if $(ENV_SETUP) \
- $(RUNTEST) SERVER=./server CLIENT=./client \
- KINIT=$(BUILDTOP)/clients/kinit/kinit \
- KDESTROY=$(BUILDTOP)/clients/kdestroy/kdestroy \
- PRIOCNTL_HACK=@PRIOCNTL_HACK@ VALGRIND="$(VALGRIND)" \
- PASS="$(PASS)" --tool rpc_test $(RUNTESTFLAGS) ; \
- then \
- echo Cleaning up... ; \
- rm -f $$RPC_TEST_KEYTAB krb5cc_rpc_test_* ; \
- $(ENV_SETUP) $(STOP_SERVERS) ; \
- trap 0 ; exit 0 ; \
- else exit 1 ; fi
+check-pytests:
+ $(RUNPYTEST) $(srcdir)/t_rpc.py $(PYTESTFLAGS)
clean:
$(RM) server client
- $(RM) dbg.log rpc_test.log rpc_test.sum runenv.exp
diff --git a/src/lib/rpc/unit-test/client.c b/src/lib/rpc/unit-test/client.c
index 5edde49df..c9a812bc5 100644
--- a/src/lib/rpc/unit-test/client.c
+++ b/src/lib/rpc/unit-test/client.c
@@ -231,32 +231,6 @@ main(argc, argv)
else
gssrpc_xdr_free(xdr_wrapstring, echo_resp);
- /*
- * Test fix for secure-rpc/586, part 1: btree keys must be
- * unique. Create another context from the same credentials; it
- * should have the same expiration time and will cause the server
- * to abort if the clients are not differentiated.
- *
- * Test fix for secure-rpc/586, part 2: btree keys cannot be
- * mutated in place. To test this: a second client, *with a
- * later expiration time*, must be run. The second client should
- * destroy itself *after* the first one; if the key-mutating bug
- * is not fixed, the second client_data will be in the btree
- * before the first, but its key will be larger; thus, when the
- * first client calls AUTH_DESTROY, the server won't find it in
- * the btree and call abort.
- *
- * For unknown reasons, running just a second client didn't
- * tickle the bug; the btree code seemed to guess which node to
- * look at first. Running a total of three clients does ticket
- * the bug. Thus, the full test sequence looks like this:
- *
- * kinit -l 20m user && client server test@ddn 200
- * sleep 1
- * kini -l 30m user && client server test@ddn 300
- * sleep 1
- * kinit -l 40m user && client server test@ddn 400
- */
if (! auth_once) {
tmp_auth = clnt->cl_auth;
clnt->cl_auth = auth_gssapi_create_default(clnt, target);
diff --git a/src/lib/rpc/unit-test/config/unix.exp b/src/lib/rpc/unit-test/config/unix.exp
deleted file mode 100644
index 18da62be4..000000000
--- a/src/lib/rpc/unit-test/config/unix.exp
+++ /dev/null
@@ -1,176 +0,0 @@
-#
-# $Id$
-#
-
-source runenv.exp
-
-set kill /bin/kill
-set sleep /bin/sleep
-set kinit $KINIT
-set kdestroy $KDESTROY
-
-set hostname [exec hostname]
-
-# Hack around Solaris 9 kernel race condition that causes last output
-# from a pty to get dropped.
-if { $PRIOCNTL_HACK } {
- catch {exec priocntl -s -c FX -m 30 -p 30 -i pid [getpid]}
- rename spawn oldspawn
- proc spawn { args } {
- upvar 1 spawn_id spawn_id
- set newargs {}
- set inflags 1
- set eatnext 0
- foreach arg $args {
- if { $arg == "-ignore" \
- || $arg == "-open" \
- || $arg == "-leaveopen" } {
- lappend newargs $arg
- set eatnext 1
- continue
- }
- if [string match "-*" $arg] {
- lappend newargs $arg
- continue
- }
- if { $eatnext } {
- set eatnext 0
- lappend newargs $arg
- continue
- }
- if { $inflags } {
- set inflags 0
- set newargs [concat $newargs {priocntl -e -c FX -p 0}]
- }
- lappend newargs $arg
- }
- set pid [eval oldspawn $newargs]
- return $pid
- }
-}
-
-if { [string length $VALGRIND] } {
- rename spawn valgrind_aux_spawn
- proc spawn { args } {
- global VALGRIND
- upvar 1 spawn_id spawn_id
- set newargs {}
- set inflags 1
- set eatnext 0
- foreach arg $args {
- if { $arg == "-ignore" \
- || $arg == "-open" \
- || $arg == "-leaveopen" } {
- lappend newargs $arg
- set eatnext 1
- continue
- }
- if [string match "-*" $arg] {
- lappend newargs $arg
- continue
- }
- if { $eatnext } {
- set eatnext 0
- lappend newargs $arg
- continue
- }
- if { $inflags } {
- set inflags 0
- # Only run valgrind for local programs, not
- # system ones.
-#&&![string match "/bin/sh" $arg] sh is used to start kadmind!
- if [string match "/" [string index $arg 0]]&&![string match "/bin/ls" $arg]&&![regexp {/kshd$} $arg] {
- set newargs [concat $newargs $VALGRIND]
- } elseif [string match "." [string index $arg 0]] {
- set newargs [concat $newargs $VALGRIND]
- }
- }
- lappend newargs $arg
- }
- set pid [eval valgrind_aux_spawn $newargs]
- return $pid
- }
-}
-
-# this will initialize the database and keytab
-load_lib "helpers.exp"
-
-proc rpc_test_version {} {
- global CLIENT
- global SERVER
-
- clone_output "$CLIENT version <unknown>"
- clone_output "$SERVER version <unknown>"
-}
-
-proc rpc_test_load {} {
- #
-}
-
-# rpc_test_exit -- clean up and exit
-proc rpc_test_exit {} {
- global server_id
- global server_pid
- global server_started
- global kill
-
- if {[catch {
- expect {
- -i $server_id
- eof {
- fail "server exited!"
- verbose $expect_out(buffer) 1
- }
- timeout { pass "server survived" }
- }
- } tmp]} {
- fail "server exited! (expect failed)"
- }
-}
-
-#
-# rpc_test_start -- start the rpc_test server running
-#
-proc rpc_test_start { } {
- global SERVER PROT
- global server_id
- global server_pid
- global server_started
- global server_port
- global env
-
- if [info exists server_pid] { rpc_test_exit }
-
- set env(KRB5_KTNAME) FILE:$env(RPC_TEST_KEYTAB)
-
- verbose "% $SERVER" 1
- set server_pid [spawn $SERVER $PROT]
- set server_id $spawn_id
- set server_started 1
- set server_port -1
-
- unset env(KRB5_KTNAME)
-
- set timeout 30
-
- expect {
- -re "port: (\[0-9\]*)\r\n" {
- set server_port $expect_out(1,string)
- }
- "running" { }
- eof {
- send_error "server exited!"
- verbose $expect_out(buffer) 1
- }
- timeout {
- send_error "server didn't start in $timeout seconds"
- verbose $expect_out(buffer) 1
- }
- }
-
-}
-
-set MULTIPASS {
- {tcp PROT=-t dummy=[rpc_test_start]}
- {udp PROT=-u dummy=[rpc_test_start]}
-}
diff --git a/src/lib/rpc/unit-test/lib/helpers.exp b/src/lib/rpc/unit-test/lib/helpers.exp
deleted file mode 100644
index eb2797c53..000000000
--- a/src/lib/rpc/unit-test/lib/helpers.exp
+++ /dev/null
@@ -1,234 +0,0 @@
-if {[info commands exp_version] != {}} {
- set exp_version_4 [regexp {^4} [exp_version]]
-} else {
- set exp_version_4 [regexp {^4} [expect_version]]
-}
-
-# Backward compatibility until we're using expect 5 everywhere
-if {$exp_version_4} {
- global wait_error_index wait_errno_index wait_status_index
- set wait_error_index 0
- set wait_errno_index 1
- set wait_status_index 1
-} else {
- set wait_error_index 2
- set wait_errno_index 3
- set wait_status_index 3
-}
-
-proc set_from_env {varname default_value} {
- global env
- upvar $varname v
-
- if [info exists env($varname)] {
- set v $env($varname)
- } else {
- set v $default_value
- }
-}
-proc expect_tcl_prompt {} {
- global kadmin_tcl_spawn_id
- expect {
- -i $kadmin_tcl_spawn_id
- -re "^% $" { }
- -re . { perror "unexpected output {$expect_out(buffer)} from subprocess, expecting tcl prompt" }
- timeout { perror "timeout waiting for tcl prompt" }
- eof { perror "eof from subprocess when expecting tcl prompt" }
- }
-}
-proc send_tcl_cmd_await_echo {cmd} {
- global kadmin_tcl_spawn_id
- send -i $kadmin_tcl_spawn_id "$cmd\n"
- expect {
- -i $kadmin_tcl_spawn_id
- -ex "$cmd\r\n" { }
- timeout { perror "timeout waiting for tcl subprocess to echo input" }
- eof { perror "eof waiting for tcl subprocess to echo input" }
- }
-}
-proc expect_kadm_ok {} {
- global kadmin_tcl_spawn_id
- expect {
- -i $kadmin_tcl_spawn_id
- -re "^OK KADM5_OK \[^\n\]*\n" {}
- -re "^ERROR \[^\n\]*\n" { perror "kadmin tcl subprocess reported unexpected error" }
- -re "^marshall_new_creds: \[^\n\]*\n" { exp_continue }
- -re "^gssapi_\[^\n\]*\n" { exp_continue }
- -re "^\r?\n" { exp_continue }
- eof { perror "kadmin tcl subprocess died" }
- default { perror "didn't get ok back" }
- }
-}
-proc setup_database {} {
- global env spawn_id kadmin_tcl_spawn_id TESTDIR CANON_HOST
-
- # XXXXX
- set_from_env TOP {/x/x/x/x/x}
- send_user "TOP=$TOP\n"
-
- set_from_env TESTDIR $env(TOP)/testing
- set_from_env CLNTTCL $TESTDIR/util/kadm5_clnt_tcl
- set_from_env TCLUTIL $TESTDIR/tcl/util.t
- set env(TCLUTIL) $TCLUTIL
- set env(PATH) "$TOP/install/admin:$env(PATH)"
-
- # $VERBOSE ?
-
- if [info exists spawn_id] { set x $spawn_id }
- spawn $CLNTTCL
- set kadmin_tcl_spawn_id $spawn_id
- if [info exists x] { set spawn_id $x }
-
- expect_tcl_prompt
- # tcl 8.4 for some reason screws up autodetection of output EOL
- # translation. Work around it for now.
- send_tcl_cmd_await_echo "if { \[info commands fconfigure\] != \"\" } { fconfigure stdout -translation lf }"
- expect_tcl_prompt
- send_tcl_cmd_await_echo "source {$TCLUTIL}"
- expect_tcl_prompt
- send_tcl_cmd_await_echo "set h {$CANON_HOST}"
- expect {
- -ex "$CANON_HOST\r\n" { }
- timeout { perror "timeout waiting for subprocess" }
- eof { perror "eof from subprocess" }
- }
- expect_tcl_prompt
-
- send_tcl_cmd_await_echo {kadm5_init admin admin $KADM5_ADMIN_SERVICE null $KADM5_STRUCT_VERSION $KADM5_API_VERSION_2 server_handle}
- expect_kadm_ok
- expect "^% "
- send_tcl_cmd_await_echo {kadm5_create_principal $server_handle [simple_principal server/$h] {KADM5_PRINCIPAL} admin}
- expect_kadm_ok
- expect "^% "
- send_tcl_cmd_await_echo {kadm5_randkey_principal $server_handle server/$h key null}
- expect_kadm_ok
- expect "^% "
- send_tcl_cmd_await_echo {kadm5_create_principal $server_handle [simple_principal notserver/$h] {KADM5_PRINCIPAL} admin}
- expect_kadm_ok
- expect "^% "
- send_tcl_cmd_await_echo {kadm5_randkey_principal $server_handle notserver/$h key null}
- expect_kadm_ok
- expect "^% "
- send_tcl_cmd_await_echo {kadm5_destroy $server_handle}
- expect_kadm_ok
- expect "^% "
- wait -nowait -i $spawn_id
- close -i $spawn_id
-}
-
-if ![info exists CANON_HOST] {
- set CANON_HOST $env(QUALNAME)
- setup_database
- file delete $env(RPC_TEST_KEYTAB)
- exec $env(TOP)/cli/kadmin -p admin -w admin ktadd -k $env(RPC_TEST_KEYTAB) server/$CANON_HOST
-}
-
-
-proc kinit {princ pass lifetime} {
- global kinit
- global wait_error_index wait_errno_index wait_status_index
-
- spawn -noecho $kinit -5 -l $lifetime $princ
- expect {
- -re "Password for $princ.*: " { send "$pass\n"; expect eof }
- timeout { perror "Timeout waiting for kinit"; close }
- eof
- }
-
- set ret [wait]
- if {[lindex $ret $wait_error_index] == -1} {
- perror \
- "wait(kinit $princ) returned error [lindex $ret $wait_errno_index]"
- } else {
- if {[lindex $ret $wait_status_index] != 0} {
- perror \
- "kinit $princ failed with [lindex $ret $wait_status_index]"
- }
- }
-}
-
-proc flush_server {} {
- global server_id
- global expect_out
-
- verbose "flushing server output" 1
-
- while {1} {
- set timeout 5
-
- expect {
- -i $server_id
- -re "^.+$" {
- verbose "server output: $expect_out(buffer)"
- }
- timeout { break }
- }
- }
-}
-
-proc start_client {testname ccname user password lifetime count
- {target ""}} {
- global env CLIENT PROT hostname server_port spawn_id verbose
-
- if {$target == ""} {
- set target "server@$hostname"
- }
-
- set env(KRB5CCNAME) FILE:[pwd]/krb5cc_rpc_test_$ccname
- kinit $user $password $lifetime
-
- if {$verbose > 0} {
- spawn $CLIENT -a 1 -s 1 -m 1 $PROT $hostname $server_port $target $count
- } else {
- spawn $CLIENT $PROT $hostname $server_port $target $count
- }
-
- verbose "$testname: client $ccname started"
-
- unset env(KRB5CCNAME)
-}
-
-proc eof_client {testname ccname id status} {
- verbose "$testname: eof'ing for client $ccname" 1
-
- expect {
- -i $id
- -re "^marshall_new_creds\[^\n\]*\n" { exp_continue }
- -re "^gssapi_\[^\n\]*\n" { exp_continue }
- -re "^\r?\n" { exp_continue }
- eof { verbose $expect_out(buffer) 1 }
- timeout {
- fail "$testname: timeout waiting for client $ccname to exit"
- }
- }
- wait_client $testname $ccname $id $status
-}
-
-
-proc wait_client {testname ccname id status} {
- global env
- global kill
- global kdestroy
- global wait_error_index wait_errno_index wait_status_index
-
- verbose "$testname: waiting for client $ccname" 1
-
- set ret [wait -i $id]
- if {[lindex $ret $wait_error_index] == -1} {
- fail \
- "$testname: wait $ccname returned error [lindex $ret $wait_errno_index]"
- } else {
- if {[lindex $ret $wait_status_index] == $status} {
- pass "$testname: client $ccname"
- } else {
- fail "$testname: client $ccname: unexpected return status [lindex $ret $wait_status_index], should be $status."
- }
- }
-
- set env(KRB5CCNAME) FILE:[pwd]/krb5cc_rpc_test_$ccname
- if {[catch "exec $kdestroy -5"] != 0} {
- perror "$testname: cannot destroy client $ccname ccache"
- }
-
- unset env(KRB5CCNAME)
-}
diff --git a/src/lib/rpc/unit-test/rpc_test.0/expire.exp b/src/lib/rpc/unit-test/rpc_test.0/expire.exp
deleted file mode 100644
index e19cca0ef..000000000
--- a/src/lib/rpc/unit-test/rpc_test.0/expire.exp
+++ /dev/null
@@ -1,49 +0,0 @@
-set timeout 40
-
-load_lib "helpers.exp"
-
-global server_started
-
-proc expired {} {
- global spawn_id server_id
-
- start_client expired expired testuser notathena -1m 100
- eof_client expired expired $spawn_id 2
-
- expect {
- -i $server_id
- -re "rpc_test server: Authen.*failed:.*credential.*expired" { pass "expired" }
- timeout { fail "expired: timeout waiting for expired creds error" }
- }
-
- flush_server
-}
-
-# This test doesn't work after #6948, because the client won't try to
-# authenticate using an expired TGT.
-#if { $server_started } {expired }
-
-proc overlap {} {
- global spawn_id
-
- start_client expire 1 testuser notathena 20m 100
- set client1_id $spawn_id
- flush_server
-
- start_client expire 2 testuser notathena 40m 300
- set client2_id $spawn_id
- flush_server
-
- start_client expire 3 testuser notathena 60m 500
- set client3_id $spawn_id
- flush_server
-
- eof_client expire 1 $client1_id 0
- eof_client expire 2 $client2_id 0
- eof_client expire 3 $client3_id 0
-
- flush_server
-}
-if { $server_started } {overlap}
-
-
diff --git a/src/lib/rpc/unit-test/rpc_test.0/fullrun.exp b/src/lib/rpc/unit-test/rpc_test.0/fullrun.exp
deleted file mode 100644
index 73083de1f..000000000
--- a/src/lib/rpc/unit-test/rpc_test.0/fullrun.exp
+++ /dev/null
@@ -1,91 +0,0 @@
-set timeout 120
-
-load_lib "helpers.exp"
-
-global spawn_id
-global server_id
-global server_started
-
-if { !$server_started } {return}
-
-# Start the client and do a full run
-start_client "full run" fullrun testuser notathena 8h 1026
-set client_id $spawn_id
-
-#
-# test: did we get 11 dots?
-#
-verbose "Starting RPC echo test. This will take about 50 seconds.\n"
-
-set ver_line "rpc_test server: bad verifier\[^\r\n\]*\[\r\n]+"
-
-set dots 0
-set server_lines 0
-while {1} {
- expect {
- -i $server_id
- -re $ver_line {
- verbose "Got line from server."
- incr server_lines
- }
- default {
- exp_continue
- }
-
- -i $client_id
- . {
- incr dots
- verbose "$expect_out(buffer)" 1
- if ($dots==11) { break }
- }
- eof {
- #
- # test: was the exit status right?
- #
- wait_client "full run" fullrun $client_id 0
- break
- }
-
- timeout {
- verbose "Timeout waiting for dot\n" 1
- fail "full run: timeout waiting for dot"
- break
- }
- }
-}
-if {$dots==11} {
- pass "fullrun: echo test"
-} else {
- fail "fullrun: echo test: expected 11 dots, got $dots"
-}
-
-#
-# test: server logged four bad verifiers?
-#
-verbose "full run: checking server output"
-
-# Small timeout, since the server should have already printed everything
-set timeout 5
-
-while {$server_lines < 4} {
- expect {
- -i $server_id
- -re $ver_line {
- incr server_lines
- }
- -re ".+\r\n" {
- verbose "Unexpected server output: $expect_out(buffer)"
- }
- default {
- break
- }
- }
-}
-
-if {$server_lines == 4} {
- pass "fullrun: bad verifiers"
-} else {
- fail "fullrun: expected four bad verifiers, got $server_lines"
-}
-
-flush_server
diff --git a/src/lib/rpc/unit-test/rpc_test.0/gsserr.exp b/src/lib/rpc/unit-test/rpc_test.0/gsserr.exp
deleted file mode 100644
index 005971989..000000000
--- a/src/lib/rpc/unit-test/rpc_test.0/gsserr.exp
+++ /dev/null
@@ -1,30 +0,0 @@
-set timeout 30
-
-load_lib "helpers.exp"
-
-global spawn_id
-global server_id
-global server_started
-global hostname
-
-if { !$server_started } {return}
-
-start_client "gss err" gsserr testuser notathena 8h 1026 notserver@$hostname
-
-eof_client "gss err" gsserr $spawn_id 2
-
-#
-# test: server logged an authentication attempted failed?
-#
-verbose "gss err: checking server output"
-
-expect {
- -i $server_id
- -re "rpc_test server: Authent.*failed: .* not found in keytab" {
- pass "gss err: server logged auth error"
- }
- eof { fail "gss err: server exited" }
- timeout { fail "gss err: timeout waiting for server output" }
-}
-
-flush_server
diff --git a/src/lib/rpc/unit-test/server.c b/src/lib/rpc/unit-test/server.c
index 13e99bb06..c3bbcbf8c 100644
--- a/src/lib/rpc/unit-test/server.c
+++ b/src/lib/rpc/unit-test/server.c
@@ -37,7 +37,7 @@ static void rpc_test_badverf(gss_name_t client, gss_name_t server,
caddr_t data);
#ifndef SERVICE_NAME
-#define SERVICE_NAME "server"
+#define SERVICE_NAME "host"
#endif
static void usage()
@@ -120,7 +120,6 @@ main(int argc, char **argv)
prot == IPPROTO_TCP ? "tcp" : "udp");
exit(1);
}
- printf("port: %d\n", (int)transp->xp_port);
if (svcauth_gssapi_set_names(names, 0) == FALSE) {
fprintf(stderr, "unable to set gssapi names\n");
@@ -144,6 +143,8 @@ main(int argc, char **argv)
signal(SIGTERM, handlesig);
#endif
printf("running\n");
+ printf("port: %d\n", (int)transp->xp_port);
+ fflush(stdout);
svc_run();
fprintf(stderr, "svc_run returned");
@@ -177,6 +178,7 @@ static void rpc_test_badverf(gss_name_t client, gss_name_t server,
inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr),
ntohs(rqst->rq_xprt->xp_raddr.sin_port),
(int) server_name.length, (char *) server_name.value);
+ fflush(stdout);
(void) gss_release_buffer(&minor_stat, &client_name);
(void) gss_release_buffer(&minor_stat, &server_name);
@@ -211,6 +213,7 @@ void rpc_test_badauth(OM_uint32 major, OM_uint32 minor,
printf("rpc_test server: Authentication attempt failed: %s", a);
log_badauth_display_status(major, minor);
printf("\n");
+ fflush(stdout);
}
void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
@@ -220,6 +223,7 @@ void log_miscerr(struct svc_req *rqst, struct rpc_msg *msg,
a = inet_ntoa(rqst->rq_xprt->xp_raddr.sin_addr);
printf("Miscellaneous RPC error: %s, %s\n", a, error);
+ fflush(stdout);
}
void log_badauth_display_status(OM_uint32 major, OM_uint32 minor)
@@ -243,10 +247,12 @@ void log_badauth_display_status_1(OM_uint32 code, int type, int rec)
log_badauth_display_status_1(gssstat,GSS_C_GSS_CODE,1);
log_badauth_display_status_1(minor_stat,
GSS_C_MECH_CODE, 1);
- } else
+ } else {
printf("GSS-API authentication error %.*s: "
"recursive failure!\n", (int) msg.length,
(char *)msg.value);
+ }
+ fflush(stdout);
return;
}
@@ -256,4 +262,5 @@ void log_badauth_display_status_1(OM_uint32 code, int type, int rec)
if (!msg_ctx)
break;
}
+ fflush(stdout);
}
diff --git a/src/lib/rpc/unit-test/t_rpc.py b/src/lib/rpc/unit-test/t_rpc.py
new file mode 100644
index 000000000..4e565d25c
--- /dev/null
+++ b/src/lib/rpc/unit-test/t_rpc.py
@@ -0,0 +1,29 @@
+import re
+
+from k5test import *
+
+realm = K5Realm()
+
+server = realm.start_server(['./server', '-t'], 'running')
+line = server.stdout.readline()
+portstr = re.match(r'^port: (\d+)$', line).group(1)
+
+realm.run(['./client', '-t', hostname, portstr, 'host@' + hostname, '1026'],
+ expected_msg='...........')
+
+for i in range(4):
+ line = server.stdout.readline()
+ if 'rpc_test server: bad verifier from user@KRBTEST.COM at ' not in line:
+ fail('unexpected server message: ' + line)
+ output(line)
+
+realm.addprinc('nokey/' + hostname)
+
+realm.run(['./client', '-t', hostname, portstr, 'nokey@' + hostname, '1026'],
+ expected_code=2)
+
+line = server.stdout.readline()
+if 'rpc_test server: Authentication attempt failed: ' not in line:
+ fail('unexpected server message: ' + line)
+
+success('gssrpc auth_gssapi tests')

View File

@ -1,41 +0,0 @@
From 35d041e432ea6d4611b232cc9bb72a36552eda27 Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Wed, 4 Mar 2020 17:18:51 -0500
Subject: [PATCH] Use two queues for concurrent t_otp.py daemons
t_otp.py occasionally fails during the #8708 regression test, reading
a true answer instead of the expected false answer during the first
verify() call. Most likely the daemons are writing their answers to
the shared queue out of order. Use a separate queue for the second
daemon to ensure correct correlation of results.
(cherry picked from commit c03f67eefec05db19e84e889fab7c25904929633)
---
src/tests/t_otp.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/tests/t_otp.py b/src/tests/t_otp.py
index cba871a0f..c3b820a41 100755
--- a/src/tests/t_otp.py
+++ b/src/tests/t_otp.py
@@ -256,16 +256,17 @@ verify(daemon, queue, True, realm.user_princ, 'accept')
## tokens configured, with the first rejecting and the second
## accepting. With the bug, the KDC incorrectly rejects the request
## and then performs invalid memory accesses, most likely crashing.
+queue2 = Queue()
daemon1 = UDPRadiusDaemon(args=(server_addr, secret_file, 'accept1', queue))
-daemon2 = UnixRadiusDaemon(args=(socket_file, None, 'accept2', queue))
+daemon2 = UnixRadiusDaemon(args=(socket_file, None, 'accept2', queue2))
daemon1.start()
queue.get()
daemon2.start()
-queue.get()
+queue2.get()
oconf = '[' + otpconfig_1('udp') + ', ' + otpconfig_1('unix') + ']'
realm.run([kadminl, 'setstr', realm.user_princ, 'otp', oconf])
realm.kinit(realm.user_princ, 'accept2', flags=flags)
verify(daemon1, queue, False, realm.user_princ.split('@')[0], 'accept2')
-verify(daemon2, queue, True, realm.user_princ, 'accept2')
+verify(daemon2, queue2, True, realm.user_princ, 'accept2')
success('OTP tests')

View File

@ -1,4 +1,4 @@
From 3a83d2b4c2a3eea5dde8de883ee9b41630a6a487 Mon Sep 17 00:00:00 2001
From 146967416993f66c3ba32cbf3881e43e7bc1ed1c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 9 Nov 2018 15:12:21 -0500
Subject: [PATCH] [downstream] FIPS with PRNG and RADIUS and MD4
@ -39,10 +39,10 @@ Last-updated: krb5-1.17
15 files changed, 151 insertions(+), 33 deletions(-)
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index 1d2aa7f68..3a8b9cf47 100644
index e4e2443ed..af3df5871 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -331,6 +331,12 @@ The libdefaults section may contain any of the following relations:
@@ -330,6 +330,12 @@ The libdefaults section may contain any of the following relations:
qualification of shortnames, set this relation to the empty string
with ``qualify_shortname = ""``. (New in release 1.18.)
@ -111,7 +111,7 @@ index 2da691329..f79679a0b 100644
state->data = (void *) malloc(16);
if (state->data == NULL)
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
index a65d57b7a..6ccaca94a 100644
index bc87c6f42..9bf407899 100644
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
@@ -66,6 +66,9 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
@ -349,7 +349,7 @@ index 03c613716..d89982a13 100644
return retval;
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
index 996a89372..312dc8258 100644
index 0143d155a..223ffd730 100644
--- a/src/lib/krad/internal.h
+++ b/src/lib/krad/internal.h
@@ -39,6 +39,8 @@
@ -475,7 +475,7 @@ index c597174b6..fc2d24800 100644
}
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
index 437f7e91a..0f90443ce 100644
index c96a9b4ee..eca432424 100644
--- a/src/lib/krad/remote.c
+++ b/src/lib/krad/remote.c
@@ -263,7 +263,7 @@ on_io_write(krad_remote *rr)

View File

@ -1,4 +1,4 @@
From 0ef71d2bef3efcb38b20fc8b3050944286ada726 Mon Sep 17 00:00:00 2001
From 3af536f114e1c1b33b1579f9f16bbb3f497d4a1d Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 26 Mar 2019 18:51:10 -0400
Subject: [PATCH] [downstream] Remove 3des support
@ -8,11 +8,11 @@ des3-hmac-sha1, des3-cbc-sha1-kd). Update all tests and documentation
to user other enctypes. Mark the 3DES enctypes UNSUPPORTED and retain
their constants.
Last-updated: 1.18-beta2
Last-updated: 1.19-beta1
---
doc/admin/advanced/retiring-des.rst | 11 +
doc/admin/conf_files/kdc_conf.rst | 7 +-
doc/admin/enctypes.rst | 13 +-
doc/admin/enctypes.rst | 10 +-
doc/admin/troubleshoot.rst | 9 +-
doc/appdev/refs/macros/index.rst | 1 -
doc/conf.py | 2 +-
@ -28,7 +28,7 @@ Last-updated: 1.18-beta2
src/lib/crypto/builtin/des/Makefile.in | 80 ----
src/lib/crypto/builtin/des/d3_aead.c | 133 ------
src/lib/crypto/builtin/des/d3_kysched.c | 51 ---
src/lib/crypto/builtin/des/deps | 148 -------
src/lib/crypto/builtin/des/deps | 150 -------
src/lib/crypto/builtin/des/des_int.h | 285 -------------
src/lib/crypto/builtin/des/des_keys.c | 40 --
src/lib/crypto/builtin/des/destest.c | 240 -----------
@ -45,7 +45,7 @@ Last-updated: 1.18-beta2
src/lib/crypto/builtin/des/t_verify.c | 395 ------------------
src/lib/crypto/builtin/des/weak_key.c | 86 ----
.../crypto/builtin/enc_provider/Makefile.in | 6 +-
src/lib/crypto/builtin/enc_provider/deps | 12 -
src/lib/crypto/builtin/enc_provider/deps | 13 -
src/lib/crypto/builtin/enc_provider/des3.c | 105 -----
src/lib/crypto/crypto_tests/t_cf2.expected | 1 -
src/lib/crypto/crypto_tests/t_cf2.in | 5 -
@ -83,7 +83,6 @@ Last-updated: 1.18-beta2
.../api.current/randkey-principal-v2.exp | 4 +-
src/lib/krb5/krb/init_ctx.c | 3 -
src/lib/krb5/krb/s4u_creds.c | 2 -
src/lib/krb5/krb/t_copy_context.c | 2 +-
src/lib/krb5/krb/t_etypes.c | 48 +--
src/lib/krb5/os/t_trace.c | 4 +-
src/lib/krb5/os/t_trace.ref | 2 +-
@ -106,7 +105,7 @@ Last-updated: 1.18-beta2
src/tests/t_salt.py | 5 +-
src/util/k5test.py | 7 -
.../leash/htmlhelp/html/Encryption_Types.htm | 13 -
96 files changed, 163 insertions(+), 4834 deletions(-)
95 files changed, 160 insertions(+), 4835 deletions(-)
delete mode 100644 src/lib/crypto/builtin/des/ISSUES
delete mode 100644 src/lib/crypto/builtin/des/Makefile.in
delete mode 100644 src/lib/crypto/builtin/des/d3_aead.c
@ -135,7 +134,7 @@ Last-updated: 1.18-beta2
delete mode 100644 src/lib/crypto/openssl/enc_provider/des3.c
diff --git a/doc/admin/advanced/retiring-des.rst b/doc/admin/advanced/retiring-des.rst
index 4a964c15c..cb6258d77 100644
index 38f76d3f4..d5e3c30c0 100644
--- a/doc/admin/advanced/retiring-des.rst
+++ b/doc/admin/advanced/retiring-des.rst
@@ -10,6 +10,13 @@ ability have rendered DES vulnerable to brute force attacks on its 56-bit
@ -164,19 +163,19 @@ index 4a964c15c..cb6258d77 100644
-------------
diff --git a/doc/admin/conf_files/kdc_conf.rst b/doc/admin/conf_files/kdc_conf.rst
index 9759756a2..cf8a12547 100644
index 1dc958d62..3a72aabef 100644
--- a/doc/admin/conf_files/kdc_conf.rst
+++ b/doc/admin/conf_files/kdc_conf.rst
@@ -843,8 +843,6 @@ Encryption types marked as "weak" are available for compatibility but
not recommended for use.
@@ -848,8 +848,6 @@ Encryption types marked as "weak" and "deprecated" are available for
compatibility but not recommended for use.
==================================================== =========================================================
-des3-cbc-raw Triple DES cbc mode raw (weak)
-des3-cbc-sha1 des3-hmac-sha1 des3-cbc-sha1-kd Triple DES cbc mode with HMAC/sha1
-des3-cbc-sha1 des3-hmac-sha1 des3-cbc-sha1-kd Triple DES cbc mode with HMAC/sha1 (deprecated)
aes256-cts-hmac-sha1-96 aes256-cts aes256-sha1 AES-256 CTS mode with 96-bit SHA-1 HMAC
aes128-cts-hmac-sha1-96 aes128-cts aes128-sha1 AES-128 CTS mode with 96-bit SHA-1 HMAC
aes256-cts-hmac-sha384-192 aes256-sha2 AES-256 CTS mode with 192-bit SHA-384 HMAC
@@ -853,7 +851,6 @@ arcfour-hmac rc4-hmac arcfour-hmac-md5 RC4 with HMAC/MD5
@@ -858,7 +856,6 @@ arcfour-hmac rc4-hmac arcfour-hmac-md5 RC4 with HMAC/MD5 (deprecat
arcfour-hmac-exp rc4-hmac-exp arcfour-hmac-md5-exp Exportable RC4 with HMAC/MD5 (weak)
camellia256-cts-cmac camellia256-cts Camellia-256 CTS mode with CMAC
camellia128-cts-cmac camellia128-cts Camellia-128 CTS mode with CMAC
@ -184,7 +183,7 @@ index 9759756a2..cf8a12547 100644
aes The AES family: aes256-cts-hmac-sha1-96, aes128-cts-hmac-sha1-96, aes256-cts-hmac-sha384-192, and aes128-cts-hmac-sha256-128
rc4 The RC4 family: arcfour-hmac
camellia The Camellia family: camellia256-cts-cmac and camellia128-cts-cmac
@@ -865,8 +862,8 @@ from the current list by prefixing them with a minus sign ("-").
@@ -870,8 +867,8 @@ from the current list by prefixing them with a minus sign ("-").
Types or families can be prefixed with a plus sign ("+") for symmetry;
it has the same meaning as just listing the type or family. For
example, "``DEFAULT -rc4``" would be the default set of encryption
@ -196,35 +195,35 @@ index 9759756a2..cf8a12547 100644
While **aes128-cts** and **aes256-cts** are supported for all Kerberos
diff --git a/doc/admin/enctypes.rst b/doc/admin/enctypes.rst
index caf6d9267..65b55cdb9 100644
index 047185afb..b08d954d9 100644
--- a/doc/admin/enctypes.rst
+++ b/doc/admin/enctypes.rst
@@ -129,7 +129,7 @@ enctype weak? krb5 Windows
des-cbc-crc weak <1.18 >=2000
des-cbc-md4 weak <1.18 ?
des-cbc-md5 weak <1.18 >=2000
-des3-cbc-sha1 >=1.1 none
+des3-cbc-sha1 <1.18 none
arcfour-hmac >=1.3 >=2000
arcfour-hmac-exp weak >=1.3 >=2000
aes128-cts-hmac-sha1-96 >=1.3 >=Vista
@@ -140,7 +140,10 @@ camellia128-cts-cmac >=1.9 none
camellia256-cts-cmac >=1.9 none
========================== ===== ======== =======
-krb5 releases 1.18 and later do not support single-DES. krb5 releases
-1.8 and later disable the single-DES enctypes by default. Microsoft
-Windows releases Windows 7 and later disable single-DES enctypes by
-default.
+krb5 releases 1.8 and later disable the single-DES enctypes by
+default. Microsoft Windows releases Windows 7 and later disable
+single-DES enctypes by default.
@@ -129,7 +129,7 @@ enctype weak? krb5 Windows
des-cbc-crc weak <1.18 >=2000
des-cbc-md4 weak <1.18 ?
des-cbc-md5 weak <1.18 >=2000
-des3-cbc-sha1 deprecated >=1.1 none
+des3-cbc-sha1 deprecated <1.18 none
arcfour-hmac deprecated >=1.3 >=2000
arcfour-hmac-exp weak >=1.3 >=2000
aes128-cts-hmac-sha1-96 >=1.3 >=Vista
@@ -148,9 +148,11 @@ default.
krb5 releases 1.17 and later flag deprecated encryption types
(including ``des3-cbc-sha1`` and ``arcfour-hmac``) in KDC logs and
kadmin output. krb5 release 1.19 issues a warning during initial
-authentication if ``des3-cbc-sha1`` is used. Future releases will
-disable ``des3-cbc-sha1`` by default and eventually remove support for
-it.
+authentication if ``des3-cbc-sha1`` is used.
+
+krb5 releases 1.18 and later remove single-DES and 3DES
+(downstream-only patch) enctype support. Microsoft Windows never
+supported 3DES.
Migrating away from older encryption types
diff --git a/doc/admin/troubleshoot.rst b/doc/admin/troubleshoot.rst
index 6a0c7f89b..263fc9c97 100644
index ade5e1f87..e4dc54f7e 100644
--- a/doc/admin/troubleshoot.rst
+++ b/doc/admin/troubleshoot.rst
@@ -73,11 +73,10 @@ credential verification failed: KDC has no support for encryption type
@ -244,7 +243,7 @@ index 6a0c7f89b..263fc9c97 100644
.. _err_cert_chain_cert_expired:
diff --git a/doc/appdev/refs/macros/index.rst b/doc/appdev/refs/macros/index.rst
index 68debe714..788d094bf 100644
index cebb6644c..4d51e795c 100644
--- a/doc/appdev/refs/macros/index.rst
+++ b/doc/appdev/refs/macros/index.rst
@@ -36,7 +36,6 @@ Public
@ -256,10 +255,10 @@ index 68debe714..788d094bf 100644
CKSUMTYPE_NIST_SHA.rst
CKSUMTYPE_RSA_MD4.rst
diff --git a/doc/conf.py b/doc/conf.py
index c32b2882a..5eeafc30f 100644
index 9226b8e01..19cf38326 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -272,7 +272,7 @@ else:
@@ -271,7 +271,7 @@ else:
rst_epilog += '''
.. |krb5conf| replace:: ``/etc/krb5.conf``
.. |defkeysalts| replace:: ``aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal``
@ -269,7 +268,7 @@ index c32b2882a..5eeafc30f 100644
.. |copy| unicode:: U+000A9
'''
diff --git a/doc/mitK5features.rst b/doc/mitK5features.rst
index 5d286b6ee..f4594ed13 100644
index 4954bb3aa..92ce2a772 100644
--- a/doc/mitK5features.rst
+++ b/doc/mitK5features.rst
@@ -37,7 +37,7 @@ Database backends: LDAP, DB2, LMDB
@ -282,7 +281,7 @@ index 5d286b6ee..f4594ed13 100644
Interoperability
----------------
diff --git a/src/Makefile.in b/src/Makefile.in
index 56c7a4e6f..70db82a30 100644
index f9270aba2..c958da60f 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -130,7 +130,7 @@ WINMAKEFILES=Makefile \
@ -304,10 +303,10 @@ index 56c7a4e6f..70db82a30 100644
##DOS## $(WCONFIG) config < $@.in > $@
##DOS##lib\crypto\builtin\camellia\Makefile: lib\crypto\builtin\camellia\Makefile.in $(MKFDEP)
diff --git a/src/configure.ac b/src/configure.ac
index 440a22bd9..d4e4da525 100644
index bd151ca26..27c2383d7 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1481,7 +1481,6 @@ V5_AC_OUTPUT_MAKEFILE(.
@@ -1480,7 +1480,6 @@ V5_AC_OUTPUT_MAKEFILE(.
lib/crypto lib/crypto/krb lib/crypto/$CRYPTO_IMPL
lib/crypto/$CRYPTO_IMPL/enc_provider
lib/crypto/$CRYPTO_IMPL/hash_provider
@ -316,7 +315,7 @@ index 440a22bd9..d4e4da525 100644
lib/crypto/$CRYPTO_IMPL/sha1 lib/crypto/$CRYPTO_IMPL/sha2
lib/crypto/$CRYPTO_IMPL/aes lib/crypto/$CRYPTO_IMPL/camellia
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index e9435c693..6355e6540 100644
index db80063eb..63e67a2ba 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -426,8 +426,8 @@ typedef struct _krb5_crypto_iov {
@ -365,10 +364,10 @@ index 8a4b87de1..d7f1d076b 100644
+ supported_enctypes = aes256-cts:normal aes128-cts:normal aes256-sha2:normal aes128-sha2:normal
}
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
index ba0ce0b71..e3352f9cc 100644
index 60f30c4f4..c65375aef 100644
--- a/src/kdc/kdc_util.c
+++ b/src/kdc/kdc_util.c
@@ -1103,8 +1103,6 @@ enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
@@ -1017,8 +1017,6 @@ enctype_name(krb5_enctype ktype, char *buf, size_t buflen)
name = "rsaEncryption-EnvOID";
else if (ktype == ENCTYPE_RSA_ES_OAEP_ENV)
name = "id-RSAES-OAEP-EnvOID";
@ -377,7 +376,7 @@ index ba0ce0b71..e3352f9cc 100644
else
return krb5_enctype_to_name(ktype, FALSE, buf, buflen);
@@ -1826,8 +1824,6 @@ krb5_boolean
@@ -1605,8 +1603,6 @@ krb5_boolean
enctype_requires_etype_info_2(krb5_enctype enctype)
{
switch(enctype) {
@ -470,7 +469,7 @@ index 157891103..000000000
-const?
diff --git a/src/lib/crypto/builtin/des/Makefile.in b/src/lib/crypto/builtin/des/Makefile.in
deleted file mode 100644
index ed25dab7c..000000000
index 54b329d0f..000000000
--- a/src/lib/crypto/builtin/des/Makefile.in
+++ /dev/null
@@ -1,80 +0,0 @@
@ -527,7 +526,7 @@ index ed25dab7c..000000000
-verify$(EXEEXT): t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \
- $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB)
- $(CC_LINK) -o $@ t_verify.$(OBJEXT) $(TOBJS) f_parity.$(OBJEXT) \
- -lcom_err $(SUPPORT_LIB)
- $(COM_ERR_LIB) $(SUPPORT_LIB)
-
-destest$(EXEEXT): destest.$(OBJEXT) $(TOBJS) $(SUPPORT_DEPLIB)
- $(CC_LINK) -o $@ destest.$(OBJEXT) $(TOBJS) $(SUPPORT_LIB)
@ -752,17 +751,18 @@ index ebd1050b1..000000000
-}
diff --git a/src/lib/crypto/builtin/des/deps b/src/lib/crypto/builtin/des/deps
deleted file mode 100644
index df2a31dac..000000000
index a1db1f36e..000000000
--- a/src/lib/crypto/builtin/des/deps
+++ /dev/null
@@ -1,148 +0,0 @@
@@ -1,150 +0,0 @@
-#
-# Generated makefile dependencies follow.
-#
-d3_aead.so d3_aead.po $(OUTPRE)d3_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
- $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
- $(srcdir)/../aes/aes.h $(srcdir)/../aes/brg_types.h \
- $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
- $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
@ -786,19 +786,20 @@ index df2a31dac..000000000
- $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \
- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \
- $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h $(srcdir)/../aes/aes.h \
- $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
- $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \
- $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
- $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
- $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \
- des_int.h des_keys.c
- $(srcdir)/../aes/brg_types.h $(srcdir)/../crypto_mod.h \
- $(srcdir)/../sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
- $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
- $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \
- $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-trace.h \
- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \
- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \
- $(top_srcdir)/include/socket-utils.h des_int.h des_keys.c
-f_aead.so f_aead.po $(OUTPRE)f_aead.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
- $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
- $(srcdir)/../aes/aes.h $(srcdir)/../aes/brg_types.h \
- $(srcdir)/../crypto_mod.h $(srcdir)/../sha2/sha2.h \
- $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \
- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \
- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \
@ -1489,7 +1490,7 @@ index 52114304e..000000000
-}
diff --git a/src/lib/crypto/builtin/des/doc/libdes.doc b/src/lib/crypto/builtin/des/doc/libdes.doc
deleted file mode 100644
index 19c03c1d3..000000000
index 6e9431ed2..000000000
--- a/src/lib/crypto/builtin/des/doc/libdes.doc
+++ /dev/null
@@ -1,208 +0,0 @@
@ -1644,7 +1645,7 @@ index 19c03c1d3..000000000
- by "*key", then after getting a new key, call the des_set_key()
- routine when needed.
-
- No meaningfull value is returned. Void is not used for compatibility
- No meaningful value is returned. Void is not used for compatibility
- with other compilers.
-
-
@ -3625,7 +3626,7 @@ index 7ff34eedc..000000000
-1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
diff --git a/src/lib/crypto/builtin/des/t_verify.c b/src/lib/crypto/builtin/des/t_verify.c
deleted file mode 100644
index f4332f5c0..000000000
index 4a19933ca..000000000
--- a/src/lib/crypto/builtin/des/t_verify.c
+++ /dev/null
@@ -1,395 +0,0 @@
@ -3956,7 +3957,7 @@ index f4332f5c0..000000000
- printf("%02x ",cipher_text[j]);
- printf("\n\n");
- if ( memcmp((char *)cipher_text, (char *)checksum, 8) ) {
- printf("verify: error in CBC cheksum\n");
- printf("verify: error in CBC checksum\n");
- exit(-1);
- }
- else
@ -4150,17 +4151,18 @@ index 3459e1d0e..af6276b96 100644
$(srcdir)/camellia.c \
$(srcdir)/rc4.c
diff --git a/src/lib/crypto/builtin/enc_provider/deps b/src/lib/crypto/builtin/enc_provider/deps
index 7a3324c44..c1201cc1a 100644
index ea4ffecd8..061289a91 100644
--- a/src/lib/crypto/builtin/enc_provider/deps
+++ b/src/lib/crypto/builtin/enc_provider/deps
@@ -1,18 +1,6 @@
@@ -1,19 +1,6 @@
#
# Generated makefile dependencies follow.
#
-des3.so des3.po $(OUTPRE)des3.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(srcdir)/../../krb/crypto_int.h \
- $(srcdir)/../aes/aes.h $(srcdir)/../crypto_mod.h $(srcdir)/../des/des_int.h \
- $(srcdir)/../aes/aes.h $(srcdir)/../aes/brg_types.h \
- $(srcdir)/../crypto_mod.h $(srcdir)/../des/des_int.h \
- $(srcdir)/../sha2/sha2.h $(top_srcdir)/include/k5-buf.h \
- $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \
- $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \
@ -4311,7 +4313,7 @@ index 73e2f8fbc..c4d23b506 100644
key1
key2
diff --git a/src/lib/crypto/crypto_tests/t_cksums.c b/src/lib/crypto/crypto_tests/t_cksums.c
index 4da14ea43..84408fb68 100644
index 8297fcbf5..3063d12ec 100644
--- a/src/lib/crypto/crypto_tests/t_cksums.c
+++ b/src/lib/crypto/crypto_tests/t_cksums.c
@@ -59,16 +59,6 @@ struct test {
@ -4593,7 +4595,7 @@ index ecc2e08c9..f5fbe8a2a 100644
"hmac-md5-rc4", { "hmac-md5-enc", "hmac-md5-earcfour" },
"Microsoft HMAC MD5",
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index ba693f8a4..5cc1f8e43 100644
index 19f808749..4bc430c7a 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -276,10 +276,6 @@ krb5_error_code krb5int_aes2_string_to_key(const struct krb5_keytypes *enc,
@ -4814,7 +4816,7 @@ index 157462526..863090beb 100644
- return 0;
-}
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index 451d5e035..9db181381 100644
index d6cc1b423..f44cb9170 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -86,7 +86,6 @@ krb5_k_verify_checksum
@ -5193,10 +5195,10 @@ index 1c439c2cd..000000000
- krb5int_default_free_state
-};
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
index c821cc830..c5bddb1e8 100644
index 636ee303f..e2c5e2b59 100644
--- a/src/lib/gssapi/krb5/accept_sec_context.c
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
@@ -1010,7 +1010,6 @@ kg_accept_krb5(minor_status, context_handle,
@@ -1039,7 +1039,6 @@ kg_accept_krb5(minor_status, context_handle,
}
switch (negotiated_etype) {
@ -5205,7 +5207,7 @@ index c821cc830..c5bddb1e8 100644
case ENCTYPE_ARCFOUR_HMAC_EXP:
/* RFC 4121 accidentally omits RC4-HMAC-EXP as a "not-newer"
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 2e2c775d6..f5b0fede6 100644
index a7e0e63ec..3bacdcd35 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -125,14 +125,14 @@ enum sgn_alg {
@ -5552,7 +5554,7 @@ index 85a9574f3..3ce2a90ce 100644
code = 0;
retval = GSS_S_BAD_SIG;
diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c
index ddb0af8fc..d6c71aeb8 100644
index 84f194988..32150f5e3 100644
--- a/src/lib/gssapi/krb5/util_crypt.c
+++ b/src/lib/gssapi/krb5/util_crypt.c
@@ -97,17 +97,6 @@ kg_setup_keys(krb5_context context, krb5_gss_ctx_id_rec *ctx, krb5_key subkey,
@ -5623,7 +5625,7 @@ index 2925c1c43..2f76c8b43 100644
if { ! [cmd {kadm5_destroy $server_handle}]} {
perror "$test: unexpected failure in destroy"
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index e7d67cca4..9a4741fa6 100644
index 21d5cb1ca..a8ba6fc5b 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -59,7 +59,6 @@
@ -5634,7 +5636,7 @@ index e7d67cca4..9a4741fa6 100644
ENCTYPE_ARCFOUR_HMAC,
ENCTYPE_CAMELLIA128_CTS_CMAC, ENCTYPE_CAMELLIA256_CTS_CMAC,
0
@@ -479,8 +478,6 @@ krb5int_parse_enctype_list(krb5_context context, const char *profkey,
@@ -456,8 +455,6 @@ krb5int_parse_enctype_list(krb5_context context, const char *profkey,
/* Set all enctypes in the default list. */
for (i = 0; default_list[i]; i++)
mod_list(default_list[i], sel, weak, &list);
@ -5644,10 +5646,10 @@ index e7d67cca4..9a4741fa6 100644
mod_list(ENCTYPE_AES256_CTS_HMAC_SHA1_96, sel, weak, &list);
mod_list(ENCTYPE_AES128_CTS_HMAC_SHA1_96, sel, weak, &list);
diff --git a/src/lib/krb5/krb/s4u_creds.c b/src/lib/krb5/krb/s4u_creds.c
index 504eb557f..fc5c886d6 100644
index 44d113e7c..966278578 100644
--- a/src/lib/krb5/krb/s4u_creds.c
+++ b/src/lib/krb5/krb/s4u_creds.c
@@ -287,8 +287,6 @@ verify_s4u2self_reply(krb5_context context,
@@ -288,8 +288,6 @@ verify_s4u2self_reply(krb5_context context,
assert(req_s4u_user != NULL);
switch (subkey->enctype) {
@ -5656,21 +5658,8 @@ index 504eb557f..fc5c886d6 100644
case ENCTYPE_ARCFOUR_HMAC:
case ENCTYPE_ARCFOUR_HMAC_EXP :
not_newer = TRUE;
diff --git a/src/lib/krb5/krb/t_copy_context.c b/src/lib/krb5/krb/t_copy_context.c
index 2970a8cea..fb82daf19 100644
--- a/src/lib/krb5/krb/t_copy_context.c
+++ b/src/lib/krb5/krb/t_copy_context.c
@@ -113,7 +113,7 @@ main(int argc, char **argv)
{
krb5_context ctx, ctx2;
krb5_plugin_initvt_fn *mods;
- const krb5_enctype etypes1[] = { ENCTYPE_DES3_CBC_SHA1, 0 };
+ const krb5_enctype etypes1[] = { ENCTYPE_AES128_CTS_HMAC_SHA256_128, 0 };
const krb5_enctype etypes2[] = { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
ENCTYPE_AES256_CTS_HMAC_SHA1_96, 0 };
krb5_prompt_type ptypes[] = { KRB5_PROMPT_TYPE_PASSWORD };
diff --git a/src/lib/krb5/krb/t_etypes.c b/src/lib/krb5/krb/t_etypes.c
index f609e938a..248ffea90 100644
index 90c9f626c..935aca12f 100644
--- a/src/lib/krb5/krb/t_etypes.c
+++ b/src/lib/krb5/krb/t_etypes.c
@@ -50,17 +50,6 @@ static struct {
@ -5787,7 +5776,7 @@ index e3d284631..586661bb7 100644
#define CKK_CAST3 (0x17)
#define CKK_CAST128 (0x18)
diff --git a/src/plugins/preauth/pkinit/pkinit_clnt.c b/src/plugins/preauth/pkinit/pkinit_clnt.c
index 1a642139a..2f0431991 100644
index 2817cc213..a385da7c3 100644
--- a/src/plugins/preauth/pkinit/pkinit_clnt.c
+++ b/src/plugins/preauth/pkinit/pkinit_clnt.c
@@ -212,14 +212,6 @@ pkinit_as_req_create(krb5_context context,
@ -5806,7 +5795,7 @@ index 1a642139a..2f0431991 100644
case DH_PROTOCOL:
TRACE_PKINIT_CLIENT_REQ_DH(context);
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
index 8064a07d0..a291889b0 100644
index 77d5c61fe..1f9868351 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
@@ -380,18 +380,6 @@ krb5_error_code server_process_dh
@ -5829,10 +5818,10 @@ index 8064a07d0..a291889b0 100644
* this functions takes in crypto specific representation of
* trustedCertifiers and creates a list of
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 8c7fd0cca..52976895b 100644
index d7d1593f4..0a67c44ef 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -5487,44 +5487,6 @@ cleanup:
@@ -5488,44 +5488,6 @@ cleanup:
return retval;
}
@ -5963,7 +5952,7 @@ index 2279202d3..96b0307d7 100644
/* initial key, w, x, y, T, S, K */
"8846F7EAEE8FB117AD06BDD830B7586C",
diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp
index b047ef1f7..4d8c917cd 100644
index 619fcce48..0a2ed723d 100644
--- a/src/tests/dejagnu/config/default.exp
+++ b/src/tests/dejagnu/config/default.exp
@@ -15,8 +15,6 @@ set timeout 100
@ -6042,7 +6031,7 @@ index b047ef1f7..4d8c917cd 100644
{allow_weak_crypto(kdc)=false}
{allow_weak_crypto(replica)=false}
{allow_weak_crypto(client)=false}
@@ -946,7 +911,6 @@ proc setup_kerberos_db { standalone } {
@@ -945,7 +910,6 @@ proc setup_kerberos_db { standalone } {
global REALMNAME KDB5_UTIL KADMIN_LOCAL KEY
global tmppwd hostname
global spawn_id
@ -6050,7 +6039,7 @@ index b047ef1f7..4d8c917cd 100644
global multipass_name last_passname_db
set failall 0
@@ -1143,48 +1107,6 @@ proc setup_kerberos_db { standalone } {
@@ -1142,48 +1106,6 @@ proc setup_kerberos_db { standalone } {
}
}
@ -6100,7 +6089,7 @@ index b047ef1f7..4d8c917cd 100644
# create the admin database lock file
diff --git a/src/tests/dejagnu/krb-standalone/kprop.exp b/src/tests/dejagnu/krb-standalone/kprop.exp
index f71ee8638..8c08cf42f 100644
index 661e3fd9a..2b8f60045 100644
--- a/src/tests/dejagnu/krb-standalone/kprop.exp
+++ b/src/tests/dejagnu/krb-standalone/kprop.exp
@@ -54,7 +54,7 @@ proc doit { } {
@ -6258,7 +6247,7 @@ index f71774cdc..d1857c433 100644
"3BB3AE288C12B3B9D06B208A4151B3B6",
"9AEA11A3BCF3C53F1F91F5A0BA2132E2501ADF5F3C28"
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
index c589adf2a..4fbdbec05 100644
index 3fa957ad2..2e01f46bc 100644
--- a/src/tests/t_authdata.py
+++ b/src/tests/t_authdata.py
@@ -174,7 +174,7 @@ realm.run([kvno, 'restricted'])
@ -6271,7 +6260,7 @@ index c589adf2a..4fbdbec05 100644
realm.run(['./forward'])
realm.run([kvno, realm.host_princ])
diff --git a/src/tests/t_etype_info.py b/src/tests/t_etype_info.py
index 2a052fc17..ace0edc3c 100644
index c982508d8..96e90a69d 100644
--- a/src/tests/t_etype_info.py
+++ b/src/tests/t_etype_info.py
@@ -1,6 +1,6 @@
@ -6282,7 +6271,7 @@ index 2a052fc17..ace0edc3c 100644
conf = {'libdefaults': {'allow_weak_crypto': 'true'},
'realms': {'$realm': {'supported_enctypes': supported_enctypes}}}
realm = K5Realm(create_host=False, get_creds=False, krb5_conf=conf)
@@ -24,9 +24,9 @@ def test_etinfo(princ, enctypes, expected_lines):
@@ -26,9 +26,9 @@ def test_etinfo(princ, enctypes, expected_lines):
# With no newer enctypes in the request, PA-ETYPE-INFO2,
# PA-ETYPE-INFO, and PA-PW-SALT appear in the AS-REP, each listing one
# key for the most preferred matching enctype.
@ -6295,7 +6284,7 @@ index 2a052fc17..ace0edc3c 100644
'asrep pw_salt KRBTEST.COMuser'])
# With a newer enctype in the request (even if it is not the most
@@ -37,9 +37,9 @@ test_etinfo('user', 'rc4 aes256-cts',
@@ -39,9 +39,9 @@ test_etinfo('user', 'rc4 aes256-cts',
# In preauth-required errors, PA-PW-SALT does not appear, but the same
# etype-info2 values are expected.
@ -6308,7 +6297,7 @@ index 2a052fc17..ace0edc3c 100644
test_etinfo('preauthuser', 'rc4 aes256-cts',
['error etype_info2 rc4-hmac KRBTEST.COMpreauthuser'])
@@ -48,8 +48,8 @@ test_etinfo('preauthuser', 'rc4 aes256-cts',
@@ -50,8 +50,8 @@ test_etinfo('preauthuser', 'rc4 aes256-cts',
# (to allow for preauth mechs which don't depend on long-term keys).
# An AS-REP cannot be generated without preauth as there is no reply
# key.
@ -6348,7 +6337,7 @@ index 2c825a692..f29e0d550 100755
realm.stop()
diff --git a/src/tests/t_mkey.py b/src/tests/t_mkey.py
index 99273c907..f84041ca4 100755
index 32f4070bc..da0ed1831 100755
--- a/src/tests/t_mkey.py
+++ b/src/tests/t_mkey.py
@@ -7,7 +7,6 @@ import struct
@ -6421,10 +6410,10 @@ index 65084bbf3..55ca89745 100755
# Test using different salt types in a principal's key list.
# Parameters from one key in the list must not leak over to later ones.
diff --git a/src/util/k5test.py b/src/util/k5test.py
index 442a4e4f7..eea92275d 100644
index 10f6b0a25..d234a5667 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -1299,13 +1299,6 @@ _passes = [
@@ -1277,13 +1277,6 @@ _passes = [
# No special settings; exercises AES256.
('default', None, None, None),

View File

@ -1,4 +1,4 @@
From 2c4d04d1da4dbb1a312db965f3392d7d0bc67a17 Mon Sep 17 00:00:00 2001
From 289615de0c73969574e3d48611deda66989c36c0 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:30:53 -0400
Subject: [PATCH] [downstream] SELinux integration
@ -67,7 +67,7 @@ Last-updated: krb5-1.18-beta1
create mode 100644 src/util/support/selinux.c
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 59621e3e7..398eca7e4 100644
index ca9fcf664..5afb96e58 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -85,6 +85,7 @@ AC_SUBST_FILE(libnodeps_frag)
@ -78,7 +78,7 @@ index 59621e3e7..398eca7e4 100644
KRB5_LIB_PARAMS
KRB5_AC_INITFINI
KRB5_AC_ENABLE_THREADS
@@ -1739,4 +1740,51 @@ AC_SUBST(PAM_LIBS)
@@ -1745,4 +1746,51 @@ AC_SUBST(PAM_LIBS)
AC_SUBST(PAM_MAN)
AC_SUBST(NON_PAM_MAN)
])dnl
@ -131,7 +131,7 @@ index 59621e3e7..398eca7e4 100644
+AC_SUBST(SELINUX_LIBS)
+])dnl
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
index f6184da3f..c17cb5eb5 100755
index 9f96a8719..120922ac3 100755
--- a/src/build-tools/krb5-config.in
+++ b/src/build-tools/krb5-config.in
@@ -41,6 +41,7 @@ DL_LIB='@DL_LIB@'
@ -152,7 +152,7 @@ index f6184da3f..c17cb5eb5 100755
echo $lib_flags
diff --git a/src/config/pre.in b/src/config/pre.in
index ce87e21ca..917357df9 100644
index 7b3a583cc..0c51e6966 100644
--- a/src/config/pre.in
+++ b/src/config/pre.in
@@ -177,6 +177,7 @@ LD = $(PURE) @LD@
@ -173,10 +173,10 @@ index ce87e21ca..917357df9 100644
GSS_LIBS = $(GSS_KRB5_LIB)
# needs fixing if ever used on macOS!
diff --git a/src/configure.ac b/src/configure.ac
index d1f576124..440a22bd9 100644
index fdaba0ce7..bd151ca26 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1392,6 +1392,8 @@ AC_PATH_PROG(GROFF, groff)
@@ -1391,6 +1391,8 @@ AC_PATH_PROG(GROFF, groff)
KRB5_WITH_PAM
@ -186,7 +186,7 @@ index d1f576124..440a22bd9 100644
if test "${localedir+set}" != set; then
localedir='$(datadir)/locale'
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 9616b24bf..0d9af3d95 100644
index b3e346991..93d3a1f97 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -128,6 +128,7 @@ typedef unsigned char u_char;
@ -236,7 +236,7 @@ index 000000000..dfaaa847c
+#endif
+#endif
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 79761f6d2..e9435c693 100644
index 045334a08..db80063eb 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -87,6 +87,12 @@
@ -288,7 +288,7 @@ index ff2f25050..e3457622a 100644
com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok);
goto cleanup;
diff --git a/src/kdc/main.c b/src/kdc/main.c
index 38d76b3b1..eb6966f2d 100644
index 27aa10da0..b5916b147 100644
--- a/src/kdc/main.c
+++ b/src/kdc/main.c
@@ -872,7 +872,7 @@ write_pid_file(const char *path)
@ -301,7 +301,7 @@ index 38d76b3b1..eb6966f2d 100644
return errno;
pid = (unsigned long) getpid();
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
index 5622d56e1..356e3e0e6 100644
index 874ba1305..9d6378cc0 100644
--- a/src/kprop/kpropd.c
+++ b/src/kprop/kpropd.c
@@ -487,6 +487,9 @@ doit(int fd)
@ -416,7 +416,7 @@ index 7b100a0ec..5683a0433 100644
_("Credential cache directory %s does not exist"),
dirname);
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
index 021c94398..aaf573439 100644
index e510211fc..f3ea28c8e 100644
--- a/src/lib/krb5/keytab/kt_file.c
+++ b/src/lib/krb5/keytab/kt_file.c
@@ -735,14 +735,14 @@ krb5_ktfileint_open(krb5_context context, krb5_keytab id, int mode)
@ -463,7 +463,7 @@ index 7db30a33b..2b9d01921 100644
* maybe someone took away write permission so we could only
* get shared locks?
diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c
index 5106a5c99..e481e8121 100644
index 1a476b586..b40bb2240 100644
--- a/src/plugins/kdb/db2/kdb_db2.c
+++ b/src/plugins/kdb/db2/kdb_db2.c
@@ -694,8 +694,8 @@ ctx_create_db(krb5_context context, krb5_db2_context *dbc)
@ -542,7 +542,7 @@ index d8b26e701..b0daa7c02 100644
if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
diff --git a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
index b92cb58c7..0a95101ad 100644
index e87688d66..30f7c00ab 100644
--- a/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
+++ b/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
@@ -190,7 +190,7 @@ kdb5_ldap_stash_service_password(int argc, char **argv)

View File

@ -1,4 +1,4 @@
From a89e833a2ae26197a0edf864bb9274d776003c60 Mon Sep 17 00:00:00 2001
From 7b22d94779ff340db5f9f25cf7b55aeb365091e1 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Fri, 15 Nov 2019 20:05:16 +0000
Subject: [PATCH] [downstream] Use backported version of OpenSSL-3 KDF
@ -12,7 +12,7 @@ Last-updated: krb5-1.17
3 files changed, 428 insertions(+), 189 deletions(-)
diff --git a/src/configure.ac b/src/configure.ac
index d4e4da525..29be532cb 100644
index 27c2383d7..d3e022274 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -282,6 +282,10 @@ AC_SUBST(CRYPTO_IMPL)
@ -441,7 +441,7 @@ index 6707a7308..915a173dd 100644
return k5_sp800_108_counter_hmac(hash, inkey, outrnd, in_constant,
&empty);
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
index 52976895b..dd718c2be 100644
index 0a67c44ef..dbb054378 100644
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
@@ -38,6 +38,13 @@

View File

@ -1,4 +1,4 @@
From 0f98db9b00fa2ce685f841db18fff641f8eaa904 Mon Sep 17 00:00:00 2001
From 27614a4fd889525fbd1ca5cb45c20c64a4f9568c Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:49:25 -0400
Subject: [PATCH] [downstream] fix debuginfo with y.tab.c

View File

@ -1,4 +1,4 @@
From a5a642c33a2f57d24c1cfa8ca3e286418206ab55 Mon Sep 17 00:00:00 2001
From f7749ad59d75c2da64f4e9defdbfbc0c1e345bfb Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:29:58 -0400
Subject: [PATCH] [downstream] ksu pam integration
@ -30,10 +30,10 @@ Last-updated: krb5-1.18-beta1
create mode 100644 src/clients/ksu/pam.h
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 8709a7f5d..59621e3e7 100644
index 024d6370c..ca9fcf664 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1671,3 +1671,72 @@ if test "$with_ldap" = yes; then
@@ -1677,3 +1677,72 @@ if test "$with_ldap" = yes; then
OPENLDAP_PLUGIN=yes
fi
])dnl
@ -145,11 +145,11 @@ index 8b4edce4d..9d58f29b5 100644
clean:
$(RM) ksu
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
index 57c349200..508242e0e 100644
index af1286172..931f05404 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
* KSU was written by: Ari Medvinsky, ari@isi.edu
*/
+#include "autoconf.h"
@ -760,10 +760,10 @@ index 000000000..0ab76569c
+void appl_pam_cleanup(void);
+#endif
diff --git a/src/configure.ac b/src/configure.ac
index 234f4281c..d1f576124 100644
index 49814922f..fdaba0ce7 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -1390,6 +1390,8 @@ AC_SUBST([VERTO_VERSION])
@@ -1389,6 +1389,8 @@ AC_SUBST([VERTO_VERSION])
AC_PATH_PROG(GROFF, groff)

View File

@ -1,4 +1,4 @@
From 29f58a8059cb73ca586514b57458b2b17e091f36 Mon Sep 17 00:00:00 2001
From df80ded9756b0637ab7cca706e1520f3f372c2e2 Mon Sep 17 00:00:00 2001
From: Robbie Harwood <rharwood@redhat.com>
Date: Tue, 23 Aug 2016 16:46:21 -0400
Subject: [PATCH] [downstream] netlib and dns
@ -11,10 +11,10 @@ Last-updated: krb5-1.3.1
1 file changed, 1 insertion(+)
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 398eca7e4..7ef2db56b 100644
index 5afb96e58..4a4d460e3 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -720,6 +720,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
@@ -718,6 +718,7 @@ AC_HELP_STRING([--with-netlib=LIBS], use user defined resolver library),
LIBS="$LIBS $withval"
AC_MSG_RESULT("netlib will use \'$withval\'")
fi

View File

@ -1,5 +1,3 @@
%global WITH_DIRSRV 1
# Set this so that find-lang.sh will recognize the .po files.
%global gettext_domain mit-krb5
# Guess where the -libs subpackage's docs are going to go.
@ -8,21 +6,24 @@
%global configure_default_ccache_name 1
%global configured_default_ccache_name KEYRING:persistent:%%{uid}
# leave empty or set to e.g., -beta2
%global prerelease %{nil}
# either beta1 or % { nil }
%global prerelease beta1
%if %{defined prerelease}
%global dashpre -%{prerelease}
%global zdpd 0.%{prerelease}.
%endif
# Should be in form 5.0, 6.1, etc.
%global kdbversion 8.0
Summary: The Kerberos network authentication system
Name: krb5
Version: 1.18.3
# for prerelease, should be e.g., 0.% {prerelease}.1% { ?dist } (without spaces)
Release: 5%{?dist}
Version: 1.19
Release: %{?zdpd}2%{?dist}
# rharwood has trust path to signing key and verifies on check-in
Source0: https://web.mit.edu/kerberos/dist/krb5/1.18/krb5-%{version}%{prerelease}.tar.gz
Source1: https://web.mit.edu/kerberos/dist/krb5/1.18/krb5-%{version}%{prerelease}.tar.gz.asc
Source0: https://web.mit.edu/kerberos/dist/krb5/%{version}/krb5-%{version}%{?dashpre}.tar.gz
Source1: https://web.mit.edu/kerberos/dist/krb5/%{version}/krb5-%{version}%{?dashpre}.tar.gz.asc
# Numbering is a relic of old init systems etc. It's easiest to just leave.
Source2: kprop.service
@ -46,37 +47,6 @@ Patch4: downstream-fix-debuginfo-with-y.tab.c.patch
Patch5: downstream-Remove-3des-support.patch
Patch6: downstream-Use-backported-version-of-OpenSSL-3-KDF-i.patch
Patch7: downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch
Patch9: Allow-certauth-modules-to-set-hw-authent-flag.patch
Patch11: Refresh-manually-acquired-creds-from-client-keytab.patch
Patch13: Add-finalization-safety-check-to-com_err.patch
Patch15: Correctly-import-service-GSS-host-based-name.patch
Patch16: Do-expiration-warnings-for-all-init_creds-APIs.patch
Patch17: Pass-gss_localname-through-SPNEGO.patch
Patch18: Omit-KDC-indicator-check-for-S4U2Self-requests.patch
Patch19: Fix-typo-in-in-in-the-ksu-man-page.patch
Patch21: Replace-gssrpc-tests-with-a-Python-script.patch
Patch22: Default-dns_canonicalize_hostname-to-fallback.patch
Patch23: Remove-resolver-test-utility.patch
Patch24: Omit-PA_FOR_USER-if-we-can-t-compute-its-checksum.patch
Patch25: Improve-negoex_parse_token-code-hygiene.patch
Patch26: Refactor-krb5-GSS-checksum-handling.patch
Patch27: Implement-GSS_C_CHANNEL_BOUND_FLAG.patch
Patch28: Implement-KERB_AP_OPTIONS_CBT-server-side.patch
Patch29: Add-client_aware_channel_bindings-option.patch
Patch30: Pass-channel-bindings-through-SPNEGO.patch
Patch31: Add-channel-bindings-tests.patch
Patch32: Use-two-queues-for-concurrent-t_otp.py-daemons.patch
Patch34: Ignore-bad-enctypes-in-krb5_string_to_keysalts.patch
Patch35: Fix-leak-in-KERB_AP_OPTIONS_CBT-server-support.patch
Patch37: Add-three-kvno-options-from-Heimdal-kgetcred.patch
Patch39: Improve-KDC-alias-checking-for-S4U-requests.patch
Patch40: Adjust-KDC-alias-helper-function-contract.patch
Patch41: Allow-aliases-when-matching-U2U-second-ticket.patch
Patch42: Refactor-KDC-authdata-list-management-helpers.patch
Patch43: Avoid-passing-DB-entry-structures-in-KDC.patch
Patch44: Minimize-usage-of-tgs_server-in-KDC.patch
Patch45: Fix-minor-static-analysis-defects.patch
Patch46: Install-shared-libraries-as-executable.patch
Patch47: Document-k-option-in-kvno-1-synopsis.patch
License: MIT
@ -211,7 +181,7 @@ contains only the libkadm5clnt and libkadm5serv shared objects. This
interface is not considered stable.
%prep
%autosetup -S git -n %{name}-%{version}%{prerelease}
%autosetup -S git -n %{name}-%{version}%{?dashpre}
ln NOTICE LICENSE
# Generate an FDS-compatible LDIF file.
@ -276,9 +246,7 @@ CPPFLAGS="`echo $DEFINES $INCLUDES`"
--with-tcl \
--enable-dns-for-realm \
--with-ldap \
%if %{WITH_DIRSRV}
--with-dirsrv-account-locking \
%endif
--enable-pkinit \
--with-crypto-impl=openssl \
--with-tls-impl=openssl \
@ -317,13 +285,17 @@ rm -fr build-html/_sources
%ifnarch s390x
pushd src
# ugh. COPR doesn't expose the keyring, so try to cope.
KEYCTL=keyctl
keyctl list @u &>/dev/null || KEYCTL=:
# ugh. COPR doesn't work right with the tests. I suspect keyring issues, but
# can't actually debug, so...
%if 0%{?copr_username:1}
%global keyctl :
%else
%global keyctl keyctl
%endif
# The build system may give us a revoked session keyring, so run affected
# tests with a new one.
$KEYCTL session - make check OFFLINE=yes TMPDIR=%{_tmppath}
%{keyctl} session - make check OFFLINE=yes TMPDIR=%{_tmppath}
popd
%endif
@ -639,6 +611,9 @@ exit 0
%{_libdir}/libkadm5srv_mit.so.*
%changelog
* Wed Dec 16 2020 Robbie Harwood <rharwood@redhat.com> - 1.19-0.beta1.2
- New upstream version (1.19-beta1)
* Wed Dec 16 2020 Robbie Harwood <rharwood@redhat.com> - 1.18.3-5
- Fix runstatedir configuration
- Why couldn't systemd just leave it alone?

View File

@ -1,2 +1,2 @@
SHA512 (krb5-1.18.3.tar.gz) = cf0bf6cf8f622fa085954e6da998d952cf64dc7ccc319972ed81ea0542089cabf2d0e8243df84da01ad6f40584768ca2f02d108630c6741fa7b3d7d98c887c01
SHA512 (krb5-1.18.3.tar.gz.asc) = 7c5a83e13d00910d895d545ed63310ebec48c90c29846dd54e48048f710360e8306778729b636baa091a4e9048998ff6d4dfe37f88dd6292540d55678c961a30
SHA512 (krb5-1.19-beta1.tar.gz) = 3538a13a38c20d6b5fee0fba474bc49a12434b184de409f829e7b6e5c76ad2fc105fc27f2574a93c3cd9fe9ccf3d5d98f6cd3bdd13a089bb3485e0c3974417de
SHA512 (krb5-1.19-beta1.tar.gz.asc) = cfa793f83f0adaba87f2fe242b0796ed8732de898501d51b745d57a55d98966b337e68f29ec0ae233b15613baca70f2c56f742e467d310e157e3b49b59ad9c5f