New upstream version (1.20.1)
Also set "supportedCMSTypes" to SHA-512/256 with RSA encryption Resolves: rhbz#2124463 Resolves: rhbz#2114766 Signed-off-by: Julien Rische <jrische@redhat.com>
This commit is contained in:
parent
c13bf943d8
commit
56cee506e7
95
.gitignore
vendored
95
.gitignore
vendored
@ -1,49 +1,50 @@
|
||||
krb5-1.3.4.tar.gz
|
||||
krb5-1.3.5.tar.gz
|
||||
krb5-1.3.5.tar.gz.asc
|
||||
krb5-1.3.6.tar.gz
|
||||
krb5-1.3.6.tar.gz.asc
|
||||
krb5-1.4.tar.gz
|
||||
krb5-1.4.tar.gz.asc
|
||||
krb5-1.4.1.tar.gz
|
||||
krb5-1.4.1.tar.gz.asc
|
||||
krb5-1.4.2.tar.gz
|
||||
krb5-1.4.2.tar.gz.asc
|
||||
krb5-1.4.3.tar.gz
|
||||
krb5-1.4.3.tar.gz.asc
|
||||
krb5-1.5.tar.gz
|
||||
krb5-1.5.tar.gz.asc
|
||||
krb5-1.6.tar.gz
|
||||
krb5-1.6.tar.gz.asc
|
||||
krb5-1.6-pdf.tar.gz
|
||||
krb5-1.6.1.tar.gz
|
||||
krb5-1.6.1.tar.gz.asc
|
||||
krb5-1.6.1-pdf.tar.gz
|
||||
krb5-1.6.2.tar.gz
|
||||
krb5-1.6.2.tar.gz.asc
|
||||
krb5-1.6.2-pdf.tar.gz
|
||||
krb5-1.6.3.tar.gz
|
||||
krb5-1.6.3.tar.gz.asc
|
||||
krb5-1.6.3-pdf.tar.gz
|
||||
krb5-1.7.tar.gz
|
||||
krb5-1.7.tar.gz.asc
|
||||
krb5-1.7-pdf.tar.gz
|
||||
krb5-1.7.1.tar.gz
|
||||
krb5-1.7.1.tar.gz.asc
|
||||
krb5-1.7.1-pdf.tar.gz
|
||||
krb5-1.8.tar.gz
|
||||
krb5-1.8.tar.gz.asc
|
||||
krb5-appl-1.0.tar.gz
|
||||
krb5-appl-1.0.tar.gz.asc
|
||||
krb5-1.8-pdf.tar.gz
|
||||
krb5-1.8.1.tar.gz
|
||||
krb5-1.8.1.tar.gz.asc
|
||||
krb5-1.8.1-pdf.tar.gz
|
||||
krb5-1.8.2.tar.gz.asc
|
||||
krb5-1.8.2-pdf.tar.gz
|
||||
krb5-1.8.3.tar.gz
|
||||
krb5-1.8.3.tar.gz.asc
|
||||
krb5-1.8.3-pdf.tar.gz
|
||||
/results_krb5
|
||||
/krb5-1.3.4.tar.gz
|
||||
/krb5-1.3.5.tar.gz
|
||||
/krb5-1.3.5.tar.gz.asc
|
||||
/krb5-1.3.6.tar.gz
|
||||
/krb5-1.3.6.tar.gz.asc
|
||||
/krb5-1.4.tar.gz
|
||||
/krb5-1.4.tar.gz.asc
|
||||
/krb5-1.4.1.tar.gz
|
||||
/krb5-1.4.1.tar.gz.asc
|
||||
/krb5-1.4.2.tar.gz
|
||||
/krb5-1.4.2.tar.gz.asc
|
||||
/krb5-1.4.3.tar.gz
|
||||
/krb5-1.4.3.tar.gz.asc
|
||||
/krb5-1.5.tar.gz
|
||||
/krb5-1.5.tar.gz.asc
|
||||
/krb5-1.6.tar.gz
|
||||
/krb5-1.6.tar.gz.asc
|
||||
/krb5-1.6-pdf.tar.gz
|
||||
/krb5-1.6.1.tar.gz
|
||||
/krb5-1.6.1.tar.gz.asc
|
||||
/krb5-1.6.1-pdf.tar.gz
|
||||
/krb5-1.6.2.tar.gz
|
||||
/krb5-1.6.2.tar.gz.asc
|
||||
/krb5-1.6.2-pdf.tar.gz
|
||||
/krb5-1.6.3.tar.gz
|
||||
/krb5-1.6.3.tar.gz.asc
|
||||
/krb5-1.6.3-pdf.tar.gz
|
||||
/krb5-1.7.tar.gz
|
||||
/krb5-1.7.tar.gz.asc
|
||||
/krb5-1.7-pdf.tar.gz
|
||||
/krb5-1.7.1.tar.gz
|
||||
/krb5-1.7.1.tar.gz.asc
|
||||
/krb5-1.7.1-pdf.tar.gz
|
||||
/krb5-1.8.tar.gz
|
||||
/krb5-1.8.tar.gz.asc
|
||||
/krb5-appl-1.0.tar.gz
|
||||
/krb5-appl-1.0.tar.gz.asc
|
||||
/krb5-1.8-pdf.tar.gz
|
||||
/krb5-1.8.1.tar.gz
|
||||
/krb5-1.8.1.tar.gz.asc
|
||||
/krb5-1.8.1-pdf.tar.gz
|
||||
/krb5-1.8.2.tar.gz.asc
|
||||
/krb5-1.8.2-pdf.tar.gz
|
||||
/krb5-1.8.3.tar.gz
|
||||
/krb5-1.8.3.tar.gz.asc
|
||||
/krb5-1.8.3-pdf.tar.gz
|
||||
/krb5-1.9-beta2.tar.gz
|
||||
/krb5-1.9-beta2.tar.gz.asc
|
||||
/krb5-1.9-beta2-pdf.tar.bz2
|
||||
@ -199,3 +200,5 @@ krb5-1.8.3-pdf.tar.gz
|
||||
/krb5-1.19.1.tar.gz.asc
|
||||
/krb5-1.19.2.tar.gz
|
||||
/krb5-1.19.2.tar.gz.asc
|
||||
/krb5-1.20.1.tar.gz
|
||||
/krb5-1.20.1.tar.gz.asc
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 659b3b4a654b879ce84ad8fb4621dde5ae693385 Mon Sep 17 00:00:00 2001
|
||||
From 37d69135d0be7f46732c401cdbb3abc075bf4117 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 024d6370c..ca9fcf664 100644
|
||||
index 9920476f91..bf9da35bbc 100644
|
||||
--- a/src/aclocal.m4
|
||||
+++ b/src/aclocal.m4
|
||||
@@ -1677,3 +1677,72 @@ if test "$with_ldap" = yes; then
|
||||
@@ -1458,3 +1458,72 @@ if test "$with_ldap" = yes; then
|
||||
OPENLDAP_PLUGIN=yes
|
||||
fi
|
||||
])dnl
|
||||
@ -107,7 +107,7 @@ index 024d6370c..ca9fcf664 100644
|
||||
+])dnl
|
||||
+
|
||||
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
|
||||
index 8b4edce4d..9d58f29b5 100644
|
||||
index 8b4edce4d8..9d58f29b5d 100644
|
||||
--- a/src/clients/ksu/Makefile.in
|
||||
+++ b/src/clients/ksu/Makefile.in
|
||||
@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S)..
|
||||
@ -145,7 +145,7 @@ index 8b4edce4d..9d58f29b5 100644
|
||||
clean:
|
||||
$(RM) ksu
|
||||
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
|
||||
index af1286172..931f05404 100644
|
||||
index af12861729..931f054041 100644
|
||||
--- a/src/clients/ksu/main.c
|
||||
+++ b/src/clients/ksu/main.c
|
||||
@@ -26,6 +26,7 @@
|
||||
@ -303,7 +303,7 @@ index af1286172..931f05404 100644
|
||||
}
|
||||
diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c
|
||||
new file mode 100644
|
||||
index 000000000..cbfe48704
|
||||
index 0000000000..cbfe487047
|
||||
--- /dev/null
|
||||
+++ b/src/clients/ksu/pam.c
|
||||
@@ -0,0 +1,389 @@
|
||||
@ -698,7 +698,7 @@ index 000000000..cbfe48704
|
||||
+#endif
|
||||
diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h
|
||||
new file mode 100644
|
||||
index 000000000..0ab76569c
|
||||
index 0000000000..0ab76569cb
|
||||
--- /dev/null
|
||||
+++ b/src/clients/ksu/pam.h
|
||||
@@ -0,0 +1,57 @@
|
||||
@ -760,10 +760,10 @@ index 000000000..0ab76569c
|
||||
+void appl_pam_cleanup(void);
|
||||
+#endif
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 4eb080784..693f76a81 100644
|
||||
index f03028b5fd..aa970b0447 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1389,6 +1389,8 @@ AC_SUBST([VERTO_VERSION])
|
||||
@@ -1400,6 +1400,8 @@ AC_SUBST([VERTO_VERSION])
|
||||
|
||||
AC_PATH_PROG(GROFF, groff)
|
||||
|
||||
@ -772,3 +772,6 @@ index 4eb080784..693f76a81 100644
|
||||
# Make localedir work in autoconf 2.5x.
|
||||
if test "${localedir+set}" != set; then
|
||||
localedir='$(datadir)/locale'
|
||||
--
|
||||
2.38.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 97966ffaac6bf9f2e09ac33a16b15794b31d51de Mon Sep 17 00:00:00 2001
|
||||
From c6b58ed180ed91b579d322ff5004f68750f1eb4f 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
|
||||
@ -36,7 +36,9 @@ The selabel APIs for looking up the context should be thread-safe (per
|
||||
Red Hat #273081), so switching to using them instead of matchpathcon(),
|
||||
which we used earlier, is some improvement.
|
||||
|
||||
Last-updated: krb5-1.18-beta1
|
||||
Last-updated: krb5-1.20.1
|
||||
[jrische@redhat.com: Replace deprecated security_context_t by char *:
|
||||
- src/util/support/selinux.c]
|
||||
---
|
||||
src/aclocal.m4 | 48 +++
|
||||
src/build-tools/krb5-config.in | 3 +-
|
||||
@ -61,13 +63,13 @@ Last-updated: krb5-1.18-beta1
|
||||
.../kdb/ldap/ldap_util/kdb5_ldap_services.c | 11 +-
|
||||
src/util/profile/prof_file.c | 3 +-
|
||||
src/util/support/Makefile.in | 3 +-
|
||||
src/util/support/selinux.c | 406 ++++++++++++++++++
|
||||
24 files changed, 573 insertions(+), 21 deletions(-)
|
||||
src/util/support/selinux.c | 405 ++++++++++++++++++
|
||||
24 files changed, 572 insertions(+), 21 deletions(-)
|
||||
create mode 100644 src/include/k5-label.h
|
||||
create mode 100644 src/util/support/selinux.c
|
||||
|
||||
diff --git a/src/aclocal.m4 b/src/aclocal.m4
|
||||
index ca9fcf664..5afb96e58 100644
|
||||
index bf9da35bbc..01283f482e 100644
|
||||
--- a/src/aclocal.m4
|
||||
+++ b/src/aclocal.m4
|
||||
@@ -85,6 +85,7 @@ AC_SUBST_FILE(libnodeps_frag)
|
||||
@ -78,7 +80,7 @@ index ca9fcf664..5afb96e58 100644
|
||||
KRB5_LIB_PARAMS
|
||||
KRB5_AC_INITFINI
|
||||
KRB5_AC_ENABLE_THREADS
|
||||
@@ -1745,4 +1746,51 @@ AC_SUBST(PAM_LIBS)
|
||||
@@ -1526,4 +1527,51 @@ AC_SUBST(PAM_LIBS)
|
||||
AC_SUBST(PAM_MAN)
|
||||
AC_SUBST(NON_PAM_MAN)
|
||||
])dnl
|
||||
@ -131,7 +133,7 @@ index ca9fcf664..5afb96e58 100644
|
||||
+AC_SUBST(SELINUX_LIBS)
|
||||
+])dnl
|
||||
diff --git a/src/build-tools/krb5-config.in b/src/build-tools/krb5-config.in
|
||||
index dead0dddc..fef3e054f 100755
|
||||
index dead0dddce..fef3e054fc 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 +154,7 @@ index dead0dddc..fef3e054f 100755
|
||||
|
||||
echo $lib_flags
|
||||
diff --git a/src/config/pre.in b/src/config/pre.in
|
||||
index 3752174c7..0d2068575 100644
|
||||
index a0c60c70b3..7eaa2f351c 100644
|
||||
--- a/src/config/pre.in
|
||||
+++ b/src/config/pre.in
|
||||
@@ -177,6 +177,7 @@ LD = $(PURE) @LD@
|
||||
@ -163,7 +165,7 @@ index 3752174c7..0d2068575 100644
|
||||
|
||||
INSTALL=@INSTALL@
|
||||
INSTALL_STRIP=
|
||||
@@ -403,7 +404,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
|
||||
@@ -379,7 +380,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
|
||||
# HESIOD_LIBS is -lhesiod...
|
||||
HESIOD_LIBS = @HESIOD_LIBS@
|
||||
|
||||
@ -173,10 +175,10 @@ index 3752174c7..0d2068575 100644
|
||||
GSS_LIBS = $(GSS_KRB5_LIB)
|
||||
# needs fixing if ever used on macOS!
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 693f76a81..dd2cad3ee 100644
|
||||
index aa970b0447..40545f2bfc 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1391,6 +1391,8 @@ AC_PATH_PROG(GROFF, groff)
|
||||
@@ -1402,6 +1402,8 @@ AC_PATH_PROG(GROFF, groff)
|
||||
|
||||
KRB5_WITH_PAM
|
||||
|
||||
@ -186,7 +188,7 @@ index 693f76a81..dd2cad3ee 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 cf524252f..efb523689 100644
|
||||
index 44dc1eeb3f..c3aecba7d4 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -128,6 +128,7 @@ typedef unsigned char u_char;
|
||||
@ -199,7 +201,7 @@ index cf524252f..efb523689 100644
|
||||
#define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */
|
||||
diff --git a/src/include/k5-label.h b/src/include/k5-label.h
|
||||
new file mode 100644
|
||||
index 000000000..dfaaa847c
|
||||
index 0000000000..dfaaa847cb
|
||||
--- /dev/null
|
||||
+++ b/src/include/k5-label.h
|
||||
@@ -0,0 +1,32 @@
|
||||
@ -236,7 +238,7 @@ index 000000000..dfaaa847c
|
||||
+#endif
|
||||
+#endif
|
||||
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
||||
index 045334a08..db80063eb 100644
|
||||
index c0194c3c94..7e1dea2cbf 100644
|
||||
--- a/src/include/krb5/krb5.hin
|
||||
+++ b/src/include/krb5/krb5.hin
|
||||
@@ -87,6 +87,12 @@
|
||||
@ -253,7 +255,7 @@ index 045334a08..db80063eb 100644
|
||||
|
||||
#include <stdlib.h>
|
||||
diff --git a/src/kadmin/dbutil/dump.c b/src/kadmin/dbutil/dump.c
|
||||
index 634ba4a8b..cea7939f4 100644
|
||||
index a89b5144f6..4d6cc0bdf9 100644
|
||||
--- a/src/kadmin/dbutil/dump.c
|
||||
+++ b/src/kadmin/dbutil/dump.c
|
||||
@@ -148,12 +148,21 @@ create_ofile(char *ofile, char **tmpname)
|
||||
@ -288,10 +290,10 @@ index 634ba4a8b..cea7939f4 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 3be6dcb07..24d441e16 100644
|
||||
index 38b9299066..085afc9220 100644
|
||||
--- a/src/kdc/main.c
|
||||
+++ b/src/kdc/main.c
|
||||
@@ -872,7 +872,7 @@ write_pid_file(const char *path)
|
||||
@@ -848,7 +848,7 @@ write_pid_file(const char *path)
|
||||
FILE *file;
|
||||
unsigned long pid;
|
||||
|
||||
@ -301,10 +303,10 @@ index 3be6dcb07..24d441e16 100644
|
||||
return errno;
|
||||
pid = (unsigned long) getpid();
|
||||
diff --git a/src/kprop/kpropd.c b/src/kprop/kpropd.c
|
||||
index 498ca599a..c6b8efc28 100644
|
||||
index f2341d720f..ffdac9f397 100644
|
||||
--- a/src/kprop/kpropd.c
|
||||
+++ b/src/kprop/kpropd.c
|
||||
@@ -487,6 +487,9 @@ doit(int fd)
|
||||
@@ -488,6 +488,9 @@ doit(int fd)
|
||||
krb5_enctype etype;
|
||||
int database_fd;
|
||||
char host[INET6_ADDRSTRLEN + 1];
|
||||
@ -314,7 +316,7 @@ index 498ca599a..c6b8efc28 100644
|
||||
|
||||
signal_wrapper(SIGALRM, alarm_handler);
|
||||
alarm(params.iprop_resync_timeout);
|
||||
@@ -542,9 +545,15 @@ doit(int fd)
|
||||
@@ -543,9 +546,15 @@ doit(int fd)
|
||||
free(name);
|
||||
exit(1);
|
||||
}
|
||||
@ -331,7 +333,7 @@ index 498ca599a..c6b8efc28 100644
|
||||
KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK);
|
||||
if (retval) {
|
||||
diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c
|
||||
index c6885edf2..9aec3c05e 100644
|
||||
index c6885edf2a..9aec3c05e8 100644
|
||||
--- a/src/lib/kadm5/logger.c
|
||||
+++ b/src/lib/kadm5/logger.c
|
||||
@@ -309,7 +309,7 @@ krb5_klog_init(krb5_context kcontext, char *ename, char *whoami, krb5_boolean do
|
||||
@ -353,7 +355,7 @@ index c6885edf2..9aec3c05e 100644
|
||||
set_cloexec_file(f);
|
||||
log_control.log_entries[lindex].lfu_filep = f;
|
||||
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
|
||||
index 2659a2501..e9b95fce5 100644
|
||||
index 2659a25018..e9b95fce59 100644
|
||||
--- a/src/lib/kdb/kdb_log.c
|
||||
+++ b/src/lib/kdb/kdb_log.c
|
||||
@@ -480,7 +480,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
|
||||
@ -366,7 +368,7 @@ index 2659a2501..e9b95fce5 100644
|
||||
retval = errno;
|
||||
goto cleanup;
|
||||
diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c
|
||||
index 7b100a0ec..5683a0433 100644
|
||||
index 1da40b51d0..f3ab7340a6 100644
|
||||
--- a/src/lib/krb5/ccache/cc_dir.c
|
||||
+++ b/src/lib/krb5/ccache/cc_dir.c
|
||||
@@ -183,10 +183,19 @@ write_primary_file(const char *primary_path, const char *contents)
|
||||
@ -416,7 +418,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 e510211fc..f3ea28c8e 100644
|
||||
index e510211fc5..f3ea28c8ec 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)
|
||||
@ -437,10 +439,10 @@ index e510211fc..f3ea28c8e 100644
|
||||
goto report_errno;
|
||||
writevno = 1;
|
||||
diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c
|
||||
index 7073459f0..e9b99f4ca 100644
|
||||
index 3369fc4ba6..95f82cda03 100644
|
||||
--- a/src/lib/krb5/os/trace.c
|
||||
+++ b/src/lib/krb5/os/trace.c
|
||||
@@ -458,7 +458,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
|
||||
@@ -459,7 +459,7 @@ krb5_set_trace_filename(krb5_context context, const char *filename)
|
||||
fd = malloc(sizeof(*fd));
|
||||
if (fd == NULL)
|
||||
return ENOMEM;
|
||||
@ -450,7 +452,7 @@ index 7073459f0..e9b99f4ca 100644
|
||||
free(fd);
|
||||
return errno;
|
||||
diff --git a/src/plugins/kdb/db2/adb_openclose.c b/src/plugins/kdb/db2/adb_openclose.c
|
||||
index 7db30a33b..2b9d01921 100644
|
||||
index 7db30a33b0..2b9d01921d 100644
|
||||
--- a/src/plugins/kdb/db2/adb_openclose.c
|
||||
+++ b/src/plugins/kdb/db2/adb_openclose.c
|
||||
@@ -152,7 +152,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char *filename, char *lockfilename,
|
||||
@ -463,7 +465,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 1a476b586..b40bb2240 100644
|
||||
index 2c163d91cc..9a344a603e 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)
|
||||
@ -478,7 +480,7 @@ index 1a476b586..b40bb2240 100644
|
||||
retval = errno;
|
||||
goto cleanup;
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/btree/bt_open.c b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
index 2977b17f3..d5809a5a9 100644
|
||||
index 2977b17f3a..d5809a5a93 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/btree/bt_open.c
|
||||
@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8.11 (Berkeley) 11/2/95";
|
||||
@ -499,7 +501,7 @@ index 2977b17f3..d5809a5a9 100644
|
||||
|
||||
} else {
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/hash/hash.c b/src/plugins/kdb/db2/libdb2/hash/hash.c
|
||||
index 862dbb164..686a960c9 100644
|
||||
index 862dbb1640..686a960c96 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/hash/hash.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/hash/hash.c
|
||||
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 (Berkeley) 11/7/95";
|
||||
@ -520,7 +522,7 @@ index 862dbb164..686a960c9 100644
|
||||
(void)fcntl(hashp->fp, F_SETFD, 1);
|
||||
}
|
||||
diff --git a/src/plugins/kdb/db2/libdb2/recno/rec_open.c b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
||||
index d8b26e701..b0daa7c02 100644
|
||||
index d8b26e7011..b0daa7c021 100644
|
||||
--- a/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
||||
+++ b/src/plugins/kdb/db2/libdb2/recno/rec_open.c
|
||||
@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)rec_open.c 8.12 (Berkeley) 11/18/94";
|
||||
@ -542,7 +544,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 e87688d66..30f7c00ab 100644
|
||||
index e87688d666..30f7c00ab5 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)
|
||||
@ -579,7 +581,7 @@ index e87688d66..30f7c00ab 100644
|
||||
if (newfile == NULL) {
|
||||
com_err(me, errno, _("Error creating file %s"), tmp_file);
|
||||
diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c
|
||||
index aa951df05..79f9500f6 100644
|
||||
index aa951df05f..79f9500f69 100644
|
||||
--- a/src/util/profile/prof_file.c
|
||||
+++ b/src/util/profile/prof_file.c
|
||||
@@ -33,6 +33,7 @@
|
||||
@ -600,7 +602,7 @@ index aa951df05..79f9500f6 100644
|
||||
retval = errno;
|
||||
if (retval == 0)
|
||||
diff --git a/src/util/support/Makefile.in b/src/util/support/Makefile.in
|
||||
index 86d5a950a..1052d53a1 100644
|
||||
index 86d5a950a6..1052d53a1e 100644
|
||||
--- a/src/util/support/Makefile.in
|
||||
+++ b/src/util/support/Makefile.in
|
||||
@@ -74,6 +74,7 @@ IPC_SYMS= \
|
||||
@ -622,10 +624,10 @@ index 86d5a950a..1052d53a1 100644
|
||||
|
||||
diff --git a/src/util/support/selinux.c b/src/util/support/selinux.c
|
||||
new file mode 100644
|
||||
index 000000000..6d41f3244
|
||||
index 0000000000..807d039da3
|
||||
--- /dev/null
|
||||
+++ b/src/util/support/selinux.c
|
||||
@@ -0,0 +1,406 @@
|
||||
@@ -0,0 +1,405 @@
|
||||
+/*
|
||||
+ * Copyright 2007,2008,2009,2011,2012,2013,2016 Red Hat, Inc. All Rights Reserved.
|
||||
+ *
|
||||
@ -724,17 +726,16 @@ index 000000000..6d41f3244
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static security_context_t
|
||||
+static char *
|
||||
+push_fscreatecon(const char *pathname, mode_t mode)
|
||||
+{
|
||||
+ security_context_t previous, configuredsc, currentsc, derivedsc;
|
||||
+ char *previous, *configuredsc, *currentsc, *genpath;
|
||||
+ const char *derivedsc, *fullpath, *currentuser;
|
||||
+ context_t current, derived;
|
||||
+ const char *fullpath, *currentuser;
|
||||
+ char *genpath;
|
||||
+
|
||||
+ previous = configuredsc = currentsc = derivedsc = NULL;
|
||||
+ previous = configuredsc = currentsc = genpath = NULL;
|
||||
+ derivedsc = NULL;
|
||||
+ current = derived = NULL;
|
||||
+ genpath = NULL;
|
||||
+
|
||||
+ fullpath = pathname;
|
||||
+
|
||||
@ -862,7 +863,7 @@ index 000000000..6d41f3244
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+pop_fscreatecon(security_context_t previous)
|
||||
+pop_fscreatecon(char *previous)
|
||||
+{
|
||||
+ if (!is_selinux_enabled()) {
|
||||
+ return;
|
||||
@ -916,7 +917,7 @@ index 000000000..6d41f3244
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+
|
||||
+ if ((strcmp(mode, "r") == 0) ||
|
||||
+ (strcmp(mode, "rb") == 0)) {
|
||||
@ -942,7 +943,7 @@ index 000000000..6d41f3244
|
||||
+{
|
||||
+ int fd;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+
|
||||
+ k5_once(&labeled_once, label_mutex_init);
|
||||
+ k5_mutex_lock(&labeled_mutex);
|
||||
@ -963,7 +964,7 @@ index 000000000..6d41f3244
|
||||
+{
|
||||
+ int ret;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+
|
||||
+ k5_once(&labeled_once, label_mutex_init);
|
||||
+ k5_mutex_lock(&labeled_mutex);
|
||||
@ -984,7 +985,7 @@ index 000000000..6d41f3244
|
||||
+{
|
||||
+ int ret;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+
|
||||
+ k5_once(&labeled_once, label_mutex_init);
|
||||
+ k5_mutex_lock(&labeled_mutex);
|
||||
@ -1005,7 +1006,7 @@ index 000000000..6d41f3244
|
||||
+{
|
||||
+ int fd;
|
||||
+ int errno_save;
|
||||
+ security_context_t ctx;
|
||||
+ char *ctx;
|
||||
+ mode_t mode;
|
||||
+ va_list ap;
|
||||
+
|
||||
@ -1032,3 +1033,6 @@ index 000000000..6d41f3244
|
||||
+}
|
||||
+
|
||||
+#endif /* USE_SELINUX */
|
||||
--
|
||||
2.38.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 98b50683165089bf7bd9d91f953abbd79a8b1b08 Mon Sep 17 00:00:00 2001
|
||||
From c7fe7cbd61f7debf052ddcc6cc5f01bb7e4f5385 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
|
||||
@ -14,7 +14,7 @@ Last-updated: krb5-1.9
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in
|
||||
index adfea6e2b..d1327e400 100644
|
||||
index adfea6e2b5..d1327e400b 100644
|
||||
--- a/src/kadmin/cli/Makefile.in
|
||||
+++ b/src/kadmin/cli/Makefile.in
|
||||
@@ -37,3 +37,8 @@ clean-unix::
|
||||
@ -27,7 +27,7 @@ index adfea6e2b..d1327e400 100644
|
||||
+ $(YACC.y) $<
|
||||
+ $(CP) y.tab.c $@
|
||||
diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in
|
||||
index 8669c2436..a22f23c02 100644
|
||||
index 8669c2436c..a22f23c02c 100644
|
||||
--- a/src/plugins/kdb/ldap/ldap_util/Makefile.in
|
||||
+++ b/src/plugins/kdb/ldap/ldap_util/Makefile.in
|
||||
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIB) $(GETDATE)
|
||||
@ -39,3 +39,6 @@ index 8669c2436..a22f23c02 100644
|
||||
|
||||
install:
|
||||
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
|
||||
--
|
||||
2.38.1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
From 91e1d43858d90f59f5d9f45987cfca02c3175feb Mon Sep 17 00:00:00 2001
|
||||
From 239cd24624b801d4fc4bb4686bef8526e7675d77 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
|
||||
@ -21,10 +21,10 @@ post7 restores MD5 and adds radius_md5_fips_override.
|
||||
|
||||
post8 silences a static analyzer warning.
|
||||
|
||||
Last-updated: krb5-1.17
|
||||
Last-updated: krb5-1.20
|
||||
---
|
||||
doc/admin/conf_files/krb5_conf.rst | 6 +++
|
||||
src/lib/crypto/krb/prng.c | 11 ++++-
|
||||
src/lib/crypto/krb/prng.c | 15 +++++-
|
||||
.../crypto/openssl/enc_provider/camellia.c | 6 +++
|
||||
src/lib/crypto/openssl/enc_provider/rc4.c | 13 +++++-
|
||||
.../crypto/openssl/hash_provider/hash_evp.c | 12 +++++
|
||||
@ -38,10 +38,10 @@ Last-updated: krb5-1.17
|
||||
src/lib/krad/t_attrset.c | 4 +-
|
||||
src/plugins/preauth/spake/spake_client.c | 6 +++
|
||||
src/plugins/preauth/spake/spake_kdc.c | 6 +++
|
||||
15 files changed, 151 insertions(+), 33 deletions(-)
|
||||
15 files changed, 155 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index 675175955..adba8238d 100644
|
||||
index d5d6e06ebb..2a4962069f 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -330,6 +330,12 @@ The libdefaults section may contain any of the following relations:
|
||||
@ -58,22 +58,26 @@ index 675175955..adba8238d 100644
|
||||
If this flag is true, reverse name lookup will be used in addition
|
||||
to forward name lookup to canonicalizing hostnames for use in
|
||||
diff --git a/src/lib/crypto/krb/prng.c b/src/lib/crypto/krb/prng.c
|
||||
index cb9ca9b98..f0e9984ca 100644
|
||||
index d6b79e2dea..9e80a03d21 100644
|
||||
--- a/src/lib/crypto/krb/prng.c
|
||||
+++ b/src/lib/crypto/krb/prng.c
|
||||
@@ -26,6 +26,8 @@
|
||||
@@ -26,6 +26,12 @@
|
||||
|
||||
#include "crypto_int.h"
|
||||
|
||||
+#include <openssl/rand.h>
|
||||
+
|
||||
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
+#include <openssl/crypto.h>
|
||||
+#endif
|
||||
+
|
||||
krb5_error_code KRB5_CALLCONV
|
||||
krb5_c_random_seed(krb5_context context, krb5_data *data)
|
||||
{
|
||||
@@ -99,9 +101,16 @@ krb5_boolean
|
||||
k5_get_os_entropy(unsigned char *buf, size_t len, int strong)
|
||||
@@ -96,9 +102,16 @@ cleanup:
|
||||
static krb5_boolean
|
||||
get_os_entropy(unsigned char *buf, size_t len)
|
||||
{
|
||||
const char *device;
|
||||
-#if defined(__linux__) && defined(SYS_getrandom)
|
||||
int r;
|
||||
|
||||
@ -89,10 +93,10 @@ index cb9ca9b98..f0e9984ca 100644
|
||||
/*
|
||||
* Pull from the /dev/urandom pool, but require it to have been seeded.
|
||||
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
index 2da691329..f79679a0b 100644
|
||||
index 01920e6ce1..d9f327add6 100644
|
||||
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
@@ -304,6 +304,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
|
||||
@@ -387,6 +387,9 @@ krb5int_camellia_cbc_mac(krb5_key key, const krb5_crypto_iov *data,
|
||||
unsigned char blockY[CAMELLIA_BLOCK_SIZE], blockB[CAMELLIA_BLOCK_SIZE];
|
||||
struct iov_cursor cursor;
|
||||
|
||||
@ -102,7 +106,7 @@ index 2da691329..f79679a0b 100644
|
||||
if (output->length < CAMELLIA_BLOCK_SIZE)
|
||||
return KRB5_BAD_MSIZE;
|
||||
|
||||
@@ -331,6 +334,9 @@ static krb5_error_code
|
||||
@@ -418,6 +421,9 @@ static krb5_error_code
|
||||
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
|
||||
krb5_data *state)
|
||||
{
|
||||
@ -113,10 +117,10 @@ 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 bc87c6f42..9bf407899 100644
|
||||
index 448d563348..ce63cb5f1b 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,
|
||||
@@ -69,6 +69,9 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
struct arcfour_state *arcstate;
|
||||
|
||||
@ -126,7 +130,7 @@ index bc87c6f42..9bf407899 100644
|
||||
arcstate = (state != NULL) ? (void *)state->data : NULL;
|
||||
if (arcstate != NULL) {
|
||||
ctx = arcstate->ctx;
|
||||
@@ -113,7 +116,12 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||
@@ -116,7 +119,12 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||
static void
|
||||
k5_arcfour_free_state(krb5_data *state)
|
||||
{
|
||||
@ -140,7 +144,7 @@ index bc87c6f42..9bf407899 100644
|
||||
|
||||
EVP_CIPHER_CTX_free(arcstate->ctx);
|
||||
free(arcstate);
|
||||
@@ -125,6 +133,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
|
||||
@@ -128,6 +136,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
|
||||
{
|
||||
struct arcfour_state *arcstate;
|
||||
|
||||
@ -151,10 +155,10 @@ index bc87c6f42..9bf407899 100644
|
||||
* The cipher state here is a saved pointer to a struct arcfour_state
|
||||
* object, rather than a flat byte array as in most enc providers. The
|
||||
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
index 1e0fb8fc3..2eb5139c0 100644
|
||||
index f2fbffdb29..11659908bb 100644
|
||||
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
@@ -49,6 +49,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
@@ -60,6 +60,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
if (ctx == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
@ -166,7 +170,7 @@ index 1e0fb8fc3..2eb5139c0 100644
|
||||
ok = EVP_DigestInit_ex(ctx, type, NULL);
|
||||
for (i = 0; i < num_data; i++) {
|
||||
if (!SIGN_IOV(&data[i]))
|
||||
@@ -64,12 +69,19 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
@@ -78,6 +83,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
static krb5_error_code
|
||||
hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||
{
|
||||
@ -178,6 +182,7 @@ index 1e0fb8fc3..2eb5139c0 100644
|
||||
return hash_evp(EVP_md4(), data, num_data, output);
|
||||
}
|
||||
|
||||
@@ -90,6 +100,8 @@ const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||
static krb5_error_code
|
||||
hash_md5(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||
{
|
||||
@ -187,24 +192,24 @@ index 1e0fb8fc3..2eb5139c0 100644
|
||||
}
|
||||
|
||||
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
|
||||
index 7dc59dcc0..769a50c00 100644
|
||||
index bf12b8d6a0..f21e268f7f 100644
|
||||
--- a/src/lib/crypto/openssl/hmac.c
|
||||
+++ b/src/lib/crypto/openssl/hmac.c
|
||||
@@ -103,7 +103,11 @@ map_digest(const struct krb5_hash_provider *hash)
|
||||
@@ -111,7 +111,11 @@ map_digest(const struct krb5_hash_provider *hash)
|
||||
return EVP_sha256();
|
||||
else if (!strncmp(hash->hash_name, "SHA-384",7))
|
||||
else if (hash == &krb5int_hash_sha384)
|
||||
return EVP_sha384();
|
||||
- else if (!strncmp(hash->hash_name, "MD5", 3))
|
||||
- else if (hash == &krb5int_hash_md5)
|
||||
+
|
||||
+ if (FIPS_mode())
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (!strncmp(hash->hash_name, "MD5", 3))
|
||||
+ if (hash == &krb5int_hash_md5)
|
||||
return EVP_md5();
|
||||
else if (!strncmp(hash->hash_name, "MD4", 3))
|
||||
else if (hash == &krb5int_hash_md4)
|
||||
return EVP_md4();
|
||||
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
|
||||
index 9c13d9d75..42d354a3b 100644
|
||||
index 9c13d9d755..42d354a3b5 100644
|
||||
--- a/src/lib/krad/attr.c
|
||||
+++ b/src/lib/krad/attr.c
|
||||
@@ -38,7 +38,8 @@
|
||||
@ -328,7 +333,7 @@ index 9c13d9d75..42d354a3b 100644
|
||||
|
||||
krad_attr
|
||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
|
||||
index 03c613716..d89982a13 100644
|
||||
index f309f1581c..6ec031e320 100644
|
||||
--- a/src/lib/krad/attrset.c
|
||||
+++ b/src/lib/krad/attrset.c
|
||||
@@ -167,7 +167,8 @@ krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
|
||||
@ -351,7 +356,7 @@ index 03c613716..d89982a13 100644
|
||||
return retval;
|
||||
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
||||
index 0143d155a..57672982f 100644
|
||||
index 7619563fc5..e123763954 100644
|
||||
--- a/src/lib/krad/internal.h
|
||||
+++ b/src/lib/krad/internal.h
|
||||
@@ -39,6 +39,8 @@
|
||||
@ -397,7 +402,7 @@ index 0143d155a..57672982f 100644
|
||||
|
||||
/* Decode attributes from a buffer. */
|
||||
krb5_error_code
|
||||
@@ -152,4 +163,17 @@ gai_error_code(int err)
|
||||
@@ -156,4 +167,17 @@ gai_error_code(int err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -416,7 +421,7 @@ index 0143d155a..57672982f 100644
|
||||
+
|
||||
#endif /* INTERNAL_H_ */
|
||||
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
|
||||
index c597174b6..fc2d24800 100644
|
||||
index c597174b65..fc2d248001 100644
|
||||
--- a/src/lib/krad/packet.c
|
||||
+++ b/src/lib/krad/packet.c
|
||||
@@ -53,12 +53,6 @@ typedef unsigned char uchar;
|
||||
@ -477,7 +482,7 @@ index c597174b6..fc2d24800 100644
|
||||
}
|
||||
|
||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
|
||||
index a938665f6..7b5804b1d 100644
|
||||
index 06ae751bc8..929f1cef67 100644
|
||||
--- a/src/lib/krad/remote.c
|
||||
+++ b/src/lib/krad/remote.c
|
||||
@@ -263,7 +263,7 @@ on_io_write(krad_remote *rr)
|
||||
@ -498,7 +503,7 @@ index a938665f6..7b5804b1d 100644
|
||||
request_finish(r, 0, rsp);
|
||||
break;
|
||||
}
|
||||
@@ -455,6 +455,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
||||
@@ -460,6 +460,12 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
||||
(krad_packet_iter_cb)iterator, &r, &tmp);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
@ -512,7 +517,7 @@ index a938665f6..7b5804b1d 100644
|
||||
K5_TAILQ_FOREACH(r, &rr->list, list) {
|
||||
if (r->request == tmp) {
|
||||
diff --git a/src/lib/krad/t_attr.c b/src/lib/krad/t_attr.c
|
||||
index eb2a780c8..4d285ad9d 100644
|
||||
index eb2a780c89..4d285ad9de 100644
|
||||
--- a/src/lib/krad/t_attr.c
|
||||
+++ b/src/lib/krad/t_attr.c
|
||||
@@ -50,6 +50,7 @@ main()
|
||||
@ -533,7 +538,7 @@ index eb2a780c8..4d285ad9d 100644
|
||||
insist(len == sizeof(encoded));
|
||||
insist(memcmp(outbuf, encoded, len) == 0);
|
||||
diff --git a/src/lib/krad/t_attrset.c b/src/lib/krad/t_attrset.c
|
||||
index 7928335ca..0f9576253 100644
|
||||
index 7928335ca4..0f95762534 100644
|
||||
--- a/src/lib/krad/t_attrset.c
|
||||
+++ b/src/lib/krad/t_attrset.c
|
||||
@@ -49,6 +49,7 @@ main()
|
||||
@ -555,7 +560,7 @@ index 7928335ca..0f9576253 100644
|
||||
|
||||
/* Manually encode User-Name. */
|
||||
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
|
||||
index 00734a13b..a3ce22b70 100644
|
||||
index 00734a13b5..a3ce22b70f 100644
|
||||
--- a/src/plugins/preauth/spake/spake_client.c
|
||||
+++ b/src/plugins/preauth/spake/spake_client.c
|
||||
@@ -38,6 +38,8 @@
|
||||
@ -579,7 +584,7 @@ index 00734a13b..a3ce22b70 100644
|
||||
vt->name = "spake";
|
||||
vt->pa_type_list = pa_types;
|
||||
diff --git a/src/plugins/preauth/spake/spake_kdc.c b/src/plugins/preauth/spake/spake_kdc.c
|
||||
index 88c964ce1..c7df0392f 100644
|
||||
index 1a772d450f..232e78bc05 100644
|
||||
--- a/src/plugins/preauth/spake/spake_kdc.c
|
||||
+++ b/src/plugins/preauth/spake/spake_kdc.c
|
||||
@@ -41,6 +41,8 @@
|
||||
@ -591,7 +596,7 @@ index 88c964ce1..c7df0392f 100644
|
||||
/*
|
||||
* The SPAKE kdcpreauth module uses a secure cookie containing the following
|
||||
* concatenated fields (all integer fields are big-endian):
|
||||
@@ -571,6 +573,10 @@ kdcpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
|
||||
@@ -551,6 +553,10 @@ kdcpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
|
||||
|
||||
if (maj_ver != 1)
|
||||
return KRB5_PLUGIN_VER_NOTSUPP;
|
||||
@ -602,3 +607,6 @@ index 88c964ce1..c7df0392f 100644
|
||||
vt = (krb5_kdcpreauth_vtable)vtable;
|
||||
vt->name = "spake";
|
||||
vt->pa_type_list = pa_types;
|
||||
--
|
||||
2.38.1
|
||||
|
@ -1,7 +1,8 @@
|
||||
From a43d621ae83c89abb74764f0fd9d90a8e9992333 Mon Sep 17 00:00:00 2001
|
||||
From 5587c755b6ca82bde093523e2d17b255158cd90e Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Thu, 5 May 2022 17:15:12 +0200
|
||||
Subject: [PATCH] Allow krad UDP/TCP localhost connection with FIPS
|
||||
Subject: [PATCH] [downstream] Allow krad UDP/TCP localhost connection
|
||||
with FIPS
|
||||
|
||||
libkrad allows to establish connections only to UNIX socket in FIPS
|
||||
mode, because MD5 digest is not considered safe enough to be used for
|
||||
@ -17,7 +18,7 @@ Resolves: rhbz#2082189
|
||||
1 file changed, 33 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
|
||||
index 7b5804b1d..e671bc5c2 100644
|
||||
index 929f1cef67..063f17a613 100644
|
||||
--- a/src/lib/krad/remote.c
|
||||
+++ b/src/lib/krad/remote.c
|
||||
@@ -33,6 +33,7 @@
|
||||
@ -64,7 +65,7 @@ index 7b5804b1d..e671bc5c2 100644
|
||||
/* Iterate over the set of outstanding packets. */
|
||||
static const krad_packet *
|
||||
iterator(request **out)
|
||||
@@ -455,8 +485,9 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
||||
@@ -460,8 +490,9 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
||||
(krad_packet_iter_cb)iterator, &r, &tmp);
|
||||
if (retval != 0)
|
||||
goto error;
|
||||
@ -77,5 +78,5 @@ index 7b5804b1d..e671bc5c2 100644
|
||||
retval = ESOCKTNOSUPPORT;
|
||||
goto error;
|
||||
--
|
||||
2.35.1
|
||||
2.38.1
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 2a91dabd9752825b96faf3b25ea643d5282c5957 Mon Sep 17 00:00:00 2001
|
||||
From 842b4c3b5695e2518e6f1a1545db78865c04b59c Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Fri, 22 Apr 2022 14:12:37 +0200
|
||||
Subject: [PATCH] Add configure variable for default PKCS#11 module
|
||||
@ -20,10 +20,10 @@ ticket: 9058 (new)
|
||||
9 files changed, 34 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||
index adba8238d..3d25c9a12 100644
|
||||
index 2a4962069f..a33711d918 100644
|
||||
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||
@@ -1020,7 +1020,7 @@ information for PKINIT is as follows:
|
||||
@@ -1017,7 +1017,7 @@ information for PKINIT is as follows:
|
||||
All keyword/values are optional. *modname* specifies the location
|
||||
of a library implementing PKCS #11. If a value is encountered
|
||||
with no keyword, it is assumed to be the *modname*. If no
|
||||
@ -33,10 +33,10 @@ index adba8238d..3d25c9a12 100644
|
||||
a particular smard card reader or token if there is more than one
|
||||
available. ``certid=`` and/or ``certlabel=`` may be specified to
|
||||
diff --git a/doc/build/options2configure.rst b/doc/build/options2configure.rst
|
||||
index a8959626d..8f8ac911c 100644
|
||||
index 9e355dc2c5..e879b18bd2 100644
|
||||
--- a/doc/build/options2configure.rst
|
||||
+++ b/doc/build/options2configure.rst
|
||||
@@ -143,6 +143,9 @@ Environment variables
|
||||
@@ -137,6 +137,9 @@ Environment variables
|
||||
This option allows one to specify libraries to be passed to the
|
||||
linker (e.g., ``-l<library>``)
|
||||
|
||||
@ -47,7 +47,7 @@ index a8959626d..8f8ac911c 100644
|
||||
If ``-lss`` is not the correct way to link in your installed ss
|
||||
library, for example if additional support libraries are needed,
|
||||
diff --git a/doc/conf.py b/doc/conf.py
|
||||
index a876fd633..252ab891a 100644
|
||||
index 12168fa695..0ab5ff9606 100644
|
||||
--- a/doc/conf.py
|
||||
+++ b/doc/conf.py
|
||||
@@ -242,6 +242,7 @@ if 'mansubs' in tags:
|
||||
@ -75,7 +75,7 @@ index a876fd633..252ab891a 100644
|
||||
.. |krb5conf| replace:: ``/etc/krb5.conf``
|
||||
.. |defkeysalts| replace:: ``aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal``
|
||||
diff --git a/doc/mitK5defaults.rst b/doc/mitK5defaults.rst
|
||||
index 74e69f4ad..aea7af3db 100644
|
||||
index 74e69f4ad0..aea7af3dbb 100644
|
||||
--- a/doc/mitK5defaults.rst
|
||||
+++ b/doc/mitK5defaults.rst
|
||||
@@ -59,18 +59,19 @@ subdirectories of ``/usr/local``. When MIT krb5 is integrated into an
|
||||
@ -111,10 +111,10 @@ index 74e69f4ad..aea7af3db 100644
|
||||
The default client keytab name (DEFCKTNAME) typically defaults to
|
||||
``FILE:/usr/local/var/krb5/user/%{euid}/client.keytab`` for a custom
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 82b049af9..52e6563da 100644
|
||||
index 8dc864718d..9774cb71ae 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1442,6 +1442,14 @@ AC_DEFINE_UNQUOTED(DEFKTNAME, ["$DEFKTNAME"], [Define to default keytab name])
|
||||
@@ -1471,6 +1471,14 @@ AC_DEFINE_UNQUOTED(DEFKTNAME, ["$DEFKTNAME"], [Define to default keytab name])
|
||||
AC_DEFINE_UNQUOTED(DEFCKTNAME, ["$DEFCKTNAME"],
|
||||
[Define to default client keytab name])
|
||||
|
||||
@ -130,7 +130,7 @@ index 82b049af9..52e6563da 100644
|
||||
AC_CONFIG_FILES([build-tools/kadm-server.pc
|
||||
build-tools/kadm-client.pc
|
||||
diff --git a/src/doc/Makefile.in b/src/doc/Makefile.in
|
||||
index 379bc3651..a1b0cff0a 100644
|
||||
index 379bc36511..a1b0cff0a4 100644
|
||||
--- a/src/doc/Makefile.in
|
||||
+++ b/src/doc/Makefile.in
|
||||
@@ -10,6 +10,7 @@ sysconfdir=@sysconfdir@
|
||||
@ -150,7 +150,7 @@ index 379bc3651..a1b0cff0a 100644
|
||||
# Dummy rule that man/Makefile can invoke
|
||||
version.py: $(docsrc)/version.py
|
||||
diff --git a/src/man/Makefile.in b/src/man/Makefile.in
|
||||
index 00b1b2de0..85cae0914 100644
|
||||
index 00b1b2de06..85cae0914e 100644
|
||||
--- a/src/man/Makefile.in
|
||||
+++ b/src/man/Makefile.in
|
||||
@@ -8,6 +8,7 @@ sysconfdir=@sysconfdir@
|
||||
@ -172,10 +172,10 @@ index 00b1b2de0..85cae0914 100644
|
||||
all: $(MANSUBS)
|
||||
|
||||
diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man
|
||||
index e993d5c09..42f5ea4f9 100644
|
||||
index 51acb38815..fd2c6f2bc4 100644
|
||||
--- a/src/man/krb5.conf.man
|
||||
+++ b/src/man/krb5.conf.man
|
||||
@@ -1151,7 +1151,7 @@ user\(aqs certificate and private key.
|
||||
@@ -1148,7 +1148,7 @@ user\(aqs certificate and private key.
|
||||
All keyword/values are optional. \fImodname\fP specifies the location
|
||||
of a library implementing PKCS #11. If a value is encountered
|
||||
with no keyword, it is assumed to be the \fImodname\fP\&. If no
|
||||
@ -185,7 +185,7 @@ index e993d5c09..42f5ea4f9 100644
|
||||
a particular smard card reader or token if there is more than one
|
||||
available. \fBcertid=\fP and/or \fBcertlabel=\fP may be specified to
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit.h b/src/plugins/preauth/pkinit/pkinit.h
|
||||
index b437fd53f..a2018cb10 100644
|
||||
index 8135535e2c..66f92d8f03 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit.h
|
||||
@@ -42,7 +42,6 @@
|
||||
@ -197,5 +197,5 @@ index b437fd53f..a2018cb10 100644
|
||||
#define PK_NOSLOT 999999
|
||||
#endif
|
||||
--
|
||||
2.35.1
|
||||
2.38.1
|
||||
|
159
0008-Set-reasonable-supportedCMSTypes-in-PKINIT.patch
Normal file
159
0008-Set-reasonable-supportedCMSTypes-in-PKINIT.patch
Normal file
@ -0,0 +1,159 @@
|
||||
From 3fb8c4c68274d2ff4addb44b7b95b4698c2c4f34 Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Wed, 1 Jun 2022 18:02:04 +0200
|
||||
Subject: [PATCH] Set reasonable supportedCMSTypes in PKINIT
|
||||
|
||||
The PKINIT client uses AuthPack.supportedCMSTypes to let the KDC know
|
||||
the algorithms it supports for verification of the CMS data signature.
|
||||
(The MIT krb5 KDC currently ignores this list, but other
|
||||
implementations use it.)
|
||||
|
||||
Replace 3DES with sha512WithRSAEncryption and sha256WithRSAEncryption.
|
||||
|
||||
[ghudson@mit.edu: simplified code and used appropriate helpers; edited
|
||||
commit message]
|
||||
|
||||
ticket: 9066 (new)
|
||||
---
|
||||
src/plugins/preauth/pkinit/pkinit_constants.c | 33 ++++++++++++-
|
||||
src/plugins/preauth/pkinit/pkinit_crypto.h | 4 ++
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 49 ++++++++++---------
|
||||
3 files changed, 60 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_constants.c b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
index 652897fa14..1da482e0b4 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_constants.c
|
||||
@@ -32,9 +32,14 @@
|
||||
|
||||
#include "pkinit.h"
|
||||
|
||||
-/* statically declare OID constants for all three algorithms */
|
||||
-static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01};
|
||||
+/* RFC 8636 id-pkinit-kdf-ah-sha1: iso(1) identified-organization(3) dod(6)
|
||||
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha1(1) */
|
||||
+static char sha1_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x01 };
|
||||
+/* RFC 8636 id-pkinit-kdf-ah-sha256: iso(1) identified-organization(3) dod(6)
|
||||
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha256(2) */
|
||||
static char sha256_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x02 };
|
||||
+/* RFC 8636 id-pkinit-kdf-ah-sha512: iso(1) identified-organization(3) dod(6)
|
||||
+ * internet(1) security(5) kerberosv5(2) pkinit(3) kdf(6) sha512(3) */
|
||||
static char sha512_oid[8] = { 0x2B, 0x06, 0x01, 0x05, 0x02, 0x03, 0x06, 0x03 };
|
||||
|
||||
const krb5_data sha1_id = { KV5M_DATA, sizeof(sha1_oid), sha1_oid };
|
||||
@@ -48,6 +53,30 @@ krb5_data const * const supported_kdf_alg_ids[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
|
||||
+ * rsadsi(113549) pkcs(1) 1 11 */
|
||||
+static char sha256WithRSAEncr_oid[9] = {
|
||||
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b
|
||||
+};
|
||||
+/* RFC 4055 sha256WithRSAEncryption: iso(1) member-body(2) us(840)
|
||||
+ * rsadsi(113549) pkcs(1) 1 13 */
|
||||
+static char sha512WithRSAEncr_oid[9] = {
|
||||
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d
|
||||
+};
|
||||
+
|
||||
+const krb5_data sha256WithRSAEncr_id = {
|
||||
+ KV5M_DATA, sizeof(sha256WithRSAEncr_oid), sha256WithRSAEncr_oid
|
||||
+};
|
||||
+const krb5_data sha512WithRSAEncr_id = {
|
||||
+ KV5M_DATA, sizeof(sha512WithRSAEncr_oid), sha512WithRSAEncr_oid
|
||||
+};
|
||||
+
|
||||
+krb5_data const * const supported_cms_algs[] = {
|
||||
+ &sha512WithRSAEncr_id,
|
||||
+ &sha256WithRSAEncr_id,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
/* RFC 2412 section E.2 (well-known group 2) parameters, DER-encoded as
|
||||
* DomainParameters (RFC 3279 section 2.3.3). */
|
||||
static const uint8_t o1024[] = {
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto.h b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
index 65f6210727..64300da856 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto.h
|
||||
@@ -620,6 +620,10 @@ extern const krb5_data oakley_4096;
|
||||
*/
|
||||
extern krb5_data const * const supported_kdf_alg_ids[];
|
||||
|
||||
+/* CMS signature algorithms supported by this implementation, in order of
|
||||
+ * decreasing preference. */
|
||||
+extern krb5_data const * const supported_cms_algs[];
|
||||
+
|
||||
krb5_error_code
|
||||
crypto_encode_der_cert(krb5_context context, pkinit_req_crypto_context reqctx,
|
||||
uint8_t **der_out, size_t *der_len);
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index d500455dec..1c2aa02827 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -5475,37 +5475,38 @@ create_krb5_supportedCMSTypes(krb5_context context,
|
||||
pkinit_plg_crypto_context plg_cryptoctx,
|
||||
pkinit_req_crypto_context req_cryptoctx,
|
||||
pkinit_identity_crypto_context id_cryptoctx,
|
||||
- krb5_algorithm_identifier ***oids)
|
||||
+ krb5_algorithm_identifier ***algs_out)
|
||||
{
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_algorithm_identifier **algs = NULL;
|
||||
+ size_t i, count;
|
||||
|
||||
- krb5_error_code retval = ENOMEM;
|
||||
- krb5_algorithm_identifier **loids = NULL;
|
||||
- krb5_data des3oid = {0, 8, "\x2A\x86\x48\x86\xF7\x0D\x03\x07" };
|
||||
+ *algs_out = NULL;
|
||||
|
||||
- *oids = NULL;
|
||||
- loids = malloc(2 * sizeof(krb5_algorithm_identifier *));
|
||||
- if (loids == NULL)
|
||||
- goto cleanup;
|
||||
- loids[1] = NULL;
|
||||
- loids[0] = malloc(sizeof(krb5_algorithm_identifier));
|
||||
- if (loids[0] == NULL) {
|
||||
- free(loids);
|
||||
- goto cleanup;
|
||||
- }
|
||||
- retval = pkinit_copy_krb5_data(&loids[0]->algorithm, &des3oid);
|
||||
- if (retval) {
|
||||
- free(loids[0]);
|
||||
- free(loids);
|
||||
+ /* Count supported OIDs and allocate list (including null terminator). */
|
||||
+ for (count = 0; supported_cms_algs[count] != NULL; count++);
|
||||
+ algs = k5calloc(count + 1, sizeof(*algs), &ret);
|
||||
+ if (algs == NULL)
|
||||
goto cleanup;
|
||||
+
|
||||
+ /* Add an algorithm identifier for each OID, with no parameters. */
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ algs[i] = k5alloc(sizeof(*algs[i]), &ret);
|
||||
+ if (algs[i] == NULL)
|
||||
+ goto cleanup;
|
||||
+ ret = krb5int_copy_data_contents(context, supported_cms_algs[i],
|
||||
+ &algs[i]->algorithm);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+ algs[i]->parameters = empty_data();
|
||||
}
|
||||
- loids[0]->parameters.length = 0;
|
||||
- loids[0]->parameters.data = NULL;
|
||||
|
||||
- *oids = loids;
|
||||
- retval = 0;
|
||||
-cleanup:
|
||||
+ *algs_out = algs;
|
||||
+ algs = NULL;
|
||||
|
||||
- return retval;
|
||||
+cleanup:
|
||||
+ free_krb5_algorithm_identifiers(&algs);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
--
|
||||
2.38.1
|
||||
|
622
0009-Simplify-plugin-loading-code.patch
Normal file
622
0009-Simplify-plugin-loading-code.patch
Normal file
@ -0,0 +1,622 @@
|
||||
From ffb47e4120d68aef015453350a3a50a9bab1ec58 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Thu, 23 Jun 2022 16:41:40 -0400
|
||||
Subject: [PATCH] Simplify plugin loading code
|
||||
|
||||
Remove the USE_CFBUNDLE code, which was only used by KfM. Handle
|
||||
platform conditionals according to current practice. Use
|
||||
k5_dir_filenames() instead of opendir() and remove the Windows
|
||||
implementation of opendir().
|
||||
---
|
||||
src/util/support/plugins.c | 507 +++++++++++--------------------------
|
||||
1 file changed, 150 insertions(+), 357 deletions(-)
|
||||
|
||||
diff --git a/src/util/support/plugins.c b/src/util/support/plugins.c
|
||||
index c6a9a21d57..0850565687 100644
|
||||
--- a/src/util/support/plugins.c
|
||||
+++ b/src/util/support/plugins.c
|
||||
@@ -29,16 +29,6 @@
|
||||
#if USE_DLOPEN
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
-#include <sys/types.h>
|
||||
-#ifdef HAVE_SYS_STAT_H
|
||||
-#include <sys/stat.h>
|
||||
-#endif
|
||||
-#ifdef HAVE_SYS_PARAM_H
|
||||
-#include <sys/param.h>
|
||||
-#endif
|
||||
-#ifdef HAVE_UNISTD_H
|
||||
-#include <unistd.h>
|
||||
-#endif
|
||||
|
||||
#if USE_DLOPEN
|
||||
#ifdef RTLD_GROUP
|
||||
@@ -68,16 +58,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
-#if USE_DLOPEN && USE_CFBUNDLE
|
||||
-#include <CoreFoundation/CoreFoundation.h>
|
||||
-
|
||||
-/* Currently CoreFoundation only exists on the Mac so we just use
|
||||
- * pthreads directly to avoid creating empty function calls on other
|
||||
- * platforms. If a thread initializer ever gets created in the common
|
||||
- * plugin code, move this there */
|
||||
-static pthread_mutex_t krb5int_bundle_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
-#endif
|
||||
-
|
||||
#include <stdarg.h>
|
||||
static void Tprintf (const char *fmt, ...)
|
||||
{
|
||||
@@ -90,374 +70,193 @@ static void Tprintf (const char *fmt, ...)
|
||||
}
|
||||
|
||||
struct plugin_file_handle {
|
||||
-#if USE_DLOPEN
|
||||
+#if defined(USE_DLOPEN)
|
||||
void *dlhandle;
|
||||
-#endif
|
||||
-#ifdef _WIN32
|
||||
- HMODULE hinstPlugin;
|
||||
-#endif
|
||||
-#if !defined (USE_DLOPEN) && !defined (_WIN32)
|
||||
+#elif defined(_WIN32)
|
||||
+ HMODULE module;
|
||||
+#else
|
||||
char dummy;
|
||||
#endif
|
||||
};
|
||||
|
||||
-#ifdef _WIN32
|
||||
-struct dirent {
|
||||
- long d_ino; /* inode (always 1 in WIN32) */
|
||||
- off_t d_off; /* offset to this dirent */
|
||||
- unsigned short d_reclen; /* length of d_name */
|
||||
- char d_name[_MAX_FNAME+1]; /* filename (null terminated) */
|
||||
-};
|
||||
-
|
||||
-typedef struct {
|
||||
- intptr_t handle; /* _findfirst/_findnext handle */
|
||||
- short offset; /* offset into directory */
|
||||
- short finished; /* 1 if there are not more files */
|
||||
- struct _finddata_t fileinfo;/* from _findfirst/_findnext */
|
||||
- char *dir; /* the dir we are reading */
|
||||
- struct dirent dent; /* the dirent to return */
|
||||
-} DIR;
|
||||
+#if defined(USE_DLOPEN)
|
||||
|
||||
-DIR * opendir(const char *dir)
|
||||
+static long
|
||||
+open_plugin_dlfcn(struct plugin_file_handle *h, const char *filename,
|
||||
+ struct errinfo *ep)
|
||||
{
|
||||
- DIR *dp;
|
||||
- char *filespec;
|
||||
- intptr_t handle;
|
||||
- int index;
|
||||
-
|
||||
- filespec = malloc(strlen(dir) + 2 + 1);
|
||||
- strcpy(filespec, dir);
|
||||
- index = strlen(filespec) - 1;
|
||||
- if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
|
||||
- filespec[index] = '\0';
|
||||
- strcat(filespec, "/*");
|
||||
-
|
||||
- dp = (DIR *)malloc(sizeof(DIR));
|
||||
- dp->offset = 0;
|
||||
- dp->finished = 0;
|
||||
- dp->dir = strdup(dir);
|
||||
-
|
||||
- if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
|
||||
- if (errno == ENOENT)
|
||||
- dp->finished = 1;
|
||||
- else {
|
||||
- free(filespec);
|
||||
- free(dp->dir);
|
||||
- free(dp);
|
||||
- return NULL;
|
||||
- }
|
||||
+ const char *e;
|
||||
+
|
||||
+ h->dlhandle = dlopen(filename, PLUGIN_DLOPEN_FLAGS);
|
||||
+ if (h->dlhandle == NULL) {
|
||||
+ e = dlerror();
|
||||
+ if (e == NULL)
|
||||
+ e = _("unknown failure");
|
||||
+ Tprintf("dlopen(%s): %s\n", filename, e);
|
||||
+ k5_set_error(ep, ENOENT, _("unable to load plugin [%s]: %s"),
|
||||
+ filename, e);
|
||||
+ return ENOENT;
|
||||
}
|
||||
-
|
||||
- dp->handle = handle;
|
||||
- free(filespec);
|
||||
-
|
||||
- return dp;
|
||||
+ return 0;
|
||||
}
|
||||
+#define open_plugin open_plugin_dlfcn
|
||||
|
||||
-struct dirent * readdir(DIR *dp)
|
||||
+static long
|
||||
+get_sym_dlfcn(struct plugin_file_handle *h, const char *csymname,
|
||||
+ void **sym_out, struct errinfo *ep)
|
||||
{
|
||||
- if (!dp || dp->finished) return NULL;
|
||||
-
|
||||
- if (dp->offset != 0) {
|
||||
- if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
|
||||
- dp->finished = 1;
|
||||
- return NULL;
|
||||
- }
|
||||
+ const char *e;
|
||||
+
|
||||
+ if (h->dlhandle == NULL)
|
||||
+ return ENOENT;
|
||||
+ *sym_out = dlsym(h->dlhandle, csymname);
|
||||
+ if (*sym_out == NULL) {
|
||||
+ e = dlerror();
|
||||
+ if (e == NULL)
|
||||
+ e = _("unknown failure");
|
||||
+ Tprintf("dlsym(%s): %s\n", csymname, e);
|
||||
+ k5_set_error(ep, ENOENT, "%s", e);
|
||||
+ return ENOENT;
|
||||
}
|
||||
- dp->offset++;
|
||||
-
|
||||
- strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
|
||||
- dp->dent.d_ino = 1;
|
||||
- dp->dent.d_reclen = (unsigned short)strlen(dp->dent.d_name);
|
||||
- dp->dent.d_off = dp->offset;
|
||||
-
|
||||
- return &(dp->dent);
|
||||
-}
|
||||
-
|
||||
-int closedir(DIR *dp)
|
||||
-{
|
||||
- if (!dp) return 0;
|
||||
- _findclose(dp->handle);
|
||||
- free(dp->dir);
|
||||
- free(dp);
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
-#endif
|
||||
+#define get_sym get_sym_dlfcn
|
||||
|
||||
-long KRB5_CALLCONV
|
||||
-krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct errinfo *ep)
|
||||
+static void
|
||||
+close_plugin_dlfcn(struct plugin_file_handle *h)
|
||||
{
|
||||
- long err = 0;
|
||||
- struct plugin_file_handle *htmp = NULL;
|
||||
- int got_plugin = 0;
|
||||
-#if defined(USE_CFBUNDLE) || defined(_WIN32)
|
||||
- struct stat statbuf;
|
||||
-
|
||||
- if (!err) {
|
||||
- if (stat (filepath, &statbuf) < 0) {
|
||||
- err = errno;
|
||||
- Tprintf ("stat(%s): %s\n", filepath, strerror (err));
|
||||
- k5_set_error(ep, err, _("unable to find plugin [%s]: %s"),
|
||||
- filepath, strerror(err));
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- if (!err) {
|
||||
- htmp = calloc (1, sizeof (*htmp)); /* calloc initializes ptrs to NULL */
|
||||
- if (htmp == NULL) { err = ENOMEM; }
|
||||
- }
|
||||
-
|
||||
-#if USE_DLOPEN
|
||||
- if (!err
|
||||
-#if USE_CFBUNDLE
|
||||
- && ((statbuf.st_mode & S_IFMT) == S_IFREG
|
||||
- || (statbuf.st_mode & S_IFMT) == S_IFDIR)
|
||||
-#endif /* USE_CFBUNDLE */
|
||||
- ) {
|
||||
- void *handle = NULL;
|
||||
-
|
||||
-#if USE_CFBUNDLE
|
||||
- char executablepath[MAXPATHLEN];
|
||||
-
|
||||
- if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
|
||||
- int lock_err = 0;
|
||||
- CFStringRef pluginString = NULL;
|
||||
- CFURLRef pluginURL = NULL;
|
||||
- CFBundleRef pluginBundle = NULL;
|
||||
- CFURLRef executableURL = NULL;
|
||||
-
|
||||
- /* Lock around CoreFoundation calls since objects are refcounted
|
||||
- * and the refcounts are not thread-safe. Using pthreads directly
|
||||
- * because this code is Mac-specific */
|
||||
- lock_err = pthread_mutex_lock(&krb5int_bundle_mutex);
|
||||
- if (lock_err) { err = lock_err; }
|
||||
-
|
||||
- if (!err) {
|
||||
- pluginString = CFStringCreateWithCString (kCFAllocatorDefault,
|
||||
- filepath,
|
||||
- kCFStringEncodingASCII);
|
||||
- if (pluginString == NULL) { err = ENOMEM; }
|
||||
- }
|
||||
-
|
||||
- if (!err) {
|
||||
- pluginURL = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
|
||||
- pluginString,
|
||||
- kCFURLPOSIXPathStyle,
|
||||
- true);
|
||||
- if (pluginURL == NULL) { err = ENOMEM; }
|
||||
- }
|
||||
-
|
||||
- if (!err) {
|
||||
- pluginBundle = CFBundleCreate (kCFAllocatorDefault, pluginURL);
|
||||
- if (pluginBundle == NULL) { err = ENOENT; } /* XXX need better error */
|
||||
- }
|
||||
-
|
||||
- if (!err) {
|
||||
- executableURL = CFBundleCopyExecutableURL (pluginBundle);
|
||||
- if (executableURL == NULL) { err = ENOMEM; }
|
||||
- }
|
||||
-
|
||||
- if (!err) {
|
||||
- if (!CFURLGetFileSystemRepresentation (executableURL,
|
||||
- true, /* absolute */
|
||||
- (UInt8 *)executablepath,
|
||||
- sizeof (executablepath))) {
|
||||
- err = ENOMEM;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (!err) {
|
||||
- /* override the path the caller passed in */
|
||||
- filepath = executablepath;
|
||||
- }
|
||||
-
|
||||
- if (executableURL != NULL) { CFRelease (executableURL); }
|
||||
- if (pluginBundle != NULL) { CFRelease (pluginBundle); }
|
||||
- if (pluginURL != NULL) { CFRelease (pluginURL); }
|
||||
- if (pluginString != NULL) { CFRelease (pluginString); }
|
||||
-
|
||||
- /* unlock after CFRelease calls since they modify refcounts */
|
||||
- if (!lock_err) { pthread_mutex_unlock (&krb5int_bundle_mutex); }
|
||||
- }
|
||||
-#endif /* USE_CFBUNDLE */
|
||||
-
|
||||
- if (!err) {
|
||||
- handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS);
|
||||
- if (handle == NULL) {
|
||||
- const char *e = dlerror();
|
||||
- if (e == NULL)
|
||||
- e = _("unknown failure");
|
||||
- Tprintf ("dlopen(%s): %s\n", filepath, e);
|
||||
- err = ENOENT; /* XXX */
|
||||
- k5_set_error(ep, err, _("unable to load plugin [%s]: %s"),
|
||||
- filepath, e);
|
||||
- }
|
||||
- }
|
||||
+ if (h->dlhandle != NULL)
|
||||
+ dlclose(h->dlhandle);
|
||||
+}
|
||||
+#define close_plugin close_plugin_dlfcn
|
||||
|
||||
- if (!err) {
|
||||
- got_plugin = 1;
|
||||
- htmp->dlhandle = handle;
|
||||
- handle = NULL;
|
||||
- }
|
||||
+#elif defined(_WIN32)
|
||||
|
||||
- if (handle != NULL) { dlclose (handle); }
|
||||
+static long
|
||||
+open_plugin_win32(struct plugin_file_handle *h, const char *filename,
|
||||
+ struct errinfo *ep)
|
||||
+{
|
||||
+ h->module = LoadLibrary(filename);
|
||||
+ if (h == NULL) {
|
||||
+ Tprintf("Unable to load dll: %s\n", filename);
|
||||
+ k5_set_error(ep, ENOENT, _("unable to load DLL [%s]"), filename);
|
||||
+ return ENOENT;
|
||||
}
|
||||
-#endif /* USE_DLOPEN */
|
||||
-
|
||||
-#ifdef _WIN32
|
||||
- if (!err && (statbuf.st_mode & S_IFMT) == S_IFREG) {
|
||||
- HMODULE handle = NULL;
|
||||
+ return 0;
|
||||
+}
|
||||
+#define open_plugin open_plugin_win32
|
||||
|
||||
- handle = LoadLibrary(filepath);
|
||||
- if (handle == NULL) {
|
||||
- Tprintf ("Unable to load dll: %s\n", filepath);
|
||||
- err = ENOENT; /* XXX */
|
||||
- k5_set_error(ep, err, _("unable to load DLL [%s]"), filepath);
|
||||
- }
|
||||
+static long
|
||||
+get_sym_win32(struct plugin_file_handle *h, const char *csymname,
|
||||
+ void **sym_out, struct errinfo *ep)
|
||||
+{
|
||||
+ LPVOID lpMsgBuf;
|
||||
+ DWORD dw;
|
||||
|
||||
- if (!err) {
|
||||
- got_plugin = 1;
|
||||
- htmp->hinstPlugin = handle;
|
||||
- handle = NULL;
|
||||
+ if (h->module == NULL)
|
||||
+ return ENOENT;
|
||||
+ *sym_out = GetProcAddress(h->module, csymname);
|
||||
+ if (*sym_out == NULL) {
|
||||
+ Tprintf("GetProcAddress(%s): %i\n", csymname, GetLastError());
|
||||
+ dw = GetLastError();
|
||||
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
+ FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
+ NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
+ (LPTSTR)&lpMsgBuf, 0, NULL)) {
|
||||
+ k5_set_error(ep, ENOENT, _("unable to get DLL Symbol: %s"),
|
||||
+ (char *)lpMsgBuf);
|
||||
+ LocalFree(lpMsgBuf);
|
||||
}
|
||||
-
|
||||
- if (handle != NULL)
|
||||
- FreeLibrary(handle);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- if (!err && !got_plugin) {
|
||||
- err = ENOENT; /* no plugin or no way to load plugins */
|
||||
- k5_set_error(ep, err, _("plugin unavailable: %s"), strerror(err));
|
||||
+ return ENOENT;
|
||||
}
|
||||
+ return 0;
|
||||
+}
|
||||
+#define get_sym get_sym_win32
|
||||
|
||||
- if (!err) {
|
||||
- *h = htmp;
|
||||
- htmp = NULL; /* h takes ownership */
|
||||
- }
|
||||
+static void
|
||||
+close_plugin_win32(struct plugin_file_handle *h)
|
||||
+{
|
||||
+ if (h->module != NULL)
|
||||
+ FreeLibrary(h->module);
|
||||
+}
|
||||
+#define close_plugin close_plugin_win32
|
||||
|
||||
- free(htmp);
|
||||
+#else
|
||||
|
||||
- return err;
|
||||
+static long
|
||||
+open_plugin_dummy(struct plugin_file_handle *h, const char *filename,
|
||||
+ struct errinfo *ep)
|
||||
+{
|
||||
+ k5_set_error(ep, ENOENT, _("plugin loading unavailable"));
|
||||
+ return ENOENT;
|
||||
}
|
||||
+#define open_plugin open_plugin_dummy
|
||||
|
||||
static long
|
||||
-krb5int_get_plugin_sym (struct plugin_file_handle *h,
|
||||
- const char *csymname, int isfunc, void **ptr,
|
||||
- struct errinfo *ep)
|
||||
+get_sym_dummy(struct plugin_file_handle *h, const char *csymname,
|
||||
+ void **sym_out, struct errinfo *ep)
|
||||
{
|
||||
- long err = 0;
|
||||
- void *sym = NULL;
|
||||
+ return ENOENT;
|
||||
+}
|
||||
+#define get_sym get_sym_dummy
|
||||
+
|
||||
+static void
|
||||
+close_plugin_dummy(struct plugin_file_handle *h)
|
||||
+{
|
||||
+}
|
||||
+#define close_plugin close_plugin_dummy
|
||||
|
||||
-#if USE_DLOPEN
|
||||
- if (!err && !sym && (h->dlhandle != NULL)) {
|
||||
- /* XXX Do we need to add a leading "_" to the symbol name on any
|
||||
- modern platforms? */
|
||||
- sym = dlsym (h->dlhandle, csymname);
|
||||
- if (sym == NULL) {
|
||||
- const char *e = dlerror (); /* XXX copy and save away */
|
||||
- if (e == NULL)
|
||||
- e = "unknown failure";
|
||||
- Tprintf ("dlsym(%s): %s\n", csymname, e);
|
||||
- err = ENOENT; /* XXX */
|
||||
- k5_set_error(ep, err, "%s", e);
|
||||
- }
|
||||
- }
|
||||
#endif
|
||||
|
||||
-#ifdef _WIN32
|
||||
- LPVOID lpMsgBuf;
|
||||
- DWORD dw;
|
||||
+long KRB5_CALLCONV
|
||||
+krb5int_open_plugin(const char *filename,
|
||||
+ struct plugin_file_handle **handle_out, struct errinfo *ep)
|
||||
+{
|
||||
+ long ret;
|
||||
+ struct plugin_file_handle *h;
|
||||
|
||||
- if (!err && !sym && (h->hinstPlugin != NULL)) {
|
||||
- sym = GetProcAddress(h->hinstPlugin, csymname);
|
||||
- if (sym == NULL) {
|
||||
- const char *e = "unable to get dll symbol"; /* XXX copy and save away */
|
||||
- Tprintf ("GetProcAddress(%s): %i\n", csymname, GetLastError());
|
||||
- err = ENOENT; /* XXX */
|
||||
- k5_set_error(ep, err, "%s", e);
|
||||
-
|
||||
- dw = GetLastError();
|
||||
- if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
- FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
- NULL,
|
||||
- dw,
|
||||
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
- (LPTSTR) &lpMsgBuf,
|
||||
- 0, NULL )) {
|
||||
-
|
||||
- fprintf (stderr, "unable to get dll symbol, %s\n", (LPCTSTR)lpMsgBuf);
|
||||
- LocalFree(lpMsgBuf);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
+ *handle_out = NULL;
|
||||
|
||||
- if (!err && (sym == NULL)) {
|
||||
- err = ENOENT; /* unimplemented */
|
||||
- }
|
||||
+ h = calloc(1, sizeof(*h));
|
||||
+ if (h == NULL)
|
||||
+ return ENOMEM;
|
||||
|
||||
- if (!err) {
|
||||
- *ptr = sym;
|
||||
+ ret = open_plugin(h, filename, ep);
|
||||
+ if (ret) {
|
||||
+ free(h);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
- return err;
|
||||
+ *handle_out = h;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
long KRB5_CALLCONV
|
||||
-krb5int_get_plugin_data (struct plugin_file_handle *h, const char *csymname,
|
||||
- void **ptr, struct errinfo *ep)
|
||||
+krb5int_get_plugin_data(struct plugin_file_handle *h, const char *csymname,
|
||||
+ void **sym_out, struct errinfo *ep)
|
||||
{
|
||||
- return krb5int_get_plugin_sym (h, csymname, 0, ptr, ep);
|
||||
+ return get_sym(h, csymname, sym_out, ep);
|
||||
}
|
||||
|
||||
long KRB5_CALLCONV
|
||||
-krb5int_get_plugin_func (struct plugin_file_handle *h, const char *csymname,
|
||||
- void (**ptr)(), struct errinfo *ep)
|
||||
+krb5int_get_plugin_func(struct plugin_file_handle *h, const char *csymname,
|
||||
+ void (**sym_out)(), struct errinfo *ep)
|
||||
{
|
||||
void *dptr = NULL;
|
||||
- long err = krb5int_get_plugin_sym (h, csymname, 1, &dptr, ep);
|
||||
- if (!err) {
|
||||
- /* Cast function pointers to avoid code duplication */
|
||||
- *ptr = (void (*)()) dptr;
|
||||
- }
|
||||
- return err;
|
||||
+ long ret = get_sym(h, csymname, &dptr, ep);
|
||||
+
|
||||
+ if (!ret)
|
||||
+ *sym_out = (void (*)())dptr;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
void KRB5_CALLCONV
|
||||
krb5int_close_plugin (struct plugin_file_handle *h)
|
||||
{
|
||||
-#if USE_DLOPEN
|
||||
- if (h->dlhandle != NULL) { dlclose(h->dlhandle); }
|
||||
-#endif
|
||||
-#ifdef _WIN32
|
||||
- if (h->hinstPlugin != NULL) { FreeLibrary(h->hinstPlugin); }
|
||||
-#endif
|
||||
- free (h);
|
||||
+ close_plugin(h);
|
||||
+ free(h);
|
||||
}
|
||||
|
||||
-/* autoconf docs suggest using this preference order */
|
||||
-#if HAVE_DIRENT_H || USE_DIRENT_H
|
||||
-#include <dirent.h>
|
||||
-#define NAMELEN(D) strlen((D)->d_name)
|
||||
-#else
|
||||
-#ifndef _WIN32
|
||||
-#define dirent direct
|
||||
-#define NAMELEN(D) ((D)->d->namlen)
|
||||
-#else
|
||||
-#define NAMELEN(D) strlen((D)->d_name)
|
||||
-#endif
|
||||
-#if HAVE_SYS_NDIR_H
|
||||
-# include <sys/ndir.h>
|
||||
-#elif HAVE_SYS_DIR_H
|
||||
-# include <sys/dir.h>
|
||||
-#elif HAVE_NDIR_H
|
||||
-# include <ndir.h>
|
||||
-#endif
|
||||
-#endif
|
||||
-
|
||||
static long
|
||||
krb5int_plugin_file_handle_array_init (struct plugin_file_handle ***harray)
|
||||
{
|
||||
@@ -619,42 +418,36 @@ krb5int_open_plugin_dirs (const char * const *dirnames,
|
||||
if (handle != NULL) { krb5int_close_plugin (handle); }
|
||||
}
|
||||
} else {
|
||||
- /* load all plugins in each directory */
|
||||
- DIR *dir = opendir (dirnames[i]);
|
||||
+ char **fnames = NULL;
|
||||
+ int j;
|
||||
|
||||
- while (dir != NULL && !err) {
|
||||
- struct dirent *d = NULL;
|
||||
+ err = k5_dir_filenames(dirnames[i], &fnames);
|
||||
+ for (j = 0; !err && fnames[j] != NULL; j++) {
|
||||
char *filepath = NULL;
|
||||
struct plugin_file_handle *handle = NULL;
|
||||
|
||||
- d = readdir (dir);
|
||||
- if (d == NULL) { break; }
|
||||
-
|
||||
- if ((strcmp (d->d_name, ".") == 0) ||
|
||||
- (strcmp (d->d_name, "..") == 0)) {
|
||||
+ if (strcmp(fnames[j], ".") == 0 ||
|
||||
+ strcmp(fnames[j], "..") == 0)
|
||||
continue;
|
||||
- }
|
||||
|
||||
- if (!err) {
|
||||
- int len = NAMELEN (d);
|
||||
- if (asprintf(&filepath, "%s/%*s", dirnames[i], len, d->d_name) < 0) {
|
||||
- filepath = NULL;
|
||||
- err = ENOMEM;
|
||||
- }
|
||||
+ if (asprintf(&filepath, "%s/%s", dirnames[i], fnames[j]) < 0) {
|
||||
+ filepath = NULL;
|
||||
+ err = ENOMEM;
|
||||
}
|
||||
|
||||
- if (!err) {
|
||||
- if (krb5int_open_plugin (filepath, &handle, ep) == 0) {
|
||||
- err = krb5int_plugin_file_handle_array_add (&h, &count, handle);
|
||||
- if (!err) { handle = NULL; } /* h takes ownership */
|
||||
- }
|
||||
+ if (!err && krb5int_open_plugin(filepath, &handle, ep) == 0) {
|
||||
+ err = krb5int_plugin_file_handle_array_add(&h, &count,
|
||||
+ handle);
|
||||
+ if (!err)
|
||||
+ handle = NULL; /* h takes ownership */
|
||||
}
|
||||
|
||||
free(filepath);
|
||||
- if (handle != NULL) { krb5int_close_plugin (handle); }
|
||||
+ if (handle != NULL)
|
||||
+ krb5int_close_plugin(handle);
|
||||
}
|
||||
|
||||
- if (dir != NULL) { closedir (dir); }
|
||||
+ k5_free_filenames(fnames);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.38.1
|
||||
|
@ -1,220 +0,0 @@
|
||||
From 3a99832252755cf7e5fef2bd824459cea3eb823e Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Thu, 14 Jan 2021 18:13:09 -0500
|
||||
Subject: [PATCH] Add APIs for marshalling credentials
|
||||
|
||||
Faciliate KCM daemon implementations by providing functions to
|
||||
deserialize and reserialize credentials in the FILE v4 format.
|
||||
|
||||
[ghudson@mit.edu: minor editorial changes]
|
||||
|
||||
ticket: 8980 (new)
|
||||
(cherry picked from commit 18ea3bd2fca55b789b7de9c663624bc11d348fa6)
|
||||
---
|
||||
doc/appdev/refs/api/index.rst | 2 ++
|
||||
src/include/krb5/krb5.hin | 36 ++++++++++++++++++++++
|
||||
src/lib/krb5/ccache/ccmarshal.c | 53 +++++++++++++++++++++++++++++++++
|
||||
src/lib/krb5/ccache/t_marshal.c | 15 +++++++++-
|
||||
src/lib/krb5/libkrb5.exports | 2 ++
|
||||
src/lib/krb5_32.def | 4 +++
|
||||
6 files changed, 111 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/doc/appdev/refs/api/index.rst b/doc/appdev/refs/api/index.rst
|
||||
index 727d9b492..9e03fd386 100644
|
||||
--- a/doc/appdev/refs/api/index.rst
|
||||
+++ b/doc/appdev/refs/api/index.rst
|
||||
@@ -232,6 +232,7 @@ Rarely used public interfaces
|
||||
krb5_kt_remove_entry.rst
|
||||
krb5_kt_start_seq_get.rst
|
||||
krb5_make_authdata_kdc_issued.rst
|
||||
+ krb5_marshal_credentials.rst
|
||||
krb5_merge_authdata.rst
|
||||
krb5_mk_1cred.rst
|
||||
krb5_mk_error.rst
|
||||
@@ -285,6 +286,7 @@ Rarely used public interfaces
|
||||
krb5_tkt_creds_get_times.rst
|
||||
krb5_tkt_creds_init.rst
|
||||
krb5_tkt_creds_step.rst
|
||||
+ krb5_unmarshal_credentials.rst
|
||||
krb5_verify_init_creds.rst
|
||||
krb5_verify_init_creds_opt_init.rst
|
||||
krb5_verify_init_creds_opt_set_ap_req_nofail.rst
|
||||
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
||||
index 63e67a2ba..c26dde535 100644
|
||||
--- a/src/include/krb5/krb5.hin
|
||||
+++ b/src/include/krb5/krb5.hin
|
||||
@@ -3125,6 +3125,42 @@ krb5_get_credentials(krb5_context context, krb5_flags options,
|
||||
krb5_ccache ccache, krb5_creds *in_creds,
|
||||
krb5_creds **out_creds);
|
||||
|
||||
+/**
|
||||
+ * Serialize a @c krb5_creds object.
|
||||
+ *
|
||||
+ * @param [in] context Library context
|
||||
+ * @param [in] creds The credentials object to serialize
|
||||
+ * @param [out] data_out The serialized credentials
|
||||
+ *
|
||||
+ * Serialize @a creds in the format used by the FILE ccache format (vesion 4)
|
||||
+ * and KCM ccache protocol.
|
||||
+ *
|
||||
+ * Use krb5_free_data() to free @a data_out when it is no longer needed.
|
||||
+ *
|
||||
+ * @retval 0 Success; otherwise - Kerberos error codes
|
||||
+ */
|
||||
+krb5_error_code KRB5_CALLCONV
|
||||
+krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds,
|
||||
+ krb5_data **data_out);
|
||||
+
|
||||
+/**
|
||||
+ * Deserialize a @c krb5_creds object.
|
||||
+ *
|
||||
+ * @param [in] context Library context
|
||||
+ * @param [in] data The serialized credentials
|
||||
+ * @param [out] creds_out The resulting creds object
|
||||
+ *
|
||||
+ * Deserialize @a data to credentials in the format used by the FILE ccache
|
||||
+ * format (vesion 4) and KCM ccache protocol.
|
||||
+ *
|
||||
+ * Use krb5_free_creds() to free @a creds_out when it is no longer needed.
|
||||
+ *
|
||||
+ * @retval 0 Success; otherwise - Kerberos error codes
|
||||
+ */
|
||||
+krb5_error_code KRB5_CALLCONV
|
||||
+krb5_unmarshal_credentials(krb5_context context, const krb5_data *data,
|
||||
+ krb5_creds **creds_out);
|
||||
+
|
||||
/** @deprecated Replaced by krb5_get_validated_creds. */
|
||||
krb5_error_code KRB5_CALLCONV
|
||||
krb5_get_credentials_validate(krb5_context context, krb5_flags options,
|
||||
diff --git a/src/lib/krb5/ccache/ccmarshal.c b/src/lib/krb5/ccache/ccmarshal.c
|
||||
index ae634ccab..ab284e721 100644
|
||||
--- a/src/lib/krb5/ccache/ccmarshal.c
|
||||
+++ b/src/lib/krb5/ccache/ccmarshal.c
|
||||
@@ -515,3 +515,56 @@ k5_marshal_mcred(struct k5buf *buf, krb5_creds *mcred)
|
||||
if (mcred->second_ticket.length > 0)
|
||||
put_data(buf, version, &mcred->second_ticket);
|
||||
}
|
||||
+
|
||||
+krb5_error_code KRB5_CALLCONV
|
||||
+krb5_marshal_credentials(krb5_context context, krb5_creds *in_creds,
|
||||
+ krb5_data **data_out)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_data *data;
|
||||
+ struct k5buf buf;
|
||||
+
|
||||
+ *data_out = NULL;
|
||||
+
|
||||
+ data = k5alloc(sizeof(krb5_data), &ret);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ k5_buf_init_dynamic(&buf);
|
||||
+ k5_marshal_cred(&buf, 4, in_creds);
|
||||
+
|
||||
+ ret = k5_buf_status(&buf);
|
||||
+ if (ret) {
|
||||
+ free(data);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* Steal payload from buf. */
|
||||
+ *data = make_data(buf.data, buf.len);
|
||||
+ *data_out = data;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code KRB5_CALLCONV
|
||||
+krb5_unmarshal_credentials(krb5_context context, const krb5_data *data,
|
||||
+ krb5_creds **creds_out)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_creds *creds;
|
||||
+
|
||||
+ *creds_out = NULL;
|
||||
+
|
||||
+ creds = k5alloc(sizeof(krb5_creds), &ret);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = k5_unmarshal_cred((unsigned char *)data->data, data->length, 4,
|
||||
+ creds);
|
||||
+ if (ret) {
|
||||
+ free(creds);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ *creds_out = creds;
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/src/lib/krb5/ccache/t_marshal.c b/src/lib/krb5/ccache/t_marshal.c
|
||||
index bd0284afa..96e0931a2 100644
|
||||
--- a/src/lib/krb5/ccache/t_marshal.c
|
||||
+++ b/src/lib/krb5/ccache/t_marshal.c
|
||||
@@ -268,13 +268,14 @@ main(int argc, char **argv)
|
||||
krb5_context context;
|
||||
krb5_ccache cache;
|
||||
krb5_principal princ;
|
||||
- krb5_creds cred1, cred2;
|
||||
+ krb5_creds cred1, cred2, *alloc_cred;
|
||||
krb5_cc_cursor cursor;
|
||||
const char *filename;
|
||||
char *ccname, filebuf[256];
|
||||
int version, fd;
|
||||
const struct test *t;
|
||||
struct k5buf buf;
|
||||
+ krb5_data ser_data, *alloc_data;
|
||||
|
||||
if (argc != 2)
|
||||
abort();
|
||||
@@ -285,6 +286,18 @@ main(int argc, char **argv)
|
||||
if (krb5_init_context(&context) != 0)
|
||||
abort();
|
||||
|
||||
+ /* Test public functions for unmarshalling and marshalling. */
|
||||
+ ser_data = make_data((char *)tests[3].cred1, tests[3].cred1len);
|
||||
+ if (krb5_unmarshal_credentials(context, &ser_data, &alloc_cred) != 0)
|
||||
+ abort();
|
||||
+ verify_cred1(alloc_cred);
|
||||
+ if (krb5_marshal_credentials(context, alloc_cred, &alloc_data) != 0)
|
||||
+ abort();
|
||||
+ assert(alloc_data->length == tests[3].cred1len);
|
||||
+ assert(memcmp(tests[3].cred1, alloc_data->data, alloc_data->length) == 0);
|
||||
+ krb5_free_data(context, alloc_data);
|
||||
+ krb5_free_creds(context, alloc_cred);
|
||||
+
|
||||
for (version = FIRST_VERSION; version <= 4; version++) {
|
||||
t = &tests[version - 1];
|
||||
|
||||
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
|
||||
index 2d9d56530..adbfa332b 100644
|
||||
--- a/src/lib/krb5/libkrb5.exports
|
||||
+++ b/src/lib/krb5/libkrb5.exports
|
||||
@@ -489,6 +489,7 @@ krb5_lock_file
|
||||
krb5_make_authdata_kdc_issued
|
||||
krb5_make_full_ipaddr
|
||||
krb5_make_fulladdr
|
||||
+krb5_marshal_credentials
|
||||
krb5_mcc_ops
|
||||
krb5_merge_authdata
|
||||
krb5_mk_1cred
|
||||
@@ -592,6 +593,7 @@ krb5_timeofday
|
||||
krb5_timestamp_to_sfstring
|
||||
krb5_timestamp_to_string
|
||||
krb5_unlock_file
|
||||
+krb5_unmarshal_credentials
|
||||
krb5_unpack_full_ipaddr
|
||||
krb5_unparse_name
|
||||
krb5_unparse_name_ext
|
||||
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
|
||||
index 4953907aa..60b8dd311 100644
|
||||
--- a/src/lib/krb5_32.def
|
||||
+++ b/src/lib/krb5_32.def
|
||||
@@ -503,3 +503,7 @@ EXPORTS
|
||||
; new in 1.19
|
||||
k5_cc_store_primary_cred @470 ; PRIVATE
|
||||
k5_kt_have_match @471 ; PRIVATE GSSAPI
|
||||
+
|
||||
+; new in 1.20
|
||||
+ krb5_marshal_credentials @472
|
||||
+ krb5_unmarshal_credentials @473
|
@ -1,358 +0,0 @@
|
||||
From 8772d8f47b7460a0eef48366881483fd9b3acfd3 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Thu, 11 Feb 2021 15:33:10 +0100
|
||||
Subject: [PATCH] Add KCM_OP_GET_CRED_LIST for faster iteration
|
||||
|
||||
For large caches, one IPC operation per credential dominates the cost
|
||||
of iteration. Instead transfer the whole list of credentials to the
|
||||
client in one IPC operation.
|
||||
|
||||
Add optional support for the new opcode to the test KCM server to
|
||||
allow testing of the main and fallback code paths.
|
||||
|
||||
[ghudson@mit.edu: fixed memory leaks and potential memory errors;
|
||||
adjusted code style and comments; rewrote commit message; added
|
||||
kcmserver.py support and tests]
|
||||
|
||||
ticket: 8990 (new)
|
||||
(cherry picked from commit 81bdb47d8ded390263d8ee48f71d5c312b4f1736)
|
||||
---
|
||||
src/include/kcm.h | 12 ++-
|
||||
src/lib/krb5/ccache/cc_kcm.c | 144 ++++++++++++++++++++++++++++++++---
|
||||
src/tests/kcmserver.py | 28 ++++++-
|
||||
src/tests/t_ccache.py | 10 ++-
|
||||
4 files changed, 175 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/include/kcm.h b/src/include/kcm.h
|
||||
index 5ea1447cd..e4140c3a0 100644
|
||||
--- a/src/include/kcm.h
|
||||
+++ b/src/include/kcm.h
|
||||
@@ -51,9 +51,9 @@
|
||||
*
|
||||
* All replies begin with a 32-bit big-endian reply code.
|
||||
*
|
||||
- * Parameters are appended to the request or reply with no delimiters. Flags
|
||||
- * and time offsets are stored as 32-bit big-endian integers. Names are
|
||||
- * marshalled as zero-terminated strings. Principals and credentials are
|
||||
+ * Parameters are appended to the request or reply with no delimiters. Flags,
|
||||
+ * time offsets, and lengths are stored as 32-bit big-endian integers. Names
|
||||
+ * are marshalled as zero-terminated strings. Principals and credentials are
|
||||
* marshalled in the v4 FILE ccache format. UUIDs are 16 bytes. UUID lists
|
||||
* are not delimited, so nothing can come after them.
|
||||
*/
|
||||
@@ -89,7 +89,11 @@ typedef enum kcm_opcode {
|
||||
KCM_OP_HAVE_NTLM_CRED,
|
||||
KCM_OP_DEL_NTLM_CRED,
|
||||
KCM_OP_DO_NTLM_AUTH,
|
||||
- KCM_OP_GET_NTLM_USER_LIST
|
||||
+ KCM_OP_GET_NTLM_USER_LIST,
|
||||
+
|
||||
+ /* MIT extensions */
|
||||
+ KCM_OP_MIT_EXTENSION_BASE = 13000,
|
||||
+ KCM_OP_GET_CRED_LIST, /* (name) -> (count, count*{len, cred}) */
|
||||
} kcm_opcode;
|
||||
|
||||
#endif /* KCM_H */
|
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
||||
index 9093f894d..772928e4d 100644
|
||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
||||
@@ -61,6 +61,17 @@ struct uuid_list {
|
||||
size_t pos;
|
||||
};
|
||||
|
||||
+struct cred_list {
|
||||
+ krb5_creds *creds;
|
||||
+ size_t count;
|
||||
+ size_t pos;
|
||||
+};
|
||||
+
|
||||
+struct kcm_cursor {
|
||||
+ struct uuid_list *uuids;
|
||||
+ struct cred_list *creds;
|
||||
+};
|
||||
+
|
||||
struct kcmio {
|
||||
SOCKET fd;
|
||||
#ifdef __APPLE__
|
||||
@@ -489,6 +500,69 @@ free_uuid_list(struct uuid_list *uuids)
|
||||
free(uuids);
|
||||
}
|
||||
|
||||
+static void
|
||||
+free_cred_list(struct cred_list *list)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (list == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ /* Creds are transferred to the caller as list->pos is incremented, so we
|
||||
+ * can start freeing there. */
|
||||
+ for (i = list->pos; i < list->count; i++)
|
||||
+ krb5_free_cred_contents(NULL, &list->creds[i]);
|
||||
+ free(list->creds);
|
||||
+ free(list);
|
||||
+}
|
||||
+
|
||||
+/* Fetch a cred list from req->reply. */
|
||||
+static krb5_error_code
|
||||
+kcmreq_get_cred_list(struct kcmreq *req, struct cred_list **creds_out)
|
||||
+{
|
||||
+ struct cred_list *list;
|
||||
+ const unsigned char *data;
|
||||
+ krb5_error_code ret = 0;
|
||||
+ size_t count, len, i;
|
||||
+
|
||||
+ *creds_out = NULL;
|
||||
+
|
||||
+ /* Check a rough bound on the count to prevent very large allocations. */
|
||||
+ count = k5_input_get_uint32_be(&req->reply);
|
||||
+ if (count > req->reply.len / 4)
|
||||
+ return KRB5_KCM_MALFORMED_REPLY;
|
||||
+
|
||||
+ list = malloc(sizeof(*list));
|
||||
+ if (list == NULL)
|
||||
+ return ENOMEM;
|
||||
+
|
||||
+ list->creds = NULL;
|
||||
+ list->count = count;
|
||||
+ list->pos = 0;
|
||||
+ list->creds = k5calloc(count, sizeof(*list->creds), &ret);
|
||||
+ if (list->creds == NULL) {
|
||||
+ free(list);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ len = k5_input_get_uint32_be(&req->reply);
|
||||
+ data = k5_input_get_bytes(&req->reply, len);
|
||||
+ if (data == NULL)
|
||||
+ break;
|
||||
+ ret = k5_unmarshal_cred(data, len, 4, &list->creds[i]);
|
||||
+ if (ret)
|
||||
+ break;
|
||||
+ }
|
||||
+ if (i < count) {
|
||||
+ free_cred_list(list);
|
||||
+ return (ret == ENOMEM) ? ENOMEM : KRB5_KCM_MALFORMED_REPLY;
|
||||
+ }
|
||||
+
|
||||
+ *creds_out = list;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
kcmreq_free(struct kcmreq *req)
|
||||
{
|
||||
@@ -753,33 +827,53 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache,
|
||||
{
|
||||
krb5_error_code ret;
|
||||
struct kcmreq req = EMPTY_KCMREQ;
|
||||
- struct uuid_list *uuids;
|
||||
+ struct uuid_list *uuids = NULL;
|
||||
+ struct cred_list *creds = NULL;
|
||||
+ struct kcm_cursor *cursor;
|
||||
|
||||
*cursor_out = NULL;
|
||||
|
||||
get_kdc_offset(context, cache);
|
||||
|
||||
- kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache);
|
||||
+ kcmreq_init(&req, KCM_OP_GET_CRED_LIST, cache);
|
||||
ret = cache_call(context, cache, &req);
|
||||
- if (ret)
|
||||
+ if (ret == 0) {
|
||||
+ /* GET_CRED_LIST is available. */
|
||||
+ ret = kcmreq_get_cred_list(&req, &creds);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+ } else if (ret == KRB5_FCC_INTERNAL) {
|
||||
+ /* Fall back to GET_CRED_UUID_LIST. */
|
||||
+ kcmreq_free(&req);
|
||||
+ kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache);
|
||||
+ ret = cache_call(context, cache, &req);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+ ret = kcmreq_get_uuid_list(&req, &uuids);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+ } else {
|
||||
goto cleanup;
|
||||
- ret = kcmreq_get_uuid_list(&req, &uuids);
|
||||
- if (ret)
|
||||
+ }
|
||||
+
|
||||
+ cursor = k5alloc(sizeof(*cursor), &ret);
|
||||
+ if (cursor == NULL)
|
||||
goto cleanup;
|
||||
- *cursor_out = (krb5_cc_cursor)uuids;
|
||||
+ cursor->uuids = uuids;
|
||||
+ cursor->creds = creds;
|
||||
+ *cursor_out = (krb5_cc_cursor)cursor;
|
||||
|
||||
cleanup:
|
||||
kcmreq_free(&req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static krb5_error_code KRB5_CALLCONV
|
||||
-kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
|
||||
- krb5_creds *cred_out)
|
||||
+static krb5_error_code
|
||||
+next_cred_by_uuid(krb5_context context, krb5_ccache cache,
|
||||
+ struct uuid_list *uuids, krb5_creds *cred_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
struct kcmreq req;
|
||||
- struct uuid_list *uuids = (struct uuid_list *)*cursor;
|
||||
|
||||
memset(cred_out, 0, sizeof(*cred_out));
|
||||
|
||||
@@ -797,11 +891,39 @@ kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
|
||||
return map_invalid(ret);
|
||||
}
|
||||
|
||||
+static krb5_error_code KRB5_CALLCONV
|
||||
+kcm_next_cred(krb5_context context, krb5_ccache cache, krb5_cc_cursor *cursor,
|
||||
+ krb5_creds *cred_out)
|
||||
+{
|
||||
+ struct kcm_cursor *c = (struct kcm_cursor *)*cursor;
|
||||
+ struct cred_list *list;
|
||||
+
|
||||
+ if (c->uuids != NULL)
|
||||
+ return next_cred_by_uuid(context, cache, c->uuids, cred_out);
|
||||
+
|
||||
+ list = c->creds;
|
||||
+ if (list->pos >= list->count)
|
||||
+ return KRB5_CC_END;
|
||||
+
|
||||
+ /* Transfer memory ownership of one cred to the caller. */
|
||||
+ *cred_out = list->creds[list->pos];
|
||||
+ memset(&list->creds[list->pos], 0, sizeof(*list->creds));
|
||||
+ list->pos++;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static krb5_error_code KRB5_CALLCONV
|
||||
kcm_end_seq_get(krb5_context context, krb5_ccache cache,
|
||||
krb5_cc_cursor *cursor)
|
||||
{
|
||||
- free_uuid_list((struct uuid_list *)*cursor);
|
||||
+ struct kcm_cursor *c = *cursor;
|
||||
+
|
||||
+ if (c == NULL)
|
||||
+ return 0;
|
||||
+ free_uuid_list(c->uuids);
|
||||
+ free_cred_list(c->creds);
|
||||
+ free(c);
|
||||
*cursor = NULL;
|
||||
return 0;
|
||||
}
|
||||
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py
|
||||
index 57432e5a7..8c5e66ff1 100644
|
||||
--- a/src/tests/kcmserver.py
|
||||
+++ b/src/tests/kcmserver.py
|
||||
@@ -23,6 +23,7 @@
|
||||
# traceback.print_exception(etype, value, tb, file=f)
|
||||
# sys.excepthook = ehook
|
||||
|
||||
+import optparse
|
||||
import select
|
||||
import socket
|
||||
import struct
|
||||
@@ -49,12 +50,14 @@ class KCMOpcodes(object):
|
||||
SET_DEFAULT_CACHE = 21
|
||||
GET_KDC_OFFSET = 22
|
||||
SET_KDC_OFFSET = 23
|
||||
+ GET_CRED_LIST = 13001
|
||||
|
||||
|
||||
class KRB5Errors(object):
|
||||
KRB5_CC_END = -1765328242
|
||||
KRB5_CC_NOSUPP = -1765328137
|
||||
KRB5_FCC_NOFILE = -1765328189
|
||||
+ KRB5_FCC_INTERNAL = -1765328188
|
||||
|
||||
|
||||
def make_uuid():
|
||||
@@ -183,6 +186,14 @@ def op_set_kdc_offset(argbytes):
|
||||
return 0, b''
|
||||
|
||||
|
||||
+def op_get_cred_list(argbytes):
|
||||
+ name, rest = unmarshal_name(argbytes)
|
||||
+ cache = get_cache(name)
|
||||
+ creds = [cache.creds[u] for u in cache.cred_uuids]
|
||||
+ return 0, (struct.pack('>L', len(creds)) +
|
||||
+ b''.join(struct.pack('>L', len(c)) + c for c in creds))
|
||||
+
|
||||
+
|
||||
ophandlers = {
|
||||
KCMOpcodes.GEN_NEW : op_gen_new,
|
||||
KCMOpcodes.INITIALIZE : op_initialize,
|
||||
@@ -197,7 +208,8 @@ ophandlers = {
|
||||
KCMOpcodes.GET_DEFAULT_CACHE : op_get_default_cache,
|
||||
KCMOpcodes.SET_DEFAULT_CACHE : op_set_default_cache,
|
||||
KCMOpcodes.GET_KDC_OFFSET : op_get_kdc_offset,
|
||||
- KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset
|
||||
+ KCMOpcodes.SET_KDC_OFFSET : op_set_kdc_offset,
|
||||
+ KCMOpcodes.GET_CRED_LIST : op_get_cred_list
|
||||
}
|
||||
|
||||
# Read and respond to a request from the socket s.
|
||||
@@ -215,7 +227,11 @@ def service_request(s):
|
||||
|
||||
majver, minver, op = struct.unpack('>BBH', req[:4])
|
||||
argbytes = req[4:]
|
||||
- code, payload = ophandlers[op](argbytes)
|
||||
+
|
||||
+ if op in ophandlers:
|
||||
+ code, payload = ophandlers[op](argbytes)
|
||||
+ else:
|
||||
+ code, payload = KRB5Errors.KRB5_FCC_INTERNAL, b''
|
||||
|
||||
# The KCM response is the code (4 bytes) and the response payload.
|
||||
# The Heimdal IPC response is the length of the KCM response (4
|
||||
@@ -226,9 +242,15 @@ def service_request(s):
|
||||
s.sendall(hipc_response)
|
||||
return True
|
||||
|
||||
+parser = optparse.OptionParser()
|
||||
+parser.add_option('-c', '--credlist', action='store_true', dest='credlist',
|
||||
+ default=False, help='Support KCM_OP_GET_CRED_LIST')
|
||||
+(options, args) = parser.parse_args()
|
||||
+if not options.credlist:
|
||||
+ del ophandlers[KCMOpcodes.GET_CRED_LIST]
|
||||
|
||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
-server.bind(sys.argv[1])
|
||||
+server.bind(args[0])
|
||||
server.listen(5)
|
||||
select_input = [server,]
|
||||
sys.stderr.write('starting...\n')
|
||||
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
|
||||
index 66804afa5..90040fb7b 100755
|
||||
--- a/src/tests/t_ccache.py
|
||||
+++ b/src/tests/t_ccache.py
|
||||
@@ -125,10 +125,18 @@ def collection_test(realm, ccname):
|
||||
|
||||
|
||||
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc'))
|
||||
+
|
||||
+# Test KCM without and with GET_CRED_LIST support.
|
||||
kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py')
|
||||
-realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
|
||||
+kcmd = realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
|
||||
+ 'starting...')
|
||||
+collection_test(realm, 'KCM:')
|
||||
+stop_daemon(kcmd)
|
||||
+os.remove(kcm_socket_path)
|
||||
+realm.start_server([sys.executable, kcmserver_path, '-c', kcm_socket_path],
|
||||
'starting...')
|
||||
collection_test(realm, 'KCM:')
|
||||
+
|
||||
if test_keyring:
|
||||
def cleanup_keyring(anchor, name):
|
||||
out = realm.run(['keyctl', 'list', anchor])
|
@ -1,25 +0,0 @@
|
||||
From 2f039fc910022c9569fe6941a194f0b26bd6c894 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Fri, 20 Sep 2019 16:11:29 -0400
|
||||
Subject: [PATCH] Add buildsystem detection of the OpenSSL-3 KDF interface
|
||||
|
||||
(cherry picked from commit a3e03dfd40928c4615bd9b8546eac0c104377850)
|
||||
---
|
||||
src/configure.ac | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index eb6307468..9c2e816fe 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -282,6 +282,10 @@ AC_SUBST(CRYPTO_IMPL)
|
||||
AC_SUBST(CRYPTO_IMPL_CFLAGS)
|
||||
AC_SUBST(CRYPTO_IMPL_LIBS)
|
||||
|
||||
+if test "$CRYPTO_IMPL" = openssl; then
|
||||
+ AC_CHECK_FUNCS(EVP_KDF_fetch)
|
||||
+fi
|
||||
+
|
||||
AC_ARG_WITH([prng-alg],
|
||||
AC_HELP_STRING([--with-prng-alg=ALG], [use specified PRNG algorithm. @<:@fortuna@:>@]),
|
||||
[PRNG_ALG=$withval
|
@ -1,84 +0,0 @@
|
||||
From e88f0319427cee7245fb05c97a25473297c9d2d6 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 15 Jan 2021 14:43:34 -0500
|
||||
Subject: [PATCH] Add hostname canonicalization helper to k5test.py
|
||||
|
||||
To facilitate fallback tests, add a canonicalize_hostname() function
|
||||
to k5test.py which works similarly to krb5_expand_hostname(). Use it
|
||||
in t_gssapi.py for the recently-added acceptor name fallback test.
|
||||
|
||||
(cherry picked from commit 225fffe4e912772acea3a01d45bafb60bfb80948)
|
||||
---
|
||||
src/tests/gssapi/t_gssapi.py | 11 +++--------
|
||||
src/util/k5test.py | 22 ++++++++++++++++++++++
|
||||
2 files changed, 25 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py
|
||||
index 1af6f31c2..e22cec427 100755
|
||||
--- a/src/tests/gssapi/t_gssapi.py
|
||||
+++ b/src/tests/gssapi/t_gssapi.py
|
||||
@@ -8,7 +8,7 @@ for realm in multipass_realms():
|
||||
realm.run(['./t_iov', '-s', 'p:' + realm.host_princ])
|
||||
realm.run(['./t_pcontok', 'p:' + realm.host_princ])
|
||||
|
||||
-realm = K5Realm(krb5_conf={'libdefaults': {'rdns': 'false'}})
|
||||
+realm = K5Realm()
|
||||
|
||||
# Test gss_add_cred().
|
||||
realm.run(['./t_add_cred'])
|
||||
@@ -62,13 +62,8 @@ realm.run(['./t_accname', 'p:host/-nomatch-',
|
||||
expected_msg=' not found in keytab')
|
||||
|
||||
# If possible, test with an acceptor name requiring fallback to match
|
||||
-# against a keytab entry. Forward-canonicalize the hostname, relying
|
||||
-# on the rdns=false realm setting.
|
||||
-try:
|
||||
- ai = socket.getaddrinfo(hostname, None, 0, 0, 0, socket.AI_CANONNAME)
|
||||
- (family, socktype, proto, canonname, sockaddr) = ai[0]
|
||||
-except socket.gaierror:
|
||||
- canonname = hostname
|
||||
+# against a keytab entry.
|
||||
+canonname = canonicalize_hostname(hostname)
|
||||
if canonname != hostname:
|
||||
os.rename(realm.keytab, realm.keytab + '.save')
|
||||
canonprinc = 'host/' + canonname
|
||||
diff --git a/src/util/k5test.py b/src/util/k5test.py
|
||||
index 789b0f4b9..251d11a9d 100644
|
||||
--- a/src/util/k5test.py
|
||||
+++ b/src/util/k5test.py
|
||||
@@ -155,6 +155,10 @@ Scripts may use the following functions and variables:
|
||||
* password(name): Return a weakly random password based on name. The
|
||||
password will be consistent across calls with the same name.
|
||||
|
||||
+* canonicalize_hostname(name, rdns=True): Return the DNS
|
||||
+ canonicalization of name, optionally using reverse DNS. On error,
|
||||
+ return name converted to lowercase.
|
||||
+
|
||||
* stop_daemon(proc): Stop a daemon process started with
|
||||
realm.start_server() or realm.start_in_inetd(). Only necessary if
|
||||
the port needs to be reused; daemon processes will be stopped
|
||||
@@ -458,6 +462,24 @@ def password(name):
|
||||
return name + str(os.getpid())
|
||||
|
||||
|
||||
+def canonicalize_hostname(name, rdns=True):
|
||||
+ """Canonicalize name using DNS, optionally with reverse DNS."""
|
||||
+ try:
|
||||
+ ai = socket.getaddrinfo(name, None, 0, 0, 0, socket.AI_CANONNAME)
|
||||
+ except socket.gaierror as e:
|
||||
+ return name.lower()
|
||||
+ (family, socktype, proto, canonname, sockaddr) = ai[0]
|
||||
+
|
||||
+ if not rdns:
|
||||
+ return canonname.lower()
|
||||
+
|
||||
+ try:
|
||||
+ rname = socket.getnameinfo(sockaddr, socket.NI_NAMEREQD)
|
||||
+ except socket.gaierror:
|
||||
+ return canonname.lower()
|
||||
+ return rname[0].lower()
|
||||
+
|
||||
+
|
||||
# Exit handler which ensures processes are cleaned up and, on failure,
|
||||
# prints messages to help developers debug the problem.
|
||||
def _onexit():
|
@ -1,60 +0,0 @@
|
||||
From fb4d9fa851b1d0d3375556d1cdc1fce72176df1e Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Thu, 3 Jun 2021 16:03:07 -0400
|
||||
Subject: [PATCH] Allow kinit with keytab to defer canonicalization
|
||||
|
||||
[ghudson@mit.edu: added tests]
|
||||
|
||||
ticket: 9012 (new)
|
||||
(cherry picked from commit 5e6a6efc5df689d9fb8730d0227167ffbb6ece0e)
|
||||
---
|
||||
src/clients/kinit/kinit.c | 11 -----------
|
||||
src/tests/t_keytab.py | 13 +++++++++++++
|
||||
2 files changed, 13 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/clients/kinit/kinit.c b/src/clients/kinit/kinit.c
|
||||
index d1f5d74c3..5a6d7237c 100644
|
||||
--- a/src/clients/kinit/kinit.c
|
||||
+++ b/src/clients/kinit/kinit.c
|
||||
@@ -510,17 +510,6 @@ k5_begin(struct k_opts *opts, struct k5_data *k5)
|
||||
_("when creating default server principal name"));
|
||||
goto cleanup;
|
||||
}
|
||||
- if (k5->me->realm.data[0] == 0) {
|
||||
- ret = krb5_unparse_name(k5->ctx, k5->me, &k5->name);
|
||||
- if (ret == 0) {
|
||||
- com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
|
||||
- _("(principal %s)"), k5->name);
|
||||
- } else {
|
||||
- com_err(progname, KRB5_ERR_HOST_REALM_UNKNOWN,
|
||||
- _("for local services"));
|
||||
- }
|
||||
- goto cleanup;
|
||||
- }
|
||||
} else if (k5->out_cc != NULL) {
|
||||
/* If the output ccache is initialized, use its principal. */
|
||||
if (krb5_cc_get_principal(k5->ctx, k5->out_cc, &princ) == 0)
|
||||
diff --git a/src/tests/t_keytab.py b/src/tests/t_keytab.py
|
||||
index 850375c92..a9adebb26 100755
|
||||
--- a/src/tests/t_keytab.py
|
||||
+++ b/src/tests/t_keytab.py
|
||||
@@ -41,6 +41,19 @@ realm.kinit(realm.user_princ, flags=['-i'],
|
||||
expected_msg='keytab specified, forcing -k')
|
||||
realm.klist(realm.user_princ)
|
||||
|
||||
+# Test default principal for -k. This operation requires
|
||||
+# canonicalization against the keytab in krb5_get_init_creds_keytab()
|
||||
+# as the krb5_sname_to_principal() result won't have a realm. Try
|
||||
+# with and without without fallback processing since the code paths
|
||||
+# are different.
|
||||
+mark('default principal for -k')
|
||||
+realm.run([kinit, '-k'])
|
||||
+realm.klist(realm.host_princ)
|
||||
+no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}}
|
||||
+no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf)
|
||||
+realm.run([kinit, '-k'], env=no_canon)
|
||||
+realm.klist(realm.host_princ)
|
||||
+
|
||||
# Test extracting keys with multiple key versions present.
|
||||
mark('multi-kvno extract')
|
||||
os.remove(realm.keytab)
|
@ -1,35 +0,0 @@
|
||||
From 95547c12b39e62df55cef05cae890302834b7f98 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Wed, 23 Jun 2021 16:57:39 -0400
|
||||
Subject: [PATCH] Clean up context after failed open in libkdb5
|
||||
|
||||
If krb5_db_open() or krb5_db_create() fails, release the dal_handle,
|
||||
as the caller is unlikely to call krb5_db_close() after a failure.
|
||||
|
||||
(cherry picked from commit 849b7056e703bd3724d909263769ce190db59acc)
|
||||
---
|
||||
src/lib/kdb/kdb5.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c
|
||||
index 47e9b31a7..11e2430c4 100644
|
||||
--- a/src/lib/kdb/kdb5.c
|
||||
+++ b/src/lib/kdb/kdb5.c
|
||||
@@ -675,6 +675,8 @@ krb5_db_open(krb5_context kcontext, char **db_args, int mode)
|
||||
return status;
|
||||
status = v->init_module(kcontext, section, db_args, mode);
|
||||
free(section);
|
||||
+ if (status)
|
||||
+ (void)krb5_db_fini(kcontext);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -702,6 +704,8 @@ krb5_db_create(krb5_context kcontext, char **db_args)
|
||||
return status;
|
||||
status = v->create(kcontext, section, db_args);
|
||||
free(section);
|
||||
+ if (status)
|
||||
+ (void)krb5_db_fini(kcontext);
|
||||
return status;
|
||||
}
|
||||
|
@ -1,193 +0,0 @@
|
||||
From 5e5ea8e8345c8b2f3254b0d346b8e0de0df3a696 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Wed, 26 May 2021 18:22:10 -0400
|
||||
Subject: [PATCH] Clean up gssapi_krb5 ccache name functions
|
||||
|
||||
Modernize kg_get_ccache_name() and kg_get_ccache_name(). Drop
|
||||
unnecessary use of const in kg_get_ccache_name() so that its return
|
||||
value can be properly freed. Fixes some static analyzer false
|
||||
positives.
|
||||
|
||||
(cherry picked from commit f573f7f8ee5269103a0492d6521a3242c5ffb63b)
|
||||
---
|
||||
src/lib/gssapi/krb5/gssapiP_krb5.h | 3 +-
|
||||
src/lib/gssapi/krb5/gssapi_krb5.c | 47 ++++++++--------------
|
||||
src/lib/gssapi/krb5/set_ccache.c | 64 ++++++++++++------------------
|
||||
3 files changed, 42 insertions(+), 72 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
|
||||
index fd7abbd77..88d41130a 100644
|
||||
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
|
||||
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
|
||||
@@ -380,8 +380,7 @@ OM_uint32 kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status);
|
||||
OM_uint32 kg_caller_provided_ccache_name (OM_uint32 *minor_status,
|
||||
int *out_caller_provided_name);
|
||||
|
||||
-OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status,
|
||||
- const char **out_name);
|
||||
+OM_uint32 kg_get_ccache_name (OM_uint32 *minor_status, char **out_name);
|
||||
|
||||
OM_uint32 kg_set_ccache_name (OM_uint32 *minor_status,
|
||||
const char *name);
|
||||
diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
|
||||
index 46aa9b7a5..9915a8bb5 100644
|
||||
--- a/src/lib/gssapi/krb5/gssapi_krb5.c
|
||||
+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
|
||||
@@ -253,46 +253,31 @@ kg_caller_provided_ccache_name (OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
-kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name)
|
||||
+kg_get_ccache_name(OM_uint32 *minor_status, char **out_name)
|
||||
{
|
||||
- const char *name = NULL;
|
||||
- OM_uint32 err = 0;
|
||||
char *kg_ccache_name;
|
||||
+ const char *def_name;
|
||||
+ OM_uint32 err;
|
||||
+ krb5_context context;
|
||||
+
|
||||
+ *out_name = NULL;
|
||||
|
||||
kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME);
|
||||
-
|
||||
if (kg_ccache_name != NULL) {
|
||||
- name = strdup(kg_ccache_name);
|
||||
- if (name == NULL)
|
||||
- err = ENOMEM;
|
||||
+ *out_name = strdup(kg_ccache_name);
|
||||
+ err = (*out_name == NULL) ? ENOMEM : 0;
|
||||
} else {
|
||||
- krb5_context context = NULL;
|
||||
-
|
||||
- /* Reset the context default ccache (see text above), and then
|
||||
- retrieve it. */
|
||||
+ /* Use the default ccache name. */
|
||||
err = krb5_gss_init_context(&context);
|
||||
- if (!err)
|
||||
- err = krb5_cc_set_default_name (context, NULL);
|
||||
- if (!err) {
|
||||
- name = krb5_cc_default_name(context);
|
||||
- if (name) {
|
||||
- name = strdup(name);
|
||||
- if (name == NULL)
|
||||
- err = ENOMEM;
|
||||
- }
|
||||
- }
|
||||
- if (err && context)
|
||||
- save_error_info(err, context);
|
||||
- if (context)
|
||||
- krb5_free_context(context);
|
||||
- }
|
||||
-
|
||||
- if (!err) {
|
||||
- if (out_name) {
|
||||
- *out_name = name;
|
||||
- }
|
||||
+ if (err)
|
||||
+ goto cleanup;
|
||||
+ def_name = krb5_cc_default_name(context);
|
||||
+ *out_name = (def_name != NULL) ? strdup(def_name) : NULL;
|
||||
+ err = (*out_name == NULL) ? ENOMEM : 0;
|
||||
+ krb5_free_context(context);
|
||||
}
|
||||
|
||||
+cleanup:
|
||||
*minor_status = err;
|
||||
return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
|
||||
}
|
||||
diff --git a/src/lib/gssapi/krb5/set_ccache.c b/src/lib/gssapi/krb5/set_ccache.c
|
||||
index 8acf3ec90..91c3462be 100644
|
||||
--- a/src/lib/gssapi/krb5/set_ccache.c
|
||||
+++ b/src/lib/gssapi/krb5/set_ccache.c
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/*
|
||||
* Set ccache name used by gssapi, and optionally obtain old ccache
|
||||
- * name. Caller should not free returned name.
|
||||
+ * name. Caller must not free returned name.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@@ -38,11 +38,9 @@ gss_krb5int_ccache_name(OM_uint32 *minor_status,
|
||||
const gss_OID desired_object,
|
||||
const gss_buffer_t value)
|
||||
{
|
||||
- char *old_name = NULL;
|
||||
OM_uint32 err = 0;
|
||||
- OM_uint32 minor = 0;
|
||||
- char *gss_out_name;
|
||||
struct krb5_gss_ccache_name_req *req;
|
||||
+ char *old_name, *cur_name = NULL;
|
||||
|
||||
err = gss_krb5int_initialize_library();
|
||||
if (err) {
|
||||
@@ -57,45 +55,33 @@ gss_krb5int_ccache_name(OM_uint32 *minor_status,
|
||||
|
||||
req = (struct krb5_gss_ccache_name_req *)value->value;
|
||||
|
||||
- gss_out_name = k5_getspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME);
|
||||
+ /* Our job is simple if the caller doesn't want the current name. */
|
||||
+ if (req->out_name == NULL)
|
||||
+ return kg_set_ccache_name(minor_status, req->name);
|
||||
|
||||
- if (req->out_name) {
|
||||
- const char *tmp_name = NULL;
|
||||
+ /* Fetch the current name and change it. */
|
||||
+ kg_get_ccache_name(&err, &cur_name);
|
||||
+ if (err)
|
||||
+ goto cleanup;
|
||||
+ kg_set_ccache_name(&err, req->name);
|
||||
+ if (err)
|
||||
+ goto cleanup;
|
||||
|
||||
- if (!err) {
|
||||
- kg_get_ccache_name (&err, &tmp_name);
|
||||
- }
|
||||
- if (!err) {
|
||||
- old_name = gss_out_name;
|
||||
- gss_out_name = (char *)tmp_name;
|
||||
- }
|
||||
- }
|
||||
- /* If out_name was NULL, we keep the same gss_out_name value, and
|
||||
- don't free up any storage (leave old_name NULL). */
|
||||
+ /* Store the current name in a thread-specific variable. Free that
|
||||
+ * variable's previous contents. */
|
||||
+ old_name = k5_getspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME);
|
||||
+ err = k5_setspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, cur_name);
|
||||
+ if (err)
|
||||
+ goto cleanup;
|
||||
+ free(old_name);
|
||||
|
||||
- if (!err)
|
||||
- kg_set_ccache_name (&err, req->name);
|
||||
-
|
||||
- minor = k5_setspecific(K5_KEY_GSS_KRB5_SET_CCACHE_OLD_NAME, gss_out_name);
|
||||
- if (minor) {
|
||||
- /* Um. Now what? */
|
||||
- if (err == 0) {
|
||||
- err = minor;
|
||||
- }
|
||||
- free(gss_out_name);
|
||||
- gss_out_name = NULL;
|
||||
- }
|
||||
-
|
||||
- if (!err) {
|
||||
- if (req->out_name) {
|
||||
- *(req->out_name) = gss_out_name;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (old_name != NULL) {
|
||||
- free (old_name);
|
||||
- }
|
||||
+ /* Give the caller an alias to the stored value. */
|
||||
+ *req->out_name = cur_name;
|
||||
+ cur_name = NULL;
|
||||
+ err = 0;
|
||||
|
||||
+cleanup:
|
||||
+ free(cur_name);
|
||||
*minor_status = err;
|
||||
return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
From 1528c264d0e1eebff34132c01f4f770f01f1d1c2 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 29 Mar 2021 14:32:56 -0400
|
||||
Subject: [PATCH] Fix KCM flag transmission for remove_cred
|
||||
|
||||
MIT krb5 uses low bits for KRB5_TC flags, while Heimdal uses high bits
|
||||
so that the same flag word can also hold KRB5_GC flags. Add a mapping
|
||||
function and send the Heimdal flag values when performing a
|
||||
remove_cred operation.
|
||||
|
||||
ticket: 8995
|
||||
(cherry picked from commit 11a82cf424f9c905bb73680c64524f087090d4ef)
|
||||
---
|
||||
src/include/kcm.h | 19 +++++++++++++++++++
|
||||
src/lib/krb5/ccache/cc_kcm.c | 36 +++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 54 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/include/kcm.h b/src/include/kcm.h
|
||||
index e4140c3a0..9b66f1cbd 100644
|
||||
--- a/src/include/kcm.h
|
||||
+++ b/src/include/kcm.h
|
||||
@@ -56,8 +56,27 @@
|
||||
* are marshalled as zero-terminated strings. Principals and credentials are
|
||||
* marshalled in the v4 FILE ccache format. UUIDs are 16 bytes. UUID lists
|
||||
* are not delimited, so nothing can come after them.
|
||||
+ *
|
||||
+ * Flag words must use Heimdal flag values, which are not the same as MIT krb5
|
||||
+ * values for KRB5_GC and KRB5_TC constants. The same flag word may contain
|
||||
+ * both kinds of flags in Heimdal, but not in MIT krb5. Defines for the
|
||||
+ * applicable Heimdal flag values are given below using KCM_GC and KCM_TC
|
||||
+ * prefixes.
|
||||
*/
|
||||
|
||||
+#define KCM_GC_CACHED (1U << 0)
|
||||
+
|
||||
+#define KCM_TC_DONT_MATCH_REALM (1U << 31)
|
||||
+#define KCM_TC_MATCH_KEYTYPE (1U << 30)
|
||||
+#define KCM_TC_MATCH_SRV_NAMEONLY (1U << 29)
|
||||
+#define KCM_TC_MATCH_FLAGS_EXACT (1U << 28)
|
||||
+#define KCM_TC_MATCH_FLAGS (1U << 27)
|
||||
+#define KCM_TC_MATCH_TIMES_EXACT (1U << 26)
|
||||
+#define KCM_TC_MATCH_TIMES (1U << 25)
|
||||
+#define KCM_TC_MATCH_AUTHDATA (1U << 24)
|
||||
+#define KCM_TC_MATCH_2ND_TKT (1U << 23)
|
||||
+#define KCM_TC_MATCH_IS_SKEY (1U << 22)
|
||||
+
|
||||
/* Opcodes without comments are currently unused in the MIT client
|
||||
* implementation. */
|
||||
typedef enum kcm_opcode {
|
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
||||
index 772928e4d..1f81a2190 100644
|
||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
||||
@@ -110,6 +110,40 @@ map_invalid(krb5_error_code code)
|
||||
KRB5_KCM_MALFORMED_REPLY : code;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Map an MIT krb5 KRB5_TC flag word to the equivalent Heimdal flag word. Note
|
||||
+ * that there is no MIT krb5 equivalent for Heimdal's KRB5_TC_DONT_MATCH_REALM
|
||||
+ * (which is like KRB5_TC_MATCH_SRV_NAMEONLY but also applies to the client
|
||||
+ * principal) and no Heimdal equivalent for MIT krb5's KRB5_TC_SUPPORTED_KTYPES
|
||||
+ * (which matches against enctypes from the krb5_context rather than the
|
||||
+ * matching cred).
|
||||
+ */
|
||||
+static inline krb5_flags
|
||||
+map_tcflags(krb5_flags mitflags)
|
||||
+{
|
||||
+ krb5_flags heimflags = 0;
|
||||
+
|
||||
+ if (mitflags & KRB5_TC_MATCH_TIMES)
|
||||
+ heimflags |= KCM_TC_MATCH_TIMES;
|
||||
+ if (mitflags & KRB5_TC_MATCH_IS_SKEY)
|
||||
+ heimflags |= KCM_TC_MATCH_IS_SKEY;
|
||||
+ if (mitflags & KRB5_TC_MATCH_FLAGS)
|
||||
+ heimflags |= KCM_TC_MATCH_FLAGS;
|
||||
+ if (mitflags & KRB5_TC_MATCH_TIMES_EXACT)
|
||||
+ heimflags |= KCM_TC_MATCH_TIMES_EXACT;
|
||||
+ if (mitflags & KRB5_TC_MATCH_FLAGS_EXACT)
|
||||
+ heimflags |= KCM_TC_MATCH_FLAGS_EXACT;
|
||||
+ if (mitflags & KRB5_TC_MATCH_AUTHDATA)
|
||||
+ heimflags |= KCM_TC_MATCH_AUTHDATA;
|
||||
+ if (mitflags & KRB5_TC_MATCH_SRV_NAMEONLY)
|
||||
+ heimflags |= KCM_TC_MATCH_SRV_NAMEONLY;
|
||||
+ if (mitflags & KRB5_TC_MATCH_2ND_TKT)
|
||||
+ heimflags |= KCM_TC_MATCH_2ND_TKT;
|
||||
+ if (mitflags & KRB5_TC_MATCH_KTYPE)
|
||||
+ heimflags |= KCM_TC_MATCH_KEYTYPE;
|
||||
+ return heimflags;
|
||||
+}
|
||||
+
|
||||
/* Begin a request for the given opcode. If cache is non-null, supply the
|
||||
* cache name as a request parameter. */
|
||||
static void
|
||||
@@ -936,7 +970,7 @@ kcm_remove_cred(krb5_context context, krb5_ccache cache, krb5_flags flags,
|
||||
struct kcmreq req;
|
||||
|
||||
kcmreq_init(&req, KCM_OP_REMOVE_CRED, cache);
|
||||
- k5_buf_add_uint32_be(&req.reqbuf, flags);
|
||||
+ k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags));
|
||||
k5_marshal_mcred(&req.reqbuf, mcred);
|
||||
ret = cache_call(context, cache, &req);
|
||||
kcmreq_free(&req);
|
@ -1,62 +0,0 @@
|
||||
From 43be8fba5301d08fc4d5ddef14f8ae3d9655b0ba Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Tue, 11 May 2021 14:04:07 -0400
|
||||
Subject: [PATCH] Fix KCM retrieval support for sssd
|
||||
|
||||
Commit 795ebba8c039be172ab93cd41105c73ffdba0fdb added a retrieval
|
||||
handler using KCM_OP_RETRIEVE, falling back on the same error codes as
|
||||
the previous KCM_OP_GET_CRED_LIST support. But sssd (as of 2.4)
|
||||
returns KRB5_CC_NOSUPP instead of KRB5_CC_IO if it recognizes an
|
||||
opcode but does not implement it. Add a helper function to recognize
|
||||
all known unsupported-opcode error codes, and use it in kcm_retrieve()
|
||||
and kcm_start_seq_get().
|
||||
|
||||
ticket: 8997
|
||||
(cherry picked from commit da103e36e13f3c846bcddbe38dd518a21e5260a0)
|
||||
---
|
||||
src/lib/krb5/ccache/cc_kcm.c | 18 ++++++++++++++++--
|
||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
||||
index 23fcf13ea..18505cd3d 100644
|
||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
||||
@@ -144,6 +144,20 @@ map_tcflags(krb5_flags mitflags)
|
||||
return heimflags;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Return true if code could indicate an unsupported operation. Heimdal's KCM
|
||||
+ * returns KRB5_FCC_INTERNAL. sssd's KCM daemon (as of sssd 2.4) returns
|
||||
+ * KRB5_CC_NO_SUPP if it recognizes the operation but does not implement it,
|
||||
+ * and KRB5_CC_IO if it doesn't recognize the operation (which is unfortunate
|
||||
+ * since it could also indicate a communication failure).
|
||||
+ */
|
||||
+static krb5_boolean
|
||||
+unsupported_op_error(krb5_error_code code)
|
||||
+{
|
||||
+ return code == KRB5_FCC_INTERNAL || code == KRB5_CC_IO ||
|
||||
+ code == KRB5_CC_NOSUPP;
|
||||
+}
|
||||
+
|
||||
/* Begin a request for the given opcode. If cache is non-null, supply the
|
||||
* cache name as a request parameter. */
|
||||
static void
|
||||
@@ -841,7 +855,7 @@ kcm_retrieve(krb5_context context, krb5_ccache cache, krb5_flags flags,
|
||||
ret = cache_call(context, cache, &req);
|
||||
|
||||
/* Fall back to iteration if the server does not support retrieval. */
|
||||
- if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) {
|
||||
+ if (unsupported_op_error(ret)) {
|
||||
ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred,
|
||||
cred_out);
|
||||
goto cleanup;
|
||||
@@ -922,7 +936,7 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache,
|
||||
ret = kcmreq_get_cred_list(&req, &creds);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
- } else if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) {
|
||||
+ } else if (unsupported_op_error(ret)) {
|
||||
/* Fall back to GET_CRED_UUID_LIST. */
|
||||
kcmreq_free(&req);
|
||||
kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache);
|
@ -1,45 +0,0 @@
|
||||
From bb8fa495d00ccd931eec87a01b8920636cf7903e Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Tue, 3 Aug 2021 01:15:27 -0400
|
||||
Subject: [PATCH] Fix KDC null deref on TGS inner body null server
|
||||
|
||||
After the KDC decodes a FAST inner body, it does not check for a null
|
||||
server. Prior to commit 39548a5b17bbda9eeb63625a201cfd19b9de1c5b this
|
||||
would typically result in an error from krb5_unparse_name(), but with
|
||||
the addition of get_local_tgt() it results in a null dereference. Add
|
||||
a null check.
|
||||
|
||||
Reported by Joseph Sutton of Catalyst.
|
||||
|
||||
CVE-2021-37750:
|
||||
|
||||
In MIT krb5 releases 1.14 and later, an authenticated attacker can
|
||||
cause a null dereference in the KDC by sending a FAST TGS request with
|
||||
no server field.
|
||||
|
||||
ticket: 9008 (new)
|
||||
tags: pullup
|
||||
target_version: 1.19-next
|
||||
target_version: 1.18-next
|
||||
|
||||
(cherry picked from commit d775c95af7606a51bf79547a94fa52ddd1cb7f49)
|
||||
---
|
||||
src/kdc/do_tgs_req.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
|
||||
index 6d244ffd4..39a504ca1 100644
|
||||
--- a/src/kdc/do_tgs_req.c
|
||||
+++ b/src/kdc/do_tgs_req.c
|
||||
@@ -207,6 +207,11 @@ process_tgs_req(krb5_kdc_req *request, krb5_data *pkt,
|
||||
status = "FIND_FAST";
|
||||
goto cleanup;
|
||||
}
|
||||
+ if (sprinc == NULL) {
|
||||
+ status = "NULL_SERVER";
|
||||
+ errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
|
||||
errcode = get_local_tgt(kdc_context, &sprinc->realm, header_server,
|
||||
&local_tgt, &local_tgt_storage, &local_tgt_key);
|
@ -1,106 +0,0 @@
|
||||
From 06d30f43a41029d83248bbac1a9b65fc09987597 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 17 Oct 2022 20:25:11 -0400
|
||||
Subject: [PATCH] Fix integer overflows in PAC parsing
|
||||
|
||||
In krb5_parse_pac(), check for buffer counts large enough to threaten
|
||||
integer overflow in the header length and memory length calculations.
|
||||
Avoid potential integer overflows when checking the length of each
|
||||
buffer.
|
||||
|
||||
CVE-2022-42898:
|
||||
|
||||
In MIT krb5 releases 1.8 and later, an authenticated attacker may be
|
||||
able to cause a KDC or kadmind process to crash by reading beyond the
|
||||
bounds of allocated memory, creating a denial of service. A
|
||||
privileged attacker may similarly be able to cause a Kerberos or GSS
|
||||
application service to crash. On 32-bit platforms, an attacker can
|
||||
also cause insufficient memory to be allocated for the result,
|
||||
potentially leading to remote code execution in a KDC, kadmind, or GSS
|
||||
or Kerberos application server process. An attacker with the
|
||||
privileges of a cross-realm KDC may be able to extract secrets from
|
||||
the KDC process's memory by having them copied into the PAC of a new
|
||||
ticket.
|
||||
|
||||
ticket: 9074 (new)
|
||||
tags: pullup
|
||||
target_version: 1.20-next
|
||||
target_version: 1.19-next
|
||||
---
|
||||
src/lib/krb5/krb/pac.c | 9 +++++++--
|
||||
src/lib/krb5/krb/t_pac.c | 18 ++++++++++++++++++
|
||||
2 files changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
|
||||
index 950beda657..1b9ef12276 100644
|
||||
--- a/src/lib/krb5/krb/pac.c
|
||||
+++ b/src/lib/krb5/krb/pac.c
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "k5-int.h"
|
||||
#include "authdata.h"
|
||||
|
||||
+#define MAX_BUFFERS 4096
|
||||
+
|
||||
/* draft-brezak-win2k-krb-authz-00 */
|
||||
|
||||
/*
|
||||
@@ -316,6 +318,9 @@ krb5_pac_parse(krb5_context context,
|
||||
if (version != 0)
|
||||
return EINVAL;
|
||||
|
||||
+ if (cbuffers < 1 || cbuffers > MAX_BUFFERS)
|
||||
+ return ERANGE;
|
||||
+
|
||||
header_len = PACTYPE_LENGTH + (cbuffers * PAC_INFO_BUFFER_LENGTH);
|
||||
if (len < header_len)
|
||||
return ERANGE;
|
||||
@@ -348,8 +353,8 @@ krb5_pac_parse(krb5_context context,
|
||||
krb5_pac_free(context, pac);
|
||||
return EINVAL;
|
||||
}
|
||||
- if (buffer->Offset < header_len ||
|
||||
- buffer->Offset + buffer->cbBufferSize > len) {
|
||||
+ if (buffer->Offset < header_len || buffer->Offset > len ||
|
||||
+ buffer->cbBufferSize > len - buffer->Offset) {
|
||||
krb5_pac_free(context, pac);
|
||||
return ERANGE;
|
||||
}
|
||||
diff --git a/src/lib/krb5/krb/t_pac.c b/src/lib/krb5/krb/t_pac.c
|
||||
index ee47152ee4..ccd165380d 100644
|
||||
--- a/src/lib/krb5/krb/t_pac.c
|
||||
+++ b/src/lib/krb5/krb/t_pac.c
|
||||
@@ -431,6 +431,16 @@ static const unsigned char s4u_pac_ent_xrealm[] = {
|
||||
0x8a, 0x81, 0x9c, 0x9c, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
+static const unsigned char fuzz1[] = {
|
||||
+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x06, 0xff, 0xff, 0xff, 0x00, 0x00, 0xf5
|
||||
+};
|
||||
+
|
||||
+static const unsigned char fuzz2[] = {
|
||||
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x20, 0x20
|
||||
+};
|
||||
+
|
||||
static const char *s4u_principal = "w2k8u@ACME.COM";
|
||||
static const char *s4u_enterprise = "w2k8u@abc@ACME.COM";
|
||||
|
||||
@@ -646,6 +656,14 @@ main(int argc, char **argv)
|
||||
krb5_free_principal(context, sep);
|
||||
}
|
||||
|
||||
+ /* Check problematic PACs found by fuzzing. */
|
||||
+ ret = krb5_pac_parse(context, fuzz1, sizeof(fuzz1), &pac);
|
||||
+ if (!ret)
|
||||
+ err(context, ret, "krb5_pac_parse should have failed");
|
||||
+ ret = krb5_pac_parse(context, fuzz2, sizeof(fuzz2), &pac);
|
||||
+ if (!ret)
|
||||
+ err(context, ret, "krb5_pac_parse should have failed");
|
||||
+
|
||||
/*
|
||||
* Test empty free
|
||||
*/
|
||||
--
|
||||
2.37.3
|
||||
|
@ -1,58 +0,0 @@
|
||||
From 51938a8b731740299fe47d132b8840edba4141bc Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Sat, 29 May 2021 12:05:49 -0400
|
||||
Subject: [PATCH] Fix k5tls module for OpenSSL 3
|
||||
|
||||
Starting in OpenSSL 3, connection termination without a close_notify
|
||||
alert causes SSL_read() to return SSL_ERROR_SSL instead of
|
||||
SSL_ERROR_SYSCALL. OpenSSL 3 also provides a new option
|
||||
SSL_OP_IGNORE_UNEXPECTED_EOF which allows an application to explicitly
|
||||
ignore possible truncation attacks and receive SSL_ERROR_ZERO_RETURN
|
||||
instead.
|
||||
|
||||
Remove the call to SSL_CTX_get_options() since SSL_CTX_set_options()
|
||||
doesn't clear existing options.
|
||||
|
||||
[ghudson@mit.edu: edited commit message and comment]
|
||||
|
||||
(cherry picked from commit aa9b4a2a64046afd2fab7cb49c346295874a5fb6)
|
||||
(cherry picked from commit 201e38845e9f70234bcaa9ba7c25b28e38169b0a)
|
||||
---
|
||||
src/plugins/tls/k5tls/openssl.c | 17 ++++++++++++++---
|
||||
1 file changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c
|
||||
index 76a43b3cd..99fda7ffc 100644
|
||||
--- a/src/plugins/tls/k5tls/openssl.c
|
||||
+++ b/src/plugins/tls/k5tls/openssl.c
|
||||
@@ -433,7 +433,7 @@ setup(krb5_context context, SOCKET fd, const char *servername,
|
||||
char **anchors, k5_tls_handle *handle_out)
|
||||
{
|
||||
int e;
|
||||
- long options;
|
||||
+ long options = SSL_OP_NO_SSLv2;
|
||||
SSL_CTX *ctx = NULL;
|
||||
SSL *ssl = NULL;
|
||||
k5_tls_handle handle = NULL;
|
||||
@@ -448,8 +448,19 @@ setup(krb5_context context, SOCKET fd, const char *servername,
|
||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if (ctx == NULL)
|
||||
goto error;
|
||||
- options = SSL_CTX_get_options(ctx);
|
||||
- SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2);
|
||||
+
|
||||
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
|
||||
+ /*
|
||||
+ * For OpenSSL 3 and later, mark close_notify alerts as optional. We don't
|
||||
+ * need to worry about truncation attacks because the protocols this module
|
||||
+ * is used with (Kerberos and change-password) receive a single
|
||||
+ * length-delimited message from the server. For prior versions of OpenSSL
|
||||
+ * we check for SSL_ERROR_SYSCALL when reading instead (this error changes
|
||||
+ * to SSL_ERROR_SSL in OpenSSL 3).
|
||||
+ */
|
||||
+ options |= SSL_OP_IGNORE_UNEXPECTED_EOF;
|
||||
+#endif
|
||||
+ SSL_CTX_set_options(ctx, options);
|
||||
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
|
||||
X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0);
|
@ -1,64 +0,0 @@
|
||||
From 2d2bb9a14613b3283dabdd40c3ee28e5b680cf93 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 7 Jun 2021 15:00:41 -0400
|
||||
Subject: [PATCH] Fix kadmin -k with fallback or referral realm
|
||||
|
||||
kadmin -k produces a client principal name with
|
||||
krb5_sname_to_principal(), but it gets converted to a string and back
|
||||
due to the signature of kadm5_init_with_skey(), which loses track of
|
||||
the name type, so no canonicalization is performed.
|
||||
|
||||
In libkadm5clnt initialization, recognize the important subset of this
|
||||
case--an empty realm indicates either fallback processing or the
|
||||
referral realm--and restore the host-based name type so that the
|
||||
client principal can be canonicalized against the keytab.
|
||||
|
||||
ticket: 9013 (new)
|
||||
(cherry picked from commit dcb79089276624d7ddf44e08d35bd6d7d7e557d2)
|
||||
---
|
||||
src/lib/kadm5/clnt/client_init.c | 7 +++++++
|
||||
src/tests/t_kadmin.py | 12 ++++++++++++
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c
|
||||
index aa1223bb3..0aaca701f 100644
|
||||
--- a/src/lib/kadm5/clnt/client_init.c
|
||||
+++ b/src/lib/kadm5/clnt/client_init.c
|
||||
@@ -221,9 +221,16 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
return KADM5_MISSING_KRB5_CONF_PARAMS;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Parse the client name. If it has an empty realm, it is almost certainly
|
||||
+ * a host-based principal using DNS fallback processing or the referral
|
||||
+ * realm, so give it the appropriate name type for canonicalization.
|
||||
+ */
|
||||
code = krb5_parse_name(handle->context, client_name, &client);
|
||||
if (code)
|
||||
goto error;
|
||||
+ if (init_type == INIT_SKEY && client->realm.length == 0)
|
||||
+ client->type = KRB5_NT_SRV_HST;
|
||||
|
||||
/*
|
||||
* Get credentials. Also does some fallbacks in case kadmin/fqdn
|
||||
diff --git a/src/tests/t_kadmin.py b/src/tests/t_kadmin.py
|
||||
index fe6a3cc2e..98453d92e 100644
|
||||
--- a/src/tests/t_kadmin.py
|
||||
+++ b/src/tests/t_kadmin.py
|
||||
@@ -51,4 +51,16 @@ for i in range(200):
|
||||
realm.run_kadmin(['addprinc', '-randkey', 'foo%d' % i])
|
||||
realm.run_kadmin(['listprincs'], expected_msg='foo199')
|
||||
|
||||
+# Test kadmin -k with the default principal, with and without
|
||||
+# fallback. This operation requires canonicalization against the
|
||||
+# keytab in krb5_get_init_creds_keytab() as the
|
||||
+# krb5_sname_to_principal() result won't have a realm. Try with and
|
||||
+# without without fallback processing since the code paths are
|
||||
+# different.
|
||||
+mark('kadmin -k')
|
||||
+realm.run([kadmin, '-k', 'getprinc', realm.host_princ])
|
||||
+no_canon_conf = {'libdefaults': {'dns_canonicalize_hostname': 'false'}}
|
||||
+no_canon = realm.special_env('no_canon', False, krb5_conf=no_canon_conf)
|
||||
+realm.run([kadmin, '-k', 'getprinc', realm.host_princ], env=no_canon)
|
||||
+
|
||||
success('kadmin and kpasswd tests')
|
@ -1,664 +0,0 @@
|
||||
From a14e0fd3c1d00ba625e6d9eb72829f31527c6ad8 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Wed, 23 Jun 2021 16:53:16 -0400
|
||||
Subject: [PATCH] Fix leaks on error in kadm5 init functions
|
||||
|
||||
In the GENERIC_CHECK_HANDLE function, separate out the
|
||||
version-checking logic so we can call it in the init functions before
|
||||
allocating resources.
|
||||
|
||||
In the client and server library initialization functions, use a
|
||||
single exit path after argument validation, and share the destruction
|
||||
code with kadm5_destroy() via a helper.
|
||||
|
||||
(cherry picked from commit 552d7b7626450f963b8e37345c472420c842402c)
|
||||
---
|
||||
src/lib/kadm5/admin_internal.h | 39 ++++---
|
||||
src/lib/kadm5/clnt/client_init.c | 174 +++++++++++-----------------
|
||||
src/lib/kadm5/srv/server_init.c | 191 ++++++++++---------------------
|
||||
3 files changed, 145 insertions(+), 259 deletions(-)
|
||||
|
||||
diff --git a/src/lib/kadm5/admin_internal.h b/src/lib/kadm5/admin_internal.h
|
||||
index faf8e9c36..9be53883a 100644
|
||||
--- a/src/lib/kadm5/admin_internal.h
|
||||
+++ b/src/lib/kadm5/admin_internal.h
|
||||
@@ -11,29 +11,32 @@
|
||||
|
||||
#define KADM5_SERVER_HANDLE_MAGIC 0x12345800
|
||||
|
||||
-#define GENERIC_CHECK_HANDLE(handle, old_api_version, new_api_version) \
|
||||
+#define CHECK_VERSIONS(struct_version, api_version, old_api_err, new_api_err) \
|
||||
{ \
|
||||
- kadm5_server_handle_t srvr = \
|
||||
- (kadm5_server_handle_t) handle; \
|
||||
- \
|
||||
- if (! srvr) \
|
||||
- return KADM5_BAD_SERVER_HANDLE; \
|
||||
- if (srvr->magic_number != KADM5_SERVER_HANDLE_MAGIC) \
|
||||
- return KADM5_BAD_SERVER_HANDLE; \
|
||||
- if ((srvr->struct_version & KADM5_MASK_BITS) != \
|
||||
- KADM5_STRUCT_VERSION_MASK) \
|
||||
+ if ((struct_version & KADM5_MASK_BITS) != KADM5_STRUCT_VERSION_MASK) \
|
||||
return KADM5_BAD_STRUCT_VERSION; \
|
||||
- if (srvr->struct_version < KADM5_STRUCT_VERSION_1) \
|
||||
+ if (struct_version < KADM5_STRUCT_VERSION_1) \
|
||||
return KADM5_OLD_STRUCT_VERSION; \
|
||||
- if (srvr->struct_version > KADM5_STRUCT_VERSION_1) \
|
||||
+ if (struct_version > KADM5_STRUCT_VERSION_1) \
|
||||
return KADM5_NEW_STRUCT_VERSION; \
|
||||
- if ((srvr->api_version & KADM5_MASK_BITS) != \
|
||||
- KADM5_API_VERSION_MASK) \
|
||||
+ if ((api_version & KADM5_MASK_BITS) != KADM5_API_VERSION_MASK) \
|
||||
return KADM5_BAD_API_VERSION; \
|
||||
- if (srvr->api_version < KADM5_API_VERSION_2) \
|
||||
- return old_api_version; \
|
||||
- if (srvr->api_version > KADM5_API_VERSION_4) \
|
||||
- return new_api_version; \
|
||||
+ if (api_version < KADM5_API_VERSION_2) \
|
||||
+ return old_api_err; \
|
||||
+ if (api_version > KADM5_API_VERSION_4) \
|
||||
+ return new_api_err; \
|
||||
+ }
|
||||
+
|
||||
+#define GENERIC_CHECK_HANDLE(handle, old_api_err, new_api_err) \
|
||||
+ { \
|
||||
+ kadm5_server_handle_t srvr = handle; \
|
||||
+ \
|
||||
+ if (srvr == NULL) \
|
||||
+ return KADM5_BAD_SERVER_HANDLE; \
|
||||
+ if (srvr->magic_number != KADM5_SERVER_HANDLE_MAGIC) \
|
||||
+ return KADM5_BAD_SERVER_HANDLE; \
|
||||
+ CHECK_VERSIONS(srvr->struct_version, srvr->api_version, \
|
||||
+ old_api_err, new_api_err); \
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c
|
||||
index 0aaca701f..75614bb19 100644
|
||||
--- a/src/lib/kadm5/clnt/client_init.c
|
||||
+++ b/src/lib/kadm5/clnt/client_init.c
|
||||
@@ -138,6 +138,36 @@ kadm5_init_with_skey(krb5_context context, char *client_name,
|
||||
server_handle);
|
||||
}
|
||||
|
||||
+static kadm5_ret_t
|
||||
+free_handle(kadm5_server_handle_t handle)
|
||||
+{
|
||||
+ kadm5_ret_t ret = 0;
|
||||
+ OM_uint32 minor_stat;
|
||||
+ krb5_ccache ccache;
|
||||
+
|
||||
+ if (handle == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (handle->destroy_cache && handle->cache_name != NULL) {
|
||||
+ ret = krb5_cc_resolve(handle->context, handle->cache_name, &ccache);
|
||||
+ if (!ret)
|
||||
+ ret = krb5_cc_destroy(handle->context, ccache);
|
||||
+ }
|
||||
+ free(handle->cache_name);
|
||||
+ (void)gss_release_cred(&minor_stat, &handle->cred);
|
||||
+ if (handle->clnt != NULL && handle->clnt->cl_auth != NULL)
|
||||
+ AUTH_DESTROY(handle->clnt->cl_auth);
|
||||
+ if (handle->clnt != NULL)
|
||||
+ clnt_destroy(handle->clnt);
|
||||
+ if (handle->client_socket != -1)
|
||||
+ close(handle->client_socket);
|
||||
+ free(handle->lhandle);
|
||||
+ kadm5_free_config_params(handle->context, &handle->params);
|
||||
+ free(handle);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static kadm5_ret_t
|
||||
init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
char *pass, krb5_ccache ccache_in, char *service_name,
|
||||
@@ -145,36 +175,34 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
krb5_ui_4 api_version, char **db_args, void **server_handle)
|
||||
{
|
||||
int fd = -1;
|
||||
- OM_uint32 minor_stat;
|
||||
krb5_boolean iprop_enable;
|
||||
int port;
|
||||
rpcprog_t rpc_prog;
|
||||
rpcvers_t rpc_vers;
|
||||
- krb5_ccache ccache;
|
||||
krb5_principal client = NULL, server = NULL;
|
||||
struct timeval timeout;
|
||||
|
||||
- kadm5_server_handle_t handle;
|
||||
+ kadm5_server_handle_t handle = NULL;
|
||||
kadm5_config_params params_local;
|
||||
|
||||
- int code = 0;
|
||||
+ krb5_error_code code;
|
||||
generic_ret r = { 0, 0 };
|
||||
|
||||
initialize_ovk_error_table();
|
||||
initialize_ovku_error_table();
|
||||
|
||||
- if (! server_handle) {
|
||||
+ if (server_handle == NULL || client_name == NULL)
|
||||
return EINVAL;
|
||||
- }
|
||||
|
||||
- if (! (handle = malloc(sizeof(*handle)))) {
|
||||
- return ENOMEM;
|
||||
- }
|
||||
- memset(handle, 0, sizeof(*handle));
|
||||
- if (! (handle->lhandle = malloc(sizeof(*handle)))) {
|
||||
- free(handle);
|
||||
- return ENOMEM;
|
||||
- }
|
||||
+ CHECK_VERSIONS(struct_version, api_version, KADM5_OLD_LIB_API_VERSION,
|
||||
+ KADM5_NEW_LIB_API_VERSION);
|
||||
+
|
||||
+ handle = k5alloc(sizeof(*handle), &code);
|
||||
+ if (handle == NULL)
|
||||
+ goto cleanup;
|
||||
+ handle->lhandle = k5alloc(sizeof(*handle), &code);
|
||||
+ if (handle->lhandle == NULL)
|
||||
+ goto cleanup;
|
||||
|
||||
handle->magic_number = KADM5_SERVER_HANDLE_MAGIC;
|
||||
handle->struct_version = struct_version;
|
||||
@@ -192,33 +220,20 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
|
||||
handle->context = context;
|
||||
|
||||
- if(client_name == NULL) {
|
||||
- free(handle);
|
||||
- return EINVAL;
|
||||
- }
|
||||
-
|
||||
- /*
|
||||
- * Verify the version numbers before proceeding; we can't use
|
||||
- * CHECK_HANDLE because not all fields are set yet.
|
||||
- */
|
||||
- GENERIC_CHECK_HANDLE(handle, KADM5_OLD_LIB_API_VERSION,
|
||||
- KADM5_NEW_LIB_API_VERSION);
|
||||
-
|
||||
memset(¶ms_local, 0, sizeof(params_local));
|
||||
|
||||
- if ((code = kadm5_get_config_params(handle->context, 0,
|
||||
- params_in, &handle->params))) {
|
||||
- free(handle);
|
||||
- return(code);
|
||||
- }
|
||||
+ code = kadm5_get_config_params(handle->context, 0, params_in,
|
||||
+ &handle->params);
|
||||
+ if (code)
|
||||
+ goto cleanup;
|
||||
|
||||
#define REQUIRED_PARAMS (KADM5_CONFIG_REALM | \
|
||||
KADM5_CONFIG_ADMIN_SERVER | \
|
||||
KADM5_CONFIG_KADMIND_PORT)
|
||||
|
||||
if ((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
|
||||
- free(handle);
|
||||
- return KADM5_MISSING_KRB5_CONF_PARAMS;
|
||||
+ code = KADM5_MISSING_KRB5_CONF_PARAMS;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -228,7 +243,7 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
*/
|
||||
code = krb5_parse_name(handle->context, client_name, &client);
|
||||
if (code)
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
if (init_type == INIT_SKEY && client->realm.length == 0)
|
||||
client->type = KRB5_NT_SRV_HST;
|
||||
|
||||
@@ -239,7 +254,7 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
code = get_init_creds(handle, client, init_type, pass, ccache_in,
|
||||
service_name, handle->params.realm, &server);
|
||||
if (code)
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
|
||||
/* If the service_name and client_name are iprop-centric, use the iprop
|
||||
* port and RPC identifiers. */
|
||||
@@ -258,7 +273,7 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
|
||||
code = connect_to_server(handle->params.admin_server, port, &fd);
|
||||
if (code)
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
|
||||
handle->clnt = clnttcp_create(NULL, rpc_prog, rpc_vers, &fd, 0, 0);
|
||||
if (handle->clnt == NULL) {
|
||||
@@ -266,7 +281,7 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
#ifdef DEBUG
|
||||
clnt_pcreateerror("clnttcp_create");
|
||||
#endif
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/* Set a one-hour timeout. */
|
||||
@@ -278,10 +293,6 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
handle->lhandle->clnt = handle->clnt;
|
||||
handle->lhandle->client_socket = fd;
|
||||
|
||||
- /* now that handle->clnt is set, we can check the handle */
|
||||
- if ((code = _kadm5_check_handle((void *) handle)))
|
||||
- goto error;
|
||||
-
|
||||
/*
|
||||
* The RPC connection is open; establish the GSS-API
|
||||
* authentication context.
|
||||
@@ -289,7 +300,7 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
code = setup_gss(handle, params_in,
|
||||
(init_type == INIT_CREDS) ? client : NULL, server);
|
||||
if (code)
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
|
||||
/*
|
||||
* Bypass the remainder of the code and return straight away
|
||||
@@ -297,7 +308,8 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
*/
|
||||
if (iprop_enable) {
|
||||
code = 0;
|
||||
- *server_handle = (void *) handle;
|
||||
+ *server_handle = handle;
|
||||
+ handle = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -306,7 +318,7 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
#ifdef DEBUG
|
||||
clnt_perror(handle->clnt, "init_2 null resp");
|
||||
#endif
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
}
|
||||
/* Drop down to v3 wire protocol if server does not support v4 */
|
||||
if (r.code == KADM5_NEW_SERVER_API_VERSION &&
|
||||
@@ -315,7 +327,7 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
memset(&r, 0, sizeof(generic_ret));
|
||||
if (init_2(&handle->api_version, &r, handle->clnt)) {
|
||||
code = KADM5_RPC_ERROR;
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
}
|
||||
}
|
||||
/* Drop down to v2 wire protocol if server does not support v3 */
|
||||
@@ -325,47 +337,21 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
|
||||
memset(&r, 0, sizeof(generic_ret));
|
||||
if (init_2(&handle->api_version, &r, handle->clnt)) {
|
||||
code = KADM5_RPC_ERROR;
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
}
|
||||
}
|
||||
if (r.code) {
|
||||
code = r.code;
|
||||
- goto error;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
- *server_handle = (void *) handle;
|
||||
-
|
||||
- goto cleanup;
|
||||
-
|
||||
-error:
|
||||
- /*
|
||||
- * Note that it is illegal for this code to execute if "handle"
|
||||
- * has not been allocated and initialized. I.e., don't use "goto
|
||||
- * error" before the block of code at the top of the function
|
||||
- * that allocates and initializes "handle".
|
||||
- */
|
||||
- if (handle->destroy_cache && handle->cache_name) {
|
||||
- if (krb5_cc_resolve(handle->context,
|
||||
- handle->cache_name, &ccache) == 0)
|
||||
- (void) krb5_cc_destroy (handle->context, ccache);
|
||||
- }
|
||||
- if (handle->cache_name)
|
||||
- free(handle->cache_name);
|
||||
- (void)gss_release_cred(&minor_stat, &handle->cred);
|
||||
- if(handle->clnt && handle->clnt->cl_auth)
|
||||
- AUTH_DESTROY(handle->clnt->cl_auth);
|
||||
- if(handle->clnt)
|
||||
- clnt_destroy(handle->clnt);
|
||||
- if (fd != -1)
|
||||
- close(fd);
|
||||
- free(handle->lhandle);
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
+ *server_handle = handle;
|
||||
+ handle = NULL;
|
||||
|
||||
cleanup:
|
||||
- krb5_free_principal(handle->context, client);
|
||||
- krb5_free_principal(handle->context, server);
|
||||
- if (code)
|
||||
- free(handle);
|
||||
+ krb5_free_principal(context, client);
|
||||
+ krb5_free_principal(context, server);
|
||||
+ (void)free_handle(handle);
|
||||
|
||||
return code;
|
||||
}
|
||||
@@ -695,38 +681,8 @@ rpc_auth(kadm5_server_handle_t handle, kadm5_config_params *params_in,
|
||||
kadm5_ret_t
|
||||
kadm5_destroy(void *server_handle)
|
||||
{
|
||||
- OM_uint32 minor_stat;
|
||||
- krb5_ccache ccache = NULL;
|
||||
- int code = KADM5_OK;
|
||||
- kadm5_server_handle_t handle =
|
||||
- (kadm5_server_handle_t) server_handle;
|
||||
-
|
||||
CHECK_HANDLE(server_handle);
|
||||
-
|
||||
- if (handle->destroy_cache && handle->cache_name) {
|
||||
- if ((code = krb5_cc_resolve(handle->context,
|
||||
- handle->cache_name, &ccache)) == 0)
|
||||
- code = krb5_cc_destroy (handle->context, ccache);
|
||||
- }
|
||||
- if (handle->cache_name)
|
||||
- free(handle->cache_name);
|
||||
- if (handle->cred)
|
||||
- (void)gss_release_cred(&minor_stat, &handle->cred);
|
||||
- if (handle->clnt && handle->clnt->cl_auth)
|
||||
- AUTH_DESTROY(handle->clnt->cl_auth);
|
||||
- if (handle->clnt)
|
||||
- clnt_destroy(handle->clnt);
|
||||
- if (handle->client_socket != -1)
|
||||
- close(handle->client_socket);
|
||||
- if (handle->lhandle)
|
||||
- free (handle->lhandle);
|
||||
-
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
-
|
||||
- handle->magic_number = 0;
|
||||
- free(handle);
|
||||
-
|
||||
- return code;
|
||||
+ return free_handle(server_handle);
|
||||
}
|
||||
/* not supported on client */
|
||||
kadm5_ret_t kadm5_lock(void *server_handle)
|
||||
diff --git a/src/lib/kadm5/srv/server_init.c b/src/lib/kadm5/srv/server_init.c
|
||||
index 3adc4b57d..2c0d51efd 100644
|
||||
--- a/src/lib/kadm5/srv/server_init.c
|
||||
+++ b/src/lib/kadm5/srv/server_init.c
|
||||
@@ -19,23 +19,6 @@
|
||||
#include "osconf.h"
|
||||
#include "iprop_hdr.h"
|
||||
|
||||
-/*
|
||||
- * Function check_handle
|
||||
- *
|
||||
- * Purpose: Check a server handle and return a com_err code if it is
|
||||
- * invalid or 0 if it is valid.
|
||||
- *
|
||||
- * Arguments:
|
||||
- *
|
||||
- * handle The server handle.
|
||||
- */
|
||||
-
|
||||
-static int check_handle(void *handle)
|
||||
-{
|
||||
- CHECK_HANDLE(handle);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static int dup_db_args(kadm5_server_handle_t handle, char **db_args)
|
||||
{
|
||||
int count = 0;
|
||||
@@ -84,6 +67,23 @@ static void free_db_args(kadm5_server_handle_t handle)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+free_handle(kadm5_server_handle_t handle)
|
||||
+{
|
||||
+ if (handle == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ destroy_pwqual(handle);
|
||||
+ k5_kadm5_hook_free_handles(handle->context, handle->hook_handles);
|
||||
+ ulog_fini(handle->context);
|
||||
+ krb5_db_fini(handle->context);
|
||||
+ krb5_free_principal(handle->context, handle->current_caller);
|
||||
+ kadm5_free_config_params(handle->context, &handle->params);
|
||||
+ free(handle->lhandle);
|
||||
+ free_db_args(handle);
|
||||
+ free(handle);
|
||||
+}
|
||||
+
|
||||
kadm5_ret_t kadm5_init_with_password(krb5_context context, char *client_name,
|
||||
char *pass, char *service_name,
|
||||
kadm5_config_params *params,
|
||||
@@ -163,8 +163,8 @@ kadm5_ret_t kadm5_init(krb5_context context, char *client_name, char *pass,
|
||||
char **db_args,
|
||||
void **server_handle)
|
||||
{
|
||||
- int ret;
|
||||
- kadm5_server_handle_t handle;
|
||||
+ krb5_error_code ret;
|
||||
+ kadm5_server_handle_t handle = NULL;
|
||||
kadm5_config_params params_local; /* for v1 compat */
|
||||
|
||||
if (! server_handle)
|
||||
@@ -173,17 +173,17 @@ kadm5_ret_t kadm5_init(krb5_context context, char *client_name, char *pass,
|
||||
if (! client_name)
|
||||
return EINVAL;
|
||||
|
||||
- if (! (handle = (kadm5_server_handle_t) malloc(sizeof *handle)))
|
||||
- return ENOMEM;
|
||||
- memset(handle, 0, sizeof(*handle));
|
||||
+ CHECK_VERSIONS(struct_version, api_version, KADM5_OLD_SERVER_API_VERSION,
|
||||
+ KADM5_NEW_SERVER_API_VERSION);
|
||||
+
|
||||
+ handle = k5alloc(sizeof(*handle), &ret);
|
||||
+ if (handle == NULL)
|
||||
+ goto cleanup;
|
||||
+ handle->context = context;
|
||||
|
||||
ret = dup_db_args(handle, db_args);
|
||||
- if (ret) {
|
||||
- free(handle);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- handle->context = context;
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
initialize_ovk_error_table();
|
||||
initialize_ovku_error_table();
|
||||
@@ -192,13 +192,6 @@ kadm5_ret_t kadm5_init(krb5_context context, char *client_name, char *pass,
|
||||
handle->struct_version = struct_version;
|
||||
handle->api_version = api_version;
|
||||
|
||||
- /*
|
||||
- * Verify the version numbers before proceeding; we can't use
|
||||
- * CHECK_HANDLE because not all fields are set yet.
|
||||
- */
|
||||
- GENERIC_CHECK_HANDLE(handle, KADM5_OLD_SERVER_API_VERSION,
|
||||
- KADM5_NEW_SERVER_API_VERSION);
|
||||
-
|
||||
/*
|
||||
* Acquire relevant profile entries. Merge values
|
||||
* in params_in with values from profile, based on
|
||||
@@ -208,11 +201,8 @@ kadm5_ret_t kadm5_init(krb5_context context, char *client_name, char *pass,
|
||||
|
||||
ret = kadm5_get_config_params(handle->context, 1, params_in,
|
||||
&handle->params);
|
||||
- if (ret) {
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return(ret);
|
||||
- }
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
#define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_DBNAME | \
|
||||
KADM5_CONFIG_ENCTYPE | \
|
||||
@@ -226,132 +216,69 @@ kadm5_ret_t kadm5_init(krb5_context context, char *client_name, char *pass,
|
||||
KADM5_CONFIG_IPROP_PORT)
|
||||
|
||||
if ((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return KADM5_MISSING_CONF_PARAMS;
|
||||
+ ret = KADM5_MISSING_CONF_PARAMS;
|
||||
+ goto cleanup;
|
||||
}
|
||||
if ((handle->params.mask & KADM5_CONFIG_IPROP_ENABLED) == KADM5_CONFIG_IPROP_ENABLED
|
||||
&& handle->params.iprop_enabled) {
|
||||
if ((handle->params.mask & IPROP_REQUIRED_PARAMS) != IPROP_REQUIRED_PARAMS) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return KADM5_MISSING_CONF_PARAMS;
|
||||
+ ret = KADM5_MISSING_CONF_PARAMS;
|
||||
+ goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ret = krb5_set_default_realm(handle->context, handle->params.realm);
|
||||
- if (ret) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return ret;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
ret = krb5_db_open(handle->context, db_args,
|
||||
KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN);
|
||||
- if (ret) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return(ret);
|
||||
- }
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
- if ((ret = krb5_parse_name(handle->context, client_name,
|
||||
- &handle->current_caller))) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- krb5_db_fini(handle->context);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return ret;
|
||||
- }
|
||||
+ ret = krb5_parse_name(handle->context, client_name,
|
||||
+ &handle->current_caller);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
- if (! (handle->lhandle = malloc(sizeof(*handle)))) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- krb5_db_fini(handle->context);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return ENOMEM;
|
||||
- }
|
||||
+ handle->lhandle = k5alloc(sizeof(*handle), &ret);
|
||||
+ if (handle->lhandle == NULL)
|
||||
+ goto cleanup;
|
||||
*handle->lhandle = *handle;
|
||||
handle->lhandle->api_version = KADM5_API_VERSION_4;
|
||||
handle->lhandle->struct_version = KADM5_STRUCT_VERSION;
|
||||
handle->lhandle->lhandle = handle->lhandle;
|
||||
|
||||
- /* can't check the handle until current_caller is set */
|
||||
- ret = check_handle((void *) handle);
|
||||
- if (ret) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
ret = kdb_init_master(handle, handle->params.realm,
|
||||
(handle->params.mask & KADM5_CONFIG_MKEY_FROM_KBD)
|
||||
&& handle->params.mkey_from_kbd);
|
||||
- if (ret) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- krb5_db_fini(handle->context);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return ret;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
ret = kdb_init_hist(handle, handle->params.realm);
|
||||
- if (ret) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- krb5_db_fini(handle->context);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return ret;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
ret = k5_kadm5_hook_load(context,&handle->hook_handles);
|
||||
- if (ret) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- krb5_db_fini(handle->context);
|
||||
- krb5_free_principal(handle->context, handle->current_caller);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return ret;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
ret = init_pwqual(handle);
|
||||
- if (ret) {
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- k5_kadm5_hook_free_handles(context, handle->hook_handles);
|
||||
- krb5_db_fini(handle->context);
|
||||
- krb5_free_principal(handle->context, handle->current_caller);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
- return ret;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
|
||||
- *server_handle = (void *) handle;
|
||||
+ *server_handle = handle;
|
||||
+ handle = NULL;
|
||||
|
||||
- return KADM5_OK;
|
||||
+cleanup:
|
||||
+ free_handle(handle);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
kadm5_ret_t kadm5_destroy(void *server_handle)
|
||||
{
|
||||
- kadm5_server_handle_t handle = server_handle;
|
||||
-
|
||||
CHECK_HANDLE(server_handle);
|
||||
-
|
||||
- destroy_pwqual(handle);
|
||||
-
|
||||
- k5_kadm5_hook_free_handles(handle->context, handle->hook_handles);
|
||||
- ulog_fini(handle->context);
|
||||
- krb5_db_fini(handle->context);
|
||||
- krb5_free_principal(handle->context, handle->current_caller);
|
||||
- kadm5_free_config_params(handle->context, &handle->params);
|
||||
- handle->magic_number = 0;
|
||||
- free(handle->lhandle);
|
||||
- free_db_args(handle);
|
||||
- free(handle);
|
||||
-
|
||||
+ free_handle(server_handle);
|
||||
return KADM5_OK;
|
||||
}
|
||||
|
@ -1,552 +0,0 @@
|
||||
From f85a818fe1a7438db7e1ea579818da67e0be017d Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Sat, 15 May 2021 17:35:25 -0400
|
||||
Subject: [PATCH] Fix softpkcs11 build issues with openssl 3.0
|
||||
|
||||
EVP_PKEY_get0_RSA() has been modified to have const return type. Remove
|
||||
its usages in favor of the EVP_PKEY interface. Also remove calls to
|
||||
RSA_blinding_off(), which we don't need and would require a non-const
|
||||
object. Similarly, remove RSA_set_method() calls that set a pre-existing
|
||||
default.
|
||||
|
||||
Since softpkcs11 doesn't link against krb5 and can't use zap(), allocate
|
||||
buffers with OPENSSL_malloc() so can use OPENSSL_clear_free().
|
||||
|
||||
Move several argument validation checks to the top of their functions.
|
||||
|
||||
Fix some incorrect/inconsistent log messages.
|
||||
|
||||
(cherry picked from commit 00de1aad7b3647b91017c7009b0bc65cd0c8b2e0)
|
||||
(cherry picked from commit a86b780ef275b35e8dc1e6d1886ec8e8d941f7c4)
|
||||
---
|
||||
src/tests/softpkcs11/main.c | 360 ++++++++++++++----------------------
|
||||
1 file changed, 141 insertions(+), 219 deletions(-)
|
||||
|
||||
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
|
||||
index 1cccdfb43..caa537b68 100644
|
||||
--- a/src/tests/softpkcs11/main.c
|
||||
+++ b/src/tests/softpkcs11/main.c
|
||||
@@ -375,10 +375,9 @@ add_st_object(void)
|
||||
return NULL;
|
||||
soft_token.object.objs = objs;
|
||||
|
||||
- o = malloc(sizeof(*o));
|
||||
+ o = calloc(1, sizeof(*o));
|
||||
if (o == NULL)
|
||||
return NULL;
|
||||
- memset(o, 0, sizeof(*o));
|
||||
o->attrs = NULL;
|
||||
o->num_attributes = 0;
|
||||
o->object_handle = soft_token.object.num_objs;
|
||||
@@ -424,7 +423,7 @@ add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
|
||||
CK_ULONG modulus_bits = 0;
|
||||
CK_BYTE *exponent = NULL;
|
||||
size_t exponent_len = 0;
|
||||
- RSA *rsa;
|
||||
+ const RSA *rsa;
|
||||
const BIGNUM *n, *e;
|
||||
|
||||
rsa = EVP_PKEY_get0_RSA(key);
|
||||
@@ -445,8 +444,6 @@ add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
|
||||
add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
|
||||
exponent, exponent_len);
|
||||
|
||||
- RSA_set_method(rsa, RSA_PKCS1_OpenSSL());
|
||||
-
|
||||
free(modulus);
|
||||
free(exponent);
|
||||
}
|
||||
@@ -679,10 +676,6 @@ add_certificate(char *label,
|
||||
} else {
|
||||
/* XXX verify keytype */
|
||||
|
||||
- if (key_type == CKK_RSA)
|
||||
- RSA_set_method(EVP_PKEY_get0_RSA(o->u.private_key.key),
|
||||
- RSA_PKCS1_OpenSSL());
|
||||
-
|
||||
if (X509_check_private_key(cert, o->u.private_key.key) != 1) {
|
||||
EVP_PKEY_free(o->u.private_key.key);
|
||||
o->u.private_key.key = NULL;
|
||||
@@ -695,7 +688,7 @@ add_certificate(char *label,
|
||||
}
|
||||
|
||||
ret = CKR_OK;
|
||||
- out:
|
||||
+out:
|
||||
if (ret != CKR_OK) {
|
||||
st_logf("something went wrong when adding cert!\n");
|
||||
|
||||
@@ -1224,8 +1217,6 @@ C_Login(CK_SESSION_HANDLE hSession,
|
||||
}
|
||||
|
||||
/* XXX check keytype */
|
||||
- RSA_set_method(EVP_PKEY_get0_RSA(o->u.private_key.key),
|
||||
- RSA_PKCS1_OpenSSL());
|
||||
|
||||
if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) {
|
||||
EVP_PKEY_free(o->u.private_key.key);
|
||||
@@ -1495,8 +1486,9 @@ C_Encrypt(CK_SESSION_HANDLE hSession,
|
||||
struct st_object *o;
|
||||
void *buffer = NULL;
|
||||
CK_RV ret;
|
||||
- RSA *rsa;
|
||||
- int padding, len, buffer_len, padding_len;
|
||||
+ size_t buffer_len = 0;
|
||||
+ int padding;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
|
||||
st_logf("Encrypt\n");
|
||||
|
||||
@@ -1512,70 +1504,58 @@ C_Encrypt(CK_SESSION_HANDLE hSession,
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(o->u.public_key);
|
||||
-
|
||||
- if (rsa == NULL)
|
||||
- return CKR_ARGUMENTS_BAD;
|
||||
-
|
||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
|
||||
-
|
||||
- buffer_len = RSA_size(rsa);
|
||||
-
|
||||
- buffer = malloc(buffer_len);
|
||||
- if (buffer == NULL) {
|
||||
- ret = CKR_DEVICE_MEMORY;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- ret = CKR_OK;
|
||||
- switch(state->encrypt_mechanism->mechanism) {
|
||||
- case CKM_RSA_PKCS:
|
||||
- padding = RSA_PKCS1_PADDING;
|
||||
- padding_len = RSA_PKCS1_PADDING_SIZE;
|
||||
- break;
|
||||
- case CKM_RSA_X_509:
|
||||
- padding = RSA_NO_PADDING;
|
||||
- padding_len = 0;
|
||||
- break;
|
||||
- default:
|
||||
- ret = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- if ((CK_ULONG)buffer_len + padding_len < ulDataLen) {
|
||||
- ret = CKR_ARGUMENTS_BAD;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
if (pulEncryptedDataLen == NULL) {
|
||||
st_logf("pulEncryptedDataLen NULL\n");
|
||||
ret = CKR_ARGUMENTS_BAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (pData == NULL_PTR) {
|
||||
+ if (pData == NULL) {
|
||||
st_logf("data NULL\n");
|
||||
ret = CKR_ARGUMENTS_BAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- len = RSA_public_encrypt(ulDataLen, pData, buffer, rsa, padding);
|
||||
- if (len <= 0) {
|
||||
+ switch(state->encrypt_mechanism->mechanism) {
|
||||
+ case CKM_RSA_PKCS:
|
||||
+ padding = RSA_PKCS1_PADDING;
|
||||
+ break;
|
||||
+ case CKM_RSA_X_509:
|
||||
+ padding = RSA_NO_PADDING;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL);
|
||||
+ if (ctx == NULL || EVP_PKEY_encrypt_init(ctx) <= 0 ||
|
||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
|
||||
+ EVP_PKEY_encrypt(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) {
|
||||
ret = CKR_DEVICE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
- if (len > buffer_len)
|
||||
- abort();
|
||||
|
||||
- if (pEncryptedData != NULL_PTR)
|
||||
- memcpy(pEncryptedData, buffer, len);
|
||||
- *pulEncryptedDataLen = len;
|
||||
-
|
||||
- out:
|
||||
- if (buffer) {
|
||||
- memset(buffer, 0, buffer_len);
|
||||
- free(buffer);
|
||||
+ buffer = OPENSSL_malloc(buffer_len);
|
||||
+ if (buffer == NULL) {
|
||||
+ ret = CKR_DEVICE_MEMORY;
|
||||
+ goto out;
|
||||
}
|
||||
+
|
||||
+ if (EVP_PKEY_encrypt(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
|
||||
+ ret = CKR_DEVICE_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ st_logf("Encrypt done\n");
|
||||
+
|
||||
+ if (pEncryptedData != NULL)
|
||||
+ memcpy(pEncryptedData, buffer, buffer_len);
|
||||
+ *pulEncryptedDataLen = buffer_len;
|
||||
+
|
||||
+ ret = CKR_OK;
|
||||
+out:
|
||||
+ OPENSSL_clear_free(buffer, buffer_len);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1646,8 +1626,9 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
|
||||
struct st_object *o;
|
||||
void *buffer = NULL;
|
||||
CK_RV ret;
|
||||
- RSA *rsa;
|
||||
- int padding, len, buffer_len, padding_len;
|
||||
+ size_t buffer_len = 0;
|
||||
+ int padding;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
|
||||
st_logf("Decrypt\n");
|
||||
|
||||
@@ -1663,41 +1644,6 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(o->u.private_key.key);
|
||||
-
|
||||
- if (rsa == NULL)
|
||||
- return CKR_ARGUMENTS_BAD;
|
||||
-
|
||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
|
||||
-
|
||||
- buffer_len = RSA_size(rsa);
|
||||
-
|
||||
- buffer = malloc(buffer_len);
|
||||
- if (buffer == NULL) {
|
||||
- ret = CKR_DEVICE_MEMORY;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- ret = CKR_OK;
|
||||
- switch(state->decrypt_mechanism->mechanism) {
|
||||
- case CKM_RSA_PKCS:
|
||||
- padding = RSA_PKCS1_PADDING;
|
||||
- padding_len = RSA_PKCS1_PADDING_SIZE;
|
||||
- break;
|
||||
- case CKM_RSA_X_509:
|
||||
- padding = RSA_NO_PADDING;
|
||||
- padding_len = 0;
|
||||
- break;
|
||||
- default:
|
||||
- ret = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- if ((CK_ULONG)buffer_len + padding_len < ulEncryptedDataLen) {
|
||||
- ret = CKR_ARGUMENTS_BAD;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
if (pulDataLen == NULL) {
|
||||
st_logf("pulDataLen NULL\n");
|
||||
ret = CKR_ARGUMENTS_BAD;
|
||||
@@ -1710,24 +1656,48 @@ C_Decrypt(CK_SESSION_HANDLE hSession,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- len = RSA_private_decrypt(ulEncryptedDataLen, pEncryptedData, buffer,
|
||||
- rsa, padding);
|
||||
- if (len <= 0) {
|
||||
+ switch(state->decrypt_mechanism->mechanism) {
|
||||
+ case CKM_RSA_PKCS:
|
||||
+ padding = RSA_PKCS1_PADDING;
|
||||
+ break;
|
||||
+ case CKM_RSA_X_509:
|
||||
+ padding = RSA_NO_PADDING;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL);
|
||||
+ if (ctx == NULL || EVP_PKEY_decrypt_init(ctx) <= 0 ||
|
||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
|
||||
+ EVP_PKEY_decrypt(ctx, NULL, &buffer_len, pEncryptedData,
|
||||
+ ulEncryptedDataLen) <= 0) {
|
||||
ret = CKR_DEVICE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
- if (len > buffer_len)
|
||||
- abort();
|
||||
+
|
||||
+ buffer = OPENSSL_malloc(buffer_len);
|
||||
+ if (buffer == NULL) {
|
||||
+ ret = CKR_DEVICE_MEMORY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (EVP_PKEY_decrypt(ctx, buffer, &buffer_len, pEncryptedData,
|
||||
+ ulEncryptedDataLen) <= 0) {
|
||||
+ ret = CKR_DEVICE_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ st_logf("Decrypt done\n");
|
||||
|
||||
if (pData != NULL_PTR)
|
||||
- memcpy(pData, buffer, len);
|
||||
- *pulDataLen = len;
|
||||
+ memcpy(pData, buffer, buffer_len);
|
||||
+ *pulDataLen = buffer_len;
|
||||
|
||||
- out:
|
||||
- if (buffer) {
|
||||
- memset(buffer, 0, buffer_len);
|
||||
- free(buffer);
|
||||
- }
|
||||
+ ret = CKR_OK;
|
||||
+out:
|
||||
+ OPENSSL_clear_free(buffer, buffer_len);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1806,8 +1776,9 @@ C_Sign(CK_SESSION_HANDLE hSession,
|
||||
struct st_object *o;
|
||||
void *buffer = NULL;
|
||||
CK_RV ret;
|
||||
- RSA *rsa;
|
||||
- int padding, len, buffer_len, padding_len;
|
||||
+ int padding;
|
||||
+ size_t buffer_len = 0;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
|
||||
st_logf("Sign\n");
|
||||
VERIFY_SESSION_HANDLE(hSession, &state);
|
||||
@@ -1822,40 +1793,6 @@ C_Sign(CK_SESSION_HANDLE hSession,
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(o->u.private_key.key);
|
||||
-
|
||||
- if (rsa == NULL)
|
||||
- return CKR_ARGUMENTS_BAD;
|
||||
-
|
||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
|
||||
-
|
||||
- buffer_len = RSA_size(rsa);
|
||||
-
|
||||
- buffer = malloc(buffer_len);
|
||||
- if (buffer == NULL) {
|
||||
- ret = CKR_DEVICE_MEMORY;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- switch(state->sign_mechanism->mechanism) {
|
||||
- case CKM_RSA_PKCS:
|
||||
- padding = RSA_PKCS1_PADDING;
|
||||
- padding_len = RSA_PKCS1_PADDING_SIZE;
|
||||
- break;
|
||||
- case CKM_RSA_X_509:
|
||||
- padding = RSA_NO_PADDING;
|
||||
- padding_len = 0;
|
||||
- break;
|
||||
- default:
|
||||
- ret = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- if ((CK_ULONG)buffer_len < ulDataLen + padding_len) {
|
||||
- ret = CKR_ARGUMENTS_BAD;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
if (pulSignatureLen == NULL) {
|
||||
st_logf("signature len NULL\n");
|
||||
ret = CKR_ARGUMENTS_BAD;
|
||||
@@ -1868,26 +1805,46 @@ C_Sign(CK_SESSION_HANDLE hSession,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- len = RSA_private_encrypt(ulDataLen, pData, buffer, rsa, padding);
|
||||
- st_logf("private encrypt done\n");
|
||||
- if (len <= 0) {
|
||||
+ switch(state->sign_mechanism->mechanism) {
|
||||
+ case CKM_RSA_PKCS:
|
||||
+ padding = RSA_PKCS1_PADDING;
|
||||
+ break;
|
||||
+ case CKM_RSA_X_509:
|
||||
+ padding = RSA_NO_PADDING;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL);
|
||||
+ if (ctx == NULL || EVP_PKEY_sign_init(ctx) <= 0 ||
|
||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
|
||||
+ EVP_PKEY_sign(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) {
|
||||
ret = CKR_DEVICE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
- if (len > buffer_len)
|
||||
- abort();
|
||||
|
||||
- if (pSignature != NULL_PTR)
|
||||
- memcpy(pSignature, buffer, len);
|
||||
- *pulSignatureLen = len;
|
||||
+ buffer = OPENSSL_malloc(buffer_len);
|
||||
+ if (buffer == NULL) {
|
||||
+ ret = CKR_DEVICE_MEMORY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (EVP_PKEY_sign(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
|
||||
+ ret = CKR_DEVICE_ERROR;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ st_logf("Sign done\n");
|
||||
+
|
||||
+ if (pSignature != NULL)
|
||||
+ memcpy(pSignature, buffer, buffer_len);
|
||||
+ *pulSignatureLen = buffer_len;
|
||||
|
||||
ret = CKR_OK;
|
||||
-
|
||||
- out:
|
||||
- if (buffer) {
|
||||
- memset(buffer, 0, buffer_len);
|
||||
- free(buffer);
|
||||
- }
|
||||
+out:
|
||||
+ OPENSSL_clear_free(buffer, buffer_len);
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1951,10 +1908,9 @@ C_Verify(CK_SESSION_HANDLE hSession,
|
||||
{
|
||||
struct session_state *state;
|
||||
struct st_object *o;
|
||||
- void *buffer = NULL;
|
||||
CK_RV ret;
|
||||
- RSA *rsa;
|
||||
- int padding, len, buffer_len;
|
||||
+ int padding;
|
||||
+ EVP_PKEY_CTX *ctx = NULL;
|
||||
|
||||
st_logf("Verify\n");
|
||||
VERIFY_SESSION_HANDLE(hSession, &state);
|
||||
@@ -1969,39 +1925,6 @@ C_Verify(CK_SESSION_HANDLE hSession,
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
}
|
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(o->u.public_key);
|
||||
-
|
||||
- if (rsa == NULL)
|
||||
- return CKR_ARGUMENTS_BAD;
|
||||
-
|
||||
- RSA_blinding_off(rsa); /* XXX RAND is broken while running in mozilla ? */
|
||||
-
|
||||
- buffer_len = RSA_size(rsa);
|
||||
-
|
||||
- buffer = malloc(buffer_len);
|
||||
- if (buffer == NULL) {
|
||||
- ret = CKR_DEVICE_MEMORY;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- ret = CKR_OK;
|
||||
- switch(state->verify_mechanism->mechanism) {
|
||||
- case CKM_RSA_PKCS:
|
||||
- padding = RSA_PKCS1_PADDING;
|
||||
- break;
|
||||
- case CKM_RSA_X_509:
|
||||
- padding = RSA_NO_PADDING;
|
||||
- break;
|
||||
- default:
|
||||
- ret = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- if ((CK_ULONG)buffer_len < ulDataLen) {
|
||||
- ret = CKR_ARGUMENTS_BAD;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
if (pSignature == NULL) {
|
||||
st_logf("signature NULL\n");
|
||||
ret = CKR_ARGUMENTS_BAD;
|
||||
@@ -2014,34 +1937,34 @@ C_Verify(CK_SESSION_HANDLE hSession,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- len = RSA_public_decrypt(ulDataLen, pData, buffer, rsa, padding);
|
||||
- st_logf("private encrypt done\n");
|
||||
- if (len <= 0) {
|
||||
+ switch(state->verify_mechanism->mechanism) {
|
||||
+ case CKM_RSA_PKCS:
|
||||
+ padding = RSA_PKCS1_PADDING;
|
||||
+ break;
|
||||
+ case CKM_RSA_X_509:
|
||||
+ padding = RSA_NO_PADDING;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL);
|
||||
+ if (ctx == NULL || EVP_PKEY_verify_init(ctx) <= 0 ||
|
||||
+ EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
|
||||
+ EVP_PKEY_verify(ctx, pSignature, ulSignatureLen, pData,
|
||||
+ ulDataLen) <= 0) {
|
||||
ret = CKR_DEVICE_ERROR;
|
||||
goto out;
|
||||
}
|
||||
- if (len > buffer_len)
|
||||
- abort();
|
||||
+ st_logf("Verify done\n");
|
||||
|
||||
- if ((CK_ULONG)len != ulSignatureLen) {
|
||||
- ret = CKR_GENERAL_ERROR;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- if (memcmp(pSignature, buffer, len) != 0) {
|
||||
- ret = CKR_GENERAL_ERROR;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- out:
|
||||
- if (buffer) {
|
||||
- memset(buffer, 0, buffer_len);
|
||||
- free(buffer);
|
||||
- }
|
||||
+ ret = CKR_OK;
|
||||
+out:
|
||||
+ EVP_PKEY_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
-
|
||||
CK_RV
|
||||
C_VerifyUpdate(CK_SESSION_HANDLE hSession,
|
||||
CK_BYTE_PTR pPart,
|
||||
@@ -2072,7 +1995,6 @@ C_GenerateRandom(CK_SESSION_HANDLE hSession,
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
-
|
||||
CK_FUNCTION_LIST funcs = {
|
||||
{ 2, 11 },
|
||||
C_Initialize,
|
@ -1,96 +0,0 @@
|
||||
From 0779309f52f4c05bb1f01f638261ef1b8ca82488 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 7 Jun 2021 13:27:29 -0400
|
||||
Subject: [PATCH] Fix some principal realm canonicalization cases
|
||||
|
||||
The no_hostrealm and subst_defrealm flags in struct canonprinc were
|
||||
only applied when dns_canonicalize_hostname=fallback; in the other
|
||||
cases, the initial krb5_sname_to_principal() result is treated as
|
||||
canonical. For no_hostrealm this limitation doesn't currently matter,
|
||||
because all uses pass a principal with no realm as input. However,
|
||||
subst_defrealm is used to convert the referral realm to the default
|
||||
realm in krb5_get_init_creds_keytab(), krb5_cc_cache_match(), and
|
||||
gss_acquire_cred() when it needs to check the desired name against a
|
||||
specified ccache.
|
||||
|
||||
In k5_canonprinc(), if the input principal is a
|
||||
krb5_sname_to_principal() result and fallback isn't in effect, apply
|
||||
subst_defrealm. Document in os-proto.h that no_hostrealm doesn't
|
||||
remove an existing realm and that krb5_sname_to_principal() may
|
||||
already have looked one up.
|
||||
|
||||
ticket: 9011 (new)
|
||||
(cherry picked from commit c077d0c6430c4ac163443aacc03d14d206a4cbb8)
|
||||
---
|
||||
src/lib/krb5/os/os-proto.h | 13 +++++++++----
|
||||
src/lib/krb5/os/sn2princ.c | 24 +++++++++++++++++++++---
|
||||
2 files changed, 30 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
|
||||
index 7d5e7978f..a985f2aec 100644
|
||||
--- a/src/lib/krb5/os/os-proto.h
|
||||
+++ b/src/lib/krb5/os/os-proto.h
|
||||
@@ -85,10 +85,15 @@ struct sendto_callback_info {
|
||||
|
||||
/*
|
||||
* Initialize with all zeros except for princ. Set no_hostrealm to disable
|
||||
- * host-to-realm lookup, which ordinarily happens after canonicalizing the host
|
||||
- * part. Set subst_defrealm to substitute the default realm for the referral
|
||||
- * realm after realm lookup (this has no effect if no_hostrealm is set). Free
|
||||
- * with free_canonprinc() when done.
|
||||
+ * host-to-realm lookup, which ordinarily happens during fallback processing
|
||||
+ * after canonicalizing the host part. Set subst_defrealm to substitute the
|
||||
+ * default realm for the referral realm after realm lookup. Do not set both
|
||||
+ * flags. Free with free_canonprinc() when done.
|
||||
+ *
|
||||
+ * no_hostrealm only applies if fallback processing is in use
|
||||
+ * (dns_canonicalize_hostname = fallback). It will not remove the realm if
|
||||
+ * krb5_sname_to_principal() already canonicalized the hostname and looked up a
|
||||
+ * realm. subst_defrealm applies whether or not fallback processing is in use.
|
||||
*/
|
||||
struct canonprinc {
|
||||
krb5_const_principal princ;
|
||||
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c
|
||||
index c99b7da17..93c155932 100644
|
||||
--- a/src/lib/krb5/os/sn2princ.c
|
||||
+++ b/src/lib/krb5/os/sn2princ.c
|
||||
@@ -271,18 +271,36 @@ krb5_error_code
|
||||
k5_canonprinc(krb5_context context, struct canonprinc *iter,
|
||||
krb5_const_principal *princ_out)
|
||||
{
|
||||
+ krb5_error_code ret;
|
||||
int step = ++iter->step;
|
||||
|
||||
*princ_out = NULL;
|
||||
|
||||
- /* If we're not doing fallback, the input principal is canonical. */
|
||||
- if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK ||
|
||||
- iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 ||
|
||||
+ /* If the hostname isn't from krb5_sname_to_principal(), the input
|
||||
+ * principal is canonical. */
|
||||
+ if (iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 ||
|
||||
iter->princ->data[1].length == 0) {
|
||||
*princ_out = (step == 1) ? iter->princ : NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ /* If we're not doing fallback, the hostname is canonical, but we may need
|
||||
+ * to substitute the default realm. */
|
||||
+ if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK) {
|
||||
+ if (step > 1)
|
||||
+ return 0;
|
||||
+ iter->copy = *iter->princ;
|
||||
+ if (iter->subst_defrealm && iter->copy.realm.length == 0) {
|
||||
+ ret = krb5_get_default_realm(context, &iter->realm);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ iter->copy = *iter->princ;
|
||||
+ iter->copy.realm = string2data(iter->realm);
|
||||
+ }
|
||||
+ *princ_out = &iter->copy;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
/* Canonicalize without DNS at step 1, with DNS at step 2. */
|
||||
if (step > 2)
|
||||
return 0;
|
@ -1,301 +0,0 @@
|
||||
From e3f3d31a3db23f6c8437cd0efe45f67a7f4fc6aa Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Sat, 15 May 2021 21:18:06 -0400
|
||||
Subject: [PATCH] Handle OpenSSL 3's providers
|
||||
|
||||
OpenSSL 3 compartmentalizes what algorithms it uses, which for us means
|
||||
another hoop to jump through to use dubious cryptography. (Right now,
|
||||
we need to load "legacy" in order to access MD4 and RC4.)
|
||||
|
||||
Use our normal initializer logic to set up providers both in the OpenSSL
|
||||
provider an the PKINIT plugin. Since DT_FINI is too late, release them
|
||||
using atexit() as OpenSSL does.
|
||||
|
||||
(cherry picked from commit bea5a703a06da1f1ab56821b77a2d3661cb0dda4)
|
||||
[rharwood@redhat.com: work around des3 removal and rc4 fips changes]
|
||||
---
|
||||
src/configure.ac | 1 +
|
||||
src/lib/crypto/openssl/enc_provider/aes.c | 16 ++++++
|
||||
.../crypto/openssl/enc_provider/camellia.c | 16 ++++++
|
||||
src/lib/crypto/openssl/enc_provider/rc4.c | 4 ++
|
||||
.../crypto/openssl/hash_provider/hash_evp.c | 5 ++
|
||||
src/lib/crypto/openssl/init.c | 53 +++++++++++++++++++
|
||||
src/plugins/preauth/pkinit/Makefile.in | 1 +
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 33 ++++++++++--
|
||||
8 files changed, 126 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 9c2e816fe..20066918b 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -284,6 +284,7 @@ AC_SUBST(CRYPTO_IMPL_LIBS)
|
||||
|
||||
if test "$CRYPTO_IMPL" = openssl; then
|
||||
AC_CHECK_FUNCS(EVP_KDF_fetch)
|
||||
+ AC_CHECK_FUNCS(OSSL_PROVIDER_load)
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([prng-alg],
|
||||
diff --git a/src/lib/crypto/openssl/enc_provider/aes.c b/src/lib/crypto/openssl/enc_provider/aes.c
|
||||
index 6b4622fe9..31c90a69d 100644
|
||||
--- a/src/lib/crypto/openssl/enc_provider/aes.c
|
||||
+++ b/src/lib/crypto/openssl/enc_provider/aes.c
|
||||
@@ -68,6 +68,10 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
struct iov_cursor cursor;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return ENOMEM;
|
||||
@@ -102,6 +106,10 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
struct iov_cursor cursor;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return ENOMEM;
|
||||
@@ -137,6 +145,10 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
||||
struct iov_cursor cursor;
|
||||
AES_KEY enck;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
memset(iv_cts,0,sizeof(iv_cts));
|
||||
if (ivec && ivec->data){
|
||||
if (ivec->length != sizeof(iv_cts))
|
||||
@@ -190,6 +202,10 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
||||
struct iov_cursor cursor;
|
||||
AES_KEY deck;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
memset(iv_cts,0,sizeof(iv_cts));
|
||||
if (ivec && ivec->data){
|
||||
if (ivec->length != sizeof(iv_cts))
|
||||
diff --git a/src/lib/crypto/openssl/enc_provider/camellia.c b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
index f79679a0b..7cc7fc6fb 100644
|
||||
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||
@@ -92,6 +92,10 @@ cbc_enc(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
struct iov_cursor cursor;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return ENOMEM;
|
||||
@@ -126,6 +130,10 @@ cbc_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
struct iov_cursor cursor;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
ctx = EVP_CIPHER_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return ENOMEM;
|
||||
@@ -161,6 +169,10 @@ cts_encr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
||||
struct iov_cursor cursor;
|
||||
CAMELLIA_KEY enck;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
memset(iv_cts,0,sizeof(iv_cts));
|
||||
if (ivec && ivec->data){
|
||||
if (ivec->length != sizeof(iv_cts))
|
||||
@@ -214,6 +226,10 @@ cts_decr(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
|
||||
struct iov_cursor cursor;
|
||||
CAMELLIA_KEY deck;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
memset(iv_cts,0,sizeof(iv_cts));
|
||||
if (ivec && ivec->data){
|
||||
if (ivec->length != sizeof(iv_cts))
|
||||
diff --git a/src/lib/crypto/openssl/enc_provider/rc4.c b/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
index 9bf407899..a10cb5192 100644
|
||||
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||
@@ -66,6 +66,10 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
struct arcfour_state *arcstate;
|
||||
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
if (FIPS_mode())
|
||||
return KRB5_CRYPTO_INTERNAL;
|
||||
|
||||
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
index 2eb5139c0..09d7b3896 100644
|
||||
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||
@@ -41,6 +41,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||
const krb5_data *d;
|
||||
size_t i;
|
||||
int ok;
|
||||
+ krb5_error_code ret;
|
||||
+
|
||||
+ ret = krb5int_crypto_init();
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
if (output->length != (unsigned int)EVP_MD_size(type))
|
||||
return KRB5_CRYPTO_INTERNAL;
|
||||
diff --git a/src/lib/crypto/openssl/init.c b/src/lib/crypto/openssl/init.c
|
||||
index 1139bce53..f72dbfe81 100644
|
||||
--- a/src/lib/crypto/openssl/init.c
|
||||
+++ b/src/lib/crypto/openssl/init.c
|
||||
@@ -26,12 +26,65 @@
|
||||
|
||||
#include "crypto_int.h"
|
||||
|
||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD
|
||||
+
|
||||
+/*
|
||||
+ * Starting in OpenSSL 3, algorithms are grouped into containers called
|
||||
+ * "providers", not all of which are loaded by default. At time of writing,
|
||||
+ * we need MD4 and RC4 from the legacy provider. Oddly, 3DES is not in
|
||||
+ * legacy.
|
||||
+ */
|
||||
+
|
||||
+#include <openssl/provider.h>
|
||||
+
|
||||
+static OSSL_PROVIDER *legacy_provider = NULL;
|
||||
+static OSSL_PROVIDER *default_provider = NULL;
|
||||
+
|
||||
+static void
|
||||
+unload_providers(void)
|
||||
+{
|
||||
+ if (default_provider != NULL)
|
||||
+ (void)OSSL_PROVIDER_unload(default_provider);
|
||||
+ if (legacy_provider != NULL)
|
||||
+ (void)OSSL_PROVIDER_unload(legacy_provider);
|
||||
+ default_provider = NULL;
|
||||
+ legacy_provider = NULL;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+krb5int_crypto_impl_init(void)
|
||||
+{
|
||||
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
|
||||
+ default_provider = OSSL_PROVIDER_load(NULL, "default");
|
||||
+
|
||||
+ /*
|
||||
+ * Someone might build openssl without the legacy provider. They will
|
||||
+ * have a bad time, but some things will still work. I don't know think
|
||||
+ * this configuration is worth supporting.
|
||||
+ */
|
||||
+ if (legacy_provider == NULL || default_provider == NULL)
|
||||
+ abort();
|
||||
+
|
||||
+ /*
|
||||
+ * If we attempt to do this with our normal LIBFINIFUNC logic (DT_FINI),
|
||||
+ * OpenSSL will have cleaned itself up by the time we're invoked. OpenSSL
|
||||
+ * registers its cleanup (OPENSSL_cleanup) with atexit() - do the same and
|
||||
+ * we'll be higher on the stack.
|
||||
+ */
|
||||
+ atexit(unload_providers);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#else /* !HAVE_OSSL_PROVIDER_LOAD */
|
||||
+
|
||||
int
|
||||
krb5int_crypto_impl_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#endif
|
||||
+
|
||||
void
|
||||
krb5int_crypto_impl_cleanup(void)
|
||||
{
|
||||
diff --git a/src/plugins/preauth/pkinit/Makefile.in b/src/plugins/preauth/pkinit/Makefile.in
|
||||
index 15ca0eb48..d20fb18a8 100644
|
||||
--- a/src/plugins/preauth/pkinit/Makefile.in
|
||||
+++ b/src/plugins/preauth/pkinit/Makefile.in
|
||||
@@ -5,6 +5,7 @@ MODULE_INSTALL_DIR = $(KRB5_PA_MODULE_DIR)
|
||||
LIBBASE=pkinit
|
||||
LIBMAJOR=0
|
||||
LIBMINOR=0
|
||||
+LIBINITFUNC=pkinit_openssl_init
|
||||
RELDIR=../plugins/preauth/pkinit
|
||||
# Depends on libk5crypto and libkrb5
|
||||
SHLIB_EXPDEPS = \
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 350c2118a..42e5c581d 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -44,6 +44,13 @@
|
||||
#include <openssl/params.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD
|
||||
+#include <openssl/provider.h>
|
||||
+
|
||||
+static OSSL_PROVIDER *legacy_provider = NULL;
|
||||
+static OSSL_PROVIDER *default_provider = NULL;
|
||||
+#endif
|
||||
+
|
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
||||
|
||||
@@ -2937,12 +2944,32 @@ cleanup:
|
||||
return retval;
|
||||
}
|
||||
|
||||
+/* pkinit_openssl_init() and unload_providers() are largely duplicated from
|
||||
+ * lib/crypto/openssl/init.c - see explanations there. */
|
||||
+static void
|
||||
+unload_providers(void)
|
||||
+{
|
||||
+ if (default_provider != NULL)
|
||||
+ (void)OSSL_PROVIDER_unload(default_provider);
|
||||
+ if (legacy_provider != NULL)
|
||||
+ (void)OSSL_PROVIDER_unload(legacy_provider);
|
||||
+ default_provider = NULL;
|
||||
+ legacy_provider = NULL;
|
||||
+}
|
||||
+
|
||||
int
|
||||
pkinit_openssl_init()
|
||||
{
|
||||
- /* Initialize OpenSSL. */
|
||||
- ERR_load_crypto_strings();
|
||||
- OpenSSL_add_all_algorithms();
|
||||
+#ifdef HAVE_OSSL_PROVIDER_LOAD
|
||||
+ legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
|
||||
+ default_provider = OSSL_PROVIDER_load(NULL, "default");
|
||||
+
|
||||
+ if (legacy_provider == NULL || default_provider == NULL)
|
||||
+ abort();
|
||||
+
|
||||
+ atexit(unload_providers);
|
||||
+#endif
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,26 +0,0 @@
|
||||
From 32ee800fa31d3bbda660bb9270f9aa20718ab202 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||||
Date: Tue, 30 Mar 2021 14:35:28 +0200
|
||||
Subject: [PATCH] Make KCM iteration fallback work with sssd-kcm
|
||||
|
||||
sssd-kcm returns KRB5_CC_IO if the operation code is not known.
|
||||
|
||||
ticket: 8990
|
||||
(cherry picked from commit 06afae820a44c1dc96ad88a0b16c3e50bc938b2a)
|
||||
---
|
||||
src/lib/krb5/ccache/cc_kcm.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
||||
index 1f81a2190..46705f1da 100644
|
||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
||||
@@ -876,7 +876,7 @@ kcm_start_seq_get(krb5_context context, krb5_ccache cache,
|
||||
ret = kcmreq_get_cred_list(&req, &creds);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
- } else if (ret == KRB5_FCC_INTERNAL) {
|
||||
+ } else if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) {
|
||||
/* Fall back to GET_CRED_UUID_LIST. */
|
||||
kcmreq_free(&req);
|
||||
kcmreq_init(&req, KCM_OP_GET_CRED_UUID_LIST, cache);
|
File diff suppressed because it is too large
Load Diff
@ -1,71 +0,0 @@
|
||||
From f8747c22fd159ad3556fdf6ec4f269c754c1eadb Mon Sep 17 00:00:00 2001
|
||||
From: Simo Sorce <simo@redhat.com>
|
||||
Date: Thu, 19 May 2022 12:27:40 -0400
|
||||
Subject: [PATCH] Read GSS configuration files with mtime 0
|
||||
|
||||
There is at least one case (with flatpaks) where configuration files
|
||||
in the special read-only /etc all have an mtime of 0. Using an
|
||||
initial last modified time of 0 in g_initialize.c causes these files
|
||||
to never be read.
|
||||
|
||||
Change the initial high value to the be the "invalid" value
|
||||
(time_t)-1. Since the C and POSIX standards do not require time_t to
|
||||
be signed, special-case the checks in load_if_changed() and
|
||||
updateMechList() to treat all mod times as newer than -1.
|
||||
|
||||
[ghudson@mit.edu: edited commit message; slightly modified approach]
|
||||
|
||||
ticket: 9060 (new)
|
||||
target_version: 1.20
|
||||
tags: pullup
|
||||
---
|
||||
src/lib/gssapi/mechglue/g_initialize.c | 11 ++++++-----
|
||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c
|
||||
index 6d49700a5..857d4a4f2 100644
|
||||
--- a/src/lib/gssapi/mechglue/g_initialize.c
|
||||
+++ b/src/lib/gssapi/mechglue/g_initialize.c
|
||||
@@ -93,7 +93,7 @@ static void free_mechSet(void);
|
||||
static gss_mech_info g_mechList = NULL;
|
||||
static gss_mech_info g_mechListTail = NULL;
|
||||
static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER;
|
||||
-static time_t g_confFileModTime = (time_t)0;
|
||||
+static time_t g_confFileModTime = (time_t)-1;
|
||||
static time_t g_confLastCall = (time_t)0;
|
||||
|
||||
static gss_OID_set_desc g_mechSet = { 0, NULL };
|
||||
@@ -469,9 +469,9 @@ load_if_changed(const char *pathname, time_t last, time_t *highest)
|
||||
mtime = check_link_mtime(pathname, &mtime);
|
||||
if (mtime == (time_t)-1)
|
||||
return;
|
||||
- if (mtime > *highest)
|
||||
+ if (mtime > *highest || *highest == (time_t)-1)
|
||||
*highest = mtime;
|
||||
- if (mtime > last)
|
||||
+ if (mtime > last || last == (time_t)-1)
|
||||
loadConfigFile(pathname);
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ static void
|
||||
loadConfigFiles()
|
||||
{
|
||||
glob_t globbuf;
|
||||
- time_t highest = 0, now;
|
||||
+ time_t highest = (time_t)-1, now;
|
||||
char **path;
|
||||
const char *val;
|
||||
|
||||
@@ -522,7 +522,8 @@ updateMechList(void)
|
||||
|
||||
#if defined(_WIN32)
|
||||
time_t lastConfModTime = getRegConfigModTime(MECH_KEY);
|
||||
- if (g_confFileModTime >= lastConfModTime)
|
||||
+ if (g_confFileModTime >= lastConfModTime &&
|
||||
+ g_confFileModTime != (time_t)-1)
|
||||
return;
|
||||
g_confFileModTime = lastConfModTime;
|
||||
loadConfigFromRegistry(HKEY_CURRENT_USER, MECH_KEY);
|
||||
--
|
||||
2.35.3
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,150 +0,0 @@
|
||||
From c99ecf1bb49e2fbd0bf30a7b357cf06407b9588a Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Sat, 15 May 2021 18:04:58 -0400
|
||||
Subject: [PATCH] Remove deprecated OpenSSL calls from softpkcs11
|
||||
|
||||
Rewrite add_pubkey_info() in terms of the EVP_PKEY interface. In this
|
||||
process, fix its unchecked allocations and fail fast for non-RSA keys.
|
||||
|
||||
(cherry picked from commit d6bf42279675100e3e4fe7c6e08eef74d49624cb)
|
||||
(cherry picked from commit 5072bfdfaddae762680d0f9d97afa6dbf8274760)
|
||||
---
|
||||
src/configure.ac | 1 +
|
||||
src/tests/softpkcs11/main.c | 106 ++++++++++++++++++++++++------------
|
||||
2 files changed, 72 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 3e1052db7..eb6307468 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -1114,6 +1114,7 @@ int i = 1;
|
||||
])], k5_cv_openssl_version_okay=yes, k5_cv_openssl_version_okay=no)])
|
||||
old_LIBS="$LIBS"
|
||||
AC_CHECK_LIB(crypto, PKCS7_get_signer_info)
|
||||
+ AC_CHECK_FUNCS(EVP_PKEY_get_bn_param)
|
||||
LIBS="$old_LIBS"
|
||||
fi
|
||||
if test "$k5_cv_openssl_version_okay" = yes && (test "$enable_pkinit" = yes || test "$enable_pkinit" = try); then
|
||||
diff --git a/src/tests/softpkcs11/main.c b/src/tests/softpkcs11/main.c
|
||||
index caa537b68..86b4ef711 100644
|
||||
--- a/src/tests/softpkcs11/main.c
|
||||
+++ b/src/tests/softpkcs11/main.c
|
||||
@@ -413,47 +413,83 @@ add_object_attribute(struct st_object *o,
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_EVP_PKEY_GET_BN_PARAM
|
||||
+
|
||||
+/* Declare owner pointers since EVP_PKEY_get_bn_param() gives us copies. */
|
||||
+#define DECLARE_BIGNUM(name) BIGNUM *name = NULL
|
||||
+#define RELEASE_BIGNUM(bn) BN_clear_free(bn)
|
||||
static CK_RV
|
||||
-add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
|
||||
+get_bignums(EVP_PKEY *key, BIGNUM **n, BIGNUM **e)
|
||||
{
|
||||
- switch (key_type) {
|
||||
- case CKK_RSA: {
|
||||
- CK_BYTE *modulus = NULL;
|
||||
- size_t modulus_len = 0;
|
||||
- CK_ULONG modulus_bits = 0;
|
||||
- CK_BYTE *exponent = NULL;
|
||||
- size_t exponent_len = 0;
|
||||
- const RSA *rsa;
|
||||
- const BIGNUM *n, *e;
|
||||
+ if (EVP_PKEY_get_bn_param(key, "n", n) == 0 ||
|
||||
+ EVP_PKEY_get_bn_param(key, "e", e) == 0)
|
||||
+ return CKR_DEVICE_ERROR;
|
||||
|
||||
- rsa = EVP_PKEY_get0_RSA(key);
|
||||
- RSA_get0_key(rsa, &n, &e, NULL);
|
||||
- modulus_bits = BN_num_bits(n);
|
||||
-
|
||||
- modulus_len = BN_num_bytes(n);
|
||||
- modulus = malloc(modulus_len);
|
||||
- BN_bn2bin(n, modulus);
|
||||
-
|
||||
- exponent_len = BN_num_bytes(e);
|
||||
- exponent = malloc(exponent_len);
|
||||
- BN_bn2bin(e, exponent);
|
||||
-
|
||||
- add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
|
||||
- add_object_attribute(o, 0, CKA_MODULUS_BITS,
|
||||
- &modulus_bits, sizeof(modulus_bits));
|
||||
- add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT,
|
||||
- exponent, exponent_len);
|
||||
-
|
||||
- free(modulus);
|
||||
- free(exponent);
|
||||
- }
|
||||
- default:
|
||||
- /* XXX */
|
||||
- break;
|
||||
- }
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
+#else
|
||||
+
|
||||
+/* Declare const pointers since the old API gives us aliases. */
|
||||
+#define DECLARE_BIGNUM(name) const BIGNUM *name
|
||||
+#define RELEASE_BIGNUM(bn)
|
||||
+static CK_RV
|
||||
+get_bignums(EVP_PKEY *key, const BIGNUM **n, const BIGNUM **e)
|
||||
+{
|
||||
+ const RSA *rsa;
|
||||
+
|
||||
+ rsa = EVP_PKEY_get0_RSA(key);
|
||||
+ RSA_get0_key(rsa, n, e, NULL);
|
||||
+
|
||||
+ return CKR_OK;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+static CK_RV
|
||||
+add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
|
||||
+{
|
||||
+ CK_BYTE *modulus = NULL, *exponent = 0;
|
||||
+ size_t modulus_len = 0, exponent_len = 0;
|
||||
+ CK_ULONG modulus_bits = 0;
|
||||
+ CK_RV ret;
|
||||
+ DECLARE_BIGNUM(n);
|
||||
+ DECLARE_BIGNUM(e);
|
||||
+
|
||||
+ if (key_type != CKK_RSA)
|
||||
+ abort();
|
||||
+
|
||||
+ ret = get_bignums(key, &n, &e);
|
||||
+ if (ret != CKR_OK)
|
||||
+ goto done;
|
||||
+
|
||||
+ modulus_bits = BN_num_bits(n);
|
||||
+ modulus_len = BN_num_bytes(n);
|
||||
+ exponent_len = BN_num_bytes(e);
|
||||
+
|
||||
+ modulus = malloc(modulus_len);
|
||||
+ exponent = malloc(exponent_len);
|
||||
+ if (modulus == NULL || exponent == NULL) {
|
||||
+ ret = CKR_DEVICE_MEMORY;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ BN_bn2bin(n, modulus);
|
||||
+ BN_bn2bin(e, exponent);
|
||||
+
|
||||
+ add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
|
||||
+ add_object_attribute(o, 0, CKA_MODULUS_BITS, &modulus_bits,
|
||||
+ sizeof(modulus_bits));
|
||||
+ add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, exponent, exponent_len);
|
||||
+
|
||||
+ ret = CKR_OK;
|
||||
+done:
|
||||
+ free(modulus);
|
||||
+ free(exponent);
|
||||
+ RELEASE_BIGNUM(n);
|
||||
+ RELEASE_BIGNUM(e);
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
static int
|
||||
pem_callback(char *buf, int num, int w, void *key)
|
@ -1,578 +0,0 @@
|
||||
From 818a777822658d44ce647fe975011a5ea25e8250 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 15 Jan 2021 13:51:34 -0500
|
||||
Subject: [PATCH] Support host-based GSS initiator names
|
||||
|
||||
When checking if we can get initial credentials in the GSS krb5 mech,
|
||||
use krb5_kt_have_match() to support fallback iteration. When scanning
|
||||
the ccache or getting initial credentials, rewrite cred->name->princ
|
||||
to the canonical client name. When a name check is necessary (such as
|
||||
when the caller specifies both a name and ccache), use a new internal
|
||||
API k5_sname_compare() to support fallback iteration. Add fallback
|
||||
iteration to krb5_cc_cache_match() to allow host-based names to be
|
||||
canonicalized against the cache collection.
|
||||
|
||||
Create and store the matching principal for acceptor names in
|
||||
acquire_accept_cred() so that it isn't affected by changes in
|
||||
cred->name->princ during acquire_init_cred().
|
||||
|
||||
ticket: 8978 (new)
|
||||
(cherry picked from commit c374ab40dd059a5938ffc0440d87457ac5da3a46)
|
||||
---
|
||||
src/include/k5-int.h | 9 +++
|
||||
src/include/k5-trace.h | 3 +
|
||||
src/lib/gssapi/krb5/accept_sec_context.c | 15 +---
|
||||
src/lib/gssapi/krb5/acquire_cred.c | 89 ++++++++++++++----------
|
||||
src/lib/gssapi/krb5/gssapiP_krb5.h | 1 +
|
||||
src/lib/gssapi/krb5/rel_cred.c | 1 +
|
||||
src/lib/krb5/ccache/cccursor.c | 57 +++++++++++----
|
||||
src/lib/krb5/libkrb5.exports | 1 +
|
||||
src/lib/krb5/os/sn2princ.c | 23 +++++-
|
||||
src/lib/krb5_32.def | 1 +
|
||||
src/tests/gssapi/t_client_keytab.py | 44 ++++++++++++
|
||||
src/tests/gssapi/t_credstore.py | 32 +++++++++
|
||||
12 files changed, 214 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||
index efb523689..46f2ce2d3 100644
|
||||
--- a/src/include/k5-int.h
|
||||
+++ b/src/include/k5-int.h
|
||||
@@ -2411,4 +2411,13 @@ void k5_change_error_message_code(krb5_context ctx, krb5_error_code oldcode,
|
||||
#define k5_prependmsg krb5_prepend_error_message
|
||||
#define k5_wrapmsg krb5_wrap_error_message
|
||||
|
||||
+/*
|
||||
+ * Like krb5_principal_compare(), but with canonicalization of sname if
|
||||
+ * fallback is enabled. This function should be avoided if multiple matches
|
||||
+ * are required, since repeated canonicalization is inefficient.
|
||||
+ */
|
||||
+krb5_boolean
|
||||
+k5_sname_compare(krb5_context context, krb5_const_principal sname,
|
||||
+ krb5_const_principal princ);
|
||||
+
|
||||
#endif /* _KRB5_INT_H */
|
||||
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
|
||||
index b3e039dc8..79b5a7a85 100644
|
||||
--- a/src/include/k5-trace.h
|
||||
+++ b/src/include/k5-trace.h
|
||||
@@ -105,6 +105,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
|
||||
|
||||
#endif /* DISABLE_TRACING */
|
||||
|
||||
+#define TRACE_CC_CACHE_MATCH(c, princ, ret) \
|
||||
+ TRACE(c, "Matching {princ} in collection with result: {kerr}", \
|
||||
+ princ, ret)
|
||||
#define TRACE_CC_DESTROY(c, cache) \
|
||||
TRACE(c, "Destroying ccache {ccache}", cache)
|
||||
#define TRACE_CC_GEN_NEW(c, cache) \
|
||||
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
index fcf2c2152..a1d7e0d96 100644
|
||||
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||
@@ -683,7 +683,6 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
krb5_flags ap_req_options = 0;
|
||||
krb5_enctype negotiated_etype;
|
||||
krb5_authdata_context ad_context = NULL;
|
||||
- krb5_principal accprinc = NULL;
|
||||
krb5_ap_req *request = NULL;
|
||||
|
||||
code = krb5int_accessor (&kaccess, KRB5INT_ACCESS_VERSION);
|
||||
@@ -849,17 +848,9 @@ kg_accept_krb5(minor_status, context_handle,
|
||||
}
|
||||
}
|
||||
|
||||
- if (!cred->default_identity) {
|
||||
- if ((code = kg_acceptor_princ(context, cred->name, &accprinc))) {
|
||||
- major_status = GSS_S_FAILURE;
|
||||
- goto fail;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- code = krb5_rd_req_decoded(context, &auth_context, request, accprinc,
|
||||
- cred->keytab, &ap_req_options, NULL);
|
||||
-
|
||||
- krb5_free_principal(context, accprinc);
|
||||
+ code = krb5_rd_req_decoded(context, &auth_context, request,
|
||||
+ cred->acceptor_mprinc, cred->keytab,
|
||||
+ &ap_req_options, NULL);
|
||||
if (code) {
|
||||
major_status = GSS_S_FAILURE;
|
||||
goto fail;
|
||||
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
|
||||
index 632ee7def..e226a0269 100644
|
||||
--- a/src/lib/gssapi/krb5/acquire_cred.c
|
||||
+++ b/src/lib/gssapi/krb5/acquire_cred.c
|
||||
@@ -123,11 +123,11 @@ gss_krb5int_register_acceptor_identity(OM_uint32 *minor_status,
|
||||
/* Try to verify that keytab contains at least one entry for name. Return 0 if
|
||||
* it does, KRB5_KT_NOTFOUND if it doesn't, or another error as appropriate. */
|
||||
static krb5_error_code
|
||||
-check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name)
|
||||
+check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name,
|
||||
+ krb5_principal mprinc)
|
||||
{
|
||||
krb5_error_code code;
|
||||
krb5_keytab_entry ent;
|
||||
- krb5_principal accprinc = NULL;
|
||||
char *princname;
|
||||
|
||||
if (name->service == NULL) {
|
||||
@@ -141,21 +141,15 @@ check_keytab(krb5_context context, krb5_keytab kt, krb5_gss_name_t name)
|
||||
if (kt->ops->start_seq_get == NULL)
|
||||
return 0;
|
||||
|
||||
- /* Get the partial principal for the acceptor name. */
|
||||
- code = kg_acceptor_princ(context, name, &accprinc);
|
||||
- if (code)
|
||||
- return code;
|
||||
-
|
||||
- /* Scan the keytab for host-based entries matching accprinc. */
|
||||
- code = k5_kt_have_match(context, kt, accprinc);
|
||||
+ /* Scan the keytab for host-based entries matching mprinc. */
|
||||
+ code = k5_kt_have_match(context, kt, mprinc);
|
||||
if (code == KRB5_KT_NOTFOUND) {
|
||||
- if (krb5_unparse_name(context, accprinc, &princname) == 0) {
|
||||
+ if (krb5_unparse_name(context, mprinc, &princname) == 0) {
|
||||
k5_setmsg(context, code, _("No key table entry found matching %s"),
|
||||
princname);
|
||||
free(princname);
|
||||
}
|
||||
}
|
||||
- krb5_free_principal(context, accprinc);
|
||||
return code;
|
||||
}
|
||||
|
||||
@@ -202,8 +196,14 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status,
|
||||
}
|
||||
|
||||
if (cred->name != NULL) {
|
||||
+ code = kg_acceptor_princ(context, cred->name, &cred->acceptor_mprinc);
|
||||
+ if (code) {
|
||||
+ major = GSS_S_FAILURE;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
/* Make sure we have keys matching the desired name in the keytab. */
|
||||
- code = check_keytab(context, kt, cred->name);
|
||||
+ code = check_keytab(context, kt, cred->name, cred->acceptor_mprinc);
|
||||
if (code) {
|
||||
if (code == KRB5_KT_NOTFOUND) {
|
||||
k5_change_error_message_code(context, code, KG_KEYTAB_NOMATCH);
|
||||
@@ -324,7 +324,6 @@ static krb5_boolean
|
||||
can_get_initial_creds(krb5_context context, krb5_gss_cred_id_rec *cred)
|
||||
{
|
||||
krb5_error_code code;
|
||||
- krb5_keytab_entry entry;
|
||||
|
||||
if (cred->password != NULL)
|
||||
return TRUE;
|
||||
@@ -336,20 +335,21 @@ can_get_initial_creds(krb5_context context, krb5_gss_cred_id_rec *cred)
|
||||
if (cred->name == NULL)
|
||||
return !krb5_kt_have_content(context, cred->client_keytab);
|
||||
|
||||
- /* Check if we have a keytab key for the client principal. */
|
||||
- code = krb5_kt_get_entry(context, cred->client_keytab, cred->name->princ,
|
||||
- 0, 0, &entry);
|
||||
- if (code) {
|
||||
- krb5_clear_error_message(context);
|
||||
- return FALSE;
|
||||
- }
|
||||
- krb5_free_keytab_entry_contents(context, &entry);
|
||||
- return TRUE;
|
||||
+ /*
|
||||
+ * Check if we have a keytab key for the client principal. This is a bit
|
||||
+ * more permissive than we really want because krb5_kt_have_match()
|
||||
+ * supports wildcarding and obeys ignore_acceptor_hostname, but that should
|
||||
+ * generally be harmless.
|
||||
+ */
|
||||
+ code = k5_kt_have_match(context, cred->client_keytab, cred->name->princ);
|
||||
+ return code == 0;
|
||||
}
|
||||
|
||||
-/* Scan cred->ccache for name, expiry time, impersonator, refresh time. */
|
||||
+/* Scan cred->ccache for name, expiry time, impersonator, refresh time. If
|
||||
+ * check_name is true, verify the cache name against the credential name. */
|
||||
static krb5_error_code
|
||||
-scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred)
|
||||
+scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred,
|
||||
+ krb5_boolean check_name)
|
||||
{
|
||||
krb5_error_code code;
|
||||
krb5_ccache ccache = cred->ccache;
|
||||
@@ -365,23 +365,31 @@ scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred)
|
||||
if (code)
|
||||
return code;
|
||||
|
||||
- /* Credentials cache principal must match the initiator name. */
|
||||
code = krb5_cc_get_principal(context, ccache, &ccache_princ);
|
||||
if (code != 0)
|
||||
goto cleanup;
|
||||
- if (cred->name != NULL &&
|
||||
- !krb5_principal_compare(context, ccache_princ, cred->name->princ)) {
|
||||
- code = KG_CCACHE_NOMATCH;
|
||||
- goto cleanup;
|
||||
- }
|
||||
|
||||
- /* Save the ccache principal as the credential name if not already set. */
|
||||
- if (!cred->name) {
|
||||
+ if (cred->name == NULL) {
|
||||
+ /* Save the ccache principal as the credential name. */
|
||||
code = kg_init_name(context, ccache_princ, NULL, NULL, NULL,
|
||||
KG_INIT_NAME_NO_COPY, &cred->name);
|
||||
if (code)
|
||||
goto cleanup;
|
||||
ccache_princ = NULL;
|
||||
+ } else {
|
||||
+ /* Check against the desired name if needed. */
|
||||
+ if (check_name) {
|
||||
+ if (!k5_sname_compare(context, cred->name->princ, ccache_princ)) {
|
||||
+ code = KG_CCACHE_NOMATCH;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Replace the credential name principal with the canonical client
|
||||
+ * principal, retaining acceptor_mprinc if set. */
|
||||
+ krb5_free_principal(context, cred->name->princ);
|
||||
+ cred->name->princ = ccache_princ;
|
||||
+ ccache_princ = NULL;
|
||||
}
|
||||
|
||||
assert(cred->name->princ != NULL);
|
||||
@@ -447,7 +455,7 @@ get_cache_for_name(krb5_context context, krb5_gss_cred_id_rec *cred)
|
||||
assert(cred->name != NULL && cred->ccache == NULL);
|
||||
#ifdef USE_LEASH
|
||||
code = get_ccache_leash(context, cred->name->princ, &cred->ccache);
|
||||
- return code ? code : scan_ccache(context, cred);
|
||||
+ return code ? code : scan_ccache(context, cred, TRUE);
|
||||
#else
|
||||
/* Check first whether we can acquire tickets, to avoid overwriting the
|
||||
* extended error message from krb5_cc_cache_match. */
|
||||
@@ -456,7 +464,7 @@ get_cache_for_name(krb5_context context, krb5_gss_cred_id_rec *cred)
|
||||
/* Look for an existing cache for the client principal. */
|
||||
code = krb5_cc_cache_match(context, cred->name->princ, &cred->ccache);
|
||||
if (code == 0)
|
||||
- return scan_ccache(context, cred);
|
||||
+ return scan_ccache(context, cred, FALSE);
|
||||
if (code != KRB5_CC_NOTFOUND || !can_get)
|
||||
return code;
|
||||
krb5_clear_error_message(context);
|
||||
@@ -633,6 +641,13 @@ get_initial_cred(krb5_context context, const struct verify_params *verify,
|
||||
kg_cred_set_initial_refresh(context, cred, &creds.times);
|
||||
cred->have_tgt = TRUE;
|
||||
cred->expire = creds.times.endtime;
|
||||
+
|
||||
+ /* Steal the canonical client principal name from creds and save it in the
|
||||
+ * credential name, retaining acceptor_mprinc if set. */
|
||||
+ krb5_free_principal(context, cred->name->princ);
|
||||
+ cred->name->princ = creds.client;
|
||||
+ creds.client = NULL;
|
||||
+
|
||||
krb5_free_cred_contents(context, &creds);
|
||||
cleanup:
|
||||
krb5_get_init_creds_opt_free(context, opt);
|
||||
@@ -721,7 +736,7 @@ acquire_init_cred(krb5_context context, OM_uint32 *minor_status,
|
||||
|
||||
if (cred->ccache != NULL) {
|
||||
/* The caller specified a ccache; check what's in it. */
|
||||
- code = scan_ccache(context, cred);
|
||||
+ code = scan_ccache(context, cred, TRUE);
|
||||
if (code == KRB5_FCC_NOFILE) {
|
||||
/* See if we can get initial creds. If the caller didn't specify
|
||||
* a name, pick one from the client keytab. */
|
||||
@@ -984,7 +999,7 @@ kg_cred_resolve(OM_uint32 *minor_status, krb5_context context,
|
||||
}
|
||||
}
|
||||
if (cred->ccache != NULL) {
|
||||
- code = scan_ccache(context, cred);
|
||||
+ code = scan_ccache(context, cred, FALSE);
|
||||
if (code)
|
||||
goto kerr;
|
||||
}
|
||||
@@ -996,7 +1011,7 @@ kg_cred_resolve(OM_uint32 *minor_status, krb5_context context,
|
||||
code = krb5int_cc_default(context, &cred->ccache);
|
||||
if (code)
|
||||
goto kerr;
|
||||
- code = scan_ccache(context, cred);
|
||||
+ code = scan_ccache(context, cred, FALSE);
|
||||
if (code == KRB5_FCC_NOFILE) {
|
||||
/* Default ccache doesn't exist; fall through to client keytab. */
|
||||
krb5_cc_close(context, cred->ccache);
|
||||
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
|
||||
index 3bacdcd35..fd7abbd77 100644
|
||||
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
|
||||
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
|
||||
@@ -175,6 +175,7 @@ typedef struct _krb5_gss_cred_id_rec {
|
||||
/* name/type of credential */
|
||||
gss_cred_usage_t usage;
|
||||
krb5_gss_name_t name;
|
||||
+ krb5_principal acceptor_mprinc;
|
||||
krb5_principal impersonator;
|
||||
unsigned int default_identity : 1;
|
||||
unsigned int iakerb_mech : 1;
|
||||
diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c
|
||||
index a9515daf7..0da6c1b95 100644
|
||||
--- a/src/lib/gssapi/krb5/rel_cred.c
|
||||
+++ b/src/lib/gssapi/krb5/rel_cred.c
|
||||
@@ -72,6 +72,7 @@ krb5_gss_release_cred(minor_status, cred_handle)
|
||||
if (cred->name)
|
||||
kg_release_name(context, &cred->name);
|
||||
|
||||
+ krb5_free_principal(context, cred->acceptor_mprinc);
|
||||
krb5_free_principal(context, cred->impersonator);
|
||||
|
||||
if (cred->req_enctypes)
|
||||
diff --git a/src/lib/krb5/ccache/cccursor.c b/src/lib/krb5/ccache/cccursor.c
|
||||
index 8f5872116..760216d05 100644
|
||||
--- a/src/lib/krb5/ccache/cccursor.c
|
||||
+++ b/src/lib/krb5/ccache/cccursor.c
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "cc-int.h"
|
||||
#include "../krb/int-proto.h"
|
||||
+#include "../os/os-proto.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -141,18 +142,18 @@ krb5_cccol_cursor_free(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-krb5_error_code KRB5_CALLCONV
|
||||
-krb5_cc_cache_match(krb5_context context, krb5_principal client,
|
||||
- krb5_ccache *cache_out)
|
||||
+static krb5_error_code
|
||||
+match_caches(krb5_context context, krb5_const_principal client,
|
||||
+ krb5_ccache *cache_out)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_cccol_cursor cursor;
|
||||
krb5_ccache cache = NULL;
|
||||
krb5_principal princ;
|
||||
- char *name;
|
||||
krb5_boolean eq;
|
||||
|
||||
*cache_out = NULL;
|
||||
+
|
||||
ret = krb5_cccol_cursor_new(context, &cursor);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -169,20 +170,52 @@ krb5_cc_cache_match(krb5_context context, krb5_principal client,
|
||||
krb5_cc_close(context, cache);
|
||||
}
|
||||
krb5_cccol_cursor_free(context, &cursor);
|
||||
+
|
||||
if (ret)
|
||||
return ret;
|
||||
- if (cache == NULL) {
|
||||
- ret = krb5_unparse_name(context, client, &name);
|
||||
- if (ret == 0) {
|
||||
- k5_setmsg(context, KRB5_CC_NOTFOUND,
|
||||
+ if (cache == NULL)
|
||||
+ return KRB5_CC_NOTFOUND;
|
||||
+
|
||||
+ *cache_out = cache;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+krb5_error_code KRB5_CALLCONV
|
||||
+krb5_cc_cache_match(krb5_context context, krb5_principal client,
|
||||
+ krb5_ccache *cache_out)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ struct canonprinc iter = { client, .subst_defrealm = TRUE };
|
||||
+ krb5_const_principal canonprinc = NULL;
|
||||
+ krb5_ccache cache = NULL;
|
||||
+ char *name;
|
||||
+
|
||||
+ *cache_out = NULL;
|
||||
+
|
||||
+ while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 &&
|
||||
+ canonprinc != NULL) {
|
||||
+ ret = match_caches(context, canonprinc, &cache);
|
||||
+ if (ret != KRB5_CC_NOTFOUND)
|
||||
+ break;
|
||||
+ }
|
||||
+ free_canonprinc(&iter);
|
||||
+
|
||||
+ if (ret == 0 && canonprinc == NULL) {
|
||||
+ ret = KRB5_CC_NOTFOUND;
|
||||
+ if (krb5_unparse_name(context, client, &name) == 0) {
|
||||
+ k5_setmsg(context, ret,
|
||||
_("Can't find client principal %s in cache collection"),
|
||||
name);
|
||||
krb5_free_unparsed_name(context, name);
|
||||
}
|
||||
- ret = KRB5_CC_NOTFOUND;
|
||||
- } else
|
||||
- *cache_out = cache;
|
||||
- return ret;
|
||||
+ }
|
||||
+
|
||||
+ TRACE_CC_CACHE_MATCH(context, client, ret);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ *cache_out = cache;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/* Store the error state for code from context into errsave, but only if code
|
||||
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
|
||||
index adbfa332b..df6e2ffbe 100644
|
||||
--- a/src/lib/krb5/libkrb5.exports
|
||||
+++ b/src/lib/krb5/libkrb5.exports
|
||||
@@ -181,6 +181,7 @@ k5_size_authdata_context
|
||||
k5_size_context
|
||||
k5_size_keyblock
|
||||
k5_size_principal
|
||||
+k5_sname_compare
|
||||
k5_unmarshal_cred
|
||||
k5_unmarshal_princ
|
||||
k5_unwrap_cammac_svc
|
||||
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c
|
||||
index 8b7214189..c99b7da17 100644
|
||||
--- a/src/lib/krb5/os/sn2princ.c
|
||||
+++ b/src/lib/krb5/os/sn2princ.c
|
||||
@@ -277,7 +277,8 @@ k5_canonprinc(krb5_context context, struct canonprinc *iter,
|
||||
|
||||
/* If we're not doing fallback, the input principal is canonical. */
|
||||
if (context->dns_canonicalize_hostname != CANONHOST_FALLBACK ||
|
||||
- iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2) {
|
||||
+ iter->princ->type != KRB5_NT_SRV_HST || iter->princ->length != 2 ||
|
||||
+ iter->princ->data[1].length == 0) {
|
||||
*princ_out = (step == 1) ? iter->princ : NULL;
|
||||
return 0;
|
||||
}
|
||||
@@ -288,6 +289,26 @@ k5_canonprinc(krb5_context context, struct canonprinc *iter,
|
||||
return canonicalize_princ(context, iter, step == 2, princ_out);
|
||||
}
|
||||
|
||||
+krb5_boolean
|
||||
+k5_sname_compare(krb5_context context, krb5_const_principal sname,
|
||||
+ krb5_const_principal princ)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ struct canonprinc iter = { sname, .subst_defrealm = TRUE };
|
||||
+ krb5_const_principal canonprinc = NULL;
|
||||
+ krb5_boolean match = FALSE;
|
||||
+
|
||||
+ while ((ret = k5_canonprinc(context, &iter, &canonprinc)) == 0 &&
|
||||
+ canonprinc != NULL) {
|
||||
+ if (krb5_principal_compare(context, canonprinc, princ)) {
|
||||
+ match = TRUE;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ free_canonprinc(&iter);
|
||||
+ return match;
|
||||
+}
|
||||
+
|
||||
krb5_error_code KRB5_CALLCONV
|
||||
krb5_sname_to_principal(krb5_context context, const char *hostname,
|
||||
const char *sname, krb5_int32 type,
|
||||
diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def
|
||||
index 60b8dd311..cf690dbe4 100644
|
||||
--- a/src/lib/krb5_32.def
|
||||
+++ b/src/lib/krb5_32.def
|
||||
@@ -507,3 +507,4 @@ EXPORTS
|
||||
; new in 1.20
|
||||
krb5_marshal_credentials @472
|
||||
krb5_unmarshal_credentials @473
|
||||
+ k5_sname_compare @474 ; PRIVATE GSSAPI
|
||||
diff --git a/src/tests/gssapi/t_client_keytab.py b/src/tests/gssapi/t_client_keytab.py
|
||||
index 7847b3ecd..9a61d53b8 100755
|
||||
--- a/src/tests/gssapi/t_client_keytab.py
|
||||
+++ b/src/tests/gssapi/t_client_keytab.py
|
||||
@@ -141,5 +141,49 @@ 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)
|
||||
+realm.run([kdestroy, '-A'])
|
||||
+
|
||||
+# Test 19: host-based initiator name
|
||||
+mark('host-based initiator name')
|
||||
+hsvc = 'h:svc@' + hostname
|
||||
+svcprinc = 'svc/%s@%s' % (hostname, realm.realm)
|
||||
+realm.addprinc(svcprinc)
|
||||
+realm.extract_keytab(svcprinc, realm.client_keytab)
|
||||
+# On the first run we match against the keytab while getting tickets,
|
||||
+# substituting the default realm.
|
||||
+msgs = ('/Can\'t find client principal svc/%s@ in' % hostname,
|
||||
+ 'Getting initial credentials for svc/%s@' % hostname,
|
||||
+ 'Found entries for %s in keytab' % svcprinc,
|
||||
+ 'Retrieving %s from FILE:%s' % (svcprinc, realm.client_keytab),
|
||||
+ 'Storing %s -> %s in' % (svcprinc, realm.krbtgt_princ),
|
||||
+ 'Retrieving %s -> %s from' % (svcprinc, realm.krbtgt_princ),
|
||||
+ 'authenticator for %s -> %s' % (svcprinc, realm.host_princ))
|
||||
+realm.run(['./t_ccselect', phost, hsvc], expected_trace=msgs)
|
||||
+# On the second run we match against the collection.
|
||||
+msgs = ('Matching svc/%s@ in collection with result: 0' % hostname,
|
||||
+ 'Getting credentials %s -> %s' % (svcprinc, realm.host_princ),
|
||||
+ 'authenticator for %s -> %s' % (svcprinc, realm.host_princ))
|
||||
+realm.run(['./t_ccselect', phost, hsvc], expected_trace=msgs)
|
||||
+realm.run([kdestroy, '-A'])
|
||||
+
|
||||
+# Test 20: host-based initiator name with fallback
|
||||
+mark('host-based fallback initiator name')
|
||||
+canonname = canonicalize_hostname(hostname)
|
||||
+if canonname != hostname:
|
||||
+ hfsvc = 'h:fsvc@' + hostname
|
||||
+ canonprinc = 'fsvc/%s@%s' % (canonname, realm.realm)
|
||||
+ realm.addprinc(canonprinc)
|
||||
+ realm.extract_keytab(canonprinc, realm.client_keytab)
|
||||
+ msgs = ('/Can\'t find client principal fsvc/%s@ in' % hostname,
|
||||
+ 'Found entries for %s in keytab' % canonprinc,
|
||||
+ 'authenticator for %s -> %s' % (canonprinc, realm.host_princ))
|
||||
+ realm.run(['./t_ccselect', phost, hfsvc], expected_trace=msgs)
|
||||
+ msgs = ('Matching fsvc/%s@ in collection with result: 0' % hostname,
|
||||
+ 'Getting credentials %s -> %s' % (canonprinc, realm.host_princ))
|
||||
+ realm.run(['./t_ccselect', phost, hfsvc], expected_trace=msgs)
|
||||
+ realm.run([kdestroy, '-A'])
|
||||
+else:
|
||||
+ skipped('GSS initiator name fallback test',
|
||||
+ '%s does not canonicalize to a different name' % hostname)
|
||||
|
||||
success('Client keytab tests')
|
||||
diff --git a/src/tests/gssapi/t_credstore.py b/src/tests/gssapi/t_credstore.py
|
||||
index c11975bf5..9be57bb82 100644
|
||||
--- a/src/tests/gssapi/t_credstore.py
|
||||
+++ b/src/tests/gssapi/t_credstore.py
|
||||
@@ -15,6 +15,38 @@ msgs = ('Storing %s -> %s in %s' % (service_cs, realm.krbtgt_princ,
|
||||
realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache,
|
||||
'keytab', servicekeytab], expected_trace=msgs)
|
||||
|
||||
+mark('matching')
|
||||
+scc = 'FILE:' + os.path.join(realm.testdir, 'service_cache')
|
||||
+realm.kinit(realm.host_princ, flags=['-k', '-c', scc])
|
||||
+realm.run(['./t_credstore', '-i', 'p:' + realm.host_princ, 'ccache', scc])
|
||||
+realm.run(['./t_credstore', '-i', 'h:host', 'ccache', scc])
|
||||
+realm.run(['./t_credstore', '-i', 'h:host@' + hostname, 'ccache', scc])
|
||||
+realm.run(['./t_credstore', '-i', 'p:wrong', 'ccache', scc],
|
||||
+ expected_code=1, expected_msg='does not match desired name')
|
||||
+realm.run(['./t_credstore', '-i', 'h:host@-nomatch-', 'ccache', scc],
|
||||
+ expected_code=1, expected_msg='does not match desired name')
|
||||
+realm.run(['./t_credstore', '-i', 'h:svc', 'ccache', scc],
|
||||
+ expected_code=1, expected_msg='does not match desired name')
|
||||
+
|
||||
+mark('matching (fallback)')
|
||||
+canonname = canonicalize_hostname(hostname)
|
||||
+if canonname != hostname:
|
||||
+ canonprinc = 'host/%s@%s' % (canonname, realm.realm)
|
||||
+ realm.addprinc(canonprinc)
|
||||
+ realm.extract_keytab(canonprinc, realm.keytab)
|
||||
+ realm.kinit(canonprinc, flags=['-k', '-c', scc])
|
||||
+ realm.run(['./t_credstore', '-i', 'h:host', 'ccache', scc])
|
||||
+ realm.run(['./t_credstore', '-i', 'h:host@' + hostname, 'ccache', scc])
|
||||
+ realm.run(['./t_credstore', '-i', 'h:host@' + canonname, 'ccache', scc])
|
||||
+ realm.run(['./t_credstore', '-i', 'p:' + canonprinc, 'ccache', scc])
|
||||
+ realm.run(['./t_credstore', '-i', 'p:' + realm.host_princ, 'ccache', scc],
|
||||
+ expected_code=1, expected_msg='does not match desired name')
|
||||
+ realm.run(['./t_credstore', '-i', 'h:host@-nomatch-', 'ccache', scc],
|
||||
+ expected_code=1, expected_msg='does not match desired name')
|
||||
+else:
|
||||
+ skipped('fallback matching test',
|
||||
+ '%s does not canonicalize to a different name' % hostname)
|
||||
+
|
||||
mark('rcache')
|
||||
# t_credstore -r should produce a replay error normally, but not with
|
||||
# rcache set to "none:".
|
@ -1,91 +0,0 @@
|
||||
From 1f706852ee759160e763c355a3053ad5e045fa06 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 4 Mar 2022 00:45:00 -0500
|
||||
Subject: [PATCH] Try harder to avoid password change replay errors
|
||||
|
||||
Commit d7b3018d338fc9c989c3fa17505870f23c3759a8 (ticket 7905) changed
|
||||
change_set_password() to prefer TCP. However, because UDP_LAST falls
|
||||
back to UDP after one second, we can still get a replay error due to a
|
||||
dropped packet, before the TCP layer has a chance to retry.
|
||||
|
||||
Instead, try k5_sendto() with NO_UDP, and only fall back to UDP after
|
||||
TCP fails completely without reaching a server. In sendto_kdc.c,
|
||||
implement an ONLY_UDP transport strategy to allow the UDP fallback.
|
||||
|
||||
ticket: 9037
|
||||
---
|
||||
src/lib/krb5/os/changepw.c | 9 ++++++++-
|
||||
src/lib/krb5/os/os-proto.h | 1 +
|
||||
src/lib/krb5/os/sendto_kdc.c | 12 ++++++++----
|
||||
3 files changed, 17 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
|
||||
index 9f968da7f..c59232586 100644
|
||||
--- a/src/lib/krb5/os/changepw.c
|
||||
+++ b/src/lib/krb5/os/changepw.c
|
||||
@@ -255,9 +255,16 @@ change_set_password(krb5_context context,
|
||||
callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup;
|
||||
krb5_free_data_contents(callback_ctx.context, &chpw_rep);
|
||||
|
||||
+ /* UDP retransmits may be seen as replays. Only try UDP after other
|
||||
+ * transports fail completely. */
|
||||
code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm,
|
||||
- &sl, UDP_LAST, &callback_info, &chpw_rep,
|
||||
+ &sl, NO_UDP, &callback_info, &chpw_rep,
|
||||
ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL);
|
||||
+ if (code == KRB5_KDC_UNREACH) {
|
||||
+ code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm,
|
||||
+ &sl, ONLY_UDP, &callback_info, &chpw_rep,
|
||||
+ ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL);
|
||||
+ }
|
||||
if (code)
|
||||
goto cleanup;
|
||||
|
||||
diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h
|
||||
index a985f2aec..91d2791ce 100644
|
||||
--- a/src/lib/krb5/os/os-proto.h
|
||||
+++ b/src/lib/krb5/os/os-proto.h
|
||||
@@ -49,6 +49,7 @@ typedef enum {
|
||||
UDP_FIRST = 0,
|
||||
UDP_LAST,
|
||||
NO_UDP,
|
||||
+ ONLY_UDP
|
||||
} k5_transport_strategy;
|
||||
|
||||
/* A single server hostname or address. */
|
||||
diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c
|
||||
index 0eedec175..c7f5d861a 100644
|
||||
--- a/src/lib/krb5/os/sendto_kdc.c
|
||||
+++ b/src/lib/krb5/os/sendto_kdc.c
|
||||
@@ -802,11 +802,14 @@ resolve_server(krb5_context context, const krb5_data *realm,
|
||||
int err, result;
|
||||
char portbuf[PORT_LENGTH];
|
||||
|
||||
- /* Skip UDP entries if we don't want UDP. */
|
||||
+ /* Skip entries excluded by the strategy. */
|
||||
if (strategy == NO_UDP && entry->transport == UDP)
|
||||
return 0;
|
||||
+ if (strategy == ONLY_UDP && entry->transport != UDP &&
|
||||
+ entry->transport != TCP_OR_UDP)
|
||||
+ return 0;
|
||||
|
||||
- transport = (strategy == UDP_FIRST) ? UDP : TCP;
|
||||
+ transport = (strategy == UDP_FIRST || strategy == ONLY_UDP) ? UDP : TCP;
|
||||
if (entry->hostname == NULL) {
|
||||
/* Added by a module, so transport is either TCP or UDP. */
|
||||
ai.ai_socktype = socktype_for_transport(entry->transport);
|
||||
@@ -850,8 +853,9 @@ resolve_server(krb5_context context, const krb5_data *realm,
|
||||
}
|
||||
|
||||
/* For TCP_OR_UDP entries, add each address again with the non-preferred
|
||||
- * transport, unless we are avoiding UDP. Flag these as deferred. */
|
||||
- if (retval == 0 && entry->transport == TCP_OR_UDP && strategy != NO_UDP) {
|
||||
+ * transport, if there is one. Flag these as deferred. */
|
||||
+ if (retval == 0 && entry->transport == TCP_OR_UDP &&
|
||||
+ (strategy == UDP_FIRST || strategy == UDP_LAST)) {
|
||||
transport = (strategy == UDP_FIRST) ? TCP : UDP;
|
||||
for (a = addrs; a != 0 && retval == 0; a = a->ai_next) {
|
||||
a->ai_socktype = socktype_for_transport(transport);
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,235 +0,0 @@
|
||||
From 336f744403baa5dfaffcc5bd226fdd8f14a0200b Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Fri, 26 Mar 2021 23:38:54 -0400
|
||||
Subject: [PATCH] Use KCM_OP_RETRIEVE in KCM client
|
||||
|
||||
In kcm_retrieve(), try KCM_OP_RETRIEVE. Fall back to iteration if the
|
||||
server doesn't implement it, or if we can an answer incompatible with
|
||||
KRB5_TC_SUPPORTED_KTYPES.
|
||||
|
||||
In kcmserver.py, implement partial decoding for creds and cred tags so
|
||||
that we can do a basic principal name match.
|
||||
|
||||
ticket: 8997 (new)
|
||||
(cherry picked from commit 795ebba8c039be172ab93cd41105c73ffdba0fdb)
|
||||
---
|
||||
src/include/kcm.h | 2 +-
|
||||
src/lib/krb5/ccache/cc_kcm.c | 52 +++++++++++++++++++++++++++++++++---
|
||||
src/tests/kcmserver.py | 44 +++++++++++++++++++++++++++---
|
||||
src/tests/t_ccache.py | 11 +++++---
|
||||
4 files changed, 99 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/include/kcm.h b/src/include/kcm.h
|
||||
index 9b66f1cbd..85c20d345 100644
|
||||
--- a/src/include/kcm.h
|
||||
+++ b/src/include/kcm.h
|
||||
@@ -87,7 +87,7 @@ typedef enum kcm_opcode {
|
||||
KCM_OP_INITIALIZE, /* (name, princ) -> () */
|
||||
KCM_OP_DESTROY, /* (name) -> () */
|
||||
KCM_OP_STORE, /* (name, cred) -> () */
|
||||
- KCM_OP_RETRIEVE,
|
||||
+ KCM_OP_RETRIEVE, /* (name, flags, credtag) -> (cred) */
|
||||
KCM_OP_GET_PRINCIPAL, /* (name) -> (princ) */
|
||||
KCM_OP_GET_CRED_UUID_LIST, /* (name) -> (uuid, ...) */
|
||||
KCM_OP_GET_CRED_BY_UUID, /* (name, uuid) -> (cred) */
|
||||
diff --git a/src/lib/krb5/ccache/cc_kcm.c b/src/lib/krb5/ccache/cc_kcm.c
|
||||
index 46705f1da..23fcf13ea 100644
|
||||
--- a/src/lib/krb5/ccache/cc_kcm.c
|
||||
+++ b/src/lib/krb5/ccache/cc_kcm.c
|
||||
@@ -826,9 +826,55 @@ static krb5_error_code KRB5_CALLCONV
|
||||
kcm_retrieve(krb5_context context, krb5_ccache cache, krb5_flags flags,
|
||||
krb5_creds *mcred, krb5_creds *cred_out)
|
||||
{
|
||||
- /* There is a KCM opcode for retrieving creds, but Heimdal's client doesn't
|
||||
- * use it. It causes the KCM daemon to actually make a TGS request. */
|
||||
- return k5_cc_retrieve_cred_default(context, cache, flags, mcred, cred_out);
|
||||
+ krb5_error_code ret;
|
||||
+ struct kcmreq req = EMPTY_KCMREQ;
|
||||
+ krb5_creds cred;
|
||||
+ krb5_enctype *enctypes = NULL;
|
||||
+
|
||||
+ memset(&cred, 0, sizeof(cred));
|
||||
+
|
||||
+ /* Include KCM_GC_CACHED in flags to prevent Heimdal's sssd from making a
|
||||
+ * TGS request itself. */
|
||||
+ kcmreq_init(&req, KCM_OP_RETRIEVE, cache);
|
||||
+ k5_buf_add_uint32_be(&req.reqbuf, map_tcflags(flags) | KCM_GC_CACHED);
|
||||
+ k5_marshal_mcred(&req.reqbuf, mcred);
|
||||
+ ret = cache_call(context, cache, &req);
|
||||
+
|
||||
+ /* Fall back to iteration if the server does not support retrieval. */
|
||||
+ if (ret == KRB5_FCC_INTERNAL || ret == KRB5_CC_IO) {
|
||||
+ ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred,
|
||||
+ cred_out);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ ret = k5_unmarshal_cred(req.reply.ptr, req.reply.len, 4, &cred);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* In rare cases we might retrieve a credential with a session key this
|
||||
+ * context can't support, in which case we must retry using iteration. */
|
||||
+ if (flags & KRB5_TC_SUPPORTED_KTYPES) {
|
||||
+ ret = krb5_get_tgs_ktypes(context, cred.server, &enctypes);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+ if (!k5_etypes_contains(enctypes, cred.keyblock.enctype)) {
|
||||
+ ret = k5_cc_retrieve_cred_default(context, cache, flags, mcred,
|
||||
+ cred_out);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *cred_out = cred;
|
||||
+ memset(&cred, 0, sizeof(cred));
|
||||
+
|
||||
+cleanup:
|
||||
+ kcmreq_free(&req);
|
||||
+ krb5_free_cred_contents(context, &cred);
|
||||
+ free(enctypes);
|
||||
+ /* Heimdal's KCM returns KRB5_CC_END if no cred is found. */
|
||||
+ return (ret == KRB5_CC_END) ? KRB5_CC_NOTFOUND : map_invalid(ret);
|
||||
}
|
||||
|
||||
static krb5_error_code KRB5_CALLCONV
|
||||
diff --git a/src/tests/kcmserver.py b/src/tests/kcmserver.py
|
||||
index 8c5e66ff1..25e6f2bbe 100644
|
||||
--- a/src/tests/kcmserver.py
|
||||
+++ b/src/tests/kcmserver.py
|
||||
@@ -40,6 +40,7 @@ class KCMOpcodes(object):
|
||||
INITIALIZE = 4
|
||||
DESTROY = 5
|
||||
STORE = 6
|
||||
+ RETRIEVE = 7
|
||||
GET_PRINCIPAL = 8
|
||||
GET_CRED_UUID_LIST = 9
|
||||
GET_CRED_BY_UUID = 10
|
||||
@@ -54,6 +55,7 @@ class KCMOpcodes(object):
|
||||
|
||||
|
||||
class KRB5Errors(object):
|
||||
+ KRB5_CC_NOTFOUND = -1765328243
|
||||
KRB5_CC_END = -1765328242
|
||||
KRB5_CC_NOSUPP = -1765328137
|
||||
KRB5_FCC_NOFILE = -1765328189
|
||||
@@ -86,11 +88,29 @@ def get_cache(name):
|
||||
return cache
|
||||
|
||||
|
||||
+def unpack_data(argbytes):
|
||||
+ dlen, = struct.unpack('>L', argbytes[:4])
|
||||
+ return argbytes[4:dlen+4], argbytes[dlen+4:]
|
||||
+
|
||||
+
|
||||
def unmarshal_name(argbytes):
|
||||
offset = argbytes.find(b'\0')
|
||||
return argbytes[0:offset], argbytes[offset+1:]
|
||||
|
||||
|
||||
+def unmarshal_princ(argbytes):
|
||||
+ # Ignore the type at argbytes[0:4].
|
||||
+ ncomps, = struct.unpack('>L', argbytes[4:8])
|
||||
+ realm, rest = unpack_data(argbytes[8:])
|
||||
+ comps = []
|
||||
+ for i in range(ncomps):
|
||||
+ comp, rest = unpack_data(rest)
|
||||
+ comps.append(comp)
|
||||
+ # Asssume no quoting is needed.
|
||||
+ princ = b'/'.join(comps) + b'@' + realm
|
||||
+ return princ, rest
|
||||
+
|
||||
+
|
||||
def op_gen_new(argbytes):
|
||||
# Does not actually check for uniqueness.
|
||||
global next_unique
|
||||
@@ -126,6 +146,22 @@ def op_store(argbytes):
|
||||
return 0, b''
|
||||
|
||||
|
||||
+def op_retrieve(argbytes):
|
||||
+ name, rest = unmarshal_name(argbytes)
|
||||
+ # Ignore the flags at rest[0:4] and the header at rest[4:8].
|
||||
+ # Assume there are client and server creds in the tag and match
|
||||
+ # only against them.
|
||||
+ cprinc, rest = unmarshal_princ(rest[8:])
|
||||
+ sprinc, rest = unmarshal_princ(rest)
|
||||
+ cache = get_cache(name)
|
||||
+ for cred in (cache.creds[u] for u in cache.cred_uuids):
|
||||
+ cred_cprinc, rest = unmarshal_princ(cred)
|
||||
+ cred_sprinc, rest = unmarshal_princ(rest)
|
||||
+ if cred_cprinc == cprinc and cred_sprinc == sprinc:
|
||||
+ return 0, cred
|
||||
+ return KRB5Errors.KRB5_CC_NOTFOUND, b''
|
||||
+
|
||||
+
|
||||
def op_get_principal(argbytes):
|
||||
name, rest = unmarshal_name(argbytes)
|
||||
cache = get_cache(name)
|
||||
@@ -199,6 +235,7 @@ ophandlers = {
|
||||
KCMOpcodes.INITIALIZE : op_initialize,
|
||||
KCMOpcodes.DESTROY : op_destroy,
|
||||
KCMOpcodes.STORE : op_store,
|
||||
+ KCMOpcodes.RETRIEVE : op_retrieve,
|
||||
KCMOpcodes.GET_PRINCIPAL : op_get_principal,
|
||||
KCMOpcodes.GET_CRED_UUID_LIST : op_get_cred_uuid_list,
|
||||
KCMOpcodes.GET_CRED_BY_UUID : op_get_cred_by_uuid,
|
||||
@@ -243,10 +280,11 @@ def service_request(s):
|
||||
return True
|
||||
|
||||
parser = optparse.OptionParser()
|
||||
-parser.add_option('-c', '--credlist', action='store_true', dest='credlist',
|
||||
- default=False, help='Support KCM_OP_GET_CRED_LIST')
|
||||
+parser.add_option('-f', '--fallback', action='store_true', dest='fallback',
|
||||
+ default=False, help='Do not support RETRIEVE/GET_CRED_LIST')
|
||||
(options, args) = parser.parse_args()
|
||||
-if not options.credlist:
|
||||
+if options.fallback:
|
||||
+ del ophandlers[KCMOpcodes.RETRIEVE]
|
||||
del ophandlers[KCMOpcodes.GET_CRED_LIST]
|
||||
|
||||
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
diff --git a/src/tests/t_ccache.py b/src/tests/t_ccache.py
|
||||
index 90040fb7b..6ea9fb969 100755
|
||||
--- a/src/tests/t_ccache.py
|
||||
+++ b/src/tests/t_ccache.py
|
||||
@@ -25,7 +25,7 @@ from k5test import *
|
||||
kcm_socket_path = os.path.join(os.getcwd(), 'testdir', 'kcm')
|
||||
conf = {'libdefaults': {'kcm_socket': kcm_socket_path,
|
||||
'kcm_mach_service': '-'}}
|
||||
-realm = K5Realm(create_host=False, krb5_conf=conf)
|
||||
+realm = K5Realm(krb5_conf=conf)
|
||||
|
||||
keyctl = which('keyctl')
|
||||
out = realm.run([klist, '-c', 'KEYRING:process:abcd'], expected_code=1)
|
||||
@@ -71,6 +71,11 @@ def collection_test(realm, ccname):
|
||||
realm.kinit('alice', password('alice'))
|
||||
realm.run([klist], expected_msg='Default principal: alice@')
|
||||
realm.run([klist, '-A', '-s'])
|
||||
+ realm.run([kvno, realm.host_princ], expected_msg = 'kvno = 1')
|
||||
+ realm.run([kvno, realm.host_princ], expected_msg = 'kvno = 1')
|
||||
+ out = realm.run([klist])
|
||||
+ if out.count(realm.host_princ) != 1:
|
||||
+ fail('Wrong number of service tickets in cache')
|
||||
realm.run([kdestroy])
|
||||
output = realm.run([klist], expected_code=1)
|
||||
if 'No credentials cache' not in output and 'not found' not in output:
|
||||
@@ -126,14 +131,14 @@ def collection_test(realm, ccname):
|
||||
|
||||
collection_test(realm, 'DIR:' + os.path.join(realm.testdir, 'cc'))
|
||||
|
||||
-# Test KCM without and with GET_CRED_LIST support.
|
||||
+# Test KCM with and without RETRIEVE and GET_CRED_LIST support.
|
||||
kcmserver_path = os.path.join(srctop, 'tests', 'kcmserver.py')
|
||||
kcmd = realm.start_server([sys.executable, kcmserver_path, kcm_socket_path],
|
||||
'starting...')
|
||||
collection_test(realm, 'KCM:')
|
||||
stop_daemon(kcmd)
|
||||
os.remove(kcm_socket_path)
|
||||
-realm.start_server([sys.executable, kcmserver_path, '-c', kcm_socket_path],
|
||||
+realm.start_server([sys.executable, kcmserver_path, '-f', kcm_socket_path],
|
||||
'starting...')
|
||||
collection_test(realm, 'KCM:')
|
||||
|
@ -1,482 +0,0 @@
|
||||
From 21e3b9a4463f1d1aeb71de8a27c298f1307d186b Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Fri, 4 Oct 2019 14:49:29 -0400
|
||||
Subject: [PATCH] Use OpenSSL's KBKDF and KRB5KDF for deriving long-term keys
|
||||
|
||||
If supported, use OpenSSL-provided KBKDF (aes-sha2 and camellia) and
|
||||
KRB5KDF (3des and aes-sha1). We already use OpenSSL's PBKDF2 where
|
||||
appropriate. OpenSSL added support for these KDFs in 3.0.
|
||||
|
||||
(cherry picked from commit ef8d11f6fb1232201c9efd2ae2ed567023fb85d2)
|
||||
[rharwood@redhat.com: 3des removal]
|
||||
---
|
||||
src/lib/crypto/krb/derive.c | 409 ++++++++++++++++++++++++++++--------
|
||||
1 file changed, 324 insertions(+), 85 deletions(-)
|
||||
|
||||
diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
|
||||
index 6707a7308..8e474b38e 100644
|
||||
--- a/src/lib/crypto/krb/derive.c
|
||||
+++ b/src/lib/crypto/krb/derive.c
|
||||
@@ -27,6 +27,12 @@
|
||||
|
||||
#include "crypto_int.h"
|
||||
|
||||
+#ifdef HAVE_EVP_KDF_FETCH
|
||||
+#include <openssl/core_names.h>
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/kdf.h>
|
||||
+#endif
|
||||
+
|
||||
static krb5_key
|
||||
find_cached_dkey(struct derived_key *list, const krb5_data *constant)
|
||||
{
|
||||
@@ -77,55 +83,251 @@ cleanup:
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_EVP_KDF_FETCH
|
||||
static krb5_error_code
|
||||
-derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
- krb5_key inkey, krb5_data *outrnd,
|
||||
- const krb5_data *in_constant)
|
||||
+openssl_kbdkf_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *label, const krb5_data *context)
|
||||
{
|
||||
- size_t blocksize, keybytes, n;
|
||||
krb5_error_code ret;
|
||||
- krb5_data block = empty_data();
|
||||
+ EVP_KDF *kdf = NULL;
|
||||
+ EVP_KDF_CTX *kctx = NULL;
|
||||
+ OSSL_PARAM params[6];
|
||||
+ size_t i = 0;
|
||||
+ char *digest;
|
||||
|
||||
- blocksize = enc->block_size;
|
||||
- keybytes = enc->keybytes;
|
||||
+ /* On NULL hash, preserve default behavior for pbkdf2_string_to_key(). */
|
||||
+ if (hash == NULL || !strcmp(hash->hash_name, "SHA1")) {
|
||||
+ digest = "SHA1";
|
||||
+ } else if (!strcmp(hash->hash_name, "SHA-256")) {
|
||||
+ digest = "SHA256";
|
||||
+ } else if (!strcmp(hash->hash_name, "SHA-384")) {
|
||||
+ digest = "SHA384";
|
||||
+ } else {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
- if (blocksize == 1)
|
||||
- return KRB5_BAD_ENCTYPE;
|
||||
- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
|
||||
+ kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL);
|
||||
+ if (!kdf) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kctx = EVP_KDF_CTX_new(kdf);
|
||||
+ if (!kctx) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
+ digest, 0);
|
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
|
||||
+ "HMAC", 0);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
||||
+ inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
|
||||
+ context->data,
|
||||
+ context->length);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
|
||||
+ label->data,
|
||||
+ label->length);
|
||||
+ params[i] = OSSL_PARAM_construct_end();
|
||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length,
|
||||
+ params) <= 0) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_free(kdf);
|
||||
+ EVP_KDF_CTX_free(kctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static krb5_error_code
|
||||
+openssl_kbkdf_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ EVP_KDF *kdf = NULL;
|
||||
+ EVP_KDF_CTX *kctx = NULL;
|
||||
+ OSSL_PARAM params[7];
|
||||
+ size_t i = 0;
|
||||
+ char *cipher;
|
||||
+ static unsigned char zeroes[16];
|
||||
+
|
||||
+ memset(zeroes, 0, sizeof(zeroes));
|
||||
+
|
||||
+ if (!memcmp(enc, &krb5int_enc_camellia128, sizeof(*enc))) {
|
||||
+ cipher = "CAMELLIA-128-CBC";
|
||||
+ } else if (!memcmp(enc, &krb5int_enc_camellia256, sizeof(*enc))) {
|
||||
+ cipher = "CAMELLIA-256-CBC";
|
||||
+ } else {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL);
|
||||
+ if (!kdf) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kctx = EVP_KDF_CTX_new(kdf);
|
||||
+ if (!kctx) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE,
|
||||
+ "FEEDBACK", 0);
|
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC,
|
||||
+ "CMAC", 0);
|
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER,
|
||||
+ cipher, 0);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
||||
+ inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
|
||||
+ in_constant->data,
|
||||
+ in_constant->length);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED,
|
||||
+ zeroes, sizeof(zeroes));
|
||||
+ params[i] = OSSL_PARAM_construct_end();
|
||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length,
|
||||
+ params) <= 0) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_free(kdf);
|
||||
+ EVP_KDF_CTX_free(kctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static krb5_error_code
|
||||
+openssl_krb5kdf(const struct krb5_enc_provider *enc, krb5_key inkey,
|
||||
+ krb5_data *outrnd, const krb5_data *in_constant)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ EVP_KDF *kdf = NULL;
|
||||
+ EVP_KDF_CTX *kctx = NULL;
|
||||
+ OSSL_PARAM params[4];
|
||||
+ size_t i = 0;
|
||||
+ char *cipher;
|
||||
+
|
||||
+ if (inkey->keyblock.length != enc->keylength ||
|
||||
+ outrnd->length != enc->keybytes) {
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!memcmp(enc, &krb5int_enc_aes128, sizeof(*enc))) {
|
||||
+ cipher = "AES-128-CBC";
|
||||
+ } else if (!memcmp(enc, &krb5int_enc_aes256, sizeof(*enc))) {
|
||||
+ cipher = "AES-256-CBC";
|
||||
+ } else {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL);
|
||||
+ if (kdf == NULL) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kctx = EVP_KDF_CTX_new(kdf);
|
||||
+ if (kctx == NULL) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER,
|
||||
+ cipher, 0);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
||||
+ inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_CONSTANT,
|
||||
+ in_constant->data,
|
||||
+ in_constant->length);
|
||||
+ params[i] = OSSL_PARAM_construct_end();
|
||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)outrnd->data, outrnd->length,
|
||||
+ params) <= 0) {
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_free(kdf);
|
||||
+ EVP_KDF_CTX_free(kctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#else /* HAVE_EVP_KDF_FETCH */
|
||||
+
|
||||
+/*
|
||||
+ * NIST SP800-108 KDF in counter mode (section 5.1).
|
||||
+ * Parameters:
|
||||
+ * - HMAC (with hash as the hash provider) is the PRF.
|
||||
+ * - A block counter of four bytes is used.
|
||||
+ * - Four bytes are used to encode the output length in the PRF input.
|
||||
+ *
|
||||
+ * There are no uses requiring more than a single PRF invocation.
|
||||
+ */
|
||||
+static krb5_error_code
|
||||
+builtin_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *label,
|
||||
+ const krb5_data *context)
|
||||
+{
|
||||
+ krb5_crypto_iov iov[5];
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_data prf;
|
||||
+ unsigned char ibuf[4], lbuf[4];
|
||||
+
|
||||
+ if (hash == NULL || outrnd->length > hash->hashsize)
|
||||
return KRB5_CRYPTO_INTERNAL;
|
||||
|
||||
/* Allocate encryption data buffer. */
|
||||
- ret = alloc_data(&block, blocksize);
|
||||
+ ret = alloc_data(&prf, hash->hashsize);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Initialize the input block. */
|
||||
- if (in_constant->length == blocksize) {
|
||||
- memcpy(block.data, in_constant->data, blocksize);
|
||||
- } else {
|
||||
- krb5int_nfold(in_constant->length * 8,
|
||||
- (unsigned char *) in_constant->data,
|
||||
- blocksize * 8, (unsigned char *) block.data);
|
||||
- }
|
||||
+ /* [i]2: four-byte big-endian binary string giving the block counter (1) */
|
||||
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[0].data = make_data(ibuf, sizeof(ibuf));
|
||||
+ store_32_be(1, ibuf);
|
||||
+ /* Label */
|
||||
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[1].data = *label;
|
||||
+ /* 0x00: separator byte */
|
||||
+ iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[2].data = make_data("", 1);
|
||||
+ /* Context */
|
||||
+ iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[3].data = *context;
|
||||
+ /* [L]2: four-byte big-endian binary string giving the output length */
|
||||
+ iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[4].data = make_data(lbuf, sizeof(lbuf));
|
||||
+ store_32_be(outrnd->length * 8, lbuf);
|
||||
|
||||
- /* Loop encrypting the blocks until enough key bytes are generated. */
|
||||
- n = 0;
|
||||
- while (n < keybytes) {
|
||||
- ret = encrypt_block(enc, inkey, &block);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
-
|
||||
- if ((keybytes - n) <= blocksize) {
|
||||
- memcpy(outrnd->data + n, block.data, (keybytes - n));
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- memcpy(outrnd->data + n, block.data, blocksize);
|
||||
- n += blocksize;
|
||||
- }
|
||||
-
|
||||
-cleanup:
|
||||
- zapfree(block.data, blocksize);
|
||||
+ ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
|
||||
+ if (!ret)
|
||||
+ memcpy(outrnd->data, prf.data, outrnd->length);
|
||||
+ zapfree(prf.data, prf.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -139,9 +341,9 @@ cleanup:
|
||||
* - Four bytes are used to encode the output length in the PRF input.
|
||||
*/
|
||||
static krb5_error_code
|
||||
-derive_random_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
- krb5_key inkey, krb5_data *outrnd,
|
||||
- const krb5_data *in_constant)
|
||||
+builtin_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
{
|
||||
size_t blocksize, keybytes, n;
|
||||
krb5_crypto_iov iov[6];
|
||||
@@ -204,56 +406,94 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * NIST SP800-108 KDF in counter mode (section 5.1).
|
||||
- * Parameters:
|
||||
- * - HMAC (with hash as the hash provider) is the PRF.
|
||||
- * - A block counter of four bytes is used.
|
||||
- * - Four bytes are used to encode the output length in the PRF input.
|
||||
- *
|
||||
- * There are no uses requiring more than a single PRF invocation.
|
||||
- */
|
||||
+static krb5_error_code
|
||||
+builtin_derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+ size_t blocksize, keybytes, n;
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_data block = empty_data();
|
||||
+
|
||||
+ blocksize = enc->block_size;
|
||||
+ keybytes = enc->keybytes;
|
||||
+
|
||||
+ if (blocksize == 1)
|
||||
+ return KRB5_BAD_ENCTYPE;
|
||||
+ if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+
|
||||
+ /* Allocate encryption data buffer. */
|
||||
+ ret = alloc_data(&block, blocksize);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Initialize the input block. */
|
||||
+ if (in_constant->length == blocksize) {
|
||||
+ memcpy(block.data, in_constant->data, blocksize);
|
||||
+ } else {
|
||||
+ krb5int_nfold(in_constant->length * 8,
|
||||
+ (unsigned char *) in_constant->data,
|
||||
+ blocksize * 8, (unsigned char *) block.data);
|
||||
+ }
|
||||
+
|
||||
+ /* Loop encrypting the blocks until enough key bytes are generated. */
|
||||
+ n = 0;
|
||||
+ while (n < keybytes) {
|
||||
+ ret = encrypt_block(enc, inkey, &block);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if ((keybytes - n) <= blocksize) {
|
||||
+ memcpy(outrnd->data + n, block.data, (keybytes - n));
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(outrnd->data + n, block.data, blocksize);
|
||||
+ n += blocksize;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ zapfree(block.data, blocksize);
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif /* HAVE_EVP_KDF_FETCH */
|
||||
+
|
||||
krb5_error_code
|
||||
k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
krb5_key inkey, krb5_data *outrnd,
|
||||
const krb5_data *label, const krb5_data *context)
|
||||
{
|
||||
- krb5_crypto_iov iov[5];
|
||||
- krb5_error_code ret;
|
||||
- krb5_data prf;
|
||||
- unsigned char ibuf[4], lbuf[4];
|
||||
+#ifdef HAVE_EVP_KDF_FETCH
|
||||
+ return openssl_kbdkf_counter_hmac(hash, inkey, outrnd, label, context);
|
||||
+#else
|
||||
+ return builtin_sp800_108_counter_hmac(hash, inkey, outrnd, label,
|
||||
+ context);
|
||||
+#endif
|
||||
+}
|
||||
|
||||
- if (hash == NULL || outrnd->length > hash->hashsize)
|
||||
- return KRB5_CRYPTO_INTERNAL;
|
||||
+static krb5_error_code
|
||||
+sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+#ifdef HAVE_EVP_KDF_FETCH
|
||||
+ return openssl_kbkdf_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
+#else
|
||||
+ return builtin_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
+#endif
|
||||
+}
|
||||
|
||||
- /* Allocate encryption data buffer. */
|
||||
- ret = alloc_data(&prf, hash->hashsize);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- /* [i]2: four-byte big-endian binary string giving the block counter (1) */
|
||||
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[0].data = make_data(ibuf, sizeof(ibuf));
|
||||
- store_32_be(1, ibuf);
|
||||
- /* Label */
|
||||
- iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[1].data = *label;
|
||||
- /* 0x00: separator byte */
|
||||
- iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[2].data = make_data("", 1);
|
||||
- /* Context */
|
||||
- iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[3].data = *context;
|
||||
- /* [L]2: four-byte big-endian binary string giving the output length */
|
||||
- iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[4].data = make_data(lbuf, sizeof(lbuf));
|
||||
- store_32_be(outrnd->length * 8, lbuf);
|
||||
-
|
||||
- ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
|
||||
- if (!ret)
|
||||
- memcpy(outrnd->data, prf.data, outrnd->length);
|
||||
- zapfree(prf.data, prf.length);
|
||||
- return ret;
|
||||
+static krb5_error_code
|
||||
+derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+#ifdef HAVE_EVP_KDF_FETCH
|
||||
+ return openssl_krb5kdf(enc, inkey, outrnd, in_constant);
|
||||
+#else
|
||||
+ return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
||||
+#endif
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -268,8 +508,7 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
|
||||
case DERIVE_RFC3961:
|
||||
return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
||||
case DERIVE_SP800_108_CMAC:
|
||||
- return derive_random_sp800_108_feedback_cmac(enc, inkey, outrnd,
|
||||
- in_constant);
|
||||
+ return sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
case DERIVE_SP800_108_HMAC:
|
||||
return k5_sp800_108_counter_hmac(hash, inkey, outrnd, in_constant,
|
||||
&empty);
|
@ -1,408 +0,0 @@
|
||||
From 8bbb492f2be1418e1e4bb2cf197414810dac9589 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Fri, 20 Sep 2019 17:20:59 -0400
|
||||
Subject: [PATCH] Use OpenSSL's SSKDF in PKINIT when available
|
||||
|
||||
Starting in 3.0, OpenSSL implements SSKDF, which is the basis of our
|
||||
id-pkinit-kdf (RFC 8636). Factor out common setup code around
|
||||
other_info. Adjust code to comply to existing style.
|
||||
|
||||
(cherry picked from commit 4376a22e41fb639be31daf81275a332d3f930996)
|
||||
---
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 294 +++++++++++-------
|
||||
1 file changed, 181 insertions(+), 113 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index e1153344e..350c2118a 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -38,6 +38,12 @@
|
||||
#include <dirent.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
+#ifdef HAVE_EVP_KDF_FETCH
|
||||
+#include <openssl/core_names.h>
|
||||
+#include <openssl/kdf.h>
|
||||
+#include <openssl/params.h>
|
||||
+#endif
|
||||
+
|
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
||||
|
||||
@@ -2294,15 +2300,16 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
-/**
|
||||
+/*
|
||||
* Given an algorithm_identifier, this function returns the hash length
|
||||
* and EVP function associated with that algorithm.
|
||||
+ *
|
||||
+ * RFC 8636 defines a SHA384 variant, but we don't use it.
|
||||
*/
|
||||
static krb5_error_code
|
||||
-pkinit_alg_values(krb5_context context,
|
||||
- const krb5_data *alg_id,
|
||||
- size_t *hash_bytes,
|
||||
- const EVP_MD *(**func)(void))
|
||||
+pkinit_alg_values(krb5_context context, const krb5_data *alg_id,
|
||||
+ size_t *hash_bytes, const EVP_MD *(**func)(void),
|
||||
+ char **hash_name)
|
||||
{
|
||||
*hash_bytes = 0;
|
||||
*func = NULL;
|
||||
@@ -2311,18 +2318,21 @@ pkinit_alg_values(krb5_context context,
|
||||
krb5_pkinit_sha1_oid_len))) {
|
||||
*hash_bytes = 20;
|
||||
*func = &EVP_sha1;
|
||||
+ *hash_name = strdup("SHA1");
|
||||
return 0;
|
||||
} else if ((alg_id->length == krb5_pkinit_sha256_oid_len) &&
|
||||
(0 == memcmp(alg_id->data, krb5_pkinit_sha256_oid,
|
||||
krb5_pkinit_sha256_oid_len))) {
|
||||
*hash_bytes = 32;
|
||||
*func = &EVP_sha256;
|
||||
+ *hash_name = strdup("SHA256");
|
||||
return 0;
|
||||
} else if ((alg_id->length == krb5_pkinit_sha512_oid_len) &&
|
||||
(0 == memcmp(alg_id->data, krb5_pkinit_sha512_oid,
|
||||
krb5_pkinit_sha512_oid_len))) {
|
||||
*hash_bytes = 64;
|
||||
*func = &EVP_sha512;
|
||||
+ *hash_name = strdup("SHA512");
|
||||
return 0;
|
||||
} else {
|
||||
krb5_set_error_message(context, KRB5_ERR_BAD_S2K_PARAMS,
|
||||
@@ -2331,11 +2341,60 @@ pkinit_alg_values(krb5_context context,
|
||||
}
|
||||
} /* pkinit_alg_values() */
|
||||
|
||||
+#ifdef HAVE_EVP_KDF_FETCH
|
||||
+static krb5_error_code
|
||||
+openssl_sskdf(krb5_context context, size_t hash_bytes, krb5_data *key,
|
||||
+ krb5_data *info, char *out, size_t out_len, char *digest)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ EVP_KDF *kdf = NULL;
|
||||
+ EVP_KDF_CTX *kctx = NULL;
|
||||
+ OSSL_PARAM params[4];
|
||||
+ size_t i = 0;
|
||||
|
||||
-/* pkinit_alg_agility_kdf() --
|
||||
- * This function generates a key using the KDF described in
|
||||
- * draft_ietf_krb_wg_pkinit_alg_agility-04.txt. The algorithm is
|
||||
- * described as follows:
|
||||
+ if (digest == NULL) {
|
||||
+ ret = oerr(context, ENOMEM,
|
||||
+ _("Failed to allocate space for digest algorithm name"));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL);
|
||||
+ if (kdf == NULL) {
|
||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL, _("Failed to fetch SSKDF"));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ kctx = EVP_KDF_CTX_new(kdf);
|
||||
+ if (!kctx) {
|
||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL,
|
||||
+ _("Failed to instantiate SSKDF"));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ params[i++] = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST,
|
||||
+ digest, 0);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
|
||||
+ key->data, key->length);
|
||||
+ params[i++] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO,
|
||||
+ info->data, info->length);
|
||||
+ params[i] = OSSL_PARAM_construct_end();
|
||||
+ if (EVP_KDF_derive(kctx, (unsigned char *)out, out_len, params) <= 0) {
|
||||
+ ret = oerr(context, KRB5_CRYPTO_INTERNAL,
|
||||
+ _("Failed to derive key using SSKDF"));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ EVP_KDF_free(kdf);
|
||||
+ EVP_KDF_CTX_free(kctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+#else
|
||||
+/*
|
||||
+ * Generate a key using the KDF described in RFC 8636, also known as SSKDF
|
||||
+ * (single-step kdf). Our caller precomputes `reps`, but otherwise the
|
||||
+ * algorithm is as follows:
|
||||
*
|
||||
* 1. reps = keydatalen (K) / hash length (H)
|
||||
*
|
||||
@@ -2349,95 +2408,16 @@ pkinit_alg_values(krb5_context context,
|
||||
*
|
||||
* 4. Set key = Hash1 || Hash2 || ... so that length of key is K bytes.
|
||||
*/
|
||||
-krb5_error_code
|
||||
-pkinit_alg_agility_kdf(krb5_context context,
|
||||
- krb5_data *secret,
|
||||
- krb5_data *alg_oid,
|
||||
- krb5_const_principal party_u_info,
|
||||
- krb5_const_principal party_v_info,
|
||||
- krb5_enctype enctype,
|
||||
- krb5_data *as_req,
|
||||
- krb5_data *pk_as_rep,
|
||||
- krb5_keyblock *key_block)
|
||||
+static krb5_error_code
|
||||
+builtin_sskdf(krb5_context context, unsigned int reps, size_t hash_len,
|
||||
+ const EVP_MD *(*EVP_func)(void), krb5_data *secret,
|
||||
+ krb5_data *other_info, char *out, size_t out_len)
|
||||
{
|
||||
- krb5_error_code retval = 0;
|
||||
+ krb5_error_code ret = 0;
|
||||
|
||||
- unsigned int reps = 0;
|
||||
- uint32_t counter = 1; /* Does this type work on Windows? */
|
||||
+ uint32_t counter = 1;
|
||||
size_t offset = 0;
|
||||
- size_t hash_len = 0;
|
||||
- size_t rand_len = 0;
|
||||
- size_t key_len = 0;
|
||||
- krb5_data random_data;
|
||||
- krb5_sp80056a_other_info other_info_fields;
|
||||
- krb5_pkinit_supp_pub_info supp_pub_info_fields;
|
||||
- krb5_data *other_info = NULL;
|
||||
- krb5_data *supp_pub_info = NULL;
|
||||
- krb5_algorithm_identifier alg_id;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
- const EVP_MD *(*EVP_func)(void);
|
||||
-
|
||||
- /* initialize random_data here to make clean-up safe */
|
||||
- random_data.length = 0;
|
||||
- random_data.data = NULL;
|
||||
-
|
||||
- /* allocate and initialize the key block */
|
||||
- key_block->magic = 0;
|
||||
- key_block->enctype = enctype;
|
||||
- if (0 != (retval = krb5_c_keylengths(context, enctype, &rand_len,
|
||||
- &key_len)))
|
||||
- goto cleanup;
|
||||
-
|
||||
- random_data.length = rand_len;
|
||||
- key_block->length = key_len;
|
||||
-
|
||||
- if (NULL == (key_block->contents = malloc(key_block->length))) {
|
||||
- retval = ENOMEM;
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
- memset (key_block->contents, 0, key_block->length);
|
||||
-
|
||||
- /* If this is anonymous pkinit, use the anonymous principle for party_u_info */
|
||||
- if (party_u_info && krb5_principal_compare_any_realm(context, party_u_info,
|
||||
- krb5_anonymous_principal()))
|
||||
- party_u_info = (krb5_principal)krb5_anonymous_principal();
|
||||
-
|
||||
- if (0 != (retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func)))
|
||||
- goto cleanup;
|
||||
-
|
||||
- /* 1. reps = keydatalen (K) / hash length (H) */
|
||||
- reps = key_block->length/hash_len;
|
||||
-
|
||||
- /* ... and round up, if necessary */
|
||||
- if (key_block->length > (reps * hash_len))
|
||||
- reps++;
|
||||
-
|
||||
- /* Allocate enough space in the random data buffer to hash directly into
|
||||
- * it, even if the last hash will make it bigger than the key length. */
|
||||
- if (NULL == (random_data.data = malloc(reps * hash_len))) {
|
||||
- retval = ENOMEM;
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
- /* Encode the ASN.1 octet string for "SuppPubInfo" */
|
||||
- supp_pub_info_fields.enctype = enctype;
|
||||
- supp_pub_info_fields.as_req = *as_req;
|
||||
- supp_pub_info_fields.pk_as_rep = *pk_as_rep;
|
||||
- if (0 != ((retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
|
||||
- &supp_pub_info))))
|
||||
- goto cleanup;
|
||||
-
|
||||
- /* Now encode the ASN.1 octet string for "OtherInfo" */
|
||||
- memset(&alg_id, 0, sizeof alg_id);
|
||||
- alg_id.algorithm = *alg_oid; /*alias*/
|
||||
-
|
||||
- other_info_fields.algorithm_identifier = alg_id;
|
||||
- other_info_fields.party_u_info = (krb5_principal) party_u_info;
|
||||
- other_info_fields.party_v_info = (krb5_principal) party_v_info;
|
||||
- other_info_fields.supp_pub_info = *supp_pub_info;
|
||||
- if (0 != (retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info)))
|
||||
- goto cleanup;
|
||||
|
||||
/* 2. Initialize a 32-bit, big-endian bit string counter as 1.
|
||||
* 3. For i = 1 to reps by 1, do the following:
|
||||
@@ -2450,7 +2430,7 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
|
||||
ctx = EVP_MD_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
- retval = KRB5_CRYPTO_INTERNAL;
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -2458,7 +2438,7 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
if (!EVP_DigestInit(ctx, EVP_func())) {
|
||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
|
||||
"Call to OpenSSL EVP_DigestInit() returned an error.");
|
||||
- retval = KRB5_CRYPTO_INTERNAL;
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -2467,15 +2447,16 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
!EVP_DigestUpdate(ctx, other_info->data, other_info->length)) {
|
||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
|
||||
"Call to OpenSSL EVP_DigestUpdate() returned an error.");
|
||||
- retval = KRB5_CRYPTO_INTERNAL;
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* 4. Set key = Hash1 || Hash2 || ... so that length of key is K bytes. */
|
||||
- if (!EVP_DigestFinal(ctx, (uint8_t *)random_data.data + offset, &s)) {
|
||||
+ /* 4. Set key = Hash1 || Hash2 || ... so that length of key is K
|
||||
+ * bytes. */
|
||||
+ if (!EVP_DigestFinal(ctx, (unsigned char *)out + offset, &s)) {
|
||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
|
||||
"Call to OpenSSL EVP_DigestUpdate() returned an error.");
|
||||
- retval = KRB5_CRYPTO_INTERNAL;
|
||||
+ ret = KRB5_CRYPTO_INTERNAL;
|
||||
goto cleanup;
|
||||
}
|
||||
offset += s;
|
||||
@@ -2484,26 +2465,113 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
EVP_MD_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
-
|
||||
- retval = krb5_c_random_to_key(context, enctype, &random_data,
|
||||
- key_block);
|
||||
-
|
||||
cleanup:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+} /* builtin_sskdf() */
|
||||
+#endif /* HAVE_EVP_KDF_FETCH */
|
||||
|
||||
- /* If this has been an error, free the allocated key_block, if any */
|
||||
- if (retval) {
|
||||
- krb5_free_keyblock_contents(context, key_block);
|
||||
+/* id-pkinit-kdf family, as specified by RFC 8636. */
|
||||
+krb5_error_code
|
||||
+pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
|
||||
+ krb5_data *alg_oid, krb5_const_principal party_u_info,
|
||||
+ krb5_const_principal party_v_info,
|
||||
+ krb5_enctype enctype, krb5_data *as_req,
|
||||
+ krb5_data *pk_as_rep, krb5_keyblock *key_block)
|
||||
+{
|
||||
+ krb5_error_code ret;
|
||||
+ size_t hash_len = 0, rand_len = 0, key_len = 0;
|
||||
+ const EVP_MD *(*EVP_func)(void);
|
||||
+ krb5_sp80056a_other_info other_info_fields;
|
||||
+ krb5_pkinit_supp_pub_info supp_pub_info_fields;
|
||||
+ krb5_data *other_info = NULL, *supp_pub_info = NULL;
|
||||
+ krb5_data random_data = empty_data();
|
||||
+ krb5_algorithm_identifier alg_id;
|
||||
+ unsigned int reps;
|
||||
+ char *hash_name = NULL;
|
||||
+
|
||||
+ /* Allocate and initialize the key block. */
|
||||
+ key_block->magic = 0;
|
||||
+ key_block->enctype = enctype;
|
||||
+
|
||||
+ /* Use separate variables to avoid alignment restriction problems. */
|
||||
+ ret = krb5_c_keylengths(context, enctype, &rand_len, &key_len);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+ random_data.length = rand_len;
|
||||
+ key_block->length = key_len;
|
||||
+
|
||||
+ key_block->contents = k5calloc(key_block->length, 1, &ret);
|
||||
+ if (key_block->contents == NULL)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* If this is anonymous pkinit, use the anonymous principle for
|
||||
+ * party_u_info. */
|
||||
+ if (party_u_info &&
|
||||
+ krb5_principal_compare_any_realm(context, party_u_info,
|
||||
+ krb5_anonymous_principal())) {
|
||||
+ party_u_info = (krb5_principal)krb5_anonymous_principal();
|
||||
}
|
||||
|
||||
- /* free other allocated resources, either way */
|
||||
- if (random_data.data)
|
||||
- free(random_data.data);
|
||||
+ ret = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func,
|
||||
+ &hash_name);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* 1. reps = keydatalen (K) / hash length (H) */
|
||||
+ reps = key_block->length / hash_len;
|
||||
+
|
||||
+ /* ... and round up, if necessary. */
|
||||
+ if (key_block->length > (reps * hash_len))
|
||||
+ reps++;
|
||||
+
|
||||
+ /* Allocate enough space in the random data buffer to hash directly into
|
||||
+ * it, even if the last hash will make it bigger than the key length. */
|
||||
+ random_data.data = k5alloc(reps * hash_len, &ret);
|
||||
+ if (random_data.data == NULL)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Encode the ASN.1 octet string for "SuppPubInfo". */
|
||||
+ supp_pub_info_fields.enctype = enctype;
|
||||
+ supp_pub_info_fields.as_req = *as_req;
|
||||
+ supp_pub_info_fields.pk_as_rep = *pk_as_rep;
|
||||
+ ret = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
|
||||
+ &supp_pub_info);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Now encode the ASN.1 octet string for "OtherInfo". */
|
||||
+ memset(&alg_id, 0, sizeof(alg_id));
|
||||
+ alg_id.algorithm = *alg_oid;
|
||||
+ other_info_fields.algorithm_identifier = alg_id;
|
||||
+ other_info_fields.party_u_info = (krb5_principal)party_u_info;
|
||||
+ other_info_fields.party_v_info = (krb5_principal)party_v_info;
|
||||
+ other_info_fields.supp_pub_info = *supp_pub_info;
|
||||
+ ret = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+#ifdef HAVE_EVP_KDF_FETCH
|
||||
+ ret = openssl_sskdf(context, hash_len, secret, other_info,
|
||||
+ random_data.data, key_block->length, hash_name);
|
||||
+#else
|
||||
+ ret = builtin_sskdf(context, reps, hash_len, EVP_func, secret,
|
||||
+ other_info, random_data.data, key_block->length);
|
||||
+#endif
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ ret = krb5_c_random_to_key(context, enctype, &random_data, key_block);
|
||||
+cleanup:
|
||||
+ if (ret)
|
||||
+ krb5_free_keyblock_contents(context, key_block);
|
||||
+
|
||||
+ free(hash_name);
|
||||
+ zapfree(random_data.data, random_data.length);
|
||||
krb5_free_data(context, other_info);
|
||||
krb5_free_data(context, supp_pub_info);
|
||||
-
|
||||
- return retval;
|
||||
-} /*pkinit_alg_agility_kdf() */
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
/* Call DH_compute_key() and ensure that we left-pad short results instead of
|
||||
* leaving junk bytes at the end of the buffer. */
|
@ -1,113 +0,0 @@
|
||||
From 538be893707e2306e89f5e5ca92c0db0ee305e3e Mon Sep 17 00:00:00 2001
|
||||
From: Julien Rische <jrische@redhat.com>
|
||||
Date: Fri, 11 Mar 2022 11:33:56 +0100
|
||||
Subject: [PATCH] Use SHA-256 instead of SHA-1 for PKINIT CMS digest
|
||||
|
||||
Various organizations including NIST have been strongly recommending to
|
||||
stop using SHA-1 for digital signatures for some years already. CMS
|
||||
digest is used to generate such signatures, hence it should be upgraded
|
||||
to use SHA-256.
|
||||
---
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 27 ++++++++++---------
|
||||
1 file changed, 14 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
index 42e5c581d..2a6ef4aaa 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -1240,7 +1240,7 @@ cms_signeddata_create(krb5_context context,
|
||||
/* will not fill-out EVP_PKEY because it's on the smartcard */
|
||||
|
||||
/* Set digest algs */
|
||||
- p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
|
||||
+ p7si->digest_alg->algorithm = OBJ_nid2obj(NID_sha256);
|
||||
|
||||
if (p7si->digest_alg->parameter != NULL)
|
||||
ASN1_TYPE_free(p7si->digest_alg->parameter);
|
||||
@@ -1251,17 +1251,17 @@ cms_signeddata_create(krb5_context context,
|
||||
/* Set sig algs */
|
||||
if (p7si->digest_enc_alg->parameter != NULL)
|
||||
ASN1_TYPE_free(p7si->digest_enc_alg->parameter);
|
||||
- p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha1WithRSAEncryption);
|
||||
+ p7si->digest_enc_alg->algorithm = OBJ_nid2obj(NID_sha256WithRSAEncryption);
|
||||
if (!(p7si->digest_enc_alg->parameter = ASN1_TYPE_new()))
|
||||
goto cleanup;
|
||||
p7si->digest_enc_alg->parameter->type = V_ASN1_NULL;
|
||||
|
||||
/* add signed attributes */
|
||||
- /* compute sha1 digest over the EncapsulatedContentInfo */
|
||||
+ /* compute sha256 digest over the EncapsulatedContentInfo */
|
||||
ctx = EVP_MD_CTX_new();
|
||||
if (ctx == NULL)
|
||||
goto cleanup;
|
||||
- EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
|
||||
+ EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
|
||||
EVP_DigestUpdate(ctx, data, data_len);
|
||||
md_tmp = EVP_MD_CTX_md(ctx);
|
||||
EVP_DigestFinal_ex(ctx, md_data, &md_len);
|
||||
@@ -1289,9 +1289,10 @@ cms_signeddata_create(krb5_context context,
|
||||
goto cleanup2;
|
||||
|
||||
#ifndef WITHOUT_PKCS11
|
||||
- /* Some tokens can only do RSAEncryption without sha1 hash */
|
||||
- /* to compute sha1WithRSAEncryption, encode the algorithm ID for the hash
|
||||
- * function and the hash value into an ASN.1 value of type DigestInfo
|
||||
+ /* Some tokens can only do RSAEncryption without sha256 hash */
|
||||
+ /* to compute sha256WithRSAEncryption, encode the algorithm ID for the
|
||||
+ * hash function and the hash value into an ASN.1 value of type
|
||||
+ * DigestInfo
|
||||
* DigestInfo::=SEQUENCE {
|
||||
* digestAlgorithm AlgorithmIdentifier,
|
||||
* digest OCTET STRING }
|
||||
@@ -1310,7 +1311,7 @@ cms_signeddata_create(krb5_context context,
|
||||
alg = X509_ALGOR_new();
|
||||
if (alg == NULL)
|
||||
goto cleanup2;
|
||||
- X509_ALGOR_set0(alg, OBJ_nid2obj(NID_sha1), V_ASN1_NULL, NULL);
|
||||
+ X509_ALGOR_set0(alg, OBJ_nid2obj(NID_sha256), V_ASN1_NULL, NULL);
|
||||
alg_len = i2d_X509_ALGOR(alg, NULL);
|
||||
|
||||
digest = ASN1_OCTET_STRING_new();
|
||||
@@ -1339,7 +1340,7 @@ cms_signeddata_create(krb5_context context,
|
||||
#endif
|
||||
{
|
||||
pkiDebug("mech = %s\n",
|
||||
- id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA1_RSA_PKCS" : "FS");
|
||||
+ id_cryptoctx->pkcs11_method == 1 ? "CKM_SHA256_RSA_PKCS" : "FS");
|
||||
retval = pkinit_sign_data(context, id_cryptoctx, abuf, alen,
|
||||
&sig, &sig_len);
|
||||
}
|
||||
@@ -4189,7 +4190,7 @@ create_signature(unsigned char **sig, unsigned int *sig_len,
|
||||
ctx = EVP_MD_CTX_new();
|
||||
if (ctx == NULL)
|
||||
return ENOMEM;
|
||||
- EVP_SignInit(ctx, EVP_sha1());
|
||||
+ EVP_SignInit(ctx, EVP_sha256());
|
||||
EVP_SignUpdate(ctx, data, data_len);
|
||||
*sig_len = EVP_PKEY_size(pkey);
|
||||
if ((*sig = malloc(*sig_len)) == NULL)
|
||||
@@ -4663,10 +4664,10 @@ pkinit_get_certs_pkcs11(krb5_context context,
|
||||
|
||||
#ifndef PKINIT_USE_MECH_LIST
|
||||
/*
|
||||
- * We'd like to use CKM_SHA1_RSA_PKCS for signing if it's available, but
|
||||
+ * We'd like to use CKM_SHA256_RSA_PKCS for signing if it's available, but
|
||||
* many cards seems to be confused about whether they are capable of
|
||||
* this or not. The safe thing seems to be to ignore the mechanism list,
|
||||
- * always use CKM_RSA_PKCS and calculate the sha1 digest ourselves.
|
||||
+ * always use CKM_RSA_PKCS and calculate the sha256 digest ourselves.
|
||||
*/
|
||||
|
||||
id_cryptoctx->mech = CKM_RSA_PKCS;
|
||||
@@ -4694,7 +4695,7 @@ pkinit_get_certs_pkcs11(krb5_context context,
|
||||
if (mechp[i] == CKM_RSA_PKCS) {
|
||||
/* This seems backwards... */
|
||||
id_cryptoctx->mech =
|
||||
- (info.flags & CKF_SIGN) ? CKM_SHA1_RSA_PKCS : CKM_RSA_PKCS;
|
||||
+ (info.flags & CKF_SIGN) ? CKM_SHA256_RSA_PKCS : CKM_RSA_PKCS;
|
||||
}
|
||||
}
|
||||
free(mechp);
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,22 +0,0 @@
|
||||
From 37e1fe755c6e976253a7f40ec7a9e740e4329789 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Mon, 21 Jun 2021 19:15:26 -0400
|
||||
Subject: [PATCH] Use asan in one of the CI builds
|
||||
|
||||
(cherry picked from commit 7368354bcd0b58480a88b1fb81e63bd6aae7edf2)
|
||||
---
|
||||
.github/workflows/build.yml | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
|
||||
index 8d1042b7b..06a35b7b9 100644
|
||||
--- a/.github/workflows/build.yml
|
||||
+++ b/.github/workflows/build.yml
|
||||
@@ -17,6 +17,7 @@ jobs:
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
||||
makevars: CPPFLAGS=-Werror
|
||||
+ configureopts: --enable-asan
|
||||
- name: linux-clang-openssl
|
||||
os: ubuntu-18.04
|
||||
compiler: clang
|
@ -1,752 +0,0 @@
|
||||
From 86d606e33439fd0511c5154be7f32b0df2c72e54 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
|
||||
interface
|
||||
|
||||
Last-updated: krb5-1.17
|
||||
---
|
||||
src/configure.ac | 4 +
|
||||
src/lib/crypto/krb/derive.c | 356 +++++++++++++-----
|
||||
.../preauth/pkinit/pkinit_crypto_openssl.c | 257 ++++++++-----
|
||||
3 files changed, 428 insertions(+), 189 deletions(-)
|
||||
|
||||
diff --git a/src/configure.ac b/src/configure.ac
|
||||
index 3e1052db7..ea708491b 100644
|
||||
--- a/src/configure.ac
|
||||
+++ b/src/configure.ac
|
||||
@@ -282,6 +282,10 @@ AC_SUBST(CRYPTO_IMPL)
|
||||
AC_SUBST(CRYPTO_IMPL_CFLAGS)
|
||||
AC_SUBST(CRYPTO_IMPL_LIBS)
|
||||
|
||||
+AC_CHECK_FUNCS(EVP_KDF_CTX_new_id EVP_KDF_ctrl EVP_KDF_derive,
|
||||
+ AC_DEFINE(OSSL_KDFS, 1, [Define if using OpenSSL KDFs]),
|
||||
+ AC_MSG_ERROR([backported OpenSSL KDFs not found]))
|
||||
+
|
||||
AC_ARG_WITH([prng-alg],
|
||||
AC_HELP_STRING([--with-prng-alg=ALG], [use specified PRNG algorithm. @<:@fortuna@:>@]),
|
||||
[PRNG_ALG=$withval
|
||||
diff --git a/src/lib/crypto/krb/derive.c b/src/lib/crypto/krb/derive.c
|
||||
index 6707a7308..915a173dd 100644
|
||||
--- a/src/lib/crypto/krb/derive.c
|
||||
+++ b/src/lib/crypto/krb/derive.c
|
||||
@@ -27,6 +27,13 @@
|
||||
|
||||
#include "crypto_int.h"
|
||||
|
||||
+#ifdef OSSL_KDFS
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/kdf.h>
|
||||
+#else
|
||||
+#error "Refusing to build without OpenSSL KDFs!"
|
||||
+#endif
|
||||
+
|
||||
static krb5_key
|
||||
find_cached_dkey(struct derived_key *list, const krb5_data *constant)
|
||||
{
|
||||
@@ -77,55 +84,193 @@ cleanup:
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
+#ifdef OSSL_KDFS
|
||||
static krb5_error_code
|
||||
-derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
- krb5_key inkey, krb5_data *outrnd,
|
||||
- const krb5_data *in_constant)
|
||||
+openssl_kbdkf_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *label, const krb5_data *context)
|
||||
{
|
||||
- size_t blocksize, keybytes, n;
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ const EVP_MD *digest;
|
||||
+
|
||||
+ if (!strcmp(hash->hash_name, "SHA1"))
|
||||
+ digest = EVP_sha1();
|
||||
+ else if (!strcmp(hash->hash_name, "SHA-256"))
|
||||
+ digest = EVP_sha256();
|
||||
+ else if (!strcmp(hash->hash_name, "SHA-384"))
|
||||
+ digest = EVP_sha384();
|
||||
+ else
|
||||
+ goto done;
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KB);
|
||||
+ if (!ctx)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MAC_TYPE,
|
||||
+ EVP_KDF_KB_MAC_TYPE_HMAC) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length) != 1 ||
|
||||
+ (context->length > 0 &&
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_INFO, context->data,
|
||||
+ context->length) != 1) ||
|
||||
+ (label->length > 0 &&
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SALT, label->data,
|
||||
+ label->length) != 1) ||
|
||||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
|
||||
+ outrnd->length) != 1)
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static krb5_error_code
|
||||
+openssl_kbkdf_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ const EVP_CIPHER *cipher;
|
||||
+ static unsigned char zeroes[16];
|
||||
+
|
||||
+ memset(zeroes, 0, sizeof(zeroes));
|
||||
+
|
||||
+ if (enc->keylength == 16)
|
||||
+ cipher = EVP_camellia_128_cbc();
|
||||
+ else if (enc->keylength == 32)
|
||||
+ cipher = EVP_camellia_256_cbc();
|
||||
+ else
|
||||
+ goto done;
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KB);
|
||||
+ if (!ctx)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MODE,
|
||||
+ EVP_KDF_KB_MODE_FEEDBACK) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_MAC_TYPE,
|
||||
+ EVP_KDF_KB_MAC_TYPE_CMAC) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_CIPHER, cipher) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SALT, in_constant->data,
|
||||
+ in_constant->length) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KB_SEED, zeroes,
|
||||
+ sizeof(zeroes)) != 1 ||
|
||||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
|
||||
+ outrnd->length) != 1)
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static krb5_error_code
|
||||
+openssl_krb5kdf(const struct krb5_enc_provider *enc, krb5_key inkey,
|
||||
+ krb5_data *outrnd, const krb5_data *in_constant)
|
||||
+{
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ const EVP_CIPHER *cipher;
|
||||
+
|
||||
+ if (inkey->keyblock.length != enc->keylength ||
|
||||
+ outrnd->length != enc->keybytes) {
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+ }
|
||||
+
|
||||
+ if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 16)
|
||||
+ cipher = EVP_aes_128_cbc();
|
||||
+ else if (enc->encrypt == krb5int_aes_encrypt && enc->keylength == 32)
|
||||
+ cipher = EVP_aes_256_cbc();
|
||||
+ else if (enc->keylength == 24)
|
||||
+ cipher = EVP_des_ede3_cbc();
|
||||
+ else
|
||||
+ goto done;
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_KRB5KDF);
|
||||
+ if (ctx == NULL)
|
||||
+ goto done;
|
||||
+
|
||||
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_CIPHER, cipher) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, inkey->keyblock.contents,
|
||||
+ inkey->keyblock.length) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KRB5KDF_CONSTANT,
|
||||
+ in_constant->data, in_constant->length) != 1 ||
|
||||
+ EVP_KDF_derive(ctx, (unsigned char *)outrnd->data,
|
||||
+ outrnd->length) != 1)
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret)
|
||||
+ zap(outrnd->data, outrnd->length);
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#else /* OSSL_KDFS */
|
||||
+
|
||||
+/*
|
||||
+ * NIST SP800-108 KDF in counter mode (section 5.1).
|
||||
+ * Parameters:
|
||||
+ * - HMAC (with hash as the hash provider) is the PRF.
|
||||
+ * - A block counter of four bytes is used.
|
||||
+ * - Four bytes are used to encode the output length in the PRF input.
|
||||
+ *
|
||||
+ * There are no uses requiring more than a single PRF invocation.
|
||||
+ */
|
||||
+static krb5_error_code
|
||||
+builtin_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *label,
|
||||
+ const krb5_data *context)
|
||||
+{
|
||||
+ krb5_crypto_iov iov[5];
|
||||
krb5_error_code ret;
|
||||
- krb5_data block = empty_data();
|
||||
+ krb5_data prf;
|
||||
+ unsigned char ibuf[4], lbuf[4];
|
||||
|
||||
- blocksize = enc->block_size;
|
||||
- keybytes = enc->keybytes;
|
||||
-
|
||||
- if (blocksize == 1)
|
||||
- return KRB5_BAD_ENCTYPE;
|
||||
- if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
|
||||
+ if (hash == NULL || outrnd->length > hash->hashsize)
|
||||
return KRB5_CRYPTO_INTERNAL;
|
||||
|
||||
/* Allocate encryption data buffer. */
|
||||
- ret = alloc_data(&block, blocksize);
|
||||
+ ret = alloc_data(&prf, hash->hashsize);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- /* Initialize the input block. */
|
||||
- if (in_constant->length == blocksize) {
|
||||
- memcpy(block.data, in_constant->data, blocksize);
|
||||
- } else {
|
||||
- krb5int_nfold(in_constant->length * 8,
|
||||
- (unsigned char *) in_constant->data,
|
||||
- blocksize * 8, (unsigned char *) block.data);
|
||||
- }
|
||||
+ /* [i]2: four-byte big-endian binary string giving the block counter (1) */
|
||||
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[0].data = make_data(ibuf, sizeof(ibuf));
|
||||
+ store_32_be(1, ibuf);
|
||||
+ /* Label */
|
||||
+ iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[1].data = *label;
|
||||
+ /* 0x00: separator byte */
|
||||
+ iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[2].data = make_data("", 1);
|
||||
+ /* Context */
|
||||
+ iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[3].data = *context;
|
||||
+ /* [L]2: four-byte big-endian binary string giving the output length */
|
||||
+ iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
+ iov[4].data = make_data(lbuf, sizeof(lbuf));
|
||||
+ store_32_be(outrnd->length * 8, lbuf);
|
||||
|
||||
- /* Loop encrypting the blocks until enough key bytes are generated. */
|
||||
- n = 0;
|
||||
- while (n < keybytes) {
|
||||
- ret = encrypt_block(enc, inkey, &block);
|
||||
- if (ret)
|
||||
- goto cleanup;
|
||||
-
|
||||
- if ((keybytes - n) <= blocksize) {
|
||||
- memcpy(outrnd->data + n, block.data, (keybytes - n));
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- memcpy(outrnd->data + n, block.data, blocksize);
|
||||
- n += blocksize;
|
||||
- }
|
||||
-
|
||||
-cleanup:
|
||||
- zapfree(block.data, blocksize);
|
||||
+ ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
|
||||
+ if (!ret)
|
||||
+ memcpy(outrnd->data, prf.data, outrnd->length);
|
||||
+ zapfree(prf.data, prf.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -139,9 +284,9 @@ cleanup:
|
||||
* - Four bytes are used to encode the output length in the PRF input.
|
||||
*/
|
||||
static krb5_error_code
|
||||
-derive_random_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
- krb5_key inkey, krb5_data *outrnd,
|
||||
- const krb5_data *in_constant)
|
||||
+builtin_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
{
|
||||
size_t blocksize, keybytes, n;
|
||||
krb5_crypto_iov iov[6];
|
||||
@@ -204,56 +349,94 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * NIST SP800-108 KDF in counter mode (section 5.1).
|
||||
- * Parameters:
|
||||
- * - HMAC (with hash as the hash provider) is the PRF.
|
||||
- * - A block counter of four bytes is used.
|
||||
- * - Four bytes are used to encode the output length in the PRF input.
|
||||
- *
|
||||
- * There are no uses requiring more than a single PRF invocation.
|
||||
- */
|
||||
+static krb5_error_code
|
||||
+builtin_derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+ size_t blocksize, keybytes, n;
|
||||
+ krb5_error_code ret;
|
||||
+ krb5_data block = empty_data();
|
||||
+
|
||||
+ blocksize = enc->block_size;
|
||||
+ keybytes = enc->keybytes;
|
||||
+
|
||||
+ if (blocksize == 1)
|
||||
+ return KRB5_BAD_ENCTYPE;
|
||||
+ if (inkey->keyblock.length != enc->keylength || outrnd->length != keybytes)
|
||||
+ return KRB5_CRYPTO_INTERNAL;
|
||||
+
|
||||
+ /* Allocate encryption data buffer. */
|
||||
+ ret = alloc_data(&block, blocksize);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Initialize the input block. */
|
||||
+ if (in_constant->length == blocksize) {
|
||||
+ memcpy(block.data, in_constant->data, blocksize);
|
||||
+ } else {
|
||||
+ krb5int_nfold(in_constant->length * 8,
|
||||
+ (unsigned char *) in_constant->data,
|
||||
+ blocksize * 8, (unsigned char *) block.data);
|
||||
+ }
|
||||
+
|
||||
+ /* Loop encrypting the blocks until enough key bytes are generated. */
|
||||
+ n = 0;
|
||||
+ while (n < keybytes) {
|
||||
+ ret = encrypt_block(enc, inkey, &block);
|
||||
+ if (ret)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if ((keybytes - n) <= blocksize) {
|
||||
+ memcpy(outrnd->data + n, block.data, (keybytes - n));
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(outrnd->data + n, block.data, blocksize);
|
||||
+ n += blocksize;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ zapfree(block.data, blocksize);
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif /* OSSL_KDFS */
|
||||
+
|
||||
krb5_error_code
|
||||
k5_sp800_108_counter_hmac(const struct krb5_hash_provider *hash,
|
||||
krb5_key inkey, krb5_data *outrnd,
|
||||
const krb5_data *label, const krb5_data *context)
|
||||
{
|
||||
- krb5_crypto_iov iov[5];
|
||||
- krb5_error_code ret;
|
||||
- krb5_data prf;
|
||||
- unsigned char ibuf[4], lbuf[4];
|
||||
+#ifdef OSSL_KDFS
|
||||
+ return openssl_kbdkf_counter_hmac(hash, inkey, outrnd, label, context);
|
||||
+#else
|
||||
+ return builtin_sp800_108_counter_hmac(hash, inkey, outrnd, label,
|
||||
+ context);
|
||||
+#endif
|
||||
+}
|
||||
|
||||
- if (hash == NULL || outrnd->length > hash->hashsize)
|
||||
- return KRB5_CRYPTO_INTERNAL;
|
||||
+static krb5_error_code
|
||||
+k5_sp800_108_feedback_cmac(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+#ifdef OSSL_KDFS
|
||||
+ return openssl_kbkdf_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
+#else
|
||||
+ return builtin_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
+#endif
|
||||
+}
|
||||
|
||||
- /* Allocate encryption data buffer. */
|
||||
- ret = alloc_data(&prf, hash->hashsize);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- /* [i]2: four-byte big-endian binary string giving the block counter (1) */
|
||||
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[0].data = make_data(ibuf, sizeof(ibuf));
|
||||
- store_32_be(1, ibuf);
|
||||
- /* Label */
|
||||
- iov[1].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[1].data = *label;
|
||||
- /* 0x00: separator byte */
|
||||
- iov[2].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[2].data = make_data("", 1);
|
||||
- /* Context */
|
||||
- iov[3].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[3].data = *context;
|
||||
- /* [L]2: four-byte big-endian binary string giving the output length */
|
||||
- iov[4].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||
- iov[4].data = make_data(lbuf, sizeof(lbuf));
|
||||
- store_32_be(outrnd->length * 8, lbuf);
|
||||
-
|
||||
- ret = krb5int_hmac(hash, inkey, iov, 5, &prf);
|
||||
- if (!ret)
|
||||
- memcpy(outrnd->data, prf.data, outrnd->length);
|
||||
- zapfree(prf.data, prf.length);
|
||||
- return ret;
|
||||
+static krb5_error_code
|
||||
+k5_derive_random_rfc3961(const struct krb5_enc_provider *enc,
|
||||
+ krb5_key inkey, krb5_data *outrnd,
|
||||
+ const krb5_data *in_constant)
|
||||
+{
|
||||
+#ifdef OSSL_KDFS
|
||||
+ return openssl_krb5kdf(enc, inkey, outrnd, in_constant);
|
||||
+#else
|
||||
+ return builtin_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
||||
+#endif
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -266,10 +449,9 @@ krb5int_derive_random(const struct krb5_enc_provider *enc,
|
||||
|
||||
switch (alg) {
|
||||
case DERIVE_RFC3961:
|
||||
- return derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
||||
+ return k5_derive_random_rfc3961(enc, inkey, outrnd, in_constant);
|
||||
case DERIVE_SP800_108_CMAC:
|
||||
- return derive_random_sp800_108_feedback_cmac(enc, inkey, outrnd,
|
||||
- in_constant);
|
||||
+ return k5_sp800_108_feedback_cmac(enc, inkey, outrnd, in_constant);
|
||||
case DERIVE_SP800_108_HMAC:
|
||||
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 e1153344e..911e74fd9 100644
|
||||
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||
@@ -38,6 +38,13 @@
|
||||
#include <dirent.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
+#ifdef OSSL_KDFS
|
||||
+#include <openssl/evp.h>
|
||||
+#include <openssl/kdf.h>
|
||||
+#else
|
||||
+#error "Refusing to build without OpenSSL KDFs!"
|
||||
+#endif
|
||||
+
|
||||
static krb5_error_code pkinit_init_pkinit_oids(pkinit_plg_crypto_context );
|
||||
static void pkinit_fini_pkinit_oids(pkinit_plg_crypto_context );
|
||||
|
||||
@@ -2331,11 +2338,51 @@ pkinit_alg_values(krb5_context context,
|
||||
}
|
||||
} /* pkinit_alg_values() */
|
||||
|
||||
+#ifdef OSSL_KDFS
|
||||
+static krb5_error_code
|
||||
+openssl_sskdf(krb5_context context, size_t hash_bytes, krb5_data *key,
|
||||
+ krb5_data *info, char *out, size_t out_len)
|
||||
+{
|
||||
+ krb5_error_code ret = KRB5_CRYPTO_INTERNAL;
|
||||
+ EVP_KDF_CTX *ctx = NULL;
|
||||
+ const EVP_MD *digest;
|
||||
|
||||
-/* pkinit_alg_agility_kdf() --
|
||||
- * This function generates a key using the KDF described in
|
||||
- * draft_ietf_krb_wg_pkinit_alg_agility-04.txt. The algorithm is
|
||||
- * described as follows:
|
||||
+ /* RFC 8636 defines a SHA384 variant, but we don't use it. */
|
||||
+ if (hash_bytes == 20) {
|
||||
+ digest = EVP_sha1();
|
||||
+ } else if (hash_bytes == 32) {
|
||||
+ digest = EVP_sha256();
|
||||
+ } else if (hash_bytes == 64) {
|
||||
+ digest = EVP_sha512();
|
||||
+ } else {
|
||||
+ krb5_set_error_message(context, ret, "Bad hash type for SSKDF");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ctx = EVP_KDF_CTX_new_id(EVP_KDF_SS);
|
||||
+ if (!ctx) {
|
||||
+ oerr(context, ret, _("Failed to instantiate SSKDF"));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD, digest) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key->data,
|
||||
+ key->length) != 1 ||
|
||||
+ EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSKDF_INFO, info->data,
|
||||
+ info->length) != 1 ||
|
||||
+ EVP_KDF_derive(ctx, (unsigned char *)out, out_len) != 1)
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ EVP_KDF_CTX_free(ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+#else
|
||||
+/*
|
||||
+ * Generate a key using the KDF described in RFC 8636, also known as SSKDF
|
||||
+ * (single-step kdf). Our caller precomputes `reps`, but otherwise the
|
||||
+ * algorithm is as follows:
|
||||
*
|
||||
* 1. reps = keydatalen (K) / hash length (H)
|
||||
*
|
||||
@@ -2349,95 +2396,16 @@ pkinit_alg_values(krb5_context context,
|
||||
*
|
||||
* 4. Set key = Hash1 || Hash2 || ... so that length of key is K bytes.
|
||||
*/
|
||||
-krb5_error_code
|
||||
-pkinit_alg_agility_kdf(krb5_context context,
|
||||
- krb5_data *secret,
|
||||
- krb5_data *alg_oid,
|
||||
- krb5_const_principal party_u_info,
|
||||
- krb5_const_principal party_v_info,
|
||||
- krb5_enctype enctype,
|
||||
- krb5_data *as_req,
|
||||
- krb5_data *pk_as_rep,
|
||||
- krb5_keyblock *key_block)
|
||||
+static krb5_error_code
|
||||
+builtin_sskdf(krb5_context context, unsigned int reps, size_t hash_len,
|
||||
+ const EVP_MD *(*EVP_func)(void), krb5_data *secret,
|
||||
+ krb5_data *other_info, char *out, size_t out_len)
|
||||
{
|
||||
krb5_error_code retval = 0;
|
||||
|
||||
- unsigned int reps = 0;
|
||||
- uint32_t counter = 1; /* Does this type work on Windows? */
|
||||
+ uint32_t counter = 1;
|
||||
size_t offset = 0;
|
||||
- size_t hash_len = 0;
|
||||
- size_t rand_len = 0;
|
||||
- size_t key_len = 0;
|
||||
- krb5_data random_data;
|
||||
- krb5_sp80056a_other_info other_info_fields;
|
||||
- krb5_pkinit_supp_pub_info supp_pub_info_fields;
|
||||
- krb5_data *other_info = NULL;
|
||||
- krb5_data *supp_pub_info = NULL;
|
||||
- krb5_algorithm_identifier alg_id;
|
||||
EVP_MD_CTX *ctx = NULL;
|
||||
- const EVP_MD *(*EVP_func)(void);
|
||||
-
|
||||
- /* initialize random_data here to make clean-up safe */
|
||||
- random_data.length = 0;
|
||||
- random_data.data = NULL;
|
||||
-
|
||||
- /* allocate and initialize the key block */
|
||||
- key_block->magic = 0;
|
||||
- key_block->enctype = enctype;
|
||||
- if (0 != (retval = krb5_c_keylengths(context, enctype, &rand_len,
|
||||
- &key_len)))
|
||||
- goto cleanup;
|
||||
-
|
||||
- random_data.length = rand_len;
|
||||
- key_block->length = key_len;
|
||||
-
|
||||
- if (NULL == (key_block->contents = malloc(key_block->length))) {
|
||||
- retval = ENOMEM;
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
- memset (key_block->contents, 0, key_block->length);
|
||||
-
|
||||
- /* If this is anonymous pkinit, use the anonymous principle for party_u_info */
|
||||
- if (party_u_info && krb5_principal_compare_any_realm(context, party_u_info,
|
||||
- krb5_anonymous_principal()))
|
||||
- party_u_info = (krb5_principal)krb5_anonymous_principal();
|
||||
-
|
||||
- if (0 != (retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func)))
|
||||
- goto cleanup;
|
||||
-
|
||||
- /* 1. reps = keydatalen (K) / hash length (H) */
|
||||
- reps = key_block->length/hash_len;
|
||||
-
|
||||
- /* ... and round up, if necessary */
|
||||
- if (key_block->length > (reps * hash_len))
|
||||
- reps++;
|
||||
-
|
||||
- /* Allocate enough space in the random data buffer to hash directly into
|
||||
- * it, even if the last hash will make it bigger than the key length. */
|
||||
- if (NULL == (random_data.data = malloc(reps * hash_len))) {
|
||||
- retval = ENOMEM;
|
||||
- goto cleanup;
|
||||
- }
|
||||
-
|
||||
- /* Encode the ASN.1 octet string for "SuppPubInfo" */
|
||||
- supp_pub_info_fields.enctype = enctype;
|
||||
- supp_pub_info_fields.as_req = *as_req;
|
||||
- supp_pub_info_fields.pk_as_rep = *pk_as_rep;
|
||||
- if (0 != ((retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
|
||||
- &supp_pub_info))))
|
||||
- goto cleanup;
|
||||
-
|
||||
- /* Now encode the ASN.1 octet string for "OtherInfo" */
|
||||
- memset(&alg_id, 0, sizeof alg_id);
|
||||
- alg_id.algorithm = *alg_oid; /*alias*/
|
||||
-
|
||||
- other_info_fields.algorithm_identifier = alg_id;
|
||||
- other_info_fields.party_u_info = (krb5_principal) party_u_info;
|
||||
- other_info_fields.party_v_info = (krb5_principal) party_v_info;
|
||||
- other_info_fields.supp_pub_info = *supp_pub_info;
|
||||
- if (0 != (retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info)))
|
||||
- goto cleanup;
|
||||
|
||||
/* 2. Initialize a 32-bit, big-endian bit string counter as 1.
|
||||
* 3. For i = 1 to reps by 1, do the following:
|
||||
@@ -2471,8 +2439,9 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* 4. Set key = Hash1 || Hash2 || ... so that length of key is K bytes. */
|
||||
- if (!EVP_DigestFinal(ctx, (uint8_t *)random_data.data + offset, &s)) {
|
||||
+ /* 4. Set key = Hash1 || Hash2 || ... so that length of key is K
|
||||
+ * bytes. */
|
||||
+ if (!EVP_DigestFinal(ctx, (unsigned char *)out + offset, &s)) {
|
||||
krb5_set_error_message(context, KRB5_CRYPTO_INTERNAL,
|
||||
"Call to OpenSSL EVP_DigestUpdate() returned an error.");
|
||||
retval = KRB5_CRYPTO_INTERNAL;
|
||||
@@ -2484,26 +2453,110 @@ pkinit_alg_agility_kdf(krb5_context context,
|
||||
EVP_MD_CTX_free(ctx);
|
||||
ctx = NULL;
|
||||
}
|
||||
-
|
||||
- retval = krb5_c_random_to_key(context, enctype, &random_data,
|
||||
- key_block);
|
||||
-
|
||||
cleanup:
|
||||
EVP_MD_CTX_free(ctx);
|
||||
+ return retval;
|
||||
+} /* builtin_sskdf() */
|
||||
+#endif /* OSSL_KDFS */
|
||||
|
||||
- /* If this has been an error, free the allocated key_block, if any */
|
||||
- if (retval) {
|
||||
- krb5_free_keyblock_contents(context, key_block);
|
||||
+/* id-pkinit-kdf family, as specified by RFC 8636. */
|
||||
+krb5_error_code
|
||||
+pkinit_alg_agility_kdf(krb5_context context, krb5_data *secret,
|
||||
+ krb5_data *alg_oid, krb5_const_principal party_u_info,
|
||||
+ krb5_const_principal party_v_info,
|
||||
+ krb5_enctype enctype, krb5_data *as_req,
|
||||
+ krb5_data *pk_as_rep, krb5_keyblock *key_block)
|
||||
+{
|
||||
+ krb5_error_code retval;
|
||||
+ size_t hash_len = 0, rand_len = 0, key_len = 0;
|
||||
+ const EVP_MD *(*EVP_func)(void);
|
||||
+ krb5_sp80056a_other_info other_info_fields;
|
||||
+ krb5_pkinit_supp_pub_info supp_pub_info_fields;
|
||||
+ krb5_data *other_info = NULL, *supp_pub_info = NULL;
|
||||
+ krb5_data random_data = empty_data();
|
||||
+ krb5_algorithm_identifier alg_id;
|
||||
+ unsigned int reps;
|
||||
+
|
||||
+ /* Allocate and initialize the key block. */
|
||||
+ key_block->magic = 0;
|
||||
+ key_block->enctype = enctype;
|
||||
+
|
||||
+ /* Use separate variables to avoid alignment restriction problems. */
|
||||
+ retval = krb5_c_keylengths(context, enctype, &rand_len, &key_len);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+ random_data.length = rand_len;
|
||||
+ key_block->length = key_len;
|
||||
+
|
||||
+ key_block->contents = k5calloc(key_block->length, 1, &retval);
|
||||
+ if (key_block->contents == NULL)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* If this is anonymous pkinit, use the anonymous principle for
|
||||
+ * party_u_info. */
|
||||
+ if (party_u_info &&
|
||||
+ krb5_principal_compare_any_realm(context, party_u_info,
|
||||
+ krb5_anonymous_principal())) {
|
||||
+ party_u_info = (krb5_principal)krb5_anonymous_principal();
|
||||
}
|
||||
|
||||
- /* free other allocated resources, either way */
|
||||
- if (random_data.data)
|
||||
- free(random_data.data);
|
||||
+ retval = pkinit_alg_values(context, alg_oid, &hash_len, &EVP_func);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* 1. reps = keydatalen (K) / hash length (H) */
|
||||
+ reps = key_block->length / hash_len;
|
||||
+
|
||||
+ /* ... and round up, if necessary. */
|
||||
+ if (key_block->length > (reps * hash_len))
|
||||
+ reps++;
|
||||
+
|
||||
+ /* Allocate enough space in the random data buffer to hash directly into
|
||||
+ * it, even if the last hash will make it bigger than the key length. */
|
||||
+ random_data.data = k5alloc(reps * hash_len, &retval);
|
||||
+ if (random_data.data == NULL)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Encode the ASN.1 octet string for "SuppPubInfo". */
|
||||
+ supp_pub_info_fields.enctype = enctype;
|
||||
+ supp_pub_info_fields.as_req = *as_req;
|
||||
+ supp_pub_info_fields.pk_as_rep = *pk_as_rep;
|
||||
+ retval = encode_krb5_pkinit_supp_pub_info(&supp_pub_info_fields,
|
||||
+ &supp_pub_info);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Now encode the ASN.1 octet string for "OtherInfo". */
|
||||
+ memset(&alg_id, 0, sizeof(alg_id));
|
||||
+ alg_id.algorithm = *alg_oid;
|
||||
+ other_info_fields.algorithm_identifier = alg_id;
|
||||
+ other_info_fields.party_u_info = (krb5_principal)party_u_info;
|
||||
+ other_info_fields.party_v_info = (krb5_principal)party_v_info;
|
||||
+ other_info_fields.supp_pub_info = *supp_pub_info;
|
||||
+ retval = encode_krb5_sp80056a_other_info(&other_info_fields, &other_info);
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+#ifdef OSSL_KDFS
|
||||
+ retval = openssl_sskdf(context, hash_len, secret, other_info,
|
||||
+ random_data.data, key_block->length);
|
||||
+#else
|
||||
+ retval = builtin_sskdf(context, reps, hash_len, EVP_func, secret,
|
||||
+ other_info, random_data.data, key_block->length);
|
||||
+#endif
|
||||
+ if (retval)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ retval = krb5_c_random_to_key(context, enctype, &random_data, key_block);
|
||||
+cleanup:
|
||||
+ if (retval)
|
||||
+ krb5_free_keyblock_contents(context, key_block);
|
||||
+
|
||||
+ zapfree(random_data.data, random_data.length);
|
||||
krb5_free_data(context, other_info);
|
||||
krb5_free_data(context, supp_pub_info);
|
||||
-
|
||||
return retval;
|
||||
-} /*pkinit_alg_agility_kdf() */
|
||||
+}
|
||||
|
||||
/* Call DH_compute_key() and ensure that we left-pad short results instead of
|
||||
* leaving junk bytes at the end of the buffer. */
|
@ -1,69 +0,0 @@
|
||||
From f35077bfc570205092eca2a9d44e50ce265622f4 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Mon, 8 Nov 2021 17:48:50 +0100
|
||||
Subject: [PATCH] Support larger RADIUS attributes in libkrad
|
||||
|
||||
In kr_attrset_decode(), explicitly treat the length byte as unsigned.
|
||||
Otherwise attributes longer than 125 characters will be rejected with
|
||||
EBADMSG.
|
||||
|
||||
Add a 253-character-long NAS-Identifier attribute to the tests to make
|
||||
sure that attributes with the maximal number of characters are working
|
||||
as expected.
|
||||
|
||||
[ghudson@mit.edu: used uint8_t cast per current practices; edited
|
||||
commit message]
|
||||
|
||||
ticket: 9036 (new)
|
||||
---
|
||||
src/lib/krad/attrset.c | 2 +-
|
||||
src/lib/krad/t_packet.c | 13 +++++++++++++
|
||||
2 files changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
|
||||
index 03c613716..f309f1581 100644
|
||||
--- a/src/lib/krad/attrset.c
|
||||
+++ b/src/lib/krad/attrset.c
|
||||
@@ -217,7 +217,7 @@ kr_attrset_decode(krb5_context ctx, const krb5_data *in, const char *secret,
|
||||
|
||||
for (i = 0; i + 2 < in->length; ) {
|
||||
type = in->data[i++];
|
||||
- tmp = make_data(&in->data[i + 1], in->data[i] - 2);
|
||||
+ tmp = make_data(&in->data[i + 1], (uint8_t)in->data[i] - 2);
|
||||
i += tmp.length + 1;
|
||||
|
||||
retval = (in->length < i) ? EBADMSG : 0;
|
||||
diff --git a/src/lib/krad/t_packet.c b/src/lib/krad/t_packet.c
|
||||
index 0a92e9cc2..c22489144 100644
|
||||
--- a/src/lib/krad/t_packet.c
|
||||
+++ b/src/lib/krad/t_packet.c
|
||||
@@ -57,6 +57,14 @@ make_packet(krb5_context ctx, const krb5_data *username,
|
||||
krb5_error_code retval;
|
||||
const krb5_data *data;
|
||||
int i = 0;
|
||||
+ krb5_data nas_id;
|
||||
+
|
||||
+ nas_id = string2data("12345678901234567890123456789012345678901234567890"
|
||||
+ "12345678901234567890123456789012345678901234567890"
|
||||
+ "12345678901234567890123456789012345678901234567890"
|
||||
+ "12345678901234567890123456789012345678901234567890"
|
||||
+ "12345678901234567890123456789012345678901234567890"
|
||||
+ "123");
|
||||
|
||||
retval = krad_attrset_new(ctx, &set);
|
||||
if (retval != 0)
|
||||
@@ -71,6 +79,11 @@ make_packet(krb5_context ctx, const krb5_data *username,
|
||||
if (retval != 0)
|
||||
goto out;
|
||||
|
||||
+ retval = krad_attrset_add(set, krad_attr_name2num("NAS-Identifier"),
|
||||
+ &nas_id);
|
||||
+ if (retval != 0)
|
||||
+ goto out;
|
||||
+
|
||||
retval = krad_packet_new_request(ctx, "foo",
|
||||
krad_code_name2num("Access-Request"),
|
||||
set, iterator, &i, &tmp);
|
||||
--
|
||||
2.35.1
|
||||
|
@ -1,209 +0,0 @@
|
||||
From ce160f8826bae223876a6527a731c36b6912db15 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Hudson <ghudson@mit.edu>
|
||||
Date: Tue, 9 Nov 2021 13:00:43 -0500
|
||||
Subject: [PATCH 1/2] Avoid use after free during libkrad cleanup
|
||||
|
||||
libkrad client requests contain a list of references to remotes, with
|
||||
no back-references or reference counts. To prevent accesses to
|
||||
dangling references during cleanup, cancel all requests on all remotes
|
||||
before freeing any remotes.
|
||||
|
||||
Remove the code for aging out unused servers. This code was fairly
|
||||
safe as all requests referencing a remote should have completed or
|
||||
timed out during an hour of disuse, but in the current design we have
|
||||
no way to guarantee or check that. The set of addresses we send
|
||||
RADIUS requests to will generally be small, so aging out servers is
|
||||
unnecessary.
|
||||
|
||||
ticket: 9035 (new)
|
||||
---
|
||||
src/lib/krad/client.c | 42 ++++++++++++++---------------------------
|
||||
src/lib/krad/internal.h | 4 ++++
|
||||
src/lib/krad/remote.c | 11 ++++++++---
|
||||
3 files changed, 26 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krad/client.c b/src/lib/krad/client.c
|
||||
index 6365dd1c6..810940afc 100644
|
||||
--- a/src/lib/krad/client.c
|
||||
+++ b/src/lib/krad/client.c
|
||||
@@ -64,7 +64,6 @@ struct request_st {
|
||||
|
||||
struct server_st {
|
||||
krad_remote *serv;
|
||||
- time_t last;
|
||||
K5_LIST_ENTRY(server_st) list;
|
||||
};
|
||||
|
||||
@@ -81,15 +80,10 @@ get_server(krad_client *rc, const struct addrinfo *ai, const char *secret,
|
||||
krad_remote **out)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
- time_t currtime;
|
||||
server *srv;
|
||||
|
||||
- if (time(&currtime) == (time_t)-1)
|
||||
- return errno;
|
||||
-
|
||||
K5_LIST_FOREACH(srv, &rc->servers, list) {
|
||||
if (kr_remote_equals(srv->serv, ai, secret)) {
|
||||
- srv->last = currtime;
|
||||
*out = srv->serv;
|
||||
return 0;
|
||||
}
|
||||
@@ -98,7 +92,6 @@ get_server(krad_client *rc, const struct addrinfo *ai, const char *secret,
|
||||
srv = calloc(1, sizeof(server));
|
||||
if (srv == NULL)
|
||||
return ENOMEM;
|
||||
- srv->last = currtime;
|
||||
|
||||
retval = kr_remote_new(rc->kctx, rc->vctx, ai, secret, &srv->serv);
|
||||
if (retval != 0) {
|
||||
@@ -173,28 +166,12 @@ request_new(krad_client *rc, krad_code code, const krad_attrset *attrs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/* Close remotes that haven't been used in a while. */
|
||||
-static void
|
||||
-age(struct server_head *head, time_t currtime)
|
||||
-{
|
||||
- server *srv, *tmp;
|
||||
-
|
||||
- K5_LIST_FOREACH_SAFE(srv, head, list, tmp) {
|
||||
- if (currtime == (time_t)-1 || currtime - srv->last > 60 * 60) {
|
||||
- K5_LIST_REMOVE(srv, list);
|
||||
- kr_remote_free(srv->serv);
|
||||
- free(srv);
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/* Handle a response from a server (or related errors). */
|
||||
static void
|
||||
on_response(krb5_error_code retval, const krad_packet *reqp,
|
||||
const krad_packet *rspp, void *data)
|
||||
{
|
||||
request *req = data;
|
||||
- time_t currtime;
|
||||
size_t i;
|
||||
|
||||
/* Do nothing if we are already completed. */
|
||||
@@ -221,10 +198,6 @@ on_response(krb5_error_code retval, const krad_packet *reqp,
|
||||
for (i = 0; req->remotes[i].remote != NULL; i++)
|
||||
kr_remote_cancel(req->remotes[i].remote, req->remotes[i].packet);
|
||||
|
||||
- /* Age out servers that haven't been used in a while. */
|
||||
- if (time(&currtime) != (time_t)-1)
|
||||
- age(&req->rc->servers, currtime);
|
||||
-
|
||||
request_free(req);
|
||||
}
|
||||
|
||||
@@ -247,10 +220,23 @@ krad_client_new(krb5_context kctx, verto_ctx *vctx, krad_client **out)
|
||||
void
|
||||
krad_client_free(krad_client *rc)
|
||||
{
|
||||
+ server *srv;
|
||||
+
|
||||
if (rc == NULL)
|
||||
return;
|
||||
|
||||
- age(&rc->servers, -1);
|
||||
+ /* Cancel all requests before freeing any remotes, since each request's
|
||||
+ * callback data may contain references to multiple remotes. */
|
||||
+ K5_LIST_FOREACH(srv, &rc->servers, list)
|
||||
+ kr_remote_cancel_all(srv->serv);
|
||||
+
|
||||
+ while (!K5_LIST_EMPTY(&rc->servers)) {
|
||||
+ srv = K5_LIST_FIRST(&rc->servers);
|
||||
+ K5_LIST_REMOVE(srv, list);
|
||||
+ kr_remote_free(srv->serv);
|
||||
+ free(srv);
|
||||
+ }
|
||||
+
|
||||
free(rc);
|
||||
}
|
||||
|
||||
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
||||
index 0143d155a..7619563fc 100644
|
||||
--- a/src/lib/krad/internal.h
|
||||
+++ b/src/lib/krad/internal.h
|
||||
@@ -109,6 +109,10 @@ kr_remote_send(krad_remote *rr, krad_code code, krad_attrset *attrs,
|
||||
void
|
||||
kr_remote_cancel(krad_remote *rr, const krad_packet *pkt);
|
||||
|
||||
+/* Cancel all requests awaiting responses. */
|
||||
+void
|
||||
+kr_remote_cancel_all(krad_remote *rr);
|
||||
+
|
||||
/* Determine if this remote object refers to the remote resource identified
|
||||
* by the addrinfo struct and the secret. */
|
||||
krb5_boolean
|
||||
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
|
||||
index 7e491e994..06ae751bc 100644
|
||||
--- a/src/lib/krad/remote.c
|
||||
+++ b/src/lib/krad/remote.c
|
||||
@@ -421,15 +421,20 @@ error:
|
||||
return retval;
|
||||
}
|
||||
|
||||
+void
|
||||
+kr_remote_cancel_all(krad_remote *rr)
|
||||
+{
|
||||
+ while (!K5_TAILQ_EMPTY(&rr->list))
|
||||
+ request_finish(K5_TAILQ_FIRST(&rr->list), ECANCELED, NULL);
|
||||
+}
|
||||
+
|
||||
void
|
||||
kr_remote_free(krad_remote *rr)
|
||||
{
|
||||
if (rr == NULL)
|
||||
return;
|
||||
|
||||
- while (!K5_TAILQ_EMPTY(&rr->list))
|
||||
- request_finish(K5_TAILQ_FIRST(&rr->list), ECANCELED, NULL);
|
||||
-
|
||||
+ kr_remote_cancel_all(rr);
|
||||
free(rr->secret);
|
||||
if (rr->info != NULL)
|
||||
free(rr->info->ai_addr);
|
||||
--
|
||||
2.35.1
|
||||
|
||||
|
||||
From e0084425df784952e76b3bcc8ae9d08300234733 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Mon, 8 Nov 2021 17:47:17 +0100
|
||||
Subject: [PATCH 2/2] More python3 fixes for t_daemon.py
|
||||
|
||||
[ghudson@mit.edu: use a list comprehension instead of map()]
|
||||
---
|
||||
src/lib/krad/t_daemon.py | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/lib/krad/t_daemon.py b/src/lib/krad/t_daemon.py
|
||||
index 7668cd7f8..4a3de079c 100755
|
||||
--- a/src/lib/krad/t_daemon.py
|
||||
+++ b/src/lib/krad/t_daemon.py
|
||||
@@ -50,7 +50,7 @@ class TestServer(server.Server):
|
||||
|
||||
for key in pkt.keys():
|
||||
if key == "User-Password":
|
||||
- passwd = map(pkt.PwDecrypt, pkt[key])
|
||||
+ passwd = [pkt.PwDecrypt(x) for x in pkt[key]]
|
||||
|
||||
reply = self.CreateReplyPacket(pkt)
|
||||
if passwd == ['accept']:
|
||||
@@ -61,8 +61,8 @@ class TestServer(server.Server):
|
||||
|
||||
srv = TestServer(addresses=["localhost"],
|
||||
hosts={"127.0.0.1":
|
||||
- server.RemoteHost("127.0.0.1", "foo", "localhost")},
|
||||
- dict=dictionary.Dictionary(StringIO.StringIO(DICTIONARY)))
|
||||
+ server.RemoteHost("127.0.0.1", b"foo", "localhost")},
|
||||
+ dict=dictionary.Dictionary(StringIO(DICTIONARY)))
|
||||
|
||||
# Write a sentinel character to let the parent process know we're listening.
|
||||
sys.stdout.write("~")
|
||||
--
|
||||
2.35.1
|
||||
|
127
krb5.spec
127
krb5.spec
@ -34,7 +34,7 @@
|
||||
#
|
||||
# baserelease is what we have standardized across Fedora and what
|
||||
# rpmdev-bumpspec knows how to handle.
|
||||
%global baserelease 13
|
||||
%global baserelease 0.1
|
||||
|
||||
# This should be e.g. beta1 or %%nil
|
||||
%global pre_release %nil
|
||||
@ -46,9 +46,9 @@
|
||||
%endif
|
||||
|
||||
%global krb5_version_major 1
|
||||
%global krb5_version_minor 19
|
||||
%global krb5_version_minor 20
|
||||
# For a release without a patch number set to %%nil
|
||||
%global krb5_version_patch 2
|
||||
%global krb5_version_patch 1
|
||||
|
||||
%global krb5_version_major_minor %{krb5_version_major}.%{krb5_version_minor}
|
||||
%global krb5_version %{krb5_version_major_minor}
|
||||
@ -68,59 +68,29 @@ Release: %{krb5_release}%{?dist}
|
||||
Source0: https://web.mit.edu/kerberos/dist/krb5/%{krb5_version_major_minor}/krb5-%{krb5_version}%{?krb5_pre_release}.tar.gz
|
||||
Source1: https://web.mit.edu/kerberos/dist/krb5/%{krb5_version_major_minor}/krb5-%{krb5_version}%{?krb5_pre_release}.tar.gz.asc
|
||||
|
||||
# Numbering is a relic of old init systems etc. It's easiest to just leave.
|
||||
Source2: kprop.service
|
||||
Source4: kadmin.service
|
||||
Source5: krb5kdc.service
|
||||
Source6: krb5.conf
|
||||
Source10: kdc.conf
|
||||
Source11: kadm5.acl
|
||||
Source19: krb5kdc.sysconfig
|
||||
Source20: kadmin.sysconfig
|
||||
Source21: kprop.sysconfig
|
||||
Source29: ksu.pamd
|
||||
Source33: krb5kdc.logrotate
|
||||
Source34: kadmind.logrotate
|
||||
Source39: krb5-krb5kdc.conf
|
||||
Source3: kadmin.service
|
||||
Source4: krb5kdc.service
|
||||
Source5: krb5.conf
|
||||
Source6: kdc.conf
|
||||
Source7: kadm5.acl
|
||||
Source8: krb5kdc.sysconfig
|
||||
Source9: kadmin.sysconfig
|
||||
Source10: kprop.sysconfig
|
||||
Source11: ksu.pamd
|
||||
Source12: krb5kdc.logrotate
|
||||
Source13: kadmind.logrotate
|
||||
Source14: krb5-krb5kdc.conf
|
||||
|
||||
Patch0: downstream-ksu-pam-integration.patch
|
||||
Patch1: downstream-SELinux-integration.patch
|
||||
Patch4: downstream-fix-debuginfo-with-y.tab.c.patch
|
||||
Patch5: downstream-Remove-3des-support.patch
|
||||
Patch7: downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch
|
||||
Patch8: Add-APIs-for-marshalling-credentials.patch
|
||||
Patch9: Add-hostname-canonicalization-helper-to-k5test.py.patch
|
||||
Patch10: Support-host-based-GSS-initiator-names.patch
|
||||
Patch11: Add-KCM_OP_GET_CRED_LIST-for-faster-iteration.patch
|
||||
Patch12: Fix-KCM-flag-transmission-for-remove_cred.patch
|
||||
Patch13: Make-KCM-iteration-fallback-work-with-sssd-kcm.patch
|
||||
Patch14: Use-KCM_OP_RETRIEVE-in-KCM-client.patch
|
||||
Patch15: Fix-KCM-retrieval-support-for-sssd.patch
|
||||
Patch17: Move-some-dejagnu-kadmin-tests-to-Python-tests.patch
|
||||
Patch18: Fix-some-principal-realm-canonicalization-cases.patch
|
||||
Patch19: Allow-kinit-with-keytab-to-defer-canonicalization.patch
|
||||
Patch20: Fix-kadmin-k-with-fallback-or-referral-realm.patch
|
||||
Patch21: Fix-softpkcs11-build-issues-with-openssl-3.0.patch
|
||||
Patch22: Remove-deprecated-OpenSSL-calls-from-softpkcs11.patch
|
||||
Patch23: Fix-k5tls-module-for-OpenSSL-3.patch
|
||||
Patch24: Fix-leaks-on-error-in-kadm5-init-functions.patch
|
||||
Patch25: Clean-up-context-after-failed-open-in-libkdb5.patch
|
||||
Patch26: Use-asan-in-one-of-the-CI-builds.patch
|
||||
Patch29: Clean-up-gssapi_krb5-ccache-name-functions.patch
|
||||
Patch30: Fix-KDC-null-deref-on-TGS-inner-body-null-server.patch
|
||||
Patch32: Add-buildsystem-detection-of-the-OpenSSL-3-KDF-inter.patch
|
||||
Patch33: Use-OpenSSL-s-SSKDF-in-PKINIT-when-available.patch
|
||||
Patch34: Use-OpenSSL-s-KBKDF-and-KRB5KDF-for-deriving-long-te.patch
|
||||
Patch35: Handle-OpenSSL-3-s-providers.patch
|
||||
Patch36: Remove-TCL-based-libkadm5-API-tests.patch
|
||||
Patch37: Use-SHA256-instead-of-SHA1-for-PKINIT-CMS-digest.patch
|
||||
Patch38: krb5-krad-remote.patch
|
||||
Patch39: krb5-krad-larger-attrs.patch
|
||||
Patch40: Try-harder-to-avoid-password-change-replay-errors.patch
|
||||
Patch41: Add-configure-variable-for-default-PKCS-11-module.patch
|
||||
Patch42: downstream-Allow-krad-UDP-TCP-localhost-connection-with-FIPS.patch
|
||||
Patch43: Read-GSS-configuration-files-with-mtime-0.patch
|
||||
Patch44: Fix-integer-overflows-in-PAC-parsing.patch
|
||||
Patch1: 0001-downstream-ksu-pam-integration.patch
|
||||
Patch2: 0002-downstream-SELinux-integration.patch
|
||||
Patch3: 0003-downstream-fix-debuginfo-with-y.tab.c.patch
|
||||
Patch4: 0004-downstream-Remove-3des-support.patch
|
||||
Patch5: 0005-downstream-FIPS-with-PRNG-and-RADIUS-and-MD4.patch
|
||||
Patch6: 0006-downstream-Allow-krad-UDP-TCP-localhost-connection-w.patch
|
||||
Patch7: 0007-Add-configure-variable-for-default-PKCS-11-module.patch
|
||||
Patch8: 0008-Set-reasonable-supportedCMSTypes-in-PKINIT.patch
|
||||
Patch9: 0009-Simplify-plugin-loading-code.patch
|
||||
|
||||
License: MIT
|
||||
URL: https://web.mit.edu/kerberos/www/
|
||||
@ -153,8 +123,14 @@ BuildRequires: procps-ng
|
||||
BuildRequires: resolv_wrapper
|
||||
%endif
|
||||
|
||||
%if 0%{?fedora} > 35
|
||||
# Need KDFs. This is the "real" version
|
||||
BuildRequires: openssl-devel => 1:3.0.0
|
||||
%else
|
||||
# Need KDFs. This is the backported version
|
||||
BuildRequires: openssl-devel >= 1:1.1.1d-4
|
||||
BuildRequires: openssl-devel < 1:3.0.0
|
||||
%endif
|
||||
|
||||
%description
|
||||
Kerberos V5 is a trusted-third-party network authentication system,
|
||||
@ -180,7 +156,12 @@ to install this package.
|
||||
|
||||
%package libs
|
||||
Summary: The non-admin shared libraries used by Kerberos 5
|
||||
%if 0%{?fedora} > 35
|
||||
Requires: openssl-libs >= 1:3.0.0
|
||||
%else
|
||||
Requires: openssl-libs >= 1:1.1.1d-4
|
||||
Requires: openssl-libs < 1:3.0.0
|
||||
%endif
|
||||
Requires: coreutils, gawk, sed
|
||||
Requires: keyutils-libs >= 1.5.8
|
||||
Requires: /etc/crypto-policies/back-ends/krb5.config
|
||||
@ -296,6 +277,13 @@ PORT=`expr 7777 + $LONG_BIT - 48`
|
||||
sed -i -e s,7777,`expr "$PORT" + 0`,g $cfg
|
||||
sed -i -e s,7778,`expr "$PORT" + 1`,g $cfg
|
||||
|
||||
# Fix kadmind port hard-coded in tests
|
||||
PORT=`expr 61000 + $LONG_BIT - 48`
|
||||
sed -i -e \
|
||||
"s,params.kadmind_port = 61001;,params.kadmind_port = $((PORT + 1));," \
|
||||
src/lib/kadm5/t_kadm5.c
|
||||
|
||||
|
||||
%build
|
||||
# Go ahead and supply tcl info, because configure doesn't know how to find it.
|
||||
source %{_libdir}/tclConfig.sh
|
||||
@ -379,15 +367,15 @@ popd
|
||||
|
||||
# Sample KDC config files (bundled kdc.conf and kadm5.acl).
|
||||
mkdir -p $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc
|
||||
install -pm 600 %{SOURCE10} $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc/
|
||||
install -pm 600 %{SOURCE11} $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc/
|
||||
install -pm 600 %{SOURCE6} $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc/
|
||||
install -pm 600 %{SOURCE7} $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc/
|
||||
|
||||
# Where per-user keytabs live by default.
|
||||
mkdir -p $RPM_BUILD_ROOT%{_var}/kerberos/krb5/user
|
||||
|
||||
# Default configuration file for everything.
|
||||
mkdir -p $RPM_BUILD_ROOT/etc
|
||||
install -pm 644 %{SOURCE6} $RPM_BUILD_ROOT/etc/krb5.conf
|
||||
install -pm 644 %{SOURCE5} $RPM_BUILD_ROOT/etc/krb5.conf
|
||||
|
||||
# Default include on this directory
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/krb5.conf.d
|
||||
@ -407,16 +395,16 @@ mkdir -m 755 -p $RPM_BUILD_ROOT/etc/gss/mech.d
|
||||
export DEFCCNAME="%{configured_default_ccache_name}"
|
||||
awk '{print}
|
||||
/^# default_realm/{print " default_ccache_name =", ENVIRON["DEFCCNAME"]}' \
|
||||
%{SOURCE6} > $RPM_BUILD_ROOT/etc/krb5.conf
|
||||
touch -r %{SOURCE6} $RPM_BUILD_ROOT/etc/krb5.conf
|
||||
%{SOURCE5} > $RPM_BUILD_ROOT/etc/krb5.conf
|
||||
touch -r %{SOURCE5} $RPM_BUILD_ROOT/etc/krb5.conf
|
||||
grep default_ccache_name $RPM_BUILD_ROOT/etc/krb5.conf
|
||||
%endif
|
||||
|
||||
# Server init scripts (krb5kdc,kadmind,kpropd) and their sysconfig files.
|
||||
mkdir -p $RPM_BUILD_ROOT%{_unitdir}
|
||||
for unit in \
|
||||
%{SOURCE5}\
|
||||
%{SOURCE4} \
|
||||
%{SOURCE4}\
|
||||
%{SOURCE3} \
|
||||
%{SOURCE2} ; do
|
||||
# In the past, the init script was supposed to be named after the service
|
||||
# that the started daemon provided. Changing their names is an
|
||||
@ -424,11 +412,11 @@ for unit in \
|
||||
install -pm 644 ${unit} $RPM_BUILD_ROOT%{_unitdir}
|
||||
done
|
||||
mkdir -p $RPM_BUILD_ROOT/%{_tmpfilesdir}
|
||||
install -pm 644 %{SOURCE39} $RPM_BUILD_ROOT/%{_tmpfilesdir}/
|
||||
install -pm 644 %{SOURCE14} $RPM_BUILD_ROOT/%{_tmpfilesdir}/
|
||||
mkdir -p $RPM_BUILD_ROOT/%{_localstatedir}/run/krb5kdc
|
||||
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/sysconfig
|
||||
for sysconfig in %{SOURCE19} %{SOURCE20} %{SOURCE21} ; do
|
||||
for sysconfig in %{SOURCE8} %{SOURCE9} %{SOURCE10} ; do
|
||||
install -pm 644 ${sysconfig} \
|
||||
$RPM_BUILD_ROOT/etc/sysconfig/`basename ${sysconfig} .sysconfig`
|
||||
done
|
||||
@ -436,15 +424,15 @@ done
|
||||
# logrotate configuration files
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/logrotate.d/
|
||||
for logrotate in \
|
||||
%{SOURCE33} \
|
||||
%{SOURCE34} ; do
|
||||
%{SOURCE12} \
|
||||
%{SOURCE13} ; do
|
||||
install -pm 644 ${logrotate} \
|
||||
$RPM_BUILD_ROOT/etc/logrotate.d/`basename ${logrotate} .logrotate`
|
||||
done
|
||||
|
||||
# PAM configuration files.
|
||||
mkdir -p $RPM_BUILD_ROOT/etc/pam.d/
|
||||
for pam in %{SOURCE29} ; do
|
||||
for pam in %{SOURCE11} ; do
|
||||
install -pm 644 ${pam} \
|
||||
$RPM_BUILD_ROOT/etc/pam.d/`basename ${pam} .pamd`
|
||||
done
|
||||
@ -676,6 +664,13 @@ exit 0
|
||||
%{_libdir}/libkadm5srv_mit.so.*
|
||||
|
||||
%changelog
|
||||
* Tue Nov 22 2022 Julien Rische <jrische@redhat.com> - 1.20.1-0.1
|
||||
- New upstream version (1.20.1)
|
||||
- Resolves: rhbz#2124463
|
||||
- Restore "supportedCMSTypes" attribute in PKINIT preauth requests
|
||||
- Set SHA-512 or SHA-256 with RSA as preferred CMS signature algorithms
|
||||
- Resolves: rhbz#2114766
|
||||
|
||||
* Wed Nov 09 2022 Julien Rische <jrische@redhat.com> - 1.19.2-13
|
||||
- Fix integer overflows in PAC parsing (CVE-2022-42898)
|
||||
- Resolves: rhbz#2143011
|
||||
|
4
sources
4
sources
@ -1,2 +1,2 @@
|
||||
SHA512 (krb5-1.19.2.tar.gz) = b90d6ed0e1e8a87eb5cb2c36d88b823a6a6caabf85e5d419adb8a930f7eea09a5f8491464e7e454cca7ba88be09d19415962fe0036ad2e31fc584f9fc0bbd470
|
||||
SHA512 (krb5-1.19.2.tar.gz.asc) = 87c4d096dbb6821401125b8f8a315ce1aac029744ba9670a4f8a2a680e6dd5798e1c6d5d2b68b17fd9a4b3b9c6ff111cd1dcac42f934d48fb20381b3765e0f64
|
||||
SHA512 (krb5-1.20.1.tar.gz) = 6f57479f13f107cd84f30de5c758eb6b9fc59171329c13e5da6073b806755f8d163eb7bd84767ea861ad6458ea0c9eeb00ee044d3bcad01ef136e9888564b6a2
|
||||
SHA512 (krb5-1.20.1.tar.gz.asc) = 1d3312bd67581e07adfdadf2c5fe394179631d8add8bd075efefe982a0de22369004e60a14422d426382c8c591e4181b9897088afe9d4e86f0b5a97e5954c67a
|
||||
|
Loading…
Reference in New Issue
Block a user