commit
adab5bbdce
@ -0,0 +1 @@
|
|||||||
|
SOURCES/krb5-1.20.1.tar.gz
|
@ -0,0 +1 @@
|
|||||||
|
06278439a6cd5a2aa861d8e877451b794487534b SOURCES/krb5-1.20.1.tar.gz
|
@ -0,0 +1,777 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
Modify ksu so that it performs account and session management on behalf of
|
||||||
|
the target user account, mimicking the action of regular su. The default
|
||||||
|
service name is "ksu", because on Fedora at least the configuration used
|
||||||
|
is determined by whether or not a login shell is being opened, and so
|
||||||
|
this may need to vary, too. At run-time, ksu's behavior can be reset to
|
||||||
|
the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu]
|
||||||
|
section of /etc/krb5.conf.
|
||||||
|
|
||||||
|
When enabled, ksu gains a dependency on libpam.
|
||||||
|
|
||||||
|
Originally RT#5939, though it's changed since then to perform the account
|
||||||
|
and session management before dropping privileges, and to apply on top of
|
||||||
|
changes we're proposing for how it handles cache collections.
|
||||||
|
|
||||||
|
Last-updated: krb5-1.18-beta1
|
||||||
|
---
|
||||||
|
src/aclocal.m4 | 69 +++++++
|
||||||
|
src/clients/ksu/Makefile.in | 8 +-
|
||||||
|
src/clients/ksu/main.c | 88 +++++++-
|
||||||
|
src/clients/ksu/pam.c | 389 ++++++++++++++++++++++++++++++++++++
|
||||||
|
src/clients/ksu/pam.h | 57 ++++++
|
||||||
|
src/configure.ac | 2 +
|
||||||
|
6 files changed, 610 insertions(+), 3 deletions(-)
|
||||||
|
create mode 100644 src/clients/ksu/pam.c
|
||||||
|
create mode 100644 src/clients/ksu/pam.h
|
||||||
|
|
||||||
|
diff --git a/src/aclocal.m4 b/src/aclocal.m4
|
||||||
|
index 9920476f91..bf9da35bbc 100644
|
||||||
|
--- a/src/aclocal.m4
|
||||||
|
+++ b/src/aclocal.m4
|
||||||
|
@@ -1458,3 +1458,72 @@ if test "$with_ldap" = yes; then
|
||||||
|
OPENLDAP_PLUGIN=yes
|
||||||
|
fi
|
||||||
|
])dnl
|
||||||
|
+dnl
|
||||||
|
+dnl
|
||||||
|
+dnl Use PAM instead of local crypt() compare for checking local passwords,
|
||||||
|
+dnl and perform PAM account, session management, and password-changing where
|
||||||
|
+dnl appropriate.
|
||||||
|
+dnl
|
||||||
|
+AC_DEFUN(KRB5_WITH_PAM,[
|
||||||
|
+AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])],
|
||||||
|
+ withpam="$withval",withpam=auto)
|
||||||
|
+AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])],
|
||||||
|
+ withksupamservice="$withval",withksupamservice=ksu)
|
||||||
|
+old_LIBS="$LIBS"
|
||||||
|
+if test "$withpam" != no ; then
|
||||||
|
+ AC_MSG_RESULT([checking for PAM...])
|
||||||
|
+ PAM_LIBS=
|
||||||
|
+
|
||||||
|
+ AC_CHECK_HEADERS(security/pam_appl.h)
|
||||||
|
+ if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then
|
||||||
|
+ if test "$withpam" = auto ; then
|
||||||
|
+ AC_MSG_RESULT([Unable to locate security/pam_appl.h.])
|
||||||
|
+ withpam=no
|
||||||
|
+ else
|
||||||
|
+ AC_MSG_ERROR([Unable to locate security/pam_appl.h.])
|
||||||
|
+ fi
|
||||||
|
+ fi
|
||||||
|
+
|
||||||
|
+ LIBS=
|
||||||
|
+ unset ac_cv_func_pam_start
|
||||||
|
+ AC_CHECK_FUNCS(putenv pam_start)
|
||||||
|
+ if test "x$ac_cv_func_pam_start" = xno ; then
|
||||||
|
+ unset ac_cv_func_pam_start
|
||||||
|
+ AC_CHECK_LIB(dl,dlopen)
|
||||||
|
+ AC_CHECK_FUNCS(pam_start)
|
||||||
|
+ if test "x$ac_cv_func_pam_start" = xno ; then
|
||||||
|
+ AC_CHECK_LIB(pam,pam_start)
|
||||||
|
+ unset ac_cv_func_pam_start
|
||||||
|
+ unset ac_cv_func_pam_getenvlist
|
||||||
|
+ AC_CHECK_FUNCS(pam_start pam_getenvlist)
|
||||||
|
+ if test "x$ac_cv_func_pam_start" = xyes ; then
|
||||||
|
+ PAM_LIBS="$LIBS"
|
||||||
|
+ else
|
||||||
|
+ if test "$withpam" = auto ; then
|
||||||
|
+ AC_MSG_RESULT([Unable to locate libpam.])
|
||||||
|
+ withpam=no
|
||||||
|
+ else
|
||||||
|
+ AC_MSG_ERROR([Unable to locate libpam.])
|
||||||
|
+ fi
|
||||||
|
+ fi
|
||||||
|
+ fi
|
||||||
|
+ fi
|
||||||
|
+ if test "$withpam" != no ; then
|
||||||
|
+ AC_MSG_NOTICE([building with PAM support])
|
||||||
|
+ AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM])
|
||||||
|
+ AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice",
|
||||||
|
+ [Define to the name of the PAM service name to be used by ksu.])
|
||||||
|
+ PAM_LIBS="$LIBS"
|
||||||
|
+ NON_PAM_MAN=".\\\" "
|
||||||
|
+ PAM_MAN=
|
||||||
|
+ else
|
||||||
|
+ PAM_MAN=".\\\" "
|
||||||
|
+ NON_PAM_MAN=
|
||||||
|
+ fi
|
||||||
|
+fi
|
||||||
|
+LIBS="$old_LIBS"
|
||||||
|
+AC_SUBST(PAM_LIBS)
|
||||||
|
+AC_SUBST(PAM_MAN)
|
||||||
|
+AC_SUBST(NON_PAM_MAN)
|
||||||
|
+])dnl
|
||||||
|
+
|
||||||
|
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
|
||||||
|
index 8b4edce4d8..9d58f29b5d 100644
|
||||||
|
--- a/src/clients/ksu/Makefile.in
|
||||||
|
+++ b/src/clients/ksu/Makefile.in
|
||||||
|
@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S)..
|
||||||
|
DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"'
|
||||||
|
|
||||||
|
KSU_LIBS=@KSU_LIBS@
|
||||||
|
+PAM_LIBS=@PAM_LIBS@
|
||||||
|
|
||||||
|
SRCS = \
|
||||||
|
$(srcdir)/krb_auth_su.c \
|
||||||
|
$(srcdir)/ccache.c \
|
||||||
|
$(srcdir)/authorization.c \
|
||||||
|
$(srcdir)/main.c \
|
||||||
|
+ $(srcdir)/pam.c \
|
||||||
|
$(srcdir)/heuristic.c \
|
||||||
|
$(srcdir)/xmalloc.c \
|
||||||
|
$(srcdir)/setenv.c
|
||||||
|
@@ -17,13 +19,17 @@ OBJS = \
|
||||||
|
ccache.o \
|
||||||
|
authorization.o \
|
||||||
|
main.o \
|
||||||
|
+ pam.o \
|
||||||
|
heuristic.o \
|
||||||
|
xmalloc.o @SETENVOBJ@
|
||||||
|
|
||||||
|
all: ksu
|
||||||
|
|
||||||
|
ksu: $(OBJS) $(KRB5_BASE_DEPLIBS)
|
||||||
|
- $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS)
|
||||||
|
+ $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS)
|
||||||
|
+
|
||||||
|
+pam.o: pam.c
|
||||||
|
+ $(CC) $(ALL_CFLAGS) -c $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) ksu
|
||||||
|
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
|
||||||
|
index af12861729..931f054041 100644
|
||||||
|
--- a/src/clients/ksu/main.c
|
||||||
|
+++ b/src/clients/ksu/main.c
|
||||||
|
@@ -26,6 +26,7 @@
|
||||||
|
* KSU was written by: Ari Medvinsky, ari@isi.edu
|
||||||
|
*/
|
||||||
|
|
||||||
|
+#include "autoconf.h"
|
||||||
|
#include "ksu.h"
|
||||||
|
#include "adm_proto.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
@@ -33,6 +34,10 @@
|
||||||
|
#include <signal.h>
|
||||||
|
#include <grp.h>
|
||||||
|
|
||||||
|
+#ifdef USE_PAM
|
||||||
|
+#include "pam.h"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* globals */
|
||||||
|
char * prog_name;
|
||||||
|
int auth_debug =0;
|
||||||
|
@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN];
|
||||||
|
char k5users_path[MAXPATHLEN];
|
||||||
|
char * gb_err = NULL;
|
||||||
|
int quiet = 0;
|
||||||
|
+int force_fork = 0;
|
||||||
|
/***********/
|
||||||
|
|
||||||
|
#define KS_TEMPORARY_CACHE "MEMORY:_ksu"
|
||||||
|
@@ -536,6 +542,23 @@ main (argc, argv)
|
||||||
|
prog_name,target_user,client_name,
|
||||||
|
source_user,ontty());
|
||||||
|
|
||||||
|
+#ifdef USE_PAM
|
||||||
|
+ if (appl_pam_enabled(ksu_context, "ksu")) {
|
||||||
|
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
|
||||||
|
+ NULL, source_user,
|
||||||
|
+ ttyname(STDERR_FILENO)) != 0) {
|
||||||
|
+ fprintf(stderr, "Access denied for %s.\n", target_user);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ if (appl_pam_requires_chauthtok()) {
|
||||||
|
+ fprintf(stderr, "Password change required for %s.\n",
|
||||||
|
+ target_user);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ force_fork++;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* Run authorization as target.*/
|
||||||
|
if (krb5_seteuid(target_uid)) {
|
||||||
|
com_err(prog_name, errno, _("while switching to target for "
|
||||||
|
@@ -596,6 +619,24 @@ main (argc, argv)
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
+#ifdef USE_PAM
|
||||||
|
+ } else {
|
||||||
|
+ /* we always do PAM account management, even for root */
|
||||||
|
+ if (appl_pam_enabled(ksu_context, "ksu")) {
|
||||||
|
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
|
||||||
|
+ NULL, source_user,
|
||||||
|
+ ttyname(STDERR_FILENO)) != 0) {
|
||||||
|
+ fprintf(stderr, "Access denied for %s.\n", target_user);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ if (appl_pam_requires_chauthtok()) {
|
||||||
|
+ fprintf(stderr, "Password change required for %s.\n",
|
||||||
|
+ target_user);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ force_fork++;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if( some_rest_copy){
|
||||||
|
@@ -653,6 +694,30 @@ main (argc, argv)
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef USE_PAM
|
||||||
|
+ if (appl_pam_enabled(ksu_context, "ksu")) {
|
||||||
|
+ if (appl_pam_session_open() != 0) {
|
||||||
|
+ fprintf(stderr, "Error opening session for %s.\n", target_user);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ if (auth_debug){
|
||||||
|
+ printf(" Opened PAM session.\n");
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ if (appl_pam_cred_init()) {
|
||||||
|
+ fprintf(stderr, "Error initializing credentials for %s.\n",
|
||||||
|
+ target_user);
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ if (auth_debug){
|
||||||
|
+ printf(" Initialized PAM credentials.\n");
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* set permissions */
|
||||||
|
if (setgid(target_pwd->pw_gid) < 0) {
|
||||||
|
perror("ksu: setgid");
|
||||||
|
@@ -750,7 +815,7 @@ main (argc, argv)
|
||||||
|
fprintf(stderr, "program to be execed %s\n",params[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if( keep_target_cache ) {
|
||||||
|
+ if( keep_target_cache && !force_fork ) {
|
||||||
|
execv(params[0], params);
|
||||||
|
com_err(prog_name, errno, _("while trying to execv %s"), params[0]);
|
||||||
|
sweep_up(ksu_context, cc_target);
|
||||||
|
@@ -780,16 +845,35 @@ main (argc, argv)
|
||||||
|
if (ret_pid == -1) {
|
||||||
|
com_err(prog_name, errno, _("while calling waitpid"));
|
||||||
|
}
|
||||||
|
- sweep_up(ksu_context, cc_target);
|
||||||
|
+ if( !keep_target_cache ) {
|
||||||
|
+ sweep_up(ksu_context, cc_target);
|
||||||
|
+ }
|
||||||
|
exit (statusp);
|
||||||
|
case -1:
|
||||||
|
com_err(prog_name, errno, _("while trying to fork."));
|
||||||
|
sweep_up(ksu_context, cc_target);
|
||||||
|
exit (1);
|
||||||
|
case 0:
|
||||||
|
+#ifdef USE_PAM
|
||||||
|
+ if (appl_pam_enabled(ksu_context, "ksu")) {
|
||||||
|
+ if (appl_pam_setenv() != 0) {
|
||||||
|
+ fprintf(stderr, "Error setting up environment for %s.\n",
|
||||||
|
+ target_user);
|
||||||
|
+ exit (1);
|
||||||
|
+ }
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ if (auth_debug){
|
||||||
|
+ printf(" Set up PAM environment.\n");
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
execv(params[0], params);
|
||||||
|
com_err(prog_name, errno, _("while trying to execv %s"),
|
||||||
|
params[0]);
|
||||||
|
+ if( keep_target_cache ) {
|
||||||
|
+ sweep_up(ksu_context, cc_target);
|
||||||
|
+ }
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..cbfe487047
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/clients/ksu/pam.c
|
||||||
|
@@ -0,0 +1,389 @@
|
||||||
|
+/*
|
||||||
|
+ * src/clients/ksu/pam.c
|
||||||
|
+ *
|
||||||
|
+ * Copyright 2007,2009,2010 Red Hat, Inc.
|
||||||
|
+ *
|
||||||
|
+ * All Rights Reserved.
|
||||||
|
+ *
|
||||||
|
+ * Redistribution and use in source and binary forms, with or without
|
||||||
|
+ * modification, are permitted provided that the following conditions are met:
|
||||||
|
+ *
|
||||||
|
+ * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
+ * list of conditions and the following disclaimer.
|
||||||
|
+ *
|
||||||
|
+ * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
+ * this list of conditions and the following disclaimer in the documentation
|
||||||
|
+ * and/or other materials provided with the distribution.
|
||||||
|
+ *
|
||||||
|
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
|
||||||
|
+ * used to endorse or promote products derived from this software without
|
||||||
|
+ * specific prior written permission.
|
||||||
|
+ *
|
||||||
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+ *
|
||||||
|
+ * Convenience wrappers for using PAM.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include "autoconf.h"
|
||||||
|
+#ifdef USE_PAM
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+#include "k5-int.h"
|
||||||
|
+#include "pam.h"
|
||||||
|
+
|
||||||
|
+#ifndef MAXPWSIZE
|
||||||
|
+#define MAXPWSIZE 128
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+static int appl_pam_started;
|
||||||
|
+static pid_t appl_pam_starter = -1;
|
||||||
|
+static int appl_pam_session_opened;
|
||||||
|
+static int appl_pam_creds_initialized;
|
||||||
|
+static int appl_pam_pwchange_required;
|
||||||
|
+static pam_handle_t *appl_pamh;
|
||||||
|
+static struct pam_conv appl_pam_conv;
|
||||||
|
+static char *appl_pam_user;
|
||||||
|
+struct appl_pam_non_interactive_args {
|
||||||
|
+ const char *user;
|
||||||
|
+ const char *password;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+appl_pam_enabled(krb5_context context, const char *section)
|
||||||
|
+{
|
||||||
|
+ int enabled = 1;
|
||||||
|
+ if ((context != NULL) && (context->profile != NULL)) {
|
||||||
|
+ if (profile_get_boolean(context->profile,
|
||||||
|
+ section,
|
||||||
|
+ USE_PAM_CONFIGURATION_KEYWORD,
|
||||||
|
+ NULL,
|
||||||
|
+ enabled, &enabled) != 0) {
|
||||||
|
+ enabled = 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return enabled;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+appl_pam_cleanup(void)
|
||||||
|
+{
|
||||||
|
+ if (getpid() != appl_pam_starter) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Called to clean up PAM.\n");
|
||||||
|
+#endif
|
||||||
|
+ if (appl_pam_creds_initialized) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Deleting PAM credentials.\n");
|
||||||
|
+#endif
|
||||||
|
+ pam_setcred(appl_pamh, PAM_DELETE_CRED);
|
||||||
|
+ appl_pam_creds_initialized = 0;
|
||||||
|
+ }
|
||||||
|
+ if (appl_pam_session_opened) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Closing PAM session.\n");
|
||||||
|
+#endif
|
||||||
|
+ pam_close_session(appl_pamh, 0);
|
||||||
|
+ appl_pam_session_opened = 0;
|
||||||
|
+ }
|
||||||
|
+ appl_pam_pwchange_required = 0;
|
||||||
|
+ if (appl_pam_started) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Shutting down PAM.\n");
|
||||||
|
+#endif
|
||||||
|
+ pam_end(appl_pamh, 0);
|
||||||
|
+ appl_pam_started = 0;
|
||||||
|
+ appl_pam_starter = -1;
|
||||||
|
+ free(appl_pam_user);
|
||||||
|
+ appl_pam_user = NULL;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+static int
|
||||||
|
+appl_pam_interactive_converse(int num_msg, const struct pam_message **msg,
|
||||||
|
+ struct pam_response **presp, void *appdata_ptr)
|
||||||
|
+{
|
||||||
|
+ const struct pam_message *message;
|
||||||
|
+ struct pam_response *resp;
|
||||||
|
+ int i, code;
|
||||||
|
+ char *pwstring, pwbuf[MAXPWSIZE];
|
||||||
|
+ unsigned int pwsize;
|
||||||
|
+ resp = malloc(sizeof(struct pam_response) * num_msg);
|
||||||
|
+ if (resp == NULL) {
|
||||||
|
+ return PAM_BUF_ERR;
|
||||||
|
+ }
|
||||||
|
+ memset(resp, 0, sizeof(struct pam_response) * num_msg);
|
||||||
|
+ code = PAM_SUCCESS;
|
||||||
|
+ for (i = 0; i < num_msg; i++) {
|
||||||
|
+ message = &(msg[0][i]); /* XXX */
|
||||||
|
+ message = msg[i]; /* XXX */
|
||||||
|
+ pwstring = NULL;
|
||||||
|
+ switch (message->msg_style) {
|
||||||
|
+ case PAM_TEXT_INFO:
|
||||||
|
+ case PAM_ERROR_MSG:
|
||||||
|
+ printf("[%s]\n", message->msg ? message->msg : "");
|
||||||
|
+ fflush(stdout);
|
||||||
|
+ resp[i].resp = NULL;
|
||||||
|
+ resp[i].resp_retcode = PAM_SUCCESS;
|
||||||
|
+ break;
|
||||||
|
+ case PAM_PROMPT_ECHO_ON:
|
||||||
|
+ case PAM_PROMPT_ECHO_OFF:
|
||||||
|
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) {
|
||||||
|
+ if (fgets(pwbuf, sizeof(pwbuf),
|
||||||
|
+ stdin) != NULL) {
|
||||||
|
+ pwbuf[strcspn(pwbuf, "\r\n")] = '\0';
|
||||||
|
+ pwstring = pwbuf;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ pwstring = getpass(message->msg ?
|
||||||
|
+ message->msg :
|
||||||
|
+ "");
|
||||||
|
+ }
|
||||||
|
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) {
|
||||||
|
+ pwsize = strlen(pwstring);
|
||||||
|
+ resp[i].resp = malloc(pwsize + 1);
|
||||||
|
+ if (resp[i].resp == NULL) {
|
||||||
|
+ resp[i].resp_retcode = PAM_BUF_ERR;
|
||||||
|
+ } else {
|
||||||
|
+ memcpy(resp[i].resp, pwstring, pwsize);
|
||||||
|
+ resp[i].resp[pwsize] = '\0';
|
||||||
|
+ resp[i].resp_retcode = PAM_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ resp[i].resp_retcode = PAM_CONV_ERR;
|
||||||
|
+ code = PAM_CONV_ERR;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ *presp = resp;
|
||||||
|
+ return code;
|
||||||
|
+}
|
||||||
|
+static int
|
||||||
|
+appl_pam_non_interactive_converse(int num_msg,
|
||||||
|
+ const struct pam_message **msg,
|
||||||
|
+ struct pam_response **presp,
|
||||||
|
+ void *appdata_ptr)
|
||||||
|
+{
|
||||||
|
+ const struct pam_message *message;
|
||||||
|
+ struct pam_response *resp;
|
||||||
|
+ int i, code;
|
||||||
|
+ unsigned int pwsize;
|
||||||
|
+ struct appl_pam_non_interactive_args *args;
|
||||||
|
+ const char *pwstring;
|
||||||
|
+ resp = malloc(sizeof(struct pam_response) * num_msg);
|
||||||
|
+ if (resp == NULL) {
|
||||||
|
+ return PAM_BUF_ERR;
|
||||||
|
+ }
|
||||||
|
+ args = appdata_ptr;
|
||||||
|
+ memset(resp, 0, sizeof(struct pam_response) * num_msg);
|
||||||
|
+ code = PAM_SUCCESS;
|
||||||
|
+ for (i = 0; i < num_msg; i++) {
|
||||||
|
+ message = &((*msg)[i]);
|
||||||
|
+ message = msg[i];
|
||||||
|
+ pwstring = NULL;
|
||||||
|
+ switch (message->msg_style) {
|
||||||
|
+ case PAM_TEXT_INFO:
|
||||||
|
+ case PAM_ERROR_MSG:
|
||||||
|
+ break;
|
||||||
|
+ case PAM_PROMPT_ECHO_ON:
|
||||||
|
+ case PAM_PROMPT_ECHO_OFF:
|
||||||
|
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) {
|
||||||
|
+ /* assume "user" */
|
||||||
|
+ pwstring = args->user;
|
||||||
|
+ } else {
|
||||||
|
+ /* assume "password" */
|
||||||
|
+ pwstring = args->password;
|
||||||
|
+ }
|
||||||
|
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) {
|
||||||
|
+ pwsize = strlen(pwstring);
|
||||||
|
+ resp[i].resp = malloc(pwsize + 1);
|
||||||
|
+ if (resp[i].resp == NULL) {
|
||||||
|
+ resp[i].resp_retcode = PAM_BUF_ERR;
|
||||||
|
+ } else {
|
||||||
|
+ memcpy(resp[i].resp, pwstring, pwsize);
|
||||||
|
+ resp[i].resp[pwsize] = '\0';
|
||||||
|
+ resp[i].resp_retcode = PAM_SUCCESS;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ resp[i].resp_retcode = PAM_CONV_ERR;
|
||||||
|
+ code = PAM_CONV_ERR;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ *presp = resp;
|
||||||
|
+ return code;
|
||||||
|
+}
|
||||||
|
+static int
|
||||||
|
+appl_pam_start(const char *service, int interactive,
|
||||||
|
+ const char *login_username,
|
||||||
|
+ const char *non_interactive_password,
|
||||||
|
+ const char *hostname,
|
||||||
|
+ const char *ruser,
|
||||||
|
+ const char *tty)
|
||||||
|
+{
|
||||||
|
+ static int exit_handler_registered;
|
||||||
|
+ static struct appl_pam_non_interactive_args args;
|
||||||
|
+ int ret = 0;
|
||||||
|
+ if (appl_pam_started &&
|
||||||
|
+ (strcmp(login_username, appl_pam_user) != 0)) {
|
||||||
|
+ appl_pam_cleanup();
|
||||||
|
+ appl_pam_user = NULL;
|
||||||
|
+ }
|
||||||
|
+ if (!appl_pam_started) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Starting PAM up (service=\"%s\",user=\"%s\").\n",
|
||||||
|
+ service, login_username);
|
||||||
|
+#endif
|
||||||
|
+ memset(&appl_pam_conv, 0, sizeof(appl_pam_conv));
|
||||||
|
+ appl_pam_conv.conv = interactive ?
|
||||||
|
+ &appl_pam_interactive_converse :
|
||||||
|
+ &appl_pam_non_interactive_converse;
|
||||||
|
+ memset(&args, 0, sizeof(args));
|
||||||
|
+ args.user = strdup(login_username);
|
||||||
|
+ args.password = non_interactive_password ?
|
||||||
|
+ strdup(non_interactive_password) :
|
||||||
|
+ NULL;
|
||||||
|
+ appl_pam_conv.appdata_ptr = &args;
|
||||||
|
+ ret = pam_start(service, login_username,
|
||||||
|
+ &appl_pam_conv, &appl_pamh);
|
||||||
|
+ if (ret == 0) {
|
||||||
|
+ if (hostname != NULL) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Setting PAM_RHOST to \"%s\".\n", hostname);
|
||||||
|
+#endif
|
||||||
|
+ pam_set_item(appl_pamh, PAM_RHOST, hostname);
|
||||||
|
+ }
|
||||||
|
+ if (ruser != NULL) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Setting PAM_RUSER to \"%s\".\n", ruser);
|
||||||
|
+#endif
|
||||||
|
+ pam_set_item(appl_pamh, PAM_RUSER, ruser);
|
||||||
|
+ }
|
||||||
|
+ if (tty != NULL) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Setting PAM_TTY to \"%s\".\n", tty);
|
||||||
|
+#endif
|
||||||
|
+ pam_set_item(appl_pamh, PAM_TTY, tty);
|
||||||
|
+ }
|
||||||
|
+ if (!exit_handler_registered &&
|
||||||
|
+ (atexit(appl_pam_cleanup) != 0)) {
|
||||||
|
+ pam_end(appl_pamh, 0);
|
||||||
|
+ appl_pamh = NULL;
|
||||||
|
+ ret = -1;
|
||||||
|
+ } else {
|
||||||
|
+ appl_pam_started = 1;
|
||||||
|
+ appl_pam_starter = getpid();
|
||||||
|
+ appl_pam_user = strdup(login_username);
|
||||||
|
+ exit_handler_registered = 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+int
|
||||||
|
+appl_pam_acct_mgmt(const char *service, int interactive,
|
||||||
|
+ const char *login_username,
|
||||||
|
+ const char *non_interactive_password,
|
||||||
|
+ const char *hostname,
|
||||||
|
+ const char *ruser,
|
||||||
|
+ const char *tty)
|
||||||
|
+{
|
||||||
|
+ int ret;
|
||||||
|
+ appl_pam_pwchange_required = 0;
|
||||||
|
+ ret = appl_pam_start(service, interactive, login_username,
|
||||||
|
+ non_interactive_password, hostname, ruser, tty);
|
||||||
|
+ if (ret == 0) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Calling pam_acct_mgmt().\n");
|
||||||
|
+#endif
|
||||||
|
+ ret = pam_acct_mgmt(appl_pamh, 0);
|
||||||
|
+ switch (ret) {
|
||||||
|
+ case PAM_IGNORE:
|
||||||
|
+ ret = 0;
|
||||||
|
+ break;
|
||||||
|
+ case PAM_NEW_AUTHTOK_REQD:
|
||||||
|
+ appl_pam_pwchange_required = 1;
|
||||||
|
+ ret = 0;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+int
|
||||||
|
+appl_pam_requires_chauthtok(void)
|
||||||
|
+{
|
||||||
|
+ return appl_pam_pwchange_required;
|
||||||
|
+}
|
||||||
|
+int
|
||||||
|
+appl_pam_session_open(void)
|
||||||
|
+{
|
||||||
|
+ int ret = 0;
|
||||||
|
+ if (appl_pam_started) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Opening PAM session.\n");
|
||||||
|
+#endif
|
||||||
|
+ ret = pam_open_session(appl_pamh, 0);
|
||||||
|
+ if (ret == 0) {
|
||||||
|
+ appl_pam_session_opened = 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+int
|
||||||
|
+appl_pam_setenv(void)
|
||||||
|
+{
|
||||||
|
+ int ret = 0;
|
||||||
|
+#ifdef HAVE_PAM_GETENVLIST
|
||||||
|
+#ifdef HAVE_PUTENV
|
||||||
|
+ int i;
|
||||||
|
+ char **list;
|
||||||
|
+ if (appl_pam_started) {
|
||||||
|
+ list = pam_getenvlist(appl_pamh);
|
||||||
|
+ for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Setting \"%s\" in environment.\n", list[i]);
|
||||||
|
+#endif
|
||||||
|
+ putenv(list[i]);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+#endif
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+int
|
||||||
|
+appl_pam_cred_init(void)
|
||||||
|
+{
|
||||||
|
+ int ret = 0;
|
||||||
|
+ if (appl_pam_started) {
|
||||||
|
+#ifdef DEBUG
|
||||||
|
+ printf("Initializing PAM credentials.\n");
|
||||||
|
+#endif
|
||||||
|
+ ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED);
|
||||||
|
+ if (ret == 0) {
|
||||||
|
+ appl_pam_creds_initialized = 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..0ab76569cb
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/clients/ksu/pam.h
|
||||||
|
@@ -0,0 +1,57 @@
|
||||||
|
+/*
|
||||||
|
+ * src/clients/ksu/pam.h
|
||||||
|
+ *
|
||||||
|
+ * Copyright 2007,2009,2010 Red Hat, Inc.
|
||||||
|
+ *
|
||||||
|
+ * All Rights Reserved.
|
||||||
|
+ *
|
||||||
|
+ * Redistribution and use in source and binary forms, with or without
|
||||||
|
+ * modification, are permitted provided that the following conditions are met:
|
||||||
|
+ *
|
||||||
|
+ * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
+ * list of conditions and the following disclaimer.
|
||||||
|
+ *
|
||||||
|
+ * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
+ * this list of conditions and the following disclaimer in the documentation
|
||||||
|
+ * and/or other materials provided with the distribution.
|
||||||
|
+ *
|
||||||
|
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
|
||||||
|
+ * used to endorse or promote products derived from this software without
|
||||||
|
+ * specific prior written permission.
|
||||||
|
+ *
|
||||||
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
+ *
|
||||||
|
+ * Convenience wrappers for using PAM.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <krb5.h>
|
||||||
|
+#ifdef HAVE_SECURITY_PAM_APPL_H
|
||||||
|
+#include <security/pam_appl.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define USE_PAM_CONFIGURATION_KEYWORD "use_pam"
|
||||||
|
+
|
||||||
|
+#ifdef USE_PAM
|
||||||
|
+int appl_pam_enabled(krb5_context context, const char *section);
|
||||||
|
+int appl_pam_acct_mgmt(const char *service, int interactive,
|
||||||
|
+ const char *local_username,
|
||||||
|
+ const char *non_interactive_password,
|
||||||
|
+ const char *hostname,
|
||||||
|
+ const char *ruser,
|
||||||
|
+ const char *tty);
|
||||||
|
+int appl_pam_requires_chauthtok(void);
|
||||||
|
+int appl_pam_session_open(void);
|
||||||
|
+int appl_pam_setenv(void);
|
||||||
|
+int appl_pam_cred_init(void);
|
||||||
|
+void appl_pam_cleanup(void);
|
||||||
|
+#endif
|
||||||
|
diff --git a/src/configure.ac b/src/configure.ac
|
||||||
|
index f03028b5fd..aa970b0447 100644
|
||||||
|
--- a/src/configure.ac
|
||||||
|
+++ b/src/configure.ac
|
||||||
|
@@ -1400,6 +1400,8 @@ AC_SUBST([VERTO_VERSION])
|
||||||
|
|
||||||
|
AC_PATH_PROG(GROFF, groff)
|
||||||
|
|
||||||
|
+KRB5_WITH_PAM
|
||||||
|
+
|
||||||
|
# Make localedir work in autoconf 2.5x.
|
||||||
|
if test "${localedir+set}" != set; then
|
||||||
|
localedir='$(datadir)/locale'
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,44 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
We want to keep these y.tab.c files around because the debuginfo points to
|
||||||
|
them. It would be more elegant at the end to use symbolic links, but that
|
||||||
|
could mess up people working in the tree on other things.
|
||||||
|
|
||||||
|
Last-updated: krb5-1.9
|
||||||
|
---
|
||||||
|
src/kadmin/cli/Makefile.in | 5 +++++
|
||||||
|
src/plugins/kdb/ldap/ldap_util/Makefile.in | 2 +-
|
||||||
|
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/kadmin/cli/Makefile.in b/src/kadmin/cli/Makefile.in
|
||||||
|
index adfea6e2b5..d1327e400b 100644
|
||||||
|
--- a/src/kadmin/cli/Makefile.in
|
||||||
|
+++ b/src/kadmin/cli/Makefile.in
|
||||||
|
@@ -37,3 +37,8 @@ clean-unix::
|
||||||
|
# CC_LINK is not meant for compilation and this use may break in the future.
|
||||||
|
datetest: getdate.c
|
||||||
|
$(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c
|
||||||
|
+
|
||||||
|
+%.c: %.y
|
||||||
|
+ $(RM) y.tab.c $@
|
||||||
|
+ $(YACC.y) $<
|
||||||
|
+ $(CP) y.tab.c $@
|
||||||
|
diff --git a/src/plugins/kdb/ldap/ldap_util/Makefile.in b/src/plugins/kdb/ldap/ldap_util/Makefile.in
|
||||||
|
index 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)
|
||||||
|
getdate.c: $(GETDATE)
|
||||||
|
$(RM) getdate.c y.tab.c
|
||||||
|
$(YACC) $(GETDATE)
|
||||||
|
- $(MV) y.tab.c getdate.c
|
||||||
|
+ $(CP) y.tab.c getdate.c
|
||||||
|
|
||||||
|
install:
|
||||||
|
$(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,655 @@
|
|||||||
|
From b8e3a859f8904d395ea0e1a7d6c49a791029711c 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
|
||||||
|
|
||||||
|
NB: Use openssl's PRNG in FIPS mode and taint within krad.
|
||||||
|
|
||||||
|
A lot of the FIPS error conditions from OpenSSL are incredibly
|
||||||
|
mysterious (at best, things return NULL unexpectedly; at worst,
|
||||||
|
internal assertions are tripped; most of the time, you just get
|
||||||
|
ENOMEM). In order to cope with this, we need to have some level of
|
||||||
|
awareness of what we can and can't safely call.
|
||||||
|
|
||||||
|
This will slow down some calls slightly (FIPS_mode() takes multiple
|
||||||
|
locks), but not for any ciphers we care about - which is to say that
|
||||||
|
AES is fine. Shame about SPAKE though.
|
||||||
|
|
||||||
|
post6 restores MD4 (and therefore keygen-only RC4).
|
||||||
|
|
||||||
|
post7 restores MD5 and adds radius_md5_fips_override.
|
||||||
|
|
||||||
|
post8 silences a static analyzer warning.
|
||||||
|
|
||||||
|
post9 add missing includes for FIPS_mode() macro
|
||||||
|
|
||||||
|
Last-updated: krb5-1.20.1
|
||||||
|
---
|
||||||
|
doc/admin/conf_files/krb5_conf.rst | 6 +++
|
||||||
|
src/lib/crypto/krb/prng.c | 17 ++++++-
|
||||||
|
.../crypto/openssl/enc_provider/camellia.c | 7 +++
|
||||||
|
src/lib/crypto/openssl/enc_provider/rc4.c | 17 ++++++-
|
||||||
|
.../crypto/openssl/hash_provider/hash_evp.c | 12 +++++
|
||||||
|
src/lib/crypto/openssl/hmac.c | 7 ++-
|
||||||
|
src/lib/krad/attr.c | 46 ++++++++++++++-----
|
||||||
|
src/lib/krad/attrset.c | 5 +-
|
||||||
|
src/lib/krad/internal.h | 32 ++++++++++++-
|
||||||
|
src/lib/krad/packet.c | 22 +++++----
|
||||||
|
src/lib/krad/remote.c | 10 +++-
|
||||||
|
src/lib/krad/t_attr.c | 3 +-
|
||||||
|
src/lib/krad/t_attrset.c | 4 +-
|
||||||
|
src/plugins/preauth/spake/spake_client.c | 10 ++++
|
||||||
|
src/plugins/preauth/spake/spake_kdc.c | 10 ++++
|
||||||
|
15 files changed, 175 insertions(+), 33 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
|
||||||
|
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:
|
||||||
|
qualification of shortnames, set this relation to the empty string
|
||||||
|
with ``qualify_shortname = ""``. (New in release 1.18.)
|
||||||
|
|
||||||
|
+**radius_md5_fips_override**
|
||||||
|
+ Downstream-only option to enable use of MD5 in RADIUS
|
||||||
|
+ communication (libkrad). This allows for local (or protected
|
||||||
|
+ tunnel) communication with a RADIUS server that doesn't use krad
|
||||||
|
+ (e.g., freeradius) while in FIPS mode.
|
||||||
|
+
|
||||||
|
**rdns**
|
||||||
|
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 d6b79e2dea..ae37c77518 100644
|
||||||
|
--- a/src/lib/crypto/krb/prng.c
|
||||||
|
+++ b/src/lib/crypto/krb/prng.c
|
||||||
|
@@ -26,6 +26,14 @@
|
||||||
|
|
||||||
|
#include "crypto_int.h"
|
||||||
|
|
||||||
|
+#include <openssl/rand.h>
|
||||||
|
+
|
||||||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
+#else
|
||||||
|
+#include <openssl/crypto.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
krb5_error_code KRB5_CALLCONV
|
||||||
|
krb5_c_random_seed(krb5_context context, krb5_data *data)
|
||||||
|
{
|
||||||
|
@@ -96,9 +104,16 @@ cleanup:
|
||||||
|
static krb5_boolean
|
||||||
|
get_os_entropy(unsigned char *buf, size_t len)
|
||||||
|
{
|
||||||
|
-#if defined(__linux__) && defined(SYS_getrandom)
|
||||||
|
int r;
|
||||||
|
|
||||||
|
+ /* A wild FIPS mode appeared! */
|
||||||
|
+ if (FIPS_mode()) {
|
||||||
|
+ /* The return codes on this API are not good */
|
||||||
|
+ r = RAND_bytes(buf, len);
|
||||||
|
+ return r == 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+#if defined(__linux__) && defined(SYS_getrandom)
|
||||||
|
while (len > 0) {
|
||||||
|
/*
|
||||||
|
* 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 01920e6ce1..3dd3b0624f 100644
|
||||||
|
--- a/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||||
|
+++ b/src/lib/crypto/openssl/enc_provider/camellia.c
|
||||||
|
@@ -32,6 +32,7 @@
|
||||||
|
#include <openssl/camellia.h>
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
#include <openssl/core_names.h>
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
#else
|
||||||
|
#include <openssl/modes.h>
|
||||||
|
#endif
|
||||||
|
@@ -387,6 +388,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;
|
||||||
|
|
||||||
|
+ if (FIPS_mode())
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
if (output->length < CAMELLIA_BLOCK_SIZE)
|
||||||
|
return KRB5_BAD_MSIZE;
|
||||||
|
|
||||||
|
@@ -418,6 +422,9 @@ static krb5_error_code
|
||||||
|
krb5int_camellia_init_state (const krb5_keyblock *key, krb5_keyusage usage,
|
||||||
|
krb5_data *state)
|
||||||
|
{
|
||||||
|
+ if (FIPS_mode())
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
state->length = 16;
|
||||||
|
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 448d563348..6a83f10d27 100644
|
||||||
|
--- a/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||||
|
+++ b/src/lib/crypto/openssl/enc_provider/rc4.c
|
||||||
|
@@ -38,6 +38,10 @@
|
||||||
|
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* The loopback field is a pointer to the structure. If the application copies
|
||||||
|
* the state (not a valid operation, but one which happens to works with some
|
||||||
|
@@ -69,6 +73,9 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||||
|
EVP_CIPHER_CTX *ctx = NULL;
|
||||||
|
struct arcfour_state *arcstate;
|
||||||
|
|
||||||
|
+ if (FIPS_mode())
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
arcstate = (state != NULL) ? (void *)state->data : NULL;
|
||||||
|
if (arcstate != NULL) {
|
||||||
|
ctx = arcstate->ctx;
|
||||||
|
@@ -116,7 +123,12 @@ k5_arcfour_docrypt(krb5_key key, const krb5_data *state, krb5_crypto_iov *data,
|
||||||
|
static void
|
||||||
|
k5_arcfour_free_state(krb5_data *state)
|
||||||
|
{
|
||||||
|
- struct arcfour_state *arcstate = (void *)state->data;
|
||||||
|
+ struct arcfour_state *arcstate;
|
||||||
|
+
|
||||||
|
+ if (FIPS_mode())
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ arcstate = (void *) state->data;
|
||||||
|
|
||||||
|
EVP_CIPHER_CTX_free(arcstate->ctx);
|
||||||
|
free(arcstate);
|
||||||
|
@@ -128,6 +140,9 @@ k5_arcfour_init_state(const krb5_keyblock *key,
|
||||||
|
{
|
||||||
|
struct arcfour_state *arcstate;
|
||||||
|
|
||||||
|
+ if (FIPS_mode())
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* 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 f2fbffdb29..11659908bb 100644
|
||||||
|
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
@@ -60,6 +60,11 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
if (ctx == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
+ if (type == EVP_md4() || type == EVP_md5()) {
|
||||||
|
+ /* See comments below in hash_md4() and hash_md5(). */
|
||||||
|
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
ok = EVP_DigestInit_ex(ctx, type, NULL);
|
||||||
|
for (i = 0; i < num_data; i++) {
|
||||||
|
if (!SIGN_IOV(&data[i]))
|
||||||
|
@@ -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)
|
||||||
|
{
|
||||||
|
+ /*
|
||||||
|
+ * MD4 is needed in FIPS mode to perform key generation for RC4 keys used
|
||||||
|
+ * by IPA. These keys are only used along a (separately) secured channel
|
||||||
|
+ * for legacy reasons when performing trusts to Active Directory.
|
||||||
|
+ */
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
+ /* MD5 is needed in FIPS mode for communication with RADIUS servers. This
|
||||||
|
+ * is gated in libkrad by libdefaults->radius_md5_fips_override. */
|
||||||
|
return hash_evp(EVP_md5(), data, num_data, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/lib/crypto/openssl/hmac.c b/src/lib/crypto/openssl/hmac.c
|
||||||
|
index bf12b8d6a0..25a419d73a 100644
|
||||||
|
--- a/src/lib/crypto/openssl/hmac.c
|
||||||
|
+++ b/src/lib/crypto/openssl/hmac.c
|
||||||
|
@@ -59,6 +59,7 @@
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
#include <openssl/params.h>
|
||||||
|
#include <openssl/core_names.h>
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
#else
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#endif
|
||||||
|
@@ -111,7 +112,11 @@ map_digest(const struct krb5_hash_provider *hash)
|
||||||
|
return EVP_sha256();
|
||||||
|
else if (hash == &krb5int_hash_sha384)
|
||||||
|
return EVP_sha384();
|
||||||
|
- else if (hash == &krb5int_hash_md5)
|
||||||
|
+
|
||||||
|
+ if (FIPS_mode())
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ if (hash == &krb5int_hash_md5)
|
||||||
|
return EVP_md5();
|
||||||
|
else if (hash == &krb5int_hash_md4)
|
||||||
|
return EVP_md4();
|
||||||
|
diff --git a/src/lib/krad/attr.c b/src/lib/krad/attr.c
|
||||||
|
index 9c13d9d755..42d354a3b5 100644
|
||||||
|
--- a/src/lib/krad/attr.c
|
||||||
|
+++ b/src/lib/krad/attr.c
|
||||||
|
@@ -38,7 +38,8 @@
|
||||||
|
typedef krb5_error_code
|
||||||
|
(*attribute_transform_fn)(krb5_context ctx, const char *secret,
|
||||||
|
const unsigned char *auth, const krb5_data *in,
|
||||||
|
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
|
||||||
|
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
|
||||||
|
+ krb5_boolean *is_fips);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
@@ -51,12 +52,14 @@ typedef struct {
|
||||||
|
static krb5_error_code
|
||||||
|
user_password_encode(krb5_context ctx, const char *secret,
|
||||||
|
const unsigned char *auth, const krb5_data *in,
|
||||||
|
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
|
||||||
|
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
|
||||||
|
+ krb5_boolean *is_fips);
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
user_password_decode(krb5_context ctx, const char *secret,
|
||||||
|
const unsigned char *auth, const krb5_data *in,
|
||||||
|
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
|
||||||
|
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
|
||||||
|
+ krb5_boolean *ignored);
|
||||||
|
|
||||||
|
static const attribute_record attributes[UCHAR_MAX] = {
|
||||||
|
{"User-Name", 1, MAX_ATTRSIZE, NULL, NULL},
|
||||||
|
@@ -128,7 +131,8 @@ static const attribute_record attributes[UCHAR_MAX] = {
|
||||||
|
static krb5_error_code
|
||||||
|
user_password_encode(krb5_context ctx, const char *secret,
|
||||||
|
const unsigned char *auth, const krb5_data *in,
|
||||||
|
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
|
||||||
|
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
|
||||||
|
+ krb5_boolean *is_fips)
|
||||||
|
{
|
||||||
|
const unsigned char *indx;
|
||||||
|
krb5_error_code retval;
|
||||||
|
@@ -154,8 +158,15 @@ user_password_encode(krb5_context ctx, const char *secret,
|
||||||
|
for (blck = 0, indx = auth; blck * BLOCKSIZE < len; blck++) {
|
||||||
|
memcpy(tmp.data + seclen, indx, BLOCKSIZE);
|
||||||
|
|
||||||
|
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
|
||||||
|
- &sum);
|
||||||
|
+ if (kr_use_fips(ctx)) {
|
||||||
|
+ /* Skip encryption here. Taint so that we won't pass it out of
|
||||||
|
+ * the machine by accident. */
|
||||||
|
+ *is_fips = TRUE;
|
||||||
|
+ sum.contents = calloc(1, BLOCKSIZE);
|
||||||
|
+ } else {
|
||||||
|
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &tmp,
|
||||||
|
+ &sum);
|
||||||
|
+ }
|
||||||
|
if (retval != 0) {
|
||||||
|
zap(tmp.data, tmp.length);
|
||||||
|
zap(outbuf, len);
|
||||||
|
@@ -180,7 +191,8 @@ user_password_encode(krb5_context ctx, const char *secret,
|
||||||
|
static krb5_error_code
|
||||||
|
user_password_decode(krb5_context ctx, const char *secret,
|
||||||
|
const unsigned char *auth, const krb5_data *in,
|
||||||
|
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
|
||||||
|
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
|
||||||
|
+ krb5_boolean *is_fips)
|
||||||
|
{
|
||||||
|
const unsigned char *indx;
|
||||||
|
krb5_error_code retval;
|
||||||
|
@@ -204,8 +216,15 @@ user_password_decode(krb5_context ctx, const char *secret,
|
||||||
|
for (blck = 0, indx = auth; blck * BLOCKSIZE < in->length; blck++) {
|
||||||
|
memcpy(tmp.data + seclen, indx, BLOCKSIZE);
|
||||||
|
|
||||||
|
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
|
||||||
|
- &tmp, &sum);
|
||||||
|
+ if (kr_use_fips(ctx)) {
|
||||||
|
+ /* Skip encryption here. Taint so that we won't pass it out of
|
||||||
|
+ * the machine by accident. */
|
||||||
|
+ *is_fips = TRUE;
|
||||||
|
+ sum.contents = calloc(1, BLOCKSIZE);
|
||||||
|
+ } else {
|
||||||
|
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0,
|
||||||
|
+ &tmp, &sum);
|
||||||
|
+ }
|
||||||
|
if (retval != 0) {
|
||||||
|
zap(tmp.data, tmp.length);
|
||||||
|
zap(outbuf, in->length);
|
||||||
|
@@ -248,7 +267,7 @@ krb5_error_code
|
||||||
|
kr_attr_encode(krb5_context ctx, const char *secret,
|
||||||
|
const unsigned char *auth, krad_attr type,
|
||||||
|
const krb5_data *in, unsigned char outbuf[MAX_ATTRSIZE],
|
||||||
|
- size_t *outlen)
|
||||||
|
+ size_t *outlen, krb5_boolean *is_fips)
|
||||||
|
{
|
||||||
|
krb5_error_code retval;
|
||||||
|
|
||||||
|
@@ -265,7 +284,8 @@ kr_attr_encode(krb5_context ctx, const char *secret,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen);
|
||||||
|
+ return attributes[type - 1].encode(ctx, secret, auth, in, outbuf, outlen,
|
||||||
|
+ is_fips);
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_error_code
|
||||||
|
@@ -274,6 +294,7 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
|
||||||
|
unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen)
|
||||||
|
{
|
||||||
|
krb5_error_code retval;
|
||||||
|
+ krb5_boolean ignored;
|
||||||
|
|
||||||
|
retval = kr_attr_valid(type, in);
|
||||||
|
if (retval != 0)
|
||||||
|
@@ -288,7 +309,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen);
|
||||||
|
+ return attributes[type - 1].decode(ctx, secret, auth, in, outbuf, outlen,
|
||||||
|
+ &ignored);
|
||||||
|
}
|
||||||
|
|
||||||
|
krad_attr
|
||||||
|
diff --git a/src/lib/krad/attrset.c b/src/lib/krad/attrset.c
|
||||||
|
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)
|
||||||
|
krb5_error_code
|
||||||
|
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||||
|
const unsigned char *auth,
|
||||||
|
- unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen)
|
||||||
|
+ unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
||||||
|
+ krb5_boolean *is_fips)
|
||||||
|
{
|
||||||
|
unsigned char buffer[MAX_ATTRSIZE];
|
||||||
|
krb5_error_code retval;
|
||||||
|
@@ -181,7 +182,7 @@ kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||||
|
|
||||||
|
K5_TAILQ_FOREACH(a, &set->list, list) {
|
||||||
|
retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
|
||||||
|
- buffer, &attrlen);
|
||||||
|
+ buffer, &attrlen, is_fips);
|
||||||
|
if (retval != 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
diff --git a/src/lib/krad/internal.h b/src/lib/krad/internal.h
|
||||||
|
index 7619563fc5..a17b6f39b1 100644
|
||||||
|
--- a/src/lib/krad/internal.h
|
||||||
|
+++ b/src/lib/krad/internal.h
|
||||||
|
@@ -39,6 +39,12 @@
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
+#include <openssl/crypto.h>
|
||||||
|
+
|
||||||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifndef UCHAR_MAX
|
||||||
|
#define UCHAR_MAX 255
|
||||||
|
#endif
|
||||||
|
@@ -49,6 +55,13 @@
|
||||||
|
|
||||||
|
typedef struct krad_remote_st krad_remote;
|
||||||
|
|
||||||
|
+struct krad_packet_st {
|
||||||
|
+ char buffer[KRAD_PACKET_SIZE_MAX];
|
||||||
|
+ krad_attrset *attrset;
|
||||||
|
+ krb5_data pkt;
|
||||||
|
+ krb5_boolean is_fips;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/* Validate constraints of an attribute. */
|
||||||
|
krb5_error_code
|
||||||
|
kr_attr_valid(krad_attr type, const krb5_data *data);
|
||||||
|
@@ -57,7 +70,8 @@ kr_attr_valid(krad_attr type, const krb5_data *data);
|
||||||
|
krb5_error_code
|
||||||
|
kr_attr_encode(krb5_context ctx, const char *secret, const unsigned char *auth,
|
||||||
|
krad_attr type, const krb5_data *in,
|
||||||
|
- unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen);
|
||||||
|
+ unsigned char outbuf[MAX_ATTRSIZE], size_t *outlen,
|
||||||
|
+ krb5_boolean *is_fips);
|
||||||
|
|
||||||
|
/* Decode an attribute. */
|
||||||
|
krb5_error_code
|
||||||
|
@@ -69,7 +83,8 @@ kr_attr_decode(krb5_context ctx, const char *secret, const unsigned char *auth,
|
||||||
|
krb5_error_code
|
||||||
|
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
||||||
|
const unsigned char *auth,
|
||||||
|
- unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen);
|
||||||
|
+ unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
||||||
|
+ krb5_boolean *is_fips);
|
||||||
|
|
||||||
|
/* Decode attributes from a buffer. */
|
||||||
|
krb5_error_code
|
||||||
|
@@ -156,4 +171,17 @@ gai_error_code(int err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static inline krb5_boolean
|
||||||
|
+kr_use_fips(krb5_context ctx)
|
||||||
|
+{
|
||||||
|
+ int val = 0;
|
||||||
|
+
|
||||||
|
+ if (!FIPS_mode())
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ (void)profile_get_boolean(ctx->profile, "libdefaults",
|
||||||
|
+ "radius_md5_fips_override", NULL, 0, &val);
|
||||||
|
+ return !val;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#endif /* INTERNAL_H_ */
|
||||||
|
diff --git a/src/lib/krad/packet.c b/src/lib/krad/packet.c
|
||||||
|
index c597174b65..fc2d248001 100644
|
||||||
|
--- a/src/lib/krad/packet.c
|
||||||
|
+++ b/src/lib/krad/packet.c
|
||||||
|
@@ -53,12 +53,6 @@ typedef unsigned char uchar;
|
||||||
|
#define pkt_auth(p) ((uchar *)offset(&(p)->pkt, OFFSET_AUTH))
|
||||||
|
#define pkt_attr(p) ((unsigned char *)offset(&(p)->pkt, OFFSET_ATTR))
|
||||||
|
|
||||||
|
-struct krad_packet_st {
|
||||||
|
- char buffer[KRAD_PACKET_SIZE_MAX];
|
||||||
|
- krad_attrset *attrset;
|
||||||
|
- krb5_data pkt;
|
||||||
|
-};
|
||||||
|
-
|
||||||
|
typedef struct {
|
||||||
|
uchar x[(UCHAR_MAX + 1) / 8];
|
||||||
|
} idmap;
|
||||||
|
@@ -187,8 +181,14 @@ auth_generate_response(krb5_context ctx, const char *secret,
|
||||||
|
memcpy(data.data + response->pkt.length, secret, strlen(secret));
|
||||||
|
|
||||||
|
/* Hash it. */
|
||||||
|
- retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
|
||||||
|
- &hash);
|
||||||
|
+ if (kr_use_fips(ctx)) {
|
||||||
|
+ /* This checksum does very little security-wise anyway, so don't
|
||||||
|
+ * taint. */
|
||||||
|
+ hash.contents = calloc(1, AUTH_FIELD_SIZE);
|
||||||
|
+ } else {
|
||||||
|
+ retval = krb5_c_make_checksum(ctx, CKSUMTYPE_RSA_MD5, NULL, 0, &data,
|
||||||
|
+ &hash);
|
||||||
|
+ }
|
||||||
|
free(data.data);
|
||||||
|
if (retval != 0)
|
||||||
|
return retval;
|
||||||
|
@@ -276,7 +276,7 @@ krad_packet_new_request(krb5_context ctx, const char *secret, krad_code code,
|
||||||
|
|
||||||
|
/* Encode the attributes. */
|
||||||
|
retval = kr_attrset_encode(set, secret, pkt_auth(pkt), pkt_attr(pkt),
|
||||||
|
- &attrset_len);
|
||||||
|
+ &attrset_len, &pkt->is_fips);
|
||||||
|
if (retval != 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
@@ -314,7 +314,7 @@ krad_packet_new_response(krb5_context ctx, const char *secret, krad_code code,
|
||||||
|
|
||||||
|
/* Encode the attributes. */
|
||||||
|
retval = kr_attrset_encode(set, secret, pkt_auth(request), pkt_attr(pkt),
|
||||||
|
- &attrset_len);
|
||||||
|
+ &attrset_len, &pkt->is_fips);
|
||||||
|
if (retval != 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
@@ -451,6 +451,8 @@ krad_packet_decode_response(krb5_context ctx, const char *secret,
|
||||||
|
const krb5_data *
|
||||||
|
krad_packet_encode(const krad_packet *pkt)
|
||||||
|
{
|
||||||
|
+ if (pkt->is_fips)
|
||||||
|
+ return NULL;
|
||||||
|
return &pkt->pkt;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
|
||||||
|
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)
|
||||||
|
request *r;
|
||||||
|
|
||||||
|
K5_TAILQ_FOREACH(r, &rr->list, list) {
|
||||||
|
- tmp = krad_packet_encode(r->request);
|
||||||
|
+ tmp = &r->request->pkt;
|
||||||
|
|
||||||
|
/* If the packet has already been sent, do nothing. */
|
||||||
|
if (r->sent == tmp->length)
|
||||||
|
@@ -359,7 +359,7 @@ on_io_read(krad_remote *rr)
|
||||||
|
if (req != NULL) {
|
||||||
|
K5_TAILQ_FOREACH(r, &rr->list, list) {
|
||||||
|
if (r->request == req &&
|
||||||
|
- r->sent == krad_packet_encode(req)->length) {
|
||||||
|
+ r->sent == req->pkt.length) {
|
||||||
|
request_finish(r, 0, rsp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -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;
|
||||||
|
+ else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL &&
|
||||||
|
+ rr->info->ai_family != AF_UNIX) {
|
||||||
|
+ /* This would expose cleartext passwords, so abort. */
|
||||||
|
+ retval = ESOCKTNOSUPPORT;
|
||||||
|
+ goto error;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
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 eb2a780c89..4d285ad9de 100644
|
||||||
|
--- a/src/lib/krad/t_attr.c
|
||||||
|
+++ b/src/lib/krad/t_attr.c
|
||||||
|
@@ -50,6 +50,7 @@ main()
|
||||||
|
const char *tmp;
|
||||||
|
krb5_data in;
|
||||||
|
size_t len;
|
||||||
|
+ krb5_boolean is_fips = FALSE;
|
||||||
|
|
||||||
|
noerror(krb5_init_context(&ctx));
|
||||||
|
|
||||||
|
@@ -73,7 +74,7 @@ main()
|
||||||
|
in = string2data((char *)decoded);
|
||||||
|
retval = kr_attr_encode(ctx, secret, auth,
|
||||||
|
krad_attr_name2num("User-Password"),
|
||||||
|
- &in, outbuf, &len);
|
||||||
|
+ &in, outbuf, &len, &is_fips);
|
||||||
|
insist(retval == 0);
|
||||||
|
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 7928335ca4..0f95762534 100644
|
||||||
|
--- a/src/lib/krad/t_attrset.c
|
||||||
|
+++ b/src/lib/krad/t_attrset.c
|
||||||
|
@@ -49,6 +49,7 @@ main()
|
||||||
|
krb5_context ctx;
|
||||||
|
size_t len = 0, encode_len;
|
||||||
|
krb5_data tmp;
|
||||||
|
+ krb5_boolean is_fips = FALSE;
|
||||||
|
|
||||||
|
noerror(krb5_init_context(&ctx));
|
||||||
|
noerror(krad_attrset_new(ctx, &set));
|
||||||
|
@@ -62,7 +63,8 @@ main()
|
||||||
|
noerror(krad_attrset_add(set, krad_attr_name2num("User-Password"), &tmp));
|
||||||
|
|
||||||
|
/* Encode attrset. */
|
||||||
|
- noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len));
|
||||||
|
+ noerror(kr_attrset_encode(set, "foo", auth, buffer, &encode_len,
|
||||||
|
+ &is_fips));
|
||||||
|
krad_attrset_free(set);
|
||||||
|
|
||||||
|
/* Manually encode User-Name. */
|
||||||
|
diff --git a/src/plugins/preauth/spake/spake_client.c b/src/plugins/preauth/spake/spake_client.c
|
||||||
|
index 00734a13b5..13c699071f 100644
|
||||||
|
--- a/src/plugins/preauth/spake/spake_client.c
|
||||||
|
+++ b/src/plugins/preauth/spake/spake_client.c
|
||||||
|
@@ -38,6 +38,12 @@
|
||||||
|
#include "groups.h"
|
||||||
|
#include <krb5/clpreauth_plugin.h>
|
||||||
|
|
||||||
|
+#include <openssl/crypto.h>
|
||||||
|
+
|
||||||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
typedef struct reqstate_st {
|
||||||
|
krb5_pa_spake *msg; /* set in prep_questions, used in process */
|
||||||
|
krb5_keyblock *initial_key;
|
||||||
|
@@ -375,6 +381,10 @@ clpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
|
||||||
|
|
||||||
|
if (maj_ver != 1)
|
||||||
|
return KRB5_PLUGIN_VER_NOTSUPP;
|
||||||
|
+
|
||||||
|
+ if (FIPS_mode())
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
vt = (krb5_clpreauth_vtable)vtable;
|
||||||
|
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 1a772d450f..3394f8a58e 100644
|
||||||
|
--- a/src/plugins/preauth/spake/spake_kdc.c
|
||||||
|
+++ b/src/plugins/preauth/spake/spake_kdc.c
|
||||||
|
@@ -41,6 +41,12 @@
|
||||||
|
|
||||||
|
#include <krb5/kdcpreauth_plugin.h>
|
||||||
|
|
||||||
|
+#include <openssl/crypto.h>
|
||||||
|
+
|
||||||
|
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* The SPAKE kdcpreauth module uses a secure cookie containing the following
|
||||||
|
* concatenated fields (all integer fields are big-endian):
|
||||||
|
@@ -551,6 +557,10 @@ kdcpreauth_spake_initvt(krb5_context context, int maj_ver, int min_ver,
|
||||||
|
|
||||||
|
if (maj_ver != 1)
|
||||||
|
return KRB5_PLUGIN_VER_NOTSUPP;
|
||||||
|
+
|
||||||
|
+ if (FIPS_mode())
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
vt = (krb5_kdcpreauth_vtable)vtable;
|
||||||
|
vt->name = "spake";
|
||||||
|
vt->pa_type_list = pa_types;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,82 @@
|
|||||||
|
From 813f3840c7b9f32c1d96dcd847be91fe545653eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Thu, 5 May 2022 17:15:12 +0200
|
||||||
|
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
|
||||||
|
network communication. However, FreeRadius requires connection on TCP or
|
||||||
|
UDP ports.
|
||||||
|
|
||||||
|
This commit allows TCP or UDP connections in FIPS mode if destination is
|
||||||
|
localhost.
|
||||||
|
|
||||||
|
Resolves: rhbz#2082189
|
||||||
|
---
|
||||||
|
src/lib/krad/remote.c | 35 +++++++++++++++++++++++++++++++++--
|
||||||
|
1 file changed, 33 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/lib/krad/remote.c b/src/lib/krad/remote.c
|
||||||
|
index 929f1cef67..063f17a613 100644
|
||||||
|
--- a/src/lib/krad/remote.c
|
||||||
|
+++ b/src/lib/krad/remote.c
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
@@ -74,6 +75,35 @@ on_io(verto_ctx *ctx, verto_ev *ev);
|
||||||
|
static void
|
||||||
|
on_timeout(verto_ctx *ctx, verto_ev *ev);
|
||||||
|
|
||||||
|
+static in_addr_t get_in_addr(struct addrinfo *info)
|
||||||
|
+{ return ((struct sockaddr_in *)(info->ai_addr))->sin_addr.s_addr; }
|
||||||
|
+
|
||||||
|
+static struct in6_addr *get_in6_addr(struct addrinfo *info)
|
||||||
|
+{ return &(((struct sockaddr_in6 *)(info->ai_addr))->sin6_addr); }
|
||||||
|
+
|
||||||
|
+static bool is_inet_localhost(struct addrinfo *info)
|
||||||
|
+{
|
||||||
|
+ struct addrinfo *p;
|
||||||
|
+
|
||||||
|
+ for (p = info; p; p = p->ai_next) {
|
||||||
|
+ switch (p->ai_family) {
|
||||||
|
+ case AF_INET:
|
||||||
|
+ if (IN_LOOPBACKNET != (get_in_addr(p) & IN_CLASSA_NET
|
||||||
|
+ >> IN_CLASSA_NSHIFT))
|
||||||
|
+ return false;
|
||||||
|
+ break;
|
||||||
|
+ case AF_INET6:
|
||||||
|
+ if (!IN6_IS_ADDR_LOOPBACK(get_in6_addr(p)))
|
||||||
|
+ return false;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Iterate over the set of outstanding packets. */
|
||||||
|
static const krad_packet *
|
||||||
|
iterator(request **out)
|
||||||
|
@@ -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;
|
||||||
|
- else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL &&
|
||||||
|
- rr->info->ai_family != AF_UNIX) {
|
||||||
|
+ else if (tmp->is_fips && rr->info->ai_family != AF_LOCAL
|
||||||
|
+ && rr->info->ai_family != AF_UNIX
|
||||||
|
+ && !is_inet_localhost(rr->info)) {
|
||||||
|
/* This would expose cleartext passwords, so abort. */
|
||||||
|
retval = ESOCKTNOSUPPORT;
|
||||||
|
goto error;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,201 @@
|
|||||||
|
From c0a6d66e98e62b94d72bb51b8d6c00130a951215 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
|
||||||
|
|
||||||
|
[ghudson@mit.edu: added documentation of configure variable and doc
|
||||||
|
substitution; shortened commit message]
|
||||||
|
|
||||||
|
ticket: 9058 (new)
|
||||||
|
---
|
||||||
|
doc/admin/conf_files/krb5_conf.rst | 2 +-
|
||||||
|
doc/build/options2configure.rst | 3 +++
|
||||||
|
doc/conf.py | 3 +++
|
||||||
|
doc/mitK5defaults.rst | 25 +++++++++++++------------
|
||||||
|
src/configure.ac | 8 ++++++++
|
||||||
|
src/doc/Makefile.in | 2 ++
|
||||||
|
src/man/Makefile.in | 4 +++-
|
||||||
|
src/man/krb5.conf.man | 2 +-
|
||||||
|
src/plugins/preauth/pkinit/pkinit.h | 1 -
|
||||||
|
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 2a4962069f..a33711d918 100644
|
||||||
|
--- a/doc/admin/conf_files/krb5_conf.rst
|
||||||
|
+++ b/doc/admin/conf_files/krb5_conf.rst
|
||||||
|
@@ -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
|
||||||
|
- module-name is specified, the default is ``opensc-pkcs11.so``.
|
||||||
|
+ module-name is specified, the default is |pkcs11_modname|.
|
||||||
|
``slotid=`` and/or ``token=`` may be specified to force the use of
|
||||||
|
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 9e355dc2c5..e879b18bd2 100644
|
||||||
|
--- a/doc/build/options2configure.rst
|
||||||
|
+++ b/doc/build/options2configure.rst
|
||||||
|
@@ -137,6 +137,9 @@ Environment variables
|
||||||
|
This option allows one to specify libraries to be passed to the
|
||||||
|
linker (e.g., ``-l<library>``)
|
||||||
|
|
||||||
|
+**PKCS11_MODNAME=**\ *library*
|
||||||
|
+ Override the built-in default PKCS11 library name.
|
||||||
|
+
|
||||||
|
**SS_LIB=**\ *libs*...
|
||||||
|
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 12168fa695..0ab5ff9606 100644
|
||||||
|
--- a/doc/conf.py
|
||||||
|
+++ b/doc/conf.py
|
||||||
|
@@ -242,6 +242,7 @@ if 'mansubs' in tags:
|
||||||
|
ccache = '``@CCNAME@``'
|
||||||
|
keytab = '``@KTNAME@``'
|
||||||
|
ckeytab = '``@CKTNAME@``'
|
||||||
|
+ pkcs11_modname = '``@PKCS11MOD@``'
|
||||||
|
elif 'pathsubs' in tags:
|
||||||
|
# Read configured paths from a file produced by the build system.
|
||||||
|
exec(open("paths.py").read())
|
||||||
|
@@ -255,6 +256,7 @@ else:
|
||||||
|
ccache = ':ref:`DEFCCNAME <paths>`'
|
||||||
|
keytab = ':ref:`DEFKTNAME <paths>`'
|
||||||
|
ckeytab = ':ref:`DEFCKTNAME <paths>`'
|
||||||
|
+ pkcs11_modname = ':ref:`PKCS11_MODNAME <paths>`'
|
||||||
|
|
||||||
|
rst_epilog = '\n'
|
||||||
|
|
||||||
|
@@ -275,6 +277,7 @@ else:
|
||||||
|
rst_epilog += '.. |ccache| replace:: %s\n' % ccache
|
||||||
|
rst_epilog += '.. |keytab| replace:: %s\n' % keytab
|
||||||
|
rst_epilog += '.. |ckeytab| replace:: %s\n' % ckeytab
|
||||||
|
+ rst_epilog += '.. |pkcs11_modname| replace:: %s\n' % pkcs11_modname
|
||||||
|
rst_epilog += '''
|
||||||
|
.. |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 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
|
||||||
|
operating system, the paths are generally chosen to match the
|
||||||
|
operating system's filesystem layout.
|
||||||
|
|
||||||
|
-========================== ============= =========================== ===========================
|
||||||
|
-Description Symbolic name Custom build path Typical OS path
|
||||||
|
-========================== ============= =========================== ===========================
|
||||||
|
-User programs BINDIR ``/usr/local/bin`` ``/usr/bin``
|
||||||
|
-Libraries and plugins LIBDIR ``/usr/local/lib`` ``/usr/lib``
|
||||||
|
-Parent of KDC state dir LOCALSTATEDIR ``/usr/local/var`` ``/var``
|
||||||
|
-Parent of KDC runtime dir RUNSTATEDIR ``/usr/local/var/run`` ``/run``
|
||||||
|
-Administrative programs SBINDIR ``/usr/local/sbin`` ``/usr/sbin``
|
||||||
|
-Alternate krb5.conf dir SYSCONFDIR ``/usr/local/etc`` ``/etc``
|
||||||
|
-Default ccache name DEFCCNAME ``FILE:/tmp/krb5cc_%{uid}`` ``FILE:/tmp/krb5cc_%{uid}``
|
||||||
|
-Default keytab name DEFKTNAME ``FILE:/etc/krb5.keytab`` ``FILE:/etc/krb5.keytab``
|
||||||
|
-========================== ============= =========================== ===========================
|
||||||
|
+========================== ============== =========================== ===========================
|
||||||
|
+Description Symbolic name Custom build path Typical OS path
|
||||||
|
+========================== ============== =========================== ===========================
|
||||||
|
+User programs BINDIR ``/usr/local/bin`` ``/usr/bin``
|
||||||
|
+Libraries and plugins LIBDIR ``/usr/local/lib`` ``/usr/lib``
|
||||||
|
+Parent of KDC state dir LOCALSTATEDIR ``/usr/local/var`` ``/var``
|
||||||
|
+Parent of KDC runtime dir RUNSTATEDIR ``/usr/local/var/run`` ``/run``
|
||||||
|
+Administrative programs SBINDIR ``/usr/local/sbin`` ``/usr/sbin``
|
||||||
|
+Alternate krb5.conf dir SYSCONFDIR ``/usr/local/etc`` ``/etc``
|
||||||
|
+Default ccache name DEFCCNAME ``FILE:/tmp/krb5cc_%{uid}`` ``FILE:/tmp/krb5cc_%{uid}``
|
||||||
|
+Default keytab name DEFKTNAME ``FILE:/etc/krb5.keytab`` ``FILE:/etc/krb5.keytab``
|
||||||
|
+Default PKCS11 module PKCS11_MODNAME ``opensc-pkcs11.so`` ``opensc-pkcs11.so``
|
||||||
|
+========================== ============== =========================== ===========================
|
||||||
|
|
||||||
|
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 8dc864718d..9774cb71ae 100644
|
||||||
|
--- a/src/configure.ac
|
||||||
|
+++ b/src/configure.ac
|
||||||
|
@@ -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])
|
||||||
|
|
||||||
|
+AC_ARG_VAR(PKCS11_MODNAME, [Default PKCS11 module name])
|
||||||
|
+if test "${PKCS11_MODNAME+set}" != set; then
|
||||||
|
+ PKCS11_MODNAME=opensc-pkcs11.so
|
||||||
|
+fi
|
||||||
|
+AC_MSG_NOTICE([Default PKCS11 module name: $PKCS11_MODNAME])
|
||||||
|
+AC_DEFINE_UNQUOTED(PKCS11_MODNAME, ["$PKCS11_MODNAME"],
|
||||||
|
+ [Default PKCS11 module name])
|
||||||
|
+
|
||||||
|
AC_CONFIG_FILES([build-tools/krb5-config], [chmod +x build-tools/krb5-config])
|
||||||
|
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 379bc36511..a1b0cff0a4 100644
|
||||||
|
--- a/src/doc/Makefile.in
|
||||||
|
+++ b/src/doc/Makefile.in
|
||||||
|
@@ -10,6 +10,7 @@ sysconfdir=@sysconfdir@
|
||||||
|
DEFCCNAME=@DEFCCNAME@
|
||||||
|
DEFKTNAME=@DEFKTNAME@
|
||||||
|
DEFCKTNAME=@DEFCKTNAME@
|
||||||
|
+PKCS11_MODNAME=@PKCS11_MODNAME@
|
||||||
|
|
||||||
|
RST_SOURCES= _static \
|
||||||
|
_templates \
|
||||||
|
@@ -118,6 +119,7 @@ paths.py:
|
||||||
|
echo 'ccache = "``$(DEFCCNAME)``"' >> $@
|
||||||
|
echo 'keytab = "``$(DEFKTNAME)``"' >> $@
|
||||||
|
echo 'ckeytab = "``$(DEFCKTNAME)``"' >> $@
|
||||||
|
+ echo 'pkcs11_modname = "``$(PKCS11_MODNAME)``"' >> $@
|
||||||
|
|
||||||
|
# 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 00b1b2de06..85cae0914e 100644
|
||||||
|
--- a/src/man/Makefile.in
|
||||||
|
+++ b/src/man/Makefile.in
|
||||||
|
@@ -8,6 +8,7 @@ sysconfdir=@sysconfdir@
|
||||||
|
DEFCCNAME=@DEFCCNAME@
|
||||||
|
DEFKTNAME=@DEFKTNAME@
|
||||||
|
DEFCKTNAME=@DEFCKTNAME@
|
||||||
|
+PKCS11_MODNAME=@PKCS11_MODNAME@
|
||||||
|
|
||||||
|
MANSUBS=k5identity.sub k5login.sub k5srvutil.sub kadm5.acl.sub kadmin.sub \
|
||||||
|
kadmind.sub kdb5_ldap_util.sub kdb5_util.sub kdc.conf.sub \
|
||||||
|
@@ -47,7 +48,8 @@ $(docsrc)/version.py: $(top_srcdir)/patchlevel.h
|
||||||
|
-e 's|@SYSCONFDIR@|$(sysconfdir)|g' \
|
||||||
|
-e 's|@CCNAME@|$(DEFCCNAME)|g' \
|
||||||
|
-e 's|@KTNAME@|$(DEFKTNAME)|g' \
|
||||||
|
- -e 's|@CKTNAME@|$(DEFCKTNAME)|g' $? > $@
|
||||||
|
+ -e 's|@CKTNAME@|$(DEFCKTNAME)|g' \
|
||||||
|
+ -e 's|@PKCS11MOD@|$(PKCS11_MODNAME)|g' $? > $@
|
||||||
|
|
||||||
|
all: $(MANSUBS)
|
||||||
|
|
||||||
|
diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man
|
||||||
|
index 51acb38815..fd2c6f2bc4 100644
|
||||||
|
--- a/src/man/krb5.conf.man
|
||||||
|
+++ b/src/man/krb5.conf.man
|
||||||
|
@@ -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
|
||||||
|
-module\-name is specified, the default is \fBopensc\-pkcs11.so\fP\&.
|
||||||
|
+module\-name is specified, the default is \fB@PKCS11MOD@\fP\&.
|
||||||
|
\fBslotid=\fP and/or \fBtoken=\fP may be specified to force the use of
|
||||||
|
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 8135535e2c..66f92d8f03 100644
|
||||||
|
--- a/src/plugins/preauth/pkinit/pkinit.h
|
||||||
|
+++ b/src/plugins/preauth/pkinit/pkinit.h
|
||||||
|
@@ -42,7 +42,6 @@
|
||||||
|
#ifndef WITHOUT_PKCS11
|
||||||
|
#include "pkcs11.h"
|
||||||
|
|
||||||
|
-#define PKCS11_MODNAME "opensc-pkcs11.so"
|
||||||
|
#define PK_SIGLEN_GUESS 1000
|
||||||
|
#define PK_NOSLOT 999999
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,159 @@
|
|||||||
|
From 3cc9ef956342f55cc9ae283e30fc3ba080248cf3 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
|
||||||
|
|
@ -0,0 +1,622 @@
|
|||||||
|
From 593109802b52e3f89c3a65436bfdba78f8c517c4 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
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From 75f71ace74449a6e5154314229bfa61960cd326c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Thu, 28 Jul 2022 15:20:12 +0200
|
||||||
|
Subject: [PATCH] Update error checking for OpenSSL CMS_verify
|
||||||
|
|
||||||
|
The code for CMS data verification was initially written for OpenSSL's
|
||||||
|
PKCS7_verify() function. It now uses CMS_verify(), but error handling
|
||||||
|
is still done using PKCS7_verify() error identifiers. Update the
|
||||||
|
recognized error codes so that the KDC generates
|
||||||
|
KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED errors when appropriate.
|
||||||
|
Use ERR_peek_last_error() to observe the error generated closest to
|
||||||
|
the API surface.
|
||||||
|
|
||||||
|
[ghudson@mit.edu: edited commit message]
|
||||||
|
|
||||||
|
ticket: 9069 (new)
|
||||||
|
tags: pullup
|
||||||
|
target_version: 1.20-next
|
||||||
|
---
|
||||||
|
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 9 ++++++---
|
||||||
|
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
index 1c2aa02827..16edf15cb2 100644
|
||||||
|
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
@@ -2102,12 +2102,15 @@ cms_signeddata_verify(krb5_context context,
|
||||||
|
goto cleanup;
|
||||||
|
out = BIO_new(BIO_s_mem());
|
||||||
|
if (CMS_verify(cms, NULL, store, NULL, out, flags) == 0) {
|
||||||
|
- unsigned long err = ERR_peek_error();
|
||||||
|
+ unsigned long err = ERR_peek_last_error();
|
||||||
|
switch(ERR_GET_REASON(err)) {
|
||||||
|
- case PKCS7_R_DIGEST_FAILURE:
|
||||||
|
+ case RSA_R_DIGEST_NOT_ALLOWED:
|
||||||
|
+ case CMS_R_UNKNOWN_DIGEST_ALGORITHM:
|
||||||
|
+ case CMS_R_NO_MATCHING_DIGEST:
|
||||||
|
+ case CMS_R_NO_MATCHING_SIGNATURE:
|
||||||
|
retval = KRB5KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED;
|
||||||
|
break;
|
||||||
|
- case PKCS7_R_SIGNATURE_FAILURE:
|
||||||
|
+ case CMS_R_VERIFICATION_FAILURE:
|
||||||
|
default:
|
||||||
|
retval = KRB5KDC_ERR_INVALID_SIG;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
From 3f8a3b57cf0e057635e570d5038fb52c19ca5744 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Fri, 19 Aug 2022 10:34:52 +0200
|
||||||
|
Subject: [PATCH] [downstream] Catch SHA-1 digest disallowed error for
|
||||||
|
PKINIT
|
||||||
|
|
||||||
|
An OpenSSL patch causes EVP_R_INVALID_DIGEST error to be raised if
|
||||||
|
CMS_verify is called to verify a SHA-1 signature. If this error is
|
||||||
|
caught, it will now return KDC_ERR_DIGEST_IN_SIGNED_DATA_NOT_ACCEPTED.
|
||||||
|
---
|
||||||
|
src/plugins/preauth/pkinit/pkinit_crypto_openssl.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
index 16edf15cb2..bfa3fe8e91 100644
|
||||||
|
--- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
|
||||||
|
@@ -2104,6 +2104,7 @@ cms_signeddata_verify(krb5_context context,
|
||||||
|
if (CMS_verify(cms, NULL, store, NULL, out, flags) == 0) {
|
||||||
|
unsigned long err = ERR_peek_last_error();
|
||||||
|
switch(ERR_GET_REASON(err)) {
|
||||||
|
+ case EVP_R_INVALID_DIGEST:
|
||||||
|
case RSA_R_DIGEST_NOT_ALLOWED:
|
||||||
|
case CMS_R_UNKNOWN_DIGEST_ALGORITHM:
|
||||||
|
case CMS_R_NO_MATCHING_DIGEST:
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,239 @@
|
|||||||
|
From 6ba011d89f9cf4661eb7110bf810cfdb514b69fa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Hudson <ghudson@mit.edu>
|
||||||
|
Date: Mon, 19 Sep 2022 15:18:50 -0400
|
||||||
|
Subject: [PATCH] Add and use ts_interval() helper
|
||||||
|
|
||||||
|
ts_delta() returns a signed result, which cannot hold an interval
|
||||||
|
larger than 2^31-1 seconds. Intervals like this have been seen when
|
||||||
|
admins set password expiration dates more than 68 years in the future.
|
||||||
|
|
||||||
|
Add a second helper ts_interval() which returns a signed result, and
|
||||||
|
has the arguments reversed so that the start time is first. Use it in
|
||||||
|
warn_pw_expiry() to handle the password expiration case, in the GSS
|
||||||
|
krb5 mech where we return an unsigned context or credential lifetime
|
||||||
|
to the caller, and in the KEYRING ccache type where we compute an
|
||||||
|
unsigned keyring timeout.
|
||||||
|
|
||||||
|
ticket: 9071 (new)
|
||||||
|
---
|
||||||
|
src/include/k5-int.h | 9 +++++++++
|
||||||
|
src/lib/gssapi/krb5/accept_sec_context.c | 10 ++++++----
|
||||||
|
src/lib/gssapi/krb5/acquire_cred.c | 3 +--
|
||||||
|
src/lib/gssapi/krb5/context_time.c | 2 +-
|
||||||
|
src/lib/gssapi/krb5/init_sec_context.c | 4 ++--
|
||||||
|
src/lib/gssapi/krb5/inq_context.c | 2 +-
|
||||||
|
src/lib/gssapi/krb5/inq_cred.c | 2 +-
|
||||||
|
src/lib/gssapi/krb5/s4u_gss_glue.c | 2 +-
|
||||||
|
src/lib/krb5/ccache/cc_keyring.c | 4 ++--
|
||||||
|
src/lib/krb5/krb/get_in_tkt.c | 15 +++++++--------
|
||||||
|
10 files changed, 31 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
|
||||||
|
index c3aecba7d4..768110e5ef 100644
|
||||||
|
--- a/src/include/k5-int.h
|
||||||
|
+++ b/src/include/k5-int.h
|
||||||
|
@@ -2325,6 +2325,15 @@ ts_delta(krb5_timestamp a, krb5_timestamp b)
|
||||||
|
return (krb5_deltat)((uint32_t)a - (uint32_t)b);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Return (end - start) as an unsigned 32-bit value, or 0 if start > end. */
|
||||||
|
+static inline uint32_t
|
||||||
|
+ts_interval(krb5_timestamp start, krb5_timestamp end)
|
||||||
|
+{
|
||||||
|
+ if ((uint32_t)start > (uint32_t)end)
|
||||||
|
+ return 0;
|
||||||
|
+ return (uint32_t)end - (uint32_t)start;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Increment a timestamp by a signed 32-bit interval, without relying on
|
||||||
|
* undefined behavior. */
|
||||||
|
static inline krb5_timestamp
|
||||||
|
diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||||
|
index 1bc807172b..7de2c9fd77 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/accept_sec_context.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/accept_sec_context.c
|
||||||
|
@@ -353,8 +353,8 @@ kg_accept_dce(minor_status, context_handle, verifier_cred_handle,
|
||||||
|
*mech_type = ctx->mech_used;
|
||||||
|
|
||||||
|
if (time_rec) {
|
||||||
|
- *time_rec = ts_delta(ctx->krb_times.endtime, now) +
|
||||||
|
- ctx->k5_context->clockskew;
|
||||||
|
+ *time_rec = ts_interval(now - ctx->k5_context->clockskew,
|
||||||
|
+ ctx->krb_times.endtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Never return GSS_C_DELEG_FLAG since we don't support DCE credential
|
||||||
|
@@ -1151,8 +1151,10 @@ kg_accept_krb5(minor_status, context_handle,
|
||||||
|
|
||||||
|
/* Add the maximum allowable clock skew as a grace period for context
|
||||||
|
* expiration, just as we do for the ticket. */
|
||||||
|
- if (time_rec)
|
||||||
|
- *time_rec = ts_delta(ctx->krb_times.endtime, now) + context->clockskew;
|
||||||
|
+ if (time_rec) {
|
||||||
|
+ *time_rec = ts_interval(now - context->clockskew,
|
||||||
|
+ ctx->krb_times.endtime);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (ret_flags)
|
||||||
|
*ret_flags = ctx->gss_flags;
|
||||||
|
diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
|
||||||
|
index e226a02692..006eba114d 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/acquire_cred.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/acquire_cred.c
|
||||||
|
@@ -879,8 +879,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
|
||||||
|
GSS_C_NO_NAME);
|
||||||
|
if (GSS_ERROR(ret))
|
||||||
|
goto error_out;
|
||||||
|
- *time_rec = ts_after(cred->expire, now) ?
|
||||||
|
- ts_delta(cred->expire, now) : 0;
|
||||||
|
+ *time_rec = ts_interval(now, cred->expire);
|
||||||
|
k5_mutex_unlock(&cred->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c
|
||||||
|
index 1fdb5a16f2..5469d8154c 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/context_time.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/context_time.c
|
||||||
|
@@ -51,7 +51,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec)
|
||||||
|
return(GSS_S_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
- lifetime = ts_delta(ctx->krb_times.endtime, now);
|
||||||
|
+ lifetime = ts_interval(now, ctx->krb_times.endtime);
|
||||||
|
if (!ctx->initiate)
|
||||||
|
lifetime += ctx->k5_context->clockskew;
|
||||||
|
if (lifetime <= 0) {
|
||||||
|
diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
|
||||||
|
index ea87cf6432..f0f094ccb7 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/init_sec_context.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/init_sec_context.c
|
||||||
|
@@ -664,7 +664,7 @@ kg_new_connection(
|
||||||
|
if (time_rec) {
|
||||||
|
if ((code = krb5_timeofday(context, &now)))
|
||||||
|
goto cleanup;
|
||||||
|
- *time_rec = ts_delta(ctx->krb_times.endtime, now);
|
||||||
|
+ *time_rec = ts_interval(now, ctx->krb_times.endtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the other returns */
|
||||||
|
@@ -878,7 +878,7 @@ mutual_auth(
|
||||||
|
if (time_rec) {
|
||||||
|
if ((code = krb5_timeofday(context, &now)))
|
||||||
|
goto fail;
|
||||||
|
- *time_rec = ts_delta(ctx->krb_times.endtime, now);
|
||||||
|
+ *time_rec = ts_interval(now, ctx->krb_times.endtime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret_flags)
|
||||||
|
diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c
|
||||||
|
index cac024da1f..51c484fdfe 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/inq_context.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/inq_context.c
|
||||||
|
@@ -120,7 +120,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
|
||||||
|
|
||||||
|
/* Add the maximum allowable clock skew as a grace period for context
|
||||||
|
* expiration, just as we do for the ticket during authentication. */
|
||||||
|
- lifetime = ts_delta(ctx->krb_times.endtime, now);
|
||||||
|
+ lifetime = ts_interval(now, ctx->krb_times.endtime);
|
||||||
|
if (!ctx->initiate)
|
||||||
|
lifetime += context->clockskew;
|
||||||
|
if (lifetime < 0)
|
||||||
|
diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c
|
||||||
|
index bb63b726c8..0e675959a3 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/inq_cred.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/inq_cred.c
|
||||||
|
@@ -131,7 +131,7 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cred->expire != 0) {
|
||||||
|
- lifetime = ts_delta(cred->expire, now);
|
||||||
|
+ lifetime = ts_interval(now, cred->expire);
|
||||||
|
if (lifetime < 0)
|
||||||
|
lifetime = 0;
|
||||||
|
}
|
||||||
|
diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c
|
||||||
|
index 7dcfe4e1eb..fa7f980af7 100644
|
||||||
|
--- a/src/lib/gssapi/krb5/s4u_gss_glue.c
|
||||||
|
+++ b/src/lib/gssapi/krb5/s4u_gss_glue.c
|
||||||
|
@@ -279,7 +279,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
|
||||||
|
if (code != 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
- *time_rec = ts_delta(cred->expire, now);
|
||||||
|
+ *time_rec = ts_interval(now, cred->expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
major_status = GSS_S_COMPLETE;
|
||||||
|
diff --git a/src/lib/krb5/ccache/cc_keyring.c b/src/lib/krb5/ccache/cc_keyring.c
|
||||||
|
index ebef37d607..1dadeef64f 100644
|
||||||
|
--- a/src/lib/krb5/ccache/cc_keyring.c
|
||||||
|
+++ b/src/lib/krb5/ccache/cc_keyring.c
|
||||||
|
@@ -762,7 +762,7 @@ update_keyring_expiration(krb5_context context, krb5_ccache id)
|
||||||
|
|
||||||
|
/* Setting the timeout to zero would reset the timeout, so we set it to one
|
||||||
|
* second instead if creds are already expired. */
|
||||||
|
- timeout = ts_after(endtime, now) ? ts_delta(endtime, now) : 1;
|
||||||
|
+ timeout = ts_after(endtime, now) ? ts_interval(now, endtime) : 1;
|
||||||
|
(void)keyctl_set_timeout(data->cache_id, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1343,7 +1343,7 @@ krcc_store(krb5_context context, krb5_ccache id, krb5_creds *creds)
|
||||||
|
|
||||||
|
if (ts_after(creds->times.endtime, now)) {
|
||||||
|
(void)keyctl_set_timeout(cred_key,
|
||||||
|
- ts_delta(creds->times.endtime, now));
|
||||||
|
+ ts_interval(now, creds->times.endtime));
|
||||||
|
}
|
||||||
|
|
||||||
|
update_keyring_expiration(context, id);
|
||||||
|
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
|
||||||
|
index 8b5ab595e9..1b420a3ac2 100644
|
||||||
|
--- a/src/lib/krb5/krb/get_in_tkt.c
|
||||||
|
+++ b/src/lib/krb5/krb/get_in_tkt.c
|
||||||
|
@@ -1522,7 +1522,7 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||||
|
void *expire_data;
|
||||||
|
krb5_timestamp pw_exp, acct_exp, now;
|
||||||
|
krb5_boolean is_last_req;
|
||||||
|
- krb5_deltat delta;
|
||||||
|
+ uint32_t interval;
|
||||||
|
char ts[256], banner[1024];
|
||||||
|
|
||||||
|
if (as_reply == NULL || as_reply->enc_part2 == NULL)
|
||||||
|
@@ -1553,8 +1553,8 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||||
|
ret = krb5_timeofday(context, &now);
|
||||||
|
if (ret != 0)
|
||||||
|
return;
|
||||||
|
- if (!is_last_req &&
|
||||||
|
- (ts_after(now, pw_exp) || ts_delta(pw_exp, now) > 7 * 24 * 60 * 60))
|
||||||
|
+ interval = ts_interval(now, pw_exp);
|
||||||
|
+ if (!is_last_req && (!interval || interval > 7 * 24 * 60 * 60))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!prompter)
|
||||||
|
@@ -1564,19 +1564,18 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options,
|
||||||
|
if (ret != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- delta = ts_delta(pw_exp, now);
|
||||||
|
- if (delta < 3600) {
|
||||||
|
+ if (interval < 3600) {
|
||||||
|
snprintf(banner, sizeof(banner),
|
||||||
|
_("Warning: Your password will expire in less than one hour "
|
||||||
|
"on %s"), ts);
|
||||||
|
- } else if (delta < 86400 * 2) {
|
||||||
|
+ } else if (interval < 86400 * 2) {
|
||||||
|
snprintf(banner, sizeof(banner),
|
||||||
|
_("Warning: Your password will expire in %d hour%s on %s"),
|
||||||
|
- delta / 3600, delta < 7200 ? "" : "s", ts);
|
||||||
|
+ interval / 3600, interval < 7200 ? "" : "s", ts);
|
||||||
|
} else {
|
||||||
|
snprintf(banner, sizeof(banner),
|
||||||
|
_("Warning: Your password will expire in %d days on %s"),
|
||||||
|
- delta / 86400, ts);
|
||||||
|
+ interval / 86400, ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PROMPTER_INVOCATION */
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,41 @@
|
|||||||
|
From 9aa12e932f08651785519890896647069e7a30b1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Wed, 7 Dec 2022 13:22:42 +0100
|
||||||
|
Subject: [PATCH] [downstream] Make tests compatible with
|
||||||
|
sssd_krb5_locator_plugin.so
|
||||||
|
|
||||||
|
The sssd_krb5_locator_plugin.so plugin provided by sssd-client conflicts
|
||||||
|
with the upstream test t_discover_uri.py. The test has to be modified in
|
||||||
|
order to avoid false positive.
|
||||||
|
---
|
||||||
|
src/lib/krb5/os/t_discover_uri.py | 9 ++++++++-
|
||||||
|
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/lib/krb5/os/t_discover_uri.py b/src/lib/krb5/os/t_discover_uri.py
|
||||||
|
index 87bac17929..26bc95a8dc 100644
|
||||||
|
--- a/src/lib/krb5/os/t_discover_uri.py
|
||||||
|
+++ b/src/lib/krb5/os/t_discover_uri.py
|
||||||
|
@@ -1,3 +1,4 @@
|
||||||
|
+from os.path import exists
|
||||||
|
from k5test import *
|
||||||
|
|
||||||
|
entries = ('URI _kerberos.TEST krb5srv::kkdcp:https://kdc1 1 1\n',
|
||||||
|
@@ -37,8 +38,14 @@ realm.env['RESOLV_WRAPPER_HOSTS'] = hosts_filename
|
||||||
|
out = realm.run(['./t_locate_kdc', 'TEST'], env=realm.env)
|
||||||
|
l = out.splitlines()
|
||||||
|
|
||||||
|
+if (exists('/usr/lib/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so')
|
||||||
|
+ or exists('/usr/lib64/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so')):
|
||||||
|
+ line_range = range(6, 14)
|
||||||
|
+else:
|
||||||
|
+ line_range = range(4, 12)
|
||||||
|
+
|
||||||
|
j = 0
|
||||||
|
-for i in range(4, 12):
|
||||||
|
+for i in line_range:
|
||||||
|
if l[i].strip() != expected[j]:
|
||||||
|
fail('URI answers do not match')
|
||||||
|
j += 1
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From fb13766f8fbd78acfcf7a150332a4e5474e4f52a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Mon, 9 Jan 2023 22:39:52 +0100
|
||||||
|
Subject: [PATCH] [downstream] Do not set root as ksu file owner
|
||||||
|
|
||||||
|
Upstream Makefile uses the install command to set root as owner of the
|
||||||
|
ksu executable file. However, this is no longer supported on latest
|
||||||
|
versions of the Mock build environment.
|
||||||
|
|
||||||
|
In case of ksu, the owner, group, and mode are already set using %attr()
|
||||||
|
in the specfile.
|
||||||
|
---
|
||||||
|
src/config/pre.in | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/config/pre.in b/src/config/pre.in
|
||||||
|
index 7eaa2f351c..e9ae71471e 100644
|
||||||
|
--- a/src/config/pre.in
|
||||||
|
+++ b/src/config/pre.in
|
||||||
|
@@ -185,7 +185,7 @@ INSTALL_PROGRAM=@INSTALL_PROGRAM@ $(INSTALL_STRIP)
|
||||||
|
INSTALL_SCRIPT=@INSTALL_PROGRAM@
|
||||||
|
INSTALL_DATA=@INSTALL_DATA@
|
||||||
|
INSTALL_SHLIB=@INSTALL_SHLIB@
|
||||||
|
-INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
|
||||||
|
+INSTALL_SETUID=$(INSTALL)
|
||||||
|
## This is needed because autoconf will sometimes define @exec_prefix@ to be
|
||||||
|
## ${prefix}.
|
||||||
|
prefix=@prefix@
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,165 @@
|
|||||||
|
From 6aea69170c2064aaea73ad3283b6d7dd0cae47e1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Thu, 19 Jan 2023 19:22:27 +0100
|
||||||
|
Subject: [PATCH] [downstream] Allow KRB5KDF, MD5, and MD4 in FIPS mode
|
||||||
|
|
||||||
|
OpenSSL's restrictions to use KRB5KDF, MD5, and MD4 in FIPS mode are
|
||||||
|
bypassed in case AES SHA-1 HMAC or RC4 encryption types are allowed by
|
||||||
|
the crypto policy.
|
||||||
|
---
|
||||||
|
.../crypto/openssl/hash_provider/hash_evp.c | 97 +++++++++++++++++--
|
||||||
|
src/lib/crypto/openssl/kdf.c | 2 +-
|
||||||
|
2 files changed, 89 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/lib/crypto/openssl/hash_provider/hash_evp.c b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
index 11659908bb..eb2e693e9f 100644
|
||||||
|
--- a/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
+++ b/src/lib/crypto/openssl/hash_provider/hash_evp.c
|
||||||
|
@@ -44,6 +44,49 @@
|
||||||
|
#define EVP_MD_CTX_free EVP_MD_CTX_destroy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#include <openssl/provider.h>
|
||||||
|
+#include <openssl/fips.h>
|
||||||
|
+#include <threads.h>
|
||||||
|
+
|
||||||
|
+typedef struct ossl_lib_md_context {
|
||||||
|
+ OSSL_LIB_CTX *libctx;
|
||||||
|
+ OSSL_PROVIDER *default_provider;
|
||||||
|
+ OSSL_PROVIDER *legacy_provider;
|
||||||
|
+} ossl_md_context_t;
|
||||||
|
+
|
||||||
|
+static thread_local ossl_md_context_t *ossl_md_ctx = NULL;
|
||||||
|
+
|
||||||
|
+static krb5_error_code
|
||||||
|
+init_ossl_md_ctx(ossl_md_context_t *ctx, const char *algo)
|
||||||
|
+{
|
||||||
|
+ ctx->libctx = OSSL_LIB_CTX_new();
|
||||||
|
+ if (!ctx->libctx)
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
+ /* Load both legacy and default provider as both may be needed. */
|
||||||
|
+ ctx->default_provider = OSSL_PROVIDER_load(ctx->libctx, "default");
|
||||||
|
+ ctx->legacy_provider = OSSL_PROVIDER_load(ctx->libctx, "legacy");
|
||||||
|
+
|
||||||
|
+ if (!(ctx->default_provider && ctx->legacy_provider))
|
||||||
|
+ return KRB5_CRYPTO_INTERNAL;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+deinit_ossl_ctx(ossl_md_context_t *ctx)
|
||||||
|
+{
|
||||||
|
+ if (ctx->legacy_provider)
|
||||||
|
+ OSSL_PROVIDER_unload(ctx->legacy_provider);
|
||||||
|
+
|
||||||
|
+ if (ctx->default_provider)
|
||||||
|
+ OSSL_PROVIDER_unload(ctx->default_provider);
|
||||||
|
+
|
||||||
|
+ if (ctx->libctx)
|
||||||
|
+ OSSL_LIB_CTX_free(ctx->libctx);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
static krb5_error_code
|
||||||
|
hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
krb5_data *output)
|
||||||
|
@@ -60,11 +103,6 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
if (ctx == NULL)
|
||||||
|
return ENOMEM;
|
||||||
|
|
||||||
|
- if (type == EVP_md4() || type == EVP_md5()) {
|
||||||
|
- /* See comments below in hash_md4() and hash_md5(). */
|
||||||
|
- EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
ok = EVP_DigestInit_ex(ctx, type, NULL);
|
||||||
|
for (i = 0; i < num_data; i++) {
|
||||||
|
if (!SIGN_IOV(&data[i]))
|
||||||
|
@@ -77,6 +115,43 @@ hash_evp(const EVP_MD *type, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
return ok ? 0 : KRB5_CRYPTO_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static krb5_error_code
|
||||||
|
+hash_legacy_evp(const char *algo, const krb5_crypto_iov *data, size_t num_data,
|
||||||
|
+ krb5_data *output)
|
||||||
|
+{
|
||||||
|
+ krb5_error_code err;
|
||||||
|
+ EVP_MD *md = NULL;
|
||||||
|
+
|
||||||
|
+ if (!ossl_md_ctx) {
|
||||||
|
+ ossl_md_ctx = malloc(sizeof(ossl_md_context_t));
|
||||||
|
+ if (!ossl_md_ctx) {
|
||||||
|
+ err = ENOMEM;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = init_ossl_md_ctx(ossl_md_ctx, algo);
|
||||||
|
+ if (err) {
|
||||||
|
+ deinit_ossl_ctx(ossl_md_ctx);
|
||||||
|
+ free(ossl_md_ctx);
|
||||||
|
+ ossl_md_ctx = NULL;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ md = EVP_MD_fetch(ossl_md_ctx->libctx, algo, NULL);
|
||||||
|
+ if (!md) {
|
||||||
|
+ err = KRB5_CRYPTO_INTERNAL;
|
||||||
|
+ goto end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ err = hash_evp(md, data, num_data, output);
|
||||||
|
+
|
||||||
|
+end:
|
||||||
|
+ if (md)
|
||||||
|
+ EVP_MD_free(md);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef K5_OPENSSL_MD4
|
||||||
|
@@ -88,7 +163,8 @@ hash_md4(const krb5_crypto_iov *data, size_t num_data, krb5_data *output)
|
||||||
|
* by IPA. These keys are only used along a (separately) secured channel
|
||||||
|
* for legacy reasons when performing trusts to Active Directory.
|
||||||
|
*/
|
||||||
|
- return hash_evp(EVP_md4(), data, num_data, output);
|
||||||
|
+ return FIPS_mode() ? hash_legacy_evp("MD4", data, num_data, output)
|
||||||
|
+ : hash_evp(EVP_md4(), data, num_data, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct krb5_hash_provider krb5int_hash_md4 = {
|
||||||
|
@@ -100,9 +176,12 @@ 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)
|
||||||
|
{
|
||||||
|
- /* MD5 is needed in FIPS mode for communication with RADIUS servers. This
|
||||||
|
- * is gated in libkrad by libdefaults->radius_md5_fips_override. */
|
||||||
|
- return hash_evp(EVP_md5(), data, num_data, output);
|
||||||
|
+ /*
|
||||||
|
+ * MD5 is needed in FIPS mode for communication with RADIUS servers. This
|
||||||
|
+ * is gated in libkrad by libdefaults->radius_md5_fips_override.
|
||||||
|
+ */
|
||||||
|
+ return FIPS_mode() ? hash_legacy_evp("MD5", data, num_data, output)
|
||||||
|
+ : hash_evp(EVP_md5(), data, num_data, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct krb5_hash_provider krb5int_hash_md5 = {
|
||||||
|
diff --git a/src/lib/crypto/openssl/kdf.c b/src/lib/crypto/openssl/kdf.c
|
||||||
|
index 5a43c3d9eb..8528ddc4a9 100644
|
||||||
|
--- a/src/lib/crypto/openssl/kdf.c
|
||||||
|
+++ b/src/lib/crypto/openssl/kdf.c
|
||||||
|
@@ -198,7 +198,7 @@ k5_derive_random_rfc3961(const struct krb5_enc_provider *enc, krb5_key key,
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
- kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL);
|
||||||
|
+ kdf = EVP_KDF_fetch(NULL, "KRB5KDF", "-fips");
|
||||||
|
if (kdf == NULL) {
|
||||||
|
ret = KRB5_CRYPTO_INTERNAL;
|
||||||
|
goto done;
|
||||||
|
--
|
||||||
|
2.38.1
|
||||||
|
|
@ -0,0 +1,672 @@
|
|||||||
|
From f09300d9a9988215263775ac122b7ea2898d04db Mon Sep 17 00:00:00 2001
|
||||||
|
From: Greg Hudson <ghudson@mit.edu>
|
||||||
|
Date: Thu, 22 Dec 2022 03:05:23 -0500
|
||||||
|
Subject: [PATCH] Add PAC full checksums
|
||||||
|
|
||||||
|
A paper by Tom Tervoort noted that computing the PAC privsvr checksum
|
||||||
|
over only the server checksum is vulnerable to collision attacks
|
||||||
|
(CVE-2022-37967). In response, Microsoft has added a second KDC
|
||||||
|
checksum over the full contents of the PAC. Generate and verify full
|
||||||
|
KDC checksums in PACs for service tickets. Update the t_pac.c ticket
|
||||||
|
test case to use a ticket issued by a recent version of Active
|
||||||
|
Directory (provided by Stefan Metzmacher).
|
||||||
|
|
||||||
|
ticket: 9084 (new)
|
||||||
|
---
|
||||||
|
doc/appdev/refs/macros/index.rst | 1 +
|
||||||
|
src/include/krb5/krb5.hin | 1 +
|
||||||
|
src/lib/krb5/krb/pac.c | 92 +++++++++--------
|
||||||
|
src/lib/krb5/krb/pac_sign.c | 146 +++++++++++++++-----------
|
||||||
|
src/lib/krb5/krb/t_pac.c | 171 ++++++++++++++++++-------------
|
||||||
|
src/tests/t_authdata.py | 4 +-
|
||||||
|
6 files changed, 240 insertions(+), 175 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/doc/appdev/refs/macros/index.rst b/doc/appdev/refs/macros/index.rst
|
||||||
|
index 5f34dea5e8..3eeee25593 100644
|
||||||
|
--- a/doc/appdev/refs/macros/index.rst
|
||||||
|
+++ b/doc/appdev/refs/macros/index.rst
|
||||||
|
@@ -247,6 +247,7 @@ Public
|
||||||
|
KRB5_PAC_SERVER_CHECKSUM.rst
|
||||||
|
KRB5_PAC_TICKET_CHECKSUM.rst
|
||||||
|
KRB5_PAC_UPN_DNS_INFO.rst
|
||||||
|
+ KRB5_PAC_FULL_CHECKSUM.rst
|
||||||
|
KRB5_PADATA_AFS3_SALT.rst
|
||||||
|
KRB5_PADATA_AP_REQ.rst
|
||||||
|
KRB5_PADATA_AS_CHECKSUM.rst
|
||||||
|
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
|
||||||
|
index fb9f2a366c..2ba4010514 100644
|
||||||
|
--- a/src/include/krb5/krb5.hin
|
||||||
|
+++ b/src/include/krb5/krb5.hin
|
||||||
|
@@ -8164,6 +8164,7 @@ krb5_verify_authdata_kdc_issued(krb5_context context,
|
||||||
|
#define KRB5_PAC_TICKET_CHECKSUM 16 /**< Ticket checksum */
|
||||||
|
#define KRB5_PAC_ATTRIBUTES_INFO 17 /**< PAC attributes */
|
||||||
|
#define KRB5_PAC_REQUESTOR 18 /**< PAC requestor SID */
|
||||||
|
+#define KRB5_PAC_FULL_CHECKSUM 19 /**< KDC full checksum */
|
||||||
|
|
||||||
|
struct krb5_pac_data;
|
||||||
|
/** PAC data structure to convey authorization information */
|
||||||
|
diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
|
||||||
|
index f6c4373de0..954482e0c7 100644
|
||||||
|
--- a/src/lib/krb5/krb/pac.c
|
||||||
|
+++ b/src/lib/krb5/krb/pac.c
|
||||||
|
@@ -490,7 +490,8 @@ zero_signature(krb5_context context, const krb5_pac pac, krb5_ui_4 type,
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
assert(type == KRB5_PAC_SERVER_CHECKSUM ||
|
||||||
|
- type == KRB5_PAC_PRIVSVR_CHECKSUM);
|
||||||
|
+ type == KRB5_PAC_PRIVSVR_CHECKSUM ||
|
||||||
|
+ type == KRB5_PAC_FULL_CHECKSUM);
|
||||||
|
assert(data->length >= pac->data.length);
|
||||||
|
|
||||||
|
for (i = 0; i < pac->pac->cBuffers; i++) {
|
||||||
|
@@ -557,17 +558,17 @@ verify_checksum(krb5_context context, const krb5_pac pac, uint32_t buffer_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code
|
||||||
|
-verify_server_checksum(krb5_context context, const krb5_pac pac,
|
||||||
|
- const krb5_keyblock *server)
|
||||||
|
+verify_pac_checksums(krb5_context context, const krb5_pac pac,
|
||||||
|
+ krb5_boolean expect_full_checksum,
|
||||||
|
+ const krb5_keyblock *server, const krb5_keyblock *privsvr)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
- krb5_data copy; /* PAC with zeroed checksums */
|
||||||
|
+ krb5_data copy, server_checksum;
|
||||||
|
|
||||||
|
+ /* Make a copy of the PAC with zeroed out server and privsvr checksums. */
|
||||||
|
ret = krb5int_copy_data_contents(context, &pac->data, ©);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
-
|
||||||
|
- /* Zero out both checksum buffers */
|
||||||
|
ret = zero_signature(context, pac, KRB5_PAC_SERVER_CHECKSUM, ©);
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
@@ -575,32 +576,46 @@ verify_server_checksum(krb5_context context, const krb5_pac pac,
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
- ret = verify_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM, server,
|
||||||
|
- KRB5_KEYUSAGE_APP_DATA_CKSUM, ©);
|
||||||
|
+ if (server != NULL) {
|
||||||
|
+ /* Verify the server checksum over the PAC copy. */
|
||||||
|
+ ret = verify_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM, server,
|
||||||
|
+ KRB5_KEYUSAGE_APP_DATA_CKSUM, ©);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
-cleanup:
|
||||||
|
- free(copy.data);
|
||||||
|
- return ret;
|
||||||
|
-}
|
||||||
|
+ if (privsvr != NULL && expect_full_checksum) {
|
||||||
|
+ /* Zero the full checksum buffer in the copy and verify the full
|
||||||
|
+ * checksum over the copy with all three checksums zeroed. */
|
||||||
|
+ ret = zero_signature(context, pac, KRB5_PAC_FULL_CHECKSUM, ©);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
+ ret = verify_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM, privsvr,
|
||||||
|
+ KRB5_KEYUSAGE_APP_DATA_CKSUM, ©);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
-static krb5_error_code
|
||||||
|
-verify_kdc_checksum(krb5_context context, const krb5_pac pac,
|
||||||
|
- const krb5_keyblock *privsvr)
|
||||||
|
-{
|
||||||
|
- krb5_error_code ret;
|
||||||
|
- krb5_data server_checksum;
|
||||||
|
+ if (privsvr != NULL) {
|
||||||
|
+ /* Verify the privsvr checksum over the server checksum. */
|
||||||
|
+ ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
+ &server_checksum);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ if (server_checksum.length < PAC_SIGNATURE_DATA_LENGTH)
|
||||||
|
+ return KRB5_BAD_MSIZE;
|
||||||
|
+ server_checksum.data += PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
+ server_checksum.length -= PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
|
||||||
|
- ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
- &server_checksum);
|
||||||
|
- if (ret)
|
||||||
|
- return ret;
|
||||||
|
- if (server_checksum.length < PAC_SIGNATURE_DATA_LENGTH)
|
||||||
|
- return KRB5_BAD_MSIZE;
|
||||||
|
- server_checksum.data += PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
- server_checksum.length -= PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
+ ret = verify_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM, privsvr,
|
||||||
|
+ KRB5_KEYUSAGE_APP_DATA_CKSUM, &server_checksum);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ pac->verified = TRUE;
|
||||||
|
|
||||||
|
- return verify_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM, privsvr,
|
||||||
|
- KRB5_KEYUSAGE_APP_DATA_CKSUM, &server_checksum);
|
||||||
|
+cleanup:
|
||||||
|
+ free(copy.data);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Per MS-PAC 2.8.3, tickets encrypted to TGS and password change principals
|
||||||
|
@@ -628,6 +643,7 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||||
|
krb5_authdata **authdata, *orig, **ifrel = NULL, **recoded_ifrel = NULL;
|
||||||
|
uint8_t z = 0;
|
||||||
|
krb5_authdata zpac = { KV5M_AUTHDATA, KRB5_AUTHDATA_WIN2K_PAC, 1, &z };
|
||||||
|
+ krb5_boolean is_service_tkt;
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
*pac_out = NULL;
|
||||||
|
@@ -669,7 +685,8 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
- if (privsvr != NULL && k5_pac_should_have_ticket_signature(server_princ)) {
|
||||||
|
+ is_service_tkt = k5_pac_should_have_ticket_signature(server_princ);
|
||||||
|
+ if (privsvr != NULL && is_service_tkt) {
|
||||||
|
/* To check the PAC ticket signatures, re-encode the ticket with the
|
||||||
|
* PAC contents replaced by a single zero. */
|
||||||
|
orig = ifrel[j];
|
||||||
|
@@ -693,8 +710,9 @@ krb5_kdc_verify_ticket(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = krb5_pac_verify_ext(context, pac, enc_tkt->times.authtime, NULL,
|
||||||
|
- server, privsvr, FALSE);
|
||||||
|
+ ret = verify_pac_checksums(context, pac, is_service_tkt, server, privsvr);
|
||||||
|
+ if (ret)
|
||||||
|
+ goto cleanup;
|
||||||
|
|
||||||
|
*pac_out = pac;
|
||||||
|
pac = NULL;
|
||||||
|
@@ -730,14 +748,8 @@ krb5_pac_verify_ext(krb5_context context,
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
|
||||||
|
- if (server != NULL) {
|
||||||
|
- ret = verify_server_checksum(context, pac, server);
|
||||||
|
- if (ret != 0)
|
||||||
|
- return ret;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (privsvr != NULL) {
|
||||||
|
- ret = verify_kdc_checksum(context, pac, privsvr);
|
||||||
|
+ if (server != NULL || privsvr != NULL) {
|
||||||
|
+ ret = verify_pac_checksums(context, pac, FALSE, server, privsvr);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -749,8 +761,6 @@ krb5_pac_verify_ext(krb5_context context,
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- pac->verified = TRUE;
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/lib/krb5/krb/pac_sign.c b/src/lib/krb5/krb/pac_sign.c
|
||||||
|
index 0f9581abbb..8ea61ac17b 100644
|
||||||
|
--- a/src/lib/krb5/krb/pac_sign.c
|
||||||
|
+++ b/src/lib/krb5/krb/pac_sign.c
|
||||||
|
@@ -187,26 +187,41 @@ k5_pac_encode_header(krb5_context context, krb5_pac pac)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-krb5_error_code KRB5_CALLCONV
|
||||||
|
-krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
- krb5_const_principal principal, const krb5_keyblock *server_key,
|
||||||
|
- const krb5_keyblock *privsvr_key, krb5_data *data)
|
||||||
|
+/* Find the buffer of type buftype in pac and write within it a checksum of
|
||||||
|
+ * type cksumtype over data. Set *cksum_out to the checksum. */
|
||||||
|
+static krb5_error_code
|
||||||
|
+compute_pac_checksum(krb5_context context, krb5_pac pac, uint32_t buftype,
|
||||||
|
+ const krb5_keyblock *key, krb5_cksumtype cksumtype,
|
||||||
|
+ const krb5_data *data, krb5_data *cksum_out)
|
||||||
|
{
|
||||||
|
- return krb5_pac_sign_ext(context, pac, authtime, principal, server_key,
|
||||||
|
- privsvr_key, FALSE, data);
|
||||||
|
+ krb5_error_code ret;
|
||||||
|
+ krb5_data buf;
|
||||||
|
+ krb5_crypto_iov iov[2];
|
||||||
|
+
|
||||||
|
+ ret = k5_pac_locate_buffer(context, pac, buftype, &buf);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ assert(buf.length > PAC_SIGNATURE_DATA_LENGTH);
|
||||||
|
+ *cksum_out = make_data(buf.data + PAC_SIGNATURE_DATA_LENGTH,
|
||||||
|
+ buf.length - PAC_SIGNATURE_DATA_LENGTH);
|
||||||
|
+ iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||||
|
+ iov[0].data = *data;
|
||||||
|
+ iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
|
||||||
|
+ iov[1].data = *cksum_out;
|
||||||
|
+ return krb5_c_make_checksum_iov(context, cksumtype, key,
|
||||||
|
+ KRB5_KEYUSAGE_APP_DATA_CKSUM, iov, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
-krb5_error_code KRB5_CALLCONV
|
||||||
|
-krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
- krb5_const_principal principal,
|
||||||
|
- const krb5_keyblock *server_key,
|
||||||
|
- const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
|
||||||
|
- krb5_data *data)
|
||||||
|
+static krb5_error_code
|
||||||
|
+sign_pac(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
+ krb5_const_principal principal, const krb5_keyblock *server_key,
|
||||||
|
+ const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
|
||||||
|
+ krb5_boolean is_service_tkt, krb5_data *data)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
- krb5_data server_cksum, privsvr_cksum;
|
||||||
|
+ krb5_data full_cksum, server_cksum, privsvr_cksum;
|
||||||
|
krb5_cksumtype server_cksumtype, privsvr_cksumtype;
|
||||||
|
- krb5_crypto_iov iov[2];
|
||||||
|
|
||||||
|
data->length = 0;
|
||||||
|
data->data = NULL;
|
||||||
|
@@ -214,67 +229,53 @@ krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
if (principal != NULL) {
|
||||||
|
ret = k5_insert_client_info(context, pac, authtime, principal,
|
||||||
|
with_realm);
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Create zeroed buffers for both checksums */
|
||||||
|
+ /* Create zeroed buffers for all checksums. */
|
||||||
|
ret = k5_insert_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
server_key, &server_cksumtype);
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
-
|
||||||
|
ret = k5_insert_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
|
||||||
|
privsvr_key, &privsvr_cksumtype);
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
+ if (is_service_tkt) {
|
||||||
|
+ ret = k5_insert_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM,
|
||||||
|
+ privsvr_key, &privsvr_cksumtype);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* Now, encode the PAC header so that the checksums will include it */
|
||||||
|
+ /* Encode the PAC header so that the checksums will include it. */
|
||||||
|
ret = k5_pac_encode_header(context, pac);
|
||||||
|
- if (ret != 0)
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
- /* Generate the server checksum over the entire PAC */
|
||||||
|
- ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
- &server_cksum);
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- assert(server_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
|
||||||
|
-
|
||||||
|
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||||
|
- iov[0].data = pac->data;
|
||||||
|
-
|
||||||
|
- iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
|
||||||
|
- iov[1].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
- iov[1].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
+ if (is_service_tkt) {
|
||||||
|
+ /* Generate a full KDC checksum over the whole PAC. */
|
||||||
|
+ ret = compute_pac_checksum(context, pac, KRB5_PAC_FULL_CHECKSUM,
|
||||||
|
+ privsvr_key, privsvr_cksumtype,
|
||||||
|
+ &pac->data, &full_cksum);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- ret = krb5_c_make_checksum_iov(context, server_cksumtype,
|
||||||
|
- server_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
|
||||||
|
- iov, sizeof(iov)/sizeof(iov[0]));
|
||||||
|
- if (ret != 0)
|
||||||
|
+ /* Generate the server checksum over the whole PAC, including the full KDC
|
||||||
|
+ * checksum if we added one. */
|
||||||
|
+ ret = compute_pac_checksum(context, pac, KRB5_PAC_SERVER_CHECKSUM,
|
||||||
|
+ server_key, server_cksumtype, &pac->data,
|
||||||
|
+ &server_cksum);
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
- /* Generate the privsvr checksum over the server checksum buffer */
|
||||||
|
- ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
|
||||||
|
+ /* Generate the privsvr checksum over the server checksum buffer. */
|
||||||
|
+ ret = compute_pac_checksum(context, pac, KRB5_PAC_PRIVSVR_CHECKSUM,
|
||||||
|
+ privsvr_key, privsvr_cksumtype, &server_cksum,
|
||||||
|
&privsvr_cksum);
|
||||||
|
- if (ret != 0)
|
||||||
|
- return ret;
|
||||||
|
-
|
||||||
|
- assert(privsvr_cksum.length > PAC_SIGNATURE_DATA_LENGTH);
|
||||||
|
-
|
||||||
|
- iov[0].flags = KRB5_CRYPTO_TYPE_DATA;
|
||||||
|
- iov[0].data.data = server_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
- iov[0].data.length = server_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
-
|
||||||
|
- iov[1].flags = KRB5_CRYPTO_TYPE_CHECKSUM;
|
||||||
|
- iov[1].data.data = privsvr_cksum.data + PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
- iov[1].data.length = privsvr_cksum.length - PAC_SIGNATURE_DATA_LENGTH;
|
||||||
|
-
|
||||||
|
- ret = krb5_c_make_checksum_iov(context, privsvr_cksumtype,
|
||||||
|
- privsvr_key, KRB5_KEYUSAGE_APP_DATA_CKSUM,
|
||||||
|
- iov, sizeof(iov)/sizeof(iov[0]));
|
||||||
|
- if (ret != 0)
|
||||||
|
+ if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
data->data = k5memdup(pac->data.data, pac->data.length, &ret);
|
||||||
|
@@ -288,6 +289,26 @@ krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+krb5_error_code KRB5_CALLCONV
|
||||||
|
+krb5_pac_sign(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
+ krb5_const_principal principal, const krb5_keyblock *server_key,
|
||||||
|
+ const krb5_keyblock *privsvr_key, krb5_data *data)
|
||||||
|
+{
|
||||||
|
+ return sign_pac(context, pac, authtime, principal, server_key,
|
||||||
|
+ privsvr_key, FALSE, FALSE, data);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+krb5_error_code KRB5_CALLCONV
|
||||||
|
+krb5_pac_sign_ext(krb5_context context, krb5_pac pac, krb5_timestamp authtime,
|
||||||
|
+ krb5_const_principal principal,
|
||||||
|
+ const krb5_keyblock *server_key,
|
||||||
|
+ const krb5_keyblock *privsvr_key, krb5_boolean with_realm,
|
||||||
|
+ krb5_data *data)
|
||||||
|
+{
|
||||||
|
+ return sign_pac(context, pac, authtime, principal, server_key, privsvr_key,
|
||||||
|
+ with_realm, FALSE, data);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Add a signature over der_enc_tkt in privsvr to pac. der_enc_tkt should be
|
||||||
|
* encoded with a dummy PAC authdata element containing a single zero byte. */
|
||||||
|
static krb5_error_code
|
||||||
|
@@ -359,6 +380,7 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_data *der_enc_tkt = NULL, pac_data = empty_data();
|
||||||
|
krb5_authdata **list, *pac_ad;
|
||||||
|
+ krb5_boolean is_service_tkt;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
/* Reallocate space for another authdata element in enc_tkt. */
|
||||||
|
@@ -377,7 +399,8 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
|
||||||
|
memmove(list + 1, list, (count + 1) * sizeof(*list));
|
||||||
|
list[0] = pac_ad;
|
||||||
|
|
||||||
|
- if (k5_pac_should_have_ticket_signature(server_princ)) {
|
||||||
|
+ is_service_tkt = k5_pac_should_have_ticket_signature(server_princ);
|
||||||
|
+ if (is_service_tkt) {
|
||||||
|
ret = encode_krb5_enc_tkt_part(enc_tkt, &der_enc_tkt);
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
@@ -388,9 +411,8 @@ krb5_kdc_sign_ticket(krb5_context context, krb5_enc_tkt_part *enc_tkt,
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
- ret = krb5_pac_sign_ext(context, pac, enc_tkt->times.authtime,
|
||||||
|
- client_princ, server, privsvr, with_realm,
|
||||||
|
- &pac_data);
|
||||||
|
+ ret = sign_pac(context, pac, enc_tkt->times.authtime, client_princ, server,
|
||||||
|
+ privsvr, with_realm, is_service_tkt, &pac_data);
|
||||||
|
if (ret)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
diff --git a/src/lib/krb5/krb/t_pac.c b/src/lib/krb5/krb/t_pac.c
|
||||||
|
index 173bde7bab..81f1642ab0 100644
|
||||||
|
--- a/src/lib/krb5/krb/t_pac.c
|
||||||
|
+++ b/src/lib/krb5/krb/t_pac.c
|
||||||
|
@@ -607,78 +607,102 @@ check_pac(krb5_context context, int index, const unsigned char *pdata,
|
||||||
|
|
||||||
|
static const krb5_keyblock ticket_sig_krbtgt_key = {
|
||||||
|
0, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
|
||||||
|
- 32, U("\x7a\x58\x98\xd2\xaf\xa6\xaf\xc0\x6a\xce\x06\x04\x4b\xc2\x70\x84"
|
||||||
|
- "\x9b\x8e\x0a\x6c\x4c\x07\xdc\x6f\xbb\x48\x43\xe1\xd2\xaa\x97\xf7")
|
||||||
|
+ 32, U("\x03\x73\x81\xEC\x43\x96\x7B\xC2\xAC\x3D\xF5\x2A\xAE\x95\xA6\x8E"
|
||||||
|
+ "\xBE\x24\x58\xDB\xCE\x52\x28\x20\xAF\x5E\xB7\x04\xA2\x22\x71\x4F")
|
||||||
|
};
|
||||||
|
|
||||||
|
static const krb5_keyblock ticket_sig_server_key = {
|
||||||
|
- 0, ENCTYPE_ARCFOUR_HMAC,
|
||||||
|
- 16, U("\xed\x23\x11\x20\x7a\x21\x44\x20\xbf\xc0\x8d\x36\xf7\xf6\xb2\x3e")
|
||||||
|
+ 0, ENCTYPE_AES256_CTS_HMAC_SHA1_96,
|
||||||
|
+ 32, U("\x11\x4A\x84\xE3\x14\x8F\xAA\xB1\xFA\x7B\x53\x51\xB2\x8A\xC2\xF1"
|
||||||
|
+ "\xFD\x19\x6D\x61\xE0\xF3\xF2\x3E\x1F\xDB\xD3\xC1\x79\x7D\xC1\xEE")
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* A ticket issued by an Active Directory KDC (Windows Server 2022), containing
|
||||||
|
+ * a PAC with a full checksum. */
|
||||||
|
static const krb5_data ticket_data = {
|
||||||
|
- .length = 972, .data =
|
||||||
|
- "\x61\x82\x03\xC8\x30\x82\x03\xC4\xA0\x03\x02\x01\x05\xA1\x0A\x1B"
|
||||||
|
- "\x08\x43\x44\x4F\x4D\x2E\x43\x4F\x4D\xA2\x0F\x30\x0D\xA0\x03\x02"
|
||||||
|
- "\x01\x01\xA1\x06\x30\x04\x1B\x02\x73\x31\xA3\x82\x03\x9E\x30\x82"
|
||||||
|
- "\x03\x9A\xA0\x03\x02\x01\x17\xA1\x03\x02\x01\x03\xA2\x82\x03\x8C"
|
||||||
|
- "\x04\x82\x03\x88\x44\x31\x61\x20\x17\xC9\xFE\xBC\xAC\x46\xB5\x77"
|
||||||
|
- "\xE9\x68\x04\x4C\x9B\x31\x91\x0C\xC1\xD4\xDD\xEF\xC7\x34\x20\x08"
|
||||||
|
- "\x90\x91\xE8\x79\xE0\xB5\x03\x26\xA4\x65\xDE\xEC\x47\x03\x2A\x8F"
|
||||||
|
- "\x61\xE7\x4D\x38\x5A\x42\x95\x5A\xF9\x2F\x41\x2C\x2A\x6E\x60\xA1"
|
||||||
|
- "\xEB\x51\xB3\xBD\x4C\x00\x41\x2A\x44\x76\x08\x37\x1A\x51\xFD\x65"
|
||||||
|
- "\x67\x7E\xBF\x3D\x90\x86\xE3\x9A\x54\x6B\x67\xA8\x08\x7A\x73\xCC"
|
||||||
|
- "\xC3\xB7\x4B\xD5\x5C\x3A\x14\x6C\xC1\x5F\x54\x4B\x92\x55\xB4\xB7"
|
||||||
|
- "\x92\x23\x3F\x53\x89\x47\x8E\x1F\x8B\xB9\xDB\x3B\x93\xE8\x70\xE4"
|
||||||
|
- "\x24\xB8\x9D\xF0\x0E\x35\x28\xF8\x7A\x27\x5D\xF7\x25\x97\x9C\xF5"
|
||||||
|
- "\x9F\x9F\x64\x04\xF2\xA3\xAB\x11\x15\xB6\xDA\x18\xD6\x46\xD5\xE6"
|
||||||
|
- "\xB8\x08\xDE\x0A\x62\xFD\xF8\xAA\x52\x90\xD9\x67\x29\xB2\xCD\x06"
|
||||||
|
- "\xB6\xB0\x50\x2B\x3F\x0F\xA3\xA5\xBF\xAA\x6E\x40\x03\xD6\x5F\x02"
|
||||||
|
- "\xBC\xD8\x18\x47\x97\x09\xD7\xE4\x96\x3B\xCB\xEB\x92\x2C\x3C\x49"
|
||||||
|
- "\xFF\x1F\x71\xE0\x52\x94\x0F\x8B\x9F\xB8\x2A\xBB\x9C\xE2\xA3\xDD"
|
||||||
|
- "\x38\x89\xE2\xB1\x0B\x9E\x1F\x7A\xB3\xE3\xD2\xB0\x94\xDC\x87\xBE"
|
||||||
|
- "\x37\xA6\xD3\xB3\x29\x35\x9A\x72\xC3\x7A\xF1\xA9\xE6\xC5\xD1\x26"
|
||||||
|
- "\x83\x65\x44\x17\xBA\x55\xA8\x5E\x94\x26\xED\xE9\x8A\x93\x11\x5D"
|
||||||
|
- "\x7E\x20\x1B\x9C\x15\x9E\x13\x37\x03\x4D\xDD\x99\x51\xD8\x66\x29"
|
||||||
|
- "\x6A\xB9\xFB\x49\xFE\x52\x78\xDA\x86\x85\xA9\xA3\xB9\xEF\xEC\xAD"
|
||||||
|
- "\x35\xA6\x8D\xAC\x0F\x75\x22\xBB\x0B\x49\x1C\x13\x52\x40\xC9\x52"
|
||||||
|
- "\x69\x09\x54\xD1\x0F\x94\x3F\x22\x48\x67\xB0\x96\x28\xAA\xE6\x28"
|
||||||
|
- "\xD9\x0C\x08\xEF\x51\xED\x15\x5E\xA2\x53\x59\xA5\x03\xB4\x06\x20"
|
||||||
|
- "\x3D\xCC\xB4\xC5\xF8\x8C\x73\x67\xA3\x21\x3D\x19\xCD\xD4\x12\x28"
|
||||||
|
- "\xD2\x93\xDE\x0D\xF0\x71\x10\x50\xD6\x33\x35\x04\x11\x64\x43\x39"
|
||||||
|
- "\xC3\xDF\x96\xE3\x66\xE3\x85\xCA\xE7\x67\x14\x3A\xF0\x43\xAA\xBB"
|
||||||
|
- "\xD4\x1D\xB5\x24\xB5\x74\x90\x25\xA7\x87\x7E\xDB\xD3\x83\x8A\x3A"
|
||||||
|
- "\x69\xA8\x2D\xAF\xB7\xB8\xF3\xDC\x13\xAF\x45\x61\x3F\x59\x39\x7E"
|
||||||
|
- "\x69\xDE\x0C\x04\xF1\x10\x6B\xB4\x56\xFA\x21\x9F\x72\x2B\x60\x86"
|
||||||
|
- "\xE3\x23\x0E\xC4\x51\xF6\xBE\xD8\xE1\x5F\xEE\x73\x4C\x17\x4C\x2C"
|
||||||
|
- "\x1B\xFB\x9F\x1F\x7A\x3B\x07\x5B\x8E\xF1\x01\xAC\xD6\x30\x94\x8A"
|
||||||
|
- "\x5D\x22\x6F\x08\xCE\xED\x5E\xB6\xDB\x86\x8C\x87\xEB\x8D\x91\xFF"
|
||||||
|
- "\x0A\x86\x30\xBD\xC0\xF8\x25\xE7\xAE\x24\x35\xF2\xFC\xE5\xFD\x1B"
|
||||||
|
- "\xB0\x05\x4A\xA3\xE5\xEB\x2E\x05\xAD\x99\x67\x49\x87\xE6\xB3\x87"
|
||||||
|
- "\x82\xA4\x59\xA7\x6E\xDD\xF2\xB6\x66\xE8\xF7\x70\xF5\xBD\xC9\x0E"
|
||||||
|
- "\xFA\x9C\x79\x84\xD4\x9B\x05\x0E\xBB\xF5\xDB\xEF\xFC\xCC\x26\xF2"
|
||||||
|
- "\x93\xCF\xD2\x04\x3C\xA9\x2C\x65\x42\x97\x86\xD8\x38\x0A\x1E\xF6"
|
||||||
|
- "\xD6\xCA\x30\xB5\x1A\xEC\xFB\xBA\x3B\x84\x57\xB0\xFD\xFB\xE6\xBC"
|
||||||
|
- "\xF2\x76\xF6\x4C\xBB\xAB\xB1\x31\xA1\x27\x7C\xE6\xE6\x81\xB6\xCE"
|
||||||
|
- "\x84\x86\x40\xB6\x40\x33\xC4\xF8\xB4\x15\xCF\xAA\xA5\x51\x78\xB9"
|
||||||
|
- "\x8B\x50\x25\xB2\x88\x86\x96\x72\x8C\x71\x4D\xB5\x3A\x94\x86\x77"
|
||||||
|
- "\x0E\x95\x9B\x16\x93\xEF\x3A\x11\x79\xBA\x83\xF7\x74\xD3\x8D\xBA"
|
||||||
|
- "\x15\xE1\x2C\x04\x57\xA8\x92\x1E\x9D\x00\x8E\x20\xFD\x30\x70\xE7"
|
||||||
|
- "\xF5\x65\x2F\x19\x0C\x94\xBA\x03\x71\x12\x96\xCD\xC8\xB4\x96\xDB"
|
||||||
|
- "\xCE\x19\xC2\xDF\x3C\xC2\xF6\x3D\x53\xED\x98\xA5\x41\x72\x2A\x22"
|
||||||
|
- "\x7B\xF3\x2B\x17\x6C\xE1\x39\x7D\xAE\x9B\x11\xF9\xC1\xA6\x9E\x9F"
|
||||||
|
- "\x89\x3C\x12\xAA\x94\x74\xA7\x4F\x70\xE8\xB9\xDE\x04\xF0\x9D\x39"
|
||||||
|
- "\x24\x2D\x92\xE8\x46\x2D\x2E\xF0\x40\x66\x1A\xD9\x27\xF9\x98\xF1"
|
||||||
|
- "\x81\x1D\x70\x62\x63\x30\x6D\xCD\x84\x04\x5F\xFA\x83\xD3\xEC\x8D"
|
||||||
|
- "\x86\xFB\x40\x61\xC1\x8A\x45\xFF\x7B\xD9\xD4\x18\x61\x7F\x51\xE3"
|
||||||
|
- "\xFC\x1E\x18\xF0\xAF\xC6\x18\x2C\xE1\x6D\x5D\xF9\x62\xFC\x20\xA3"
|
||||||
|
- "\xB2\x8A\x5F\xE5\xBB\x29\x0F\x99\x63\x07\x88\x38\x3A\x3B\x73\x2A"
|
||||||
|
- "\x6D\xDA\x3D\xA8\x0D\x8F\x56\x41\x89\x82\xE5\xB8\x61\x00\x64\x7D"
|
||||||
|
- "\x17\x0C\xCE\x03\x55\x8F\xF4\x5B\x0D\x50\xF2\xEB\x05\x67\xBE\xDB"
|
||||||
|
- "\x7B\x75\xC5\xEA\xA1\xAB\x1D\xB0\x3C\x6D\x42\x08\x0B\x9A\x45\x20"
|
||||||
|
- "\xA8\x8F\xE5\x67\x47\x30\xDE\x93\x5F\x43\x05\xEB\xA8\x2D\x80\xF5"
|
||||||
|
- "\x1A\xB8\x4A\x4E\x42\x2D\x0B\x7A\xDC\x46\x20\x2D\x13\x17\xDD\x4B"
|
||||||
|
- "\x94\x96\xAA\x1F\x06\x0C\x1F\x62\x07\x9C\x40\xA1"
|
||||||
|
+ .length = 1307, .data =
|
||||||
|
+ "\x61\x82\x05\x17\x30\x82\x05\x13\xA0\x03\x02\x01\x05\xA1\x0F\x1B"
|
||||||
|
+ "\x0D\x57\x32\x30\x32\x32\x2D\x4C\x37\x2E\x42\x41\x53\x45\xA2\x2A"
|
||||||
|
+ "\x30\x28\xA0\x03\x02\x01\x01\xA1\x21\x30\x1F\x1B\x04\x63\x69\x66"
|
||||||
|
+ "\x73\x1B\x17\x77\x32\x30\x32\x32\x2D\x31\x31\x38\x2E\x77\x32\x30"
|
||||||
|
+ "\x32\x32\x2D\x6C\x37\x2E\x62\x61\x73\x65\xA3\x82\x04\xCD\x30\x82"
|
||||||
|
+ "\x04\xC9\xA0\x03\x02\x01\x12\xA1\x03\x02\x01\x05\xA2\x82\x04\xBB"
|
||||||
|
+ "\x04\x82\x04\xB7\x44\x5C\x7B\x5A\x3F\x2E\xA3\x50\x34\xDE\xB0\x69"
|
||||||
|
+ "\x23\x2D\x47\x89\x2C\xC0\xA3\xF9\xDD\x70\xAA\xA5\x1E\xFE\x74\xE5"
|
||||||
|
+ "\x19\xA2\x4F\x65\x6C\x9E\x00\xB4\x60\x00\x7C\x0C\x29\x43\x31\x99"
|
||||||
|
+ "\x77\x02\x73\xED\xB9\x40\xF5\xD2\xD1\xC9\x20\x0F\xE3\x38\xF9\xCC"
|
||||||
|
+ "\x5E\x2A\xBD\x1F\x91\x66\x1A\xD8\x2A\x80\x3C\x2C\x00\x3C\x1E\xC9"
|
||||||
|
+ "\x2A\x29\x19\x19\x96\x18\x54\x03\x97\x8F\x1D\x5F\xDB\xE9\x66\x68"
|
||||||
|
+ "\xCD\xB1\xD5\x00\x35\x69\x49\x45\xF1\x6A\x78\x7B\x37\x71\x87\x14"
|
||||||
|
+ "\x1C\x98\x4D\x69\xCB\x1B\xD8\xF5\xA3\xD8\x53\x4A\x75\x76\x62\xBA"
|
||||||
|
+ "\x6C\x3F\xEA\x8B\x97\x21\xCA\x8A\x46\x4B\x38\xDA\x09\x9F\x5A\xC8"
|
||||||
|
+ "\x38\xFF\x34\x97\x5B\xA2\xE5\xBA\xC9\x87\x17\xD8\x08\x05\x7A\x83"
|
||||||
|
+ "\x04\xD6\x02\x8E\x9B\x18\xB6\x40\x1A\xF7\x47\x25\x24\x3E\x37\x1E"
|
||||||
|
+ "\xF6\xC1\x3A\x1F\xCA\xB3\x43\x5A\xAE\x94\x83\x31\xAF\xFB\xEE\xED"
|
||||||
|
+ "\x46\x71\xEF\xE2\x37\x37\x15\xFE\x1B\x0B\x9E\xF8\x3E\x0C\x43\x96"
|
||||||
|
+ "\xB6\x0A\x04\x78\xF8\x5E\xAA\x33\x1F\xE2\x07\x5A\x8D\xC4\x4E\x32"
|
||||||
|
+ "\x6D\xD6\xA0\xC5\xEA\x3D\x12\x59\xD4\x41\x40\x4E\xA1\xD8\xBE\xED"
|
||||||
|
+ "\x17\xCB\x68\xCC\x59\xCB\x53\xB2\x0E\x58\x8A\xA9\x33\x7F\x6F\x2B"
|
||||||
|
+ "\x37\x89\x08\x44\xBA\xC7\x67\x17\xBB\x91\xF7\xC3\x0F\x00\xF8\xAA"
|
||||||
|
+ "\xA1\x33\xA6\x08\x47\xCA\xFA\xE8\x49\x27\x45\x46\xF1\xC1\xC3\x5F"
|
||||||
|
+ "\xE2\x45\x0A\x7D\x64\x52\x8C\x2E\xE1\xDE\xFF\xB2\x64\xEC\x69\x98"
|
||||||
|
+ "\x15\xDF\x9E\xB1\xEB\xD6\x9D\x08\x06\x4E\x73\xC1\x0B\x71\x21\x05"
|
||||||
|
+ "\x9E\xBC\xA2\x17\xCF\xB3\x70\xF4\xEF\xB8\x69\xA9\x94\x27\xFD\x5E"
|
||||||
|
+ "\x72\xB1\x2D\xD2\x20\x1B\x57\x80\xAB\x38\x97\xCF\x22\x68\x4F\xB8"
|
||||||
|
+ "\xB7\x17\x53\x25\x67\x0B\xED\xD1\x58\x20\x0D\x45\xF9\x09\xFA\xE7"
|
||||||
|
+ "\x61\x3E\xDB\xC2\x59\x7B\x3A\x3B\x59\x81\x51\xAA\xA4\x81\xF4\x96"
|
||||||
|
+ "\x3B\xE1\x6F\x6F\xF4\x8E\x68\x9E\xBA\x1E\x0F\xF2\x44\x68\x11\xFC"
|
||||||
|
+ "\x2B\x5F\xBE\xF2\xEA\x07\x80\xB9\xCA\x9E\x41\xBD\x2F\x81\xF5\x11"
|
||||||
|
+ "\x2A\x12\xF3\x4F\xD6\x12\x16\x0F\x21\x90\xF1\xD3\x1E\xF1\xA4\x94"
|
||||||
|
+ "\x46\xEA\x30\xF3\x84\x06\xC1\xA4\x51\xFC\x43\x35\xBD\xEF\x4D\x89"
|
||||||
|
+ "\x1D\xA5\x44\xB2\x69\xC4\x0F\xBF\x86\x01\x08\x44\x77\xD5\xB4\xB7"
|
||||||
|
+ "\x5C\x3F\xA7\xD4\x2F\x39\x73\x85\x88\xEE\xB1\x64\x1D\x80\x6C\xEE"
|
||||||
|
+ "\x6E\x31\x90\x92\x0D\xA1\xB7\xC4\x5C\xCC\xEE\x91\xC8\xCB\x11\x2D"
|
||||||
|
+ "\x4A\x1A\x7D\x43\x8F\xEB\x60\x09\xED\x1B\x07\x58\xBE\xBC\xBD\x29"
|
||||||
|
+ "\xF3\xB3\xA3\x4F\xC5\x8A\x30\x33\xB9\xA9\x9F\x43\x08\x27\x15\xC4"
|
||||||
|
+ "\x9C\x5D\x8E\xBD\x5C\x05\xC6\x05\x9C\x87\x60\x08\x1E\xE2\x52\xB8"
|
||||||
|
+ "\x45\x8D\x28\xB6\x2C\x15\x46\x74\x9F\x0E\xAA\x6B\x70\x3A\x2A\x55"
|
||||||
|
+ "\x45\x26\xB2\x58\x4D\x35\xA6\xF1\x96\xBE\x60\xB2\x71\x7B\xF8\x54"
|
||||||
|
+ "\xB9\x90\x21\x8E\xB9\x0F\x35\x98\x5E\x88\xEB\x1A\x53\xB4\x59\x7F"
|
||||||
|
+ "\xAF\x69\x1C\x61\x67\xF4\xF6\xBD\xAC\x24\xCD\xB7\xA9\x67\xE8\xA1"
|
||||||
|
+ "\x83\x85\x5F\x11\x74\x1F\xF7\x4C\x78\x36\xEF\x50\x74\x88\x58\x4B"
|
||||||
|
+ "\x1A\x9F\x84\x9A\x9A\x05\x92\xEC\x1D\xD5\xF3\xC4\x95\x51\x28\xE2"
|
||||||
|
+ "\x3F\x32\x87\xB2\xFD\x21\x27\x66\xE4\x6B\x85\x2F\xDC\x7B\xC0\x22"
|
||||||
|
+ "\xEB\x7A\x94\x20\x5A\x7B\xD3\x7A\xB9\x5B\xF8\x1A\x5A\x84\x4E\xA1"
|
||||||
|
+ "\x73\x41\x53\xD2\x60\xF7\x7C\xEE\x68\x59\x85\x80\xFC\x3D\x70\x4B"
|
||||||
|
+ "\x04\x32\xE7\xF2\xFD\xBD\xB3\xD9\x21\xE2\x37\x56\xA2\x16\xCC\xDE"
|
||||||
|
+ "\x8A\xD3\xBC\x71\xEF\x58\x19\x0E\x45\x8A\x5B\x53\xD6\x77\x30\x6A"
|
||||||
|
+ "\xA7\xF8\x68\x06\x4E\x07\xCA\xCE\x30\xD7\x35\xAB\x1A\xC7\x18\xD4"
|
||||||
|
+ "\xC6\x2F\x1A\xFF\xE9\x7A\x94\x0B\x76\x5E\x7E\x29\x0C\xE6\xD3\x3B"
|
||||||
|
+ "\x5B\x44\x96\xA8\xF1\x29\x23\x95\xD9\x79\xB3\x39\xFC\x76\xED\xE1"
|
||||||
|
+ "\x1E\x67\x4E\xF7\xE8\x7B\x7A\x12\x9E\xD8\x4B\x35\x09\x0A\xF2\xC1"
|
||||||
|
+ "\x63\x5B\xEE\xFD\x2A\xC2\xA6\x66\x30\x3C\x1F\x95\xAF\x65\x22\x95"
|
||||||
|
+ "\x14\x1D\xF5\xD5\xDC\x38\x79\x35\x1C\xCD\x24\x47\xE0\xFD\x08\xC8"
|
||||||
|
+ "\xF4\x15\x55\x9F\xD9\xC7\xAC\x3F\x67\xB3\x4F\xEB\x26\x7C\x8E\xD6"
|
||||||
|
+ "\x74\xB3\x0A\xCD\xE7\xFA\xBE\x7E\xA3\x3E\xEC\x61\x50\x77\x52\x56"
|
||||||
|
+ "\xCF\x90\x5D\x48\xFB\xD4\x2C\x6C\x61\x8B\xDD\x2B\xF5\x92\x1F\x30"
|
||||||
|
+ "\xBF\x3F\x80\x0D\x31\xDB\xB2\x0B\x7D\x84\xE3\xA6\x42\x7F\x00\x38"
|
||||||
|
+ "\x44\x02\xC5\xB8\xD9\x58\x29\x9D\x68\x5C\x32\x8B\x76\xAE\xED\x15"
|
||||||
|
+ "\xF9\x7C\xAE\x7B\xB6\x8E\xD6\x54\x24\xFF\xFA\x87\x05\xEF\x15\x08"
|
||||||
|
+ "\x5E\x4B\x21\xA2\x2F\x49\xE7\x0F\xC3\xD0\xB9\x49\x22\xEF\xD5\xCA"
|
||||||
|
+ "\xB2\x11\xF2\x17\xB6\x77\x24\x68\x76\xB2\x07\xF8\x0A\x73\xDD\x65"
|
||||||
|
+ "\x9C\x75\x64\xF7\xA1\xC6\x23\x08\x84\x72\x3E\x54\x2E\xEB\x9B\x40"
|
||||||
|
+ "\xA6\x83\x87\xEB\xB5\x00\x40\x4F\xE1\x72\x2A\x59\x3A\x06\x60\x29"
|
||||||
|
+ "\x7E\x25\x2F\xD8\x80\x40\x8C\x59\xCA\xCF\x8E\x44\xE4\x2D\x84\x7E"
|
||||||
|
+ "\xCB\xFD\x1E\x3B\xD5\xFF\x9A\xB9\x66\x93\x6D\x5E\xC8\xB7\x13\x26"
|
||||||
|
+ "\xD6\x38\x1B\x2B\xE1\x87\x96\x05\xD5\xF3\xAB\x68\xF7\x12\x62\x2C"
|
||||||
|
+ "\x58\xC1\xC9\x85\x3C\x72\xF1\x26\xEE\xC0\x09\x5F\x1D\x4B\xAC\x01"
|
||||||
|
+ "\x41\xC8\x12\xF8\xF3\x93\x43\x41\xFF\xEC\x0B\x80\xE2\xEE\x20\x85"
|
||||||
|
+ "\x25\xCD\x6C\x30\x8C\x0D\x24\x2E\xBA\x19\xEA\x28\x7F\xCF\xD5\x10"
|
||||||
|
+ "\x5C\xE9\xB2\x9D\x5F\x16\xE4\xC0\xF3\xCC\xD9\x68\x4A\x05\x08\x70"
|
||||||
|
+ "\x17\x26\xC8\x5C\x4A\xBF\x94\x6A\x0E\xD5\xDA\x67\x47\x4B\xAF\x44"
|
||||||
|
+ "\xE3\x94\xAA\x05\xDB\xA2\x49\x74\xFA\x5C\x69\xAB\x44\xB7\xF7\xBA"
|
||||||
|
+ "\xAE\x7A\x23\x87\xEB\x54\x7E\x80\xF1\x5B\x60\xA5\x93\xE5\xD4\x24"
|
||||||
|
+ "\x84\xF7\x0A\x16\x10\xBE\xE9\x4D\xD8\x6B\x15\x40\x5D\x74\xDA\x1B"
|
||||||
|
+ "\xFF\x2E\x4D\x17\x9D\x35\xF7\x0D\xCF\x66\x38\x0D\x8A\xE4\xDD\x6B"
|
||||||
|
+ "\xE1\x0F\x1F\xBD\xFD\x4F\x30\x37\x3F\x96\xB4\x92\x54\xD3\x9A\x7A"
|
||||||
|
+ "\xD1\x5B\x5B\xA9\x54\x16\xE6\x24\xAB\xD4\x23\x39\x7D\xD2\xC7\x09"
|
||||||
|
+ "\xFA\xD4\x86\x55\x4D\x60\xC2\x87\x67\x6B\xE6"
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -686,7 +710,7 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_ticket *ticket;
|
||||||
|
- krb5_principal sprinc;
|
||||||
|
+ krb5_principal cprinc, sprinc;
|
||||||
|
krb5_authdata **authdata1, **authdata2;
|
||||||
|
krb5_pac pac, pac2, pac3;
|
||||||
|
uint32_t *list;
|
||||||
|
@@ -701,7 +725,13 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
if (ret)
|
||||||
|
err(context, ret, "while decrypting ticket");
|
||||||
|
|
||||||
|
- ret = krb5_parse_name(context, "s1@CDOM.COM", &sprinc);
|
||||||
|
+ ret = krb5_parse_name(context, "administrator@W2022-L7.BASE", &cprinc);
|
||||||
|
+ if (ret)
|
||||||
|
+ err(context, ret, "krb5_parse_name");
|
||||||
|
+
|
||||||
|
+ ret = krb5_parse_name(context,
|
||||||
|
+ "cifs/w2022-118.w2022-l7.base@W2022-L7.BASE",
|
||||||
|
+ &sprinc);
|
||||||
|
if (ret)
|
||||||
|
err(context, ret, "krb5_parse_name");
|
||||||
|
|
||||||
|
@@ -713,7 +743,7 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
|
||||||
|
/* In this test, the server is also the client. */
|
||||||
|
ret = krb5_pac_verify(context, pac, ticket->enc_part2->times.authtime,
|
||||||
|
- ticket->server, NULL, NULL);
|
||||||
|
+ cprinc, NULL, NULL);
|
||||||
|
if (ret)
|
||||||
|
err(context, ret, "while verifying PAC client info");
|
||||||
|
|
||||||
|
@@ -722,7 +752,7 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
ticket->enc_part2->authorization_data = NULL;
|
||||||
|
|
||||||
|
ret = krb5_kdc_sign_ticket(context, ticket->enc_part2, pac, sprinc,
|
||||||
|
- sprinc, &ticket_sig_server_key,
|
||||||
|
+ cprinc, &ticket_sig_server_key,
|
||||||
|
&ticket_sig_krbtgt_key, FALSE);
|
||||||
|
if (ret)
|
||||||
|
err(context, ret, "while signing ticket");
|
||||||
|
@@ -781,6 +811,7 @@ test_pac_ticket_signature(krb5_context context)
|
||||||
|
krb5_pac_free(context, pac);
|
||||||
|
krb5_pac_free(context, pac2);
|
||||||
|
krb5_pac_free(context, pac3);
|
||||||
|
+ krb5_free_principal(context, cprinc);
|
||||||
|
krb5_free_principal(context, sprinc);
|
||||||
|
krb5_free_ticket(context, ticket);
|
||||||
|
}
|
||||||
|
diff --git a/src/tests/t_authdata.py b/src/tests/t_authdata.py
|
||||||
|
index 47ea9e4b47..e934799268 100644
|
||||||
|
--- a/src/tests/t_authdata.py
|
||||||
|
+++ b/src/tests/t_authdata.py
|
||||||
|
@@ -11,7 +11,7 @@ realm = K5Realm(krb5_conf=conf)
|
||||||
|
# container.
|
||||||
|
mark('baseline authdata')
|
||||||
|
out = realm.run(['./adata', realm.host_princ])
|
||||||
|
-if '?128: [6, 7, 10, 16]' not in out or '^-42: Hello' not in out:
|
||||||
|
+if '?128: [6, 7, 10, 16, 19]' not in out or '^-42: Hello' not in out:
|
||||||
|
fail('expected authdata not seen for basic request')
|
||||||
|
|
||||||
|
# Requested authdata is copied into the ticket, with KDC-only types
|
||||||
|
@@ -243,7 +243,7 @@ out = realm.run(['./adata', '-p', realm.user_princ, 'service/2'])
|
||||||
|
if '+97: [indcl]' not in out or '[inds1]' in out:
|
||||||
|
fail('correct auth-indicator not seen for S4U2Proxy req')
|
||||||
|
# Make sure a PAC with an S4U_DELEGATION_INFO(11) buffer is included.
|
||||||
|
-if '?128: [1, 6, 7, 10, 11, 16]' not in out:
|
||||||
|
+if '?128: [1, 6, 7, 10, 11, 16, 19]' not in out:
|
||||||
|
fail('PAC with delegation info not seen for S4U2Proxy req')
|
||||||
|
|
||||||
|
# Get another S4U2Proxy ticket including request-authdata.
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From ff9c99b689855a646c371379d30a668dfd7a87a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Wed, 1 Feb 2023 15:57:26 +0100
|
||||||
|
Subject: [PATCH] Fix possible double-free during KDB creation
|
||||||
|
|
||||||
|
In krb5_dbe_def_encrypt_key_data(), when we free
|
||||||
|
key_data->key_data_contents[0], reset it to null so the caller doesn't
|
||||||
|
free it as well.
|
||||||
|
|
||||||
|
Since commit a06945b4ec267e8b80e5e8c95edd89930ff12103 this bug
|
||||||
|
manifests as a double-free during KDB creation if master key
|
||||||
|
encryption fails.
|
||||||
|
|
||||||
|
[ghudson@mit.edu: edited commit message]
|
||||||
|
|
||||||
|
ticket: 9086 (new)
|
||||||
|
tags: pullup
|
||||||
|
target_version: 1.20-next
|
||||||
|
---
|
||||||
|
src/lib/kdb/encrypt_key.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/lib/kdb/encrypt_key.c b/src/lib/kdb/encrypt_key.c
|
||||||
|
index dc612c810e..91debea533 100644
|
||||||
|
--- a/src/lib/kdb/encrypt_key.c
|
||||||
|
+++ b/src/lib/kdb/encrypt_key.c
|
||||||
|
@@ -109,6 +109,7 @@ krb5_dbe_def_encrypt_key_data( krb5_context context,
|
||||||
|
if ((retval = krb5_c_encrypt(context, mkey, /* XXX */ 0, 0,
|
||||||
|
&plain, &cipher))) {
|
||||||
|
free(key_data->key_data_contents[0]);
|
||||||
|
+ key_data->key_data_contents[0] = NULL;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -121,6 +122,7 @@ krb5_dbe_def_encrypt_key_data( krb5_context context,
|
||||||
|
key_data->key_data_contents[1] = malloc(keysalt->data.length);
|
||||||
|
if (key_data->key_data_contents[1] == NULL) {
|
||||||
|
free(key_data->key_data_contents[0]);
|
||||||
|
+ key_data->key_data_contents[0] = NULL;
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
memcpy(key_data->key_data_contents[1], keysalt->data.data,
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From 604fce63b468d0efce4438df4ba0286f00bfce8d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Julien Rische <jrische@redhat.com>
|
||||||
|
Date: Tue, 21 Feb 2023 10:03:35 +0100
|
||||||
|
Subject: [PATCH] Fix meridian type in kadmin datetime parser
|
||||||
|
|
||||||
|
The meridian suffix is typed as "Number" in kadmin YACC file for
|
||||||
|
datetime parsing, while it should be using the "Meridian" enumeration
|
||||||
|
one.
|
||||||
|
|
||||||
|
This results in invalid Meridian value on 64-bit IBM zSystems (s390x),
|
||||||
|
causing core dumped errors on most kadmin commands where meridian
|
||||||
|
suffices are used.
|
||||||
|
|
||||||
|
Upstream PR:
|
||||||
|
https://github.com/krb5/krb5/pull/1290
|
||||||
|
---
|
||||||
|
src/kadmin/cli/getdate.y | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/kadmin/cli/getdate.y b/src/kadmin/cli/getdate.y
|
||||||
|
index b9dceec1ee..d14cf963c5 100644
|
||||||
|
--- a/src/kadmin/cli/getdate.y
|
||||||
|
+++ b/src/kadmin/cli/getdate.y
|
||||||
|
@@ -181,7 +181,8 @@ static time_t yyRelSeconds;
|
||||||
|
|
||||||
|
%token tAGO tID tDST tNEVER
|
||||||
|
%token <Number> tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
|
||||||
|
-%token <Number> tSEC_UNIT tSNUMBER tUNUMBER tZONE tMERIDIAN
|
||||||
|
+%token <Number> tSEC_UNIT tSNUMBER tUNUMBER tZONE
|
||||||
|
+%token <Meridian> tMERIDIAN
|
||||||
|
%type <Meridian> o_merid
|
||||||
|
|
||||||
|
%%
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
*/admin@EXAMPLE.COM *
|
@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Kerberos 5 Password-changing and Administration
|
||||||
|
Wants=network-online.target
|
||||||
|
After=syslog.target network.target network-online.target
|
||||||
|
AssertPathExists=!/var/kerberos/krb5kdc/kpropd.acl
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
PIDFile=/run/kadmind.pid
|
||||||
|
EnvironmentFile=-/etc/sysconfig/kadmin
|
||||||
|
ExecStart=/usr/sbin/kadmind -P /run/kadmind.pid $KADMIND_ARGS
|
||||||
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -0,0 +1 @@
|
|||||||
|
KADMIND_ARGS=
|
@ -0,0 +1,9 @@
|
|||||||
|
/var/log/kadmind.log {
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
monthly
|
||||||
|
rotate 12
|
||||||
|
postrotate
|
||||||
|
systemctl reload kadmin.service || true
|
||||||
|
endscript
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
[kdcdefaults]
|
||||||
|
kdc_ports = 88
|
||||||
|
kdc_tcp_ports = 88
|
||||||
|
spake_preauth_kdc_challenge = edwards25519
|
||||||
|
|
||||||
|
[realms]
|
||||||
|
EXAMPLE.COM = {
|
||||||
|
master_key_type = aes256-cts-hmac-sha384-192
|
||||||
|
acl_file = /var/kerberos/krb5kdc/kadm5.acl
|
||||||
|
dict_file = /usr/share/dict/words
|
||||||
|
default_principal_flags = +preauth
|
||||||
|
admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
|
||||||
|
supported_enctypes = aes256-cts-hmac-sha384-192:normal aes128-cts-hmac-sha256-128:normal aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal camellia256-cts-cmac:normal camellia128-cts-cmac:normal arcfour-hmac-md5:normal
|
||||||
|
# Supported encryption types for FIPS mode:
|
||||||
|
#supported_enctypes = aes256-cts-hmac-sha384-192:normal aes128-cts-hmac-sha256-128:normal
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Kerberos 5 Propagation
|
||||||
|
Wants=network-online.target
|
||||||
|
After=syslog.target network.target network-online.target
|
||||||
|
AssertPathExists=/var/kerberos/krb5kdc/kpropd.acl
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
EnvironmentFile=-/etc/sysconfig/kprop
|
||||||
|
ExecStart=/usr/sbin/kpropd $KPROPD_ARGS
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -0,0 +1 @@
|
|||||||
|
KPROPD_ARGS=
|
@ -0,0 +1,16 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIzBAABCgAdFiEExEk8tzn0qJ+YUsvCDLoIV1+Dct8FAmNvED8ACgkQDLoIV1+D
|
||||||
|
ct9uKw/8C5GS8mdh335lB+bkfjYYCZLD+oQToDAAbdCddrIcuLftvnTfXJ8cMtMc
|
||||||
|
UT2hsp8u7ZupjJRevdhaH7fFwomc0V8iSES5J2cQHTNd9aK93j/W6NaMoqWLrQWg
|
||||||
|
jx99oqLn7orvp8N5RufEQcNMNWhFIX4XSfrA3vPfHbbffA2vkjJzOGno4UHi8zUn
|
||||||
|
6nye7jbrBpiQIeFIJSS3VPsvGrKdRgb9BqGTUsqPIuFvr3Qvo42lKr5X8CWYSXjK
|
||||||
|
0aKlOpfbWdkteEe2o84/wyMpuGvmYkmOgaMB5xQ3jfEuvPNAWX2CWHNDamiqwBT/
|
||||||
|
YxwhZimNa1B9r3P1yDHvpUu8cJaRzw2UDRi2f3Kztrmn2jlqzmoZ31WBALJA7lmL
|
||||||
|
SrVFdXi7AcWwppMp1kbe9SvurCXID8/Q4n+qAdzSvqrXbeWerVUkdYFvtxQ1bMJR
|
||||||
|
jnqN11iZFYaoCaaR2lFEhjoMdR80jUa2m6vdF7a7xhH1UvuPHDnzLT9X/TiPvx0R
|
||||||
|
Itrp5MMIrUQHcZUL9hM5hrg3nxEsGsSCnjB0zWDmgXdLGwd4CvcOF4HPQR3BBlEH
|
||||||
|
CLtAa27bBXMJTYVvmmKt06hw+U3ALDfUlFrV6ZNLr9ug69l29n7JoChAbZ97Hx1m
|
||||||
|
twPwJpKd8AiUz+j3KCfgGU21qMbHNP3jEn3q9tkq0qcs/z7RCmU=
|
||||||
|
=1WIq
|
||||||
|
-----END PGP SIGNATURE-----
|
@ -0,0 +1 @@
|
|||||||
|
d /run/krb5kdc 0755 root root
|
@ -0,0 +1,30 @@
|
|||||||
|
# To opt out of the system crypto-policies configuration of krb5, remove the
|
||||||
|
# symlink at /etc/krb5.conf.d/crypto-policies which will not be recreated.
|
||||||
|
includedir /etc/krb5.conf.d/
|
||||||
|
|
||||||
|
[logging]
|
||||||
|
default = FILE:/var/log/krb5libs.log
|
||||||
|
kdc = FILE:/var/log/krb5kdc.log
|
||||||
|
admin_server = FILE:/var/log/kadmind.log
|
||||||
|
|
||||||
|
[libdefaults]
|
||||||
|
dns_lookup_realm = false
|
||||||
|
ticket_lifetime = 24h
|
||||||
|
renew_lifetime = 7d
|
||||||
|
forwardable = true
|
||||||
|
rdns = false
|
||||||
|
pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
|
||||||
|
spake_preauth_groups = edwards25519
|
||||||
|
dns_canonicalize_hostname = fallback
|
||||||
|
qualify_shortname = ""
|
||||||
|
# default_realm = EXAMPLE.COM
|
||||||
|
|
||||||
|
[realms]
|
||||||
|
# EXAMPLE.COM = {
|
||||||
|
# kdc = kerberos.example.com
|
||||||
|
# admin_server = kerberos.example.com
|
||||||
|
# }
|
||||||
|
|
||||||
|
[domain_realm]
|
||||||
|
# .example.com = EXAMPLE.COM
|
||||||
|
# example.com = EXAMPLE.COM
|
@ -0,0 +1,9 @@
|
|||||||
|
/var/log/krb5kdc.log {
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
monthly
|
||||||
|
rotate 12
|
||||||
|
postrotate
|
||||||
|
systemctl reload krb5kdc.service || true
|
||||||
|
endscript
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Kerberos 5 KDC
|
||||||
|
Wants=network-online.target
|
||||||
|
After=syslog.target network.target network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=forking
|
||||||
|
PIDFile=/run/krb5kdc.pid
|
||||||
|
EnvironmentFile=-/etc/sysconfig/krb5kdc
|
||||||
|
ExecStart=/usr/sbin/krb5kdc -P /run/krb5kdc.pid $KRB5KDC_ARGS
|
||||||
|
ExecReload=/bin/kill -HUP $MAINPID
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -0,0 +1 @@
|
|||||||
|
KRB5KDC_ARGS=
|
@ -0,0 +1,4 @@
|
|||||||
|
#%PAM-1.0
|
||||||
|
auth include su
|
||||||
|
account include su
|
||||||
|
session include su
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue