From 01ee0aa15e14870be7b8fe4d0723134ad8b78888 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 19 2015 03:35:51 +0000 Subject: import krb5-1.13.2-10.el7 --- diff --git a/.gitignore b/.gitignore index 4f90bbf..ff82334 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -SOURCES/krb5-1.12.2-pdf.tar.xz -SOURCES/krb5-1.12.2.tar.gz +SOURCES/krb5-1.13.2-pdf.pax.xz +SOURCES/krb5-1.13.2.tar.gz SOURCES/nss_wrapper-0.0-20140204195100.git3d58327.tar.xz SOURCES/socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz diff --git a/.krb5.metadata b/.krb5.metadata index 050653a..c837707 100644 --- a/.krb5.metadata +++ b/.krb5.metadata @@ -1,4 +1,4 @@ -ad1f5d4fe9b90b4549e639050c278b176df85e0c SOURCES/krb5-1.12.2-pdf.tar.xz -6f24800d48d36a33305387a9b6340884b05573b1 SOURCES/krb5-1.12.2.tar.gz +93795fb24ecb84cd2db15c28d67d17990614b693 SOURCES/krb5-1.13.2-pdf.pax.xz +a81dec5cf59b7a4b51c5be14d65518724ae25d56 SOURCES/krb5-1.13.2.tar.gz 7e2c80565c726a6be9a62615752196710e2e2faa SOURCES/nss_wrapper-0.0-20140204195100.git3d58327.tar.xz ca7b62bd60d45817a059063bb0efd68cd1ecc889 SOURCES/socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz diff --git a/SOURCES/0000-Refactor-cm-functions-in-sendto_kdc.c.patch b/SOURCES/0000-Refactor-cm-functions-in-sendto_kdc.c.patch deleted file mode 100644 index ff332b1..0000000 --- a/SOURCES/0000-Refactor-cm-functions-in-sendto_kdc.c.patch +++ /dev/null @@ -1,436 +0,0 @@ -Tweaked a bit to apply to 1.12: -* krb5_int64 hadn't been replaced by int64_t yet. - -commit 346883c48f1b9e09b1af2cf73e3b96ee8f934072 -Author: Greg Hudson -Date: Wed Mar 26 13:21:45 2014 -0400 - - Refactor cm functions in sendto_kdc.c - - Move get_curtime_ms and the cm functions near the top of the file - right after structure definitions. Except for cm_select_or_poll, - define each cm function separately for poll and for select, since the - implementations don't share much in common. Instead of - cm_unset_write, define cm_read and cm_write functions to put an fd in - read-only or write-only state. Remove the ssflags argument from - cm_add_fd and just expect the caller to make a subsequent call to - cm_read or cm_write. Always select for exceptions when using select. - (Polling for exceptions is implicit with poll). - - With these changes, we no longer select/poll for reading on a TCP - connection until we are done writing to it. So in service_tcp_fd, - remove the check for unexpected read events. - -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index e60a375..e773a0a 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -59,8 +59,7 @@ - - typedef krb5_int64 time_ms; - --/* Since fd_set is large on some platforms (8K on AIX 5.2), this probably -- * shouldn't be allocated in automatic storage. */ -+/* This can be pretty large, so should not be stack-allocated. */ - struct select_state { - #ifdef USE_POLL - struct pollfd fds[MAX_POLLFDS]; -@@ -107,6 +106,183 @@ struct conn_state { - time_ms endtime; - }; - -+/* Get current time in milliseconds. */ -+static krb5_error_code -+get_curtime_ms(time_ms *time_out) -+{ -+ struct timeval tv; -+ -+ if (gettimeofday(&tv, 0)) -+ return errno; -+ *time_out = (time_ms)tv.tv_sec * 1000 + tv.tv_usec / 1000; -+ return 0; -+} -+ -+#ifdef USE_POLL -+ -+/* Find a pollfd in selstate by fd, or abort if we can't find it. */ -+static inline struct pollfd * -+find_pollfd(struct select_state *selstate, int fd) -+{ -+ int i; -+ -+ for (i = 0; i < selstate->nfds; i++) { -+ if (selstate->fds[i].fd == fd) -+ return &selstate->fds[i]; -+ } -+ abort(); -+} -+ -+static void -+cm_init_selstate(struct select_state *selstate) -+{ -+ selstate->nfds = 0; -+} -+ -+static krb5_boolean -+cm_add_fd(struct select_state *selstate, int fd) -+{ -+ if (selstate->nfds >= MAX_POLLFDS) -+ return FALSE; -+ selstate->fds[selstate->nfds].fd = fd; -+ selstate->fds[selstate->nfds].events = 0; -+ selstate->nfds++; -+ return TRUE; -+} -+ -+static void -+cm_remove_fd(struct select_state *selstate, int fd) -+{ -+ struct pollfd *pfd = find_pollfd(selstate, fd); -+ -+ *pfd = selstate->fds[selstate->nfds - 1]; -+ selstate->nfds--; -+} -+ -+/* Poll for reading (and not writing) on fd the next time we poll. */ -+static void -+cm_read(struct select_state *selstate, int fd) -+{ -+ find_pollfd(selstate, fd)->events = POLLIN; -+} -+ -+/* Poll for writing (and not reading) on fd the next time we poll. */ -+static void -+cm_write(struct select_state *selstate, int fd) -+{ -+ find_pollfd(selstate, fd)->events = POLLOUT; -+} -+ -+/* Get the output events for fd in the form of ssflags. */ -+static unsigned int -+cm_get_ssflags(struct select_state *selstate, int fd) -+{ -+ struct pollfd *pfd = find_pollfd(selstate, fd); -+ -+ return ((pfd->revents & POLLIN) ? SSF_READ : 0) | -+ ((pfd->revents & POLLOUT) ? SSF_WRITE : 0) | -+ ((pfd->revents & POLLERR) ? SSF_EXCEPTION : 0); -+} -+ -+#else /* not USE_POLL */ -+ -+static void -+cm_init_selstate(struct select_state *selstate) -+{ -+ selstate->nfds = 0; -+ selstate->max = 0; -+ FD_ZERO(&selstate->rfds); -+ FD_ZERO(&selstate->wfds); -+ FD_ZERO(&selstate->xfds); -+} -+ -+static krb5_boolean -+cm_add_fd(struct select_state *selstate, int fd) -+{ -+#ifndef _WIN32 /* On Windows FD_SETSIZE is a count, not a max value. */ -+ if (fd >= FD_SETSIZE) -+ return FALSE; -+#endif -+ FD_SET(fd, &selstate->xfds); -+ if (selstate->max <= fd) -+ selstate->max = fd + 1; -+ selstate->nfds++; -+ return TRUE; -+} -+ -+static void -+cm_remove_fd(struct select_state *selstate, int fd) -+{ -+ FD_CLR(fd, &selstate->rfds); -+ FD_CLR(fd, &selstate->wfds); -+ FD_CLR(fd, &selstate->xfds); -+ if (selstate->max == fd + 1) { -+ while (selstate->max > 0 && -+ !FD_ISSET(selstate->max - 1, &selstate->rfds) && -+ !FD_ISSET(selstate->max - 1, &selstate->wfds) && -+ !FD_ISSET(selstate->max - 1, &selstate->xfds)) -+ selstate->max--; -+ } -+ selstate->nfds--; -+} -+ -+/* Select for reading (and not writing) on fd the next time we select. */ -+static void -+cm_read(struct select_state *selstate, int fd) -+{ -+ FD_SET(fd, &selstate->rfds); -+ FD_CLR(fd, &selstate->wfds); -+} -+ -+/* Select for writing (and not reading) on fd the next time we select. */ -+static void -+cm_write(struct select_state *selstate, int fd) -+{ -+ FD_CLR(fd, &selstate->rfds); -+ FD_SET(fd, &selstate->wfds); -+} -+ -+/* Get the events for fd from selstate after a select. */ -+static unsigned int -+cm_get_ssflags(struct select_state *selstate, int fd) -+{ -+ return (FD_ISSET(fd, &selstate->rfds) ? SSF_READ : 0) | -+ (FD_ISSET(fd, &selstate->wfds) ? SSF_WRITE : 0) | -+ (FD_ISSET(fd, &selstate->xfds) ? SSF_EXCEPTION : 0); -+} -+ -+#endif /* not USE_POLL */ -+ -+static krb5_error_code -+cm_select_or_poll(const struct select_state *in, time_ms endtime, -+ struct select_state *out, int *sret) -+{ -+#ifndef USE_POLL -+ struct timeval tv; -+#endif -+ krb5_error_code retval; -+ time_ms curtime, interval; -+ -+ retval = get_curtime_ms(&curtime); -+ if (retval != 0) -+ return retval; -+ interval = (curtime < endtime) ? endtime - curtime : 0; -+ -+ /* We don't need a separate copy of the selstate for poll, but use one for -+ * consistency with how we use select. */ -+ *out = *in; -+ -+#ifdef USE_POLL -+ *sret = poll(out->fds, out->nfds, interval); -+#else -+ tv.tv_sec = interval / 1000; -+ tv.tv_usec = interval % 1000 * 1000; -+ *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, &tv); -+#endif -+ -+ return (*sret < 0) ? SOCKET_ERRNO : 0; -+} -+ - static int - in_addrlist(struct server_entry *entry, struct serverlist *list) - { -@@ -251,18 +427,6 @@ cleanup: - return retval; - } - --/* Get current time in milliseconds. */ --static krb5_error_code --get_curtime_ms(time_ms *time_out) --{ -- struct timeval tv; -- -- if (gettimeofday(&tv, 0)) -- return errno; -- *time_out = (time_ms)tv.tv_sec * 1000 + tv.tv_usec / 1000; -- return 0; --} -- - /* - * Notes: - * -@@ -283,144 +447,6 @@ get_curtime_ms(time_ms *time_out) - * connections already in progress - */ - --static void --cm_init_selstate(struct select_state *selstate) --{ -- selstate->nfds = 0; --#ifndef USE_POLL -- selstate->max = 0; -- FD_ZERO(&selstate->rfds); -- FD_ZERO(&selstate->wfds); -- FD_ZERO(&selstate->xfds); --#endif --} -- --static krb5_boolean --cm_add_fd(struct select_state *selstate, int fd, unsigned int ssflags) --{ --#ifdef USE_POLL -- if (selstate->nfds >= MAX_POLLFDS) -- return FALSE; -- selstate->fds[selstate->nfds].fd = fd; -- selstate->fds[selstate->nfds].events = 0; -- if (ssflags & SSF_READ) -- selstate->fds[selstate->nfds].events |= POLLIN; -- if (ssflags & SSF_WRITE) -- selstate->fds[selstate->nfds].events |= POLLOUT; --#else --#ifndef _WIN32 /* On Windows FD_SETSIZE is a count, not a max value. */ -- if (fd >= FD_SETSIZE) -- return FALSE; --#endif -- if (ssflags & SSF_READ) -- FD_SET(fd, &selstate->rfds); -- if (ssflags & SSF_WRITE) -- FD_SET(fd, &selstate->wfds); -- if (ssflags & SSF_EXCEPTION) -- FD_SET(fd, &selstate->xfds); -- if (selstate->max <= fd) -- selstate->max = fd + 1; --#endif -- selstate->nfds++; -- return TRUE; --} -- --static void --cm_remove_fd(struct select_state *selstate, int fd) --{ --#ifdef USE_POLL -- int i; -- -- /* Find the FD in the array and move the last entry to its place. */ -- assert(selstate->nfds > 0); -- for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++); -- assert(i < selstate->nfds); -- selstate->fds[i] = selstate->fds[selstate->nfds - 1]; --#else -- FD_CLR(fd, &selstate->rfds); -- FD_CLR(fd, &selstate->wfds); -- FD_CLR(fd, &selstate->xfds); -- if (selstate->max == 1 + fd) { -- while (selstate->max > 0 -- && ! FD_ISSET(selstate->max-1, &selstate->rfds) -- && ! FD_ISSET(selstate->max-1, &selstate->wfds) -- && ! FD_ISSET(selstate->max-1, &selstate->xfds)) -- selstate->max--; -- } --#endif -- selstate->nfds--; --} -- --static void --cm_unset_write(struct select_state *selstate, int fd) --{ --#ifdef USE_POLL -- int i; -- -- for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++); -- assert(i < selstate->nfds); -- selstate->fds[i].events &= ~POLLOUT; --#else -- FD_CLR(fd, &selstate->wfds); --#endif --} -- --static krb5_error_code --cm_select_or_poll(const struct select_state *in, time_ms endtime, -- struct select_state *out, int *sret) --{ --#ifndef USE_POLL -- struct timeval tv; --#endif -- krb5_error_code retval; -- time_ms curtime, interval; -- -- retval = get_curtime_ms(&curtime); -- if (retval != 0) -- return retval; -- interval = (curtime < endtime) ? endtime - curtime : 0; -- -- /* We don't need a separate copy of the selstate for poll, but use one for -- * consistency with how we use select. */ -- *out = *in; -- --#ifdef USE_POLL -- *sret = poll(out->fds, out->nfds, interval); --#else -- tv.tv_sec = interval / 1000; -- tv.tv_usec = interval % 1000 * 1000; -- *sret = select(out->max, &out->rfds, &out->wfds, &out->xfds, &tv); --#endif -- -- return (*sret < 0) ? SOCKET_ERRNO : 0; --} -- --static unsigned int --cm_get_ssflags(struct select_state *selstate, int fd) --{ -- unsigned int ssflags = 0; --#ifdef USE_POLL -- int i; -- -- for (i = 0; i < selstate->nfds && selstate->fds[i].fd != fd; i++); -- assert(i < selstate->nfds); -- if (selstate->fds[i].revents & POLLIN) -- ssflags |= SSF_READ; -- if (selstate->fds[i].revents & POLLOUT) -- ssflags |= SSF_WRITE; -- if (selstate->fds[i].revents & POLLERR) -- ssflags |= SSF_EXCEPTION; --#else -- if (FD_ISSET(fd, &selstate->rfds)) -- ssflags |= SSF_READ; -- if (FD_ISSET(fd, &selstate->wfds)) -- ssflags |= SSF_WRITE; -- if (FD_ISSET(fd, &selstate->xfds)) -- ssflags |= SSF_EXCEPTION; --#endif -- return ssflags; --} -- - static int service_tcp_fd(krb5_context context, struct conn_state *conn, - struct select_state *selstate, int ssflags); - static int service_udp_fd(krb5_context context, struct conn_state *conn, -@@ -600,7 +626,6 @@ start_connection(krb5_context context, struct conn_state *state, - struct sendto_callback_info *callback_info) - { - int fd, e; -- unsigned int ssflags; - static const int one = 1; - static const struct linger lopt = { 0, 0 }; - -@@ -676,15 +701,17 @@ start_connection(krb5_context context, struct conn_state *state, - state->state = READING; - } - } -- ssflags = SSF_READ | SSF_EXCEPTION; -- if (state->state == CONNECTING || state->state == WRITING) -- ssflags |= SSF_WRITE; -- if (!cm_add_fd(selstate, state->fd, ssflags)) { -+ -+ if (!cm_add_fd(selstate, state->fd)) { - (void) closesocket(state->fd); - state->fd = INVALID_SOCKET; - state->state = FAILED; - return -1; - } -+ if (state->state == CONNECTING || state->state == WRITING) -+ cm_write(selstate, state->fd); -+ else -+ cm_read(selstate, state->fd); - - return 0; - } -@@ -768,9 +795,8 @@ service_tcp_fd(krb5_context context, struct conn_state *conn, - ssize_t nwritten, nread; - SOCKET_WRITEV_TEMP tmp; - -- /* Check for a socket exception or readable data before we expect it. */ -- if (ssflags & SSF_EXCEPTION || -- ((ssflags & SSF_READ) && conn->state != READING)) -+ /* Check for a socket exception. */ -+ if (ssflags & SSF_EXCEPTION) - goto kill_conn; - - switch (conn->state) { -@@ -810,7 +836,7 @@ service_tcp_fd(krb5_context context, struct conn_state *conn, - } - if (conn->x.out.sg_count == 0) { - /* Done writing, switch to reading. */ -- cm_unset_write(selstate, conn->fd); -+ cm_read(selstate, conn->fd); - conn->state = READING; - conn->x.in.bufsizebytes_read = 0; - conn->x.in.bufsize = 0; diff --git a/SOURCES/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch b/SOURCES/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch deleted file mode 100644 index ac7baa1..0000000 --- a/SOURCES/0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch +++ /dev/null @@ -1,230 +0,0 @@ -From 74e775ac6d937c9d22be4fc1d429e5e62705fb7d Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Thu, 24 Jul 2014 15:39:53 -0400 -Subject: [PATCH 1/7] In ksu, merge krb5_ccache_copy() and _restricted() - -Other than whether or not they limit the creds it stores to the new -ccache based on the principal name of the client for whom the creds were -issued, there's no meaningful difference between what these two -functions do. Merge them. ---- - src/clients/ksu/ccache.c | 106 ++++++----------------------------------------- - src/clients/ksu/ksu.h | 6 +-- - src/clients/ksu/main.c | 27 ++++-------- - 3 files changed, 22 insertions(+), 117 deletions(-) - -diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c -index 9916c75..118fc53 100644 ---- a/src/clients/ksu/ccache.c -+++ b/src/clients/ksu/ccache.c -@@ -47,12 +47,14 @@ void show_credential(); - */ - - krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, -- primary_principal, cc_out, stored, target_uid) -+ primary_principal, restrict_creds, cc_out, -+ stored, target_uid) - /* IN */ - krb5_context context; - krb5_ccache cc_def; - char *cc_other_tag; - krb5_principal primary_principal; -+ krb5_boolean restrict_creds; - uid_t target_uid; - /* OUT */ - krb5_ccache *cc_out; -@@ -83,9 +85,6 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, - } - } - -- *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr, -- primary_principal); -- - if (!lstat( cc_other_name, &st_temp)) - return EINVAL; - -@@ -98,8 +97,16 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, - return retval; - } - -- retval = krb5_store_all_creds(context, * cc_other, cc_def_creds_arr, -- cc_other_creds_arr); -+ if (restrict_creds) { -+ retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr, -+ cc_other_creds_arr, primary_principal, -+ stored); -+ } else { -+ *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr, -+ primary_principal); -+ retval = krb5_store_all_creds(context, *cc_other, cc_def_creds_arr, -+ cc_other_creds_arr); -+ } - - if (cc_def_creds_arr){ - while (cc_def_creds_arr[i]){ -@@ -623,93 +630,6 @@ krb5_error_code krb5_store_some_creds(context, cc, creds_def, creds_other, prst, - *stored = temp_stored; - return 0; - } --/****************************************************************** --krb5_cache_copy_restricted -- --gets rid of any expired tickets in the secondary cache, --copies the default cache into the secondary cache, --only credentials that are for prst are copied. -- --the algorithm may look a bit funny, --but I had to do it this way, since cc_remove function did not come --with k5 beta 3 release. --************************************************************************/ -- --krb5_error_code krb5_ccache_copy_restricted (context, cc_def, cc_other_tag, -- prst, cc_out, stored, target_uid) -- krb5_context context; -- krb5_ccache cc_def; -- char *cc_other_tag; -- krb5_principal prst; -- uid_t target_uid; -- /* OUT */ -- krb5_ccache *cc_out; -- krb5_boolean *stored; --{ -- -- int i=0; -- krb5_ccache * cc_other; -- const char * cc_def_name; -- const char * cc_other_name; -- krb5_error_code retval=0; -- krb5_creds ** cc_def_creds_arr = NULL; -- krb5_creds ** cc_other_creds_arr = NULL; -- struct stat st_temp; -- -- cc_other = (krb5_ccache *) xcalloc(1, sizeof (krb5_ccache)); -- -- if ((retval = krb5_cc_resolve(context, cc_other_tag, cc_other))){ -- com_err(prog_name, retval, _("resolving ccache %s"), cc_other_tag); -- return retval; -- } -- -- cc_def_name = krb5_cc_get_name(context, cc_def); -- cc_other_name = krb5_cc_get_name(context, *cc_other); -- -- if ( ! stat(cc_def_name, &st_temp)){ -- if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){ -- return retval; -- } -- -- } -- -- if (!lstat( cc_other_name, &st_temp)) { -- return EINVAL; -- } -- -- if (krb5_seteuid(0)||krb5_seteuid(target_uid)) { -- return errno; -- } -- -- -- if ((retval = krb5_cc_initialize(context, *cc_other, prst))){ -- return retval; -- } -- -- retval = krb5_store_some_creds(context, * cc_other, -- cc_def_creds_arr, cc_other_creds_arr, prst, stored); -- -- -- -- if (cc_def_creds_arr){ -- while (cc_def_creds_arr[i]){ -- krb5_free_creds(context, cc_def_creds_arr[i]); -- i++; -- } -- } -- -- i=0; -- -- if(cc_other_creds_arr){ -- while (cc_other_creds_arr[i]){ -- krb5_free_creds(context, cc_other_creds_arr[i]); -- i++; -- } -- } -- -- *cc_out = *cc_other; -- return retval; --} - - krb5_error_code krb5_ccache_filter (context, cc, prst) - krb5_context context; -diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h -index f2c0811..9e0c613 100644 ---- a/src/clients/ksu/ksu.h -+++ b/src/clients/ksu/ksu.h -@@ -107,7 +107,7 @@ extern krb5_error_code get_best_principal - /* ccache.c */ - extern krb5_error_code krb5_ccache_copy - (krb5_context, krb5_ccache, char *, krb5_principal, -- krb5_ccache *, krb5_boolean *, uid_t); -+ krb5_boolean, krb5_ccache *, krb5_boolean *, uid_t); - - extern krb5_error_code krb5_store_all_creds - (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **); -@@ -141,10 +141,6 @@ extern krb5_error_code krb5_store_some_creds - (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **, - krb5_principal, krb5_boolean *); - --extern krb5_error_code krb5_ccache_copy_restricted --(krb5_context, krb5_ccache, char *, krb5_principal, -- krb5_ccache *, krb5_boolean *, uid_t); -- - extern krb5_error_code krb5_ccache_refresh - (krb5_context, krb5_ccache); - -diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c -index 233eb52..62f3bc0 100644 ---- a/src/clients/ksu/main.c -+++ b/src/clients/ksu/main.c -@@ -117,6 +117,7 @@ main (argc, argv) - krb5_principal kdc_server; - krb5_boolean zero_password; - char * dir_of_cc_target; -+ krb5_boolean restrict_creds; - - options.opt = KRB5_DEFAULT_OPTIONS; - options.lifetime = KRB5_DEFAULT_TKT_LIFE; -@@ -464,25 +465,13 @@ main (argc, argv) - then only the credentials for that particular user - should be copied */ - -- if ((source_uid == 0) && (target_uid != 0)) { -- -- if ((retval = krb5_ccache_copy_restricted(ksu_context, cc_source, -- cc_target_tag, client, -- &cc_target, &stored, -- target_uid))){ -- com_err(prog_name, retval, _("while copying cache %s to %s"), -- krb5_cc_get_name(ksu_context, cc_source), cc_target_tag); -- exit(1); -- } -- -- } else { -- if ((retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, -- client,&cc_target, &stored, target_uid))) { -- com_err(prog_name, retval, _("while copying cache %s to %s"), -- krb5_cc_get_name(ksu_context, cc_source), cc_target_tag); -- exit(1); -- } -- -+ restrict_creds = (source_uid == 0) && (target_uid != 0); -+ retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, client, -+ restrict_creds, &cc_target, &stored, target_uid); -+ if (retval) { -+ com_err(prog_name, retval, _("while copying cache %s to %s"), -+ krb5_cc_get_name(ksu_context, cc_source), cc_target_tag); -+ exit(1); - } - - /* Become root for authentication*/ --- -2.0.4 - diff --git a/SOURCES/0001-Simplify-sendto_kdc.c.patch b/SOURCES/0001-Simplify-sendto_kdc.c.patch deleted file mode 100644 index 51c512d..0000000 --- a/SOURCES/0001-Simplify-sendto_kdc.c.patch +++ /dev/null @@ -1,421 +0,0 @@ -From 42b3c2ed11c1e62c1691f868a6796983f93c3beb Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Wed, 9 Apr 2014 13:19:03 -0400 -Subject: [PATCH 01/13] Simplify sendto_kdc.c - -* Get rid of the "x" member of conn_state, which used to be a union - but hasn't been since r14742. -* Define a structure type for the "out" member of conn_state. -* Rename incoming_krb5_message to incoming_message for brevity. -* Make the "pos" member of incoming_message an offset instead of a - pointer, simplifying several present and future computations. -* Use "in" and "out" aliases to the conn_state in and out members - where it improves brevity. -* Rename set_conn_state_msg_length to set_transport_message and give - it a descriptive comment. -* Call set_transport_message from start_connection only, instead of - once in add_connection and perhaps again in start_connection. To - make this possible, pass the original message argument to maybe_send - and start_connection. -* Use make_data and empty_data helpers where appropriate. ---- - src/lib/krb5/os/sendto_kdc.c | 159 +++++++++++++++++++++---------------------- - 1 file changed, 79 insertions(+), 80 deletions(-) - -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index 67e2a60..5f781d3 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -76,30 +76,30 @@ static const char *const state_strings[] = { - - /* connection states */ - enum conn_states { INITIALIZING, CONNECTING, WRITING, READING, FAILED }; --struct incoming_krb5_message { -+struct incoming_message { - size_t bufsizebytes_read; - size_t bufsize; -+ size_t pos; - char *buf; -- char *pos; - unsigned char bufsizebytes[4]; - size_t n_left; - }; - -+struct outgoing_message { -+ sg_buf sgbuf[2]; -+ sg_buf *sgp; -+ int sg_count; -+ unsigned char msg_len_buf[4]; -+}; -+ - struct conn_state { - SOCKET fd; - enum conn_states state; - int (*service)(krb5_context context, struct conn_state *, - struct select_state *, int); - struct remote_address addr; -- struct { -- struct { -- sg_buf sgbuf[2]; -- sg_buf *sgp; -- int sg_count; -- unsigned char msg_len_buf[4]; -- } out; -- struct incoming_krb5_message in; -- } x; -+ struct incoming_message in; -+ struct outgoing_message out; - krb5_data callback_buffer; - size_t server_index; - struct conn_state *next; -@@ -461,30 +461,31 @@ static int service_tcp_fd(krb5_context context, struct conn_state *conn, - static int service_udp_fd(krb5_context context, struct conn_state *conn, - struct select_state *selstate, int ssflags); - -+/* Set up the actual message we will send across the underlying transport to -+ * communicate the payload message, using one or both of state->out.sgbuf. */ - static void --set_conn_state_msg_length (struct conn_state *state, const krb5_data *message) -+set_transport_message(struct conn_state *state, const krb5_data *message) - { -- if (!message || message->length == 0) -+ struct outgoing_message *out = &state->out; -+ -+ if (message == NULL || message->length == 0) - return; - - if (state->addr.type == SOCK_STREAM) { -- store_32_be(message->length, state->x.out.msg_len_buf); -- SG_SET(&state->x.out.sgbuf[0], state->x.out.msg_len_buf, 4); -- SG_SET(&state->x.out.sgbuf[1], message->data, message->length); -- state->x.out.sg_count = 2; -- -+ store_32_be(message->length, out->msg_len_buf); -+ SG_SET(&out->sgbuf[0], out->msg_len_buf, 4); -+ SG_SET(&out->sgbuf[1], message->data, message->length); -+ out->sg_count = 2; - } else { -- -- SG_SET(&state->x.out.sgbuf[0], message->data, message->length); -- SG_SET(&state->x.out.sgbuf[1], 0, 0); -- state->x.out.sg_count = 1; -- -+ SG_SET(&out->sgbuf[0], message->data, message->length); -+ SG_SET(&out->sgbuf[1], NULL, 0); -+ out->sg_count = 1; - } - } - - static krb5_error_code - add_connection(struct conn_state **conns, struct addrinfo *ai, -- size_t server_index, const krb5_data *message, char **udpbufp) -+ size_t server_index, char **udpbufp) - { - struct conn_state *state, **tailptr; - -@@ -492,28 +493,26 @@ add_connection(struct conn_state **conns, struct addrinfo *ai, - if (state == NULL) - return ENOMEM; - state->state = INITIALIZING; -- state->x.out.sgp = state->x.out.sgbuf; -+ state->out.sgp = state->out.sgbuf; - state->addr.type = ai->ai_socktype; - state->addr.family = ai->ai_family; - state->addr.len = ai->ai_addrlen; - memcpy(&state->addr.saddr, ai->ai_addr, ai->ai_addrlen); - state->fd = INVALID_SOCKET; - state->server_index = server_index; -- SG_SET(&state->x.out.sgbuf[1], 0, 0); -+ SG_SET(&state->out.sgbuf[1], NULL, 0); - if (ai->ai_socktype == SOCK_STREAM) { - state->service = service_tcp_fd; -- set_conn_state_msg_length (state, message); - } else { - state->service = service_udp_fd; -- set_conn_state_msg_length (state, message); - - if (*udpbufp == NULL) { - *udpbufp = malloc(MAX_DGRAM_SIZE); - if (*udpbufp == 0) - return ENOMEM; - } -- state->x.in.buf = *udpbufp; -- state->x.in.bufsize = MAX_DGRAM_SIZE; -+ state->in.buf = *udpbufp; -+ state->in.bufsize = MAX_DGRAM_SIZE; - } - - /* Chain the new state onto the tail of the list. */ -@@ -597,7 +596,7 @@ resolve_server(krb5_context context, const struct serverlist *servers, - ai.ai_family = entry->family; - ai.ai_addrlen = entry->addrlen; - ai.ai_addr = (struct sockaddr *)&entry->addr; -- return add_connection(conns, &ai, ind, message, udpbufp); -+ return add_connection(conns, &ai, ind, udpbufp); - } - - memset(&hint, 0, sizeof(hint)); -@@ -617,12 +616,12 @@ resolve_server(krb5_context context, const struct serverlist *servers, - /* Add each address with the preferred socktype. */ - retval = 0; - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) -- retval = add_connection(conns, a, ind, message, udpbufp); -+ retval = add_connection(conns, a, ind, udpbufp); - if (retval == 0 && entry->socktype == 0 && socktype2 != 0) { - /* Add each address again with the non-preferred socktype. */ - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { - a->ai_socktype = socktype2; -- retval = add_connection(conns, a, ind, message, udpbufp); -+ retval = add_connection(conns, a, ind, udpbufp); - } - } - freeaddrinfo(addrs); -@@ -631,7 +630,7 @@ resolve_server(krb5_context context, const struct serverlist *servers, - - static int - start_connection(krb5_context context, struct conn_state *state, -- struct select_state *selstate, -+ const krb5_data *message, struct select_state *selstate, - struct sendto_callback_info *callback_info) - { - int fd, e; -@@ -689,13 +688,14 @@ start_connection(krb5_context context, struct conn_state *state, - return -3; - } - -- set_conn_state_msg_length(state, &state->callback_buffer); -+ message = &state->callback_buffer; - } -+ set_transport_message(state, message); - - if (state->addr.type == SOCK_DGRAM) { - /* Send it now. */ - ssize_t ret; -- sg_buf *sg = &state->x.out.sgbuf[0]; -+ sg_buf *sg = &state->out.sgbuf[0]; - - TRACE_SENDTO_KDC_UDP_SEND_INITIAL(context, &state->addr); - ret = send(state->fd, SG_BUF(sg), SG_LEN(sg), 0); -@@ -731,14 +731,16 @@ start_connection(krb5_context context, struct conn_state *state, - next connection. */ - static int - maybe_send(krb5_context context, struct conn_state *conn, -- struct select_state *selstate, -+ const krb5_data *message, struct select_state *selstate, - struct sendto_callback_info *callback_info) - { - sg_buf *sg; - ssize_t ret; - -- if (conn->state == INITIALIZING) -- return start_connection(context, conn, selstate, callback_info); -+ if (conn->state == INITIALIZING) { -+ return start_connection(context, conn, message, selstate, -+ callback_info); -+ } - - /* Did we already shut down this channel? */ - if (conn->state == FAILED) { -@@ -752,7 +754,7 @@ maybe_send(krb5_context context, struct conn_state *conn, - } - - /* UDP - retransmit after a previous attempt timed out. */ -- sg = &conn->x.out.sgbuf[0]; -+ sg = &conn->out.sgbuf[0]; - TRACE_SENDTO_KDC_UDP_SEND_RETRY(context, &conn->addr); - ret = send(conn->fd, SG_BUF(sg), SG_LEN(sg), 0); - if (ret < 0 || (size_t) ret != SG_LEN(sg)) { -@@ -803,6 +805,8 @@ service_tcp_fd(krb5_context context, struct conn_state *conn, - int e = 0; - ssize_t nwritten, nread; - SOCKET_WRITEV_TEMP tmp; -+ struct incoming_message *in = &conn->in; -+ struct outgoing_message *out = &conn->out; - - /* Check for a socket exception. */ - if (ssflags & SSF_EXCEPTION) -@@ -825,68 +829,68 @@ service_tcp_fd(krb5_context context, struct conn_state *conn, - /* Fall through. */ - case WRITING: - TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr); -- nwritten = SOCKET_WRITEV(conn->fd, conn->x.out.sgp, -- conn->x.out.sg_count, tmp); -+ nwritten = SOCKET_WRITEV(conn->fd, out->sgp, out->sg_count, tmp); - if (nwritten < 0) { - TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr, - SOCKET_ERRNO); - goto kill_conn; - } - while (nwritten) { -- sg_buf *sgp = conn->x.out.sgp; -+ sg_buf *sgp = out->sgp; - if ((size_t) nwritten < SG_LEN(sgp)) { - SG_ADVANCE(sgp, (size_t) nwritten); - nwritten = 0; - } else { - nwritten -= SG_LEN(sgp); -- conn->x.out.sgp++; -- conn->x.out.sg_count--; -+ out->sgp++; -+ out->sg_count--; - } - } -- if (conn->x.out.sg_count == 0) { -+ if (out->sg_count == 0) { - /* Done writing, switch to reading. */ - cm_read(selstate, conn->fd); - conn->state = READING; -- conn->x.in.bufsizebytes_read = 0; -- conn->x.in.bufsize = 0; -- conn->x.in.buf = 0; -- conn->x.in.pos = 0; -- conn->x.in.n_left = 0; -+ in->bufsizebytes_read = 0; -+ in->bufsize = 0; -+ in->pos = 0; -+ in->buf = NULL; -+ in->n_left = 0; - } - return 0; - - case READING: -- if (conn->x.in.bufsizebytes_read == 4) { -+ if (in->bufsizebytes_read == 4) { - /* Reading data. */ -- nread = SOCKET_READ(conn->fd, conn->x.in.pos, conn->x.in.n_left); -+ nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left); - if (nread <= 0) { - e = nread ? SOCKET_ERRNO : ECONNRESET; - TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e); - goto kill_conn; - } -- conn->x.in.n_left -= nread; -- conn->x.in.pos += nread; -- if (conn->x.in.n_left <= 0) -+ in->n_left -= nread; -+ in->pos += nread; -+ if (in->n_left <= 0) - return 1; - } else { - /* Reading length. */ - nread = SOCKET_READ(conn->fd, -- conn->x.in.bufsizebytes + conn->x.in.bufsizebytes_read, -- 4 - conn->x.in.bufsizebytes_read); -+ in->bufsizebytes + in->bufsizebytes_read, -+ 4 - in->bufsizebytes_read); - if (nread <= 0) { - e = nread ? SOCKET_ERRNO : ECONNRESET; - TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e); - goto kill_conn; - } -- conn->x.in.bufsizebytes_read += nread; -- if (conn->x.in.bufsizebytes_read == 4) { -- unsigned long len = load_32_be (conn->x.in.bufsizebytes); -+ in->bufsizebytes_read += nread; -+ if (in->bufsizebytes_read == 4) { -+ unsigned long len = load_32_be(in->bufsizebytes); - /* Arbitrary 1M cap. */ - if (len > 1 * 1024 * 1024) - goto kill_conn; -- conn->x.in.bufsize = conn->x.in.n_left = len; -- conn->x.in.buf = conn->x.in.pos = malloc(len); -- if (conn->x.in.buf == 0) -+ in->bufsize = in->n_left = len; -+ in->pos = 0; -+ in->buf = malloc(len); -+ if (in->buf == NULL) - goto kill_conn; - } - } -@@ -915,13 +919,13 @@ service_udp_fd(krb5_context context, struct conn_state *conn, - if (conn->state != READING) - abort(); - -- nread = recv(conn->fd, conn->x.in.buf, conn->x.in.bufsize, 0); -+ nread = recv(conn->fd, conn->in.buf, conn->in.bufsize, 0); - if (nread < 0) { - TRACE_SENDTO_KDC_UDP_ERROR_RECV(context, &conn->addr, SOCKET_ERRNO); - kill_conn(conn, selstate); - return 0; - } -- conn->x.in.pos = conn->x.in.buf + nread; -+ conn->in.pos = nread; - return 1; - } - -@@ -986,10 +990,7 @@ service_fds(krb5_context context, struct select_state *selstate, - int stop = 1; - - if (msg_handler != NULL) { -- krb5_data reply; -- -- reply.data = state->x.in.buf; -- reply.length = state->x.in.pos - state->x.in.buf; -+ krb5_data reply = make_data(state->in.buf, state->in.pos); - - stop = (msg_handler(context, &reply, msg_handler_data) != 0); - } -@@ -1051,8 +1052,7 @@ k5_sendto(krb5_context context, const krb5_data *message, - char *udpbuf = NULL; - krb5_boolean done = FALSE; - -- reply->data = 0; -- reply->length = 0; -+ *reply = empty_data(); - - /* One for use here, listing all our fds in use, and one for - * temporary use in service_fds, for the fds of interest. */ -@@ -1077,7 +1077,7 @@ k5_sendto(krb5_context context, const krb5_data *message, - /* Contact each new connection whose socktype matches socktype1. */ - if (state->addr.type != socktype1) - continue; -- if (maybe_send(context, state, sel_state, callback_info)) -+ if (maybe_send(context, state, message, sel_state, callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, - msg_handler, msg_handler_data, &winner); -@@ -1089,7 +1089,7 @@ k5_sendto(krb5_context context, const krb5_data *message, - for (state = conns; state != NULL && !done; state = state->next) { - if (state->addr.type != socktype2) - continue; -- if (maybe_send(context, state, sel_state, callback_info)) -+ if (maybe_send(context, state, message, sel_state, callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, - msg_handler, msg_handler_data, &winner); -@@ -1105,7 +1105,7 @@ k5_sendto(krb5_context context, const krb5_data *message, - delay = 4000; - for (pass = 1; pass < MAX_PASS && !done; pass++) { - for (state = conns; state != NULL && !done; state = state->next) { -- if (maybe_send(context, state, sel_state, callback_info)) -+ if (maybe_send(context, state, message, sel_state, callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, - msg_handler, msg_handler_data, &winner); -@@ -1127,10 +1127,9 @@ k5_sendto(krb5_context context, const krb5_data *message, - goto cleanup; - } - /* Success! */ -- reply->data = winner->x.in.buf; -- reply->length = winner->x.in.pos - winner->x.in.buf; -+ *reply = make_data(winner->in.buf, winner->in.pos); - retval = 0; -- winner->x.in.buf = NULL; -+ winner->in.buf = NULL; - if (server_used != NULL) - *server_used = winner->server_index; - if (remoteaddr != NULL && remoteaddrlen != 0 && *remoteaddrlen > 0) -@@ -1142,8 +1141,8 @@ cleanup: - next = state->next; - if (state->fd != INVALID_SOCKET) - closesocket(state->fd); -- if (state->state == READING && state->x.in.buf != udpbuf) -- free(state->x.in.buf); -+ if (state->state == READING && state->in.buf != udpbuf) -+ free(state->in.buf); - if (callback_info) { - callback_info->pfn_cleanup(callback_info->data, - &state->callback_buffer); --- -2.1.0 - diff --git a/SOURCES/0002-Add-helper-to-determine-if-a-KDC-is-the-master.patch b/SOURCES/0002-Add-helper-to-determine-if-a-KDC-is-the-master.patch deleted file mode 100644 index 50ae55b..0000000 --- a/SOURCES/0002-Add-helper-to-determine-if-a-KDC-is-the-master.patch +++ /dev/null @@ -1,233 +0,0 @@ -From f4b1a7e7b80ce68e57912edcd48c39ea62c73e43 Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Sun, 6 Apr 2014 18:06:14 -0400 -Subject: [PATCH 02/13] Add helper to determine if a KDC is the master - -Add a new function k5_kdc_is_master in locate_kdc.c to determine -whether a KDC matches one of the masters, and use it in -krb5_sendto_kdc. ---- - src/lib/krb5/os/locate_kdc.c | 110 +++++++++++++++++++++++++++++-------------- - src/lib/krb5/os/os-proto.h | 3 ++ - src/lib/krb5/os/sendto_kdc.c | 31 +----------- - 3 files changed, 80 insertions(+), 64 deletions(-) - -diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c -index 88d55a8..4479465 100644 ---- a/src/lib/krb5/os/locate_kdc.c -+++ b/src/lib/krb5/os/locate_kdc.c -@@ -166,6 +166,24 @@ add_host_to_list(struct serverlist *list, const char *hostname, int port, - return 0; - } - -+/* Return true if server is identical to an entry in list. */ -+static krb5_boolean -+server_list_contains(struct serverlist *list, struct server_entry *server) -+{ -+ struct server_entry *ent; -+ -+ for (ent = list->servers; ent < list->servers + list->nservers; ent++) { -+ if (server->hostname != NULL && ent->hostname != NULL && -+ strcmp(server->hostname, ent->hostname) == 0) -+ return TRUE; -+ if (server->hostname == NULL && ent->hostname == NULL && -+ server->addrlen == ent->addrlen && -+ memcmp(&server->addr, &ent->addr, server->addrlen) == 0) -+ return TRUE; -+ } -+ return FALSE; -+} -+ - static krb5_error_code - locate_srv_conf_1(krb5_context context, const krb5_data *realm, - const char * name, struct serverlist *serverlist, -@@ -529,6 +547,41 @@ dns_locate_server(krb5_context context, const krb5_data *realm, - } - #endif /* KRB5_DNS_LOOKUP */ - -+static krb5_error_code -+locate_server(krb5_context context, const krb5_data *realm, -+ struct serverlist *serverlist, enum locate_service_type svc, -+ int socktype) -+{ -+ krb5_error_code ret; -+ struct serverlist list = SERVERLIST_INIT; -+ -+ *serverlist = list; -+ -+ /* Try modules. If a module returns 0 but leaves the list empty, return an -+ * empty list. */ -+ ret = module_locate_server(context, realm, &list, svc, socktype); -+ if (ret != KRB5_PLUGIN_NO_HANDLE) -+ goto done; -+ -+ /* Try the profile. Fall back to DNS if it returns an empty list. */ -+ ret = prof_locate_server(context, realm, &list, svc, socktype); -+ if (ret) -+ goto done; -+ -+#ifdef KRB5_DNS_LOOKUP -+ if (list.nservers == 0) -+ ret = dns_locate_server(context, realm, &list, svc, socktype); -+#endif -+ -+done: -+ if (ret) { -+ k5_free_serverlist(&list); -+ return ret; -+ } -+ *serverlist = list; -+ return 0; -+} -+ - /* - * Wrapper function for the various backends - */ -@@ -538,54 +591,26 @@ k5_locate_server(krb5_context context, const krb5_data *realm, - struct serverlist *serverlist, enum locate_service_type svc, - int socktype) - { -- krb5_error_code code; -- struct serverlist al = SERVERLIST_INIT; -- -- *serverlist = al; -+ krb5_error_code ret; - -+ memset(serverlist, 0, sizeof(*serverlist)); - if (realm == NULL || realm->data == NULL || realm->data[0] == 0) { - krb5_set_error_message(context, KRB5_REALM_CANT_RESOLVE, - "Cannot find KDC for invalid realm name \"\""); - return KRB5_REALM_CANT_RESOLVE; - } - -- code = module_locate_server(context, realm, &al, svc, socktype); -- Tprintf("module_locate_server returns %d\n", code); -- if (code == KRB5_PLUGIN_NO_HANDLE) { -- /* -- * We always try the local file before DNS. Note that there -- * is no way to indicate "service not available" via the -- * config file. -- */ -- -- code = prof_locate_server(context, realm, &al, svc, socktype); -- --#ifdef KRB5_DNS_LOOKUP -- if (code == 0 && al.nservers == 0) -- code = dns_locate_server(context, realm, &al, svc, socktype); --#endif /* KRB5_DNS_LOOKUP */ -+ ret = locate_server(context, realm, serverlist, svc, socktype); -+ if (ret) -+ return ret; - -- /* We could put more heuristics here, like looking up a hostname -- of "kerberos."+REALM, etc. */ -- } -- if (code == 0) -- Tprintf ("krb5int_locate_server found %d addresses\n", -- al.nservers); -- else -- Tprintf ("krb5int_locate_server returning error code %d/%s\n", -- code, error_message(code)); -- if (code != 0) { -- k5_free_serverlist(&al); -- return code; -- } -- if (al.nservers == 0) { /* No good servers */ -- k5_free_serverlist(&al); -+ if (serverlist->nservers == 0) { -+ k5_free_serverlist(serverlist); - krb5_set_error_message(context, KRB5_REALM_UNKNOWN, - _("Cannot find KDC for realm \"%.*s\""), - realm->length, realm->data); - return KRB5_REALM_UNKNOWN; - } -- *serverlist = al; - return 0; - } - -@@ -598,3 +623,18 @@ k5_locate_kdc(krb5_context context, const krb5_data *realm, - stype = get_masters ? locate_service_master_kdc : locate_service_kdc; - return k5_locate_server(context, realm, serverlist, stype, socktype); - } -+ -+krb5_boolean -+k5_kdc_is_master(krb5_context context, const krb5_data *realm, -+ struct server_entry *server) -+{ -+ struct serverlist list; -+ krb5_boolean found; -+ -+ if (locate_server(context, realm, &list, locate_service_master_kdc, -+ server->socktype) != 0) -+ return FALSE; -+ found = server_list_contains(&list, server); -+ k5_free_serverlist(&list); -+ return found; -+} -diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h -index c6b730f..9125ba0 100644 ---- a/src/lib/krb5/os/os-proto.h -+++ b/src/lib/krb5/os/os-proto.h -@@ -76,6 +76,9 @@ krb5_error_code k5_locate_kdc(krb5_context context, const krb5_data *realm, - struct serverlist *serverlist, int get_masters, - int socktype); - -+krb5_boolean k5_kdc_is_master(krb5_context context, const krb5_data *realm, -+ struct server_entry *server); -+ - void k5_free_serverlist(struct serverlist *); - - #ifdef HAVE_NETINET_IN_H -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index 5f781d3..e3855a3 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -293,25 +293,6 @@ cm_select_or_poll(const struct select_state *in, time_ms endtime, - } - - static int --in_addrlist(struct server_entry *entry, struct serverlist *list) --{ -- size_t i; -- struct server_entry *le; -- -- for (i = 0; i < list->nservers; i++) { -- le = &list->servers[i]; -- if (entry->hostname != NULL && le->hostname != NULL && -- strcmp(entry->hostname, le->hostname) == 0) -- return 1; -- if (entry->hostname == NULL && le->hostname == NULL && -- entry->addrlen == le->addrlen && -- memcmp(&entry->addr, &le->addr, entry->addrlen) == 0) -- return 1; -- } -- return 0; --} -- --static int - check_for_svc_unavailable (krb5_context context, - const krb5_data *reply, - void *msg_handler_data) -@@ -418,17 +399,9 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message, - /* Set use_master to 1 if we ended up talking to a master when we didn't - * explicitly request to. */ - if (*use_master == 0) { -- struct serverlist mservers; -- struct server_entry *entry = &servers.servers[server_used]; -- retval = k5_locate_kdc(context, realm, &mservers, TRUE, -- entry->socktype); -- if (retval == 0) { -- if (in_addrlist(entry, &mservers)) -- *use_master = 1; -- k5_free_serverlist(&mservers); -- } -+ *use_master = k5_kdc_is_master(context, realm, -+ &servers.servers[server_used]); - TRACE_SENDTO_KDC_MASTER(context, *use_master); -- retval = 0; - } - - cleanup: --- -2.1.0 - diff --git a/SOURCES/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch b/SOURCES/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch deleted file mode 100644 index 262e7c7..0000000 --- a/SOURCES/0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch +++ /dev/null @@ -1,369 +0,0 @@ -From 9ebae7cb434b9b177c0af85c67a6d6267f46bc68 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Fri, 1 Nov 2013 09:48:13 -0400 -Subject: [PATCH 2/7] In ksu, don't stat() not-on-disk ccache residuals - -Don't assume that ccache residual names are filenames which we can -stat() usefully. Instead, use helper functions to call the library -routines to try to read the default principal name from caches, and -use whether or not that succeeds as an indication of whether or not -there's a ccache in a given location. - -ticket: 7728 ---- - src/clients/ksu/ccache.c | 60 ++++++++++++++++++++-------------- - src/clients/ksu/heuristic.c | 13 ++------ - src/clients/ksu/ksu.h | 8 +++-- - src/clients/ksu/main.c | 79 +++++++++------------------------------------ - 4 files changed, 60 insertions(+), 100 deletions(-) - -diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c -index 118fc53..5f57279 100644 ---- a/src/clients/ksu/ccache.c -+++ b/src/clients/ksu/ccache.c -@@ -62,12 +62,9 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, - { - int i=0; - krb5_ccache * cc_other; -- const char * cc_def_name; -- const char * cc_other_name; - krb5_error_code retval=0; - krb5_creds ** cc_def_creds_arr = NULL; - krb5_creds ** cc_other_creds_arr = NULL; -- struct stat st_temp; - - cc_other = (krb5_ccache *) xcalloc(1, sizeof (krb5_ccache)); - -@@ -76,16 +73,13 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, - return retval; - } - -- cc_def_name = krb5_cc_get_name(context, cc_def); -- cc_other_name = krb5_cc_get_name(context, *cc_other); -- -- if ( ! stat(cc_def_name, &st_temp)){ -+ if (ks_ccache_is_initialized(context, cc_def)) { - if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){ - return retval; - } - } - -- if (!lstat( cc_other_name, &st_temp)) -+ if (ks_ccache_name_is_initialized(context, cc_other_tag)) - return EINVAL; - - if (krb5_seteuid(0)||krb5_seteuid(target_uid)) { -@@ -540,24 +534,18 @@ krb5_error_code krb5_ccache_overwrite(context, ccs, cct, primary_principal) - krb5_ccache cct; - krb5_principal primary_principal; - { -- const char * cct_name; -- const char * ccs_name; - krb5_error_code retval=0; - krb5_principal temp_principal; - krb5_creds ** ccs_creds_arr = NULL; - int i=0; -- struct stat st_temp; - -- ccs_name = krb5_cc_get_name(context, ccs); -- cct_name = krb5_cc_get_name(context, cct); -- -- if ( ! stat(ccs_name, &st_temp)){ -+ if (ks_ccache_is_initialized(context, ccs)) { - if ((retval = krb5_get_nonexp_tkts(context, ccs, &ccs_creds_arr))){ - return retval; - } - } - -- if ( ! stat(cct_name, &st_temp)){ -+ if (ks_ccache_is_initialized(context, cct)) { - if ((retval = krb5_cc_get_principal(context, cct, &temp_principal))){ - return retval; - } -@@ -643,12 +631,10 @@ krb5_error_code krb5_ccache_filter (context, cc, prst) - krb5_creds ** cc_creds_arr = NULL; - const char * cc_name; - krb5_boolean stored; -- struct stat st_temp; - - cc_name = krb5_cc_get_name(context, cc); - -- if ( ! stat(cc_name, &st_temp)){ -- -+ if (ks_ccache_is_initialized(context, cc)) { - if (auth_debug) { - fprintf(stderr,"putting cache %s through a filter for -z option\n", cc_name); - } -@@ -713,12 +699,8 @@ krb5_error_code krb5_find_princ_in_cache (context, cc, princ, found) - { - krb5_error_code retval; - krb5_creds ** creds_list = NULL; -- const char * cc_name; -- struct stat st_temp; -- -- cc_name = krb5_cc_get_name(context, cc); - -- if ( ! stat(cc_name, &st_temp)){ -+ if (ks_ccache_is_initialized(context, cc)) { - if ((retval = krb5_get_nonexp_tkts(context, cc, &creds_list))){ - return retval; - } -@@ -727,3 +709,33 @@ krb5_error_code krb5_find_princ_in_cache (context, cc, princ, found) - *found = krb5_find_princ_in_cred_list(context, creds_list, princ); - return 0; - } -+ -+krb5_boolean -+ks_ccache_name_is_initialized(krb5_context context, const char *cctag) -+{ -+ krb5_boolean result; -+ krb5_ccache cc; -+ -+ if (krb5_cc_resolve(context, cctag, &cc) != 0) -+ return FALSE; -+ result = ks_ccache_is_initialized(context, cc); -+ krb5_cc_close(context, cc); -+ -+ return result; -+} -+ -+krb5_boolean -+ks_ccache_is_initialized(krb5_context context, krb5_ccache cc) -+{ -+ krb5_principal princ; -+ krb5_error_code retval; -+ -+ if (cc == NULL) -+ return FALSE; -+ -+ retval = krb5_cc_get_principal(context, cc, &princ); -+ if (retval == 0) -+ krb5_free_principal(context, princ); -+ -+ return retval == 0; -+} -diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c -index 99b54e5..f73b8eb 100644 ---- a/src/clients/ksu/heuristic.c -+++ b/src/clients/ksu/heuristic.c -@@ -397,12 +397,8 @@ krb5_error_code find_either_ticket (context, cc, client, end_server, found) - krb5_principal kdc_server; - krb5_error_code retval; - krb5_boolean temp_found = FALSE; -- const char * cc_source_name; -- struct stat st_temp; - -- cc_source_name = krb5_cc_get_name(context, cc); -- -- if ( ! stat(cc_source_name, &st_temp)){ -+ if (ks_ccache_is_initialized(context, cc)) { - - retval = find_ticket(context, cc, client, end_server, &temp_found); - if (retval) -@@ -539,7 +535,6 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid, - { - - princ_info princ_trials[10]; -- const char * cc_source_name; - krb5_principal cc_def_princ = NULL; - krb5_principal temp_client; - krb5_principal target_client; -@@ -551,7 +546,6 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid, - struct stat tb; - int count =0; - int i; -- struct stat st_temp; - - *path_out = 0; - -@@ -559,10 +553,7 @@ krb5_error_code get_best_princ_for_target(context, source_uid, target_uid, - if (options->princ) - return 0; - -- cc_source_name = krb5_cc_get_name(context, cc_source); -- -- -- if (! stat(cc_source_name, &st_temp)) { -+ if (ks_ccache_is_initialized(context, cc_source)) { - retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ); - if (retval) - return retval; -diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h -index 9e0c613..e1e34f1 100644 ---- a/src/clients/ksu/ksu.h -+++ b/src/clients/ksu/ksu.h -@@ -141,6 +141,12 @@ extern krb5_error_code krb5_store_some_creds - (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **, - krb5_principal, krb5_boolean *); - -+extern krb5_boolean ks_ccache_name_is_initialized -+(krb5_context, const char *); -+ -+extern krb5_boolean ks_ccache_is_initialized -+(krb5_context, krb5_ccache); -+ - extern krb5_error_code krb5_ccache_refresh - (krb5_context, krb5_ccache); - -@@ -198,8 +204,6 @@ extern int standard_shell (char *); - - extern krb5_error_code get_params (int *, int, char **, char ***); - --extern char *get_dir_of_file (const char *); -- - /* heuristic.c */ - extern krb5_error_code get_all_princ_from_file (FILE *, char ***); - -diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c -index 62f3bc0..8c49f94 100644 ---- a/src/clients/ksu/main.c -+++ b/src/clients/ksu/main.c -@@ -51,7 +51,6 @@ static void print_status( const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 1, 2))) - #endif - ; --char * get_dir_of_file(); - - /* Note -e and -a options are mutually exclusive */ - /* insure the proper specification of target user as well as catching -@@ -96,7 +95,6 @@ main (argc, argv) - const char * cc_source_tag = NULL; - uid_t source_gid; - const char * cc_source_tag_tmp = NULL; -- char * cc_target_tag_tmp=NULL; - char * cmd = NULL, * exec_cmd = NULL; - int errflg = 0; - krb5_boolean auth_val; -@@ -112,11 +110,9 @@ main (argc, argv) - extern char * getpass(), *crypt(); - int pargc; - char ** pargv; -- struct stat st_temp; - krb5_boolean stored = FALSE; - krb5_principal kdc_server; - krb5_boolean zero_password; -- char * dir_of_cc_target; - krb5_boolean restrict_creds; - - options.opt = KRB5_DEFAULT_OPTIONS; -@@ -266,9 +262,10 @@ main (argc, argv) - if ( strchr(cc_source_tag, ':')){ - cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1; - -- if( stat( cc_source_tag_tmp, &st_temp)){ -+ if (!ks_ccache_name_is_initialized(ksu_context, -+ cc_source_tag)) { - com_err(prog_name, errno, -- _("while looking for credentials file %s"), -+ _("while looking for credentials cache %s"), - cc_source_tag_tmp); - exit (1); - } -@@ -419,32 +416,18 @@ main (argc, argv) - exit(1); - } - -- if (cc_target_tag == NULL) { -- -- cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE ,sizeof(char)); -- /* make sure that the new ticket file does not already exist -- This is run as source_uid because it is reasonable to -- require the source user to have write to where the target -- cache will be created.*/ -- -- do { -- snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d", -- KRB5_SECONDARY_CACHE, -- (long) target_uid, gen_sym()); -- cc_target_tag_tmp = strchr(cc_target_tag, ':') + 1; -- -- }while ( !stat ( cc_target_tag_tmp, &st_temp)); -- } -- -- -- dir_of_cc_target = get_dir_of_file(cc_target_tag_tmp); -- -- if (access(dir_of_cc_target, R_OK | W_OK )){ -- fprintf(stderr, -- _("%s does not have correct permissions for %s\n"), -- source_user, cc_target_tag); -- exit(1); -- } -+ /* -+ * Make sure that the new ticket file does not already exist. -+ * This is run as source_uid because it is reasonable to -+ * require the source user to have write to where the target -+ * cache will be created. -+ */ -+ cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE, sizeof(char)); -+ do { -+ snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d", -+ KRB5_SECONDARY_CACHE, -+ (long)target_uid, gen_sym()); -+ } while (ks_ccache_name_is_initialized(ksu_context, cc_target_tag)); - - if (auth_debug){ - fprintf(stderr, " source cache = %s\n", cc_source_tag); -@@ -747,13 +730,6 @@ main (argc, argv) - exit(1); - } - -- if (access( cc_target_tag_tmp, R_OK | W_OK )){ -- com_err(prog_name, errno, -- _("%s does not have correct permissions for %s, %s aborted"), -- target_user, cc_target_tag_tmp, prog_name); -- exit(1); -- } -- - if ( cc_source) - krb5_cc_close(ksu_context, cc_source); - -@@ -873,8 +849,6 @@ static void sweep_up(context, cc) - krb5_ccache cc; - { - krb5_error_code retval; -- const char * cc_name; -- struct stat st_temp; - - krb5_seteuid(0); - if (krb5_seteuid(target_uid) < 0) { -@@ -883,8 +857,7 @@ static void sweep_up(context, cc) - exit(1); - } - -- cc_name = krb5_cc_get_name(context, cc); -- if ( ! stat(cc_name, &st_temp)){ -+ if (ks_ccache_is_initialized(context, cc)) { - if ((retval = krb5_cc_destroy(context, cc))) - com_err(prog_name, retval, _("while destroying cache")); - } -@@ -937,26 +910,6 @@ void print_status(const char *fmt, ...) - } - } - -- --char *get_dir_of_file(path) -- const char *path; --{ -- char * temp_path; -- char * ptr; -- -- temp_path = xstrdup(path); -- -- if ((ptr = strrchr( temp_path, '/'))) { -- *ptr = '\0'; -- } else { -- free (temp_path); -- temp_path = xmalloc(MAXPATHLEN); -- if (temp_path) -- getcwd(temp_path, MAXPATHLEN); -- } -- return temp_path; --} -- - krb5_error_code - ksu_tgtname(context, server, client, tgtprinc) - krb5_context context; --- -2.0.4 - diff --git a/SOURCES/0003-Use-an-intermediate-memory-cache-in-ksu.patch b/SOURCES/0003-Use-an-intermediate-memory-cache-in-ksu.patch deleted file mode 100644 index 4bef600..0000000 --- a/SOURCES/0003-Use-an-intermediate-memory-cache-in-ksu.patch +++ /dev/null @@ -1,417 +0,0 @@ -From dccc80a469b1925fcfe7697406a69912efe4baa1 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Wed, 30 Oct 2013 21:45:35 -0400 -Subject: [PATCH 3/7] Use an intermediate memory cache in ksu - -Instead of copying source or obtained creds into the target cache and -changing ownership if everything succeeds, copy them into a MEMORY: -cache and then, if everything succeeds, create the target cache as the -target user. - -We no longer need to clean up the temporary ccache when exiting in -most error cases. - -Use a fake principal name ("_ksu/_ksu@_ksu") as the primary holder of -the temporary cache so that we won't accidentally select it when we -make a subsequent call to krb5_cc_cache_match() (to be added in a -later patch) to find the target location where the creds should be -stored for use while running as the target user. ---- - src/clients/ksu/ccache.c | 10 +-- - src/clients/ksu/ksu.h | 4 +- - src/clients/ksu/main.c | 156 ++++++++++++++++++++++++----------------------- - 3 files changed, 87 insertions(+), 83 deletions(-) - -diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c -index 5f57279..d0fc389 100644 ---- a/src/clients/ksu/ccache.c -+++ b/src/clients/ksu/ccache.c -@@ -47,14 +47,15 @@ void show_credential(); - */ - - krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, -- primary_principal, restrict_creds, cc_out, -- stored, target_uid) -+ primary_principal, restrict_creds, -+ target_principal, cc_out, stored, target_uid) - /* IN */ - krb5_context context; - krb5_ccache cc_def; - char *cc_other_tag; - krb5_principal primary_principal; - krb5_boolean restrict_creds; -+ krb5_principal target_principal; - uid_t target_uid; - /* OUT */ - krb5_ccache *cc_out; -@@ -86,10 +87,9 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, - return errno; - } - -- -- if ((retval = krb5_cc_initialize(context, *cc_other, primary_principal))){ -+ retval = krb5_cc_initialize(context, *cc_other, target_principal); -+ if (retval) - return retval; -- } - - if (restrict_creds) { - retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr, -diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h -index e1e34f1..08bf01b 100644 ---- a/src/clients/ksu/ksu.h -+++ b/src/clients/ksu/ksu.h -@@ -106,8 +106,8 @@ extern krb5_error_code get_best_principal - - /* ccache.c */ - extern krb5_error_code krb5_ccache_copy --(krb5_context, krb5_ccache, char *, krb5_principal, -- krb5_boolean, krb5_ccache *, krb5_boolean *, uid_t); -+(krb5_context, krb5_ccache, char *, krb5_principal, krb5_boolean, -+ krb5_principal, krb5_ccache *, krb5_boolean *, uid_t); - - extern krb5_error_code krb5_store_all_creds - (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **); -diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c -index 8c49f94..d1bb8ca 100644 ---- a/src/clients/ksu/main.c -+++ b/src/clients/ksu/main.c -@@ -42,10 +42,13 @@ char * gb_err = NULL; - int quiet = 0; - /***********/ - -+#define KS_TEMPORARY_CACHE "MEMORY:_ksu" -+#define KS_TEMPORARY_PRINC "_ksu/_ksu@_ksu" - #define _DEF_CSH "/bin/csh" - static int set_env_var (char *, char *); - static void sweep_up (krb5_context, krb5_ccache); - static char * ontty (void); -+static krb5_error_code set_ccname_env(krb5_context, krb5_ccache); - static void print_status( const char *fmt, ...) - #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) - __attribute__ ((__format__ (__printf__, 1, 2))) -@@ -84,8 +87,8 @@ main (argc, argv) - int option=0; - int statusp=0; - krb5_error_code retval = 0; -- krb5_principal client = NULL; -- krb5_ccache cc_target = NULL; -+ krb5_principal client = NULL, tmp_princ = NULL; -+ krb5_ccache cc_tmp = NULL, cc_target = NULL; - krb5_context ksu_context; - char * cc_target_tag = NULL; - char * target_user = NULL; -@@ -93,7 +96,6 @@ main (argc, argv) - - krb5_ccache cc_source = NULL; - const char * cc_source_tag = NULL; -- uid_t source_gid; - const char * cc_source_tag_tmp = NULL; - char * cmd = NULL, * exec_cmd = NULL; - int errflg = 0; -@@ -342,8 +344,6 @@ main (argc, argv) - /* allocate space and copy the usernamane there */ - source_user = xstrdup(pwd->pw_name); - source_uid = pwd->pw_uid; -- source_gid = pwd->pw_gid; -- - - if (!strcmp(SOURCE_USER_LOGIN, target_user)){ - target_user = xstrdup (source_user); -@@ -435,25 +435,32 @@ main (argc, argv) - } - - /* -- Only when proper authentication and authorization -- takes place, the target user becomes the owner of the cache. -- */ -- -- /* we continue to run as source uid until -- the middle of the copy, when becomewe become the target user -- The cache is owned by the target user.*/ -+ * After proper authentication and authorization, populate a cache for the -+ * target user. -+ */ - -+ /* -+ * We read the set of creds we want to copy from the source ccache as the -+ * source uid, become root for authentication, and then become the target -+ * user to handle authorization and creating the target user's cache. -+ */ - - /* if root ksu's to a regular user, then - then only the credentials for that particular user - should be copied */ - - restrict_creds = (source_uid == 0) && (target_uid != 0); -- retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, client, -- restrict_creds, &cc_target, &stored, target_uid); -+ retval = krb5_parse_name(ksu_context, KS_TEMPORARY_PRINC, &tmp_princ); -+ if (retval) { -+ com_err(prog_name, retval, _("while parsing temporary name")); -+ exit(1); -+ } -+ retval = krb5_ccache_copy(ksu_context, cc_source, KS_TEMPORARY_CACHE, -+ client, restrict_creds, tmp_princ, &cc_tmp, -+ &stored, 0); - if (retval) { - com_err(prog_name, retval, _("while copying cache %s to %s"), -- krb5_cc_get_name(ksu_context, cc_source), cc_target_tag); -+ krb5_cc_get_name(ksu_context, cc_source), KS_TEMPORARY_CACHE); - exit(1); - } - -@@ -473,7 +480,6 @@ main (argc, argv) - &kdc_server))){ - com_err(prog_name, retval, - _("while creating tgt for local realm")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - -@@ -481,13 +487,12 @@ main (argc, argv) - "enter it here and are logged\n")); - fprintf(stderr, _(" in remotely using an unsecure " - "(non-encrypted) channel.\n")); -- if (krb5_get_tkt_via_passwd (ksu_context, &cc_target, client, -- kdc_server, &options, -- &zero_password) == FALSE){ -+ if (krb5_get_tkt_via_passwd(ksu_context, &cc_tmp, client, -+ kdc_server, &options, -+ &zero_password) == FALSE){ - - if (zero_password == FALSE){ - fprintf(stderr, _("Goodbye\n")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - -@@ -506,48 +511,20 @@ main (argc, argv) - if (source_uid && (source_uid != target_uid)) { - char * client_name; - -- auth_val = krb5_auth_check(ksu_context, client, localhostname, &options, -- target_user,cc_target, &path_passwd, target_uid); -+ auth_val = krb5_auth_check(ksu_context, client, localhostname, -+ &options, target_user, cc_tmp, -+ &path_passwd, target_uid); - - /* if Kerberos authentication failed then exit */ - if (auth_val ==FALSE){ - fprintf(stderr, _("Authentication failed.\n")); - syslog(LOG_WARNING, "'%s %s' authentication failed for %s%s", - prog_name,target_user,source_user,ontty()); -- sweep_up(ksu_context, cc_target); - exit(1); - } - --#if 0 -- /* At best, this avoids a single kdc request -- It is hard to implement dealing with file permissions and -- is unnecessary. It is important -- to properly handle races in chown if this code is ever re-enabled. -- */ -- /* cache the tickets if possible in the source cache */ -- if (!path_passwd){ -- -- if ((retval = krb5_ccache_overwrite(ksu_context, cc_target, cc_source, -- client))){ -- com_err (prog_name, retval, -- "while copying cache %s to %s", -- krb5_cc_get_name(ksu_context, cc_target), -- krb5_cc_get_name(ksu_context, cc_source)); -- sweep_up(ksu_context, cc_target); -- exit(1); -- } -- if (chown(cc_source_tag_tmp, source_uid, source_gid)){ -- com_err(prog_name, errno, -- "while changing owner for %s", -- cc_source_tag_tmp); -- exit(1); -- } -- } --#endif /*0*/ -- - if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) { - com_err(prog_name, retval, _("When unparsing name")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - -@@ -560,7 +537,6 @@ main (argc, argv) - if (krb5_seteuid(target_uid)) { - com_err(prog_name, errno, _("while switching to target for " - "authorization check")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - -@@ -568,14 +544,12 @@ main (argc, argv) - cmd, &authorization_val, &exec_cmd))){ - com_err(prog_name,retval, _("while checking authorization")); - krb5_seteuid(0); /*So we have some chance of sweeping up*/ -- sweep_up(ksu_context, cc_target); - exit(1); - } - - if (krb5_seteuid(0)) { - com_err(prog_name, errno, _("while switching back from target " - "after authorization check")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - if (authorization_val == TRUE){ -@@ -617,25 +591,25 @@ main (argc, argv) - - } - -- sweep_up(ksu_context, cc_target); - exit(1); - } - } - - if( some_rest_copy){ -- if ((retval = krb5_ccache_filter(ksu_context, cc_target, client))){ -+ retval = krb5_ccache_filter(ksu_context, cc_tmp, client); -+ if (retval) { - com_err(prog_name,retval, _("while calling cc_filter")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - } - - if (all_rest_copy){ -- if ((retval = krb5_cc_initialize(ksu_context, cc_target, client))){ -+ retval = krb5_cc_initialize(ksu_context, cc_tmp, tmp_princ); -+ if (retval) { - com_err(prog_name, retval, _("while erasing target cache")); - exit(1); - } -- -+ stored = FALSE; - } - - /* get the shell of the user, this will be the shell used by su */ -@@ -653,7 +627,6 @@ main (argc, argv) - - if (!standard_shell(target_pwd->pw_shell) && source_uid) { - fprintf(stderr, _("ksu: permission denied (shell).\n")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - #endif /* HAVE_GETUSERSHELL */ -@@ -663,43 +636,28 @@ main (argc, argv) - if(set_env_var("USER", target_pwd->pw_name)){ - fprintf(stderr, - _("ksu: couldn't set environment variable USER\n")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - } - - if(set_env_var( "HOME", target_pwd->pw_dir)){ - fprintf(stderr, _("ksu: couldn't set environment variable HOME\n")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - - if(set_env_var( "SHELL", shell)){ - fprintf(stderr, _("ksu: couldn't set environment variable SHELL\n")); -- sweep_up(ksu_context, cc_target); -- exit(1); -- } -- -- /* set the cc env name to target */ -- -- if(set_env_var( KRB5_ENV_CCNAME, cc_target_tag)){ -- fprintf(stderr, _("ksu: couldn't set environment variable %s\n"), -- KRB5_ENV_CCNAME); -- sweep_up(ksu_context, cc_target); - exit(1); - } - - /* set permissions */ - if (setgid(target_pwd->pw_gid) < 0) { - perror("ksu: setgid"); -- sweep_up(ksu_context, cc_target); - exit(1); - } - -- - if (initgroups(target_user, target_pwd->pw_gid)) { - fprintf(stderr, _("ksu: initgroups failed.\n")); -- sweep_up(ksu_context, cc_target); - exit(1); - } - -@@ -719,13 +677,36 @@ main (argc, argv) - */ - if (setluid((uid_t) pwd->pw_uid) < 0) { - perror("setluid"); -- sweep_up(ksu_context, cc_target); - exit(1); - } - #endif /* HAVE_SETLUID */ - - if (setuid(target_pwd->pw_uid) < 0) { - perror("ksu: setuid"); -+ exit(1); -+ } -+ -+ retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag, -+ client, FALSE, client, &cc_target, &stored, -+ target_pwd->pw_uid); -+ if (retval) { -+ com_err(prog_name, retval, _("while copying cache %s to %s"), -+ KS_TEMPORARY_CACHE, cc_target_tag); -+ exit(1); -+ } -+ -+ if (stored && !ks_ccache_is_initialized(ksu_context, cc_target)) { -+ com_err(prog_name, errno, -+ _("%s does not have correct permissions for %s, %s aborted"), -+ target_user, cc_target_tag, prog_name); -+ exit(1); -+ } -+ -+ free(cc_target_tag); -+ -+ /* Set the cc env name to target. */ -+ retval = set_ccname_env(ksu_context, cc_target); -+ if (retval != 0) { - sweep_up(ksu_context, cc_target); - exit(1); - } -@@ -799,6 +780,29 @@ main (argc, argv) - } - } - -+/* Set KRB5CCNAME in the environment to point to ccache. Print an error -+ * message on failure. */ -+static krb5_error_code -+set_ccname_env(krb5_context ksu_context, krb5_ccache ccache) -+{ -+ krb5_error_code retval; -+ char *ccname; -+ -+ retval = krb5_cc_get_full_name(ksu_context, ccache, &ccname); -+ if (retval) { -+ com_err(prog_name, retval, _("while reading cache name from ccache")); -+ return retval; -+ } -+ if (set_env_var(KRB5_ENV_CCNAME, ccname)) { -+ retval = errno; -+ fprintf(stderr, -+ _("ksu: couldn't set environment variable %s\n"), -+ KRB5_ENV_CCNAME); -+ } -+ krb5_free_string(ksu_context, ccname); -+ return retval; -+} -+ - #ifdef HAVE_GETUSERSHELL - - int standard_shell(sh) --- -2.0.4 - diff --git a/SOURCES/0003-Use-k5_transport-_strategy-enums-for-k5_sendto.patch b/SOURCES/0003-Use-k5_transport-_strategy-enums-for-k5_sendto.patch deleted file mode 100644 index ba3f91c..0000000 --- a/SOURCES/0003-Use-k5_transport-_strategy-enums-for-k5_sendto.patch +++ /dev/null @@ -1,913 +0,0 @@ -From 9c6be00daca0b80aed94ec9680724f95e6be92e1 Mon Sep 17 00:00:00 2001 -From: "Robbie Harwood (frozencemetery)" -Date: Thu, 15 Aug 2013 15:55:52 -0400 -Subject: [PATCH 03/13] Use k5_transport(_strategy) enums for k5_sendto - -In k5_sendto and k5_locate_server, replace "socktype" parameters with -a new enumerator k5_transport, so that we can add new transports which -are not in the socket type namespace. Control the order in which we -make connections of different types using a new k5_transport_strategy -enumerator, to simplify the logic for adding new transports later. -Control the result of k5_locate_server with a no_udp boolean rather -than a socket type. - -[ghudson@mit.edu: renamed type to k5_transport; k5_locate_server - no_udp change; clarified commit message; fix for Solaris getaddrinfo] -[kaduk@mit.edu: name variables of type k5_transport 'transport'] -[nalin@redhat.com: use transport rather than sock_type in more places, - add and use k5_transport_strategy, update the test program] - -ticket: 7929 ---- - src/lib/krb5/os/changepw.c | 31 +++++----- - src/lib/krb5/os/hostrealm_domain.c | 2 +- - src/lib/krb5/os/locate_kdc.c | 75 ++++++++++++---------- - src/lib/krb5/os/os-proto.h | 27 +++++--- - src/lib/krb5/os/sendto_kdc.c | 123 +++++++++++++++++++++++-------------- - src/lib/krb5/os/t_locate_kdc.c | 24 ++++---- - src/lib/krb5/os/t_std_conf.c | 2 +- - src/lib/krb5/os/t_trace.c | 6 +- - src/lib/krb5/os/t_trace.ref | 4 +- - src/lib/krb5/os/trace.c | 6 +- - 10 files changed, 178 insertions(+), 122 deletions(-) - -diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c -index 4d8abd9..a1c9885 100644 ---- a/src/lib/krb5/os/changepw.c -+++ b/src/lib/krb5/os/changepw.c -@@ -59,25 +59,25 @@ struct sendto_callback_context { - - static krb5_error_code - locate_kpasswd(krb5_context context, const krb5_data *realm, -- struct serverlist *serverlist, int socktype) -+ struct serverlist *serverlist, krb5_boolean no_udp) - { - krb5_error_code code; - - code = k5_locate_server(context, realm, serverlist, locate_service_kpasswd, -- socktype); -+ no_udp); - - if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) { - code = k5_locate_server(context, realm, serverlist, -- locate_service_kadmin, SOCK_STREAM); -+ locate_service_kadmin, TRUE); - if (!code) { -- /* Success with admin_server but now we need to change the -- port number to use DEFAULT_KPASSWD_PORT and the socktype. */ -+ /* Success with admin_server but now we need to change the port -+ * number to use DEFAULT_KPASSWD_PORT and the transport. */ - size_t i; - for (i = 0; i < serverlist->nservers; i++) { - struct server_entry *s = &serverlist->servers[i]; - krb5_ui_2 kpasswd_port = htons(DEFAULT_KPASSWD_PORT); -- if (socktype != SOCK_STREAM) -- s->socktype = socktype; -+ if (!no_udp && s->transport == TCP) -+ s->transport = TCP_OR_UDP; - if (s->hostname != NULL) - s->port = kpasswd_port; - else if (s->family == AF_INET) -@@ -214,7 +214,7 @@ change_set_password(krb5_context context, - krb5_data *result_string) - { - krb5_data chpw_rep; -- krb5_boolean use_tcp = 0; -+ krb5_boolean no_udp = FALSE; - GETSOCKNAME_ARG3_TYPE addrlen; - krb5_error_code code = 0; - char *code_string; -@@ -247,9 +247,10 @@ change_set_password(krb5_context context, - callback_ctx.local_seq_num = callback_ctx.auth_context->local_seq_number; - - do { -- int socktype = (use_tcp ? SOCK_STREAM : SOCK_DGRAM); -+ k5_transport_strategy strategy = no_udp ? NO_UDP : UDP_FIRST; -+ - code = locate_kpasswd(callback_ctx.context, &creds->server->realm, &sl, -- socktype); -+ no_udp); - if (code) - break; - -@@ -260,7 +261,7 @@ change_set_password(krb5_context context, - callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup; - krb5_free_data_contents(callback_ctx.context, &chpw_rep); - -- code = k5_sendto(callback_ctx.context, NULL, &sl, socktype, 0, -+ code = k5_sendto(callback_ctx.context, NULL, &sl, strategy, - &callback_info, &chpw_rep, ss2sa(&remote_addr), - &addrlen, NULL, NULL, NULL); - if (code) { -@@ -277,9 +278,9 @@ change_set_password(krb5_context context, - result_string); - - if (code) { -- if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !use_tcp) { -+ if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !no_udp) { - k5_free_serverlist(&sl); -- use_tcp = 1; -+ no_udp = 1; - continue; - } - -@@ -305,9 +306,9 @@ change_set_password(krb5_context context, - strncpy(result_code_string->data, code_string, result_code_string->length); - } - -- if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !use_tcp) { -+ if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !no_udp) { - k5_free_serverlist(&sl); -- use_tcp = 1; -+ no_udp = 1; - } else { - break; - } -diff --git a/src/lib/krb5/os/hostrealm_domain.c b/src/lib/krb5/os/hostrealm_domain.c -index dc9cc59..2228df0 100644 ---- a/src/lib/krb5/os/hostrealm_domain.c -+++ b/src/lib/krb5/os/hostrealm_domain.c -@@ -85,7 +85,7 @@ domain_fallback_realm(krb5_context context, krb5_hostrealm_moddata data, - suffix = uhost; - while (limit-- >= 0 && (dot = strchr(suffix, '.')) != NULL) { - drealm = string2data((char *)suffix); -- if (k5_locate_kdc(context, &drealm, &slist, FALSE, SOCK_DGRAM) == 0) { -+ if (k5_locate_kdc(context, &drealm, &slist, FALSE, FALSE) == 0) { - k5_free_serverlist(&slist); - ret = k5_make_realmlist(suffix, realms_out); - goto cleanup; -diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c -index 4479465..4c8aead 100644 ---- a/src/lib/krb5/os/locate_kdc.c -+++ b/src/lib/krb5/os/locate_kdc.c -@@ -129,7 +129,7 @@ new_server_entry(struct serverlist *list) - - /* Add an address entry to list. */ - static int --add_addr_to_list(struct serverlist *list, int socktype, int family, -+add_addr_to_list(struct serverlist *list, k5_transport transport, int family, - size_t addrlen, struct sockaddr *addr) - { - struct server_entry *entry; -@@ -137,7 +137,7 @@ add_addr_to_list(struct serverlist *list, int socktype, int family, - entry = new_server_entry(list); - if (entry == NULL) - return ENOMEM; -- entry->socktype = socktype; -+ entry->transport = transport; - entry->family = family; - entry->hostname = NULL; - entry->addrlen = addrlen; -@@ -149,14 +149,14 @@ add_addr_to_list(struct serverlist *list, int socktype, int family, - /* Add a hostname entry to list. */ - static int - add_host_to_list(struct serverlist *list, const char *hostname, int port, -- int socktype, int family) -+ k5_transport transport, int family) - { - struct server_entry *entry; - - entry = new_server_entry(list); - if (entry == NULL) - return ENOMEM; -- entry->socktype = socktype; -+ entry->transport = transport; - entry->family = family; - entry->hostname = strdup(hostname); - if (entry->hostname == NULL) -@@ -187,7 +187,7 @@ server_list_contains(struct serverlist *list, struct server_entry *server) - static krb5_error_code - locate_srv_conf_1(krb5_context context, const krb5_data *realm, - const char * name, struct serverlist *serverlist, -- int socktype, int udpport, int sec_udpport) -+ k5_transport transport, int udpport, int sec_udpport) - { - const char *realm_srv_names[4]; - char **hostlist, *host, *port, *cp; -@@ -255,12 +255,12 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm, - *cp = '\0'; - } - -- code = add_host_to_list(serverlist, host, p1, socktype, AF_UNSPEC); -+ code = add_host_to_list(serverlist, host, p1, transport, AF_UNSPEC); - /* Second port is for IPv4 UDP only, and should possibly go away as - * it was originally a krb4 compatibility measure. */ - if (code == 0 && p2 != 0 && -- (socktype == 0 || socktype == SOCK_DGRAM)) -- code = add_host_to_list(serverlist, host, p2, SOCK_DGRAM, AF_INET); -+ (transport == TCP_OR_UDP || transport == UDP)) -+ code = add_host_to_list(serverlist, host, p2, UDP, AF_INET); - if (code) - goto cleanup; - } -@@ -278,7 +278,8 @@ krb5_locate_srv_conf(krb5_context context, const krb5_data *realm, - { - krb5_error_code ret; - -- ret = locate_srv_conf_1(context, realm, name, al, 0, udpport, sec_udpport); -+ ret = locate_srv_conf_1(context, realm, name, al, TCP_OR_UDP, udpport, -+ sec_udpport); - if (ret) - return ret; - if (al->nservers == 0) /* Couldn't resolve any KDC names */ -@@ -294,7 +295,7 @@ locate_srv_dns_1(const krb5_data *realm, const char *service, - { - struct srv_dns_entry *head = NULL, *entry = NULL; - krb5_error_code code = 0; -- int socktype; -+ k5_transport transport; - - code = krb5int_make_srv_query_realm(realm, service, protocol, &head); - if (code) -@@ -310,9 +311,9 @@ locate_srv_dns_1(const krb5_data *realm, const char *service, - } - - for (entry = head; entry != NULL; entry = entry->next) { -- socktype = (strcmp(protocol, "_tcp") == 0) ? SOCK_STREAM : SOCK_DGRAM; -+ transport = (strcmp(protocol, "_tcp") == 0) ? TCP : UDP; - code = add_host_to_list(serverlist, entry->host, htons(entry->port), -- socktype, AF_UNSPEC); -+ transport, AF_UNSPEC); - if (code) - goto cleanup; - } -@@ -341,6 +342,7 @@ module_callback(void *cbdata, int socktype, struct sockaddr *sa) - { - struct module_callback_data *d = cbdata; - size_t addrlen; -+ k5_transport transport; - - if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) - return 0; -@@ -350,7 +352,8 @@ module_callback(void *cbdata, int socktype, struct sockaddr *sa) - addrlen = sizeof(struct sockaddr_in6); - else - return 0; -- if (add_addr_to_list(d->list, socktype, sa->sa_family, addrlen, -+ transport = (socktype == SOCK_STREAM) ? TCP : UDP; -+ if (add_addr_to_list(d->list, transport, sa->sa_family, addrlen, - sa) != 0) { - /* Assumes only error is ENOMEM. */ - d->out_of_mem = 1; -@@ -362,14 +365,14 @@ module_callback(void *cbdata, int socktype, struct sockaddr *sa) - static krb5_error_code - module_locate_server(krb5_context ctx, const krb5_data *realm, - struct serverlist *serverlist, -- enum locate_service_type svc, int socktype) -+ enum locate_service_type svc, k5_transport transport) - { - struct krb5plugin_service_locate_result *res = NULL; - krb5_error_code code; - struct krb5plugin_service_locate_ftable *vtbl = NULL; - void **ptrs; - char *realmz; /* NUL-terminated realm */ -- int i; -+ int socktype, i; - struct module_callback_data cbdata = { 0, }; - const char *msg; - -@@ -413,11 +416,11 @@ module_locate_server(krb5_context ctx, const krb5_data *realm, - if (code) - continue; - -- code = vtbl->lookup(blob, svc, realmz, -- (socktype != 0) ? socktype : SOCK_DGRAM, AF_UNSPEC, -+ socktype = (transport == TCP) ? SOCK_STREAM : SOCK_DGRAM; -+ code = vtbl->lookup(blob, svc, realmz, socktype, AF_UNSPEC, - module_callback, &cbdata); - /* Also ask for TCP addresses if we got UDP addresses and want both. */ -- if (code == 0 && socktype == 0) { -+ if (code == 0 && transport == TCP_OR_UDP) { - code = vtbl->lookup(blob, svc, realmz, SOCK_STREAM, AF_UNSPEC, - module_callback, &cbdata); - if (code == KRB5_PLUGIN_NO_HANDLE) -@@ -459,7 +462,7 @@ module_locate_server(krb5_context ctx, const krb5_data *realm, - static krb5_error_code - prof_locate_server(krb5_context context, const krb5_data *realm, - struct serverlist *serverlist, enum locate_service_type svc, -- int socktype) -+ k5_transport transport) - { - const char *profname; - int dflport1, dflport2 = 0; -@@ -495,7 +498,7 @@ prof_locate_server(krb5_context context, const krb5_data *realm, - return EBUSY; /* XXX */ - } - -- return locate_srv_conf_1(context, realm, profname, serverlist, socktype, -+ return locate_srv_conf_1(context, realm, profname, serverlist, transport, - dflport1, dflport2); - } - -@@ -503,7 +506,7 @@ prof_locate_server(krb5_context context, const krb5_data *realm, - static krb5_error_code - dns_locate_server(krb5_context context, const krb5_data *realm, - struct serverlist *serverlist, enum locate_service_type svc, -- int socktype) -+ k5_transport transport) - { - const char *dnsname; - int use_dns = _krb5_use_dns_kdc(context); -@@ -533,12 +536,12 @@ dns_locate_server(krb5_context context, const krb5_data *realm, - } - - code = 0; -- if (socktype == SOCK_DGRAM || socktype == 0) { -+ if (transport == UDP || transport == TCP_OR_UDP) { - code = locate_srv_dns_1(realm, dnsname, "_udp", serverlist); - if (code) - Tprintf("dns udp lookup returned error %d\n", code); - } -- if ((socktype == SOCK_STREAM || socktype == 0) && code == 0) { -+ if ((transport == TCP || transport == TCP_OR_UDP) && code == 0) { - code = locate_srv_dns_1(realm, dnsname, "_tcp", serverlist); - if (code) - Tprintf("dns tcp lookup returned error %d\n", code); -@@ -547,10 +550,16 @@ dns_locate_server(krb5_context context, const krb5_data *realm, - } - #endif /* KRB5_DNS_LOOKUP */ - -+/* -+ * Try all of the server location methods in sequence. transport must be -+ * TCP_OR_UDP, TCP, or UDP. It is applied to hostname entries in the profile -+ * and affects whether we query modules or DNS for UDP or TCP or both, but does -+ * not restrict a method from returning entries of other transports. -+ */ - static krb5_error_code - locate_server(krb5_context context, const krb5_data *realm, - struct serverlist *serverlist, enum locate_service_type svc, -- int socktype) -+ k5_transport transport) - { - krb5_error_code ret; - struct serverlist list = SERVERLIST_INIT; -@@ -559,18 +568,18 @@ locate_server(krb5_context context, const krb5_data *realm, - - /* Try modules. If a module returns 0 but leaves the list empty, return an - * empty list. */ -- ret = module_locate_server(context, realm, &list, svc, socktype); -+ ret = module_locate_server(context, realm, &list, svc, transport); - if (ret != KRB5_PLUGIN_NO_HANDLE) - goto done; - - /* Try the profile. Fall back to DNS if it returns an empty list. */ -- ret = prof_locate_server(context, realm, &list, svc, socktype); -+ ret = prof_locate_server(context, realm, &list, svc, transport); - if (ret) - goto done; - - #ifdef KRB5_DNS_LOOKUP - if (list.nservers == 0) -- ret = dns_locate_server(context, realm, &list, svc, socktype); -+ ret = dns_locate_server(context, realm, &list, svc, transport); - #endif - - done: -@@ -589,9 +598,10 @@ done: - krb5_error_code - k5_locate_server(krb5_context context, const krb5_data *realm, - struct serverlist *serverlist, enum locate_service_type svc, -- int socktype) -+ krb5_boolean no_udp) - { - krb5_error_code ret; -+ k5_transport transport = no_udp ? TCP : TCP_OR_UDP; - - memset(serverlist, 0, sizeof(*serverlist)); - if (realm == NULL || realm->data == NULL || realm->data[0] == 0) { -@@ -600,7 +610,7 @@ k5_locate_server(krb5_context context, const krb5_data *realm, - return KRB5_REALM_CANT_RESOLVE; - } - -- ret = locate_server(context, realm, serverlist, svc, socktype); -+ ret = locate_server(context, realm, serverlist, svc, transport); - if (ret) - return ret; - -@@ -616,12 +626,13 @@ k5_locate_server(krb5_context context, const krb5_data *realm, - - krb5_error_code - k5_locate_kdc(krb5_context context, const krb5_data *realm, -- struct serverlist *serverlist, int get_masters, int socktype) -+ struct serverlist *serverlist, krb5_boolean get_masters, -+ krb5_boolean no_udp) - { - enum locate_service_type stype; - - stype = get_masters ? locate_service_master_kdc : locate_service_kdc; -- return k5_locate_server(context, realm, serverlist, stype, socktype); -+ return k5_locate_server(context, realm, serverlist, stype, no_udp); - } - - krb5_boolean -@@ -632,7 +643,7 @@ k5_kdc_is_master(krb5_context context, const krb5_data *realm, - krb5_boolean found; - - if (locate_server(context, realm, &list, locate_service_master_kdc, -- server->socktype) != 0) -+ server->transport) != 0) - return FALSE; - found = server_list_contains(&list, server); - k5_free_serverlist(&list); -diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h -index 9125ba0..3196bca 100644 ---- a/src/lib/krb5/os/os-proto.h -+++ b/src/lib/krb5/os/os-proto.h -@@ -38,11 +38,23 @@ - - #include - -+typedef enum { -+ TCP_OR_UDP = 0, -+ TCP, -+ UDP, -+} k5_transport; -+ -+typedef enum { -+ UDP_FIRST = 0, -+ UDP_LAST, -+ NO_UDP, -+} k5_transport_strategy; -+ - /* A single server hostname or address. */ - struct server_entry { - char *hostname; /* NULL -> use addrlen/addr instead */ - int port; /* Used only if hostname set */ -- int socktype; /* May be 0 for UDP/TCP if hostname set */ -+ k5_transport transport; /* May be 0 for UDP/TCP if hostname set */ - int family; /* May be 0 (aka AF_UNSPEC) if hostname set */ - size_t addrlen; - struct sockaddr_storage addr; -@@ -56,8 +68,8 @@ struct serverlist { - #define SERVERLIST_INIT { NULL, 0 } - - struct remote_address { -+ k5_transport transport; - int family; -- int type; - socklen_t len; - struct sockaddr_storage saddr; - }; -@@ -69,12 +81,13 @@ struct sendto_callback_info { - }; - - krb5_error_code k5_locate_server(krb5_context, const krb5_data *realm, -- struct serverlist *, -- enum locate_service_type svc, int socktype); -+ struct serverlist *serverlist, -+ enum locate_service_type svc, -+ krb5_boolean no_udp); - - krb5_error_code k5_locate_kdc(krb5_context context, const krb5_data *realm, -- struct serverlist *serverlist, int get_masters, -- int socktype); -+ struct serverlist *serverlist, -+ krb5_boolean get_masters, krb5_boolean no_udp); - - krb5_boolean k5_kdc_is_master(krb5_context context, const krb5_data *realm, - struct server_entry *server); -@@ -103,7 +116,7 @@ int _krb5_conf_boolean (const char *); - - krb5_error_code k5_sendto(krb5_context context, const krb5_data *message, - const struct serverlist *addrs, -- int socktype1, int socktype2, -+ k5_transport_strategy strategy, - struct sendto_callback_info *callback_info, - krb5_data *reply, struct sockaddr *remoteaddr, - socklen_t *remoteaddrlen, int *server_used, -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index e3855a3..3f99ce8 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -104,6 +104,7 @@ struct conn_state { - size_t server_index; - struct conn_state *next; - time_ms endtime; -+ krb5_boolean defer; - }; - - /* Get current time in milliseconds. */ -@@ -293,6 +294,19 @@ cm_select_or_poll(const struct select_state *in, time_ms endtime, - } - - static int -+socktype_for_transport(k5_transport transport) -+{ -+ switch (transport) { -+ case UDP: -+ return SOCK_DGRAM; -+ case TCP: -+ return SOCK_STREAM; -+ default: -+ return 0; -+ } -+} -+ -+static int - check_for_svc_unavailable (krb5_context context, - const krb5_data *reply, - void *msg_handler_data) -@@ -330,11 +344,12 @@ check_for_svc_unavailable (krb5_context context, - krb5_error_code - krb5_sendto_kdc(krb5_context context, const krb5_data *message, - const krb5_data *realm, krb5_data *reply, int *use_master, -- int tcp_only) -+ int no_udp) - { - krb5_error_code retval, err; - struct serverlist servers; -- int socktype1 = 0, socktype2 = 0, server_used; -+ int server_used; -+ k5_transport_strategy strategy; - - /* - * find KDC location(s) for realm -@@ -349,9 +364,9 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message, - * should probably be returned as well. - */ - -- TRACE_SENDTO_KDC(context, message->length, realm, *use_master, tcp_only); -+ TRACE_SENDTO_KDC(context, message->length, realm, *use_master, no_udp); - -- if (!tcp_only && context->udp_pref_limit < 0) { -+ if (!no_udp && context->udp_pref_limit < 0) { - int tmp; - retval = profile_get_integer(context->profile, - KRB5_CONF_LIBDEFAULTS, KRB5_CONF_UDP_PREFERENCE_LIMIT, 0, -@@ -368,22 +383,21 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message, - context->udp_pref_limit = tmp; - } - -- if (tcp_only) -- socktype1 = SOCK_STREAM, socktype2 = 0; -+ if (no_udp) -+ strategy = NO_UDP; - else if (message->length <= (unsigned int) context->udp_pref_limit) -- socktype1 = SOCK_DGRAM, socktype2 = SOCK_STREAM; -+ strategy = UDP_FIRST; - else -- socktype1 = SOCK_STREAM, socktype2 = SOCK_DGRAM; -+ strategy = UDP_LAST; - -- retval = k5_locate_kdc(context, realm, &servers, *use_master, -- tcp_only ? SOCK_STREAM : 0); -+ retval = k5_locate_kdc(context, realm, &servers, *use_master, no_udp); - if (retval) - return retval; - - err = 0; -- retval = k5_sendto(context, message, &servers, socktype1, socktype2, -- NULL, reply, NULL, NULL, &server_used, -- check_for_svc_unavailable, &err); -+ retval = k5_sendto(context, message, &servers, strategy, NULL, reply, -+ NULL, NULL, &server_used, check_for_svc_unavailable, -+ &err); - if (retval == KRB5_KDC_UNREACH) { - if (err == KDC_ERR_SVC_UNAVAILABLE) { - retval = KRB5KDC_ERR_SVC_UNAVAILABLE; -@@ -444,7 +458,7 @@ set_transport_message(struct conn_state *state, const krb5_data *message) - if (message == NULL || message->length == 0) - return; - -- if (state->addr.type == SOCK_STREAM) { -+ if (state->addr.transport == TCP) { - store_32_be(message->length, out->msg_len_buf); - SG_SET(&out->sgbuf[0], out->msg_len_buf, 4); - SG_SET(&out->sgbuf[1], message->data, message->length); -@@ -457,8 +471,9 @@ set_transport_message(struct conn_state *state, const krb5_data *message) - } - - static krb5_error_code --add_connection(struct conn_state **conns, struct addrinfo *ai, -- size_t server_index, char **udpbufp) -+add_connection(struct conn_state **conns, k5_transport transport, -+ krb5_boolean defer, struct addrinfo *ai, size_t server_index, -+ char **udpbufp) - { - struct conn_state *state, **tailptr; - -@@ -467,14 +482,15 @@ add_connection(struct conn_state **conns, struct addrinfo *ai, - return ENOMEM; - state->state = INITIALIZING; - state->out.sgp = state->out.sgbuf; -- state->addr.type = ai->ai_socktype; -+ state->addr.transport = transport; - state->addr.family = ai->ai_family; - state->addr.len = ai->ai_addrlen; - memcpy(&state->addr.saddr, ai->ai_addr, ai->ai_addrlen); -+ state->defer = defer; - state->fd = INVALID_SOCKET; - state->server_index = server_index; - SG_SET(&state->out.sgbuf[1], NULL, 0); -- if (ai->ai_socktype == SOCK_STREAM) { -+ if (transport == TCP) { - state->service = service_tcp_fd; - } else { - state->service = service_udp_fd; -@@ -549,32 +565,41 @@ translate_ai_error (int err) - */ - static krb5_error_code - resolve_server(krb5_context context, const struct serverlist *servers, -- size_t ind, int socktype1, int socktype2, -+ size_t ind, k5_transport_strategy strategy, - const krb5_data *message, char **udpbufp, - struct conn_state **conns) - { - krb5_error_code retval; - struct server_entry *entry = &servers->servers[ind]; -+ k5_transport transport; - struct addrinfo *addrs, *a, hint, ai; -+ krb5_boolean defer; - int err, result; - char portbuf[64]; - -- /* Skip any stray entries of socktypes we don't want. */ -- if (entry->socktype != 0 && entry->socktype != socktype1 && -- entry->socktype != socktype2) -+ /* Skip UDP entries if we don't want UDP. */ -+ if (strategy == NO_UDP && entry->transport == UDP) - return 0; - -+ transport = (strategy == UDP_FIRST) ? UDP : TCP; - if (entry->hostname == NULL) { -- ai.ai_socktype = entry->socktype; -+ /* Added by a module, so transport is either TCP or UDP. */ -+ ai.ai_socktype = socktype_for_transport(entry->transport); - ai.ai_family = entry->family; - ai.ai_addrlen = entry->addrlen; - ai.ai_addr = (struct sockaddr *)&entry->addr; -- return add_connection(conns, &ai, ind, udpbufp); -+ defer = (entry->transport != transport); -+ return add_connection(conns, entry->transport, defer, &ai, ind, -+ udpbufp); - } - -+ /* If the entry has a specified transport, use it. */ -+ if (entry->transport != TCP_OR_UDP) -+ transport = entry->transport; -+ - memset(&hint, 0, sizeof(hint)); - hint.ai_family = entry->family; -- hint.ai_socktype = (entry->socktype != 0) ? entry->socktype : socktype1; -+ hint.ai_socktype = socktype_for_transport(transport); - hint.ai_flags = AI_ADDRCONFIG; - #ifdef AI_NUMERICSERV - hint.ai_flags |= AI_NUMERICSERV; -@@ -586,15 +611,19 @@ resolve_server(krb5_context context, const struct serverlist *servers, - err = getaddrinfo(entry->hostname, portbuf, &hint, &addrs); - if (err) - return translate_ai_error(err); -- /* Add each address with the preferred socktype. */ -+ -+ /* Add each address with the specified or preferred transport. */ - retval = 0; - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) -- retval = add_connection(conns, a, ind, udpbufp); -- if (retval == 0 && entry->socktype == 0 && socktype2 != 0) { -- /* Add each address again with the non-preferred socktype. */ -+ retval = add_connection(conns, transport, FALSE, a, ind, udpbufp); -+ -+ /* For TCP_OR_UDP entries, add each address again with the non-preferred -+ * transport, unless we are avoiding UDP. Flag these as deferred. */ -+ if (retval == 0 && entry->transport == TCP_OR_UDP && strategy != NO_UDP) { -+ transport = (strategy == UDP_FIRST) ? TCP : UDP; - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { -- a->ai_socktype = socktype2; -- retval = add_connection(conns, a, ind, udpbufp); -+ a->ai_socktype = socktype_for_transport(transport); -+ retval = add_connection(conns, transport, TRUE, a, ind, udpbufp); - } - } - freeaddrinfo(addrs); -@@ -606,17 +635,18 @@ start_connection(krb5_context context, struct conn_state *state, - const krb5_data *message, struct select_state *selstate, - struct sendto_callback_info *callback_info) - { -- int fd, e; -+ int fd, e, type; - static const int one = 1; - static const struct linger lopt = { 0, 0 }; - -- fd = socket(state->addr.family, state->addr.type, 0); -+ type = socktype_for_transport(state->addr.transport); -+ fd = socket(state->addr.family, type, 0); - if (fd == INVALID_SOCKET) - return -1; /* try other hosts */ - set_cloexec_fd(fd); - /* Make it non-blocking. */ - ioctlsocket(fd, FIONBIO, (const void *) &one); -- if (state->addr.type == SOCK_STREAM) { -+ if (state->addr.transport == TCP) { - setsockopt(fd, SOL_SOCKET, SO_LINGER, &lopt, sizeof(lopt)); - TRACE_SENDTO_KDC_TCP_CONNECT(context, &state->addr); - } -@@ -665,7 +695,7 @@ start_connection(krb5_context context, struct conn_state *state, - } - set_transport_message(state, message); - -- if (state->addr.type == SOCK_DGRAM) { -+ if (state->addr.transport == UDP) { - /* Send it now. */ - ssize_t ret; - sg_buf *sg = &state->out.sgbuf[0]; -@@ -720,7 +750,7 @@ maybe_send(krb5_context context, struct conn_state *conn, - return -1; - } - -- if (conn->addr.type == SOCK_STREAM) { -+ if (conn->addr.transport != UDP) { - /* The select callback will handle flushing any data we - haven't written yet, and we only write it once. */ - return -1; -@@ -910,7 +940,7 @@ get_endtime(time_ms endtime, struct conn_state *conns) - struct conn_state *state; - - for (state = conns; state != NULL; state = state->next) { -- if (state->addr.type == SOCK_STREAM && -+ if (state->addr.transport == TCP && - (state->state == READING || state->state == WRITING) && - state->endtime > endtime) - endtime = state->endtime; -@@ -1008,7 +1038,7 @@ service_fds(krb5_context context, struct select_state *selstate, - - krb5_error_code - k5_sendto(krb5_context context, const krb5_data *message, -- const struct serverlist *servers, int socktype1, int socktype2, -+ const struct serverlist *servers, k5_transport_strategy strategy, - struct sendto_callback_info* callback_info, krb5_data *reply, - struct sockaddr *remoteaddr, socklen_t *remoteaddrlen, - int *server_used, -@@ -1038,17 +1068,18 @@ k5_sendto(krb5_context context, const krb5_data *message, - cm_init_selstate(sel_state); - - /* First pass: resolve server hosts, communicate with resulting addresses -- * of the preferred socktype, and wait 1s for an answer from each. */ -+ * of the preferred transport, and wait 1s for an answer from each. */ - for (s = 0; s < servers->nservers && !done; s++) { - /* Find the current tail pointer. */ - for (tailptr = &conns; *tailptr != NULL; tailptr = &(*tailptr)->next); -- retval = resolve_server(context, servers, s, socktype1, socktype2, -- message, &udpbuf, &conns); -+ retval = resolve_server(context, servers, s, strategy, message, -+ &udpbuf, &conns); - if (retval) - goto cleanup; - for (state = *tailptr; state != NULL && !done; state = state->next) { -- /* Contact each new connection whose socktype matches socktype1. */ -- if (state->addr.type != socktype1) -+ /* Contact each new connection, deferring those which use the -+ * non-preferred RFC 4120 transport. */ -+ if (state->defer) - continue; - if (maybe_send(context, state, message, sel_state, callback_info)) - continue; -@@ -1057,10 +1088,10 @@ k5_sendto(krb5_context context, const krb5_data *message, - } - } - -- /* Complete the first pass by contacting servers of the non-preferred -- * socktype (if given), waiting 1s for an answer from each. */ -+ /* Complete the first pass by contacting servers of the non-preferred RFC -+ * 4120 transport (if given), waiting 1s for an answer from each. */ - for (state = conns; state != NULL && !done; state = state->next) { -- if (state->addr.type != socktype2) -+ if (!state->defer) - continue; - if (maybe_send(context, state, message, sel_state, callback_info)) - continue; -diff --git a/src/lib/krb5/os/t_locate_kdc.c b/src/lib/krb5/os/t_locate_kdc.c -index 5453a4c..300aa71 100644 ---- a/src/lib/krb5/os/t_locate_kdc.c -+++ b/src/lib/krb5/os/t_locate_kdc.c -@@ -29,18 +29,18 @@ kfatal (krb5_error_code err) - } - - static const char * --stypename (int stype) -+ttypename (k5_transport ttype) - { - static char buf[20]; -- switch (stype) { -- case SOCK_STREAM: -- return "stream"; -- case SOCK_DGRAM: -- return "dgram"; -- case SOCK_RAW: -- return "raw"; -+ switch (ttype) { -+ case TCP_OR_UDP: -+ return "tcp or udp"; -+ case TCP: -+ return "tcp"; -+ case UDP: -+ return "udp"; - default: -- snprintf(buf, sizeof(buf), "?%d", stype); -+ snprintf(buf, sizeof(buf), "?%d", ttype); - return buf; - } - } -@@ -58,7 +58,7 @@ print_addrs (void) - - if (entry->hostname != NULL) { - printf("%2d: host %s\t%s\tport %d\n", (int)i, entry->hostname, -- stypename(entry->socktype), ntohs(entry->port)); -+ ttypename(entry->transport), ntohs(entry->port)); - continue; - } - err = getnameinfo((struct sockaddr *)&entry->addr, entry->addrlen, -@@ -69,7 +69,7 @@ print_addrs (void) - gai_strerror(err)); - } else { - printf("%2d: address %s\t%s\tport %s\n", (int)i, hostbuf, -- stypename(entry->socktype), srvbuf); -+ ttypename(entry->transport), srvbuf); - } - } - } -@@ -129,7 +129,7 @@ main (int argc, char *argv[]) - break; - - case LOOKUP_WHATEVER: -- err = k5_locate_kdc(ctx, &realm, &sl, master, 0); -+ err = k5_locate_kdc(ctx, &realm, &sl, master, FALSE); - break; - } - if (err) kfatal (err); -diff --git a/src/lib/krb5/os/t_std_conf.c b/src/lib/krb5/os/t_std_conf.c -index e2ff572..6ee54d5 100644 ---- a/src/lib/krb5/os/t_std_conf.c -+++ b/src/lib/krb5/os/t_std_conf.c -@@ -82,7 +82,7 @@ test_locate_kdc(krb5_context ctx, char *realm) - - rlm.data = realm; - rlm.length = strlen(realm); -- retval = k5_locate_kdc(ctx, &rlm, &servers, get_masters, 0); -+ retval = k5_locate_kdc(ctx, &rlm, &servers, get_masters, FALSE); - if (retval) { - com_err("krb5_locate_kdc", retval, 0); - return; -diff --git a/src/lib/krb5/os/t_trace.c b/src/lib/krb5/os/t_trace.c -index 36044f5..4cb2bd0 100644 ---- a/src/lib/krb5/os/t_trace.c -+++ b/src/lib/krb5/os/t_trace.c -@@ -112,7 +112,7 @@ main (int argc, char *argv[]) - TRACE(ctx, "size_t and const char *, as four-character hex hash: " - "{hashlenstr}", 1, NULL); - -- ra.type = SOCK_STREAM; -+ ra.transport = TCP; - addr_in = (struct sockaddr_in *)&ra.saddr; - addr_in->sin_family = AF_INET; - addr_in->sin_addr.s_addr = INADDR_ANY; -@@ -121,10 +121,10 @@ main (int argc, char *argv[]) - ra.family = AF_INET; - TRACE(ctx, "struct remote_address *, show socket type, address, port: " - "{raddr}", &ra); -- ra.type = SOCK_DGRAM; -+ ra.transport = UDP; - TRACE(ctx, "struct remote_address *, show socket type, address, port: " - "{raddr}", &ra); -- ra.type = 1234; -+ ra.transport = 1234; - addr_in->sin_family = AF_UNSPEC; - ra.family = AF_UNSPEC; - TRACE(ctx, "struct remote_address *, show socket type, address, port: " -diff --git a/src/lib/krb5/os/t_trace.ref b/src/lib/krb5/os/t_trace.ref -index 749d9c9..ca5818a 100644 ---- a/src/lib/krb5/os/t_trace.ref -+++ b/src/lib/krb5/os/t_trace.ref -@@ -10,8 +10,8 @@ size_t and const char *, as four-character hex hash: 7B9A - size_t and const char *, as four-character hex hash: (null) - struct remote_address *, show socket type, address, port: stream 0.0.0.0:88 - struct remote_address *, show socket type, address, port: dgram 0.0.0.0:88 --struct remote_address *, show socket type, address, port: socktype1234 AF_UNSPEC --struct remote_address *, show socket type, address, port: socktype1234 af5678 -+struct remote_address *, show socket type, address, port: transport1234 AF_UNSPEC -+struct remote_address *, show socket type, address, port: transport1234 af5678 - krb5_data *, display as counted string: example.data - krb5_data *, display as counted string: (null) - krb5_data *, display as hex bytes: 6578616D706C652E64617461 -diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c -index 525742c..8319a86 100644 ---- a/src/lib/krb5/os/trace.c -+++ b/src/lib/krb5/os/trace.c -@@ -197,12 +197,12 @@ trace_format(krb5_context context, const char *fmt, va_list ap) - } - } else if (strcmp(tmpbuf, "raddr") == 0) { - ra = va_arg(ap, struct remote_address *); -- if (ra->type == SOCK_DGRAM) -+ if (ra->transport == UDP) - k5_buf_add(&buf, "dgram"); -- else if (ra->type == SOCK_STREAM) -+ else if (ra->transport == TCP) - k5_buf_add(&buf, "stream"); - else -- k5_buf_add_fmt(&buf, "socktype%d", ra->type); -+ k5_buf_add_fmt(&buf, "transport%d", ra->transport); - - if (getnameinfo((struct sockaddr *)&ra->saddr, ra->len, - addrbuf, sizeof(addrbuf), portbuf, sizeof(portbuf), --- -2.1.0 - diff --git a/SOURCES/0004-Build-support-for-TLS-used-by-HTTPS-proxy-support.patch b/SOURCES/0004-Build-support-for-TLS-used-by-HTTPS-proxy-support.patch deleted file mode 100644 index df4707d..0000000 --- a/SOURCES/0004-Build-support-for-TLS-used-by-HTTPS-proxy-support.patch +++ /dev/null @@ -1,187 +0,0 @@ -From d0be57ac45ea639baa3cff0dd2108c34e834bfa7 Mon Sep 17 00:00:00 2001 -From: "Robbie Harwood (frozencemetery)" -Date: Fri, 16 Aug 2013 12:45:03 -0400 -Subject: [PATCH 04/13] Build support for TLS used by HTTPS proxy support - -Add a --with-proxy-tls-impl option to configure, taking 'openssl', -'auto', or invocation as --without-proxy-tls-impl. Use related CFLAGS -when building lib/krb5/os, and LIBS when linking libkrb5. Call the -OpenSSL library startup functions during library initialization. - -ticket: 7929 ---- - src/Makefile.in | 1 + - src/config/pre.in | 5 +++++ - src/configure.in | 40 ++++++++++++++++++++++++++++++++++++++++ - src/lib/krb5/Makefile.in | 3 ++- - src/lib/krb5/krb5_libinit.c | 2 ++ - src/lib/krb5/os/Makefile.in | 2 +- - src/lib/krb5/os/os-proto.h | 1 + - src/lib/krb5/os/sendto_kdc.c | 14 ++++++++++++++ - 8 files changed, 66 insertions(+), 2 deletions(-) - -diff --git a/src/Makefile.in b/src/Makefile.in -index 1725093..5e2cf4e 100644 ---- a/src/Makefile.in -+++ b/src/Makefile.in -@@ -553,6 +553,7 @@ pyrunenv.vals: Makefile - for i in $(RUN_VARS); do \ - eval echo 'env['\\\'$$i\\\''] = '\\\'\$$$$i\\\'; \ - done > $@ -+ echo "proxy_tls_impl = '$(PROXY_TLS_IMPL)'" >> $@ - - runenv.py: pyrunenv.vals - echo 'env = {}' > $@ -diff --git a/src/config/pre.in b/src/config/pre.in -index fbc5c11..e1d7e4b 100644 ---- a/src/config/pre.in -+++ b/src/config/pre.in -@@ -428,6 +428,11 @@ PKINIT_CRYPTO_IMPL = @PKINIT_CRYPTO_IMPL@ - PKINIT_CRYPTO_IMPL_CFLAGS = @PKINIT_CRYPTO_IMPL_CFLAGS@ - PKINIT_CRYPTO_IMPL_LIBS = @PKINIT_CRYPTO_IMPL_LIBS@ - -+# TLS implementation selection for HTTPS proxy support -+PROXY_TLS_IMPL = @PROXY_TLS_IMPL@ -+PROXY_TLS_IMPL_CFLAGS = @PROXY_TLS_IMPL_CFLAGS@ -+PROXY_TLS_IMPL_LIBS = @PROXY_TLS_IMPL_LIBS@ -+ - # error table rules - # - ### /* these are invoked as $(...) foo.et, which works, but could be better */ -diff --git a/src/configure.in b/src/configure.in -index 9bc4663..39e3738 100644 ---- a/src/configure.in -+++ b/src/configure.in -@@ -272,6 +272,46 @@ AC_SUBST(PKINIT_CRYPTO_IMPL) - AC_SUBST(PKINIT_CRYPTO_IMPL_CFLAGS) - AC_SUBST(PKINIT_CRYPTO_IMPL_LIBS) - -+# WITH_PROXY_TLS_IMPL -+ -+AC_ARG_WITH([proxy-tls-impl], -+AC_HELP_STRING([--with-proxy-tls-impl=IMPL], -+ [use specified TLS implementation for HTTPS @<:@auto@:>@]), -+[PROXY_TLS_IMPL=$withval],[PROXY_TLS_IMPL=auto]) -+case "$PROXY_TLS_IMPL" in -+openssl|auto) -+ AC_CHECK_LIB(ssl,SSL_CTX_new,[have_lib_ssl=true],[have_lib_ssl=false], -+ -lcrypto) -+ AC_MSG_CHECKING([for OpenSSL]) -+ if test x$have_lib_ssl = xtrue ; then -+ AC_DEFINE(PROXY_TLS_IMPL_OPENSSL,1, -+ [Define if HTTPS TLS implementation is OpenSSL]) -+ AC_MSG_RESULT([yes]) -+ PROXY_TLS_IMPL_LIBS="-lssl -lcrypto" -+ PROXY_TLS_IMPL=openssl -+ AC_MSG_NOTICE(HTTPS support will use TLS from '$PROXY_TLS_IMPL') -+ else -+ if test "$PROXY_TLS_IMPL" = openssl ; then -+ AC_MSG_ERROR([OpenSSL not found!]) -+ else -+ AC_MSG_WARN([OpenSSL not found!]) -+ fi -+ PROXY_TLS_IMPL=no -+ AC_MSG_NOTICE(building without HTTPS support) -+ fi -+ ;; -+no) -+ AC_MSG_NOTICE(building without HTTPS support) -+ ;; -+*) -+ AC_MSG_ERROR([Unsupported HTTPS proxy TLS implementation $withval]) -+ ;; -+esac -+ -+AC_SUBST(PROXY_TLS_IMPL) -+AC_SUBST(PROXY_TLS_IMPL_CFLAGS) -+AC_SUBST(PROXY_TLS_IMPL_LIBS) -+ - AC_ARG_ENABLE([aesni], - AC_HELP_STRING([--disable-aesni],[Do not build with AES-NI support]), , - enable_aesni=check) -diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in -index d9cddc1..472c008 100644 ---- a/src/lib/krb5/Makefile.in -+++ b/src/lib/krb5/Makefile.in -@@ -56,7 +56,8 @@ RELDIR=krb5 - SHLIB_EXPDEPS = \ - $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ - $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB) --SHLIB_EXPLIBS=-lk5crypto -lcom_err $(SUPPORT_LIB) @GEN_LIB@ $(LIBS) -+SHLIB_EXPLIBS=-lk5crypto -lcom_err $(PROXY_TLS_IMPL_LIBS) $(SUPPORT_LIB) \ -+ @GEN_LIB@ $(LIBS) - - all-unix:: all-liblinks - -diff --git a/src/lib/krb5/krb5_libinit.c b/src/lib/krb5/krb5_libinit.c -index f83d25b..f2382d1 100644 ---- a/src/lib/krb5/krb5_libinit.c -+++ b/src/lib/krb5/krb5_libinit.c -@@ -58,6 +58,8 @@ int krb5int_lib_init(void) - if (err) - return err; - -+ k5_sendto_kdc_initialize(); -+ - return 0; - } - -diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in -index 5add9f9..fb4001a 100644 ---- a/src/lib/krb5/os/Makefile.in -+++ b/src/lib/krb5/os/Makefile.in -@@ -2,7 +2,7 @@ mydir=lib$(S)krb5$(S)os - BUILDTOP=$(REL)..$(S)..$(S).. - DEFINES=-DLIBDIR=\"$(KRB5_LIBDIR)\" -DBINDIR=\"$(CLIENT_BINDIR)\" \ - -DSBINDIR=\"$(ADMIN_BINDIR)\" --LOCALINCLUDES=-I$(top_srcdir)/util/profile -+LOCALINCLUDES= $(PROXY_TLS_IMPL_CFLAGS) -I$(top_srcdir)/util/profile - - ##DOS##BUILDTOP = ..\..\.. - ##DOS##PREFIXDIR=os -diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h -index 3196bca..f23dda5 100644 ---- a/src/lib/krb5/os/os-proto.h -+++ b/src/lib/krb5/os/os-proto.h -@@ -184,5 +184,6 @@ krb5_error_code localauth_k5login_initvt(krb5_context context, int maj_ver, - krb5_plugin_vtable vtable); - krb5_error_code localauth_an2ln_initvt(krb5_context context, int maj_ver, - int min_ver, krb5_plugin_vtable vtable); -+void k5_sendto_kdc_initialize(void); - - #endif /* KRB5_LIBOS_INT_PROTO__ */ -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index 3f99ce8..c6aae8e 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -48,6 +48,10 @@ - #endif - #endif - -+#ifdef PROXY_TLS_IMPL_OPENSSL -+#include -+#endif -+ - #define MAX_PASS 3 - #define DEFAULT_UDP_PREF_LIMIT 1465 - #define HARD_UDP_LIMIT 32700 /* could probably do 64K-epsilon ? */ -@@ -107,6 +111,16 @@ struct conn_state { - krb5_boolean defer; - }; - -+void -+k5_sendto_kdc_initialize(void) -+{ -+#ifdef PROXY_TLS_IMPL_OPENSSL -+ SSL_library_init(); -+ SSL_load_error_strings(); -+ OpenSSL_add_all_algorithms(); -+#endif -+} -+ - /* Get current time in milliseconds. */ - static krb5_error_code - get_curtime_ms(time_ms *time_out) --- -2.1.0 - diff --git a/SOURCES/0004-Make-ksu-respect-the-default_ccache_name-setting.patch b/SOURCES/0004-Make-ksu-respect-the-default_ccache_name-setting.patch deleted file mode 100644 index cb45f1b..0000000 --- a/SOURCES/0004-Make-ksu-respect-the-default_ccache_name-setting.patch +++ /dev/null @@ -1,378 +0,0 @@ -From 3a456898af626dcab4e1ab0749ca2ccb9ad6162b Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Wed, 30 Oct 2013 21:47:14 -0400 -Subject: [PATCH 4/7] Make ksu respect the default_ccache_name setting - -Move the logic for resolving and initializing a cache that we're -copying creds into out of krb5_ccache_copy(), and let the caller deal -with it. Add a helper functions to select/resolve an output ccache in -the default location for the target user after we've switched to the -target user's privileges. If the destination is a collection, take -care not to change which subsidiary is its primary, and reuse a -subsidiary cache if we can. If the destination is not a collection, -append a unique value to its name to make a new ccache. - -[ghudson@mit.edu: some changes to variable names and comments; move -responsibility for getting target ccache name from -resolve_target_ccache to main] - -ticket: 7984 (new) ---- - src/clients/ksu/ccache.c | 35 +++------ - src/clients/ksu/ksu.h | 6 +- - src/clients/ksu/main.c | 181 ++++++++++++++++++++++++++++++++++++++--------- - 3 files changed, 157 insertions(+), 65 deletions(-) - -diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c -index d0fc389..4693bd4 100644 ---- a/src/clients/ksu/ccache.c -+++ b/src/clients/ksu/ccache.c -@@ -46,59 +46,41 @@ void show_credential(); - with k5 beta 3 release. - */ - --krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, -- primary_principal, restrict_creds, -- target_principal, cc_out, stored, target_uid) -+krb5_error_code krb5_ccache_copy(context, cc_def, target_principal, cc_target, -+ restrict_creds, primary_principal, stored) - /* IN */ - krb5_context context; - krb5_ccache cc_def; -- char *cc_other_tag; -- krb5_principal primary_principal; -- krb5_boolean restrict_creds; - krb5_principal target_principal; -- uid_t target_uid; -+ krb5_ccache cc_target; -+ krb5_boolean restrict_creds; -+ krb5_principal primary_principal; - /* OUT */ -- krb5_ccache *cc_out; - krb5_boolean *stored; - { - int i=0; -- krb5_ccache * cc_other; - krb5_error_code retval=0; - krb5_creds ** cc_def_creds_arr = NULL; - krb5_creds ** cc_other_creds_arr = NULL; - -- cc_other = (krb5_ccache *) xcalloc(1, sizeof (krb5_ccache)); -- -- if ((retval = krb5_cc_resolve(context, cc_other_tag, cc_other))){ -- com_err(prog_name, retval, _("resolving ccache %s"), cc_other_tag); -- return retval; -- } -- - if (ks_ccache_is_initialized(context, cc_def)) { - if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){ - return retval; - } - } - -- if (ks_ccache_name_is_initialized(context, cc_other_tag)) -- return EINVAL; -- -- if (krb5_seteuid(0)||krb5_seteuid(target_uid)) { -- return errno; -- } -- -- retval = krb5_cc_initialize(context, *cc_other, target_principal); -+ retval = krb5_cc_initialize(context, cc_target, target_principal); - if (retval) - return retval; - - if (restrict_creds) { -- retval = krb5_store_some_creds(context, *cc_other, cc_def_creds_arr, -+ retval = krb5_store_some_creds(context, cc_target, cc_def_creds_arr, - cc_other_creds_arr, primary_principal, - stored); - } else { - *stored = krb5_find_princ_in_cred_list(context, cc_def_creds_arr, - primary_principal); -- retval = krb5_store_all_creds(context, *cc_other, cc_def_creds_arr, -+ retval = krb5_store_all_creds(context, cc_target, cc_def_creds_arr, - cc_other_creds_arr); - } - -@@ -118,7 +100,6 @@ krb5_error_code krb5_ccache_copy (context, cc_def, cc_other_tag, - } - } - -- *cc_out = *cc_other; - return retval; - } - -diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h -index 08bf01b..fbbf217 100644 ---- a/src/clients/ksu/ksu.h -+++ b/src/clients/ksu/ksu.h -@@ -44,8 +44,6 @@ - #define KRB5_DEFAULT_OPTIONS 0 - #define KRB5_DEFAULT_TKT_LIFE 60*60*12 /* 12 hours */ - --#define KRB5_SECONDARY_CACHE "FILE:/tmp/krb5cc_" -- - #define KRB5_LOGIN_NAME ".k5login" - #define KRB5_USERS_NAME ".k5users" - #define USE_DEFAULT_REALM_NAME "." -@@ -106,8 +104,8 @@ extern krb5_error_code get_best_principal - - /* ccache.c */ - extern krb5_error_code krb5_ccache_copy --(krb5_context, krb5_ccache, char *, krb5_principal, krb5_boolean, -- krb5_principal, krb5_ccache *, krb5_boolean *, uid_t); -+(krb5_context, krb5_ccache, krb5_principal, krb5_ccache, -+ krb5_boolean, krb5_principal, krb5_boolean *); - - extern krb5_error_code krb5_store_all_creds - (krb5_context, krb5_ccache, krb5_creds **, krb5_creds **); -diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c -index d1bb8ca..41a3bf8 100644 ---- a/src/clients/ksu/main.c -+++ b/src/clients/ksu/main.c -@@ -54,6 +54,10 @@ static void print_status( const char *fmt, ...) - __attribute__ ((__format__ (__printf__, 1, 2))) - #endif - ; -+static krb5_error_code resolve_target_cache(krb5_context ksu_context, -+ krb5_principal princ, -+ krb5_ccache *ccache_out, -+ krb5_boolean *ccache_reused); - - /* Note -e and -a options are mutually exclusive */ - /* insure the proper specification of target user as well as catching -@@ -112,7 +116,7 @@ main (argc, argv) - extern char * getpass(), *crypt(); - int pargc; - char ** pargv; -- krb5_boolean stored = FALSE; -+ krb5_boolean stored = FALSE, cc_reused = FALSE; - krb5_principal kdc_server; - krb5_boolean zero_password; - krb5_boolean restrict_creds; -@@ -416,23 +420,8 @@ main (argc, argv) - exit(1); - } - -- /* -- * Make sure that the new ticket file does not already exist. -- * This is run as source_uid because it is reasonable to -- * require the source user to have write to where the target -- * cache will be created. -- */ -- cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE, sizeof(char)); -- do { -- snprintf(cc_target_tag, KRB5_SEC_BUFFSIZE, "%s%ld.%d", -- KRB5_SECONDARY_CACHE, -- (long)target_uid, gen_sym()); -- } while (ks_ccache_name_is_initialized(ksu_context, cc_target_tag)); -- -- if (auth_debug){ -+ if (auth_debug) - fprintf(stderr, " source cache = %s\n", cc_source_tag); -- fprintf(stderr, " target cache = %s\n", cc_target_tag); -- } - - /* - * After proper authentication and authorization, populate a cache for the -@@ -455,14 +444,19 @@ main (argc, argv) - com_err(prog_name, retval, _("while parsing temporary name")); - exit(1); - } -- retval = krb5_ccache_copy(ksu_context, cc_source, KS_TEMPORARY_CACHE, -- client, restrict_creds, tmp_princ, &cc_tmp, -- &stored, 0); -+ retval = krb5_cc_resolve(ksu_context, KS_TEMPORARY_CACHE, &cc_tmp); -+ if (retval) { -+ com_err(prog_name, retval, _("while creating temporary cache")); -+ exit(1); -+ } -+ retval = krb5_ccache_copy(ksu_context, cc_source, tmp_princ, cc_tmp, -+ restrict_creds, client, &stored); - if (retval) { - com_err(prog_name, retval, _("while copying cache %s to %s"), - krb5_cc_get_name(ksu_context, cc_source), KS_TEMPORARY_CACHE); - exit(1); - } -+ krb5_cc_close(ksu_context, cc_source); - - /* Become root for authentication*/ - -@@ -686,23 +680,38 @@ main (argc, argv) - exit(1); - } - -- retval = krb5_ccache_copy(ksu_context, cc_tmp, cc_target_tag, -- client, FALSE, client, &cc_target, &stored, -- target_pwd->pw_uid); -+ retval = resolve_target_cache(ksu_context, client, &cc_target, &cc_reused); -+ if (retval) -+ exit(1); -+ retval = krb5_cc_get_full_name(ksu_context, cc_target, &cc_target_tag); - if (retval) { -- com_err(prog_name, retval, _("while copying cache %s to %s"), -- KS_TEMPORARY_CACHE, cc_target_tag); -+ com_err(prog_name, retval, _("while getting name of target ccache")); -+ sweep_up(ksu_context, cc_target); - exit(1); - } -+ if (auth_debug) -+ fprintf(stderr, " target cache = %s\n", cc_target_tag); -+ if (cc_reused) -+ keep_target_cache = TRUE; - -- if (stored && !ks_ccache_is_initialized(ksu_context, cc_target)) { -- com_err(prog_name, errno, -- _("%s does not have correct permissions for %s, %s aborted"), -- target_user, cc_target_tag, prog_name); -- exit(1); -+ if (stored) { -+ retval = krb5_ccache_copy(ksu_context, cc_tmp, client, cc_target, -+ FALSE, client, &stored); -+ if (retval) { -+ com_err(prog_name, retval, _("while copying cache %s to %s"), -+ KS_TEMPORARY_CACHE, cc_target_tag); -+ exit(1); -+ } -+ -+ if (!ks_ccache_is_initialized(ksu_context, cc_target)) { -+ com_err(prog_name, errno, -+ _("%s does not have correct permissions for %s, " -+ "%s aborted"), target_user, cc_target_tag, prog_name); -+ exit(1); -+ } - } - -- free(cc_target_tag); -+ krb5_free_string(ksu_context, cc_target_tag); - - /* Set the cc env name to target. */ - retval = set_ccname_env(ksu_context, cc_target); -@@ -711,9 +720,6 @@ main (argc, argv) - exit(1); - } - -- if ( cc_source) -- krb5_cc_close(ksu_context, cc_source); -- - if (cmd){ - if ((source_uid == 0) || (source_uid == target_uid )){ - exec_cmd = cmd; -@@ -803,6 +809,113 @@ set_ccname_env(krb5_context ksu_context, krb5_ccache ccache) - return retval; - } - -+/* -+ * Get the configured default ccache name. Unset KRB5CCNAME and force a -+ * recomputation so we don't use values for the source user. Print an error -+ * message on failure. -+ */ -+static krb5_error_code -+get_configured_defccname(krb5_context context, char **target_out) -+{ -+ krb5_error_code retval; -+ const char *defname; -+ char *target; -+ -+ *target_out = NULL; -+ -+ if (unsetenv(KRB5_ENV_CCNAME) != 0) { -+ retval = errno; -+ com_err(prog_name, retval, _("while clearing the value of %s"), -+ KRB5_ENV_CCNAME); -+ return retval; -+ } -+ -+ /* Make sure we don't have a cached value for a different uid. */ -+ retval = krb5_cc_set_default_name(context, NULL); -+ if (retval != 0) { -+ com_err(prog_name, retval, _("while resetting target ccache name")); -+ return retval; -+ } -+ -+ defname = krb5_cc_default_name(context); -+ target = (defname == NULL) ? NULL : strdup(defname); -+ if (target == NULL) { -+ com_err(prog_name, ENOMEM, _("while determining target ccache name")); -+ return ENOMEM; -+ } -+ *target_out = target; -+ return 0; -+} -+ -+/* Determine where the target user's creds should be stored. Print an error -+ * message on failure. */ -+static krb5_error_code -+resolve_target_cache(krb5_context context, krb5_principal princ, -+ krb5_ccache *ccache_out, krb5_boolean *ccache_reused) -+{ -+ krb5_error_code retval; -+ krb5_boolean switchable, reused = FALSE; -+ krb5_ccache ccache = NULL; -+ char *sep, *ccname = NULL, *target; -+ -+ *ccache_out = NULL; -+ *ccache_reused = FALSE; -+ -+ retval = get_configured_defccname(context, &target); -+ if (retval != 0) -+ return retval; -+ -+ /* Check if the configured default name uses a switchable type. */ -+ sep = strchr(target, ':'); -+ *sep = '\0'; -+ switchable = krb5_cc_support_switch(context, target); -+ *sep = ':'; -+ -+ if (!switchable) { -+ /* Try to avoid destroying an in-use target ccache by coming up with -+ * the name of a cache that doesn't exist yet. */ -+ do { -+ free(ccname); -+ if (asprintf(&ccname, "%s.%d", target, gen_sym()) < 0) { -+ retval = ENOMEM; -+ com_err(prog_name, ENOMEM, -+ _("while allocating memory for target ccache name")); -+ goto cleanup; -+ } -+ } while (ks_ccache_name_is_initialized(context, ccname)); -+ retval = krb5_cc_resolve(context, ccname, &ccache); -+ } else { -+ /* Look for a cache in the collection that we can reuse. */ -+ retval = krb5_cc_cache_match(context, princ, &ccache); -+ if (retval == 0) { -+ reused = TRUE; -+ } else { -+ /* There isn't one, so create a new one. */ -+ *sep = '\0'; -+ retval = krb5_cc_new_unique(context, target, NULL, &ccache); -+ *sep = ':'; -+ if (retval) { -+ com_err(prog_name, retval, -+ _("while creating new target ccache")); -+ goto cleanup; -+ } -+ retval = krb5_cc_initialize(context, ccache, princ); -+ if (retval) { -+ com_err(prog_name, retval, -+ _("while initializing target cache")); -+ goto cleanup; -+ } -+ } -+ } -+ -+ *ccache_out = ccache; -+ *ccache_reused = reused; -+ -+cleanup: -+ free(target); -+ return retval; -+} -+ - #ifdef HAVE_GETUSERSHELL - - int standard_shell(sh) --- -2.0.4 - diff --git a/SOURCES/0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE.patch b/SOURCES/0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE.patch deleted file mode 100644 index f650d69..0000000 --- a/SOURCES/0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE.patch +++ /dev/null @@ -1,352 +0,0 @@ -From bb89afd7c59deea855d2818fe36ef7472b4abf2e Mon Sep 17 00:00:00 2001 -From: Nathaniel McCallum -Date: Mon, 9 Sep 2013 14:23:56 -0400 -Subject: [PATCH 05/13] Add ASN.1 codec for KKDCP's KDC-PROXY-MESSAGE - -Handle encoding and decoding [MS-KKDCP] proxy messages, including -handling of the additional length bytes. Early versions of [MS-KKDCP] -incorrectly omit that the size of the proxied message is prepended to -the proxied message, as it is when we're using plain TCP, before -encoding the proxy-message structure. This is fixed at least as of -version 2.1 of the spec. - -[nalin@redhat.com: add tests] - -ticket: 7929 ---- - src/include/k5-int.h | 13 +++++++++++++ - src/lib/krb5/asn.1/asn1_k_encode.c | 14 ++++++++++++++ - src/lib/krb5/krb/kfree.c | 10 ++++++++++ - src/lib/krb5/libkrb5.exports | 3 +++ - src/tests/asn.1/krb5_decode_test.c | 18 ++++++++++++++++++ - src/tests/asn.1/krb5_encode_test.c | 8 ++++++++ - src/tests/asn.1/ktest.c | 23 ++++++++++++++++++++++ - src/tests/asn.1/ktest.h | 5 +++++ - src/tests/asn.1/ktest_equal.c | 12 ++++++++++++ - src/tests/asn.1/ktest_equal.h | 3 +++ - src/tests/asn.1/reference_encode.out | 1 + - src/tests/asn.1/trval_reference.out | 37 ++++++++++++++++++++++++++++++++++++ - 12 files changed, 147 insertions(+) - -diff --git a/src/include/k5-int.h b/src/include/k5-int.h -index 096cd14..8f039ee 100644 ---- a/src/include/k5-int.h -+++ b/src/include/k5-int.h -@@ -518,6 +518,12 @@ typedef struct _krb5_pa_otp_req { - krb5_data vendor; - } krb5_pa_otp_req; - -+typedef struct _krb5_kkdcp_message { -+ krb5_data kerb_message; -+ krb5_data target_domain; -+ krb5_int32 dclocator_hint; -+} krb5_kkdcp_message; -+ - #include - #include - -@@ -898,6 +904,7 @@ void k5_free_otp_tokeninfo(krb5_context context, krb5_otp_tokeninfo *val); - void k5_free_pa_otp_challenge(krb5_context context, - krb5_pa_otp_challenge *val); - void k5_free_pa_otp_req(krb5_context context, krb5_pa_otp_req *val); -+void k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val); - - /* #include "krb5/wordsize.h" -- comes in through base-defs.h. */ - #include "com_err.h" -@@ -1438,6 +1445,9 @@ encode_krb5_pa_otp_req(const krb5_pa_otp_req *, krb5_data **); - krb5_error_code - encode_krb5_pa_otp_enc_req(const krb5_data *, krb5_data **); - -+krb5_error_code -+encode_krb5_kkdcp_message(const krb5_kkdcp_message *, krb5_data **); -+ - /************************************************************************* - * End of prototypes for krb5_encode.c - *************************************************************************/ -@@ -1608,6 +1618,9 @@ decode_krb5_pa_otp_req(const krb5_data *, krb5_pa_otp_req **); - krb5_error_code - decode_krb5_pa_otp_enc_req(const krb5_data *, krb5_data **); - -+krb5_error_code -+decode_krb5_kkdcp_message(const krb5_data *, krb5_kkdcp_message **); -+ - struct _krb5_key_data; /* kdb.h */ - - struct ldap_seqof_key_data { -diff --git a/src/lib/krb5/asn.1/asn1_k_encode.c b/src/lib/krb5/asn.1/asn1_k_encode.c -index 7b9179d..4dc49c2 100644 ---- a/src/lib/krb5/asn.1/asn1_k_encode.c -+++ b/src/lib/krb5/asn.1/asn1_k_encode.c -@@ -1711,3 +1711,17 @@ static const struct atype_info *pa_otp_enc_req_fields[] = { - }; - DEFSEQTYPE(pa_otp_enc_req, krb5_data, pa_otp_enc_req_fields); - MAKE_CODEC(krb5_pa_otp_enc_req, pa_otp_enc_req); -+ -+DEFFIELD(kkdcp_message_0, krb5_kkdcp_message, -+ kerb_message, 0, ostring_data); -+DEFFIELD(kkdcp_message_1, krb5_kkdcp_message, -+ target_domain, 1, opt_gstring_data); -+DEFFIELD(kkdcp_message_2, krb5_kkdcp_message, -+ dclocator_hint, 2, opt_int32); -+static const struct atype_info *kkdcp_message_fields[] = { -+ &k5_atype_kkdcp_message_0, &k5_atype_kkdcp_message_1, -+ &k5_atype_kkdcp_message_2 -+}; -+DEFSEQTYPE(kkdcp_message, krb5_kkdcp_message, -+ kkdcp_message_fields); -+MAKE_CODEC(krb5_kkdcp_message, kkdcp_message); -diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c -index 32b2151..f86c619 100644 ---- a/src/lib/krb5/krb/kfree.c -+++ b/src/lib/krb5/krb/kfree.c -@@ -821,3 +821,13 @@ k5_free_pa_otp_req(krb5_context context, krb5_pa_otp_req *val) - free(val->vendor.data); - free(val); - } -+ -+void -+k5_free_kkdcp_message(krb5_context context, krb5_kkdcp_message *val) -+{ -+ if (val == NULL) -+ return; -+ free(val->target_domain.data); -+ free(val->kerb_message.data); -+ free(val); -+} -diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports -index 863ec02..2d0852d 100644 ---- a/src/lib/krb5/libkrb5.exports -+++ b/src/lib/krb5/libkrb5.exports -@@ -25,6 +25,7 @@ decode_krb5_iakerb_finished - decode_krb5_iakerb_header - decode_krb5_kdc_req_body - decode_krb5_otp_tokeninfo -+decode_krb5_kkdcp_message - decode_krb5_pa_enc_ts - decode_krb5_pa_for_user - decode_krb5_pa_fx_fast_reply -@@ -72,6 +73,7 @@ encode_krb5_iakerb_finished - encode_krb5_iakerb_header - encode_krb5_kdc_req_body - encode_krb5_otp_tokeninfo -+encode_krb5_kkdcp_message - encode_krb5_pa_enc_ts - encode_krb5_pa_for_user - encode_krb5_pa_fx_fast_reply -@@ -113,6 +115,7 @@ k5_expand_path_tokens - k5_expand_path_tokens_extra - k5_free_algorithm_identifier - k5_free_otp_tokeninfo -+k5_free_kkdcp_message - k5_free_pa_otp_challenge - k5_free_pa_otp_req - k5_free_serverlist -diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c -index 8719978..f12bb16 100644 ---- a/src/tests/asn.1/krb5_decode_test.c -+++ b/src/tests/asn.1/krb5_decode_test.c -@@ -54,6 +54,8 @@ static void ktest_free_reply_key_pack(krb5_context context, - static void ktest_free_reply_key_pack_draft9(krb5_context context, - krb5_reply_key_pack_draft9 *val); - #endif -+static void ktest_free_kkdcp_message(krb5_context context, -+ krb5_kkdcp_message *val); - - int main(argc, argv) - int argc; -@@ -1077,6 +1079,13 @@ int main(argc, argv) - ktest_empty_data(&ref); - } - -+ /****************************************************************/ -+ /* decode_krb5_kkdcp_message */ -+ { -+ setup(krb5_kkdcp_message,ktest_make_sample_kkdcp_message); -+ decode_run("kkdcp_message","","30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61",decode_krb5_kkdcp_message,ktest_equal_kkdcp_message,ktest_free_kkdcp_message); -+ } -+ - #ifndef DISABLE_PKINIT - - /****************************************************************/ -@@ -1262,3 +1271,12 @@ ktest_free_reply_key_pack_draft9(krb5_context context, - } - - #endif /* not DISABLE_PKINIT */ -+ -+static void -+ktest_free_kkdcp_message(krb5_context context, -+ krb5_kkdcp_message *val) -+{ -+ if (val) -+ ktest_empty_kkdcp_message(val); -+ free(val); -+} -diff --git a/src/tests/asn.1/krb5_encode_test.c b/src/tests/asn.1/krb5_encode_test.c -index 638f6fe..3ba8684 100644 ---- a/src/tests/asn.1/krb5_encode_test.c -+++ b/src/tests/asn.1/krb5_encode_test.c -@@ -734,6 +734,14 @@ main(argc, argv) - encode_run(d, "pa_otp_enc_req", "", encode_krb5_pa_otp_enc_req); - ktest_empty_data(&d); - } -+ /****************************************************************/ -+ /* encode_krb5_kkdcp_message */ -+ { -+ krb5_kkdcp_message info; -+ ktest_make_sample_kkdcp_message(&info); -+ encode_run(info, "kkdcp_message", "", encode_krb5_kkdcp_message); -+ ktest_empty_kkdcp_message(&info); -+ } - #ifndef DISABLE_PKINIT - /****************************************************************/ - /* encode_krb5_pa_pk_as_req */ -diff --git a/src/tests/asn.1/ktest.c b/src/tests/asn.1/ktest.c -index aa41fd8..4ce9f70 100644 ---- a/src/tests/asn.1/ktest.c -+++ b/src/tests/asn.1/ktest.c -@@ -933,6 +933,21 @@ ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p) - } - #endif - -+void -+ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p) -+{ -+ krb5_kdc_req req; -+ krb5_data *message; -+ -+ ktest_make_sample_kdc_req(&req); -+ req.msg_type = KRB5_AS_REQ; -+ encode_krb5_as_req(&req, &message); -+ p->kerb_message = *message; -+ free(message); -+ ktest_empty_kdc_req(&req); -+ ktest_make_sample_data(&(p->target_domain)); -+ p->dclocator_hint = 0; -+} - - /****************************************************************/ - /* destructors */ -@@ -1731,3 +1746,11 @@ ktest_empty_ldap_seqof_key_data(krb5_context ctx, ldap_seqof_key_data *p) - free(p->key_data); - } - #endif -+ -+void -+ktest_empty_kkdcp_message(krb5_kkdcp_message *p) -+{ -+ ktest_empty_data(&p->kerb_message); -+ ktest_empty_data(&p->target_domain); -+ p->dclocator_hint = -1; -+} -diff --git a/src/tests/asn.1/ktest.h b/src/tests/asn.1/ktest.h -index 67a6c69..a9ebb77 100644 ---- a/src/tests/asn.1/ktest.h -+++ b/src/tests/asn.1/ktest.h -@@ -119,6 +119,9 @@ void ktest_make_sample_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p); - #ifdef ENABLE_LDAP - void ktest_make_sample_ldap_seqof_key_data(ldap_seqof_key_data *p); - #endif -+ -+void ktest_make_sample_kkdcp_message(krb5_kkdcp_message *p); -+ - /*----------------------------------------------------------------------*/ - - void ktest_empty_authorization_data(krb5_authdata **ad); -@@ -200,6 +203,8 @@ void ktest_empty_pkinit_supp_pub_info(krb5_pkinit_supp_pub_info *p); - void ktest_empty_ldap_seqof_key_data(krb5_context, ldap_seqof_key_data *p); - #endif - -+void ktest_empty_kkdcp_message(krb5_kkdcp_message *p); -+ - extern krb5_context test_context; - extern char *sample_principal_name; - -diff --git a/src/tests/asn.1/ktest_equal.c b/src/tests/asn.1/ktest_equal.c -index 4e71242..39c35b5 100644 ---- a/src/tests/asn.1/ktest_equal.c -+++ b/src/tests/asn.1/ktest_equal.c -@@ -1039,3 +1039,15 @@ ktest_equal_reply_key_pack_draft9(krb5_reply_key_pack_draft9 *ref, - } - - #endif /* not DISABLE_PKINIT */ -+ -+int -+ktest_equal_kkdcp_message(krb5_kkdcp_message *ref, krb5_kkdcp_message *var) -+{ -+ int p = TRUE; -+ if (ref == var) return TRUE; -+ else if (ref == NULL || var == NULL) return FALSE; -+ p = p && data_eq(ref->kerb_message, var->kerb_message); -+ p = p && data_eq(ref->target_domain, var->target_domain); -+ p = p && (ref->dclocator_hint == var->dclocator_hint); -+ return p; -+} -diff --git a/src/tests/asn.1/ktest_equal.h b/src/tests/asn.1/ktest_equal.h -index e75f86a..491653f 100644 ---- a/src/tests/asn.1/ktest_equal.h -+++ b/src/tests/asn.1/ktest_equal.h -@@ -145,4 +145,7 @@ generic(ktest_equal_reply_key_pack, krb5_reply_key_pack); - generic(ktest_equal_reply_key_pack_draft9, krb5_reply_key_pack_draft9); - #endif /* not DISABLE_PKINIT */ - -+int ktest_equal_kkdcp_message(krb5_kkdcp_message *ref, -+ krb5_kkdcp_message *var); -+ - #endif -diff --git a/src/tests/asn.1/reference_encode.out b/src/tests/asn.1/reference_encode.out -index 315e25b..b737da3 100644 ---- a/src/tests/asn.1/reference_encode.out -+++ b/src/tests/asn.1/reference_encode.out -@@ -68,3 +68,4 @@ encode_krb5_pa_otp_challenge: 30 81 A5 80 08 6D 61 78 6E 6F 6E 63 65 81 0B 74 65 - encode_krb5_pa_otp_req(optionals NULL): 30 2C 80 05 00 00 00 00 00 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 - encode_krb5_pa_otp_req: 30 81 B9 80 05 00 60 00 00 00 81 05 6E 6F 6E 63 65 A2 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A3 0B 06 09 60 86 48 01 65 03 04 02 01 84 02 03 E8 85 05 66 72 6F 67 73 86 0A 6D 79 66 69 72 73 74 70 69 6E 87 05 68 61 72 6B 21 88 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A 89 03 33 34 36 8A 01 02 8B 09 79 6F 75 72 74 6F 6B 65 6E 8C 28 75 72 6E 3A 69 65 74 66 3A 70 61 72 61 6D 73 3A 78 6D 6C 3A 6E 73 3A 6B 65 79 70 72 6F 76 3A 70 73 6B 63 3A 68 6F 74 70 8D 0B 45 78 61 6D 70 6C 65 63 6F 72 70 - encode_krb5_pa_otp_enc_req: 30 0A 80 08 6B 72 62 35 64 61 74 61 -+encode_krb5_kkdcp_message: 30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61 -diff --git a/src/tests/asn.1/trval_reference.out b/src/tests/asn.1/trval_reference.out -index 461021e..599580c 100644 ---- a/src/tests/asn.1/trval_reference.out -+++ b/src/tests/asn.1/trval_reference.out -@@ -1478,3 +1478,40 @@ encode_krb5_pa_otp_enc_req: - [Sequence/Sequence Of] - . [0] <8> - 6b 72 62 35 64 61 74 61 krb5data -+ -+encode_krb5_kkdcp_message: -+ -+[Sequence/Sequence Of] -+. [0] [Octet String] <488> -+ 6a 82 01 e4 30 82 01 e0 a1 03 02 01 05 a2 03 02 j...0........... -+ 01 0a a3 26 30 24 30 10 a1 03 02 01 0d a2 09 04 ...&0$0......... -+ 07 70 61 2d 64 61 74 61 30 10 a1 03 02 01 0d a2 .pa-data0....... -+ 09 04 07 70 61 2d 64 61 74 61 a4 82 01 aa 30 82 ...pa-data....0. -+ 01 a6 a0 07 03 05 00 fe dc ba 98 a1 1a 30 18 a0 .............0.. -+ 03 02 01 01 a1 11 30 0f 1b 06 68 66 74 73 61 69 ......0...hftsai -+ 1b 05 65 78 74 72 61 a2 10 1b 0e 41 54 48 45 4e ..extra....ATHEN -+ 41 2e 4d 49 54 2e 45 44 55 a3 1a 30 18 a0 03 02 A.MIT.EDU..0.... -+ 01 01 a1 11 30 0f 1b 06 68 66 74 73 61 69 1b 05 ....0...hftsai.. -+ 65 78 74 72 61 a4 11 18 0f 31 39 39 34 30 36 31 extra....1994061 -+ 30 30 36 30 33 31 37 5a a5 11 18 0f 31 39 39 34 0060317Z....1994 -+ 30 36 31 30 30 36 30 33 31 37 5a a6 11 18 0f 31 0610060317Z....1 -+ 39 39 34 30 36 31 30 30 36 30 33 31 37 5a a7 03 9940610060317Z.. -+ 02 01 2a a8 08 30 06 02 01 00 02 01 01 a9 20 30 ..*..0........ 0 -+ 1e 30 0d a0 03 02 01 02 a1 06 04 04 12 d0 00 23 .0.............# -+ 30 0d a0 03 02 01 02 a1 06 04 04 12 d0 00 23 aa 0.............#. -+ 25 30 23 a0 03 02 01 00 a1 03 02 01 05 a2 17 04 %0#............. -+ 15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74 20 6d .krbASN.1 test m -+ 65 73 73 61 67 65 ab 81 bf 30 81 bc 61 5c 30 5a essage...0..a\0Z -+ a0 03 02 01 05 a1 10 1b 0e 41 54 48 45 4e 41 2e .........ATHENA. -+ 4d 49 54 2e 45 44 55 a2 1a 30 18 a0 03 02 01 01 MIT.EDU..0...... -+ a1 11 30 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 ..0...hftsai..ex -+ 74 72 61 a3 25 30 23 a0 03 02 01 00 a1 03 02 01 tra.%0#......... -+ 05 a2 17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65 .....krbASN.1 te -+ 73 74 20 6d 65 73 73 61 67 65 61 5c 30 5a a0 03 st messagea\0Z.. -+ 02 01 05 a1 10 1b 0e 41 54 48 45 4e 41 2e 4d 49 .......ATHENA.MI -+ 54 2e 45 44 55 a2 1a 30 18 a0 03 02 01 01 a1 11 T.EDU..0........ -+ 30 0f 1b 06 68 66 74 73 61 69 1b 05 65 78 74 72 0...hftsai..extr -+ 61 a3 25 30 23 a0 03 02 01 00 a1 03 02 01 05 a2 a.%0#........... -+ 17 04 15 6b 72 62 41 53 4e 2e 31 20 74 65 73 74 ...krbASN.1 test -+ 20 6d 65 73 73 61 67 65 message -+. [1] [General string] "krb5data" --- -2.1.0 - diff --git a/SOURCES/0005-Copy-config-entries-to-the-ksu-target-ccache.patch b/SOURCES/0005-Copy-config-entries-to-the-ksu-target-ccache.patch deleted file mode 100644 index e004136..0000000 --- a/SOURCES/0005-Copy-config-entries-to-the-ksu-target-ccache.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 297496f0938955ba4aaf0ebecf4e393e527b8cbf Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Tue, 29 Oct 2013 16:27:20 -0400 -Subject: [PATCH 5/7] Copy config entries to the ksu target ccache - -When we try to screen out expired creds while reading them from one -ccache to eventually store in another, also keep configuration entries. - -ticket: 7986 (new) ---- - src/clients/ksu/ccache.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c -index 4693bd4..0f9e042 100644 ---- a/src/clients/ksu/ccache.c -+++ b/src/clients/ksu/ccache.c -@@ -219,7 +219,8 @@ krb5_error_code krb5_get_nonexp_tkts(context, cc, creds_array) - - while (!(retval = krb5_cc_next_cred(context, cc, &cur, &creds))){ - -- if ((retval = krb5_check_exp(context, creds.times))){ -+ if (!krb5_is_config_principal(context, creds.server) && -+ (retval = krb5_check_exp(context, creds.times))){ - if (retval != KRB5KRB_AP_ERR_TKT_EXPIRED){ - return retval; - } --- -2.0.4 - diff --git a/SOURCES/0006-Dispatch-style-protocol-switching-for-transport.patch b/SOURCES/0006-Dispatch-style-protocol-switching-for-transport.patch deleted file mode 100644 index e36544e..0000000 --- a/SOURCES/0006-Dispatch-style-protocol-switching-for-transport.patch +++ /dev/null @@ -1,506 +0,0 @@ -From 606e2ccc0a2546a23761f910482a55c5bf0f98ac Mon Sep 17 00:00:00 2001 -From: "Robbie Harwood (frozencemetery)" -Date: Fri, 16 Aug 2013 14:48:55 -0400 -Subject: [PATCH 06/13] Dispatch-style protocol switching for transport - -Switch to using per-transport-type functions when a socket that we're -using to communicate with a server becomes readable or writable, and add -them as pointers to the connection state. The functions are passed the -name of the realm of the server being contacted, as we expect to need -this in the near future. - -[nalin@redhat.com: replace macros with typedefs] -[nalin@redhat.com: compare transports with TCP_OR_UDP rather than with 0] - -ticket: 7929 ---- - src/lib/krb5/os/changepw.c | 6 +- - src/lib/krb5/os/os-proto.h | 1 + - src/lib/krb5/os/sendto_kdc.c | 297 ++++++++++++++++++++++++------------------- - 3 files changed, 171 insertions(+), 133 deletions(-) - -diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c -index a1c9885..0ee427d 100644 ---- a/src/lib/krb5/os/changepw.c -+++ b/src/lib/krb5/os/changepw.c -@@ -261,9 +261,9 @@ change_set_password(krb5_context context, - callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup; - krb5_free_data_contents(callback_ctx.context, &chpw_rep); - -- code = k5_sendto(callback_ctx.context, NULL, &sl, strategy, -- &callback_info, &chpw_rep, ss2sa(&remote_addr), -- &addrlen, NULL, NULL, NULL); -+ code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, -+ &sl, strategy, &callback_info, &chpw_rep, -+ ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); - if (code) { - /* - * Here we may want to switch to TCP on some errors. -diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h -index f23dda5..e60ccd0 100644 ---- a/src/lib/krb5/os/os-proto.h -+++ b/src/lib/krb5/os/os-proto.h -@@ -115,6 +115,7 @@ int _krb5_use_dns_kdc (krb5_context); - int _krb5_conf_boolean (const char *); - - krb5_error_code k5_sendto(krb5_context context, const krb5_data *message, -+ const krb5_data *realm, - const struct serverlist *addrs, - k5_transport_strategy strategy, - struct sendto_callback_info *callback_info, -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index c6aae8e..28f1c4d 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -96,11 +96,18 @@ struct outgoing_message { - unsigned char msg_len_buf[4]; - }; - -+struct conn_state; -+typedef krb5_boolean fd_handler_fn(krb5_context context, -+ const krb5_data *realm, -+ struct conn_state *conn, -+ struct select_state *selstate); -+ - struct conn_state { - SOCKET fd; - enum conn_states state; -- int (*service)(krb5_context context, struct conn_state *, -- struct select_state *, int); -+ fd_handler_fn *service_connect; -+ fd_handler_fn *service_write; -+ fd_handler_fn *service_read; - struct remote_address addr; - struct incoming_message in; - struct outgoing_message out; -@@ -409,9 +416,9 @@ krb5_sendto_kdc(krb5_context context, const krb5_data *message, - return retval; - - err = 0; -- retval = k5_sendto(context, message, &servers, strategy, NULL, reply, -- NULL, NULL, &server_used, check_for_svc_unavailable, -- &err); -+ retval = k5_sendto(context, message, realm, &servers, strategy, NULL, -+ reply, NULL, NULL, &server_used, -+ check_for_svc_unavailable, &err); - if (retval == KRB5_KDC_UNREACH) { - if (err == KDC_ERR_SVC_UNAVAILABLE) { - retval = KRB5KDC_ERR_SVC_UNAVAILABLE; -@@ -457,10 +464,10 @@ cleanup: - * connections already in progress - */ - --static int service_tcp_fd(krb5_context context, struct conn_state *conn, -- struct select_state *selstate, int ssflags); --static int service_udp_fd(krb5_context context, struct conn_state *conn, -- struct select_state *selstate, int ssflags); -+static fd_handler_fn service_tcp_connect; -+static fd_handler_fn service_tcp_write; -+static fd_handler_fn service_tcp_read; -+static fd_handler_fn service_udp_read; - - /* Set up the actual message we will send across the underlying transport to - * communicate the payload message, using one or both of state->out.sgbuf. */ -@@ -505,9 +512,13 @@ add_connection(struct conn_state **conns, k5_transport transport, - state->server_index = server_index; - SG_SET(&state->out.sgbuf[1], NULL, 0); - if (transport == TCP) { -- state->service = service_tcp_fd; -+ state->service_connect = service_tcp_connect; -+ state->service_write = service_tcp_write; -+ state->service_read = service_tcp_read; - } else { -- state->service = service_udp_fd; -+ state->service_connect = NULL; -+ state->service_write = NULL; -+ state->service_read = service_udp_read; - - if (*udpbufp == NULL) { - *udpbufp = malloc(MAX_DGRAM_SIZE); -@@ -788,9 +799,13 @@ maybe_send(krb5_context context, struct conn_state *conn, - } - - static void --kill_conn(struct conn_state *conn, struct select_state *selstate) -+kill_conn(krb5_context context, struct conn_state *conn, -+ struct select_state *selstate) - { -+ if (socktype_for_transport(conn->addr.transport) == SOCK_STREAM) -+ TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr); - cm_remove_fd(selstate, conn->fd); -+ - closesocket(conn->fd); - conn->fd = INVALID_SOCKET; - conn->state = FAILED; -@@ -814,136 +829,157 @@ get_so_error(int fd) - return sockerr; - } - --/* Process events on a TCP socket. Return 1 if we get a complete reply. */ --static int --service_tcp_fd(krb5_context context, struct conn_state *conn, -- struct select_state *selstate, int ssflags) -+/* Perform next step in sending. Return true on usable data. */ -+static krb5_boolean -+service_dispatch(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate, -+ int ssflags) - { -- int e = 0; -- ssize_t nwritten, nread; -- SOCKET_WRITEV_TEMP tmp; -- struct incoming_message *in = &conn->in; -- struct outgoing_message *out = &conn->out; -- - /* Check for a socket exception. */ -- if (ssflags & SSF_EXCEPTION) -- goto kill_conn; -+ if (ssflags & SSF_EXCEPTION) { -+ kill_conn(context, conn, selstate); -+ return FALSE; -+ } - - switch (conn->state) { - case CONNECTING: -- /* Check whether the connection succeeded. */ -- e = get_so_error(conn->fd); -- if (e) { -- TRACE_SENDTO_KDC_TCP_ERROR_CONNECT(context, &conn->addr, e); -- goto kill_conn; -- } -- conn->state = WRITING; -+ assert(conn->service_connect != NULL); -+ return conn->service_connect(context, realm, conn, selstate); -+ case WRITING: -+ assert(conn->service_write != NULL); -+ return conn->service_write(context, realm, conn, selstate); -+ case READING: -+ assert(conn->service_read != NULL); -+ return conn->service_read(context, realm, conn, selstate); -+ default: -+ abort(); -+ } -+} - -- /* Record this connection's timeout for service_fds. */ -- if (get_curtime_ms(&conn->endtime) == 0) -- conn->endtime += 10000; -+/* Initialize TCP transport. */ -+static krb5_boolean -+service_tcp_connect(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) -+{ -+ /* Check whether the connection succeeded. */ -+ int e = get_so_error(conn->fd); - -- /* Fall through. */ -- case WRITING: -- TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr); -- nwritten = SOCKET_WRITEV(conn->fd, out->sgp, out->sg_count, tmp); -- if (nwritten < 0) { -- TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr, -- SOCKET_ERRNO); -- goto kill_conn; -+ if (e) { -+ TRACE_SENDTO_KDC_TCP_ERROR_CONNECT(context, &conn->addr, e); -+ kill_conn(context, conn, selstate); -+ return FALSE; -+ } -+ -+ conn->state = WRITING; -+ -+ /* Record this connection's timeout for service_fds. */ -+ if (get_curtime_ms(&conn->endtime) == 0) -+ conn->endtime += 10000; -+ -+ return service_tcp_write(context, realm, conn, selstate); -+} -+ -+/* Sets conn->state to READING when done. */ -+static krb5_boolean -+service_tcp_write(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) -+{ -+ ssize_t nwritten; -+ SOCKET_WRITEV_TEMP tmp; -+ -+ TRACE_SENDTO_KDC_TCP_SEND(context, &conn->addr); -+ nwritten = SOCKET_WRITEV(conn->fd, conn->out.sgp, conn->out.sg_count, tmp); -+ if (nwritten < 0) { -+ TRACE_SENDTO_KDC_TCP_ERROR_SEND(context, &conn->addr, SOCKET_ERRNO); -+ kill_conn(context, conn, selstate); -+ return FALSE; -+ } -+ while (nwritten) { -+ sg_buf *sgp = conn->out.sgp; -+ if ((size_t)nwritten < SG_LEN(sgp)) { -+ SG_ADVANCE(sgp, (size_t)nwritten); -+ nwritten = 0; -+ } else { -+ nwritten -= SG_LEN(sgp); -+ conn->out.sgp++; -+ conn->out.sg_count--; - } -- while (nwritten) { -- sg_buf *sgp = out->sgp; -- if ((size_t) nwritten < SG_LEN(sgp)) { -- SG_ADVANCE(sgp, (size_t) nwritten); -- nwritten = 0; -- } else { -- nwritten -= SG_LEN(sgp); -- out->sgp++; -- out->sg_count--; -- } -+ } -+ if (conn->out.sg_count == 0) { -+ /* Done writing, switch to reading. */ -+ cm_read(selstate, conn->fd); -+ conn->state = READING; -+ } -+ return FALSE; -+} -+ -+/* Return true on usable data. */ -+static krb5_boolean -+service_tcp_read(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) -+{ -+ ssize_t nread; -+ int e = 0; -+ struct incoming_message *in = &conn->in; -+ -+ if (in->bufsizebytes_read == 4) { -+ /* Reading data. */ -+ nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left); -+ if (nread <= 0) { -+ e = nread ? SOCKET_ERRNO : ECONNRESET; -+ TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e); -+ kill_conn(context, conn, selstate); -+ return FALSE; - } -- if (out->sg_count == 0) { -- /* Done writing, switch to reading. */ -- cm_read(selstate, conn->fd); -- conn->state = READING; -- in->bufsizebytes_read = 0; -- in->bufsize = 0; -- in->pos = 0; -- in->buf = NULL; -- in->n_left = 0; -+ in->n_left -= nread; -+ in->pos += nread; -+ if (in->n_left <= 0) -+ return TRUE; -+ } else { -+ /* Reading length. */ -+ nread = SOCKET_READ(conn->fd, in->bufsizebytes + in->bufsizebytes_read, -+ 4 - in->bufsizebytes_read); -+ if (nread <= 0) { -+ e = nread ? SOCKET_ERRNO : ECONNRESET; -+ TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e); -+ kill_conn(context, conn, selstate); -+ return FALSE; - } -- return 0; -- -- case READING: -+ in->bufsizebytes_read += nread; - if (in->bufsizebytes_read == 4) { -- /* Reading data. */ -- nread = SOCKET_READ(conn->fd, &in->buf[in->pos], in->n_left); -- if (nread <= 0) { -- e = nread ? SOCKET_ERRNO : ECONNRESET; -- TRACE_SENDTO_KDC_TCP_ERROR_RECV(context, &conn->addr, e); -- goto kill_conn; -- } -- in->n_left -= nread; -- in->pos += nread; -- if (in->n_left <= 0) -- return 1; -- } else { -- /* Reading length. */ -- nread = SOCKET_READ(conn->fd, -- in->bufsizebytes + in->bufsizebytes_read, -- 4 - in->bufsizebytes_read); -- if (nread <= 0) { -- e = nread ? SOCKET_ERRNO : ECONNRESET; -- TRACE_SENDTO_KDC_TCP_ERROR_RECV_LEN(context, &conn->addr, e); -- goto kill_conn; -+ unsigned long len = load_32_be(in->bufsizebytes); -+ /* Arbitrary 1M cap. */ -+ if (len > 1 * 1024 * 1024) { -+ kill_conn(context, conn, selstate); -+ return FALSE; - } -- in->bufsizebytes_read += nread; -- if (in->bufsizebytes_read == 4) { -- unsigned long len = load_32_be(in->bufsizebytes); -- /* Arbitrary 1M cap. */ -- if (len > 1 * 1024 * 1024) -- goto kill_conn; -- in->bufsize = in->n_left = len; -- in->pos = 0; -- in->buf = malloc(len); -- if (in->buf == NULL) -- goto kill_conn; -+ in->bufsize = in->n_left = len; -+ in->pos = 0; -+ in->buf = malloc(len); -+ if (in->buf == NULL) { -+ kill_conn(context, conn, selstate); -+ return FALSE; - } - } -- break; -- -- default: -- abort(); - } -- return 0; -- --kill_conn: -- TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr); -- kill_conn(conn, selstate); -- return 0; -+ return FALSE; - } - --/* Process events on a UDP socket. Return 1 if we get a reply. */ --static int --service_udp_fd(krb5_context context, struct conn_state *conn, -- struct select_state *selstate, int ssflags) -+/* Process events on a UDP socket. Return true if we get a reply. */ -+static krb5_boolean -+service_udp_read(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) - { - int nread; - -- if (!(ssflags & (SSF_READ|SSF_EXCEPTION))) -- abort(); -- if (conn->state != READING) -- abort(); -- - nread = recv(conn->fd, conn->in.buf, conn->in.bufsize, 0); - if (nread < 0) { - TRACE_SENDTO_KDC_UDP_ERROR_RECV(context, &conn->addr, SOCKET_ERRNO); -- kill_conn(conn, selstate); -- return 0; -+ kill_conn(context, conn, selstate); -+ return FALSE; - } - conn->in.pos = nread; -- return 1; -+ return TRUE; - } - - /* Return the maximum of endtime and the endtime fields of all currently active -@@ -965,7 +1001,7 @@ get_endtime(time_ms endtime, struct conn_state *conns) - static krb5_boolean - service_fds(krb5_context context, struct select_state *selstate, - time_ms interval, struct conn_state *conns, -- struct select_state *seltemp, -+ struct select_state *seltemp, const krb5_data *realm, - int (*msg_handler)(krb5_context, const krb5_data *, void *), - void *msg_handler_data, struct conn_state **winner_out) - { -@@ -977,7 +1013,7 @@ service_fds(krb5_context context, struct select_state *selstate, - - e = get_curtime_ms(&endtime); - if (e) -- return 1; -+ return TRUE; - endtime += interval; - - e = 0; -@@ -991,7 +1027,7 @@ service_fds(krb5_context context, struct select_state *selstate, - - if (selret == 0) - /* Timeout, return to caller. */ -- return 0; -+ return FALSE; - - /* Got something on a socket, process it. */ - for (state = conns; state != NULL; state = state->next) { -@@ -1003,7 +1039,7 @@ service_fds(krb5_context context, struct select_state *selstate, - if (!ssflags) - continue; - -- if (state->service(context, state, selstate, ssflags)) { -+ if (service_dispatch(context, realm, state, selstate, ssflags)) { - int stop = 1; - - if (msg_handler != NULL) { -@@ -1014,14 +1050,14 @@ service_fds(krb5_context context, struct select_state *selstate, - - if (stop) { - *winner_out = state; -- return 1; -+ return TRUE; - } - } - } - } - if (e != 0) -- return 1; -- return 0; -+ return TRUE; -+ return FALSE; - } - - /* -@@ -1052,7 +1088,8 @@ service_fds(krb5_context context, struct select_state *selstate, - - krb5_error_code - k5_sendto(krb5_context context, const krb5_data *message, -- const struct serverlist *servers, k5_transport_strategy strategy, -+ const krb5_data *realm, const struct serverlist *servers, -+ k5_transport_strategy strategy, - struct sendto_callback_info* callback_info, krb5_data *reply, - struct sockaddr *remoteaddr, socklen_t *remoteaddrlen, - int *server_used, -@@ -1098,7 +1135,7 @@ k5_sendto(krb5_context context, const krb5_data *message, - if (maybe_send(context, state, message, sel_state, callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, -- msg_handler, msg_handler_data, &winner); -+ realm, msg_handler, msg_handler_data, &winner); - } - } - -@@ -1110,13 +1147,13 @@ k5_sendto(krb5_context context, const krb5_data *message, - if (maybe_send(context, state, message, sel_state, callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, -- msg_handler, msg_handler_data, &winner); -+ realm, msg_handler, msg_handler_data, &winner); - } - - /* Wait for two seconds at the end of the first pass. */ - if (!done) { - done = service_fds(context, sel_state, 2000, conns, seltemp, -- msg_handler, msg_handler_data, &winner); -+ realm, msg_handler, msg_handler_data, &winner); - } - - /* Make remaining passes over all of the connections. */ -@@ -1126,14 +1163,14 @@ k5_sendto(krb5_context context, const krb5_data *message, - if (maybe_send(context, state, message, sel_state, callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, -- msg_handler, msg_handler_data, &winner); -+ realm, msg_handler, msg_handler_data, &winner); - if (sel_state->nfds == 0) - break; - } - /* Wait for the delay backoff at the end of this pass. */ - if (!done) { - done = service_fds(context, sel_state, delay, conns, seltemp, -- msg_handler, msg_handler_data, &winner); -+ realm, msg_handler, msg_handler_data, &winner); - } - if (sel_state->nfds == 0) - break; --- -2.1.0 - diff --git a/SOURCES/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch b/SOURCES/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch deleted file mode 100644 index da8a32a..0000000 --- a/SOURCES/0006-Use-more-randomness-for-ksu-secondary-cache-names.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 69c8e20b18577781e17c5959e23514134dfb5755 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Thu, 24 Jul 2014 16:43:21 -0400 -Subject: [PATCH 6/7] Use more randomness for ksu secondary cache names - -When generating a suffix to append to a ccache name that will hold the -credentials for a ksu-invoked process, instead of using integers -counting up from 1, use the result of base64-encoding six randomly- -generated octets. Tweak the output alphabet just a bit to avoid using -'+' or '/' in the generated names, the latter of which could really -confuse things. ---- - src/clients/ksu/ccache.c | 27 +++++++++++++++++++++++---- - src/clients/ksu/ksu.h | 2 +- - src/clients/ksu/main.c | 16 ++++++++++++---- - 3 files changed, 36 insertions(+), 9 deletions(-) - -diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c -index 0f9e042..a0736f2 100644 ---- a/src/clients/ksu/ccache.c -+++ b/src/clients/ksu/ccache.c -@@ -27,6 +27,7 @@ - */ - - #include "ksu.h" -+#include "k5-base64.h" - #include "adm_proto.h" - #include - #include -@@ -504,10 +505,28 @@ show_credential(context, cred, cc) - free(sname); - } - --int gen_sym(){ -- static int i = 0; -- i ++; -- return i; -+/* Create a random string suitable for a filename extension. */ -+krb5_error_code -+gen_sym(krb5_context context, char **sym_out) -+{ -+ krb5_error_code retval; -+ char bytes[6], *p, *sym; -+ krb5_data data = make_data(bytes, sizeof(bytes)); -+ -+ *sym_out = NULL; -+ retval = krb5_c_random_make_octets(context, &data); -+ if (retval) -+ return retval; -+ sym = k5_base64_encode(data.data, data.length); -+ if (sym == NULL) -+ return ENOMEM; -+ /* Tweak the output alphabet just a bit. */ -+ while ((p = strchr(sym, '/')) != NULL) -+ *p = '_'; -+ while ((p = strchr(sym, '+')) != NULL) -+ *p = '-'; -+ *sym_out = sym; -+ return 0; - } - - krb5_error_code krb5_ccache_overwrite(context, ccs, cct, primary_principal) -diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h -index fbbf217..5ba5ceb 100644 ---- a/src/clients/ksu/ksu.h -+++ b/src/clients/ksu/ksu.h -@@ -130,7 +130,7 @@ extern krb5_error_code krb5_get_login_princ - extern void show_credential - (krb5_context, krb5_creds *, krb5_ccache); - --extern int gen_sym (void); -+krb5_error_code gen_sym(krb5_context context, char **sym); - - extern krb5_error_code krb5_ccache_overwrite - (krb5_context, krb5_ccache, krb5_ccache, krb5_principal); -diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c -index 41a3bf8..47fa820 100644 ---- a/src/clients/ksu/main.c -+++ b/src/clients/ksu/main.c -@@ -856,7 +856,7 @@ resolve_target_cache(krb5_context context, krb5_principal princ, - krb5_error_code retval; - krb5_boolean switchable, reused = FALSE; - krb5_ccache ccache = NULL; -- char *sep, *ccname = NULL, *target; -+ char *sep, *ccname = NULL, *sym = NULL, *target; - - *ccache_out = NULL; - *ccache_reused = FALSE; -@@ -876,12 +876,20 @@ resolve_target_cache(krb5_context context, krb5_principal princ, - * the name of a cache that doesn't exist yet. */ - do { - free(ccname); -- if (asprintf(&ccname, "%s.%d", target, gen_sym()) < 0) { -+ retval = gen_sym(context, &sym); -+ if (retval) { -+ com_err(prog_name, retval, -+ _("while generating part of the target ccache name")); -+ return retval; -+ } -+ if (asprintf(&ccname, "%s.%s", target, sym) < 0) { - retval = ENOMEM; -- com_err(prog_name, ENOMEM, -- _("while allocating memory for target ccache name")); -+ free(sym); -+ com_err(prog_name, retval, _("while allocating memory for the " -+ "target ccache name")); - goto cleanup; - } -+ free(sym); - } while (ks_ccache_name_is_initialized(context, ccname)); - retval = krb5_cc_resolve(context, ccname, &ccache); - } else { --- -2.0.4 - diff --git a/SOURCES/0007-HTTPS-transport-Microsoft-KKDCPP-implementation.patch b/SOURCES/0007-HTTPS-transport-Microsoft-KKDCPP-implementation.patch deleted file mode 100644 index cd21dac..0000000 --- a/SOURCES/0007-HTTPS-transport-Microsoft-KKDCPP-implementation.patch +++ /dev/null @@ -1,858 +0,0 @@ -From d950809ff49e3e7603594186d77135a09ab6b1b2 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Thu, 24 Apr 2014 16:30:56 -0400 -Subject: [PATCH 07/13] HTTPS transport (Microsoft KKDCPP implementation) - -Add an 'HTTPS' transport type which connects to an [MS-KKDCP] proxy -server using HTTPS to communicate with a KDC. The KDC's name should -take the form of an HTTPS URL (e.g. "https://proxybox/KdcProxy"). - -An HTTPS connection's encryption layer can be reading and writing when -the application layer is expecting to write and read, so the HTTPS -callbacks have to handle being called multiple times. - -[nalin@redhat.com: use cleanup labels, make sure we always send the - realm name, keep a copy of the URI on-hand, move most of the - conditionally-compiled sections into their own conditionally-built - functions, break out HTTPS request formatting into a helper function, - handle the MS-KKDCP length bytes, update comments to mention specific - versions of the MS-KKDCP spec, differentiate TCP and HTTP trace - messages, trace unparseable responses] - -ticket: 7929 ---- - src/include/k5-trace.h | 13 ++ - src/lib/krb5/os/locate_kdc.c | 63 ++++++- - src/lib/krb5/os/os-proto.h | 2 + - src/lib/krb5/os/sendto_kdc.c | 417 ++++++++++++++++++++++++++++++++++++++--- - src/lib/krb5/os/t_locate_kdc.c | 2 + - src/lib/krb5/os/trace.c | 2 + - 6 files changed, 471 insertions(+), 28 deletions(-) - -diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h -index dfd34f6..f0d79f1 100644 ---- a/src/include/k5-trace.h -+++ b/src/include/k5-trace.h -@@ -312,6 +312,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); - TRACE(c, "AP-REQ ticket: {princ} -> {princ}, session key {keyblock}", \ - client, server, keyblock) - -+#define TRACE_SENDTO_KDC_ERROR_SET_MESSAGE(c, raddr, err) \ -+ TRACE(c, "Error preparing message to send to {raddr}: {errno}", \ -+ raddr, err) - #define TRACE_SENDTO_KDC(c, len, rlm, master, tcp) \ - TRACE(c, "Sending request ({int} bytes) to {data}{str}{str}", len, \ - rlm, (master) ? " (master)" : "", (tcp) ? " (tcp only)" : "") -@@ -321,6 +324,16 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); - TRACE(c, "Resolving hostname {str}", hostname) - #define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr) \ - TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr) -+#define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr) \ -+ TRACE(c, "HTTPS error connecting to {raddr}", raddr) -+#define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr, err) \ -+ TRACE(c, "HTTPS error receiving from {raddr}: {errno}", raddr, err) -+#define TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(c, raddr) \ -+ TRACE(c, "HTTPS error sending to {raddr}", raddr) -+#define TRACE_SENDTO_KDC_HTTPS_SEND(c, raddr) \ -+ TRACE(c, "Sending HTTPS request to {raddr}", raddr) -+#define TRACE_SENDTO_KDC_HTTPS_ERROR(c, errs) \ -+ TRACE(c, "HTTPS error: {str}", errs) - #define TRACE_SENDTO_KDC_TCP_CONNECT(c, raddr) \ - TRACE(c, "Initiating TCP connection to {raddr}", raddr) - #define TRACE_SENDTO_KDC_TCP_DISCONNECT(c, raddr) \ -diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c -index 4c8aead..1136809 100644 ---- a/src/lib/krb5/os/locate_kdc.c -+++ b/src/lib/krb5/os/locate_kdc.c -@@ -91,8 +91,10 @@ k5_free_serverlist (struct serverlist *list) - { - size_t i; - -- for (i = 0; i < list->nservers; i++) -+ for (i = 0; i < list->nservers; i++) { - free(list->servers[i].hostname); -+ free(list->servers[i].uri_path); -+ } - free(list->servers); - list->servers = NULL; - list->nservers = 0; -@@ -140,6 +142,7 @@ add_addr_to_list(struct serverlist *list, k5_transport transport, int family, - entry->transport = transport; - entry->family = family; - entry->hostname = NULL; -+ entry->uri_path = NULL; - entry->addrlen = addrlen; - memcpy(&entry->addr, addr, addrlen); - list->nservers++; -@@ -149,7 +152,7 @@ add_addr_to_list(struct serverlist *list, k5_transport transport, int family, - /* Add a hostname entry to list. */ - static int - add_host_to_list(struct serverlist *list, const char *hostname, int port, -- k5_transport transport, int family) -+ k5_transport transport, int family, char *uri_path) - { - struct server_entry *entry; - -@@ -160,11 +163,46 @@ add_host_to_list(struct serverlist *list, const char *hostname, int port, - entry->family = family; - entry->hostname = strdup(hostname); - if (entry->hostname == NULL) -- return ENOMEM; -+ goto oom; -+ if (uri_path != NULL) { -+ entry->uri_path = strdup(uri_path); -+ if (entry->uri_path == NULL) -+ goto oom; -+ } - entry->port = port; - list->nservers++; - return 0; -+oom: -+ free(entry->hostname); -+ entry->hostname = NULL; -+ return ENOMEM; -+} -+ -+#ifdef PROXY_TLS_IMPL_OPENSSL -+static void -+parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host, -+ char **uri_path) -+{ -+ char *cp; -+ -+ if (strncmp(host_or_uri, "https://", 8) == 0) { -+ *transport = HTTPS; -+ *host = host_or_uri + 8; -+ -+ cp = strchr(*host, '/'); -+ if (cp != NULL) { -+ *cp = '\0'; -+ *uri_path = cp + 1; -+ } -+ } -+} -+#else -+static void -+parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host, -+ char **uri) -+{ - } -+#endif - - /* Return true if server is identical to an entry in list. */ - static krb5_boolean -@@ -222,9 +260,14 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm, - - for (i=0; hostlist[i]; i++) { - int p1, p2; -+ k5_transport this_transport = transport; -+ char *uri_path = NULL; - - host = hostlist[i]; - Tprintf ("entry %d is '%s'\n", i, host); -+ -+ parse_uri_if_https(host, &this_transport, &host, &uri_path); -+ - /* Find port number, and strip off any excess characters. */ - if (*host == '[' && (cp = strchr(host, ']'))) - cp = cp + 1; -@@ -244,6 +287,9 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm, - return EINVAL; - p1 = htons (l); - p2 = 0; -+ } else if (this_transport == HTTPS) { -+ p1 = htons(443); -+ p2 = 0; - } else { - p1 = udpport; - p2 = sec_udpport; -@@ -255,12 +301,15 @@ locate_srv_conf_1(krb5_context context, const krb5_data *realm, - *cp = '\0'; - } - -- code = add_host_to_list(serverlist, host, p1, transport, AF_UNSPEC); -+ code = add_host_to_list(serverlist, host, p1, this_transport, -+ AF_UNSPEC, uri_path); - /* Second port is for IPv4 UDP only, and should possibly go away as - * it was originally a krb4 compatibility measure. */ - if (code == 0 && p2 != 0 && -- (transport == TCP_OR_UDP || transport == UDP)) -- code = add_host_to_list(serverlist, host, p2, UDP, AF_INET); -+ (this_transport == TCP_OR_UDP || this_transport == UDP)) { -+ code = add_host_to_list(serverlist, host, p2, UDP, AF_INET, -+ uri_path); -+ } - if (code) - goto cleanup; - } -@@ -313,7 +362,7 @@ locate_srv_dns_1(const krb5_data *realm, const char *service, - for (entry = head; entry != NULL; entry = entry->next) { - transport = (strcmp(protocol, "_tcp") == 0) ? TCP : UDP; - code = add_host_to_list(serverlist, entry->host, htons(entry->port), -- transport, AF_UNSPEC); -+ transport, AF_UNSPEC, NULL); - if (code) - goto cleanup; - } -diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h -index e60ccd0..34bf028 100644 ---- a/src/lib/krb5/os/os-proto.h -+++ b/src/lib/krb5/os/os-proto.h -@@ -42,6 +42,7 @@ typedef enum { - TCP_OR_UDP = 0, - TCP, - UDP, -+ HTTPS, - } k5_transport; - - typedef enum { -@@ -55,6 +56,7 @@ struct server_entry { - char *hostname; /* NULL -> use addrlen/addr instead */ - int port; /* Used only if hostname set */ - k5_transport transport; /* May be 0 for UDP/TCP if hostname set */ -+ char *uri_path; /* Used only if transport is HTTPS */ - int family; /* May be 0 (aka AF_UNSPEC) if hostname set */ - size_t addrlen; - struct sockaddr_storage addr; -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index 28f1c4d..a4727c4 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -23,6 +23,32 @@ - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - */ -+/* -+ * MS-KKDCP implementation Copyright 2013,2014 Red Hat, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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. -+ */ - - /* Send packet to KDC for realm; wait for response, retransmitting - * as necessary. */ -@@ -49,6 +75,7 @@ - #endif - - #ifdef PROXY_TLS_IMPL_OPENSSL -+#include - #include - #endif - -@@ -116,6 +143,13 @@ struct conn_state { - struct conn_state *next; - time_ms endtime; - krb5_boolean defer; -+ struct { -+ const char *uri_path; -+ char *https_request; -+#ifdef PROXY_TLS_IMPL_OPENSSL -+ SSL *ssl; -+#endif -+ } http; - }; - - void -@@ -140,6 +174,22 @@ get_curtime_ms(time_ms *time_out) - return 0; - } - -+#ifdef PROXY_TLS_IMPL_OPENSSL -+static void -+free_http_ssl_data(struct conn_state *state) -+{ -+ SSL_free(state->http.ssl); -+ state->http.ssl = NULL; -+ free(state->http.https_request); -+ state->http.https_request = NULL; -+} -+#else -+static void -+free_http_ssl_data(struct conn_state *state) -+{ -+} -+#endif -+ - #ifdef USE_POLL - - /* Find a pollfd in selstate by fd, or abort if we can't find it. */ -@@ -321,6 +371,7 @@ socktype_for_transport(k5_transport transport) - case UDP: - return SOCK_DGRAM; - case TCP: -+ case HTTPS: - return SOCK_STREAM; - default: - return 0; -@@ -468,33 +519,113 @@ static fd_handler_fn service_tcp_connect; - static fd_handler_fn service_tcp_write; - static fd_handler_fn service_tcp_read; - static fd_handler_fn service_udp_read; -+static fd_handler_fn service_https_write; -+static fd_handler_fn service_https_read; -+ -+#ifdef PROXY_TLS_IMPL_OPENSSL -+static krb5_error_code -+make_proxy_request(struct conn_state *state, const krb5_data *realm, -+ const krb5_data *message, char **req_out, size_t *len_out) -+{ -+ krb5_kkdcp_message pm; -+ krb5_data *encoded_pm = NULL; -+ struct k5buf buf; -+ const char *uri_path; -+ krb5_error_code ret; -+ -+ *req_out = NULL; -+ *len_out = 0; -+ -+ /* -+ * Stuff the message length in at the front of the kerb_message field -+ * before encoding. The proxied messages are actually the payload we'd -+ * be sending and receiving if we were using plain TCP. -+ */ -+ memset(&pm, 0, sizeof(pm)); -+ ret = alloc_data(&pm.kerb_message, message->length + 4); -+ if (ret != 0) -+ goto cleanup; -+ store_32_be(message->length, pm.kerb_message.data); -+ memcpy(pm.kerb_message.data + 4, message->data, message->length); -+ pm.target_domain = *realm; -+ ret = encode_krb5_kkdcp_message(&pm, &encoded_pm); -+ if (ret != 0) -+ goto cleanup; -+ -+ /* Build the request to transmit: the headers + the proxy message. */ -+ k5_buf_init_dynamic(&buf); -+ uri_path = (state->http.uri_path != NULL) ? state->http.uri_path : ""; -+ k5_buf_add_fmt(&buf, "POST /%s HTTP/1.0\r\n", uri_path); -+ k5_buf_add(&buf, "Cache-Control: no-cache\r\n"); -+ k5_buf_add(&buf, "Pragma: no-cache\r\n"); -+ k5_buf_add(&buf, "User-Agent: kerberos/1.0\r\n"); -+ k5_buf_add(&buf, "Content-type: application/kerberos\r\n"); -+ k5_buf_add_fmt(&buf, "Content-Length: %d\r\n\r\n", encoded_pm->length); -+ k5_buf_add_len(&buf, encoded_pm->data, encoded_pm->length); -+ if (k5_buf_data(&buf) == NULL) { -+ ret = ENOMEM; -+ goto cleanup; -+ } -+ -+ *req_out = k5_buf_data(&buf); -+ *len_out = k5_buf_len(&buf); -+ -+cleanup: -+ krb5_free_data_contents(NULL, &pm.kerb_message); -+ krb5_free_data(NULL, encoded_pm); -+ return ret; -+} -+#else -+static krb5_error_code -+make_proxy_request(struct conn_state *state, const krb5_data *realm, -+ const krb5_data *message, char **req_out, size_t *len_out) -+{ -+ abort(); -+} -+#endif - - /* Set up the actual message we will send across the underlying transport to - * communicate the payload message, using one or both of state->out.sgbuf. */ --static void --set_transport_message(struct conn_state *state, const krb5_data *message) -+static krb5_error_code -+set_transport_message(struct conn_state *state, const krb5_data *realm, -+ const krb5_data *message) - { - struct outgoing_message *out = &state->out; -+ char *req = NULL; -+ size_t reqlen; -+ krb5_error_code ret; - - if (message == NULL || message->length == 0) -- return; -+ return 0; - - if (state->addr.transport == TCP) { - store_32_be(message->length, out->msg_len_buf); - SG_SET(&out->sgbuf[0], out->msg_len_buf, 4); - SG_SET(&out->sgbuf[1], message->data, message->length); - out->sg_count = 2; -+ return 0; -+ } else if (state->addr.transport == HTTPS) { -+ ret = make_proxy_request(state, realm, message, &req, &reqlen); -+ if (ret != 0) -+ return ret; -+ SG_SET(&state->out.sgbuf[0], req, reqlen); -+ SG_SET(&state->out.sgbuf[1], 0, 0); -+ state->out.sg_count = 1; -+ free(state->http.https_request); -+ state->http.https_request = req; -+ return 0; - } else { - SG_SET(&out->sgbuf[0], message->data, message->length); - SG_SET(&out->sgbuf[1], NULL, 0); - out->sg_count = 1; -+ return 0; - } - } - - static krb5_error_code - add_connection(struct conn_state **conns, k5_transport transport, - krb5_boolean defer, struct addrinfo *ai, size_t server_index, -- char **udpbufp) -+ const krb5_data *realm, const char *uri_path, char **udpbufp) - { - struct conn_state *state, **tailptr; - -@@ -515,6 +646,11 @@ add_connection(struct conn_state **conns, k5_transport transport, - state->service_connect = service_tcp_connect; - state->service_write = service_tcp_write; - state->service_read = service_tcp_read; -+ } else if (transport == HTTPS) { -+ state->service_connect = service_tcp_connect; -+ state->service_write = service_https_write; -+ state->service_read = service_https_read; -+ state->http.uri_path = uri_path; - } else { - state->service_connect = NULL; - state->service_write = NULL; -@@ -589,10 +725,10 @@ translate_ai_error (int err) - * connections. - */ - static krb5_error_code --resolve_server(krb5_context context, const struct serverlist *servers, -- size_t ind, k5_transport_strategy strategy, -- const krb5_data *message, char **udpbufp, -- struct conn_state **conns) -+resolve_server(krb5_context context, const krb5_data *realm, -+ const struct serverlist *servers, size_t ind, -+ k5_transport_strategy strategy, const krb5_data *message, -+ char **udpbufp, struct conn_state **conns) - { - krb5_error_code retval; - struct server_entry *entry = &servers->servers[ind]; -@@ -615,7 +751,7 @@ resolve_server(krb5_context context, const struct serverlist *servers, - ai.ai_addr = (struct sockaddr *)&entry->addr; - defer = (entry->transport != transport); - return add_connection(conns, entry->transport, defer, &ai, ind, -- udpbufp); -+ realm, entry->uri_path, udpbufp); - } - - /* If the entry has a specified transport, use it. */ -@@ -639,8 +775,10 @@ resolve_server(krb5_context context, const struct serverlist *servers, - - /* Add each address with the specified or preferred transport. */ - retval = 0; -- for (a = addrs; a != 0 && retval == 0; a = a->ai_next) -- retval = add_connection(conns, transport, FALSE, a, ind, udpbufp); -+ for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { -+ retval = add_connection(conns, transport, FALSE, a, ind, realm, -+ entry->uri_path, udpbufp); -+ } - - /* For TCP_OR_UDP entries, add each address again with the non-preferred - * transport, unless we are avoiding UDP. Flag these as deferred. */ -@@ -648,7 +786,8 @@ resolve_server(krb5_context context, const struct serverlist *servers, - transport = (strategy == UDP_FIRST) ? TCP : UDP; - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { - a->ai_socktype = socktype_for_transport(transport); -- retval = add_connection(conns, transport, TRUE, a, ind, udpbufp); -+ retval = add_connection(conns, transport, TRUE, a, ind, realm, -+ entry->uri_path, udpbufp); - } - } - freeaddrinfo(addrs); -@@ -658,6 +797,7 @@ resolve_server(krb5_context context, const struct serverlist *servers, - static int - start_connection(krb5_context context, struct conn_state *state, - const krb5_data *message, struct select_state *selstate, -+ const krb5_data *realm, - struct sendto_callback_info *callback_info) - { - int fd, e, type; -@@ -718,7 +858,15 @@ start_connection(krb5_context context, struct conn_state *state, - - message = &state->callback_buffer; - } -- set_transport_message(state, message); -+ -+ e = set_transport_message(state, realm, message); -+ if (e != 0) { -+ TRACE_SENDTO_KDC_ERROR_SET_MESSAGE(context, &state->addr, e); -+ (void) closesocket(state->fd); -+ state->fd = INVALID_SOCKET; -+ state->state = FAILED; -+ return -4; -+ } - - if (state->addr.transport == UDP) { - /* Send it now. */ -@@ -733,7 +881,7 @@ start_connection(krb5_context context, struct conn_state *state, - (void) closesocket(state->fd); - state->fd = INVALID_SOCKET; - state->state = FAILED; -- return -4; -+ return -5; - } else { - state->state = READING; - } -@@ -760,6 +908,7 @@ start_connection(krb5_context context, struct conn_state *state, - static int - maybe_send(krb5_context context, struct conn_state *conn, - const krb5_data *message, struct select_state *selstate, -+ const krb5_data *realm, - struct sendto_callback_info *callback_info) - { - sg_buf *sg; -@@ -767,7 +916,7 @@ maybe_send(krb5_context context, struct conn_state *conn, - - if (conn->state == INITIALIZING) { - return start_connection(context, conn, message, selstate, -- callback_info); -+ realm, callback_info); - } - - /* Did we already shut down this channel? */ -@@ -802,6 +951,8 @@ static void - kill_conn(krb5_context context, struct conn_state *conn, - struct select_state *selstate) - { -+ free_http_ssl_data(conn); -+ - if (socktype_for_transport(conn->addr.transport) == SOCK_STREAM) - TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr); - cm_remove_fd(selstate, conn->fd); -@@ -876,7 +1027,7 @@ service_tcp_connect(krb5_context context, const krb5_data *realm, - if (get_curtime_ms(&conn->endtime) == 0) - conn->endtime += 10000; - -- return service_tcp_write(context, realm, conn, selstate); -+ return conn->service_write(context, realm, conn, selstate); - } - - /* Sets conn->state to READING when done. */ -@@ -982,6 +1133,223 @@ service_udp_read(krb5_context context, const krb5_data *realm, - return TRUE; - } - -+#ifdef PROXY_TLS_IMPL_OPENSSL -+/* Output any error strings that OpenSSL's accumulated as tracing messages. */ -+static void -+flush_ssl_errors(krb5_context context) -+{ -+ unsigned long err; -+ char buf[128]; -+ -+ while ((err = ERR_get_error()) != 0) { -+ ERR_error_string_n(err, buf, sizeof(buf)); -+ TRACE_SENDTO_KDC_HTTPS_ERROR(context, buf); -+ } -+} -+ -+/* -+ * Set up structures that we use to manage the SSL handling for this connection -+ * and apply any non-default settings. Kill the connection and return false if -+ * anything goes wrong while we're doing that; return true otherwise. -+ */ -+static krb5_boolean -+setup_ssl(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) -+{ -+ long options; -+ SSL_CTX *ctx = NULL; -+ SSL *ssl = NULL; -+ -+ /* Do general SSL library setup. */ -+ ctx = SSL_CTX_new(SSLv23_client_method()); -+ if (ctx == NULL) -+ goto kill_conn; -+ options = SSL_CTX_get_options(ctx); -+ SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2); -+ -+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); -+ if (!SSL_CTX_set_default_verify_paths(ctx)) -+ goto kill_conn; -+ -+ ssl = SSL_new(ctx); -+ if (ssl == NULL) -+ goto kill_conn; -+ -+ /* Tell the SSL library about the socket. */ -+ if (!SSL_set_fd(ssl, conn->fd)) -+ goto kill_conn; -+ SSL_set_connect_state(ssl); -+ -+ SSL_CTX_free(ctx); -+ conn->http.ssl = ssl; -+ -+ return TRUE; -+ -+kill_conn: -+ TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(context, &conn->addr); -+ flush_ssl_errors(context); -+ SSL_free(ssl); -+ SSL_CTX_free(ctx); -+ kill_conn(context, conn, selstate); -+ return FALSE; -+} -+ -+/* Set conn->state to READING when done; otherwise, call a cm_set_. */ -+static krb5_boolean -+service_https_write(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) -+{ -+ ssize_t nwritten; -+ int e; -+ -+ /* If this is our first time in here, set up the SSL context. */ -+ if (conn->http.ssl == NULL && !setup_ssl(context, realm, conn, selstate)) -+ return FALSE; -+ -+ /* Try to transmit our request to the server. */ -+ nwritten = SSL_write(conn->http.ssl, SG_BUF(conn->out.sgp), -+ SG_LEN(conn->out.sgbuf)); -+ if (nwritten <= 0) { -+ e = SSL_get_error(conn->http.ssl, nwritten); -+ if (e == SSL_ERROR_WANT_READ) { -+ cm_read(selstate, conn->fd); -+ return FALSE; -+ } else if (e == SSL_ERROR_WANT_WRITE) { -+ cm_write(selstate, conn->fd); -+ return FALSE; -+ } -+ TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(context, &conn->addr); -+ flush_ssl_errors(context); -+ kill_conn(context, conn, selstate); -+ return FALSE; -+ } -+ -+ /* Done writing, switch to reading. */ -+ TRACE_SENDTO_KDC_HTTPS_SEND(context, &conn->addr); -+ cm_read(selstate, conn->fd); -+ conn->state = READING; -+ return FALSE; -+} -+ -+/* -+ * Return true on readable data, call a cm_read/write function and return -+ * false if the SSL layer needs it, kill the connection otherwise. -+ */ -+static krb5_boolean -+https_read_bytes(krb5_context context, struct conn_state *conn, -+ struct select_state *selstate) -+{ -+ size_t bufsize; -+ ssize_t nread; -+ krb5_boolean readbytes = FALSE; -+ int e = 0; -+ char *tmp; -+ struct incoming_message *in = &conn->in; -+ -+ for (;;) { -+ if (in->buf == NULL || in->bufsize - in->pos < 1024) { -+ bufsize = in->bufsize ? in->bufsize * 2 : 8192; -+ if (bufsize > 1024 * 1024) { -+ kill_conn(context, conn, selstate); -+ return FALSE; -+ } -+ tmp = realloc(in->buf, bufsize); -+ if (tmp == NULL) { -+ kill_conn(context, conn, selstate); -+ return FALSE; -+ } -+ in->buf = tmp; -+ in->bufsize = bufsize; -+ } -+ -+ nread = SSL_read(conn->http.ssl, &in->buf[in->pos], -+ in->bufsize - in->pos - 1); -+ if (nread <= 0) -+ break; -+ in->pos += nread; -+ in->buf[in->pos] = '\0'; -+ readbytes = TRUE; -+ } -+ -+ e = SSL_get_error(conn->http.ssl, nread); -+ if (e == SSL_ERROR_WANT_READ) { -+ cm_read(selstate, conn->fd); -+ return FALSE; -+ } else if (e == SSL_ERROR_WANT_WRITE) { -+ cm_write(selstate, conn->fd); -+ return FALSE; -+ } else if ((e == SSL_ERROR_ZERO_RETURN) || -+ (e == SSL_ERROR_SYSCALL && nread == 0 && readbytes)) { -+ return TRUE; -+ } -+ -+ e = readbytes ? SOCKET_ERRNO : ECONNRESET; -+ TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(context, &conn->addr, e); -+ flush_ssl_errors(context); -+ kill_conn(context, conn, selstate); -+ return FALSE; -+} -+ -+/* Return true on readable, valid KKDCPP data. */ -+static krb5_boolean -+service_https_read(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) -+{ -+ krb5_kkdcp_message *pm = NULL; -+ krb5_data buf; -+ const char *rep; -+ struct incoming_message *in = &conn->in; -+ -+ /* Read data through the encryption layer. */ -+ if (!https_read_bytes(context, conn, selstate)) -+ return FALSE; -+ -+ /* Find the beginning of the response body. */ -+ rep = strstr(in->buf, "\r\n\r\n"); -+ if (rep == NULL) -+ goto kill_conn; -+ rep += 4; -+ -+ /* Decode the response. */ -+ buf = make_data((char *)rep, in->pos - (rep - in->buf)); -+ if (decode_krb5_kkdcp_message(&buf, &pm) != 0) -+ goto kill_conn; -+ -+ /* Check and discard the message length at the front of the kerb_message -+ * field after decoding. If it's wrong or missing, something broke. */ -+ if (pm->kerb_message.length < 4 || -+ load_32_be(pm->kerb_message.data) != pm->kerb_message.length - 4) { -+ goto kill_conn; -+ } -+ -+ /* Replace all of the content that we read back with just the message. */ -+ memcpy(in->buf, pm->kerb_message.data + 4, pm->kerb_message.length - 4); -+ in->pos = pm->kerb_message.length - 4; -+ k5_free_kkdcp_message(context, pm); -+ -+ return TRUE; -+ -+kill_conn: -+ TRACE_SENDTO_KDC_HTTPS_ERROR(context, in->buf); -+ k5_free_kkdcp_message(context, pm); -+ kill_conn(context, conn, selstate); -+ return FALSE; -+} -+#else -+static krb5_boolean -+service_https_write(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) -+{ -+ abort(); -+} -+static krb5_boolean -+service_https_read(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) -+{ -+ abort(); -+} -+#endif -+ - /* Return the maximum of endtime and the endtime fields of all currently active - * TCP connections. */ - static time_ms -@@ -1123,7 +1491,7 @@ k5_sendto(krb5_context context, const krb5_data *message, - for (s = 0; s < servers->nservers && !done; s++) { - /* Find the current tail pointer. */ - for (tailptr = &conns; *tailptr != NULL; tailptr = &(*tailptr)->next); -- retval = resolve_server(context, servers, s, strategy, message, -+ retval = resolve_server(context, realm, servers, s, strategy, message, - &udpbuf, &conns); - if (retval) - goto cleanup; -@@ -1132,7 +1500,8 @@ k5_sendto(krb5_context context, const krb5_data *message, - * non-preferred RFC 4120 transport. */ - if (state->defer) - continue; -- if (maybe_send(context, state, message, sel_state, callback_info)) -+ if (maybe_send(context, state, message, sel_state, realm, -+ callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, - realm, msg_handler, msg_handler_data, &winner); -@@ -1144,7 +1513,8 @@ k5_sendto(krb5_context context, const krb5_data *message, - for (state = conns; state != NULL && !done; state = state->next) { - if (!state->defer) - continue; -- if (maybe_send(context, state, message, sel_state, callback_info)) -+ if (maybe_send(context, state, message, sel_state, realm, -+ callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, - realm, msg_handler, msg_handler_data, &winner); -@@ -1160,7 +1530,8 @@ k5_sendto(krb5_context context, const krb5_data *message, - delay = 4000; - for (pass = 1; pass < MAX_PASS && !done; pass++) { - for (state = conns; state != NULL && !done; state = state->next) { -- if (maybe_send(context, state, message, sel_state, callback_info)) -+ if (maybe_send(context, state, message, sel_state, realm, -+ callback_info)) - continue; - done = service_fds(context, sel_state, 1000, conns, seltemp, - realm, msg_handler, msg_handler_data, &winner); -@@ -1194,8 +1565,12 @@ k5_sendto(krb5_context context, const krb5_data *message, - cleanup: - for (state = conns; state != NULL; state = next) { - next = state->next; -- if (state->fd != INVALID_SOCKET) -+ if (state->fd != INVALID_SOCKET) { -+ if (socktype_for_transport(state->addr.transport) == SOCK_STREAM) -+ TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &state->addr); - closesocket(state->fd); -+ free_http_ssl_data(state); -+ } - if (state->state == READING && state->in.buf != udpbuf) - free(state->in.buf); - if (callback_info) { -diff --git a/src/lib/krb5/os/t_locate_kdc.c b/src/lib/krb5/os/t_locate_kdc.c -index 300aa71..dd609fd 100644 ---- a/src/lib/krb5/os/t_locate_kdc.c -+++ b/src/lib/krb5/os/t_locate_kdc.c -@@ -39,6 +39,8 @@ ttypename (k5_transport ttype) - return "tcp"; - case UDP: - return "udp"; -+ case HTTPS: -+ return "https"; - default: - snprintf(buf, sizeof(buf), "?%d", ttype); - return buf; -diff --git a/src/lib/krb5/os/trace.c b/src/lib/krb5/os/trace.c -index 8319a86..105a2cd 100644 ---- a/src/lib/krb5/os/trace.c -+++ b/src/lib/krb5/os/trace.c -@@ -201,6 +201,8 @@ trace_format(krb5_context context, const char *fmt, va_list ap) - k5_buf_add(&buf, "dgram"); - else if (ra->transport == TCP) - k5_buf_add(&buf, "stream"); -+ else if (ra->transport == HTTPS) -+ k5_buf_add(&buf, "https"); - else - k5_buf_add_fmt(&buf, "transport%d", ra->transport); - --- -2.1.0 - diff --git a/SOURCES/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch b/SOURCES/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch deleted file mode 100644 index c0b8778..0000000 --- a/SOURCES/0007-Make-krb5_cc_new_unique-create-DIR-directories.patch +++ /dev/null @@ -1,37 +0,0 @@ -Context tweaked to apply to 1.12.1. - -From bca1191210eb582fe09e94486e2631d72b8a5ca5 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Fri, 8 Aug 2014 16:58:03 -0400 -Subject: [PATCH 7/7] Make krb5_cc_new_unique create DIR: directories - -When we use krb5_cc_new_unique to create a new cache in a directory -cache collection, we will fail if the directory doesn't exist yet. - -Go ahead and preemptively create it, as we do during krb5_cc_resolve, -before attempting to create a new file under it. - -ticket: 7988 (new) -target_version: 1.13 -tags: pullup ---- - src/lib/krb5/ccache/cc_dir.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/lib/krb5/ccache/cc_dir.c b/src/lib/krb5/ccache/cc_dir.c -index d82f335..b00a6bb 100644 ---- a/src/lib/krb5/ccache/cc_dir.c -+++ b/src/lib/krb5/ccache/cc_dir.c -@@ -401,6 +401,9 @@ dcc_gen_new(krb5_context context, krb5_ccache *cache_out) - "collection")); - return KRB5_DCC_CANNOT_CREATE; - } -+ ret = verify_dir(context, dirname); -+ if (ret) -+ goto cleanup; - ret = k5_path_join(dirname, "tktXXXXXX", &template); - if (ret) - goto cleanup; --- -2.0.4 - diff --git a/SOURCES/0008-Load-custom-anchors-when-using-KKDCP.patch b/SOURCES/0008-Load-custom-anchors-when-using-KKDCP.patch deleted file mode 100644 index 19fe964..0000000 --- a/SOURCES/0008-Load-custom-anchors-when-using-KKDCP.patch +++ /dev/null @@ -1,312 +0,0 @@ -From f220067c2969aab107bd1300ad1cb8d4855389a7 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Thu, 17 Apr 2014 17:17:13 -0400 -Subject: [PATCH 08/13] Load custom anchors when using KKDCP - -Add an http_anchors per-realm setting which we'll apply when using an -HTTPS proxy, more or less mimicking the syntax of its similarly-named -PKINIT counterpart. We only check the [realms] section, though. - -ticket: 7929 ---- - doc/admin/conf_files/krb5_conf.rst | 26 ++++++ - src/include/k5-int.h | 1 + - src/include/k5-trace.h | 7 ++ - src/lib/krb5/os/sendto_kdc.c | 169 ++++++++++++++++++++++++++++++++++++- - 4 files changed, 201 insertions(+), 2 deletions(-) - -diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst -index 19ea9c9..c069327 100644 ---- a/doc/admin/conf_files/krb5_conf.rst -+++ b/doc/admin/conf_files/krb5_conf.rst -@@ -428,6 +428,32 @@ following tags may be specified in the realm's subsection: - (for example, when converting ``rcmd.hostname`` to - ``host/hostname.domain``). - -+**http_anchors** -+ When KDCs and kpasswd servers are accessed through HTTPS proxies, this tag -+ can be used to specify the location of the CA certificate which should be -+ trusted to issue the certificate for a proxy server. If left unspecified, -+ the system-wide default set of CA certificates is used. -+ -+ The syntax for values is similar to that of values for the -+ **pkinit_anchors** tag: -+ -+ **FILE:** *filename* -+ -+ *filename* is assumed to be the name of an OpenSSL-style ca-bundle file. -+ -+ **DIR:** *dirname* -+ -+ *dirname* is assumed to be an directory which contains CA certificates. -+ All files in the directory will be examined; if they contain certificates -+ (in PEM format), they will be used. -+ -+ **ENV:** *envvar* -+ -+ *envvar* specifies the name of an environment variable which has been set -+ to a value conforming to one of the previous values. For example, -+ ``ENV:X509_PROXY_CA``, where environment variable ``X509_PROXY_CA`` has -+ been set to ``FILE:/tmp/my_proxy.pem``. -+ - **kdc** - The name or address of a host running a KDC for that realm. An - optional port number, separated from the hostname by a colon, may -diff --git a/src/include/k5-int.h b/src/include/k5-int.h -index 8f039ee..187d16d 100644 ---- a/src/include/k5-int.h -+++ b/src/include/k5-int.h -@@ -212,6 +212,7 @@ typedef unsigned char u_char; - #define KRB5_CONF_EXTRA_ADDRESSES "extra_addresses" - #define KRB5_CONF_FORWARDABLE "forwardable" - #define KRB5_CONF_HOST_BASED_SERVICES "host_based_services" -+#define KRB5_CONF_HTTP_ANCHORS "http_anchors" - #define KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME "ignore_acceptor_hostname" - #define KRB5_CONF_IPROP_ENABLE "iprop_enable" - #define KRB5_CONF_IPROP_MASTER_ULOGSIZE "iprop_master_ulogsize" -diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h -index f0d79f1..046bc95 100644 ---- a/src/include/k5-trace.h -+++ b/src/include/k5-trace.h -@@ -324,6 +324,13 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); - TRACE(c, "Resolving hostname {str}", hostname) - #define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr) \ - TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr) -+#define TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(c) \ -+ TRACE(c, "HTTPS server certificate not received") -+#define TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(c, depth, \ -+ namelen, name, \ -+ err, errs) \ -+ TRACE(c, "HTTPS certificate error at {int} ({lenstr}): " \ -+ "{int} ({str})", depth, namelen, name, err, errs) - #define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr) \ - TRACE(c, "HTTPS error connecting to {raddr}", raddr) - #define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr, err) \ -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index a4727c4..4bd8698 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -77,6 +77,9 @@ - #ifdef PROXY_TLS_IMPL_OPENSSL - #include - #include -+#include -+#include -+#include - #endif - - #define MAX_PASS 3 -@@ -152,6 +155,11 @@ struct conn_state { - } http; - }; - -+#ifdef PROXY_TLS_IMPL_OPENSSL -+/* Extra-data identifier, used to pass context into the verify callback. */ -+static int ssl_ex_context_id = -1; -+#endif -+ - void - k5_sendto_kdc_initialize(void) - { -@@ -159,6 +167,8 @@ k5_sendto_kdc_initialize(void) - SSL_library_init(); - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); -+ -+ ssl_ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); - #endif - } - -@@ -1147,6 +1157,152 @@ flush_ssl_errors(krb5_context context) - } - } - -+static krb5_error_code -+load_http_anchor_file(X509_STORE *store, const char *path) -+{ -+ FILE *fp; -+ STACK_OF(X509_INFO) *sk = NULL; -+ X509_INFO *xi; -+ int i; -+ -+ fp = fopen(path, "r"); -+ if (fp == NULL) -+ return errno; -+ sk = PEM_X509_INFO_read(fp, NULL, NULL, NULL); -+ fclose(fp); -+ if (sk == NULL) -+ return ENOENT; -+ for (i = 0; i < sk_X509_INFO_num(sk); i++) { -+ xi = sk_X509_INFO_value(sk, i); -+ if (xi->x509 != NULL) -+ X509_STORE_add_cert(store, xi->x509); -+ } -+ sk_X509_INFO_pop_free(sk, X509_INFO_free); -+ return 0; -+} -+ -+static krb5_error_code -+load_http_anchor_dir(X509_STORE *store, const char *path) -+{ -+ DIR *d = NULL; -+ struct dirent *dentry = NULL; -+ char filename[1024]; -+ krb5_boolean found_any = FALSE; -+ -+ d = opendir(path); -+ if (d == NULL) -+ return ENOENT; -+ while ((dentry = readdir(d)) != NULL) { -+ if (dentry->d_name[0] != '.') { -+ snprintf(filename, sizeof(filename), "%s/%s", -+ path, dentry->d_name); -+ if (load_http_anchor_file(store, filename) == 0) -+ found_any = TRUE; -+ } -+ } -+ closedir(d); -+ return found_any ? 0 : ENOENT; -+} -+ -+static krb5_error_code -+load_http_anchor(SSL_CTX *ctx, const char *location) -+{ -+ X509_STORE *store; -+ const char *envloc; -+ -+ store = SSL_CTX_get_cert_store(ctx); -+ if (strncmp(location, "FILE:", 5) == 0) { -+ return load_http_anchor_file(store, location + 5); -+ } else if (strncmp(location, "DIR:", 4) == 0) { -+ return load_http_anchor_dir(store, location + 4); -+ } else if (strncmp(location, "ENV:", 4) == 0) { -+ envloc = getenv(location + 4); -+ if (envloc == NULL) -+ return ENOENT; -+ return load_http_anchor(ctx, envloc); -+ } -+ return EINVAL; -+} -+ -+static krb5_error_code -+load_http_verify_anchors(krb5_context context, const krb5_data *realm, -+ SSL_CTX *sctx) -+{ -+ const char *anchors[4]; -+ char **values = NULL, *realmz; -+ unsigned int i; -+ krb5_error_code err; -+ -+ realmz = k5memdup0(realm->data, realm->length, &err); -+ if (realmz == NULL) -+ goto cleanup; -+ -+ /* Load the configured anchors. */ -+ anchors[0] = KRB5_CONF_REALMS; -+ anchors[1] = realmz; -+ anchors[2] = KRB5_CONF_HTTP_ANCHORS; -+ anchors[3] = NULL; -+ if (profile_get_values(context->profile, anchors, &values) == 0) { -+ for (i = 0; values[i] != NULL; i++) { -+ err = load_http_anchor(sctx, values[i]); -+ if (err != 0) -+ break; -+ } -+ profile_free_list(values); -+ } else { -+ /* Use the library defaults. */ -+ if (SSL_CTX_set_default_verify_paths(sctx) != 1) -+ err = ENOENT; -+ } -+ -+cleanup: -+ free(realmz); -+ return err; -+} -+ -+static int -+ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx) -+{ -+ X509 *x; -+ SSL *ssl; -+ BIO *bio; -+ krb5_context context; -+ int err, depth; -+ const char *cert = NULL, *errstr; -+ size_t count; -+ -+ ssl = X509_STORE_CTX_get_ex_data(store_ctx, -+ SSL_get_ex_data_X509_STORE_CTX_idx()); -+ context = SSL_get_ex_data(ssl, ssl_ex_context_id); -+ /* We do have the peer's cert, right? */ -+ x = X509_STORE_CTX_get_current_cert(store_ctx); -+ if (x == NULL) { -+ TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(context); -+ return 0; -+ } -+ /* Figure out where we are. */ -+ depth = X509_STORE_CTX_get_error_depth(store_ctx); -+ if (depth < 0) -+ return 0; -+ /* If there's an error at this level that we're not ignoring, fail. */ -+ err = X509_STORE_CTX_get_error(store_ctx); -+ if (err != X509_V_OK) { -+ bio = BIO_new(BIO_s_mem()); -+ if (bio != NULL) { -+ X509_NAME_print_ex(bio, x->cert_info->subject, 0, 0); -+ count = BIO_get_mem_data(bio, &cert); -+ errstr = X509_verify_cert_error_string(err); -+ TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(context, depth, -+ count, cert, err, -+ errstr); -+ BIO_free(bio); -+ } -+ return 0; -+ } -+ /* All done. */ -+ return 1; -+} -+ - /* - * Set up structures that we use to manage the SSL handling for this connection - * and apply any non-default settings. Kill the connection and return false if -@@ -1156,10 +1312,14 @@ static krb5_boolean - setup_ssl(krb5_context context, const krb5_data *realm, - struct conn_state *conn, struct select_state *selstate) - { -+ int e; - long options; - SSL_CTX *ctx = NULL; - SSL *ssl = NULL; - -+ if (ssl_ex_context_id == -1) -+ goto kill_conn; -+ - /* Do general SSL library setup. */ - ctx = SSL_CTX_new(SSLv23_client_method()); - if (ctx == NULL) -@@ -1167,14 +1327,19 @@ setup_ssl(krb5_context context, const krb5_data *realm, - options = SSL_CTX_get_options(ctx); - SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2); - -- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); -- if (!SSL_CTX_set_default_verify_paths(ctx)) -+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ssl_verify_callback); -+ X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0); -+ e = load_http_verify_anchors(context, realm, ctx); -+ if (e != 0) - goto kill_conn; - - ssl = SSL_new(ctx); - if (ssl == NULL) - goto kill_conn; - -+ if (!SSL_set_ex_data(ssl, ssl_ex_context_id, context)) -+ goto kill_conn; -+ - /* Tell the SSL library about the socket. */ - if (!SSL_set_fd(ssl, conn->fd)) - goto kill_conn; --- -2.1.0 - diff --git a/SOURCES/0009-Check-names-in-the-server-s-cert-when-using-KKDCP.patch b/SOURCES/0009-Check-names-in-the-server-s-cert-when-using-KKDCP.patch deleted file mode 100644 index 14e3354..0000000 --- a/SOURCES/0009-Check-names-in-the-server-s-cert-when-using-KKDCP.patch +++ /dev/null @@ -1,562 +0,0 @@ -From f7825e81b1ebf533c1dba9f84ae9ad36073a89cf Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Thu, 17 Apr 2014 17:19:03 -0400 -Subject: [PATCH 09/13] Check names in the server's cert when using KKDCP - -When we connect to a KDC using an HTTPS proxy, check that the naming -information in the certificate matches the name or address which we -extracted from the server URL in the configuration. - -ticket: 7929 ---- - src/include/k5-trace.h | 5 + - src/lib/krb5/os/Makefile.in | 3 + - src/lib/krb5/os/checkhost.c | 251 +++++++++++++++++++++++++++++++++++++++++++ - src/lib/krb5/os/checkhost.h | 39 +++++++ - src/lib/krb5/os/deps | 14 ++- - src/lib/krb5/os/sendto_kdc.c | 53 +++++++-- - 6 files changed, 355 insertions(+), 10 deletions(-) - create mode 100644 src/lib/krb5/os/checkhost.c - create mode 100644 src/lib/krb5/os/checkhost.h - -diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h -index 046bc95..9e75b29 100644 ---- a/src/include/k5-trace.h -+++ b/src/include/k5-trace.h -@@ -324,6 +324,11 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); - TRACE(c, "Resolving hostname {str}", hostname) - #define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr) \ - TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr) -+#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(c, hostname) \ -+ TRACE(c, "HTTPS certificate name mismatch: server certificate is " \ -+ "not for \"{str}\"", hostname) -+#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(c, hostname) \ -+ TRACE(c, "HTTPS certificate name matched \"{str}\"", hostname) - #define TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(c) \ - TRACE(c, "HTTPS server certificate not received") - #define TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(c, depth, \ -diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in -index fb4001a..fa8a093 100644 ---- a/src/lib/krb5/os/Makefile.in -+++ b/src/lib/krb5/os/Makefile.in -@@ -13,6 +13,7 @@ STLIBOBJS= \ - c_ustime.o \ - ccdefname.o \ - changepw.o \ -+ checkhost.o \ - dnsglue.o \ - dnssrv.o \ - expand_path.o \ -@@ -59,6 +60,7 @@ OBJS= \ - $(OUTPRE)c_ustime.$(OBJEXT) \ - $(OUTPRE)ccdefname.$(OBJEXT) \ - $(OUTPRE)changepw.$(OBJEXT) \ -+ $(OUTPRE)checkhost.$(OBJEXT) \ - $(OUTPRE)dnsglue.$(OBJEXT) \ - $(OUTPRE)dnssrv.$(OBJEXT) \ - $(OUTPRE)expand_path.$(OBJEXT) \ -@@ -105,6 +107,7 @@ SRCS= \ - $(srcdir)/c_ustime.c \ - $(srcdir)/ccdefname.c \ - $(srcdir)/changepw.c \ -+ $(srcdir)/checkhost.c \ - $(srcdir)/dnsglue.c \ - $(srcdir)/dnssrv.c \ - $(srcdir)/expand_path.c \ -diff --git a/src/lib/krb5/os/checkhost.c b/src/lib/krb5/os/checkhost.c -new file mode 100644 -index 0000000..a91615d ---- /dev/null -+++ b/src/lib/krb5/os/checkhost.c -@@ -0,0 +1,251 @@ -+/* -+ * Copyright 2014 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: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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. -+ */ -+ -+#include "k5-int.h" -+#include "k5-utf8.h" -+ -+#ifdef PROXY_TLS_IMPL_OPENSSL -+#include -+#include -+#include -+#include "checkhost.h" -+ -+/* Return the passed-in character, lower-cased if it's an ASCII character. */ -+static inline char -+ascii_tolower(char p) -+{ -+ if (KRB5_UPPER(p)) -+ return p + ('a' - 'A'); -+ return p; -+} -+ -+/* -+ * Check a single label. If allow_wildcard is true, and the presented name -+ * includes a wildcard, return true and note that we matched a wildcard. -+ * Otherwise, for both the presented and expected values, do a case-insensitive -+ * comparison of ASCII characters, and a case-sensitive comparison of -+ * everything else. -+ */ -+static krb5_boolean -+label_match(const char *presented, size_t plen, const char *expected, -+ size_t elen, krb5_boolean allow_wildcard, krb5_boolean *wildcard) -+{ -+ unsigned int i; -+ -+ if (allow_wildcard && plen == 1 && presented[0] == '*') { -+ *wildcard = TRUE; -+ return TRUE; -+ } -+ -+ if (plen != elen) -+ return FALSE; -+ -+ for (i = 0; i < elen; i++) { -+ if (ascii_tolower(presented[i]) != ascii_tolower(expected[i])) -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+/* Break up the two names and check them, label by label. */ -+static krb5_boolean -+domain_match(const char *presented, size_t plen, const char *expected) -+{ -+ const char *p, *q, *r, *s; -+ int n_label; -+ krb5_boolean used_wildcard = FALSE; -+ -+ n_label = 0; -+ p = presented; -+ r = expected; -+ while (p < presented + plen && *r != '\0') { -+ q = memchr(p, '.', plen - (p - presented)); -+ if (q == NULL) -+ q = presented + plen; -+ s = r + strcspn(r, "."); -+ if (!label_match(p, q - p, r, s - r, n_label == 0, &used_wildcard)) -+ return FALSE; -+ p = q < presented + plen ? q + 1 : q; -+ r = *s ? s + 1 : s; -+ n_label++; -+ } -+ if (used_wildcard && n_label <= 2) -+ return FALSE; -+ if (p == presented + plen && *r == '\0') -+ return TRUE; -+ return FALSE; -+} -+ -+/* Fetch the list of subjectAltNames from a certificate. */ -+static GENERAL_NAMES * -+get_cert_sans(X509 *x) -+{ -+ int ext; -+ X509_EXTENSION *san_ext; -+ -+ ext = X509_get_ext_by_NID(x, NID_subject_alt_name, -1); -+ if (ext < 0) -+ return NULL; -+ san_ext = X509_get_ext(x, ext); -+ if (san_ext == NULL) -+ return NULL; -+ return X509V3_EXT_d2i(san_ext); -+} -+ -+/* Fetch a CN value from the subjct name field, returning its length, or -1 if -+ * there is no subject name or it contains no CN value. */ -+static ssize_t -+get_cert_cn(X509 *x, char *buf, size_t bufsize) -+{ -+ X509_NAME *name; -+ -+ name = X509_get_subject_name(x); -+ if (name == NULL) -+ return -1; -+ return X509_NAME_get_text_by_NID(name, NID_commonName, buf, bufsize); -+} -+ -+/* -+ * Return true if the passed-in expected IP address matches any of the names we -+ * can recover from the server certificate, false otherwise. -+ */ -+krb5_boolean -+k5_check_cert_address(X509 *x, const char *text) -+{ -+ char buf[1024]; -+ GENERAL_NAMES *sans; -+ GENERAL_NAME *san = NULL; -+ ASN1_OCTET_STRING *ip; -+ krb5_boolean found_ip_san = FALSE, matched = FALSE; -+ int n_sans, i; -+ size_t name_length; -+ union { -+ struct in_addr in; -+ struct in6_addr in6; -+ } name; -+ -+ /* Parse the IP address into an octet string. */ -+ ip = M_ASN1_OCTET_STRING_new(); -+ if (ip == NULL) -+ return FALSE; -+ -+ if (inet_aton(text, &name.in) == 1) -+ name_length = sizeof(name.in); -+ else if (inet_pton(AF_INET6, text, &name.in6) == 1) -+ name_length = sizeof(name.in6); -+ else -+ name_length = 0; -+ -+ if (name_length == 0) { -+ ASN1_OCTET_STRING_free(ip); -+ return FALSE; -+ } -+ M_ASN1_OCTET_STRING_set(ip, &name, name_length); -+ -+ /* Check for matches in ipaddress subjectAltName values. */ -+ sans = get_cert_sans(x); -+ if (sans != NULL) { -+ n_sans = sk_GENERAL_NAME_num(sans); -+ for (i = 0; i < n_sans; i++) { -+ san = sk_GENERAL_NAME_value(sans, i); -+ if (san->type != GEN_IPADD) -+ continue; -+ found_ip_san = TRUE; -+ matched = ASN1_OCTET_STRING_cmp(ip, san->d.iPAddress) == 0; -+ if (matched) -+ break; -+ } -+ sk_GENERAL_NAME_pop_free(sans, GENERAL_NAME_free); -+ } -+ ASN1_OCTET_STRING_free(ip); -+ -+ if (matched) -+ return TRUE; -+ if (found_ip_san) -+ return matched; -+ -+ /* Check for a match against the CN value in the peer's subject name. */ -+ name_length = get_cert_cn(x, buf, sizeof(buf)); -+ if (name_length >= 0) { -+ /* Do a string compare to check if it's an acceptable value. */ -+ return strlen(text) == name_length && -+ strncmp(text, buf, name_length) == 0; -+ } -+ -+ /* We didn't find a match. */ -+ return FALSE; -+} -+ -+/* -+ * Return true if the passed-in expected name matches any of the names we can -+ * recover from a server certificate, false otherwise. -+ */ -+krb5_boolean -+k5_check_cert_servername(X509 *x, const char *expected) -+{ -+ char buf[1024]; -+ GENERAL_NAMES *sans; -+ GENERAL_NAME *san = NULL; -+ unsigned char *dnsname; -+ krb5_boolean found_dns_san = FALSE, matched = FALSE; -+ int name_length, n_sans, i; -+ -+ /* Check for matches in dnsname subjectAltName values. */ -+ sans = get_cert_sans(x); -+ if (sans != NULL) { -+ n_sans = sk_GENERAL_NAME_num(sans); -+ for (i = 0; i < n_sans; i++) { -+ san = sk_GENERAL_NAME_value(sans, i); -+ if (san->type != GEN_DNS) -+ continue; -+ found_dns_san = TRUE; -+ dnsname = NULL; -+ name_length = ASN1_STRING_to_UTF8(&dnsname, san->d.dNSName); -+ if (dnsname == NULL) -+ continue; -+ matched = domain_match((char *)dnsname, name_length, expected); -+ OPENSSL_free(dnsname); -+ if (matched) -+ break; -+ } -+ sk_GENERAL_NAME_pop_free(sans, GENERAL_NAME_free); -+ } -+ -+ if (matched) -+ return TRUE; -+ if (found_dns_san) -+ return matched; -+ -+ /* Check for a match against the CN value in the peer's subject name. */ -+ name_length = get_cert_cn(x, buf, sizeof(buf)); -+ if (name_length >= 0) -+ return domain_match(buf, name_length, expected); -+ -+ /* We didn't find a match. */ -+ return FALSE; -+} -+#endif -diff --git a/src/lib/krb5/os/checkhost.h b/src/lib/krb5/os/checkhost.h -new file mode 100644 -index 0000000..b9d751e ---- /dev/null -+++ b/src/lib/krb5/os/checkhost.h -@@ -0,0 +1,39 @@ -+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -+/* -+ * Copyright 2014 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: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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. -+ */ -+ -+/* -+ * Certificate subjectAltName check prototypes. -+ */ -+ -+#ifndef KRB5_LIBOS_CHECKHOST_PROTO__ -+#define KRB5_LIBOS_CHECKHOST_PROTO__ -+ -+krb5_boolean k5_check_cert_servername(X509 *x, const char *expected); -+krb5_boolean k5_check_cert_address(X509 *x, const char *expected); -+ -+#endif /* KRB5_LIBOS_CHECKHOST_PROTO__ */ -diff --git a/src/lib/krb5/os/deps b/src/lib/krb5/os/deps -index 3dd6d46..d56ff30 100644 ---- a/src/lib/krb5/os/deps -+++ b/src/lib/krb5/os/deps -@@ -49,6 +49,17 @@ changepw.so changepw.po $(OUTPRE)changepw.$(OBJEXT): \ - $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ - $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - changepw.c os-proto.h -+checkhost.so checkhost.po $(OUTPRE)checkhost.$(OBJEXT): \ -+ $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ -+ $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ -+ $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ -+ $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ -+ $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ -+ $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ -+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \ -+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ -+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ -+ $(top_srcdir)/include/socket-utils.h checkhost.c checkhost.h - dnsglue.so dnsglue.po $(OUTPRE)dnsglue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ -@@ -418,7 +429,8 @@ sendto_kdc.so sendto_kdc.po $(OUTPRE)sendto_kdc.$(OBJEXT): \ - $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ - $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ - $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ -- $(top_srcdir)/include/socket-utils.h os-proto.h sendto_kdc.c -+ $(top_srcdir)/include/socket-utils.h checkhost.h os-proto.h \ -+ sendto_kdc.c - sn2princ.so sn2princ.po $(OUTPRE)sn2princ.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ - $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index 4bd8698..f083c0f 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -80,6 +80,7 @@ - #include - #include - #include -+#include "checkhost.h" - #endif - - #define MAX_PASS 3 -@@ -148,6 +149,7 @@ struct conn_state { - krb5_boolean defer; - struct { - const char *uri_path; -+ const char *servername; - char *https_request; - #ifdef PROXY_TLS_IMPL_OPENSSL - SSL *ssl; -@@ -158,6 +160,7 @@ struct conn_state { - #ifdef PROXY_TLS_IMPL_OPENSSL - /* Extra-data identifier, used to pass context into the verify callback. */ - static int ssl_ex_context_id = -1; -+static int ssl_ex_conn_id = -1; - #endif - - void -@@ -169,6 +172,7 @@ k5_sendto_kdc_initialize(void) - OpenSSL_add_all_algorithms(); - - ssl_ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); -+ ssl_ex_conn_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); - #endif - } - -@@ -635,7 +639,8 @@ set_transport_message(struct conn_state *state, const krb5_data *realm, - static krb5_error_code - add_connection(struct conn_state **conns, k5_transport transport, - krb5_boolean defer, struct addrinfo *ai, size_t server_index, -- const krb5_data *realm, const char *uri_path, char **udpbufp) -+ const krb5_data *realm, const char *hostname, -+ const char *uri_path, char **udpbufp) - { - struct conn_state *state, **tailptr; - -@@ -661,6 +666,7 @@ add_connection(struct conn_state **conns, k5_transport transport, - state->service_write = service_https_write; - state->service_read = service_https_read; - state->http.uri_path = uri_path; -+ state->http.servername = hostname; - } else { - state->service_connect = NULL; - state->service_write = NULL; -@@ -760,8 +766,8 @@ resolve_server(krb5_context context, const krb5_data *realm, - ai.ai_addrlen = entry->addrlen; - ai.ai_addr = (struct sockaddr *)&entry->addr; - defer = (entry->transport != transport); -- return add_connection(conns, entry->transport, defer, &ai, ind, -- realm, entry->uri_path, udpbufp); -+ return add_connection(conns, entry->transport, defer, &ai, ind, realm, -+ NULL, entry->uri_path, udpbufp); - } - - /* If the entry has a specified transport, use it. */ -@@ -787,7 +793,7 @@ resolve_server(krb5_context context, const krb5_data *realm, - retval = 0; - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { - retval = add_connection(conns, transport, FALSE, a, ind, realm, -- entry->uri_path, udpbufp); -+ entry->hostname, entry->uri_path, udpbufp); - } - - /* For TCP_OR_UDP entries, add each address again with the non-preferred -@@ -797,7 +803,7 @@ resolve_server(krb5_context context, const krb5_data *realm, - for (a = addrs; a != 0 && retval == 0; a = a->ai_next) { - a->ai_socktype = socktype_for_transport(transport); - retval = add_connection(conns, transport, TRUE, a, ind, realm, -- entry->uri_path, udpbufp); -+ entry->hostname, entry->uri_path, udpbufp); - } - } - freeaddrinfo(addrs); -@@ -1260,6 +1266,20 @@ cleanup: - return err; - } - -+static krb5_boolean -+ssl_check_name_or_ip(X509 *x, const char *expected_name) -+{ -+ struct in_addr in; -+ struct in6_addr in6; -+ -+ if (inet_aton(expected_name, &in) != 0 || -+ inet_pton(AF_INET6, expected_name, &in6) != 0) { -+ return k5_check_cert_address(x, expected_name); -+ } else { -+ return k5_check_cert_servername(x, expected_name); -+ } -+} -+ - static int - ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx) - { -@@ -1268,12 +1288,14 @@ ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx) - BIO *bio; - krb5_context context; - int err, depth; -- const char *cert = NULL, *errstr; -+ struct conn_state *conn = NULL; -+ const char *cert = NULL, *errstr, *expected_name; - size_t count; - - ssl = X509_STORE_CTX_get_ex_data(store_ctx, - SSL_get_ex_data_X509_STORE_CTX_idx()); - context = SSL_get_ex_data(ssl, ssl_ex_context_id); -+ conn = SSL_get_ex_data(ssl, ssl_ex_conn_id); - /* We do have the peer's cert, right? */ - x = X509_STORE_CTX_get_current_cert(store_ctx); - if (x == NULL) { -@@ -1299,8 +1321,19 @@ ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx) - } - return 0; - } -- /* All done. */ -- return 1; -+ /* If we're not looking at the peer, we're done and everything's ok. */ -+ if (depth != 0) -+ return 1; -+ /* Check if the name we expect to find is in the certificate. */ -+ expected_name = conn->http.servername; -+ if (ssl_check_name_or_ip(x, expected_name)) { -+ TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(context, expected_name); -+ return 1; -+ } else { -+ TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(context, expected_name); -+ } -+ /* The name didn't match. */ -+ return 0; - } - - /* -@@ -1317,7 +1350,7 @@ setup_ssl(krb5_context context, const krb5_data *realm, - SSL_CTX *ctx = NULL; - SSL *ssl = NULL; - -- if (ssl_ex_context_id == -1) -+ if (ssl_ex_context_id == -1 || ssl_ex_conn_id == -1) - goto kill_conn; - - /* Do general SSL library setup. */ -@@ -1339,6 +1372,8 @@ setup_ssl(krb5_context context, const krb5_data *realm, - - if (!SSL_set_ex_data(ssl, ssl_ex_context_id, context)) - goto kill_conn; -+ if (!SSL_set_ex_data(ssl, ssl_ex_conn_id, conn)) -+ goto kill_conn; - - /* Tell the SSL library about the socket. */ - if (!SSL_set_fd(ssl, conn->fd)) --- -2.1.0 - diff --git a/SOURCES/0010-Add-some-longer-form-docs-for-HTTPS.patch b/SOURCES/0010-Add-some-longer-form-docs-for-HTTPS.patch deleted file mode 100644 index 88f1327..0000000 --- a/SOURCES/0010-Add-some-longer-form-docs-for-HTTPS.patch +++ /dev/null @@ -1,86 +0,0 @@ -From b52acabf478e8d1aa19f7823aade81eed1553143 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Tue, 22 Apr 2014 16:31:14 -0400 -Subject: [PATCH 10/13] Add some longer-form docs for HTTPS - -Add some longer-form documentation for the new HTTPS support, walking a -prospective administrator through generating a bare minimal signing -setup, deploying a WSGI-based proxy server onto an Apache httpd server -using mod_ssl and mod_wsgi, and configuring clients to use it. - -ticket: 7929 ---- - doc/admin/https.rst | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ - doc/admin/index.rst | 1 + - 2 files changed, 49 insertions(+) - create mode 100644 doc/admin/https.rst - -diff --git a/doc/admin/https.rst b/doc/admin/https.rst -new file mode 100644 -index 0000000..b4e68b2 ---- /dev/null -+++ b/doc/admin/https.rst -@@ -0,0 +1,48 @@ -+.. _https: -+ -+HTTPS proxy configuration -+========================= -+ -+In addition to being able to use UDP or TCP to communicate directly -+with a KDC as is outlined in RFC4120, and with kpasswd services in a -+similar fashion, the client libraries can attempt to use an HTTPS -+proxy server to communicate with a KDC or kpasswd service, using the -+protocol outlined in [MS-KKDCP]. -+ -+Communicating with a KDC through an HTTPS proxy allows clients to -+contact servers when network firewalls might otherwise prevent them -+from doing so. The use of TLS also encrypts all traffic between the -+clients and the KDC, preventing observers from conducting password -+dictionary attacks or from observing the client and server principals -+being authenticated, at additional computational cost to both clients -+and servers. -+ -+An HTTPS proxy server is provided as a feature in some versions of -+Microsoft Windows Server, and a WSGI implementation named `kdcproxy` -+is available in the python package index. -+ -+ -+Configuring the clients -+----------------------- -+ -+To use an HTTPS proxy, a client host must trust the CA which issued -+that proxy's SSL certificate. If that CA's certificate is not in the -+system-wide default set of trusted certificates, configure the -+following relation in the client host's :ref:`krb5.conf(5)` file in -+the appropriate :ref:`realms` subsection:: -+ -+ http_anchors = FILE:/etc/krb5/cacert.pem -+ -+Adjust the pathname to match the path of the file which contains a -+copy of the CA's certificate. The `http_anchors` option is documented -+more fully in :ref:`krb5.conf(5)`. -+ -+Configure the client to access the KDC and kpasswd service by -+specifying their locations in its :ref:`krb5.conf(5)` file in the form -+of HTTPS URLs for the proxy server:: -+ -+ kdc = https://server.fqdn/KdcProxy -+ kpasswd_server = https://server.fqdn/KdcProxy -+ -+If the proxy and client are properly configured, client commands such -+as ``kinit``, ``kvno``, and ``kpasswd`` should all function normally. -diff --git a/doc/admin/index.rst b/doc/admin/index.rst -index 3406843..3cd57f5 100644 ---- a/doc/admin/index.rst -+++ b/doc/admin/index.rst -@@ -17,6 +17,7 @@ For administrators - otp.rst - princ_dns.rst - enctypes.rst -+ https.rst - - .. toctree:: - :maxdepth: 1 --- -2.1.0 - diff --git a/SOURCES/0011-Have-k5test.py-provide-runenv-to-python-tests.patch b/SOURCES/0011-Have-k5test.py-provide-runenv-to-python-tests.patch deleted file mode 100644 index 218e629..0000000 --- a/SOURCES/0011-Have-k5test.py-provide-runenv-to-python-tests.patch +++ /dev/null @@ -1,64 +0,0 @@ -From f78f8b1a46534db3a4547323ba952c1fa1b41fe9 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Fri, 30 May 2014 17:13:31 -0400 -Subject: [PATCH 11/13] Have k5test.py provide 'runenv' to python tests - -Expose the formerly-internal _runenv module as k5test.runenv, so that -settings we store in the top-level runenv.py will be available to them. - -ticket: 7929 ---- - src/util/k5test.py | 15 ++++++++++----- - 1 file changed, 10 insertions(+), 5 deletions(-) - -diff --git a/src/util/k5test.py b/src/util/k5test.py -index a2bfbee..8cb477d 100644 ---- a/src/util/k5test.py -+++ b/src/util/k5test.py -@@ -177,6 +177,12 @@ Scripts may use the following functions and variables: - - * args: Positional arguments left over after flags are processed. - -+* runenv: The contents of $srctop/runenv.py, containing a dictionary -+ 'env' which specifies additional variables to be added to the realm -+ environment, and a variable 'proxy_tls_impl', which indicates which -+ SSL implementation (if any) is being used by libkrb5's support for -+ contacting KDCs and kpasswd servers over HTTPS. -+ - * verbose: Whether the script is running verbosely. - - * testpass: The command-line test pass argument. The script does not -@@ -526,9 +532,9 @@ def _match_cmdnum(cmdnum, ind): - # Return an environment suitable for running programs in the build - # tree. It is safe to modify the result. - def _build_env(): -- global buildtop, _runenv -+ global buildtop, runenv - env = os.environ.copy() -- for (k, v) in _runenv.iteritems(): -+ for (k, v) in runenv.env.iteritems(): - if v.find('./') == 0: - env[k] = os.path.join(buildtop, v) - else: -@@ -544,8 +550,7 @@ def _import_runenv(): - runenv_py = os.path.join(buildtop, 'runenv.py') - if not os.path.exists(runenv_py): - fail('You must run "make runenv.py" in %s first.' % buildtop) -- module = imp.load_source('runenv', runenv_py) -- return module.env -+ return imp.load_source('runenv', runenv_py) - - - # Merge the nested dictionaries cfg1 and cfg2 into a new dictionary. -@@ -1174,7 +1179,7 @@ _cmd_index = 1 - buildtop = _find_buildtop() - srctop = _find_srctop() - plugins = os.path.join(buildtop, 'plugins') --_runenv = _import_runenv() -+runenv = _import_runenv() - hostname = _get_hostname() - null_input = open(os.devnull, 'r') - --- -2.1.0 - diff --git a/SOURCES/0012-Add-a-simple-KDC-proxy-test-server.patch b/SOURCES/0012-Add-a-simple-KDC-proxy-test-server.patch deleted file mode 100644 index 48aa032..0000000 --- a/SOURCES/0012-Add-a-simple-KDC-proxy-test-server.patch +++ /dev/null @@ -1,526 +0,0 @@ -From 142255ba9af4ce1016a8eadf147e599ee490f1f7 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Fri, 7 Feb 2014 18:03:29 -0500 -Subject: [PATCH 12/13] Add a simple KDC proxy test server - -This proxy server uses python-paste to run the kdcproxy from -https://pypi.python.org/pypi/kdcproxy. It should be used along -with the proxy.pem certificate in ../tests/dejagnu/proxy-certs. - -ticket: 7929 ---- - src/tests/dejagnu/proxy-certs/ca.pem | 28 +++++ - src/tests/dejagnu/proxy-certs/make-certs.sh | 124 +++++++++++++++++++++++ - src/tests/dejagnu/proxy-certs/proxy-badsig.pem | 56 ++++++++++ - src/tests/dejagnu/proxy-certs/proxy-ideal.pem | 56 ++++++++++ - src/tests/dejagnu/proxy-certs/proxy-no-match.pem | 54 ++++++++++ - src/tests/dejagnu/proxy-certs/proxy-san.pem | 56 ++++++++++ - src/tests/dejagnu/proxy-certs/proxy-subject.pem | 54 ++++++++++ - src/util/paste-kdcproxy.py | 18 ++++ - 8 files changed, 446 insertions(+) - create mode 100644 src/tests/dejagnu/proxy-certs/ca.pem - create mode 100755 src/tests/dejagnu/proxy-certs/make-certs.sh - create mode 100644 src/tests/dejagnu/proxy-certs/proxy-badsig.pem - create mode 100644 src/tests/dejagnu/proxy-certs/proxy-ideal.pem - create mode 100644 src/tests/dejagnu/proxy-certs/proxy-no-match.pem - create mode 100644 src/tests/dejagnu/proxy-certs/proxy-san.pem - create mode 100644 src/tests/dejagnu/proxy-certs/proxy-subject.pem - create mode 100755 src/util/paste-kdcproxy.py - -diff --git a/src/tests/dejagnu/proxy-certs/ca.pem b/src/tests/dejagnu/proxy-certs/ca.pem -new file mode 100644 -index 0000000..e0f8dc7 ---- /dev/null -+++ b/src/tests/dejagnu/proxy-certs/ca.pem -@@ -0,0 +1,28 @@ -+-----BEGIN CERTIFICATE----- -+MIIEuzCCA6OgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx -+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG -+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww -+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x -+NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMIGZMQswCQYDVQQGEwJVUzEWMBQG -+A1UECBMNTWFzc2FjaHVzZXR0czESMBAGA1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQK -+EwNNSVQxIjAgBgNVBAsTGUluc2VjdXJlIEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNV -+BAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlMIIBIjANBgkq -+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6 -+zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJ -+IkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtq -+fpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1Yd -+pmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObS -+g13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABo4IB -+CjCCAQYwHQYDVR0OBBYEFHO5+DSYzq8rvQhUldyvn0y4AqlHMIHGBgNVHSMEgb4w -+gbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGfpIGcMIGZMQswCQYDVQQGEwJVUzEW -+MBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAGA1UEBxMJQ2FtYnJpZGdlMQwwCgYD -+VQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJlIEtlcmJlcm9zIHRlc3QgQ0ExLDAq -+BgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5vdCB1c2Ugb3RoZXJ3aXNlggEBMAsG -+A1UdDwQEAwIB/jAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAM -+Mf4ptC6WoQBH3GoTfgBL0WlIeYeSFmLO7IaSjpK0FV6F/yF7iPFSXcpmu23m6USY -+LRSxnAvxFTi+h1S5Za9O2Pjq88R9nHmesg4v8HJqOw4HpkDowYo2lumjIMfAutyR -+MQUOujYJW1WyZ2PidN5M1exDeMgQN9nVjUCx/WKD9fnzOjOOR1Sc8Us2KpoyccIi -+A+ABHubCvSO3cln0Sp7qjkssJScZtouzPu8FYiroTIR+1oSIKTpJiik1EptlsTea -+L6fHTMHspFhZaiUJFHWTBAgn/dT+UkFntHdHGI6HWBThFVW05hKoarBA7N25W7FN -+AHyfC0lKds4qFiBQkpdi -+-----END CERTIFICATE----- -diff --git a/src/tests/dejagnu/proxy-certs/make-certs.sh b/src/tests/dejagnu/proxy-certs/make-certs.sh -new file mode 100755 -index 0000000..1191bf0 ---- /dev/null -+++ b/src/tests/dejagnu/proxy-certs/make-certs.sh -@@ -0,0 +1,124 @@ -+#!/bin/sh -e -+ -+PWD=`pwd` -+NAMETYPE=1 -+KEYSIZE=2048 -+DAYS=4000 -+REALM=KRBTEST.COM -+TLS_SERVER_EKU=1.3.6.1.5.5.7.3.1 -+PROXY_EKU_LIST=$TLS_SERVER_EKU -+ -+cat > openssl.cnf << EOF -+[req] -+prompt = no -+distinguished_name = \$ENV::SUBJECT -+ -+[ca] -+default_ca = test_ca -+ -+[test_ca] -+new_certs_dir = $PWD -+serial = $PWD/ca.srl -+database = $PWD/ca.db -+certificate = $PWD/ca.pem -+private_key = $PWD/privkey.pem -+default_days = $DAYS -+x509_extensions = exts_proxy -+policy = proxyname -+default_md = sha1 -+unique_subject = no -+email_in_dn = no -+ -+[signer] -+CN = test CA certificate -+C = US -+ST = Massachusetts -+L = Cambridge -+O = MIT -+OU = Insecure Kerberos test CA -+CN = test suite CA; do not use otherwise -+ -+[proxy] -+C = US -+ST = Massachusetts -+O = KRBTEST.COM -+CN = PROXYinSubject -+ -+[localhost] -+C = US -+ST = Massachusetts -+O = KRBTEST.COM -+CN = localhost -+ -+[proxyname] -+C = supplied -+ST = supplied -+O = supplied -+CN = supplied -+ -+[exts_ca] -+subjectKeyIdentifier = hash -+authorityKeyIdentifier = keyid:always,issuer:always -+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign -+basicConstraints = critical,CA:TRUE -+ -+[exts_proxy] -+subjectKeyIdentifier = hash -+authorityKeyIdentifier = keyid:always,issuer:always -+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement -+basicConstraints = critical,CA:FALSE -+subjectAltName = DNS:proxyÅ ubjectÄltÑame,DNS:proxySubjectAltName,IP:127.0.0.1,IP:::1,DNS:localhost -+extendedKeyUsage = $PROXY_EKU_LIST -+ -+[exts_proxy_no_san] -+subjectKeyIdentifier = hash -+authorityKeyIdentifier = keyid:always,issuer:always -+keyUsage = nonRepudiation,digitalSignature,keyEncipherment,keyAgreement -+basicConstraints = critical,CA:FALSE -+extendedKeyUsage = $PROXY_EKU_LIST -+EOF -+ -+# Generate a private key. -+openssl genrsa $KEYSIZE -nodes > privkey.pem -+ -+# Generate a "CA" certificate. -+SUBJECT=signer openssl req -config openssl.cnf -new -x509 -extensions exts_ca \ -+ -set_serial 1 -days $DAYS -key privkey.pem -out ca.pem -+ -+# Generate proxy certificate signing requests. -+SUBJECT=proxy openssl req -config openssl.cnf -new -key privkey.pem \ -+ -out proxy.csr -+SUBJECT=localhost openssl req -config openssl.cnf -new -key privkey.pem \ -+ -out localhost.csr -+ -+# Issue the certificate with the right name in a subjectAltName. -+echo 02 > ca.srl -+cat /dev/null > ca.db -+SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy \ -+ -batch -days $DAYS -notext -out tmp.pem -in proxy.csr -+cat privkey.pem tmp.pem > proxy-san.pem -+ -+# Issue a certificate that only has the name in the subject field -+SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy_no_san \ -+ -batch -days $DAYS -notext -out tmp.pem -in localhost.csr -+cat privkey.pem tmp.pem > proxy-subject.pem -+ -+# Issue a certificate that doesn't include any matching name values. -+SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy_no_san \ -+ -batch -days $DAYS -notext -out tmp.pem -in proxy.csr -+cat privkey.pem tmp.pem > proxy-no-match.pem -+ -+# Issue a certificate that contains all matching name values. -+SUBJECT=proxy openssl ca -config openssl.cnf -extensions exts_proxy \ -+ -batch -days $DAYS -notext -out tmp.pem -in localhost.csr -+cat privkey.pem tmp.pem > proxy-ideal.pem -+ -+# Corrupt the signature on the certificate. -+SUBJECT=proxy openssl x509 -outform der -in proxy-ideal.pem -out bad.der -+length=`od -Ad bad.der | tail -n 1 | awk '{print $1}'` -+dd if=/dev/zero bs=1 of=bad.der count=16 seek=`expr $length - 16` -+SUBJECT=proxy openssl x509 -inform der -in bad.der -out tmp.pem -+cat privkey.pem tmp.pem > proxy-badsig.pem -+ -+# Clean up. -+rm -f openssl.cnf proxy.csr localhost.csr privkey.pem ca.db ca.db.old ca.srl ca.srl.old ca.db.attr ca.db.attr.old 02.pem 03.pem 04.pem 05.pem tmp.pem bad.der -diff --git a/src/tests/dejagnu/proxy-certs/proxy-badsig.pem b/src/tests/dejagnu/proxy-certs/proxy-badsig.pem -new file mode 100644 -index 0000000..2b31f7d ---- /dev/null -+++ b/src/tests/dejagnu/proxy-certs/proxy-badsig.pem -@@ -0,0 +1,56 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU -+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I -+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ -+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x -+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP -+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo -+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM -+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS -+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR -+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o -+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt -+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm -+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL -+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB -+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn -+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ -+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 -+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG -+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 -+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj -+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 -+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 -+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK -+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW -+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -+-----END RSA PRIVATE KEY----- -+-----BEGIN CERTIFICATE----- -+MIIE3TCCA8WgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx -+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG -+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww -+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x -+NDA1MDIxOTA2MDlaFw0yNTA0MTQxOTA2MDlaME8xCzAJBgNVBAYTAlVTMRYwFAYD -+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE -+AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud -+npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5 -+MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp -+mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F -+YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W -+VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr -+WVR3QLTxnnmXsqnXvwIDAQABo4IBdzCCAXMwHQYDVR0OBBYEFHO5+DSYzq8rvQhU -+ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf -+pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG -+A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl -+IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v -+dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMFkG -+A1UdEQRSMFCCFnByb3h5xaB1YmplY3TDhGx0w5FhbWWCE3Byb3h5U3ViamVjdEFs -+dE5hbWWHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDATBgNVHSUE -+DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOCAQEAfTctgFjQSaevBi64q7yh -+GNsK3PqeNEALZz4pSXRbOwm0E4RpYIS7uqg1C4zJ5Zbd4V/dOX7q+T/iBS7gErzS -+rj21jH3Ggc92TmXzcFxMDCxLV0hO8xFkqg3P4sslJESOHxvEMTTf5s893yUb8vJ/ -+DCvZXXRoRwPot9MFozkmcQcaTNunREWFvn4i4JXcMCSAfWTd+/VkpVsy69u3tj68 -+7G2/K5nalvZikutEC+DyfyBuvDAoxIYzCi3VtQxCalW28Q5hzWV21QsvKTP5QBsh -+RaU2r0O58lZPPvrOrtWQBCudUgsnoraVLrjJshEQ4z/ZAAAAAAAAAAAAAAAAAAAA -+AA== -+-----END CERTIFICATE----- -diff --git a/src/tests/dejagnu/proxy-certs/proxy-ideal.pem b/src/tests/dejagnu/proxy-certs/proxy-ideal.pem -new file mode 100644 -index 0000000..4588f7d ---- /dev/null -+++ b/src/tests/dejagnu/proxy-certs/proxy-ideal.pem -@@ -0,0 +1,56 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU -+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I -+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ -+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x -+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP -+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo -+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM -+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS -+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR -+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o -+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt -+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm -+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL -+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB -+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn -+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ -+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 -+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG -+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 -+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj -+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 -+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 -+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK -+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW -+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -+-----END RSA PRIVATE KEY----- -+-----BEGIN CERTIFICATE----- -+MIIE3TCCA8WgAwIBAgIBBTANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx -+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG -+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww -+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x -+NDA1MDIxOTA2MDlaFw0yNTA0MTQxOTA2MDlaME8xCzAJBgNVBAYTAlVTMRYwFAYD -+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE -+AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud -+npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5 -+MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp -+mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F -+YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W -+VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr -+WVR3QLTxnnmXsqnXvwIDAQABo4IBdzCCAXMwHQYDVR0OBBYEFHO5+DSYzq8rvQhU -+ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf -+pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG -+A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl -+IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v -+dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMFkG -+A1UdEQRSMFCCFnByb3h5xaB1YmplY3TDhGx0w5FhbWWCE3Byb3h5U3ViamVjdEFs -+dE5hbWWHBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAGCCWxvY2FsaG9zdDATBgNVHSUE -+DDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOCAQEAfTctgFjQSaevBi64q7yh -+GNsK3PqeNEALZz4pSXRbOwm0E4RpYIS7uqg1C4zJ5Zbd4V/dOX7q+T/iBS7gErzS -+rj21jH3Ggc92TmXzcFxMDCxLV0hO8xFkqg3P4sslJESOHxvEMTTf5s893yUb8vJ/ -+DCvZXXRoRwPot9MFozkmcQcaTNunREWFvn4i4JXcMCSAfWTd+/VkpVsy69u3tj68 -+7G2/K5nalvZikutEC+DyfyBuvDAoxIYzCi3VtQxCalW28Q5hzWV21QsvKTP5QBsh -+RaU2r0O58lZPPvrOrtWQBCudUgsnoraVLrjJshEQ4z/ZA9fVtX2ndCSIoyWpWk01 -+gQ== -+-----END CERTIFICATE----- -diff --git a/src/tests/dejagnu/proxy-certs/proxy-no-match.pem b/src/tests/dejagnu/proxy-certs/proxy-no-match.pem -new file mode 100644 -index 0000000..a97c1c7 ---- /dev/null -+++ b/src/tests/dejagnu/proxy-certs/proxy-no-match.pem -@@ -0,0 +1,54 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU -+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I -+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ -+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x -+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP -+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo -+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM -+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS -+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR -+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o -+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt -+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm -+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL -+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB -+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn -+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ -+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 -+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG -+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 -+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj -+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 -+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 -+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK -+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW -+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -+-----END RSA PRIVATE KEY----- -+-----BEGIN CERTIFICATE----- -+MIIEhzCCA2+gAwIBAgIBBDANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx -+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG -+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww -+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x -+NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMFQxCzAJBgNVBAYTAlVTMRYwFAYD -+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTEXMBUGA1UE -+AxMOUFJPWFlpblN1YmplY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -+AQDXO52ek3wU/uIufW+CTJNKf9FDFfHXK3rOKQdoytU+OSNc89SgIWlZLd54jhpA -+WiP3cvkzBkOZLE5+UECovBXYAwBpytic08kiQe1tgp1Wy/D1vgg1NapX38M44M7t -+SjDIymmY7fn+lRdosv4CMeMvDX8SFDdli2p+kAw6R/lOdLka2pkWWtiBkoTy9MLw -+HEMozsViFZjPuSn+0bdLw79FOc/s136HVh2maUcEZ+7AhEgnPnE3DoohwLLdDQ02 -+gqeHTRZXAuZH7HXUEZKQyOJlmTAnkPRE5tKDXdAP+K2sahXaC0/ONCA099OuOwy/ -+I5YAAWtZVHdAtPGeeZeyqde/AgMBAAGjggEcMIIBGDAdBgNVHQ4EFgQUc7n4NJjO -+ryu9CFSV3K+fTLgCqUcwgcYGA1UdIwSBvjCBu4AUc7n4NJjOryu9CFSV3K+fTLgC -+qUehgZ+kgZwwgZkxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRz -+MRIwEAYDVQQHEwlDYW1icmlkZ2UxDDAKBgNVBAoTA01JVDEiMCAGA1UECxMZSW5z -+ZWN1cmUgS2VyYmVyb3MgdGVzdCBDQTEsMCoGA1UEAxQjdGVzdCBzdWl0ZSBDQTsg -+ZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0PBAQDAgPoMAwGA1UdEwEB/wQC -+MAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQEFBQADggEBAMsP++r4 -+vki0mBJg3POpp0i+H6zNMimoYLLtM5NvwXinfFuFQKbwLm8QWuHVifjfCYxMUm+l -+iL5cS/bq+SUWGDmrlOhsuu4+aYaxgNiEyki5Rol6miSOHbfOhzX8yp0EBPpq08dg -+SEdrTd/FIl4qgkkb1A4RJYZRErn/fbsyjJN66KIfSOXJuC8XMBf03Vw9f2rdrHJa -+r5lVGvqa4wjO2MPq9vVK52VFrbU/zuyyCUtggyIOwGLGSY0Axtbci+IHToDBQes+ -+6W4WwSUCssWfIZXQDLjFw1oRHnN43fXmX5vsVLi7YvOFHOAa1BDnDtCTZit26xVA -+Mdic66hR2jHP0TE= -+-----END CERTIFICATE----- -diff --git a/src/tests/dejagnu/proxy-certs/proxy-san.pem b/src/tests/dejagnu/proxy-certs/proxy-san.pem -new file mode 100644 -index 0000000..ac8bbaa ---- /dev/null -+++ b/src/tests/dejagnu/proxy-certs/proxy-san.pem -@@ -0,0 +1,56 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU -+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I -+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ -+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x -+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP -+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo -+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM -+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS -+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR -+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o -+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt -+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm -+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL -+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB -+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn -+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ -+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 -+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG -+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 -+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj -+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 -+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 -+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK -+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW -+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -+-----END RSA PRIVATE KEY----- -+-----BEGIN CERTIFICATE----- -+MIIE4jCCA8qgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx -+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG -+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww -+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x -+NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaMFQxCzAJBgNVBAYTAlVTMRYwFAYD -+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTEXMBUGA1UE -+AxMOUFJPWFlpblN1YmplY3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -+AQDXO52ek3wU/uIufW+CTJNKf9FDFfHXK3rOKQdoytU+OSNc89SgIWlZLd54jhpA -+WiP3cvkzBkOZLE5+UECovBXYAwBpytic08kiQe1tgp1Wy/D1vgg1NapX38M44M7t -+SjDIymmY7fn+lRdosv4CMeMvDX8SFDdli2p+kAw6R/lOdLka2pkWWtiBkoTy9MLw -+HEMozsViFZjPuSn+0bdLw79FOc/s136HVh2maUcEZ+7AhEgnPnE3DoohwLLdDQ02 -+gqeHTRZXAuZH7HXUEZKQyOJlmTAnkPRE5tKDXdAP+K2sahXaC0/ONCA099OuOwy/ -+I5YAAWtZVHdAtPGeeZeyqde/AgMBAAGjggF3MIIBczAdBgNVHQ4EFgQUc7n4NJjO -+ryu9CFSV3K+fTLgCqUcwgcYGA1UdIwSBvjCBu4AUc7n4NJjOryu9CFSV3K+fTLgC -+qUehgZ+kgZwwgZkxCzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRz -+MRIwEAYDVQQHEwlDYW1icmlkZ2UxDDAKBgNVBAoTA01JVDEiMCAGA1UECxMZSW5z -+ZWN1cmUgS2VyYmVyb3MgdGVzdCBDQTEsMCoGA1UEAxQjdGVzdCBzdWl0ZSBDQTsg -+ZG8gbm90IHVzZSBvdGhlcndpc2WCAQEwCwYDVR0PBAQDAgPoMAwGA1UdEwEB/wQC -+MAAwWQYDVR0RBFIwUIIWcHJveHnFoHViamVjdMOEbHTDkWFtZYITcHJveHlTdWJq -+ZWN0QWx0TmFtZYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAAYIJbG9jYWxob3N0MBMG -+A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQAH6AWuyRLzMbKq -+MUlyg9ZIar8p0Ms0/UEaa6Xm3/cfm6HSujtgcYlDN3M86Z3zWzWdTrOHsRr/YSG3 -+H3YDhJToKqxcjgho+1xdBPm0xuFsJcypRqGj/mIaJSoa+wC2AdY1EdE+URsh87XC -+SHYNbxAVo8qBHMjtROm6AKb2YusYqHnkT+U6nc4Pn9UnIzmu4wfoSB+X1vtY24TP -+AtXNYQEG4BkgSrcsgoL+z/+wtZLU8QFk6JRO7Bedq711Oh/taEasZHjRAmnqC5TB -+Ab2fnwWuoVZHqz2qydeywXUKrZlctuRVdjE++wOt9xuMPKFGo0PKDw/SymCe61Q8 -+Nc/d2mhz -+-----END CERTIFICATE----- -diff --git a/src/tests/dejagnu/proxy-certs/proxy-subject.pem b/src/tests/dejagnu/proxy-certs/proxy-subject.pem -new file mode 100644 -index 0000000..e17918f ---- /dev/null -+++ b/src/tests/dejagnu/proxy-certs/proxy-subject.pem -@@ -0,0 +1,54 @@ -+-----BEGIN RSA PRIVATE KEY----- -+MIIEpQIBAAKCAQEA1zudnpN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPU -+oCFpWS3eeI4aQFoj93L5MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4I -+NTWqV9/DOODO7UowyMppmO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZ -+FlrYgZKE8vTC8BxDKM7FYhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5x -+Nw6KIcCy3Q0NNoKnh00WVwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtP -+zjQgNPfTrjsMvyOWAAFrWVR3QLTxnnmXsqnXvwIDAQABAoIBAQCqvhpeMDXhGgoo -+Q03wmfrGwPsrMv91aIK1hYrhMPdVs1JAbRYiKh8+pcq07FYa8udRaB4UwkVh/+oM -+/nEs6niRsl/jjQ2l68TFrnNByroynvr6l9Q/EeGecF6Ygo7lY1OsFhcLQM5vjarS -+XhxvdU/6hcRmfS8tGRpUaMWqfmpiN3YgJcgt8SoYhiwAYDTMJjNyWC61lO7IqNVR -+4kntiM24sfAu1sdZynX8Gp2GrpNChapEuhilQ8RayjuStEYr2abcSIjfZFHQXN7o -+TnjL+AQUzc/ZTXDGnIe9ZzZeFz8UCueeoN6KPxfrq9UUWRL6qt7gOIMdhYR6lFxt -+6pj6kLhxAoGBAO5DTnTKDfCMY2/AsTzCJvMGSY0bT1rsdDxrpqjrbUSeMHV3s5Lm -+vEPnnm+05FD/vi99+HZjHXAZFkhA3ubij2qWFPBnQ5YUoh17IW/Ae4bzY2uXikgL -+tLZ+R+OrcGYQQlvPn//PLsxbfdk5vraqzm08kIX0T4o4Iz8ST5NFJ8hVAoGBAOdB -+ahXr14563Cjeu0pSQ1nXoz3IXdnDwePXasYhxQHl8Ayk8qZS5pt7r07H3dqq6pvn -+e09gZINJe47B9UhkR3H5bPyz/kujKS4zqo3Zlbryzm3V0BWqjNj+j8E2YuQKNQr+ -+c480jn2FzwW66w0i3n4U4KUn1w2/iq5AnVzyNkPDAoGAWLYEsyU79XE/4K79DqM3 -+P0r6/afKbw8U5B4syj4FzAOeBU6RNMPmGt5VNkBCtgnSdPpRFTsoDcG5cyN8GrkG -+Lug8WZoJJwr9pT5gH6yqEX/zZ27f1J1PJpd0CsedLNMm8eonJ2arhPkXrVZ7tKV6 -+AGAJa2agatUmAmi96hZYjpUCgYEA32abJEgsedEIhFb/GYI03ELryRCaUXfCA+gj -+lvoihn3qE1z5qGGns4adyX5dPRQmBqxtvDXDg+zl9vg6i0+MkXdCqTD8tXcOnjp9 -+RgFvmyVa9FI8beHPpQTuPNncWK3fpho/6pT8Hhi48LEsxwjrZWOnzQSaxQZH46Q6 -+IQNAFt8CgYEAkflxXvA2/2naix+riaBzv5EVJB7ilbfWiWtq2LEAtwrQ5XNFjrtK -+g45jKrZ/ezAzTfPa5Dwn4xcImd0MIavnJhDu2ATxMGB0GATLlDH2HZvU7UwKLpTW -+6Hlol4yRcX4GSEOxJ2ZpWYNIOYH0yDf1qLJXs1j8Fi3zWRe+V1kff4w= -+-----END RSA PRIVATE KEY----- -+-----BEGIN CERTIFICATE----- -+MIIEgjCCA2qgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx -+FjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxEjAQBgNVBAcTCUNhbWJyaWRnZTEMMAoG -+A1UEChMDTUlUMSIwIAYDVQQLExlJbnNlY3VyZSBLZXJiZXJvcyB0ZXN0IENBMSww -+KgYDVQQDFCN0ZXN0IHN1aXRlIENBOyBkbyBub3QgdXNlIG90aGVyd2lzZTAeFw0x -+NDA1MDIxOTA2MDhaFw0yNTA0MTQxOTA2MDhaME8xCzAJBgNVBAYTAlVTMRYwFAYD -+VQQIEw1NYXNzYWNodXNldHRzMRQwEgYDVQQKEwtLUkJURVNULkNPTTESMBAGA1UE -+AxMJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1zud -+npN8FP7iLn1vgkyTSn/RQxXx1yt6zikHaMrVPjkjXPPUoCFpWS3eeI4aQFoj93L5 -+MwZDmSxOflBAqLwV2AMAacrYnNPJIkHtbYKdVsvw9b4INTWqV9/DOODO7UowyMpp -+mO35/pUXaLL+AjHjLw1/EhQ3ZYtqfpAMOkf5TnS5GtqZFlrYgZKE8vTC8BxDKM7F -+YhWYz7kp/tG3S8O/RTnP7Nd+h1YdpmlHBGfuwIRIJz5xNw6KIcCy3Q0NNoKnh00W -+VwLmR+x11BGSkMjiZZkwJ5D0RObSg13QD/itrGoV2gtPzjQgNPfTrjsMvyOWAAFr -+WVR3QLTxnnmXsqnXvwIDAQABo4IBHDCCARgwHQYDVR0OBBYEFHO5+DSYzq8rvQhU -+ldyvn0y4AqlHMIHGBgNVHSMEgb4wgbuAFHO5+DSYzq8rvQhUldyvn0y4AqlHoYGf -+pIGcMIGZMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czESMBAG -+A1UEBxMJQ2FtYnJpZGdlMQwwCgYDVQQKEwNNSVQxIjAgBgNVBAsTGUluc2VjdXJl -+IEtlcmJlcm9zIHRlc3QgQ0ExLDAqBgNVBAMUI3Rlc3Qgc3VpdGUgQ0E7IGRvIG5v -+dCB1c2Ugb3RoZXJ3aXNlggEBMAsGA1UdDwQEAwID6DAMBgNVHRMBAf8EAjAAMBMG -+A1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQCzGPT+QOrl9mbJ -+nsGlPlLUOF+PYz0a/9V/iznlofxwCXiRi2ryMpLFbjLeOvjLJ3UzyNKtmEeudTBM -+yfR4i8tb9WA7Oh0BjK1+kD4688bAUXiIDhueKBjonmPvMd9kq3MDd4vDLkcZk6R4 -+4IcbdwhzSBmnJH8ha2J82XShPpRq5CZNR9+vTyFwGdGWdPDjTMiXoXAmpRemcEgO -+iO4Gxvcrg/Z06Ys3eLze7QHNMAEwXhC4rUR34j5I2zgU7CEhff3AktLmnKVa8go8 -+4BJT/n3XGB+3gdAEihQmgCEZetHH+YxAR0Ppn3ty7fpAlOnbRJqpeu6TMN8x/lL8 -+c6JtDWRG -+-----END CERTIFICATE----- -diff --git a/src/util/paste-kdcproxy.py b/src/util/paste-kdcproxy.py -new file mode 100755 -index 0000000..1e56b89 ---- /dev/null -+++ b/src/util/paste-kdcproxy.py -@@ -0,0 +1,18 @@ -+#!/usr/bin/python -+import kdcproxy -+from paste import httpserver -+import os -+import sys -+ -+if len(sys.argv) > 1: -+ port = sys.argv[1] -+else: -+ port = 8443 -+if len(sys.argv) > 2: -+ pem = sys.argv[2] -+else: -+ pem = '*' -+server = httpserver.serve(kdcproxy.Application(), port=port, ssl_pem=pem, -+ start_loop=False) -+os.write(sys.stdout.fileno(), 'proxy server ready\n') -+server.serve_forever() --- -2.1.0 - diff --git a/SOURCES/0013-Add-tests-for-MS-KKDCP-client-support.patch b/SOURCES/0013-Add-tests-for-MS-KKDCP-client-support.patch deleted file mode 100644 index fdb6eca..0000000 --- a/SOURCES/0013-Add-tests-for-MS-KKDCP-client-support.patch +++ /dev/null @@ -1,259 +0,0 @@ -Tweaked context for src/tests/Makefile.in because t_salt.py hadn't yet been -added as a test in 1.12, and the rdreq and s2p helpers weren't there yet. - -From 3e2c7cc557048faac3400ae41b0228bd37a82a4c Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Fri, 7 Feb 2014 18:56:10 -0500 -Subject: [PATCH 13/13] Add tests for MS-KKDCP client support - -Exercise the MS-KKDCP client support using the test proxy server, for -AS, TGS, and kpasswd requests while also checking the certificate -verification and name checks. - -ticket: 7929 ---- - src/tests/Makefile.in | 1 + - src/tests/t_proxy.py | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 220 insertions(+) - create mode 100644 src/tests/t_proxy.py - -diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in -index 7347ed6..536f5cb 100644 ---- a/src/tests/Makefile.in -+++ b/src/tests/Makefile.in -@@ -134,6 +134,7 @@ check-pytests:: t_init_creds t_localauth - $(RUNPYTEST) $(srcdir)/jsonwalker.py -d $(srcdir)/au_dict.json \ - -i au.log - $(RUNPYTEST) $(srcdir)/t_bogus_kdc_req.py $(PYTESTFLAGS) -+ $(RUNPYTEST) $(srcdir)/t_proxy.py $(PYTESTFLAGS) - - clean:: - $(RM) gcred hist hrealm kdbtest plugorder responder -diff --git a/src/tests/t_proxy.py b/src/tests/t_proxy.py -new file mode 100644 -index 0000000..e4e3d48 ---- /dev/null -+++ b/src/tests/t_proxy.py -@@ -0,0 +1,219 @@ -+#!/usr/bin/python -+from k5test import * -+ -+# Skip this test if we're missing proxy functionality or parts of the proxy. -+if runenv.proxy_tls_impl == 'no': -+ success('Warning: not testing proxy support because feature ' + -+ 'was not enabled') -+ exit(0) -+try: -+ from paste import httpserver -+except: -+ success('Warning: not testing proxy support because python ' + -+ 'paste.httpserver module not found') -+ exit(0) -+try: -+ import kdcproxy -+except: -+ success('Warning: not testing proxy support because python ' + -+ 'kdcproxy module not found') -+ exit(0) -+ -+# Construct a krb5.conf fragment configuring the client to use a local proxy -+# server. -+proxysubjectpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', -+ 'proxy-subject.pem') -+proxysanpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', -+ 'proxy-san.pem') -+proxyidealpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', -+ 'proxy-ideal.pem') -+proxywrongpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', -+ 'proxy-no-match.pem') -+proxybadpem = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', -+ 'proxy-badsig.pem') -+proxyca = os.path.join(srctop, 'tests', 'dejagnu', 'proxy-certs', 'ca.pem') -+proxyurl = 'https://localhost:$port5/KdcProxy' -+proxyurlupcase = 'https://LocalHost:$port5/KdcProxy' -+proxyurl4 = 'https://127.0.0.1:$port5/KdcProxy' -+proxyurl6 = 'https://[::1]:$port5/KdcProxy' -+ -+unanchored_krb5_conf = {'realms': {'$realm': { -+ 'kdc': proxyurl, -+ 'kpasswd_server': proxyurl}}} -+anchored_name_krb5_conf = {'realms': {'$realm': { -+ 'kdc': proxyurl, -+ 'kpasswd_server': proxyurl, -+ 'http_anchors': 'FILE:%s' % proxyca}}} -+anchored_upcasename_krb5_conf = {'realms': {'$realm': { -+ 'kdc': proxyurlupcase, -+ 'kpasswd_server': proxyurlupcase, -+ 'http_anchors': 'FILE:%s' % proxyca}}} -+anchored_kadmin_krb5_conf = {'realms': {'$realm': { -+ 'kdc': proxyurl, -+ 'admin_server': proxyurl, -+ 'http_anchors': 'FILE:%s' % proxyca}}} -+anchored_ipv4_krb5_conf = {'realms': {'$realm': { -+ 'kdc': proxyurl4, -+ 'kpasswd_server': proxyurl4, -+ 'http_anchors': 'FILE:%s' % proxyca}}} -+kpasswd_input = (password('user') + '\n' + password('user') + '\n' + -+ password('user') + '\n') -+ -+def start_proxy(realm, keycertpem): -+ proxy_conf_path = os.path.join(realm.testdir, 'kdcproxy.conf') -+ proxy_exec_path = os.path.join(srctop, 'util', 'paste-kdcproxy.py') -+ conf = open(proxy_conf_path, 'w') -+ conf.write('[%s]\n' % realm.realm) -+ conf.write('kerberos = kerberos://localhost:%d\n' % realm.portbase) -+ conf.write('kpasswd = kpasswd://localhost:%d\n' % (realm.portbase + 2)) -+ conf.close() -+ realm.env['KDCPROXY_CONFIG'] = proxy_conf_path -+ cmd = [proxy_exec_path, str(realm.server_port()), keycertpem] -+ return realm.start_server(cmd, sentinel='proxy server ready') -+ -+# Fail: untrusted issuer and hostname doesn't match. -+output("running pass 1: issuer not trusted and hostname doesn't match\n") -+realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxywrongpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Fail: untrusted issuer, host name matches subject. -+output("running pass 2: subject matches, issuer not trusted\n") -+realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxysubjectpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Fail: untrusted issuer, host name matches subjectAltName. -+output("running pass 3: subjectAltName matches, issuer not trusted\n") -+realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxysanpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Fail: untrusted issuer, certificate signature is bad. -+output("running pass 4: subject matches, issuer not trusted\n") -+realm = K5Realm(krb5_conf=unanchored_krb5_conf, get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxybadpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Fail: trusted issuer but hostname doesn't match. -+output("running pass 5: issuer trusted but hostname doesn't match\n") -+realm = K5Realm(krb5_conf=anchored_name_krb5_conf, get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxywrongpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Succeed: trusted issuer and host name matches subject. -+output("running pass 6: issuer trusted, subject matches\n") -+realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True, -+ get_creds=False) -+proxy = start_proxy(realm, proxysubjectpem) -+realm.kinit(realm.user_princ, password=password('user')) -+realm.run([kvno, realm.host_princ]) -+realm.run([kpasswd, realm.user_princ], input=kpasswd_input) -+stop_daemon(proxy) -+realm.stop() -+ -+# Succeed: trusted issuer and host name matches subjectAltName. -+output("running pass 7: issuer trusted, subjectAltName matches\n") -+realm = K5Realm(krb5_conf=anchored_name_krb5_conf, start_kadmind=True, -+ get_creds=False) -+proxy = start_proxy(realm, proxysanpem) -+realm.kinit(realm.user_princ, password=password('user')) -+realm.run([kvno, realm.host_princ]) -+realm.run([kpasswd, realm.user_princ], input=kpasswd_input) -+stop_daemon(proxy) -+realm.stop() -+ -+# Fail: certificate signature is bad. -+output("running pass 8: issuer trusted and subjectAltName matches, sig bad\n") -+realm = K5Realm(krb5_conf=anchored_name_krb5_conf, -+ get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxybadpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Fail: trusted issuer but IP doesn't match. -+output("running pass 9: issuer trusted but no name matches IP\n") -+realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxywrongpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Fail: trusted issuer, but subject does not match. -+output("running pass 10: issuer trusted, but subject does not match IP\n") -+realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxysubjectpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Succeed: trusted issuer and host name matches subjectAltName. -+output("running pass 11: issuer trusted, subjectAltName matches IP\n") -+realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, start_kadmind=True, -+ get_creds=False) -+proxy = start_proxy(realm, proxysanpem) -+realm.kinit(realm.user_princ, password=password('user')) -+realm.run([kvno, realm.host_princ]) -+realm.run([kpasswd, realm.user_princ], input=kpasswd_input) -+stop_daemon(proxy) -+realm.stop() -+ -+# Fail: certificate signature is bad. -+output("running pass 12: issuer trusted, names don't match, signature bad\n") -+realm = K5Realm(krb5_conf=anchored_ipv4_krb5_conf, get_creds=False, -+ create_host=False) -+proxy = start_proxy(realm, proxybadpem) -+realm.kinit(realm.user_princ, password=password('user'), expected_code=1) -+stop_daemon(proxy) -+realm.stop() -+ -+# Succeed: trusted issuer and host name matches subject, using kadmin -+# configuration to find kpasswdd. -+output("running pass 13: issuer trusted, subject matches\n") -+realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True, -+ get_creds=False, create_host=False) -+proxy = start_proxy(realm, proxysubjectpem) -+realm.run([kpasswd, realm.user_princ], input=kpasswd_input) -+stop_daemon(proxy) -+realm.stop() -+ -+# Succeed: trusted issuer and host name matches subjectAltName, using -+# kadmin configuration to find kpasswdd. -+output("running pass 14: issuer trusted, subjectAltName matches\n") -+realm = K5Realm(krb5_conf=anchored_kadmin_krb5_conf, start_kadmind=True, -+ get_creds=False, create_host=False) -+proxy = start_proxy(realm, proxysanpem) -+realm.run([kpasswd, realm.user_princ], input=kpasswd_input) -+stop_daemon(proxy) -+realm.stop() -+ -+# Succeed: trusted issuer and host name matches subjectAltName (give or take -+# case). -+output("running pass 15: issuer trusted, subjectAltName case-insensitive\n") -+realm = K5Realm(krb5_conf=anchored_upcasename_krb5_conf, start_kadmind=True, -+ get_creds=False, create_host=False) -+proxy = start_proxy(realm, proxysanpem) -+realm.run([kpasswd, realm.user_princ], input=kpasswd_input) -+stop_daemon(proxy) -+realm.stop() -+ -+success('MS-KKDCP proxy') --- -2.1.0 - diff --git a/SOURCES/krb5-1.10-kprop-mktemp.patch b/SOURCES/krb5-1.10-kprop-mktemp.patch deleted file mode 100644 index 62178df..0000000 --- a/SOURCES/krb5-1.10-kprop-mktemp.patch +++ /dev/null @@ -1,28 +0,0 @@ -Use an in-memory ccache to silence a compiler warning, for RT#6414. - ---- krb5/src/slave/kprop.c -+++ krb5/src/slave/kprop.c -@@ -202,9 +202,8 @@ void PRS(argc, argv) - void get_tickets(context) - krb5_context context; - { -- char buf[BUFSIZ], *def_realm; -+ char buf[] = "MEMORY:_kproptkt", *def_realm; - krb5_error_code retval; -- static char tkstring[] = "/tmp/kproptktXXXXXX"; - krb5_keytab keytab = NULL; - - /* -@@ -229,11 +228,8 @@ void get_tickets(context) - #endif - - /* -- * Initialize cache file which we're going to be using -+ * Initialize an in-memory cache for temporary use - */ -- (void) mktemp(tkstring); -- snprintf(buf, sizeof(buf), "FILE:%s", tkstring); -- - retval = krb5_cc_resolve(context, buf, &ccache); - if (retval) { - com_err(progname, retval, _("while opening credential cache %s"), buf); diff --git a/SOURCES/krb5-1.11-dirsrv-accountlock.patch b/SOURCES/krb5-1.11-dirsrv-accountlock.patch deleted file mode 100644 index 12d201d..0000000 --- a/SOURCES/krb5-1.11-dirsrv-accountlock.patch +++ /dev/null @@ -1,61 +0,0 @@ -Treat 'nsAccountLock: true' the same as 'loginDisabled: true'. Updated from -original version filed as RT#5891. - -diff -up krb5-1.8/src/aclocal.m4.dirsrv-accountlock krb5-1.8/src/aclocal.m4 ---- krb5-1.8/src/aclocal.m4.dirsrv-accountlock 2010-03-05 11:03:09.000000000 -0500 -+++ krb5-1.8/src/aclocal.m4 2010-03-05 11:03:10.000000000 -0500 -@@ -1656,6 +1656,15 @@ if test $with_ldap = yes; then - AC_MSG_NOTICE(enabling OpenLDAP database backend module support) - OPENLDAP_PLUGIN=yes - fi -+AC_ARG_WITH([dirsrv-account-locking], -+[ --with-dirsrv-account-locking compile 389/Red Hat/Fedora/Netscape Directory Server database backend module], -+[case "$withval" in -+ yes | no) ;; -+ *) AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;; -+esac], with_dirsrv_account_locking=no) -+if test $with_dirsrv_account_locking = yes; then -+ AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.]) -+fi - ])dnl - dnl - dnl If libkeyutils exists (on Linux) include it and use keyring ccache -diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c ---- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock 2009-11-24 18:52:25.000000000 -0500 -+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c 2010-03-05 11:03:10.000000000 -0500 -@@ -2101,6 +2101,22 @@ populate_krb5_db_entry(krb5_context cont - goto cleanup; - if ((st=krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data)) != 0) - goto cleanup; -+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING -+ { -+ krb5_timestamp expiretime=0; -+ char *is_login_disabled=NULL; -+ -+ /* LOGIN DISABLED */ -+ if ((st=krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled, -+ &attr_present)) != 0) -+ goto cleanup; -+ if (attr_present == TRUE) { -+ if (strcasecmp(is_login_disabled, "TRUE")== 0) -+ entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX; -+ free (is_login_disabled); -+ } -+ } -+#endif - - if ((st=krb5_read_tkt_policy (context, ldap_context, entry, tktpolname)) !=0) - goto cleanup; -diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c ---- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock 2009-11-24 18:52:25.000000000 -0500 -+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c 2010-03-05 11:03:10.000000000 -0500 -@@ -59,6 +59,9 @@ char *principal_attributes[] = { "kr - "krbLastFailedAuth", - "krbLoginFailedCount", - "krbLastSuccessfulAuth", -+#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING -+ "nsAccountLock", -+#endif - "krbLastPwdChange", - "krbLastAdminUnlock", - "krbExtraData", diff --git a/SOURCES/krb5-1.12-kpasswd-skip-address-check.patch b/SOURCES/krb5-1.12-kpasswd-skip-address-check.patch deleted file mode 100644 index 9873b93..0000000 --- a/SOURCES/krb5-1.12-kpasswd-skip-address-check.patch +++ /dev/null @@ -1,55 +0,0 @@ -commit b562400826409deceb0d52ffbe6570670ee9db55 -Author: Nalin Dahyabhai -Date: Wed Oct 9 15:03:16 2013 -0400 - - Don't check kpasswd reply address - - Don't check the address of the kpasswd server when parsing the reply - we received from it. If the server's address was modified by a proxy - or other network element, the user will be incorrectly warned that the - password change failed when it succeeded. The check is unnecessary as - the kpasswd protocol is not subject to a reflection attack. - - [ghudson@mit.edu: edit commit message] - - ticket: 7886 (new) - -diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c -index 462910f..4d8abd9 100644 ---- a/src/lib/krb5/os/changepw.c -+++ b/src/lib/krb5/os/changepw.c -@@ -214,7 +214,6 @@ change_set_password(krb5_context context, - krb5_data *result_string) - { - krb5_data chpw_rep; -- krb5_address remote_kaddr; - krb5_boolean use_tcp = 0; - GETSOCKNAME_ARG3_TYPE addrlen; - krb5_error_code code = 0; -@@ -272,26 +271,6 @@ change_set_password(krb5_context context, - break; - } - -- if (remote_addr.ss_family == AF_INET) { -- remote_kaddr.addrtype = ADDRTYPE_INET; -- remote_kaddr.length = sizeof(ss2sin(&remote_addr)->sin_addr); -- remote_kaddr.contents = -- (krb5_octet *) &ss2sin(&remote_addr)->sin_addr; -- } else if (remote_addr.ss_family == AF_INET6) { -- remote_kaddr.addrtype = ADDRTYPE_INET6; -- remote_kaddr.length = sizeof(ss2sin6(&remote_addr)->sin6_addr); -- remote_kaddr.contents = -- (krb5_octet *) &ss2sin6(&remote_addr)->sin6_addr; -- } else { -- break; -- } -- -- if ((code = krb5_auth_con_setaddrs(callback_ctx.context, -- callback_ctx.auth_context, -- NULL, -- &remote_kaddr))) -- break; -- - code = krb5int_rd_chpw_rep(callback_ctx.context, - callback_ctx.auth_context, - &chpw_rep, &local_result_code, diff --git a/SOURCES/krb5-1.12-ksu-no-ccache.patch b/SOURCES/krb5-1.12-ksu-no-ccache.patch deleted file mode 100644 index 67346b4..0000000 --- a/SOURCES/krb5-1.12-ksu-no-ccache.patch +++ /dev/null @@ -1,36 +0,0 @@ -commit 26e202d26b47d62fbff4f153fc7f03cc300cc4ab -Author: Nalin Dahyabhai -Date: Mon Sep 8 13:34:05 2014 -0400 - - Fix ksu crash in cases where it obtains the TGT - - In order to allow ksu to use any locally-present service key for - verifying creds, the previous change to ksu switched from using a - retrieved or obtained TGT to fetch creds for the local "host" service, - and then passing those creds to krb5_verify_init_creds(), to passing the - retrieved TGT directly to krb5_verify_init_creds(). It did not take - care to retrieve the TGT from the temporary ccache if it had obtained - them, and in those cases it would attempt to verify NULL creds. - -diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c -index dd0a127..bd37c9c 100644 ---- a/src/clients/ksu/krb_auth_su.c -+++ b/src/clients/ksu/krb_auth_su.c -@@ -122,6 +122,17 @@ krb5_boolean krb5_auth_check(context, client_pname, hostname, options, - return FALSE; - } - -+ retval = krb5_cc_retrieve_cred(context, cc, -+ KRB5_TC_MATCH_SRV_NAMEONLY | -+ KRB5_TC_SUPPORTED_KTYPES, -+ &tgtq, &tgt); -+ -+ if (! retval) retval = krb5_check_exp(context, tgt.times); -+ -+ if (retval){ -+ com_err(prog_name, retval, _("while getting initial credentials")); -+ return (FALSE) ; -+ } - #else - plain_dump_principal (context, client); - fprintf(stderr, diff --git a/SOURCES/krb5-1.12-ksu-untyped-default-ccache-name.patch b/SOURCES/krb5-1.12-ksu-untyped-default-ccache-name.patch deleted file mode 100644 index 4e1f835..0000000 --- a/SOURCES/krb5-1.12-ksu-untyped-default-ccache-name.patch +++ /dev/null @@ -1,46 +0,0 @@ -commit bda574576a5a2d0613fecf12d820e0adcbedf95c -Author: Nalin Dahyabhai -Date: Mon Sep 8 13:15:40 2014 -0400 - - In ksu, handle typeless default_ccache_name values - - When a configured or compiled-in default ccache name doesn't contain a - cache type and ':' as a prefix, add one to the writeable value that we - construct when we go to look it up. This lets the rest of the - application always assume that it'll be there. - - [ghudson@mit.edu: minor style changes] - - ticket: 8007 (new) - target_version: 1.13 - tags: pullup - -diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c -index 47fa820..622c36a 100644 ---- a/src/clients/ksu/main.c -+++ b/src/clients/ksu/main.c -@@ -819,7 +819,7 @@ get_configured_defccname(krb5_context context, char **target_out) - { - krb5_error_code retval; - const char *defname; -- char *target; -+ char *target = NULL; - - *target_out = NULL; - -@@ -838,7 +838,14 @@ get_configured_defccname(krb5_context context, char **target_out) - } - - defname = krb5_cc_default_name(context); -- target = (defname == NULL) ? NULL : strdup(defname); -+ if (defname != NULL) { -+ if (strchr(defname, ':') != NULL) { -+ target = strdup(defname); -+ } else { -+ if (asprintf(&target, "FILE:%s", defname) < 0) -+ target = NULL; -+ } -+ } - if (target == NULL) { - com_err(prog_name, ENOMEM, _("while determining target ccache name")); - return ENOMEM; diff --git a/SOURCES/krb5-1.12-nodelete-plugins.patch b/SOURCES/krb5-1.12-nodelete-plugins.patch deleted file mode 100644 index 88fb8c6..0000000 --- a/SOURCES/krb5-1.12-nodelete-plugins.patch +++ /dev/null @@ -1,59 +0,0 @@ -commit 0f46175d632ae03ab7d4cfba5e62534d31e128e0 -Author: Greg Hudson -Date: Wed Jun 25 11:41:54 2014 -0400 - - Load plugins with RTLD_NODELETE if possible - - On platforms which support RTLD_NODELETE, use it to load plugin - modules. While using this flag makes plugins stay in the process map - after libkrb5/libgssapi_krb5 are unloaded, it solves several problems: - - 1. It prevents plugin modules which link against OpenSSL (PKINIT and - k5tls) from repeatedly initializing instances of libssl or libcrypto, - leaking heap memory each time. This is only an issue because we - cannot safely uninitialize OpenSSL. - - 2. It prevents finalization ordering issues from causing a process - crash when unloading libgssapi_krb5 (issue #7135). - - 3. It makes memory leak tracing with valgrind easier. - - ticket: 7947 (new) - -diff --git a/src/util/support/plugins.c b/src/util/support/plugins.c -index a04dfc3..ca4b128 100644 ---- a/src/util/support/plugins.c -+++ b/src/util/support/plugins.c -@@ -45,6 +45,20 @@ - - #include "k5-platform.h" - -+#if USE_DLOPEN -+#ifdef RTLD_GROUP -+#define GROUP RTLD_GROUP -+#else -+#define GROUP 0 -+#endif -+#ifdef RTLD_NODELETE -+#define NODELETE RTLD_NODELETE -+#else -+#define NODELETE 0 -+#endif -+#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL | GROUP | NODELETE) -+#endif -+ - #if USE_DLOPEN && USE_CFBUNDLE - #include - -@@ -257,11 +271,6 @@ krb5int_open_plugin (const char *filepath, struct plugin_file_handle **h, struct - } - #endif /* USE_CFBUNDLE */ - --#ifdef RTLD_GROUP --#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL | RTLD_GROUP) --#else --#define PLUGIN_DLOPEN_FLAGS (RTLD_NOW | RTLD_LOCAL) --#endif - if (!err) { - handle = dlopen(filepath, PLUGIN_DLOPEN_FLAGS); - if (handle == NULL) { diff --git a/SOURCES/krb5-1.12-pwdch-fast.patch b/SOURCES/krb5-1.12-pwdch-fast.patch deleted file mode 100644 index 3b7d4bb..0000000 --- a/SOURCES/krb5-1.12-pwdch-fast.patch +++ /dev/null @@ -1,176 +0,0 @@ -From 230858394d2dded001ef3d2029daa6c468aca097 Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Fri, 28 Feb 2014 14:49:35 -0500 -Subject: [PATCH] Use preauth options when changing password - -If we try to change the password in rb5_get_init_creds_password, we -must use all application-specified gic options which affect -preauthentication when getting the kadmin/changepw ticket. Create a -helper function make_chpw_options which copies the application's -options, unsets the options we don't want, and sets options -appropriate for a temporary ticket. - -ticket: 7868 - -npmccallum: - * include tests from 06817686bfdef99523f300464bcbb0c8b037a27d ---- - src/lib/krb5/krb/gic_pwd.c | 63 +++++++++++++++++++++++++++++++++++++--------- - src/tests/Makefile.in | 1 + - src/tests/t_changepw.py | 37 +++++++++++++++++++++++++++ - 3 files changed, 89 insertions(+), 12 deletions(-) - create mode 100644 src/tests/t_changepw.py - -diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c -index a97823f6b51b7393755e82f36612c30b64096754..6aec7c3a71f99d2194b09374b296327174e6d4b8 100644 ---- a/src/lib/krb5/krb/gic_pwd.c -+++ b/src/lib/krb5/krb/gic_pwd.c -@@ -242,6 +242,54 @@ warn_pw_expiry(krb5_context context, krb5_get_init_creds_opt *options, - (*prompter)(context, data, 0, banner, 0, 0); - } - -+/* -+ * Create a temporary options structure for getting a kadmin/changepw ticket, -+ * based on the appplication-specified options. Propagate all application -+ * options which affect preauthentication, but not options which affect the -+ * resulting ticket or how it is stored. Set lifetime and flags appropriate -+ * for a ticket which we will use immediately and then discard. -+ * -+ * storage1 and storage2 will be used to hold the temporary options. The -+ * caller must not free the result, as it will contain aliases into the -+ * application options. -+ */ -+static krb5_get_init_creds_opt * -+make_chpw_options(krb5_get_init_creds_opt *in, krb5_gic_opt_ext *storage1, -+ gic_opt_private *storage2) -+{ -+ krb5_gic_opt_ext *in_ext; -+ krb5_get_init_creds_opt *opt; -+ -+ /* Copy the application's options to storage. */ -+ if (in == NULL) { -+ storage1->flags = 0; -+ } else if (gic_opt_is_extended(in)) { -+ in_ext = (krb5_gic_opt_ext *)in; -+ *storage1 = *in_ext; -+ *storage2 = *in_ext->opt_private; -+ storage1->opt_private = storage2; -+ } else { -+ *(krb5_get_init_creds_opt *)storage1 = *in; -+ } -+ -+ /* Get a non-forwardable, non-proxiable, short-lifetime ticket. */ -+ opt = (krb5_get_init_creds_opt *)storage1; -+ krb5_get_init_creds_opt_set_tkt_life(opt, 5 * 60); -+ krb5_get_init_creds_opt_set_renew_life(opt, 0); -+ krb5_get_init_creds_opt_set_forwardable(opt, 0); -+ krb5_get_init_creds_opt_set_proxiable(opt, 0); -+ -+ /* Unset options which should only apply to the actual ticket. */ -+ opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST; -+ opt->flags &= ~KRB5_GET_INIT_CREDS_OPT_ANONYMOUS; -+ -+ /* The output ccache should only be used for the actual ticket. */ -+ if (gic_opt_is_extended(opt)) -+ storage2->out_ccache = NULL; -+ -+ return opt; -+} -+ - krb5_error_code KRB5_CALLCONV - krb5_get_init_creds_password(krb5_context context, - krb5_creds *creds, -@@ -259,6 +307,8 @@ krb5_get_init_creds_password(krb5_context context, - int tries; - krb5_creds chpw_creds; - krb5_get_init_creds_opt *chpw_opts = NULL; -+ krb5_gic_opt_ext storage1; -+ gic_opt_private storage2; - struct gak_password gakpw; - krb5_data pw0, pw1; - char banner[1024], pw0array[1024], pw1array[1024]; -@@ -345,16 +395,7 @@ krb5_get_init_creds_password(krb5_context context, - /* ok, we have an expired password. Give the user a few chances - to change it */ - -- /* use a minimal set of options */ -- -- ret = krb5_get_init_creds_opt_alloc(context, &chpw_opts); -- if (ret) -- goto cleanup; -- krb5_get_init_creds_opt_set_tkt_life(chpw_opts, 5*60); -- krb5_get_init_creds_opt_set_renew_life(chpw_opts, 0); -- krb5_get_init_creds_opt_set_forwardable(chpw_opts, 0); -- krb5_get_init_creds_opt_set_proxiable(chpw_opts, 0); -- -+ chpw_opts = make_chpw_options(options, &storage1, &storage2); - ret = k5_get_init_creds(context, &chpw_creds, client, prompter, data, - start_time, "kadmin/changepw", chpw_opts, - krb5_get_as_key_password, &gakpw, &use_master, -@@ -471,8 +512,6 @@ cleanup: - warn_pw_expiry(context, options, prompter, data, in_tkt_service, - as_reply); - -- if (chpw_opts) -- krb5_get_init_creds_opt_free(context, chpw_opts); - zapfree(gakpw.storage.data, gakpw.storage.length); - memset(pw0array, 0, sizeof(pw0array)); - memset(pw1array, 0, sizeof(pw1array)); -diff --git a/src/tests/Makefile.in b/src/tests/Makefile.in -index 62523895d53da24844141a6ada6cab23e77dd9e6..55f1d6419f8d924a6f9a2971d36f1eac6d293d32 100644 ---- a/src/tests/Makefile.in -+++ b/src/tests/Makefile.in -@@ -94,6 +94,7 @@ check-pytests:: t_init_creds t_localauth - $(RUNPYTEST) $(srcdir)/t_iprop.py $(PYTESTFLAGS) - $(RUNPYTEST) $(srcdir)/t_kprop.py $(PYTESTFLAGS) - $(RUNPYTEST) $(srcdir)/t_policy.py $(PYTESTFLAGS) -+ $(RUNPYTEST) $(srcdir)/t_changepw.py $(PYTESTFLAGS) - $(RUNPYTEST) $(srcdir)/t_pkinit.py $(PYTESTFLAGS) - $(RUNPYTEST) $(srcdir)/t_otp.py $(PYTESTFLAGS) - $(RUNPYTEST) $(srcdir)/t_localauth.py $(PYTESTFLAGS) -diff --git a/src/tests/t_changepw.py b/src/tests/t_changepw.py -new file mode 100644 -index 0000000000000000000000000000000000000000..0b9832668e618b3db8d88cf388ec918898bb4df3 ---- /dev/null -+++ b/src/tests/t_changepw.py -@@ -0,0 +1,37 @@ -+#!/usr/bin/python -+from k5test import * -+ -+# This file is intended to cover any password-changing mechanism. For -+# now it only contains a regression test for #7868. -+ -+realm = K5Realm(create_host=False, get_creds=False, start_kadmind=True) -+ -+# Mark a principal as expired and change its password through kinit. -+realm.run_kadminl('modprinc -pwexpire "1 day ago" user') -+pwinput = password('user') + '\nabcd\nabcd\n' -+realm.run([kinit, realm.user_princ], input=pwinput) -+ -+# Do the same thing with FAST, with tracing turned on. -+realm.run_kadminl('modprinc -pwexpire "1 day ago" user') -+pwinput = 'abcd\nefgh\nefgh\n' -+tracefile = os.path.join(realm.testdir, 'trace') -+realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-T', realm.ccache, -+ realm.user_princ], input=pwinput) -+ -+# Read the trace and check that FAST was used when getting the -+# kadmin/changepw ticket. -+f = open(tracefile, 'r') -+trace = f.read() -+f.close() -+getting_changepw = fast_used_for_changepw = False -+for line in trace.splitlines(): -+ if 'Getting initial credentials for user@' in line: -+ getting_changepw_ticket = False -+ if 'Setting initial creds service to kadmin/changepw' in line: -+ getting_changepw_ticket = True -+ if getting_changepw_ticket and 'Using FAST' in line: -+ fast_used_for_changepw = True -+if not fast_used_for_changepw: -+ fail('FAST was not used to get kadmin/changepw ticket') -+ -+success('Password change tests') --- -1.8.5.3 - diff --git a/SOURCES/krb5-1.12-selinux-label.patch b/SOURCES/krb5-1.12-selinux-label.patch deleted file mode 100644 index 395f5f7..0000000 --- a/SOURCES/krb5-1.12-selinux-label.patch +++ /dev/null @@ -1,979 +0,0 @@ -SELinux bases access to files on the domain of the requesting process, -the operation being performed, and the context applied to the file. - -In many cases, applications needn't be SELinux aware to work properly, -because SELinux can apply a default label to a file based on the label -of the directory in which it's created. - -In the case of files such as /etc/krb5.keytab, however, this isn't -sufficient, as /etc/krb5.keytab will almost always need to be given a -label which differs from that of /etc/issue or /etc/resolv.conf. The -the kdb stash file needs a different label than the database for which -it's holding a master key, even though both typically live in the same -directory. - -To give the file the correct label, we can either force a "restorecon" -call to fix a file's label after it's created, or create the file with -the right label, as we attempt to do here. We lean on THREEPARAMOPEN -and define a similar macro named WRITABLEFOPEN with which we replace -several uses of fopen(). - -The file creation context that we're manipulating here is a process-wide -attribute. While for the most part, applications which need to label -files when they're created have tended to be single-threaded, there's -not much we can do to avoid interfering with an application that -manipulates the creation context directly. Right now we're mediating -access using a library-local mutex, but that can only work for consumers -that are part of this package -- an unsuspecting application will still -stomp all over us. - -The selabel APIs for looking up the context should be thread-safe (per -Red Hat #273081), so switching to using them instead of matchpathcon(), -which we used earlier, is some improvement. - ---- krb5/src/aclocal.m4 -+++ krb5/src/aclocal.m4 -@@ -103,6 +103,7 @@ AC_SUBST_FILE(libnodeps_frag) - dnl - KRB5_AC_PRAGMA_WEAK_REF - WITH_LDAP -+KRB5_WITH_SELINUX - KRB5_LIB_PARAMS - KRB5_AC_INITFINI - KRB5_AC_ENABLE_THREADS -@@ -1791,3 +1792,51 @@ AC_SUBST(manlocalstatedir) - AC_SUBST(PAM_MAN) - AC_SUBST(NON_PAM_MAN) - ])dnl -+dnl -+dnl Use libselinux to set file contexts on newly-created files. -+dnl -+AC_DEFUN(KRB5_WITH_SELINUX,[ -+AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])], -+ withselinux="$withval",withselinux=auto) -+old_LIBS="$LIBS" -+if test "$withselinux" != no ; then -+ AC_MSG_RESULT([checking for libselinux...]) -+ SELINUX_LIBS= -+ AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h) -+ if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then -+ if test "$withselinux" = auto ; then -+ AC_MSG_RESULT([Unable to locate selinux/selinux.h.]) -+ withselinux=no -+ else -+ AC_MSG_ERROR([Unable to locate selinux/selinux.h.]) -+ fi -+ fi -+ -+ LIBS= -+ unset ac_cv_func_setfscreatecon -+ AC_CHECK_FUNCS(setfscreatecon selabel_open) -+ if test "x$ac_cv_func_setfscreatecon" = xno ; then -+ AC_CHECK_LIB(selinux,setfscreatecon) -+ unset ac_cv_func_setfscreatecon -+ AC_CHECK_FUNCS(setfscreatecon selabel_open) -+ if test "x$ac_cv_func_setfscreatecon" = xyes ; then -+ SELINUX_LIBS="$LIBS" -+ else -+ if test "$withselinux" = auto ; then -+ AC_MSG_RESULT([Unable to locate libselinux.]) -+ withselinux=no -+ else -+ AC_MSG_ERROR([Unable to locate libselinux.]) -+ fi -+ fi -+ fi -+ if test "$withselinux" != no ; then -+ AC_MSG_NOTICE([building with SELinux labeling support]) -+ AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.]) -+ SELINUX_LIBS="$LIBS" -+ EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon" -+ fi -+fi -+LIBS="$old_LIBS" -+AC_SUBST(SELINUX_LIBS) -+])dnl ---- krb5/src/config/pre.in -+++ krb5/src/config/pre.in -@@ -180,6 +180,7 @@ LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@ - KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include - LDFLAGS = @LDFLAGS@ - LIBS = @LIBS@ -+SELINUX_LIBS=@SELINUX_LIBS@ - - INSTALL=@INSTALL@ - INSTALL_STRIP= -@@ -379,7 +380,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME) - # HESIOD_LIBS is -lhesiod... - HESIOD_LIBS = @HESIOD_LIBS@ - --KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB) -+KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB) - KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS) - GSS_LIBS = $(GSS_KRB5_LIB) - # needs fixing if ever used on Mac OS X! ---- krb5/src/configure.in -+++ krb5/src/configure.in -@@ -1053,6 +1053,8 @@ fi - - KRB5_WITH_PAM - -+KRB5_WITH_SELINUX -+ - # Make localedir work in autoconf 2.5x. - if test "${localedir+set}" != set; then - localedir='$(datadir)/locale' ---- krb5/src/include/k5-int.h -+++ krb5/src/include/k5-int.h -@@ -133,6 +133,7 @@ typedef unsigned char u_char; - typedef UINT64_TYPE krb5_ui_8; - typedef INT64_TYPE krb5_int64; - -+#include "k5-label.h" - - #define KRB5_KDB_MAX_LIFE (60*60*24) /* one day */ - #define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */ ---- krb5/src/include/k5-label.h -+++ krb5/src/include/k5-label.h -@@ -0,0 +1,32 @@ -+#ifndef _KRB5_LABEL_H -+#define _KRB5_LABEL_H -+ -+#ifdef THREEPARAMOPEN -+#undef THREEPARAMOPEN -+#endif -+#ifdef WRITABLEFOPEN -+#undef WRITABLEFOPEN -+#endif -+ -+/* Wrapper functions which help us create files and directories with the right -+ * context labels. */ -+#ifdef USE_SELINUX -+#include -+#include -+#include -+#include -+#include -+FILE *krb5int_labeled_fopen(const char *path, const char *mode); -+int krb5int_labeled_creat(const char *path, mode_t mode); -+int krb5int_labeled_open(const char *path, int flags, ...); -+int krb5int_labeled_mkdir(const char *path, mode_t mode); -+int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device); -+#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z) -+#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y) -+void *krb5int_push_fscreatecon_for(const char *pathname); -+void krb5int_pop_fscreatecon(void *previous); -+#else -+#define WRITABLEFOPEN(x,y) fopen(x,y) -+#define THREEPARAMOPEN(x,y,z) open(x,y,z) -+#endif -+#endif ---- krb5/src/include/krb5/krb5.hin -+++ krb5/src/include/krb5/krb5.hin -@@ -87,6 +87,12 @@ - #define THREEPARAMOPEN(x,y,z) open(x,y,z) - #endif - -+#if KRB5_PRIVATE -+#ifndef WRITABLEFOPEN -+#define WRITABLEFOPEN(x,y) fopen(x,y) -+#endif -+#endif -+ - #define KRB5_OLD_CRYPTO - - #include ---- krb5/src/kadmin/dbutil/dump.c -+++ krb5/src/kadmin/dbutil/dump.c -@@ -376,12 +376,21 @@ create_ofile(char *ofile, char **tmpname - { - int fd = -1; - FILE *f; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - *tmpname = NULL; - if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0) - goto error; - -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(ofile); -+#endif - fd = mkstemp(*tmpname); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - if (fd == -1) - goto error; - -@@ -514,7 +514,7 @@ prep_ok_file(krb5_context context, char - return 0; - } - -- *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); -+ *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); - if (*fd == -1) { - com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok); - exit_status++; ---- krb5/src/build-tools/krb5-config.in -+++ krb5/src/build-tools/krb5-config.in -@@ -38,6 +38,7 @@ RPATH_FLAG='@RPATH_FLAG@' - DEFCCNAME='@DEFCCNAME@' - DEFKTNAME='@DEFKTNAME@' - DEFCKTNAME='@DEFCKTNAME@' -+SELINUX_LIBS='@SELINUX_LIBS@' - - LIBS='@LIBS@' - GEN_LIB=@GEN_LIB@ -@@ -218,7 +219,7 @@ - fi - - # If we ever support a flag to generate output suitable for static -- # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB" -+ # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB" - # here. - - echo $lib_flags ---- krb5/src/lib/kadm5/logger.c -+++ krb5/src/lib/kadm5/logger.c -@@ -425,7 +425,7 @@ krb5_klog_init(krb5_context kcontext, ch - * Check for append/overwrite, then open the file. - */ - if (cp[4] == ':' || cp[4] == '=') { -- f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w"); -+ f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w"); - if (f) { - set_cloexec_file(f); - log_control.log_entries[i].lfu_filep = f; -@@ -961,7 +961,7 @@ krb5_klog_reopen(krb5_context kcontext) - * In case the old logfile did not get moved out of the - * way, open for append to prevent squashing the old logs. - */ -- f = fopen(log_control.log_entries[lindex].lfu_fname, "a+"); -+ f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+"); - if (f) { - set_cloexec_file(f); - log_control.log_entries[lindex].lfu_filep = f; ---- krb5/src/lib/krb5/keytab/kt_file.c -+++ krb5/src/lib/krb5/keytab/kt_file.c -@@ -1050,7 +1050,7 @@ krb5_ktfileint_open(krb5_context context - - KTCHECKLOCK(id); - errno = 0; -- KTFILEP(id) = fopen(KTFILENAME(id), -+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), - (mode == KRB5_LOCKMODE_EXCLUSIVE) ? - fopen_mode_rbplus : fopen_mode_rb); - if (!KTFILEP(id)) { -@@ -1058,7 +1058,7 @@ krb5_ktfileint_open(krb5_context context - /* try making it first time around */ - k5_create_secure_file(context, KTFILENAME(id)); - errno = 0; -- KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus); -+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus); - if (!KTFILEP(id)) - goto report_errno; - writevno = 1; ---- krb5/src/plugins/kdb/db2/adb_openclose.c -+++ krb5/src/plugins/kdb/db2/adb_openclose.c -@@ -201,7 +201,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char - * POSIX systems - */ - lockp->lockinfo.filename = strdup(lockfilename); -- if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) { -+ if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) { - /* - * maybe someone took away write permission so we could only - * get shared locks? ---- krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c -+++ krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c -@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8. - - #include "k5-platform.h" /* mkstemp? */ - -+#include "k5-int.h" - #include "db-int.h" - #include "btree.h" - -@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, - goto einval; - } - -- if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0) -+ if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) - goto err; - - } else { ---- krb5/src/plugins/kdb/db2/libdb2/hash/hash.c -+++ krb5/src/plugins/kdb/db2/libdb2/hash/hash.c -@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 - #include - #endif - -+#include "k5-int.h" - #include "db-int.h" - #include "hash.h" - #include "page.h" -@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info - new_table = 1; - } - if (file) { -- if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1) -+ if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1) - RETURN_ERROR(errno, error0); - (void)fcntl(hashp->fp, F_SETFD, 1); - } ---- krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c -+++ krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c -@@ -179,7 +179,7 @@ done: - - /* set password in the file */ - old_mode = umask(0177); -- pfile = fopen(file_name, "a+"); -+ pfile = WRITABLEFOPEN(file_name, "a+"); - if (pfile == NULL) { - com_err(me, errno, _("Failed to open file %s: %s"), file_name, - strerror (errno)); -@@ -220,6 +220,9 @@ done: - * Delete the existing entry and add the new entry - */ - FILE *newfile; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - mode_t omask; - -@@ -231,7 +234,13 @@ done: - } - - omask = umask(077); -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(file_name); -+#endif - newfile = fopen(tmp_file, "w"); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - umask (omask); - if (newfile == NULL) { - com_err(me, errno, _("Error creating file %s"), tmp_file); ---- krb5/src/slave/kpropd.c -+++ krb5/src/slave/kpropd.c -@@ -437,6 +437,9 @@ void doit(fd) - krb5_enctype etype; - int database_fd; - char host[INET6_ADDRSTRLEN+1]; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - signal_wrapper(SIGALRM, alarm_handler); - alarm(params.iprop_resync_timeout); -@@ -515,9 +518,15 @@ void doit(fd) - free(name); - exit(1); - } -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(file); -+#endif - omask = umask(077); - lock_fd = open(temp_file_name, O_RDWR|O_CREAT, 0600); - (void) umask(omask); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - retval = krb5_lock_file(kpropd_context, lock_fd, - KRB5_LOCKMODE_EXCLUSIVE|KRB5_LOCKMODE_DONTBLOCK); - if (retval) { ---- krb5/src/util/profile/prof_file.c -+++ krb5/src/util/profile/prof_file.c -@@ -30,6 +30,7 @@ - #endif - - #include "k5-platform.h" -+#include "k5-label.h" - - struct global_shared_profile_data { - /* This is the head of the global list of shared trees */ -@@ -418,7 +419,7 @@ static errcode_t write_data_to_file(prf_ - - errno = 0; - -- f = fopen(new_file, "w"); -+ f = WRITABLEFOPEN(new_file, "w"); - if (!f) { - retval = errno; - if (retval == 0) ---- krb5/src/util/support/Makefile.in -+++ krb5/src/util/support/Makefile.in -@@ -54,6 +54,7 @@ IPC_SYMS= \ - - STLIBOBJS= \ - threads.o \ -+ selinux.o \ - init-addrinfo.o \ - plugins.o \ - errors.o \ -@@ -108,7 +109,7 @@ SRCS=\ - - SHLIB_EXPDEPS = - # Add -lm if dumping thread stats, for sqrt. --SHLIB_EXPLIBS= $(LIBS) $(DL_LIB) -+SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB) - - DEPLIBS= - ---- krb5/src/util/support/selinux.c -+++ krb5/src/util/support/selinux.c -@@ -0,0 +1,381 @@ -+/* -+ * Copyright 2007,2008,2009,2011,2012,2013 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. -+ * -+ * File-opening wrappers for creating correctly-labeled files. So far, we can -+ * assume that this is Linux-specific, so we make many simplifying assumptions. -+ */ -+ -+#include "../../include/autoconf.h" -+ -+#ifdef USE_SELINUX -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef HAVE_SELINUX_LABEL_H -+#include -+#endif -+ -+/* #define DEBUG 1 */ -+ -+/* Mutex used to serialize use of the process-global file creation context. */ -+k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER; -+ -+/* Make sure we finish initializing that mutex before attempting to use it. */ -+k5_once_t labeled_once = K5_ONCE_INIT; -+static void -+label_mutex_init(void) -+{ -+ k5_mutex_finish_init(&labeled_mutex); -+} -+ -+#ifdef HAVE_SELINUX_LABEL_H -+static struct selabel_handle *selabel_ctx; -+static time_t selabel_last_changed; -+ -+MAKE_FINI_FUNCTION(cleanup_fscreatecon); -+ -+static void -+cleanup_fscreatecon(void) -+{ -+ if (selabel_ctx != NULL) { -+ selabel_close(selabel_ctx); -+ selabel_ctx = NULL; -+ } -+} -+#endif -+ -+static security_context_t -+push_fscreatecon(const char *pathname, mode_t mode) -+{ -+ security_context_t previous, configuredsc, currentsc, derivedsc; -+ context_t current, derived; -+ const char *fullpath, *currentuser; -+ -+ previous = NULL; -+ if (is_selinux_enabled()) { -+ if (getfscreatecon(&previous) == 0) { -+ char *genpath; -+ genpath = NULL; -+ if (pathname[0] != '/') { -+ char *wd; -+ size_t len; -+ len = 0; -+ wd = getcwd(NULL, len); -+ if (wd == NULL) { -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ len = strlen(wd) + 1 + strlen(pathname) + 1; -+ genpath = malloc(len); -+ if (genpath == NULL) { -+ free(wd); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ sprintf(genpath, "%s/%s", wd, pathname); -+ free(wd); -+ fullpath = genpath; -+ } else { -+ fullpath = pathname; -+ } -+#ifdef DEBUG -+ if (isatty(fileno(stderr))) { -+ fprintf(stderr, "Looking up context for " -+ "\"%s\"(%05o).\n", fullpath, mode); -+ } -+#endif -+ configuredsc = NULL; -+#ifdef HAVE_SELINUX_LABEL_H -+ if ((selabel_ctx != NULL) || -+ (selabel_last_changed == 0)) { -+ const char *cpath; -+ struct stat st; -+ int i = -1; -+ cpath = selinux_file_context_path(); -+ if ((cpath == NULL) || -+ ((i = stat(cpath, &st)) != 0) || -+ (st.st_mtime != selabel_last_changed)) { -+ if (selabel_ctx != NULL) { -+ selabel_close(selabel_ctx); -+ selabel_ctx = NULL; -+ } -+ selabel_last_changed = i ? -+ time(NULL) : -+ st.st_mtime; -+ } -+ } -+ if (selabel_ctx == NULL) { -+ selabel_ctx = selabel_open(SELABEL_CTX_FILE, -+ NULL, 0); -+ } -+ if (selabel_ctx != NULL) { -+ if (selabel_lookup(selabel_ctx, &configuredsc, -+ fullpath, mode) != 0) { -+ free(genpath); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ } -+#else -+ if (matchpathcon(fullpath, mode, &configuredsc) != 0) { -+ free(genpath); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+#endif -+ free(genpath); -+ if (configuredsc == NULL) { -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ currentsc = NULL; -+ getcon(¤tsc); -+ if (currentsc != NULL) { -+ derived = context_new(configuredsc); -+ if (derived != NULL) { -+ current = context_new(currentsc); -+ if (current != NULL) { -+ currentuser = context_user_get(current); -+ if (currentuser != NULL) { -+ if (context_user_set(derived, -+ currentuser) == 0) { -+ derivedsc = context_str(derived); -+ if (derivedsc != NULL) { -+ freecon(configuredsc); -+ configuredsc = strdup(derivedsc); -+ } -+ } -+ } -+ context_free(current); -+ } -+ context_free(derived); -+ } -+ freecon(currentsc); -+ } -+#ifdef DEBUG -+ if (isatty(fileno(stderr))) { -+ fprintf(stderr, "Setting file creation context " -+ "to \"%s\".\n", configuredsc); -+ } -+#endif -+ if (setfscreatecon(configuredsc) != 0) { -+ freecon(configuredsc); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ return NULL; -+ } -+ freecon(configuredsc); -+#ifdef DEBUG -+ } else { -+ if (isatty(fileno(stderr))) { -+ fprintf(stderr, "Unable to determine " -+ "current context.\n"); -+ } -+#endif -+ } -+ } -+ return previous; -+} -+ -+static void -+pop_fscreatecon(security_context_t previous) -+{ -+ if (is_selinux_enabled()) { -+#ifdef DEBUG -+ if (isatty(fileno(stderr))) { -+ if (previous != NULL) { -+ fprintf(stderr, "Resetting file creation " -+ "context to \"%s\".\n", previous); -+ } else { -+ fprintf(stderr, "Resetting file creation " -+ "context to default.\n"); -+ } -+ } -+#endif -+ setfscreatecon(previous); -+ if (previous != NULL) { -+ freecon(previous); -+ } -+ } -+} -+ -+void * -+krb5int_push_fscreatecon_for(const char *pathname) -+{ -+ struct stat st; -+ void *retval; -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ if (stat(pathname, &st) != 0) { -+ st.st_mode = S_IRUSR | S_IWUSR; -+ } -+ retval = push_fscreatecon(pathname, st.st_mode); -+ return retval ? retval : (void *) -1; -+} -+ -+void -+krb5int_pop_fscreatecon(void *con) -+{ -+ if (con != NULL) { -+ pop_fscreatecon((con == (void *) -1) ? NULL : con); -+ k5_mutex_unlock(&labeled_mutex); -+ } -+} -+ -+FILE * -+krb5int_labeled_fopen(const char *path, const char *mode) -+{ -+ FILE *fp; -+ int errno_save; -+ security_context_t ctx; -+ -+ if ((strcmp(mode, "r") == 0) || -+ (strcmp(mode, "rb") == 0)) { -+ return fopen(path, mode); -+ } -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, 0); -+ fp = fopen(path, mode); -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return fp; -+} -+ -+int -+krb5int_labeled_creat(const char *path, mode_t mode) -+{ -+ int fd; -+ int errno_save; -+ security_context_t ctx; -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, 0); -+ fd = creat(path, mode); -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return fd; -+} -+ -+int -+krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev) -+{ -+ int ret; -+ int errno_save; -+ security_context_t ctx; -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, mode); -+ ret = mknod(path, mode, dev); -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return ret; -+} -+ -+int -+krb5int_labeled_mkdir(const char *path, mode_t mode) -+{ -+ int ret; -+ int errno_save; -+ security_context_t ctx; -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, S_IFDIR); -+ ret = mkdir(path, mode); -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return ret; -+} -+ -+int -+krb5int_labeled_open(const char *path, int flags, ...) -+{ -+ int fd; -+ int errno_save; -+ security_context_t ctx; -+ mode_t mode; -+ va_list ap; -+ -+ if ((flags & O_CREAT) == 0) { -+ return open(path, flags); -+ } -+ -+ k5_once(&labeled_once, label_mutex_init); -+ k5_mutex_lock(&labeled_mutex); -+ ctx = push_fscreatecon(path, 0); -+ -+ va_start(ap, flags); -+ mode = va_arg(ap, mode_t); -+ fd = open(path, flags, mode); -+ va_end(ap); -+ -+ errno_save = errno; -+ pop_fscreatecon(ctx); -+ k5_mutex_unlock(&labeled_mutex); -+ errno = errno_save; -+ return fd; -+} -+ -+#endif ---- krb5/src/lib/krb5/rcache/rc_dfl.c -+++ krb5/src/lib/krb5/rcache/rc_dfl.c -@@ -813,6 +813,9 @@ krb5_rc_dfl_expunge_locked(krb5_context - krb5_error_code retval = 0; - krb5_rcache tmp; - krb5_deltat lifespan = t->lifespan; /* save original lifespan */ -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - if (! t->recovering) { - name = t->name; -@@ -834,7 +837,17 @@ krb5_rc_dfl_expunge_locked(krb5_context - retval = krb5_rc_resolve(context, tmp, 0); - if (retval) - goto cleanup; -+#ifdef USE_SELINUX -+ if (t->d.fn != NULL) -+ selabel = krb5int_push_fscreatecon_for(t->d.fn); -+ else -+ selabel = NULL; -+#endif - retval = krb5_rc_initialize(context, tmp, lifespan); -+#ifdef USE_SELINUX -+ if (selabel != NULL) -+ krb5int_pop_fscreatecon(selabel); -+#endif - if (retval) - goto cleanup; - for (q = t->a; q; q = q->na) { ---- krb5/src/lib/krb5/ccache/cc_dir.c -+++ krb5/src/lib/krb5/ccache/cc_dir.c -@@ -185,10 +185,19 @@ write_primary_file(const char *primary_p - char *newpath = NULL; - FILE *fp = NULL; - int fd = -1, status; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0) - return ENOMEM; -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(primary_path); -+#endif - fd = mkstemp(newpath); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif - if (fd < 0) - goto cleanup; - #ifdef HAVE_CHMOD -@@ -223,10 +232,23 @@ - verify_dir(krb5_context context, const char *dirname) - { - struct stat st; -+ int status; -+#ifdef USE_SELINUX -+ void *selabel; -+#endif - - if (stat(dirname, &st) < 0) { -- if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0) -- return 0; -+ if (errno == ENOENT) { -+#ifdef USE_SELINUX -+ selabel = krb5int_push_fscreatecon_for(dirname); -+#endif -+ status = mkdir(dirname, S_IRWXU); -+#ifdef USE_SELINUX -+ krb5int_pop_fscreatecon(selabel); -+#endif -+ if (status == 0) -+ return 0; -+ } - krb5_set_error_message(context, KRB5_FCC_NOFILE, - _("Credential cache directory %s does not " - "exist"), dirname); ---- krb5/src/lib/krb5/os/trace.c -+++ krb5/src/lib/krb5/os/trace.c -@@ -401,7 +401,7 @@ krb5_set_trace_filename(krb5_context con - fd = malloc(sizeof(*fd)); - if (fd == NULL) - return ENOMEM; -- *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); -+ *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); - if (*fd == -1) { - free(fd); - return errno; ---- krb5/src/plugins/kdb/db2/kdb_db2.c -+++ krb5/src/plugins/kdb/db2/kdb_db2.c -@@ -683,8 +683,8 @@ - if (retval) - return retval; - -- dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC, -- 0600); -+ dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name, -+ O_CREAT | O_RDWR | O_TRUNC, 0600); - if (dbc->db_lf_file < 0) { - retval = errno; - goto cleanup; ---- krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c -+++ krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c -@@ -51,6 +51,7 @@ - #include - #include - -+#include "k5-int.h" - #include "db-int.h" - #include "recno.h" - -@@ -68,7 +69,8 @@ - int rfd = -1, sverrno; - - /* Open the user's file -- if this fails, we're done. */ -- if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0) -+ if (fname != NULL && -+ (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) - return (NULL); - - if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) { ---- krb5/src/kdc/main.c -+++ krb5/src/kdc/main.c -@@ -905,7 +905,7 @@ write_pid_file(const char *path) - FILE *file; - unsigned long pid; - -- file = fopen(path, "w"); -+ file = WRITABLEFOPEN(path, "w"); - if (file == NULL) - return errno; - pid = (unsigned long) getpid(); ---- krb5/src/lib/kdb/kdb_log.c -+++ krb5/src/lib/kdb/kdb_log.c -@@ -566,7 +566,7 @@ ulog_map(krb5_context context, const cha - if (caller == FKPROPLOG) - return errno; - -- ulogfd = open(logname, O_RDWR | O_CREAT, 0600); -+ ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600); - if (ulogfd == -1) - return errno; - ---- krb5/src/util/gss-kernel-lib/Makefile.in -+++ krb5/src/util/gss-kernel-lib/Makefile.in -@@ -60,6 +60,7 @@ HEADERS= \ - gssapi_err_generic.h \ - k5-int.h \ - k5-int-pkinit.h \ -+ k5-label.h \ - k5-thread.h \ - k5-platform.h \ - k5-buf.h \ -@@ -166,10 +167,12 @@ gssapi_generic.h: $(GSS_GENERIC)/gssapi_ - $(CP) $(GSS_GENERIC)/gssapi_generic.h $@ - gssapi_err_generic.h: $(GSS_GENERIC_BUILD)/gssapi_err_generic.h - $(CP) $(GSS_GENERIC_BUILD)/gssapi_err_generic.h $@ --k5-int.h: $(INCLUDE)/k5-int.h -+k5-int.h: $(INCLUDE)/k5-int.h k5-label.h - $(CP) $(INCLUDE)/k5-int.h $@ - k5-int-pkinit.h: $(INCLUDE)/k5-int-pkinit.h - $(CP) $(INCLUDE)/k5-int-pkinit.h $@ -+k5-label.h: $(INCLUDE)/k5-label.h -+ $(CP) $(INCLUDE)/k5-label.h $@ - k5-thread.h: $(INCLUDE)/k5-thread.h - $(CP) $(INCLUDE)/k5-thread.h $@ - k5-platform.h: $(INCLUDE)/k5-platform.h diff --git a/SOURCES/krb5-1.12-system-exts.patch b/SOURCES/krb5-1.12-system-exts.patch deleted file mode 100644 index b90fb1b..0000000 --- a/SOURCES/krb5-1.12-system-exts.patch +++ /dev/null @@ -1,53 +0,0 @@ -On a glibc system, EAI_NODATA isn't defined unless _GNU_SOURCE is. The -recommended thing is to use AC_USE_SYSTEM_EXTENSIONS to get all extensions -defined, but that would require fixups in varous other places, so we go for the -smaller change here. - ---- krb5-1.11/src/lib/krb5/os/hostrealm.c -+++ krb5-1.11/src/lib/krb5/os/hostrealm.c -@@ -30,6 +30,9 @@ - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -+/* We need to have EAI_NODATA and friends declared. */ -+#define _GNU_SOURCE -+ - #include "k5-int.h" - #include "os-proto.h" - #include "fake-addrinfo.h" ---- krb5-1.11/src/lib/krb5/os/sendto_kdc.c -+++ krb5-1.11/src/lib/krb5/os/sendto_kdc.c -@@ -27,6 +27,9 @@ - /* Send packet to KDC for realm; wait for response, retransmitting - * as necessary. */ - -+/* We need to have EAI_NODATA and friends declared. */ -+#define _GNU_SOURCE -+ - #include "fake-addrinfo.h" - #include "k5-tls.h" - #include "k5-int.h" ---- krb5-1.11/src/util/support/fake-addrinfo.c -+++ krb5-1.11/src/util/support/fake-addrinfo.c -@@ -101,6 +101,9 @@ - * these functions, and throw all this away. Pleeease? :-) - */ - -+/* We need to have EAI_NODATA and friends declared. */ -+#define _GNU_SOURCE -+ - #include "port-sockets.h" - #include "socket-utils.h" - #include "k5-platform.h" ---- krb5-1.12/src/lib/krad/client.c -+++ krb5-1.12/src/lib/krad/client.c -@@ -27,6 +27,9 @@ - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -+/* We need to have EAI_NODATA and friends declared. */ -+#define _GNU_SOURCE -+ - #include - #include "internal.h" - diff --git a/SOURCES/krb5-1.12.2.tar.gz.asc b/SOURCES/krb5-1.12.2.tar.gz.asc deleted file mode 100644 index fc16e6f..0000000 --- a/SOURCES/krb5-1.12.2.tar.gz.asc +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1 - -iQEVAwUAU+lJVhUCTNN0nXiJAQIpkgf9HczaywhoXEZYbVORXAxDGrb8ADlAnFdY -htRjqJ8xTmj0yMtPF1NJk4ian/u9ksc7qZ9JQg7F64gy/7098RlCfsTMT/b3qp0r -0cmNiTMYq19igxHy9qWm0JonudDQhUulmIMi/58nBXc7IblhaVtlDnQNbA8qpg9W -RLdn0qyeksVWAIxJ1KKsZTbZ4+U1OOPE2npZ7nHeLeYmz7rKqorQQM+NNxu+/dtB -eo0fmeeX7bXPE2Xe/kYw7HSfIhRMHy1oH0fi9AAZnREA00/xgPq+JqhC3hIloqlk -NDTJk2+cKZnyuDh+nyuS7wGsExqJCWjFSE5mrJiJ6N0YS0hsLn+7aA== -=O612 ------END PGP SIGNATURE----- diff --git a/SOURCES/krb5-1.12ish-kpasswd_tcp.patch b/SOURCES/krb5-1.12ish-kpasswd_tcp.patch deleted file mode 100644 index 4fdfca4..0000000 --- a/SOURCES/krb5-1.12ish-kpasswd_tcp.patch +++ /dev/null @@ -1,32 +0,0 @@ -Fall back to TCP on kdc-unresolvable/unreachable errors. We still have -to wait for UDP to fail, so this might not be ideal. RT #5868. - ---- krb5/src/lib/krb5/os/changepw.c -+++ krb5/src/lib/krb5/os/changepw.c -@@ -270,10 +270,22 @@ change_set_password(krb5_context context - &sl, strategy, &callback_info, &chpw_rep, - ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); - if (code) { -- /* -- * Here we may want to switch to TCP on some errors. -- * right? -- */ -+ /* if we're not using a stream socket, and it's an error which -+ * might reasonably be specific to a datagram "connection", try -+ * again with a stream socket */ -+ if (!no_udp) { -+ switch (code) { -+ case KRB5_KDC_UNREACH: -+ case KRB5_REALM_CANT_RESOLVE: -+ case KRB5KRB_ERR_RESPONSE_TOO_BIG: -+ /* should we do this for more result codes than these? */ -+ k5_free_serverlist (&sl); -+ no_udp = 1; -+ continue; -+ default: -+ break; -+ } -+ } - break; - } - diff --git a/SOURCES/krb5-1.12ish-tls-plugins.patch b/SOURCES/krb5-1.12ish-tls-plugins.patch deleted file mode 100644 index 9004f74..0000000 --- a/SOURCES/krb5-1.12ish-tls-plugins.patch +++ /dev/null @@ -1,1680 +0,0 @@ -Adapt to headers being included in a different order in sendto_kdc.c. -Drop portions which drop checkhost.c and checkhost.h. - -commit 472349d2a47fbc7db82e46ba46411b95c312fc1f -Author: Greg Hudson -Date: Sun Jun 22 10:42:14 2014 -0400 - - Move KKDCP OpenSSL code to an internal plugin - - Create an internal pluggable interface "tls" with one in-tree dynamic - plugin module named "k5tls". Move all of the OpenSSL calls to the - plugin module, and make the libkrb5 code load and invoke the plugin. - This way we do not load or initialize libssl unless an HTTP proxy is - used. - - ticket: 7929 - -diff --git a/src/Makefile.in b/src/Makefile.in -index 5e2cf4e..92bb60a 100644 ---- a/src/Makefile.in -+++ b/src/Makefile.in -@@ -20,6 +20,7 @@ SUBDIRS=util include lib \ - @ldap_plugin_dir@ \ - plugins/preauth/otp \ - plugins/preauth/pkinit \ -+ plugins/tls/k5tls \ - kdc kadmin slave clients appl tests \ - config-files build-tools man doc @po@ - WINSUBDIRS=include util lib ccapi windows clients appl -@@ -62,7 +63,7 @@ INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROOT) $(KRB5OTHERMKDIRS) \ - $(KRB5_LIBDIR) $(KRB5_INCDIR) \ - $(KRB5_DB_MODULE_DIR) $(KRB5_PA_MODULE_DIR) \ - $(KRB5_AD_MODULE_DIR) \ -- $(KRB5_LIBKRB5_MODULE_DIR) \ -+ $(KRB5_LIBKRB5_MODULE_DIR) $(KRB5_TLS_MODULE_DIR) \ - @localstatedir@ @localstatedir@/krb5kdc \ - $(KRB5_INCSUBDIRS) $(datadir) $(EXAMPLEDIR) \ - $(PKGCONFIG_DIR) -diff --git a/src/config/pre.in b/src/config/pre.in -index e1d7e4b..fd8ee56 100644 ---- a/src/config/pre.in -+++ b/src/config/pre.in -@@ -213,6 +213,7 @@ KRB5_DB_MODULE_DIR = $(MODULE_DIR)/kdb - KRB5_PA_MODULE_DIR = $(MODULE_DIR)/preauth - KRB5_AD_MODULE_DIR = $(MODULE_DIR)/authdata - KRB5_LIBKRB5_MODULE_DIR = $(MODULE_DIR)/libkrb5 -+KRB5_TLS_MODULE_DIR = $(MODULE_DIR)/tls - KRB5_LOCALEDIR = @localedir@ - GSS_MODULE_DIR = @libdir@/gss - KRB5_INCSUBDIRS = \ -diff --git a/src/configure.in b/src/configure.in -index 8aa513e..43509ab 100644 ---- a/src/configure.in -+++ b/src/configure.in -@@ -308,6 +308,11 @@ no) - ;; - esac - -+if test "$PROXY_TLS_IMPL" = no; then -+ AC_DEFINE(PROXY_TLS_IMPL_NONE,1, -+ [Define if no HTTP TLS implementation is selected]) -+fi -+ - AC_SUBST(PROXY_TLS_IMPL) - AC_SUBST(PROXY_TLS_IMPL_CFLAGS) - AC_SUBST(PROXY_TLS_IMPL_LIBS) -@@ -1386,6 +1391,7 @@ dnl ccapi ccapi/lib ccapi/lib/unix ccapi/server ccapi/server/unix ccapi/test - plugins/authdata/greet - plugins/authdata/greet_client - plugins/authdata/greet_server -+ plugins/tls/k5tls - - clients clients/klist clients/kinit clients/kvno - clients/kdestroy clients/kpasswd clients/ksu clients/kswitch -diff --git a/src/include/k5-int.h b/src/include/k5-int.h -index 9f14ee0..38846eb 100644 ---- a/src/include/k5-int.h -+++ b/src/include/k5-int.h -@@ -1083,7 +1083,8 @@ struct plugin_interface { - #define PLUGIN_INTERFACE_LOCALAUTH 5 - #define PLUGIN_INTERFACE_HOSTREALM 6 - #define PLUGIN_INTERFACE_AUDIT 7 --#define PLUGIN_NUM_INTERFACES 8 -+#define PLUGIN_INTERFACE_TLS 8 -+#define PLUGIN_NUM_INTERFACES 9 - - /* Retrieve the plugin module of type interface_id and name modname, - * storing the result into module. */ -@@ -1126,6 +1127,7 @@ typedef struct krb5_preauth_context_st krb5_preauth_context; - struct ccselect_module_handle; - struct localauth_module_handle; - struct hostrealm_module_handle; -+struct k5_tls_vtable_st; - struct _krb5_context { - krb5_magic magic; - krb5_enctype *in_tkt_etypes; -@@ -1169,6 +1171,9 @@ struct _krb5_context { - /* hostrealm module stuff */ - struct hostrealm_module_handle **hostrealm_handles; - -+ /* TLS module vtable (if loaded) */ -+ struct k5_tls_vtable_st *tls; -+ - /* error detail info */ - struct errinfo err; - -diff --git a/src/include/k5-tls.h b/src/include/k5-tls.h -new file mode 100644 -index 0000000..0661c05 ---- /dev/null -+++ b/src/include/k5-tls.h -@@ -0,0 +1,104 @@ -+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -+/* include/k5-tls.h - internal pluggable interface for TLS */ -+/* -+ * Copyright (C) 2014 by the Massachusetts Institute of Technology. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -+ * OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* -+ * This internal pluggable interface allows libkrb5 to load an in-tree module -+ * providing TLS support at runtime. It is currently tailored for the needs of -+ * the OpenSSL module as used for HTTP proxy support. As an internal -+ * interface, it can be changed to fit different implementations and consumers -+ * without regard for backward compatibility. -+ */ -+ -+#ifndef K5_TLS_H -+#define K5_TLS_H -+ -+#include "k5-int.h" -+ -+/* An abstract type for localauth module data. */ -+typedef struct k5_tls_handle_st *k5_tls_handle; -+ -+typedef enum { -+ DATA_READ, DONE, WANT_READ, WANT_WRITE, ERROR_TLS -+} k5_tls_status; -+ -+/* -+ * Create a handle for fd, where the server certificate must match servername -+ * and be trusted according to anchors. anchors is a null-terminated list -+ * using the DIR:/FILE:/ENV: syntax borrowed from PKINIT. If anchors is null, -+ * use the system default trust anchors. -+ */ -+typedef krb5_error_code -+(*k5_tls_setup_fn)(krb5_context context, SOCKET fd, const char *servername, -+ char **anchors, k5_tls_handle *handle_out); -+ -+/* -+ * Write len bytes of data using TLS. Return DONE if writing is complete, -+ * WANT_READ or WANT_WRITE if the underlying socket must be readable or -+ * writable to continue, and ERROR_TLS if the TLS channel or underlying socket -+ * experienced an error. After WANT_READ or WANT_WRITE, the operation will be -+ * retried with the same arguments even if some data has already been written. -+ * (OpenSSL makes this contract easy to fulfill. For other implementations we -+ * might want to change it.) -+ */ -+typedef k5_tls_status -+(*k5_tls_write_fn)(krb5_context context, k5_tls_handle handle, -+ const void *data, size_t len); -+ -+/* -+ * Read up to data_size bytes of data using TLS. Return DATA_READ and set -+ * *len_out if any data is read. Return DONE if there is no more data to be -+ * read on the connection, WANT_READ or WANT_WRITE if the underlying socket -+ * must be readable or writable to continue, and ERROR_TLS if the TLS channel -+ * or underlying socket experienced an error. -+ * -+ * After DATA_READ, there may still be pending buffered data to read. The -+ * caller must call this method again with additional buffer space before -+ * selecting for reading on the underlying socket. -+ */ -+typedef k5_tls_status -+(*k5_tls_read_fn)(krb5_context context, k5_tls_handle handle, void *data, -+ size_t data_size, size_t *len_out); -+ -+/* Release a handle. Do not pass a null pointer. */ -+typedef void -+(*k5_tls_free_handle_fn)(krb5_context context, k5_tls_handle handle); -+ -+/* All functions are mandatory unless they are all null, in which case the -+ * caller should assume that TLS is unsupported. */ -+typedef struct k5_tls_vtable_st { -+ k5_tls_setup_fn setup; -+ k5_tls_write_fn write; -+ k5_tls_read_fn read; -+ k5_tls_free_handle_fn free_handle; -+} *k5_tls_vtable; -+ -+#endif /* K5_TLS_H */ -diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h -index 9e75b29..a0aa85a 100644 ---- a/src/include/k5-trace.h -+++ b/src/include/k5-trace.h -@@ -324,23 +324,11 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); - TRACE(c, "Resolving hostname {str}", hostname) - #define TRACE_SENDTO_KDC_RESPONSE(c, len, raddr) \ - TRACE(c, "Received answer ({int} bytes) from {raddr}", len, raddr) --#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(c, hostname) \ -- TRACE(c, "HTTPS certificate name mismatch: server certificate is " \ -- "not for \"{str}\"", hostname) --#define TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(c, hostname) \ -- TRACE(c, "HTTPS certificate name matched \"{str}\"", hostname) --#define TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(c) \ -- TRACE(c, "HTTPS server certificate not received") --#define TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(c, depth, \ -- namelen, name, \ -- err, errs) \ -- TRACE(c, "HTTPS certificate error at {int} ({lenstr}): " \ -- "{int} ({str})", depth, namelen, name, err, errs) --#define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr) \ -+#define TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(c, raddr) \ - TRACE(c, "HTTPS error connecting to {raddr}", raddr) --#define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr, err) \ -- TRACE(c, "HTTPS error receiving from {raddr}: {errno}", raddr, err) --#define TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(c, raddr) \ -+#define TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(c, raddr) \ -+ TRACE(c, "HTTPS error receiving from {raddr}", raddr) -+#define TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(c, raddr) \ - TRACE(c, "HTTPS error sending to {raddr}", raddr) - #define TRACE_SENDTO_KDC_HTTPS_SEND(c, raddr) \ - TRACE(c, "Sending HTTPS request to {raddr}", raddr) -@@ -383,6 +371,19 @@ void krb5int_trace(krb5_context context, const char *fmt, ...); - TRACE(c, "TGS reply didn't decode with subkey; trying session key " \ - "({keyblock)}", keyblock) - -+#define TRACE_TLS_ERROR(c, errs) \ -+ TRACE(c, "TLS error: {str}", errs) -+#define TRACE_TLS_NO_REMOTE_CERTIFICATE(c) \ -+ TRACE(c, "TLS server certificate not received") -+#define TRACE_TLS_CERT_ERROR(c, depth, namelen, name, err, errs) \ -+ TRACE(c, "TLS certificate error at {int} ({lenstr}): {int} ({str})", \ -+ depth, namelen, name, err, errs) -+#define TRACE_TLS_SERVER_NAME_MISMATCH(c, hostname) \ -+ TRACE(c, "TLS certificate name mismatch: server certificate is " \ -+ "not for \"{str}\"", hostname) -+#define TRACE_TLS_SERVER_NAME_MATCH(c, hostname) \ -+ TRACE(c, "TLS certificate name matched \"{str}\"", hostname) -+ - #define TRACE_TKT_CREDS(c, creds, cache) \ - TRACE(c, "Getting credentials {creds} using ccache {ccache}", \ - creds, cache) -diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in -index 472c008..d9cddc1 100644 ---- a/src/lib/krb5/Makefile.in -+++ b/src/lib/krb5/Makefile.in -@@ -56,8 +56,7 @@ RELDIR=krb5 - SHLIB_EXPDEPS = \ - $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ - $(COM_ERR_DEPLIB) $(SUPPORT_DEPLIB) --SHLIB_EXPLIBS=-lk5crypto -lcom_err $(PROXY_TLS_IMPL_LIBS) $(SUPPORT_LIB) \ -- @GEN_LIB@ $(LIBS) -+SHLIB_EXPLIBS=-lk5crypto -lcom_err $(SUPPORT_LIB) @GEN_LIB@ $(LIBS) - - all-unix:: all-liblinks - -diff --git a/src/lib/krb5/krb/copy_ctx.c b/src/lib/krb5/krb/copy_ctx.c -index 4237023..322c288 100644 ---- a/src/lib/krb5/krb/copy_ctx.c -+++ b/src/lib/krb5/krb/copy_ctx.c -@@ -81,6 +81,7 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out) - nctx->ccselect_handles = NULL; - nctx->localauth_handles = NULL; - nctx->hostrealm_handles = NULL; -+ nctx->tls = NULL; - nctx->kdblog_context = NULL; - nctx->trace_callback = NULL; - nctx->trace_callback_data = NULL; -diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c -index 6801bb1..6548f36 100644 ---- a/src/lib/krb5/krb/init_ctx.c -+++ b/src/lib/krb5/krb/init_ctx.c -@@ -319,6 +319,7 @@ krb5_free_context(krb5_context ctx) - k5_localauth_free_context(ctx); - k5_plugin_free_context(ctx); - free(ctx->plugin_base_dir); -+ free(ctx->tls); - - ctx->magic = 0; - free(ctx); -diff --git a/src/lib/krb5/krb/plugin.c b/src/lib/krb5/krb/plugin.c -index 8b62c7b..7375f51 100644 ---- a/src/lib/krb5/krb/plugin.c -+++ b/src/lib/krb5/krb/plugin.c -@@ -55,7 +55,8 @@ const char *interface_names[] = { - "ccselect", - "localauth", - "hostrealm", -- "audit" -+ "audit", -+ "tls" - }; - - /* Return the context's interface structure for id, or NULL if invalid. */ -diff --git a/src/lib/krb5/krb5_libinit.c b/src/lib/krb5/krb5_libinit.c -index b72bc58..eb40124 100644 ---- a/src/lib/krb5/krb5_libinit.c -+++ b/src/lib/krb5/krb5_libinit.c -@@ -55,8 +55,6 @@ int krb5int_lib_init(void) - if (err) - return err; - -- k5_sendto_kdc_initialize(); -- - return 0; - } - -diff --git a/src/lib/krb5/os/Makefile.in b/src/lib/krb5/os/Makefile.in -index fa8a093..ea68990 100644 ---- a/src/lib/krb5/os/Makefile.in -+++ b/src/lib/krb5/os/Makefile.in -@@ -2,7 +2,7 @@ mydir=lib$(S)krb5$(S)os - BUILDTOP=$(REL)..$(S)..$(S).. - DEFINES=-DLIBDIR=\"$(KRB5_LIBDIR)\" -DBINDIR=\"$(CLIENT_BINDIR)\" \ - -DSBINDIR=\"$(ADMIN_BINDIR)\" --LOCALINCLUDES= $(PROXY_TLS_IMPL_CFLAGS) -I$(top_srcdir)/util/profile -+LOCALINCLUDES= -I$(top_srcdir)/util/profile - - ##DOS##BUILDTOP = ..\..\.. - ##DOS##PREFIXDIR=os -@@ -13,7 +13,6 @@ STLIBOBJS= \ - c_ustime.o \ - ccdefname.o \ - changepw.o \ -- checkhost.o \ - dnsglue.o \ - dnssrv.o \ - expand_path.o \ -diff --git a/src/lib/krb5/os/deps b/src/lib/krb5/os/deps -index d56ff30..211354c 100644 ---- a/src/lib/krb5/os/deps -+++ b/src/lib/krb5/os/deps -@@ -49,17 +49,6 @@ changepw.so changepw.po $(OUTPRE)changepw.$(OBJEXT): \ - $(top_srcdir)/include/krb5/locate_plugin.h $(top_srcdir)/include/krb5/plugin.h \ - $(top_srcdir)/include/port-sockets.h $(top_srcdir)/include/socket-utils.h \ - changepw.c os-proto.h --checkhost.so checkhost.po $(OUTPRE)checkhost.$(OBJEXT): \ -- $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ -- $(BUILDTOP)/include/osconf.h $(BUILDTOP)/include/profile.h \ -- $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h $(top_srcdir)/include/k5-err.h \ -- $(top_srcdir)/include/k5-gmt_mktime.h $(top_srcdir)/include/k5-int-pkinit.h \ -- $(top_srcdir)/include/k5-int.h $(top_srcdir)/include/k5-platform.h \ -- $(top_srcdir)/include/k5-plugin.h $(top_srcdir)/include/k5-thread.h \ -- $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \ -- $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ -- $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ -- $(top_srcdir)/include/socket-utils.h checkhost.c checkhost.h - dnsglue.so dnsglue.po $(OUTPRE)dnsglue.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ - $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ - $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ -@@ -429,7 +418,7 @@ sendto_kdc.so sendto_kdc.po $(OUTPRE)sendto_kdc.$(OBJEXT): \ - $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \ - $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/locate_plugin.h \ - $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ -- $(top_srcdir)/include/socket-utils.h checkhost.h os-proto.h \ -+ $(top_srcdir)/include/socket-utils.h os-proto.h \ - sendto_kdc.c - sn2princ.so sn2princ.po $(OUTPRE)sn2princ.$(OBJEXT): \ - $(BUILDTOP)/include/autoconf.h $(BUILDTOP)/include/krb5/krb5.h \ -diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c -index 1f2039c..160a2d0 100644 ---- a/src/lib/krb5/os/locate_kdc.c -+++ b/src/lib/krb5/os/locate_kdc.c -@@ -177,7 +177,6 @@ oom: - return ENOMEM; - } - --#ifdef PROXY_TLS_IMPL_OPENSSL - static void - parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host, - char **uri_path) -@@ -195,13 +194,6 @@ parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host, - } - } - } --#else --static void --parse_uri_if_https(char *host_or_uri, k5_transport *transport, char **host, -- char **uri) --{ --} --#endif - - /* Return true if server is identical to an entry in list. */ - static krb5_boolean -diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h -index 34bf028..69ee376 100644 ---- a/src/lib/krb5/os/os-proto.h -+++ b/src/lib/krb5/os/os-proto.h -@@ -187,6 +187,5 @@ krb5_error_code localauth_k5login_initvt(krb5_context context, int maj_ver, - krb5_plugin_vtable vtable); - krb5_error_code localauth_an2ln_initvt(krb5_context context, int maj_ver, - int min_ver, krb5_plugin_vtable vtable); --void k5_sendto_kdc_initialize(void); - - #endif /* KRB5_LIBOS_INT_PROTO__ */ -diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c -index a572831..2242240 100644 ---- a/src/lib/krb5/os/sendto_kdc.c -+++ b/src/lib/krb5/os/sendto_kdc.c -@@ -54,6 +54,7 @@ - * as necessary. */ - - #include "fake-addrinfo.h" -+#include "k5-tls.h" - #include "k5-int.h" - - #include "os-proto.h" -@@ -74,15 +75,6 @@ - #endif - #endif - --#ifdef PROXY_TLS_IMPL_OPENSSL --#include --#include --#include --#include --#include --#include "checkhost.h" --#endif -- - #define MAX_PASS 3 - #define DEFAULT_UDP_PREF_LIMIT 1465 - #define HARD_UDP_LIMIT 32700 /* could probably do 64K-epsilon ? */ -@@ -147,29 +139,30 @@ struct conn_state { - const char *uri_path; - const char *servername; - char *https_request; --#ifdef PROXY_TLS_IMPL_OPENSSL -- SSL *ssl; --#endif -+ k5_tls_handle tls; - } http; - }; - --#ifdef PROXY_TLS_IMPL_OPENSSL --/* Extra-data identifier, used to pass context into the verify callback. */ --static int ssl_ex_context_id = -1; --static int ssl_ex_conn_id = -1; --#endif -- --void --k5_sendto_kdc_initialize(void) -+/* Set up context->tls. On allocation failure, return ENOMEM. On plugin load -+ * failure, set context->tls to point to a nulled vtable and return 0. */ -+static krb5_error_code -+init_tls_vtable(krb5_context context) - { --#ifdef PROXY_TLS_IMPL_OPENSSL -- SSL_library_init(); -- SSL_load_error_strings(); -- OpenSSL_add_all_algorithms(); -+ krb5_plugin_initvt_fn initfn; - -- ssl_ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); -- ssl_ex_conn_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); --#endif -+ if (context->tls != NULL) -+ return 0; -+ -+ context->tls = calloc(1, sizeof(*context->tls)); -+ if (context->tls == NULL) -+ return ENOMEM; -+ -+ /* Attempt to load the module; just let it stay nulled out on failure. */ -+ k5_plugin_register_dyn(context, PLUGIN_INTERFACE_TLS, "k5tls", "tls"); -+ if (k5_plugin_load(context, PLUGIN_INTERFACE_TLS, "k5tls", &initfn) == 0) -+ (*initfn)(context, 0, 0, (krb5_plugin_vtable)context->tls); -+ -+ return 0; - } - - /* Get current time in milliseconds. */ -@@ -184,21 +177,15 @@ get_curtime_ms(time_ms *time_out) - return 0; - } - --#ifdef PROXY_TLS_IMPL_OPENSSL - static void --free_http_ssl_data(struct conn_state *state) -+free_http_tls_data(krb5_context context, struct conn_state *state) - { -- SSL_free(state->http.ssl); -- state->http.ssl = NULL; -+ if (state->http.tls != NULL) -+ context->tls->free_handle(context, state->http.tls); -+ state->http.tls = NULL; - free(state->http.https_request); - state->http.https_request = NULL; - } --#else --static void --free_http_ssl_data(struct conn_state *state) --{ --} --#endif - - #ifdef USE_POLL - -@@ -532,7 +519,6 @@ static fd_handler_fn service_udp_read; - static fd_handler_fn service_https_write; - static fd_handler_fn service_https_read; - --#ifdef PROXY_TLS_IMPL_OPENSSL - static krb5_error_code - make_proxy_request(struct conn_state *state, const krb5_data *realm, - const krb5_data *message, char **req_out, size_t *len_out) -@@ -585,14 +571,6 @@ cleanup: - krb5_free_data(NULL, encoded_pm); - return ret; - } --#else --static krb5_error_code --make_proxy_request(struct conn_state *state, const krb5_data *realm, -- const krb5_data *message, char **req_out, size_t *len_out) --{ -- abort(); --} --#endif - - /* Set up the actual message we will send across the underlying transport to - * communicate the payload message, using one or both of state->out.sgbuf. */ -@@ -963,7 +941,7 @@ static void - kill_conn(krb5_context context, struct conn_state *conn, - struct select_state *selstate) - { -- free_http_ssl_data(conn); -+ free_http_tls_data(context, conn); - - if (socktype_for_transport(conn->addr.transport) == SOCK_STREAM) - TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &conn->addr); -@@ -1145,249 +1123,44 @@ service_udp_read(krb5_context context, const krb5_data *realm, - return TRUE; - } - --#ifdef PROXY_TLS_IMPL_OPENSSL --/* Output any error strings that OpenSSL's accumulated as tracing messages. */ --static void --flush_ssl_errors(krb5_context context) --{ -- unsigned long err; -- char buf[128]; -- -- while ((err = ERR_get_error()) != 0) { -- ERR_error_string_n(err, buf, sizeof(buf)); -- TRACE_SENDTO_KDC_HTTPS_ERROR(context, buf); -- } --} -- --static krb5_error_code --load_http_anchor_file(X509_STORE *store, const char *path) --{ -- FILE *fp; -- STACK_OF(X509_INFO) *sk = NULL; -- X509_INFO *xi; -- int i; -- -- fp = fopen(path, "r"); -- if (fp == NULL) -- return errno; -- sk = PEM_X509_INFO_read(fp, NULL, NULL, NULL); -- fclose(fp); -- if (sk == NULL) -- return ENOENT; -- for (i = 0; i < sk_X509_INFO_num(sk); i++) { -- xi = sk_X509_INFO_value(sk, i); -- if (xi->x509 != NULL) -- X509_STORE_add_cert(store, xi->x509); -- } -- sk_X509_INFO_pop_free(sk, X509_INFO_free); -- return 0; --} -- --static krb5_error_code --load_http_anchor_dir(X509_STORE *store, const char *path) --{ -- DIR *d = NULL; -- struct dirent *dentry = NULL; -- char filename[1024]; -- krb5_boolean found_any = FALSE; -- -- d = opendir(path); -- if (d == NULL) -- return ENOENT; -- while ((dentry = readdir(d)) != NULL) { -- if (dentry->d_name[0] != '.') { -- snprintf(filename, sizeof(filename), "%s/%s", -- path, dentry->d_name); -- if (load_http_anchor_file(store, filename) == 0) -- found_any = TRUE; -- } -- } -- closedir(d); -- return found_any ? 0 : ENOENT; --} -- --static krb5_error_code --load_http_anchor(SSL_CTX *ctx, const char *location) -+/* Set up conn->http.tls. Return true on success. */ -+static krb5_boolean -+setup_tls(krb5_context context, const krb5_data *realm, -+ struct conn_state *conn, struct select_state *selstate) - { -- X509_STORE *store; -- const char *envloc; -- -- store = SSL_CTX_get_cert_store(ctx); -- if (strncmp(location, "FILE:", 5) == 0) { -- return load_http_anchor_file(store, location + 5); -- } else if (strncmp(location, "DIR:", 4) == 0) { -- return load_http_anchor_dir(store, location + 4); -- } else if (strncmp(location, "ENV:", 4) == 0) { -- envloc = getenv(location + 4); -- if (envloc == NULL) -- return ENOENT; -- return load_http_anchor(ctx, envloc); -- } -- return EINVAL; --} -+ krb5_error_code ret; -+ krb5_boolean ok = FALSE; -+ char **anchors = NULL, *realmstr = NULL; -+ const char *names[4]; - --static krb5_error_code --load_http_verify_anchors(krb5_context context, const krb5_data *realm, -- SSL_CTX *sctx) --{ -- const char *anchors[4]; -- char **values = NULL, *realmz; -- unsigned int i; -- krb5_error_code err; -+ if (init_tls_vtable(context) != 0 || context->tls->setup == NULL) -+ return FALSE; - -- realmz = k5memdup0(realm->data, realm->length, &err); -- if (realmz == NULL) -+ realmstr = k5memdup0(realm->data, realm->length, &ret); -+ if (realmstr == NULL) - goto cleanup; - - /* Load the configured anchors. */ -- anchors[0] = KRB5_CONF_REALMS; -- anchors[1] = realmz; -- anchors[2] = KRB5_CONF_HTTP_ANCHORS; -- anchors[3] = NULL; -- if (profile_get_values(context->profile, anchors, &values) == 0) { -- for (i = 0; values[i] != NULL; i++) { -- err = load_http_anchor(sctx, values[i]); -- if (err != 0) -- break; -- } -- profile_free_list(values); -- } else { -- /* Use the library defaults. */ -- if (SSL_CTX_set_default_verify_paths(sctx) != 1) -- err = ENOENT; -- } -- --cleanup: -- free(realmz); -- return err; --} -- --static krb5_boolean --ssl_check_name_or_ip(X509 *x, const char *expected_name) --{ -- struct in_addr in; -- struct in6_addr in6; -- -- if (inet_aton(expected_name, &in) != 0 || -- inet_pton(AF_INET6, expected_name, &in6) != 0) { -- return k5_check_cert_address(x, expected_name); -- } else { -- return k5_check_cert_servername(x, expected_name); -- } --} -+ names[0] = KRB5_CONF_REALMS; -+ names[1] = realmstr; -+ names[2] = KRB5_CONF_HTTP_ANCHORS; -+ names[3] = NULL; -+ ret = profile_get_values(context->profile, names, &anchors); -+ if (ret != 0 && ret != PROF_NO_RELATION) -+ goto cleanup; - --static int --ssl_verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx) --{ -- X509 *x; -- SSL *ssl; -- BIO *bio; -- krb5_context context; -- int err, depth; -- struct conn_state *conn = NULL; -- const char *cert = NULL, *errstr, *expected_name; -- size_t count; -- -- ssl = X509_STORE_CTX_get_ex_data(store_ctx, -- SSL_get_ex_data_X509_STORE_CTX_idx()); -- context = SSL_get_ex_data(ssl, ssl_ex_context_id); -- conn = SSL_get_ex_data(ssl, ssl_ex_conn_id); -- /* We do have the peer's cert, right? */ -- x = X509_STORE_CTX_get_current_cert(store_ctx); -- if (x == NULL) { -- TRACE_SENDTO_KDC_HTTPS_NO_REMOTE_CERTIFICATE(context); -- return 0; -- } -- /* Figure out where we are. */ -- depth = X509_STORE_CTX_get_error_depth(store_ctx); -- if (depth < 0) -- return 0; -- /* If there's an error at this level that we're not ignoring, fail. */ -- err = X509_STORE_CTX_get_error(store_ctx); -- if (err != X509_V_OK) { -- bio = BIO_new(BIO_s_mem()); -- if (bio != NULL) { -- X509_NAME_print_ex(bio, x->cert_info->subject, 0, 0); -- count = BIO_get_mem_data(bio, &cert); -- errstr = X509_verify_cert_error_string(err); -- TRACE_SENDTO_KDC_HTTPS_PROXY_CERTIFICATE_ERROR(context, depth, -- count, cert, err, -- errstr); -- BIO_free(bio); -- } -- return 0; -- } -- /* If we're not looking at the peer, we're done and everything's ok. */ -- if (depth != 0) -- return 1; -- /* Check if the name we expect to find is in the certificate. */ -- expected_name = conn->http.servername; -- if (ssl_check_name_or_ip(x, expected_name)) { -- TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MATCH(context, expected_name); -- return 1; -- } else { -- TRACE_SENDTO_KDC_HTTPS_SERVER_NAME_MISMATCH(context, expected_name); -+ if (context->tls->setup(context, conn->fd, conn->http.servername, anchors, -+ &conn->http.tls) != 0) { -+ TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(context, &conn->addr); -+ goto cleanup; - } -- /* The name didn't match. */ -- return 0; --} - --/* -- * Set up structures that we use to manage the SSL handling for this connection -- * and apply any non-default settings. Kill the connection and return false if -- * anything goes wrong while we're doing that; return true otherwise. -- */ --static krb5_boolean --setup_ssl(krb5_context context, const krb5_data *realm, -- struct conn_state *conn, struct select_state *selstate) --{ -- int e; -- long options; -- SSL_CTX *ctx = NULL; -- SSL *ssl = NULL; -+ ok = TRUE; - -- if (ssl_ex_context_id == -1 || ssl_ex_conn_id == -1) -- goto kill_conn; -- -- /* Do general SSL library setup. */ -- ctx = SSL_CTX_new(SSLv23_client_method()); -- if (ctx == NULL) -- goto kill_conn; -- options = SSL_CTX_get_options(ctx); -- SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2); -- -- SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, ssl_verify_callback); -- X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0); -- e = load_http_verify_anchors(context, realm, ctx); -- if (e != 0) -- goto kill_conn; -- -- ssl = SSL_new(ctx); -- if (ssl == NULL) -- goto kill_conn; -- -- if (!SSL_set_ex_data(ssl, ssl_ex_context_id, context)) -- goto kill_conn; -- if (!SSL_set_ex_data(ssl, ssl_ex_conn_id, conn)) -- goto kill_conn; -- -- /* Tell the SSL library about the socket. */ -- if (!SSL_set_fd(ssl, conn->fd)) -- goto kill_conn; -- SSL_set_connect_state(ssl); -- -- SSL_CTX_free(ctx); -- conn->http.ssl = ssl; -- -- return TRUE; -- --kill_conn: -- TRACE_SENDTO_KDC_HTTPS_ERROR_CONNECT(context, &conn->addr); -- flush_ssl_errors(context); -- SSL_free(ssl); -- SSL_CTX_free(ctx); -- kill_conn(context, conn, selstate); -- return FALSE; -+cleanup: -+ free(realmstr); -+ profile_free_list(anchors); -+ return ok; - } - - /* Set conn->state to READING when done; otherwise, call a cm_set_. */ -@@ -1395,50 +1168,41 @@ static krb5_boolean - service_https_write(krb5_context context, const krb5_data *realm, - struct conn_state *conn, struct select_state *selstate) - { -- ssize_t nwritten; -- int e; -+ k5_tls_status st; - - /* If this is our first time in here, set up the SSL context. */ -- if (conn->http.ssl == NULL && !setup_ssl(context, realm, conn, selstate)) -+ if (conn->http.tls == NULL && !setup_tls(context, realm, conn, selstate)) { -+ kill_conn(context, conn, selstate); - return FALSE; -+ } - - /* Try to transmit our request to the server. */ -- nwritten = SSL_write(conn->http.ssl, SG_BUF(conn->out.sgp), -- SG_LEN(conn->out.sgbuf)); -- if (nwritten <= 0) { -- e = SSL_get_error(conn->http.ssl, nwritten); -- if (e == SSL_ERROR_WANT_READ) { -- cm_read(selstate, conn->fd); -- return FALSE; -- } else if (e == SSL_ERROR_WANT_WRITE) { -- cm_write(selstate, conn->fd); -- return FALSE; -- } -+ st = context->tls->write(context, conn->http.tls, SG_BUF(conn->out.sgp), -+ SG_LEN(conn->out.sgbuf)); -+ if (st == DONE) { -+ TRACE_SENDTO_KDC_HTTPS_SEND(context, &conn->addr); -+ cm_read(selstate, conn->fd); -+ conn->state = READING; -+ } else if (st == WANT_READ) { -+ cm_read(selstate, conn->fd); -+ } else if (st == WANT_WRITE) { -+ cm_write(selstate, conn->fd); -+ } else if (st == ERROR_TLS) { - TRACE_SENDTO_KDC_HTTPS_ERROR_SEND(context, &conn->addr); -- flush_ssl_errors(context); - kill_conn(context, conn, selstate); -- return FALSE; - } - -- /* Done writing, switch to reading. */ -- TRACE_SENDTO_KDC_HTTPS_SEND(context, &conn->addr); -- cm_read(selstate, conn->fd); -- conn->state = READING; - return FALSE; - } - --/* -- * Return true on readable data, call a cm_read/write function and return -- * false if the SSL layer needs it, kill the connection otherwise. -- */ -+/* Return true on finished data. Call a cm_read/write function and return -+ * false if the TLS layer needs it. Kill the connection on error. */ - static krb5_boolean - https_read_bytes(krb5_context context, struct conn_state *conn, - struct select_state *selstate) - { -- size_t bufsize; -- ssize_t nread; -- krb5_boolean readbytes = FALSE; -- int e = 0; -+ size_t bufsize, nread; -+ k5_tls_status st; - char *tmp; - struct incoming_message *in = &conn->in; - -@@ -1458,31 +1222,26 @@ https_read_bytes(krb5_context context, struct conn_state *conn, - in->bufsize = bufsize; - } - -- nread = SSL_read(conn->http.ssl, &in->buf[in->pos], -- in->bufsize - in->pos - 1); -- if (nread <= 0) -+ st = context->tls->read(context, conn->http.tls, &in->buf[in->pos], -+ in->bufsize - in->pos - 1, &nread); -+ if (st != DATA_READ) - break; -+ - in->pos += nread; - in->buf[in->pos] = '\0'; -- readbytes = TRUE; - } - -- e = SSL_get_error(conn->http.ssl, nread); -- if (e == SSL_ERROR_WANT_READ) { -+ if (st == DONE) -+ return TRUE; -+ -+ if (st == WANT_READ) { - cm_read(selstate, conn->fd); -- return FALSE; -- } else if (e == SSL_ERROR_WANT_WRITE) { -+ } else if (st == WANT_WRITE) { - cm_write(selstate, conn->fd); -- return FALSE; -- } else if ((e == SSL_ERROR_ZERO_RETURN) || -- (e == SSL_ERROR_SYSCALL && nread == 0 && readbytes)) { -- return TRUE; -+ } else if (st == ERROR_TLS) { -+ TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(context, &conn->addr); -+ kill_conn(context, conn, selstate); - } -- -- e = readbytes ? SOCKET_ERRNO : ECONNRESET; -- TRACE_SENDTO_KDC_HTTPS_ERROR_RECV(context, &conn->addr, e); -- flush_ssl_errors(context); -- kill_conn(context, conn, selstate); - return FALSE; - } - -@@ -1531,20 +1290,6 @@ kill_conn: - kill_conn(context, conn, selstate); - return FALSE; - } --#else --static krb5_boolean --service_https_write(krb5_context context, const krb5_data *realm, -- struct conn_state *conn, struct select_state *selstate) --{ -- abort(); --} --static krb5_boolean --service_https_read(krb5_context context, const krb5_data *realm, -- struct conn_state *conn, struct select_state *selstate) --{ -- abort(); --} --#endif - - /* Return the maximum of endtime and the endtime fields of all currently active - * TCP connections. */ -@@ -1765,7 +1510,7 @@ cleanup: - if (socktype_for_transport(state->addr.transport) == SOCK_STREAM) - TRACE_SENDTO_KDC_TCP_DISCONNECT(context, &state->addr); - closesocket(state->fd); -- free_http_ssl_data(state); -+ free_http_tls_data(context, state); - } - if (state->state == READING && state->in.buf != udpbuf) - free(state->in.buf); -diff --git a/src/plugins/tls/k5tls/Makefile.in b/src/plugins/tls/k5tls/Makefile.in -new file mode 100644 -index 0000000..4d58df0 ---- /dev/null -+++ b/src/plugins/tls/k5tls/Makefile.in -@@ -0,0 +1,22 @@ -+mydir=plugins$(S)tls$(S)k5tls -+BUILDTOP=$(REL)..$(S)..$(S).. -+MODULE_INSTALL_DIR = $(KRB5_TLS_MODULE_DIR) -+LOCALINCLUDES= $(PROXY_TLS_IMPL_CFLAGS) -+ -+LIBBASE=k5tls -+LIBMAJOR=0 -+LIBMINOR=0 -+RELDIR=../plugins/tls/k5tls -+SHLIB_EXPDEPS= $(KRB5_DEPLIB) $(SUPPORT_DEPLIB) -+SHLIB_EXPLIBS= $(KRB5_LIB) $(SUPPORT_LIB) $(PROXY_TLS_IMPL_LIBS) -+ -+STLIBOBJS=openssl.o notls.o -+ -+SRCS=$(srcdir)/openssl.c $(srcdir)/notls.c -+ -+all-unix:: all-liblinks -+install-unix:: install-libs -+clean-unix:: clean-libs clean-libobjs -+ -+@libnover_frag@ -+@libobj_frag@ -diff --git a/src/plugins/tls/k5tls/deps b/src/plugins/tls/k5tls/deps -new file mode 100644 -index 0000000..a6088a7 ---- /dev/null -+++ b/src/plugins/tls/k5tls/deps -@@ -0,0 +1,25 @@ -+# -+# Generated makefile dependencies follow. -+# -+openssl.so openssl.po $(OUTPRE)openssl.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ -+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ -+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ -+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ -+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ -+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ -+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-tls.h \ -+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \ -+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ -+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ -+ $(top_srcdir)/include/socket-utils.h openssl.c -+notls.so notls.po $(OUTPRE)notls.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ -+ $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \ -+ $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \ -+ $(top_srcdir)/include/k5-err.h $(top_srcdir)/include/k5-gmt_mktime.h \ -+ $(top_srcdir)/include/k5-int-pkinit.h $(top_srcdir)/include/k5-int.h \ -+ $(top_srcdir)/include/k5-platform.h $(top_srcdir)/include/k5-plugin.h \ -+ $(top_srcdir)/include/k5-thread.h $(top_srcdir)/include/k5-tls.h \ -+ $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/k5-utf8.h \ -+ $(top_srcdir)/include/krb5.h $(top_srcdir)/include/krb5/authdata_plugin.h \ -+ $(top_srcdir)/include/krb5/plugin.h $(top_srcdir)/include/port-sockets.h \ -+ $(top_srcdir)/include/socket-utils.h notls.c -diff --git a/src/plugins/tls/k5tls/k5tls.exports b/src/plugins/tls/k5tls/k5tls.exports -new file mode 100644 -index 0000000..d67d928 ---- /dev/null -+++ b/src/plugins/tls/k5tls/k5tls.exports -@@ -0,0 +1 @@ -+tls_k5tls_initvt -diff --git a/src/plugins/tls/k5tls/notls.c b/src/plugins/tls/k5tls/notls.c -new file mode 100644 -index 0000000..7be0a4a ---- /dev/null -+++ b/src/plugins/tls/k5tls/notls.c -@@ -0,0 +1,53 @@ -+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -+/* plus/tls/k5tls/none.c - Stub TLS module implementation */ -+/* -+ * Copyright (C) 2014 by the Massachusetts Institute of Technology. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -+ * OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+/* This dummy module is used if no TLS implemented is selected. */ -+ -+#include "k5-int.h" -+#include "k5-utf8.h" -+#include "k5-tls.h" -+ -+#ifdef PROXY_TLS_IMPL_NONE -+ -+krb5_error_code -+tls_k5tls_initvt(krb5_context context, int maj_ver, int min_ver, -+ krb5_plugin_vtable vtable); -+ -+krb5_error_code -+tls_k5tls_initvt(krb5_context context, int maj_ver, int min_ver, -+ krb5_plugin_vtable vtable) -+{ -+ /* Leave all vtable functions nulled. */ -+ return 0; -+} -+ -+#endif /* PROXY_TLS_IMPL_NONE */ -diff --git a/src/plugins/tls/k5tls/openssl.c b/src/plugins/tls/k5tls/openssl.c -new file mode 100644 -index 0000000..0691a34 ---- /dev/null -+++ b/src/plugins/tls/k5tls/openssl.c -@@ -0,0 +1,570 @@ -+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -+/* plugins/tls/k5tls/openssl.c - OpenSSL TLS module implementation */ -+/* -+ * Copyright 2013,2014 Red Hat, Inc. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 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. -+ */ -+ -+#include "k5-int.h" -+#include "k5-utf8.h" -+#include "k5-tls.h" -+ -+#ifdef PROXY_TLS_IMPL_OPENSSL -+#include -+#include -+#include -+#include -+#include -+ -+struct k5_tls_handle_st { -+ SSL *ssl; -+ char *servername; -+}; -+ -+static int ex_context_id = -1; -+static int ex_handle_id = -1; -+ -+MAKE_INIT_FUNCTION(init_openssl); -+ -+int -+init_openssl() -+{ -+ SSL_library_init(); -+ SSL_load_error_strings(); -+ OpenSSL_add_all_algorithms(); -+ ex_context_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); -+ ex_handle_id = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); -+ return 0; -+} -+ -+static void -+flush_errors(krb5_context context) -+{ -+ unsigned long err; -+ char buf[128]; -+ -+ while ((err = ERR_get_error()) != 0) { -+ ERR_error_string_n(err, buf, sizeof(buf)); -+ TRACE_TLS_ERROR(context, buf); -+ } -+} -+ -+/* Return the passed-in character, lower-cased if it's an ASCII character. */ -+static inline char -+ascii_tolower(char p) -+{ -+ if (KRB5_UPPER(p)) -+ return p + ('a' - 'A'); -+ return p; -+} -+ -+/* -+ * Check a single label. If allow_wildcard is true, and the presented name -+ * includes a wildcard, return true and note that we matched a wildcard. -+ * Otherwise, for both the presented and expected values, do a case-insensitive -+ * comparison of ASCII characters, and a case-sensitive comparison of -+ * everything else. -+ */ -+static krb5_boolean -+label_match(const char *presented, size_t plen, const char *expected, -+ size_t elen, krb5_boolean allow_wildcard, krb5_boolean *wildcard) -+{ -+ unsigned int i; -+ -+ if (allow_wildcard && plen == 1 && presented[0] == '*') { -+ *wildcard = TRUE; -+ return TRUE; -+ } -+ -+ if (plen != elen) -+ return FALSE; -+ -+ for (i = 0; i < elen; i++) { -+ if (ascii_tolower(presented[i]) != ascii_tolower(expected[i])) -+ return FALSE; -+ } -+ return TRUE; -+} -+ -+/* Break up the two names and check them, label by label. */ -+static krb5_boolean -+domain_match(const char *presented, size_t plen, const char *expected) -+{ -+ const char *p, *q, *r, *s; -+ int n_label; -+ krb5_boolean used_wildcard = FALSE; -+ -+ n_label = 0; -+ p = presented; -+ r = expected; -+ while (p < presented + plen && *r != '\0') { -+ q = memchr(p, '.', plen - (p - presented)); -+ if (q == NULL) -+ q = presented + plen; -+ s = r + strcspn(r, "."); -+ if (!label_match(p, q - p, r, s - r, n_label == 0, &used_wildcard)) -+ return FALSE; -+ p = q < presented + plen ? q + 1 : q; -+ r = *s ? s + 1 : s; -+ n_label++; -+ } -+ if (used_wildcard && n_label <= 2) -+ return FALSE; -+ if (p == presented + plen && *r == '\0') -+ return TRUE; -+ return FALSE; -+} -+ -+/* Fetch the list of subjectAltNames from a certificate. */ -+static GENERAL_NAMES * -+get_cert_sans(X509 *x) -+{ -+ int ext; -+ X509_EXTENSION *san_ext; -+ -+ ext = X509_get_ext_by_NID(x, NID_subject_alt_name, -1); -+ if (ext < 0) -+ return NULL; -+ san_ext = X509_get_ext(x, ext); -+ if (san_ext == NULL) -+ return NULL; -+ return X509V3_EXT_d2i(san_ext); -+} -+ -+/* Fetch a CN value from the subjct name field, returning its length, or -1 if -+ * there is no subject name or it contains no CN value. */ -+static int -+get_cert_cn(X509 *x, char *buf, size_t bufsize) -+{ -+ X509_NAME *name; -+ -+ name = X509_get_subject_name(x); -+ if (name == NULL) -+ return -1; -+ return X509_NAME_get_text_by_NID(name, NID_commonName, buf, bufsize); -+} -+ -+/* Return true if text matches any of the addresses we can recover from x. */ -+static krb5_boolean -+check_cert_address(X509 *x, const char *text) -+{ -+ char buf[1024]; -+ GENERAL_NAMES *sans; -+ GENERAL_NAME *san = NULL; -+ ASN1_OCTET_STRING *ip; -+ krb5_boolean found_ip_san = FALSE, matched = FALSE; -+ int n_sans, i; -+ int name_length; -+ struct in_addr sin; -+ struct in6_addr sin6; -+ -+ /* Parse the IP address into an octet string. */ -+ ip = M_ASN1_OCTET_STRING_new(); -+ if (ip == NULL) -+ return FALSE; -+ if (inet_pton(AF_INET, text, &sin)) { -+ M_ASN1_OCTET_STRING_set(ip, &sin, sizeof(sin)); -+ } else if (inet_pton(AF_INET6, text, &sin6)) { -+ M_ASN1_OCTET_STRING_set(ip, &sin6, sizeof(sin6)); -+ } else { -+ ASN1_OCTET_STRING_free(ip); -+ return FALSE; -+ } -+ -+ /* Check for matches in ipaddress subjectAltName values. */ -+ sans = get_cert_sans(x); -+ if (sans != NULL) { -+ n_sans = sk_GENERAL_NAME_num(sans); -+ for (i = 0; i < n_sans; i++) { -+ san = sk_GENERAL_NAME_value(sans, i); -+ if (san->type != GEN_IPADD) -+ continue; -+ found_ip_san = TRUE; -+ matched = (ASN1_OCTET_STRING_cmp(ip, san->d.iPAddress) == 0); -+ if (matched) -+ break; -+ } -+ sk_GENERAL_NAME_pop_free(sans, GENERAL_NAME_free); -+ } -+ ASN1_OCTET_STRING_free(ip); -+ -+ if (found_ip_san) -+ return matched; -+ -+ /* Check for a match against the CN value in the peer's subject name. */ -+ name_length = get_cert_cn(x, buf, sizeof(buf)); -+ if (name_length >= 0) { -+ /* Do a string compare to check if it's an acceptable value. */ -+ return strlen(text) == (size_t)name_length && -+ strncmp(text, buf, name_length) == 0; -+ } -+ -+ /* We didn't find a match. */ -+ return FALSE; -+} -+ -+/* Return true if expected matches any of the names we can recover from x. */ -+static krb5_boolean -+check_cert_servername(X509 *x, const char *expected) -+{ -+ char buf[1024]; -+ GENERAL_NAMES *sans; -+ GENERAL_NAME *san = NULL; -+ unsigned char *dnsname; -+ krb5_boolean found_dns_san = FALSE, matched = FALSE; -+ int name_length, n_sans, i; -+ -+ /* Check for matches in dnsname subjectAltName values. */ -+ sans = get_cert_sans(x); -+ if (sans != NULL) { -+ n_sans = sk_GENERAL_NAME_num(sans); -+ for (i = 0; i < n_sans; i++) { -+ san = sk_GENERAL_NAME_value(sans, i); -+ if (san->type != GEN_DNS) -+ continue; -+ found_dns_san = TRUE; -+ dnsname = NULL; -+ name_length = ASN1_STRING_to_UTF8(&dnsname, san->d.dNSName); -+ if (dnsname == NULL) -+ continue; -+ matched = domain_match((char *)dnsname, name_length, expected); -+ OPENSSL_free(dnsname); -+ if (matched) -+ break; -+ } -+ sk_GENERAL_NAME_pop_free(sans, GENERAL_NAME_free); -+ } -+ -+ if (matched) -+ return TRUE; -+ if (found_dns_san) -+ return matched; -+ -+ /* Check for a match against the CN value in the peer's subject name. */ -+ name_length = get_cert_cn(x, buf, sizeof(buf)); -+ if (name_length >= 0) -+ return domain_match(buf, name_length, expected); -+ -+ /* We didn't find a match. */ -+ return FALSE; -+} -+ -+static krb5_boolean -+check_cert_name_or_ip(X509 *x, const char *expected_name) -+{ -+ struct in_addr in; -+ struct in6_addr in6; -+ -+ if (inet_pton(AF_INET, expected_name, &in) != 0 || -+ inet_pton(AF_INET6, expected_name, &in6) != 0) { -+ return check_cert_address(x, expected_name); -+ } else { -+ return check_cert_servername(x, expected_name); -+ } -+} -+ -+static int -+verify_callback(int preverify_ok, X509_STORE_CTX *store_ctx) -+{ -+ X509 *x; -+ SSL *ssl; -+ BIO *bio; -+ krb5_context context; -+ int err, depth; -+ k5_tls_handle handle; -+ const char *cert = NULL, *errstr, *expected_name; -+ size_t count; -+ -+ ssl = X509_STORE_CTX_get_ex_data(store_ctx, -+ SSL_get_ex_data_X509_STORE_CTX_idx()); -+ context = SSL_get_ex_data(ssl, ex_context_id); -+ handle = SSL_get_ex_data(ssl, ex_handle_id); -+ assert(context != NULL && handle != NULL); -+ /* We do have the peer's cert, right? */ -+ x = X509_STORE_CTX_get_current_cert(store_ctx); -+ if (x == NULL) { -+ TRACE_TLS_NO_REMOTE_CERTIFICATE(context); -+ return 0; -+ } -+ /* Figure out where we are. */ -+ depth = X509_STORE_CTX_get_error_depth(store_ctx); -+ if (depth < 0) -+ return 0; -+ /* If there's an error at this level that we're not ignoring, fail. */ -+ err = X509_STORE_CTX_get_error(store_ctx); -+ if (err != X509_V_OK) { -+ bio = BIO_new(BIO_s_mem()); -+ if (bio != NULL) { -+ X509_NAME_print_ex(bio, x->cert_info->subject, 0, 0); -+ count = BIO_get_mem_data(bio, &cert); -+ errstr = X509_verify_cert_error_string(err); -+ TRACE_TLS_CERT_ERROR(context, depth, count, cert, err, errstr); -+ BIO_free(bio); -+ } -+ return 0; -+ } -+ /* If we're not looking at the peer, we're done and everything's ok. */ -+ if (depth != 0) -+ return 1; -+ /* Check if the name we expect to find is in the certificate. */ -+ expected_name = handle->servername; -+ if (check_cert_name_or_ip(x, expected_name)) { -+ TRACE_TLS_SERVER_NAME_MATCH(context, expected_name); -+ return 1; -+ } else { -+ TRACE_TLS_SERVER_NAME_MISMATCH(context, expected_name); -+ } -+ /* The name didn't match. */ -+ return 0; -+} -+ -+static krb5_error_code -+load_anchor_file(X509_STORE *store, const char *path) -+{ -+ FILE *fp; -+ STACK_OF(X509_INFO) *sk = NULL; -+ X509_INFO *xi; -+ int i; -+ -+ fp = fopen(path, "r"); -+ if (fp == NULL) -+ return errno; -+ sk = PEM_X509_INFO_read(fp, NULL, NULL, NULL); -+ fclose(fp); -+ if (sk == NULL) -+ return ENOENT; -+ for (i = 0; i < sk_X509_INFO_num(sk); i++) { -+ xi = sk_X509_INFO_value(sk, i); -+ if (xi->x509 != NULL) -+ X509_STORE_add_cert(store, xi->x509); -+ } -+ sk_X509_INFO_pop_free(sk, X509_INFO_free); -+ return 0; -+} -+ -+static krb5_error_code -+load_anchor_dir(X509_STORE *store, const char *path) -+{ -+ DIR *d = NULL; -+ struct dirent *dentry = NULL; -+ char filename[1024]; -+ krb5_boolean found_any = FALSE; -+ -+ d = opendir(path); -+ if (d == NULL) -+ return ENOENT; -+ while ((dentry = readdir(d)) != NULL) { -+ if (dentry->d_name[0] != '.') { -+ snprintf(filename, sizeof(filename), "%s/%s", -+ path, dentry->d_name); -+ if (load_anchor_file(store, filename) == 0) -+ found_any = TRUE; -+ } -+ } -+ closedir(d); -+ return found_any ? 0 : ENOENT; -+} -+ -+static krb5_error_code -+load_anchor(SSL_CTX *ctx, const char *location) -+{ -+ X509_STORE *store; -+ const char *envloc; -+ -+ store = SSL_CTX_get_cert_store(ctx); -+ if (strncmp(location, "FILE:", 5) == 0) { -+ return load_anchor_file(store, location + 5); -+ } else if (strncmp(location, "DIR:", 4) == 0) { -+ return load_anchor_dir(store, location + 4); -+ } else if (strncmp(location, "ENV:", 4) == 0) { -+ envloc = getenv(location + 4); -+ if (envloc == NULL) -+ return ENOENT; -+ return load_anchor(ctx, envloc); -+ } -+ return EINVAL; -+} -+ -+static krb5_error_code -+load_anchors(krb5_context context, char **anchors, SSL_CTX *sctx) -+{ -+ unsigned int i; -+ krb5_error_code ret; -+ -+ if (anchors != NULL) { -+ for (i = 0; anchors[i] != NULL; i++) { -+ ret = load_anchor(sctx, anchors[i]); -+ if (ret) -+ return ret; -+ } -+ } else { -+ /* Use the library defaults. */ -+ if (SSL_CTX_set_default_verify_paths(sctx) != 1) -+ return ENOENT; -+ } -+ -+ return 0; -+} -+ -+static krb5_error_code -+setup(krb5_context context, SOCKET fd, const char *servername, -+ char **anchors, k5_tls_handle *handle_out) -+{ -+ int e; -+ long options; -+ SSL_CTX *ctx = NULL; -+ SSL *ssl = NULL; -+ k5_tls_handle handle = NULL; -+ -+ *handle_out = NULL; -+ -+ (void)CALL_INIT_FUNCTION(init_openssl); -+ if (ex_context_id == -1 || ex_handle_id == -1) -+ return KRB5_PLUGIN_OP_NOTSUPP; -+ -+ /* Do general SSL library setup. */ -+ ctx = SSL_CTX_new(SSLv23_client_method()); -+ if (ctx == NULL) -+ goto error; -+ options = SSL_CTX_get_options(ctx); -+ SSL_CTX_set_options(ctx, options | SSL_OP_NO_SSLv2); -+ -+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback); -+ X509_STORE_set_flags(SSL_CTX_get_cert_store(ctx), 0); -+ e = load_anchors(context, anchors, ctx); -+ if (e != 0) -+ goto error; -+ -+ ssl = SSL_new(ctx); -+ if (ssl == NULL) -+ goto error; -+ -+ if (!SSL_set_fd(ssl, fd)) -+ goto error; -+ SSL_set_connect_state(ssl); -+ -+ /* Create a handle and allow verify_callback to access it. */ -+ handle = malloc(sizeof(*handle)); -+ if (handle == NULL || !SSL_set_ex_data(ssl, ex_handle_id, handle)) -+ goto error; -+ -+ handle->ssl = ssl; -+ handle->servername = strdup(servername); -+ if (handle->servername == NULL) -+ goto error; -+ *handle_out = handle; -+ SSL_CTX_free(ctx); -+ return 0; -+ -+error: -+ flush_errors(context); -+ free(handle); -+ SSL_free(ssl); -+ SSL_CTX_free(ctx); -+ return KRB5_PLUGIN_OP_NOTSUPP; -+} -+ -+static k5_tls_status -+write_tls(krb5_context context, k5_tls_handle handle, const void *data, -+ size_t len) -+{ -+ int nwritten, e; -+ -+ /* Try to transmit our request; allow verify_callback to access context. */ -+ if (!SSL_set_ex_data(handle->ssl, ex_context_id, context)) -+ return ERROR_TLS; -+ nwritten = SSL_write(handle->ssl, data, len); -+ (void)SSL_set_ex_data(handle->ssl, ex_context_id, NULL); -+ if (nwritten > 0) -+ return DONE; -+ -+ e = SSL_get_error(handle->ssl, nwritten); -+ if (e == SSL_ERROR_WANT_READ) -+ return WANT_READ; -+ else if (e == SSL_ERROR_WANT_WRITE) -+ return WANT_WRITE; -+ flush_errors(context); -+ return ERROR_TLS; -+} -+ -+static k5_tls_status -+read_tls(krb5_context context, k5_tls_handle handle, void *data, -+ size_t data_size, size_t *len_out) -+{ -+ ssize_t nread; -+ int e; -+ -+ *len_out = 0; -+ -+ /* Try to read response data; allow verify_callback to access context. */ -+ if (!SSL_set_ex_data(handle->ssl, ex_context_id, context)) -+ return ERROR_TLS; -+ nread = SSL_read(handle->ssl, data, data_size); -+ (void)SSL_set_ex_data(handle->ssl, ex_context_id, NULL); -+ if (nread > 0) { -+ *len_out = nread; -+ return DATA_READ; -+ } -+ -+ e = SSL_get_error(handle->ssl, nread); -+ if (e == SSL_ERROR_WANT_READ) -+ return WANT_READ; -+ else if (e == SSL_ERROR_WANT_WRITE) -+ return WANT_WRITE; -+ -+ if (e == SSL_ERROR_ZERO_RETURN || (e == SSL_ERROR_SYSCALL && nread == 0)) -+ return DONE; -+ -+ flush_errors(context); -+ return ERROR_TLS; -+} -+ -+static void -+free_handle(krb5_context context, k5_tls_handle handle) -+{ -+ SSL_free(handle->ssl); -+ free(handle->servername); -+ free(handle); -+} -+ -+krb5_error_code -+tls_k5tls_initvt(krb5_context context, int maj_ver, int min_ver, -+ krb5_plugin_vtable vtable); -+ -+krb5_error_code -+tls_k5tls_initvt(krb5_context context, int maj_ver, int min_ver, -+ krb5_plugin_vtable vtable) -+{ -+ k5_tls_vtable vt; -+ -+ vt = (k5_tls_vtable)vtable; -+ vt->setup = setup; -+ vt->write = write_tls; -+ vt->read = read_tls; -+ vt->free_handle = free_handle; -+ return 0; -+} -+ -+#endif /* PROXY_TLS_IMPL_OPENSSL */ diff --git a/SOURCES/krb5-1.13-dirsrv-accountlock.patch b/SOURCES/krb5-1.13-dirsrv-accountlock.patch new file mode 100644 index 0000000..0a6661c --- /dev/null +++ b/SOURCES/krb5-1.13-dirsrv-accountlock.patch @@ -0,0 +1,63 @@ +Treat 'nsAccountLock: true' the same as 'loginDisabled: true'. Updated from +original version filed as RT#5891. + +diff -up krb5-1.8/src/aclocal.m4.dirsrv-accountlock krb5-1.8/src/aclocal.m4 +--- krb5-1.8/src/aclocal.m4.dirsrv-accountlock 2010-03-05 11:03:09.000000000 -0500 ++++ krb5-1.8/src/aclocal.m4 2010-03-05 11:03:10.000000000 -0500 +@@ -1656,6 +1656,15 @@ if test $with_ldap = yes; then + AC_MSG_NOTICE(enabling OpenLDAP database backend module support) + OPENLDAP_PLUGIN=yes + fi ++AC_ARG_WITH([dirsrv-account-locking], ++[ --with-dirsrv-account-locking compile 389/Red Hat/Fedora/Netscape Directory Server database backend module], ++[case "$withval" in ++ yes | no) ;; ++ *) AC_MSG_ERROR(Invalid option value --with-dirsrv-account-locking="$withval") ;; ++esac], with_dirsrv_account_locking=no) ++if test $with_dirsrv_account_locking = yes; then ++ AC_DEFINE(HAVE_DIRSRV_ACCOUNT_LOCKING,1,[Define if LDAP KDB interface should heed 389 DS's nsAccountLock attribute.]) ++fi + ])dnl + dnl + dnl If libkeyutils exists (on Linux) include it and use keyring ccache +diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +--- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock 2009-11-24 18:52:25.000000000 -0500 ++++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c 2010-03-05 11:03:10.000000000 -0500 +@@ -1546,6 +1546,23 @@ populate_krb5_db_entry(krb5_context cont + ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data); + if (ret) + goto cleanup; ++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING ++ { ++ krb5_timestamp expiretime=0; ++ char *is_login_disabled=NULL; ++ ++ /* LOGIN DISABLED */ ++ ret = krb5_ldap_get_string(ld, ent, "nsAccountLock", &is_login_disabled, ++ &attr_present); ++ if (ret) ++ goto cleanup; ++ if (attr_present == TRUE) { ++ if (strcasecmp(is_login_disabled, "TRUE")== 0) ++ entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX; ++ free (is_login_disabled); ++ } ++ } ++#endif + + ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname); + if (ret) + goto cleanup; +diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c +--- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock 2009-11-24 18:52:25.000000000 -0500 ++++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c 2010-03-05 11:03:10.000000000 -0500 +@@ -59,6 +59,9 @@ char *principal_attributes[] = { "kr + "krbLastFailedAuth", + "krbLoginFailedCount", + "krbLastSuccessfulAuth", ++#ifdef HAVE_DIRSRV_ACCOUNT_LOCKING ++ "nsAccountLock", ++#endif + "krbLastPwdChange", + "krbLastAdminUnlock", + "krbExtraData", diff --git a/SOURCES/krb5-1.13-selinux-label.patch b/SOURCES/krb5-1.13-selinux-label.patch new file mode 100644 index 0000000..1cd86c0 --- /dev/null +++ b/SOURCES/krb5-1.13-selinux-label.patch @@ -0,0 +1,979 @@ +SELinux bases access to files on the domain of the requesting process, +the operation being performed, and the context applied to the file. + +In many cases, applications needn't be SELinux aware to work properly, +because SELinux can apply a default label to a file based on the label +of the directory in which it's created. + +In the case of files such as /etc/krb5.keytab, however, this isn't +sufficient, as /etc/krb5.keytab will almost always need to be given a +label which differs from that of /etc/issue or /etc/resolv.conf. The +the kdb stash file needs a different label than the database for which +it's holding a master key, even though both typically live in the same +directory. + +To give the file the correct label, we can either force a "restorecon" +call to fix a file's label after it's created, or create the file with +the right label, as we attempt to do here. We lean on THREEPARAMOPEN +and define a similar macro named WRITABLEFOPEN with which we replace +several uses of fopen(). + +The file creation context that we're manipulating here is a process-wide +attribute. While for the most part, applications which need to label +files when they're created have tended to be single-threaded, there's +not much we can do to avoid interfering with an application that +manipulates the creation context directly. Right now we're mediating +access using a library-local mutex, but that can only work for consumers +that are part of this package -- an unsuspecting application will still +stomp all over us. + +The selabel APIs for looking up the context should be thread-safe (per +Red Hat #273081), so switching to using them instead of matchpathcon(), +which we used earlier, is some improvement. + +--- krb5/src/aclocal.m4 ++++ krb5/src/aclocal.m4 +@@ -103,6 +103,7 @@ AC_SUBST_FILE(libnodeps_frag) + dnl + KRB5_AC_PRAGMA_WEAK_REF + WITH_LDAP ++KRB5_WITH_SELINUX + KRB5_LIB_PARAMS + KRB5_AC_INITFINI + KRB5_AC_ENABLE_THREADS +@@ -1791,3 +1792,51 @@ AC_SUBST(manlocalstatedir) + AC_SUBST(PAM_MAN) + AC_SUBST(NON_PAM_MAN) + ])dnl ++dnl ++dnl Use libselinux to set file contexts on newly-created files. ++dnl ++AC_DEFUN(KRB5_WITH_SELINUX,[ ++AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])], ++ withselinux="$withval",withselinux=auto) ++old_LIBS="$LIBS" ++if test "$withselinux" != no ; then ++ AC_MSG_RESULT([checking for libselinux...]) ++ SELINUX_LIBS= ++ AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h) ++ if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then ++ if test "$withselinux" = auto ; then ++ AC_MSG_RESULT([Unable to locate selinux/selinux.h.]) ++ withselinux=no ++ else ++ AC_MSG_ERROR([Unable to locate selinux/selinux.h.]) ++ fi ++ fi ++ ++ LIBS= ++ unset ac_cv_func_setfscreatecon ++ AC_CHECK_FUNCS(setfscreatecon selabel_open) ++ if test "x$ac_cv_func_setfscreatecon" = xno ; then ++ AC_CHECK_LIB(selinux,setfscreatecon) ++ unset ac_cv_func_setfscreatecon ++ AC_CHECK_FUNCS(setfscreatecon selabel_open) ++ if test "x$ac_cv_func_setfscreatecon" = xyes ; then ++ SELINUX_LIBS="$LIBS" ++ else ++ if test "$withselinux" = auto ; then ++ AC_MSG_RESULT([Unable to locate libselinux.]) ++ withselinux=no ++ else ++ AC_MSG_ERROR([Unable to locate libselinux.]) ++ fi ++ fi ++ fi ++ if test "$withselinux" != no ; then ++ AC_MSG_NOTICE([building with SELinux labeling support]) ++ AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.]) ++ SELINUX_LIBS="$LIBS" ++ EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon" ++ fi ++fi ++LIBS="$old_LIBS" ++AC_SUBST(SELINUX_LIBS) ++])dnl +--- krb5/src/config/pre.in ++++ krb5/src/config/pre.in +@@ -180,6 +180,7 @@ LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@ + KRB_INCLUDES = -I$(BUILDTOP)/include -I$(top_srcdir)/include + LDFLAGS = @LDFLAGS@ + LIBS = @LIBS@ ++SELINUX_LIBS=@SELINUX_LIBS@ + + INSTALL=@INSTALL@ + INSTALL_STRIP= +@@ -379,7 +380,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME) + # HESIOD_LIBS is -lhesiod... + HESIOD_LIBS = @HESIOD_LIBS@ + +-KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB) ++KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB) + KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS) + GSS_LIBS = $(GSS_KRB5_LIB) + # needs fixing if ever used on Mac OS X! +--- krb5/src/configure.in ++++ krb5/src/configure.in +@@ -1053,6 +1053,8 @@ fi + + KRB5_WITH_PAM + ++KRB5_WITH_SELINUX ++ + # Make localedir work in autoconf 2.5x. + if test "${localedir+set}" != set; then + localedir='$(datadir)/locale' +--- krb5/src/include/k5-int.h ++++ krb5/src/include/k5-int.h +@@ -129,6 +129,7 @@ typedef unsigned char u_char; + + + #include "k5-platform.h" ++#include "k5-label.h" + + #define KRB5_KDB_MAX_LIFE (60*60*24) /* one day */ + #define KRB5_KDB_MAX_RLIFE (60*60*24*7) /* one week */ +--- krb5/src/include/k5-label.h ++++ krb5/src/include/k5-label.h +@@ -0,0 +1,32 @@ ++#ifndef _KRB5_LABEL_H ++#define _KRB5_LABEL_H ++ ++#ifdef THREEPARAMOPEN ++#undef THREEPARAMOPEN ++#endif ++#ifdef WRITABLEFOPEN ++#undef WRITABLEFOPEN ++#endif ++ ++/* Wrapper functions which help us create files and directories with the right ++ * context labels. */ ++#ifdef USE_SELINUX ++#include ++#include ++#include ++#include ++#include ++FILE *krb5int_labeled_fopen(const char *path, const char *mode); ++int krb5int_labeled_creat(const char *path, mode_t mode); ++int krb5int_labeled_open(const char *path, int flags, ...); ++int krb5int_labeled_mkdir(const char *path, mode_t mode); ++int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device); ++#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z) ++#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y) ++void *krb5int_push_fscreatecon_for(const char *pathname); ++void krb5int_pop_fscreatecon(void *previous); ++#else ++#define WRITABLEFOPEN(x,y) fopen(x,y) ++#define THREEPARAMOPEN(x,y,z) open(x,y,z) ++#endif ++#endif +--- krb5/src/include/krb5/krb5.hin ++++ krb5/src/include/krb5/krb5.hin +@@ -87,6 +87,12 @@ + #define THREEPARAMOPEN(x,y,z) open(x,y,z) + #endif + ++#if KRB5_PRIVATE ++#ifndef WRITABLEFOPEN ++#define WRITABLEFOPEN(x,y) fopen(x,y) ++#endif ++#endif ++ + #define KRB5_OLD_CRYPTO + + #include +--- krb5/src/kadmin/dbutil/dump.c ++++ krb5/src/kadmin/dbutil/dump.c +@@ -376,12 +376,21 @@ create_ofile(char *ofile, char **tmpname + { + int fd = -1; + FILE *f; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + *tmpname = NULL; + if (asprintf(tmpname, "%s-XXXXXX", ofile) < 0) + goto error; + ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(ofile); ++#endif + fd = mkstemp(*tmpname); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (fd == -1) + goto error; + +@@ -514,7 +514,7 @@ prep_ok_file(krb5_context context, char + return 0; + } + +- *fd = open(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); ++ *fd = THREEPARAMOPEN(file_ok, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (*fd == -1) { + com_err(progname, errno, _("while creating 'ok' file, '%s'"), file_ok); + exit_status++; +--- krb5/src/build-tools/krb5-config.in ++++ krb5/src/build-tools/krb5-config.in +@@ -38,6 +38,7 @@ RPATH_FLAG='@RPATH_FLAG@' + DEFCCNAME='@DEFCCNAME@' + DEFKTNAME='@DEFKTNAME@' + DEFCKTNAME='@DEFCKTNAME@' ++SELINUX_LIBS='@SELINUX_LIBS@' + + LIBS='@LIBS@' + GEN_LIB=@GEN_LIB@ +@@ -218,7 +219,7 @@ + fi + + # If we ever support a flag to generate output suitable for static +- # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB" ++ # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB" + # here. + + echo $lib_flags +--- krb5/src/lib/kadm5/logger.c ++++ krb5/src/lib/kadm5/logger.c +@@ -425,7 +425,7 @@ krb5_klog_init(krb5_context kcontext, ch + * Check for append/overwrite, then open the file. + */ + if (cp[4] == ':' || cp[4] == '=') { +- f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w"); ++ f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w"); + if (f) { + set_cloexec_file(f); + log_control.log_entries[i].lfu_filep = f; +@@ -961,7 +961,7 @@ krb5_klog_reopen(krb5_context kcontext) + * In case the old logfile did not get moved out of the + * way, open for append to prevent squashing the old logs. + */ +- f = fopen(log_control.log_entries[lindex].lfu_fname, "a+"); ++ f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+"); + if (f) { + set_cloexec_file(f); + log_control.log_entries[lindex].lfu_filep = f; +--- krb5/src/lib/krb5/keytab/kt_file.c ++++ krb5/src/lib/krb5/keytab/kt_file.c +@@ -1050,7 +1050,7 @@ krb5_ktfileint_open(krb5_context context + + KTCHECKLOCK(id); + errno = 0; +- KTFILEP(id) = fopen(KTFILENAME(id), ++ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), + (mode == KRB5_LOCKMODE_EXCLUSIVE) ? + fopen_mode_rbplus : fopen_mode_rb); + if (!KTFILEP(id)) { +@@ -1058,7 +1058,7 @@ krb5_ktfileint_open(krb5_context context + /* try making it first time around */ + k5_create_secure_file(context, KTFILENAME(id)); + errno = 0; +- KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus); ++ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus); + if (!KTFILEP(id)) + goto report_errno; + writevno = 1; +--- krb5/src/plugins/kdb/db2/adb_openclose.c ++++ krb5/src/plugins/kdb/db2/adb_openclose.c +@@ -201,7 +201,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char + * POSIX systems + */ + lockp->lockinfo.filename = strdup(lockfilename); +- if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) { ++ if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) { + /* + * maybe someone took away write permission so we could only + * get shared locks? +--- krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c ++++ krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c +@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8. + #include + #include + ++#include "k5-int.h" + #include "db-int.h" + #include "btree.h" + +@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo, + goto einval; + } + +- if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0) ++ if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) + goto err; + + } else { +--- krb5/src/plugins/kdb/db2/libdb2/hash/hash.c ++++ krb5/src/plugins/kdb/db2/libdb2/hash/hash.c +@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12 + #include + #endif + ++#include "k5-int.h" + #include "db-int.h" + #include "hash.h" + #include "page.h" +@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info + new_table = 1; + } + if (file) { +- if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1) ++ if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1) + RETURN_ERROR(errno, error0); + (void)fcntl(hashp->fp, F_SETFD, 1); + } +--- krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c ++++ krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c +@@ -179,7 +179,7 @@ done: + + /* set password in the file */ + old_mode = umask(0177); +- pfile = fopen(file_name, "a+"); ++ pfile = WRITABLEFOPEN(file_name, "a+"); + if (pfile == NULL) { + com_err(me, errno, _("Failed to open file %s: %s"), file_name, + strerror (errno)); +@@ -220,6 +220,9 @@ done: + * Delete the existing entry and add the new entry + */ + FILE *newfile; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + mode_t omask; + +@@ -231,7 +234,13 @@ done: + } + + omask = umask(077); ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(file_name); ++#endif + newfile = fopen(tmp_file, "w"); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + umask (omask); + if (newfile == NULL) { + com_err(me, errno, _("Error creating file %s"), tmp_file); +--- krb5/src/slave/kpropd.c ++++ krb5/src/slave/kpropd.c +@@ -437,6 +437,9 @@ void doit(fd) + krb5_enctype etype; + int database_fd; + char host[INET6_ADDRSTRLEN + 1]; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + signal_wrapper(SIGALRM, alarm_handler); + alarm(params.iprop_resync_timeout); +@@ -515,9 +518,15 @@ void doit(fd) + free(name); + exit(1); + } ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(file); ++#endif + omask = umask(077); + lock_fd = open(temp_file_name, O_RDWR | O_CREAT, 0600); + (void)umask(omask); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + retval = krb5_lock_file(kpropd_context, lock_fd, + KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK); + if (retval) { +--- krb5/src/util/profile/prof_file.c ++++ krb5/src/util/profile/prof_file.c +@@ -30,6 +30,7 @@ + #endif + + #include "k5-platform.h" ++#include "k5-label.h" + + struct global_shared_profile_data { + /* This is the head of the global list of shared trees */ +@@ -418,7 +419,7 @@ static errcode_t write_data_to_file(prf_ + + errno = 0; + +- f = fopen(new_file, "w"); ++ f = WRITABLEFOPEN(new_file, "w"); + if (!f) { + retval = errno; + if (retval == 0) +--- krb5/src/util/support/Makefile.in ++++ krb5/src/util/support/Makefile.in +@@ -54,6 +54,7 @@ IPC_SYMS= \ + + STLIBOBJS= \ + threads.o \ ++ selinux.o \ + init-addrinfo.o \ + plugins.o \ + errors.o \ +@@ -108,7 +109,7 @@ SRCS=\ + + SHLIB_EXPDEPS = + # Add -lm if dumping thread stats, for sqrt. +-SHLIB_EXPLIBS= $(LIBS) $(DL_LIB) ++SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB) + + DEPLIBS= + +--- krb5/src/util/support/selinux.c ++++ krb5/src/util/support/selinux.c +@@ -0,0 +1,381 @@ ++/* ++ * Copyright 2007,2008,2009,2011,2012,2013 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. ++ * ++ * File-opening wrappers for creating correctly-labeled files. So far, we can ++ * assume that this is Linux-specific, so we make many simplifying assumptions. ++ */ ++ ++#include "../../include/autoconf.h" ++ ++#ifdef USE_SELINUX ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef HAVE_SELINUX_LABEL_H ++#include ++#endif ++ ++/* #define DEBUG 1 */ ++ ++/* Mutex used to serialize use of the process-global file creation context. */ ++k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER; ++ ++/* Make sure we finish initializing that mutex before attempting to use it. */ ++k5_once_t labeled_once = K5_ONCE_INIT; ++static void ++label_mutex_init(void) ++{ ++ k5_mutex_finish_init(&labeled_mutex); ++} ++ ++#ifdef HAVE_SELINUX_LABEL_H ++static struct selabel_handle *selabel_ctx; ++static time_t selabel_last_changed; ++ ++MAKE_FINI_FUNCTION(cleanup_fscreatecon); ++ ++static void ++cleanup_fscreatecon(void) ++{ ++ if (selabel_ctx != NULL) { ++ selabel_close(selabel_ctx); ++ selabel_ctx = NULL; ++ } ++} ++#endif ++ ++static security_context_t ++push_fscreatecon(const char *pathname, mode_t mode) ++{ ++ security_context_t previous, configuredsc, currentsc, derivedsc; ++ context_t current, derived; ++ const char *fullpath, *currentuser; ++ ++ previous = NULL; ++ if (is_selinux_enabled()) { ++ if (getfscreatecon(&previous) == 0) { ++ char *genpath; ++ genpath = NULL; ++ if (pathname[0] != '/') { ++ char *wd; ++ size_t len; ++ len = 0; ++ wd = getcwd(NULL, len); ++ if (wd == NULL) { ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ return NULL; ++ } ++ len = strlen(wd) + 1 + strlen(pathname) + 1; ++ genpath = malloc(len); ++ if (genpath == NULL) { ++ free(wd); ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ return NULL; ++ } ++ sprintf(genpath, "%s/%s", wd, pathname); ++ free(wd); ++ fullpath = genpath; ++ } else { ++ fullpath = pathname; ++ } ++#ifdef DEBUG ++ if (isatty(fileno(stderr))) { ++ fprintf(stderr, "Looking up context for " ++ "\"%s\"(%05o).\n", fullpath, mode); ++ } ++#endif ++ configuredsc = NULL; ++#ifdef HAVE_SELINUX_LABEL_H ++ if ((selabel_ctx != NULL) || ++ (selabel_last_changed == 0)) { ++ const char *cpath; ++ struct stat st; ++ int i = -1; ++ cpath = selinux_file_context_path(); ++ if ((cpath == NULL) || ++ ((i = stat(cpath, &st)) != 0) || ++ (st.st_mtime != selabel_last_changed)) { ++ if (selabel_ctx != NULL) { ++ selabel_close(selabel_ctx); ++ selabel_ctx = NULL; ++ } ++ selabel_last_changed = i ? ++ time(NULL) : ++ st.st_mtime; ++ } ++ } ++ if (selabel_ctx == NULL) { ++ selabel_ctx = selabel_open(SELABEL_CTX_FILE, ++ NULL, 0); ++ } ++ if (selabel_ctx != NULL) { ++ if (selabel_lookup(selabel_ctx, &configuredsc, ++ fullpath, mode) != 0) { ++ free(genpath); ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ return NULL; ++ } ++ } ++#else ++ if (matchpathcon(fullpath, mode, &configuredsc) != 0) { ++ free(genpath); ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ return NULL; ++ } ++#endif ++ free(genpath); ++ if (configuredsc == NULL) { ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ return NULL; ++ } ++ currentsc = NULL; ++ getcon(¤tsc); ++ if (currentsc != NULL) { ++ derived = context_new(configuredsc); ++ if (derived != NULL) { ++ current = context_new(currentsc); ++ if (current != NULL) { ++ currentuser = context_user_get(current); ++ if (currentuser != NULL) { ++ if (context_user_set(derived, ++ currentuser) == 0) { ++ derivedsc = context_str(derived); ++ if (derivedsc != NULL) { ++ freecon(configuredsc); ++ configuredsc = strdup(derivedsc); ++ } ++ } ++ } ++ context_free(current); ++ } ++ context_free(derived); ++ } ++ freecon(currentsc); ++ } ++#ifdef DEBUG ++ if (isatty(fileno(stderr))) { ++ fprintf(stderr, "Setting file creation context " ++ "to \"%s\".\n", configuredsc); ++ } ++#endif ++ if (setfscreatecon(configuredsc) != 0) { ++ freecon(configuredsc); ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ return NULL; ++ } ++ freecon(configuredsc); ++#ifdef DEBUG ++ } else { ++ if (isatty(fileno(stderr))) { ++ fprintf(stderr, "Unable to determine " ++ "current context.\n"); ++ } ++#endif ++ } ++ } ++ return previous; ++} ++ ++static void ++pop_fscreatecon(security_context_t previous) ++{ ++ if (is_selinux_enabled()) { ++#ifdef DEBUG ++ if (isatty(fileno(stderr))) { ++ if (previous != NULL) { ++ fprintf(stderr, "Resetting file creation " ++ "context to \"%s\".\n", previous); ++ } else { ++ fprintf(stderr, "Resetting file creation " ++ "context to default.\n"); ++ } ++ } ++#endif ++ setfscreatecon(previous); ++ if (previous != NULL) { ++ freecon(previous); ++ } ++ } ++} ++ ++void * ++krb5int_push_fscreatecon_for(const char *pathname) ++{ ++ struct stat st; ++ void *retval; ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ if (stat(pathname, &st) != 0) { ++ st.st_mode = S_IRUSR | S_IWUSR; ++ } ++ retval = push_fscreatecon(pathname, st.st_mode); ++ return retval ? retval : (void *) -1; ++} ++ ++void ++krb5int_pop_fscreatecon(void *con) ++{ ++ if (con != NULL) { ++ pop_fscreatecon((con == (void *) -1) ? NULL : con); ++ k5_mutex_unlock(&labeled_mutex); ++ } ++} ++ ++FILE * ++krb5int_labeled_fopen(const char *path, const char *mode) ++{ ++ FILE *fp; ++ int errno_save; ++ security_context_t ctx; ++ ++ if ((strcmp(mode, "r") == 0) || ++ (strcmp(mode, "rb") == 0)) { ++ return fopen(path, mode); ++ } ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ fp = fopen(path, mode); ++ errno_save = errno; ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ errno = errno_save; ++ return fp; ++} ++ ++int ++krb5int_labeled_creat(const char *path, mode_t mode) ++{ ++ int fd; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ fd = creat(path, mode); ++ errno_save = errno; ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ errno = errno_save; ++ return fd; ++} ++ ++int ++krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev) ++{ ++ int ret; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, mode); ++ ret = mknod(path, mode, dev); ++ errno_save = errno; ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ errno = errno_save; ++ return ret; ++} ++ ++int ++krb5int_labeled_mkdir(const char *path, mode_t mode) ++{ ++ int ret; ++ int errno_save; ++ security_context_t ctx; ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, S_IFDIR); ++ ret = mkdir(path, mode); ++ errno_save = errno; ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ errno = errno_save; ++ return ret; ++} ++ ++int ++krb5int_labeled_open(const char *path, int flags, ...) ++{ ++ int fd; ++ int errno_save; ++ security_context_t ctx; ++ mode_t mode; ++ va_list ap; ++ ++ if ((flags & O_CREAT) == 0) { ++ return open(path, flags); ++ } ++ ++ k5_once(&labeled_once, label_mutex_init); ++ k5_mutex_lock(&labeled_mutex); ++ ctx = push_fscreatecon(path, 0); ++ ++ va_start(ap, flags); ++ mode = va_arg(ap, mode_t); ++ fd = open(path, flags, mode); ++ va_end(ap); ++ ++ errno_save = errno; ++ pop_fscreatecon(ctx); ++ k5_mutex_unlock(&labeled_mutex); ++ errno = errno_save; ++ return fd; ++} ++ ++#endif +--- krb5/src/lib/krb5/rcache/rc_dfl.c ++++ krb5/src/lib/krb5/rcache/rc_dfl.c +@@ -813,6 +813,9 @@ krb5_rc_dfl_expunge_locked(krb5_context + krb5_error_code retval = 0; + krb5_rcache tmp; + krb5_deltat lifespan = t->lifespan; /* save original lifespan */ ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (! t->recovering) { + name = t->name; +@@ -834,7 +837,17 @@ krb5_rc_dfl_expunge_locked(krb5_context + retval = krb5_rc_resolve(context, tmp, 0); + if (retval) + goto cleanup; ++#ifdef USE_SELINUX ++ if (t->d.fn != NULL) ++ selabel = krb5int_push_fscreatecon_for(t->d.fn); ++ else ++ selabel = NULL; ++#endif + retval = krb5_rc_initialize(context, tmp, lifespan); ++#ifdef USE_SELINUX ++ if (selabel != NULL) ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (retval) + goto cleanup; + for (q = t->a; q; q = q->na) { +--- krb5/src/lib/krb5/ccache/cc_dir.c ++++ krb5/src/lib/krb5/ccache/cc_dir.c +@@ -185,10 +185,19 @@ write_primary_file(const char *primary_p + char *newpath = NULL; + FILE *fp = NULL; + int fd = -1, status; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (asprintf(&newpath, "%s.XXXXXX", primary_path) < 0) + return ENOMEM; ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(primary_path); ++#endif + fd = mkstemp(newpath); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif + if (fd < 0) + goto cleanup; + #ifdef HAVE_CHMOD +@@ -223,10 +232,23 @@ + verify_dir(krb5_context context, const char *dirname) + { + struct stat st; ++ int status; ++#ifdef USE_SELINUX ++ void *selabel; ++#endif + + if (stat(dirname, &st) < 0) { +- if (errno == ENOENT && mkdir(dirname, S_IRWXU) == 0) +- return 0; ++ if (errno == ENOENT) { ++#ifdef USE_SELINUX ++ selabel = krb5int_push_fscreatecon_for(dirname); ++#endif ++ status = mkdir(dirname, S_IRWXU); ++#ifdef USE_SELINUX ++ krb5int_pop_fscreatecon(selabel); ++#endif ++ if (status == 0) ++ return 0; ++ } + k5_setmsg(context, KRB5_FCC_NOFILE, + _("Credential cache directory %s does not exist"), + dirname); +--- krb5/src/lib/krb5/os/trace.c ++++ krb5/src/lib/krb5/os/trace.c +@@ -401,7 +401,7 @@ krb5_set_trace_filename(krb5_context con + fd = malloc(sizeof(*fd)); + if (fd == NULL) + return ENOMEM; +- *fd = open(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); ++ *fd = THREEPARAMOPEN(filename, O_WRONLY|O_CREAT|O_APPEND, 0600); + if (*fd == -1) { + free(fd); + return errno; +--- krb5/src/plugins/kdb/db2/kdb_db2.c ++++ krb5/src/plugins/kdb/db2/kdb_db2.c +@@ -683,8 +683,8 @@ + if (retval) + return retval; + +- dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC, +- 0600); ++ dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name, ++ O_CREAT | O_RDWR | O_TRUNC, 0600); + if (dbc->db_lf_file < 0) { + retval = errno; + goto cleanup; +--- krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c ++++ krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c +@@ -51,6 +51,7 @@ + #include + #include + ++#include "k5-int.h" + #include "db-int.h" + #include "recno.h" + +@@ -68,7 +69,8 @@ + int rfd = -1, sverrno; + + /* Open the user's file -- if this fails, we're done. */ +- if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0) ++ if (fname != NULL && ++ (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0) + return (NULL); + + if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) { +--- krb5/src/kdc/main.c ++++ krb5/src/kdc/main.c +@@ -905,7 +905,7 @@ write_pid_file(const char *path) + FILE *file; + unsigned long pid; + +- file = fopen(path, "w"); ++ file = WRITABLEFOPEN(path, "w"); + if (file == NULL) + return errno; + pid = (unsigned long) getpid(); +--- krb5/src/lib/kdb/kdb_log.c ++++ krb5/src/lib/kdb/kdb_log.c +@@ -456,7 +456,7 @@ ulog_map(krb5_context context, const cha + int ulogfd = -1; + + if (stat(logname, &st) == -1) { +- ulogfd = open(logname, O_RDWR | O_CREAT, 0600); ++ ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600); + if (ulogfd == -1) + return errno; + +--- krb5/src/util/gss-kernel-lib/Makefile.in ++++ krb5/src/util/gss-kernel-lib/Makefile.in +@@ -60,6 +60,7 @@ HEADERS= \ + gssapi_err_generic.h \ + k5-int.h \ + k5-int-pkinit.h \ ++ k5-label.h \ + k5-thread.h \ + k5-platform.h \ + k5-buf.h \ +@@ -166,10 +167,12 @@ gssapi_generic.h: $(GSS_GENERIC)/gssapi_ + $(CP) $(GSS_GENERIC)/gssapi_generic.h $@ + gssapi_err_generic.h: $(GSS_GENERIC_BUILD)/gssapi_err_generic.h + $(CP) $(GSS_GENERIC_BUILD)/gssapi_err_generic.h $@ +-k5-int.h: $(INCLUDE)/k5-int.h ++k5-int.h: $(INCLUDE)/k5-int.h k5-label.h + $(CP) $(INCLUDE)/k5-int.h $@ + k5-int-pkinit.h: $(INCLUDE)/k5-int-pkinit.h + $(CP) $(INCLUDE)/k5-int-pkinit.h $@ ++k5-label.h: $(INCLUDE)/k5-label.h ++ $(CP) $(INCLUDE)/k5-label.h $@ + k5-thread.h: $(INCLUDE)/k5-thread.h + $(CP) $(INCLUDE)/k5-thread.h $@ + k5-platform.h: $(INCLUDE)/k5-platform.h diff --git a/SOURCES/krb5-1.13.2.tar.gz.asc b/SOURCES/krb5-1.13.2.tar.gz.asc new file mode 100644 index 0000000..969169d --- /dev/null +++ b/SOURCES/krb5-1.13.2.tar.gz.asc @@ -0,0 +1,14 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1 + +iQGcBAABAgAGBQJVTUldAAoJEKMvF/0AVcMF9IoMAIEawAFZ1pRw91oRN6c3eAxy +RYBuJWsEa73JtqKCRtz7LA3qgacnJ8FGTpXaGHB3zErO55+Bclo1KZsUoNDtT27O +bxjsptPBjp15zTZhavlIpAjANFmo6QpghUHpLNcLxH8pXgmQDztHnPaenStxF8Bv +P2oFKh31uY3gYzOKnYi/r14XKSTNpFiDiGty53KY61efAO4H7xRFMhBgN2Vv1pBm +FvekjCWRypN7ai2z+94cuVNIlu8eipDnU4oBb865fRKlflxCdpBmHLr1K5AgwSEb +OAvDUPAEV9GwBP94M0yAoPwGf5ZHPvdORXbHfX00lzX2SgV+9DH4BqJOnytOeuaT +PA1Z+7izF+Xja4iHMcYlyJ7a/sGWachlZrw2ifELlYUf4vtcPY5e6gH0hSMUoA7t +Ww18ryv5fPHT1l+/o2P03hzZSFllOXjVsComsfw6Ws7qzbFuigpiVYdBg1XKMi9L +kjA7j43FTHvVKjtrEubiW+YHxowQHu5DIeQWVqsBJg== +=KdUH +-----END PGP SIGNATURE----- diff --git a/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch b/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch new file mode 100644 index 0000000..fc3101f --- /dev/null +++ b/SOURCES/krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch @@ -0,0 +1,32 @@ +From 0e65104d521d29664c129c1cf5e918bf54ac055e Mon Sep 17 00:00:00 2001 +From: Greg Hudson +Date: Tue, 19 May 2015 10:38:51 -0400 +Subject: [PATCH] Fix bindresvport_sa port byte swap bug + +The sa_setport() helper handles conversion to network byte order, so +bindresvport_sa() should not itself call htons() on the port argument. + +(This bug was introduced in commit +0d04b60d159ab83b943e43802b1449a3b074bc83 when adding +bindresvport_sa(). It was my fault, not Andreas Schneider's.) + +ticket: 8197 (new) +target_version: 1.13.3 +tags: pullup +--- + src/lib/rpc/bindresvport.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/rpc/bindresvport.c b/src/lib/rpc/bindresvport.c +index ccc4d73..a421dd8 100644 +--- a/src/lib/rpc/bindresvport.c ++++ b/src/lib/rpc/bindresvport.c +@@ -76,7 +76,7 @@ bindresvport_sa(int sd, struct sockaddr *sa) + res = -1; + errno = EADDRINUSE; + for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) { +- sa_setport(sa, htons(port++)); ++ sa_setport(sa, port++); + if (port > ENDPORT) { + port = STARTPORT; + } diff --git a/SOURCES/krb5-1.13.3-client_referrals.patch b/SOURCES/krb5-1.13.3-client_referrals.patch new file mode 100644 index 0000000..6b94e1b --- /dev/null +++ b/SOURCES/krb5-1.13.3-client_referrals.patch @@ -0,0 +1,31 @@ +From 4065b979071b6e34b440f1db24d66d8691792bee Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Thu, 3 Sep 2015 18:24:26 +0300 +Subject: [PATCH] client referral: return correct client principal in case of a + wrong realm + +prepare_error_as_req() gets protocol error code but compares it with +table code and misses to add proper client principal as returned by the +DAL driver. + +Use proper error code constant. +--- + src/kdc/do_as_req.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c +index 3a3ce8b..5440949 100644 +--- a/src/kdc/do_as_req.c ++++ b/src/kdc/do_as_req.c +@@ -862,7 +862,7 @@ prepare_error_as(struct kdc_request_state *rstate, krb5_kdc_req *request, + return retval; + errpkt.error = error; + errpkt.server = request->server; +- errpkt.client = (error == KRB5KDC_ERR_WRONG_REALM) ? canon_client : ++ errpkt.client = (error == KDC_ERR_WRONG_REALM) ? canon_client : + request->client; + errpkt.text = string2data((char *)status); + +-- +2.4.3 + diff --git a/SOURCES/krb5-1.13.3-client_referrals_test.patch b/SOURCES/krb5-1.13.3-client_referrals_test.patch new file mode 100644 index 0000000..449646e --- /dev/null +++ b/SOURCES/krb5-1.13.3-client_referrals_test.patch @@ -0,0 +1,604 @@ +diff --git a/src/plugins/kdb/test/Makefile.in b/src/plugins/kdb/test/Makefile.in +new file mode 100644 +index 0000000..f9578a3 +--- /dev/null ++++ b/src/plugins/kdb/test/Makefile.in +@@ -0,0 +1,21 @@ ++mydir=plugins$(S)kdb$(S)test ++BUILDTOP=$(REL)..$(S)..$(S).. ++ ++LIBBASE=test ++LIBMAJOR=0 ++LIBMINOR=0 ++RELDIR=../plugins/kdb/test ++SHLIB_EXPDEPS=$(KADMSRV_DEPLIB) $(KRB5_BASE_DEPLIBS) ++SHLIB_EXPLIBS=$(KADMSRV_LIBS) $(KRB5_BASE_LIBS) ++LOCALINCLUDES=-I../../../lib/kdb -I$(srcdir)/../../../lib/kdb ++ ++SRCS = $(srcdir)/kdb_test.c ++ ++STLIBOBJS = kdb_test.o ++ ++all-unix:: all-liblinks ++install-unix:: ++clean-unix:: clean-liblinks clean-libs clean-libobjs ++ ++@libnover_frag@ ++@libobj_frag@ +diff --git a/src/plugins/kdb/test/deps b/src/plugins/kdb/test/deps +new file mode 100644 +index 0000000..e69de29 +diff --git a/src/plugins/kdb/test/kdb_test.c b/src/plugins/kdb/test/kdb_test.c +new file mode 100644 +index 0000000..a0e4970 +--- /dev/null ++++ b/src/plugins/kdb/test/kdb_test.c +@@ -0,0 +1,561 @@ ++/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ ++/* plugins/kdb/test/kdb_test.c - Test KDB module */ ++/* ++ * Copyright (C) 2015 by the Massachusetts Institute of Technology. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ++ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ++ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * This is a read-only KDB module intended to help test KDC behavior which ++ * cannot be exercised with the DB2 module. Responses are read from the ++ * dbmodules subsection according to this example: ++ * ++ * [dbmodules] ++ * test = { ++ * alias = { ++ * aliasname = canonname ++ * # For cross-realm aliases, only the realm part will ++ * # matter to the client. ++ * aliasname = @FOREIGN_REALM ++ * enterprise@PRINC = @FOREIGN_REALM ++ * } ++ * princs = { ++ * krbtgt/KRBTEST.COM = { ++ * flags = +preauth +ok-to-auth-as-delegate ++ * maxlife = 1d ++ * maxrenewlife = 7d ++ * expiration = 14d # relative to current time ++ * pwexpiration = 1h ++ * # Initial number is kvno; defaults to 1. ++ * keys = 3 aes256-cts aes128-cts:normal ++ * keys = 2 rc4-hmac ++ * } ++ * } ++ * delegation = { ++ * intermediate_service = target_service ++ * } ++ * } ++ * ++ * Key values are generated using a hash of the kvno, enctype, salt type, and ++ * principal name. This module does not use master key encryption, so it ++ * serves as a partial test of the DAL's ability to avoid that. ++ */ ++ ++#include "k5-int.h" ++#include "kdb5.h" ++#include "adm_proto.h" ++#include ++ ++typedef struct { ++ void *profile; ++ char *section; ++ const char *names[6]; ++} *testhandle; ++ ++static void * ++ealloc(size_t sz) ++{ ++ void *p = calloc(sz, 1); ++ ++ if (p == NULL) ++ abort(); ++ return p; ++} ++ ++static char * ++estrdup(const char *s) ++{ ++ char *copy = strdup(s); ++ ++ if (copy == NULL) ++ abort(); ++ return copy; ++} ++ ++static void ++check(krb5_error_code code) ++{ ++ if (code != 0) ++ abort(); ++} ++ ++/* Set up for a profile query using h->names. Look up s1 -> s2 -> s3 (some of ++ * which may be NULL) within this database's dbmodules section. */ ++static void ++set_names(testhandle h, const char *s1, const char *s2, const char *s3) ++{ ++ h->names[0] = KDB_MODULE_SECTION; ++ h->names[1] = h->section; ++ h->names[2] = s1; ++ h->names[3] = s2; ++ h->names[4] = s3; ++ h->names[5] = NULL; ++} ++ ++/* Look up a string within this database's dbmodules section. */ ++static char * ++get_string(testhandle h, const char *s1, const char *s2, const char *s3) ++{ ++ krb5_error_code ret; ++ char **values, *val; ++ ++ set_names(h, s1, s2, s3); ++ ret = profile_get_values(h->profile, h->names, &values); ++ if (ret == PROF_NO_RELATION) ++ return NULL; ++ if (ret) ++ abort(); ++ val = estrdup(values[0]); ++ profile_free_list(values); ++ return val; ++} ++ ++/* Look up a duration within this database's dbmodules section. */ ++static krb5_deltat ++get_duration(testhandle h, const char *s1, const char *s2, const char *s3) ++{ ++ char *strval = get_string(h, s1, s2, s3); ++ krb5_deltat val; ++ ++ if (strval == NULL) ++ return 0; ++ check(krb5_string_to_deltat(strval, &val)); ++ free(strval); ++ return val; ++} ++ ++/* Look up an absolute time within this database's dbmodules section. The time ++ * is expressed in the profile as an interval relative to the current time. */ ++static krb5_timestamp ++get_time(testhandle h, const char *s1, const char *s2, const char *s3) ++{ ++ char *strval = get_string(h, s1, s2, s3); ++ krb5_deltat val; ++ ++ if (strval == NULL) ++ return 0; ++ check(krb5_string_to_deltat(strval, &val)); ++ free(strval); ++ return val + time(NULL); ++} ++ ++/* Initialize kb_out with a key of type etype, using a hash of kvno, etype, ++ * salttype, and princstr for the key bytes. */ ++static void ++make_keyblock(krb5_kvno kvno, krb5_enctype etype, int32_t salttype, ++ const char *princstr, krb5_keyblock *kb_out) ++{ ++ size_t keybytes, keylength, pos, n; ++ char *hashstr; ++ krb5_data d, rndin; ++ krb5_checksum cksum; ++ ++ check(krb5_c_keylengths(NULL, etype, &keybytes, &keylength)); ++ alloc_data(&rndin, keybytes); ++ ++ /* Hash the kvno, enctype, salt type, and principal name together. */ ++ if (asprintf(&hashstr, "%d %d %d %s", (int)kvno, (int)etype, ++ (int)salttype, princstr) < 0) ++ abort(); ++ d = string2data(hashstr); ++ check(krb5_c_make_checksum(NULL, CKSUMTYPE_NIST_SHA, NULL, 0, &d, &cksum)); ++ ++ /* Make the appropriate number of input bytes from the hash result. */ ++ for (pos = 0; pos < keybytes; pos += n) { ++ n = (cksum.length < keybytes - pos) ? cksum.length : keybytes - pos; ++ memcpy(rndin.data + pos, cksum.contents, n); ++ } ++ ++ kb_out->enctype = etype; ++ kb_out->length = keylength; ++ kb_out->contents = ealloc(keylength); ++ check(krb5_c_random_to_key(NULL, etype, &rndin, kb_out)); ++ free(cksum.contents); ++ free(rndin.data); ++ free(hashstr); ++} ++ ++/* Return key data for the given key/salt tuple strings, using hashes of the ++ * enctypes, salts, and princstr for the key contents. */ ++static void ++make_keys(char **strings, const char *princstr, krb5_db_entry *ent) ++{ ++ krb5_key_data *key_data, *kd; ++ krb5_keyblock kb; ++ int32_t *ks_list_sizes, nstrings, nkeys, i, j; ++ krb5_key_salt_tuple **ks_lists, *ks; ++ krb5_kvno *kvnos; ++ char *s; ++ ++ for (nstrings = 0; strings[nstrings] != NULL; nstrings++); ++ ks_lists = ealloc(nstrings * sizeof(*ks_lists)); ++ ks_list_sizes = ealloc(nstrings * sizeof(*ks_list_sizes)); ++ kvnos = ealloc(nstrings * sizeof(*kvnos)); ++ ++ /* Convert each string into a key/salt tuple list and count the total ++ * number of key data structures needed. */ ++ nkeys = 0; ++ for (i = 0; i < nstrings; i++) { ++ s = strings[i]; ++ /* Read a leading kvno if present; otherwise assume kvno 1. */ ++ if (isdigit(*s)) { ++ kvnos[i] = strtol(s, &s, 10); ++ while (isspace(*s)) ++ s++; ++ } else { ++ kvnos[i] = 1; ++ } ++ check(krb5_string_to_keysalts(s, NULL, NULL, FALSE, &ks_lists[i], ++ &ks_list_sizes[i])); ++ nkeys += ks_list_sizes[i]; ++ } ++ ++ /* Turn each key/salt tuple into a key data entry. */ ++ kd = key_data = ealloc(nkeys * sizeof(*kd)); ++ for (i = 0; i < nstrings; i++) { ++ ks = ks_lists[i]; ++ for (j = 0; j < ks_list_sizes[i]; j++) { ++ make_keyblock(kvnos[i], ks[j].ks_enctype, ks[j].ks_salttype, ++ princstr, &kb); ++ kd->key_data_ver = 2; ++ kd->key_data_kvno = kvnos[i]; ++ kd->key_data_type[0] = ks[j].ks_enctype; ++ kd->key_data_length[0] = kb.length; ++ kd->key_data_contents[0] = kb.contents; ++ kd->key_data_type[1] = ks[j].ks_salttype; ++ kd++; ++ } ++ } ++ ++ for (i = 0; i < nstrings; i++) ++ free(ks_lists[i]); ++ free(ks_lists); ++ free(ks_list_sizes); ++ free(kvnos); ++ ent->key_data = key_data; ++ ent->n_key_data = nkeys; ++} ++ ++static krb5_error_code ++test_init() ++{ ++ return 0; ++} ++ ++static krb5_error_code ++test_cleanup() ++{ ++ return 0; ++} ++ ++static krb5_error_code ++test_open(krb5_context context, char *conf_section, char **db_args, int mode) ++{ ++ testhandle h; ++ ++ h = ealloc(sizeof(*h)); ++ h->profile = context->profile; ++ h->section = estrdup(conf_section); ++ context->dal_handle->db_context = h; ++ return 0; ++} ++ ++static krb5_error_code ++test_close(krb5_context context) ++{ ++ testhandle h = context->dal_handle->db_context; ++ ++ free(h->section); ++ free(h); ++ return 0; ++} ++ ++static krb5_error_code ++test_get_principal(krb5_context context, krb5_const_principal search_for, ++ unsigned int flags, krb5_db_entry **entry) ++{ ++ krb5_error_code ret; ++ krb5_principal princ = NULL; ++ krb5_principal_data empty_princ = { KV5M_PRINCIPAL }; ++ testhandle h = context->dal_handle->db_context; ++ char *search_name = NULL, *canon = NULL, *flagstr, **names, **key_strings; ++ const char *ename; ++ krb5_db_entry *ent; ++ ++ *entry = NULL; ++ ++ check(krb5_unparse_name_flags(context, search_for, ++ KRB5_PRINCIPAL_UNPARSE_NO_REALM, ++ &search_name)); ++ canon = get_string(h, "alias", search_name, NULL); ++ if (canon != NULL) { ++ if (!(flags & KRB5_KDB_FLAG_ALIAS_OK)) { ++ ret = KRB5_KDB_NOENTRY; ++ goto cleanup; ++ } ++ check(krb5_parse_name(context, canon, &princ)); ++ if (!krb5_realm_compare(context, search_for, princ)) { ++ if (flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) { ++ /* Return a client referral by creating an entry with only the ++ * principal set. */ ++ *entry = ealloc(sizeof(**entry)); ++ (*entry)->princ = princ; ++ princ = NULL; ++ ret = 0; ++ goto cleanup; ++ } else { ++ /* We could look up a cross-realm TGS entry, but we don't need ++ * that behavior yet. */ ++ ret = KRB5_KDB_NOENTRY; ++ goto cleanup; ++ } ++ } ++ ename = canon; ++ } else { ++ check(krb5_copy_principal(context, search_for, &princ)); ++ ename = search_name; ++ } ++ ++ /* Check that the entry exists. */ ++ set_names(h, "princs", ename, NULL); ++ ret = profile_get_relation_names(h->profile, h->names, &names); ++ if (ret == PROF_NO_RELATION) { ++ ret = KRB5_KDB_NOENTRY; ++ goto cleanup; ++ } ++ profile_free_list(names); ++ ++ /* No error exits after this point. */ ++ ++ ent = ealloc(sizeof(*ent)); ++ ent->princ = princ; ++ princ = NULL; ++ ++ flagstr = get_string(h, "princs", ename, "flags"); ++ if (flagstr != NULL) { ++ check(krb5_flagspec_to_mask(flagstr, &ent->attributes, ++ &ent->attributes)); ++ } ++ free(flagstr); ++ ++ ent->max_life = get_duration(h, "princs", ename, "maxlife"); ++ ent->max_renewable_life = get_duration(h, "princs", ename, "maxrenewlife"); ++ ent->expiration = get_time(h, "princs", ename, "expiration"); ++ ent->pw_expiration = get_time(h, "princs", ename, "pwexpiration"); ++ ++ /* Leave last_success, last_failed, fail_auth_count zeroed. */ ++ /* Leave tl_data and e_data empty. */ ++ ++ set_names(h, "princs", ename, "keys"); ++ ret = profile_get_values(h->profile, h->names, &key_strings); ++ if (ret != PROF_NO_RELATION) { ++ make_keys(key_strings, ename, ent); ++ profile_free_list(key_strings); ++ } ++ ++ /* We must include mod-princ data or kadm5_get_principal() won't work and ++ * we can't extract keys with kadmin.local. */ ++ check(krb5_dbe_update_mod_princ_data(context, ent, 0, &empty_princ)); ++ ++ *entry = ent; ++ ++cleanup: ++ krb5_free_unparsed_name(context, search_name); ++ krb5_free_principal(context, princ); ++ free(canon); ++ return ret; ++} ++ ++static void ++test_free_principal(krb5_context context, krb5_db_entry *entry) ++{ ++ krb5_tl_data *tl, *next; ++ int i, j; ++ ++ if (entry == NULL) ++ return; ++ free(entry->e_data); ++ krb5_free_principal(context, entry->princ); ++ for (tl = entry->tl_data; tl != NULL; tl = next) { ++ next = tl->tl_data_next; ++ free(tl->tl_data_contents); ++ free(tl); ++ } ++ for (i = 0; i < entry->n_key_data; i++) { ++ for (j = 0; j < entry->key_data[i].key_data_ver; j++) { ++ if (entry->key_data[i].key_data_length[j]) { ++ zapfree(entry->key_data[i].key_data_contents[j], ++ entry->key_data[i].key_data_length[j]); ++ } ++ entry->key_data[i].key_data_contents[j] = NULL; ++ entry->key_data[i].key_data_length[j] = 0; ++ entry->key_data[i].key_data_type[j] = 0; ++ } ++ } ++ free(entry->key_data); ++ free(entry); ++} ++ ++static void * ++test_alloc(krb5_context context, void *ptr, size_t size) ++{ ++ return realloc(ptr, size); ++} ++ ++static void ++test_free(krb5_context context, void *ptr) ++{ ++ free(ptr); ++} ++ ++static krb5_error_code ++test_fetch_master_key(krb5_context context, krb5_principal mname, ++ krb5_keyblock *key_out, krb5_kvno *kvno_out, ++ char *db_args) ++{ ++ memset(key_out, 0, sizeof(*key_out)); ++ *kvno_out = 0; ++ return 0; ++} ++ ++static krb5_error_code ++test_fetch_master_key_list(krb5_context context, krb5_principal mname, ++ const krb5_keyblock *key, ++ krb5_keylist_node **mkeys_out) ++{ ++ /* krb5_dbe_get_mkvno() returns an error if we produce NULL, so return an ++ * empty node to make kadm5_get_principal() work. */ ++ *mkeys_out = ealloc(sizeof(**mkeys_out)); ++ return 0; ++} ++ ++static krb5_error_code ++test_decrypt_key_data(krb5_context context, const krb5_keyblock *mkey, ++ const krb5_key_data *kd, krb5_keyblock *key_out, ++ krb5_keysalt *salt_out) ++{ ++ key_out->magic = KV5M_KEYBLOCK; ++ key_out->enctype = kd->key_data_type[0]; ++ key_out->length = kd->key_data_length[0]; ++ key_out->contents = ealloc(key_out->length); ++ memcpy(key_out->contents, kd->key_data_contents[0], key_out->length); ++ if (salt_out != NULL) { ++ salt_out->type = (kd->key_data_ver > 1) ? kd->key_data_type[1] : ++ KRB5_KDB_SALTTYPE_NORMAL; ++ salt_out->data = empty_data(); ++ } ++ return 0; ++} ++ ++static krb5_error_code ++test_encrypt_key_data(krb5_context context, const krb5_keyblock *mkey, ++ const krb5_keyblock *key, const krb5_keysalt *salt, ++ int kvno, krb5_key_data *kd_out) ++{ ++ memset(kd_out, 0, sizeof(*kd_out)); ++ kd_out->key_data_ver = 2; ++ kd_out->key_data_kvno = kvno; ++ kd_out->key_data_type[0] = key->enctype; ++ kd_out->key_data_length[0] = key->length; ++ kd_out->key_data_contents[0] = ealloc(key->length); ++ memcpy(kd_out->key_data_contents[0], key->contents, key->length); ++ kd_out->key_data_type[1] = (salt != NULL) ? salt->type : ++ KRB5_KDB_SALTTYPE_NORMAL; ++ return 0; ++} ++ ++static krb5_error_code ++test_check_allowed_to_delegate(krb5_context context, ++ krb5_const_principal client, ++ const krb5_db_entry *server, ++ krb5_const_principal proxy) ++{ ++ krb5_error_code ret; ++ testhandle h = context->dal_handle->db_context; ++ char *sprinc, *tprinc, **values, **v; ++ krb5_boolean found = FALSE; ++ ++ check(krb5_unparse_name_flags(context, server->princ, ++ KRB5_PRINCIPAL_UNPARSE_NO_REALM, &sprinc)); ++ check(krb5_unparse_name_flags(context, proxy, ++ KRB5_PRINCIPAL_UNPARSE_NO_REALM, &tprinc)); ++ set_names(h, "delegation", sprinc, NULL); ++ ret = profile_get_values(h->profile, h->names, &values); ++ if (ret == PROF_NO_RELATION) ++ return KRB5KDC_ERR_POLICY; ++ for (v = values; *v != NULL; v++) { ++ if (strcmp(*v, tprinc) == 0) { ++ found = TRUE; ++ break; ++ } ++ } ++ profile_free_list(values); ++ return found ? 0 : KRB5KDC_ERR_POLICY; ++} ++ ++kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_test, kdb_function_table) = { ++ KRB5_KDB_DAL_MAJOR_VERSION, /* major version number */ ++ 0, /* minor version number 0 */ ++ test_init, ++ test_cleanup, ++ test_open, ++ test_close, ++ NULL, /* create */ ++ NULL, /* destroy */ ++ NULL, /* get_age */ ++ NULL, /* lock */ ++ NULL, /* unlock */ ++ test_get_principal, ++ test_free_principal, ++ NULL, /* put_principal */ ++ NULL, /* delete_principal */ ++ NULL, /* iterate */ ++ NULL, /* create_policy */ ++ NULL, /* get_policy */ ++ NULL, /* put_policy */ ++ NULL, /* iter_policy */ ++ NULL, /* delete_policy */ ++ NULL, /* free_policy */ ++ test_alloc, ++ test_free, ++ test_fetch_master_key, ++ test_fetch_master_key_list, ++ NULL, /* store_master_key_list */ ++ NULL, /* dbe_search_enctype */ ++ NULL, /* change_pwd */ ++ NULL, /* promote_db */ ++ test_decrypt_key_data, ++ test_encrypt_key_data, ++ NULL, /* sign_authdata */ ++ NULL, /* check_transited_realms */ ++ NULL, /* check_policy_as */ ++ NULL, /* check_policy_tgs */ ++ NULL, /* audit_as_req */ ++ NULL, /* refresh_config */ ++ test_check_allowed_to_delegate ++}; +diff --git a/src/plugins/kdb/test/test.exports b/src/plugins/kdb/test/test.exports +new file mode 100644 +index 0000000..f2b7c11 +--- /dev/null ++++ b/src/plugins/kdb/test/test.exports +@@ -0,0 +1 @@ ++kdb_function_table diff --git a/SOURCES/krb5-1.13_kinit_C_loop_krb5bug243.patch b/SOURCES/krb5-1.13_kinit_C_loop_krb5bug243.patch deleted file mode 100644 index f9aa870..0000000 --- a/SOURCES/krb5-1.13_kinit_C_loop_krb5bug243.patch +++ /dev/null @@ -1,118 +0,0 @@ -From d5755694b620570defeecee772def90a2733c6cc Mon Sep 17 00:00:00 2001 -From: Simo Sorce -Date: Tue, 20 Jan 2015 13:48:34 -0500 -Subject: [PATCH 1/2] Do not loop on principal unknown errors - -If the canonicalize flag is set, the MIT KDC always return the client -principal when KRB5_KDC_ERR_C_PRICIPAL_UNKNOWN is returned. - -Check that this is really a referral by testing that the returned -client realm differs from the requested one. - -[ghudson@mit.edu: simplified and narrowed is_referral() contract. -Note that a WRONG_REALM response with e-data or FAST error padata -could now be passed through k5_preauth_tryagain() if it has an empty -crealm or a crealm equal to the requested client realm. Such a -response is unexpected in practice and there is nothing dangerous -about handling it this way.] - -ticket: 8060 -target_version: 1.13.1 -tags: pullup ---- - src/lib/krb5/krb/get_in_tkt.c | 40 +++++++++++++--------------------------- - 1 file changed, 13 insertions(+), 27 deletions(-) - -diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c -index 2c2b654..f9bc027 100644 ---- a/src/lib/krb5/krb/get_in_tkt.c -+++ b/src/lib/krb5/krb/get_in_tkt.c -@@ -1379,33 +1379,23 @@ note_req_timestamp(krb5_context context, krb5_init_creds_context ctx, - AUTH_OFFSET : UNAUTH_OFFSET; - } - --/* Determine whether the client realm in a KRB-ERROR is empty. */ --static krb5_boolean --is_empty_crealm(krb5_error *err) --{ -- -- return (err->client == NULL || err->client->realm.length == 0); --} -- - /* -- * Determine whether a KRB-ERROR is a referral to another realm. -+ * Determine whether err is a client referral to another realm, given the -+ * previously requested client principal name. - * -- * RFC 6806 Section 7 requires that KDCs return the referral realm in -- * an error type WRONG_REALM, but Microsoft Windows Server 2003 (and -- * possibly others) return the realm in a PRINCIPAL_UNKNOWN message. -- * Detect this case by looking for a non-empty client.realm field in -- * such responses. -+ * RFC 6806 Section 7 requires that KDCs return the referral realm in an error -+ * type WRONG_REALM, but Microsoft Windows Server 2003 (and possibly others) -+ * return the realm in a PRINCIPAL_UNKNOWN message. - */ - static krb5_boolean --is_referral(krb5_init_creds_context ctx) -+is_referral(krb5_context context, krb5_error *err, krb5_principal client) - { -- krb5_error *err = ctx->err_reply; -- -- if (err->error == KDC_ERR_WRONG_REALM) -- return TRUE; -- if (err->error != KDC_ERR_C_PRINCIPAL_UNKNOWN) -+ if (err->error != KDC_ERR_WRONG_REALM && -+ err->error != KDC_ERR_C_PRINCIPAL_UNKNOWN) -+ return FALSE; -+ if (err->client == NULL) - return FALSE; -- return !is_empty_crealm(err); -+ return !krb5_realm_compare(context, err->client, client); - } - - static krb5_error_code -@@ -1467,12 +1457,8 @@ init_creds_step_reply(krb5_context context, - ctx->preauth_to_use); - ctx->preauth_required = TRUE; - -- } else if (canon_flag && is_referral(ctx)) { -- if (is_empty_crealm(ctx->err_reply)) { -- /* Only WRONG_REALM referral types can reach this. */ -- code = KRB5KDC_ERR_WRONG_REALM; -- goto cleanup; -- } -+ } else if (canon_flag && is_referral(context, ctx->err_reply, -+ ctx->request->client)) { - TRACE_INIT_CREDS_REFERRAL(context, &ctx->err_reply->client->realm); - /* Rewrite request.client with realm from error reply */ - krb5_free_data_contents(context, &ctx->request->client->realm); - -From c0778ab2252ece4c3510788d9b72f7f5e3bb05dd Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Fri, 23 Jan 2015 12:52:31 -0500 -Subject: [PATCH 2/2] Add test for kinit -C WRONG_REALM response - -ticket: 8060 ---- - src/tests/t_general.py | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/tests/t_general.py b/src/tests/t_general.py -index 98e77a2..5349b05 100755 ---- a/src/tests/t_general.py -+++ b/src/tests/t_general.py -@@ -33,6 +33,13 @@ - - realm = K5Realm(create_host=False) - -+# Test that WRONG_REALM responses aren't treated as referrals unless -+# they contain a crealm field pointing to a different realm. -+# (Regression test for #8060.) -+out = realm.run([kinit, '-C', 'notfoundprinc'], expected_code=1) -+if 'not found in Kerberos database' not in out: -+ fail('Expected error message not seen in kinit -C output') -+ - # Spot-check KRB5_TRACE output - tracefile = os.path.join(realm.testdir, 'trace') - realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, realm.user_princ], diff --git a/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch b/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch new file mode 100644 index 0000000..7757885 --- /dev/null +++ b/SOURCES/krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch @@ -0,0 +1,142 @@ +From 95c3cab051aa1b8b4f7eb309bf135e8f51665baa Mon Sep 17 00:00:00 2001 +From: Nathaniel McCallum +Date: Sun, 25 Jan 2015 16:53:49 -0500 +Subject: [PATCH] Support KDC_ERR_MORE_PREAUTH_DATA_REQUIRED + +Add support for multi-hop preauth mechs. + +In the KDC, allow kdcpreauth modules to return +KDC_ERR_MORE_PREAUTH_DATA_REQUIRED as defined in RFC 6113. + +In libkrb5, treat this code like KDC_ERR_PREAUTH_REQUIRED. clpreauth +modules can use the modreq parameter to distinguish between the first +and subsequent KDC messages. We assume that the error padata will +include an element of the preauth mech's type, or at least of a type +recognized by the clpreauth module. + +Also reset the list of previously attempted preauth types for both +kinds of errors. That list is really only appropriate for retrying +after a failed preauth attempt, which we don't currently do. Add an +intermediate variable for the reply code to avoid a long conditional +expression. + +[ghudson@mit.edu: adjust get_in_tkt.c logic to avoid needing a helper +function; clarify commit message] + +ticket: 8063 (new) +--- + doc/plugindev/clpreauth.rst | 6 +++--- + src/include/k5-int.h | 1 + + src/kdc/kdc_preauth.c | 2 ++ + src/lib/krb5/error_tables/krb5_err.et | 2 +- + src/lib/krb5/krb/get_in_tkt.c | 13 ++++++++----- + 5 files changed, 15 insertions(+), 9 deletions(-) + +diff --git a/doc/plugindev/clpreauth.rst b/doc/plugindev/clpreauth.rst +index c3e7298..38aa52e 100644 +--- a/doc/plugindev/clpreauth.rst ++++ b/doc/plugindev/clpreauth.rst +@@ -21,9 +21,9 @@ A clpreauth module is generally responsible for: + just returns ``PA_REAL``, indicating that it implements a normal + preauthentication type. + +-* Examining the padata information included in the preauth_required +- error and producing padata values for the next AS request. This is +- done with the **process** method. ++* Examining the padata information included in a PREAUTH_REQUIRED or ++ MORE_PREAUTH_DATA_REQUIRED error and producing padata values for the ++ next AS request. This is done with the **process** method. + + * Examining the padata information included in a successful ticket + reply, possibly verifying the KDC identity and computing a reply +diff --git a/src/include/k5-int.h b/src/include/k5-int.h +index a1ea25a..4868e7d 100644 +--- a/src/include/k5-int.h ++++ b/src/include/k5-int.h +@@ -391,6 +391,7 @@ typedef unsigned char u_char; + not find a KDC */ + #define KRB_AP_ERR_IAKERB_KDC_NO_RESPONSE 86 /* The KDC did not respond + to the IAKERB proxy */ ++#define KDC_ERR_MORE_PREAUTH_DATA_REQUIRED 91 /* RFC 6113 */ + #define KRB_ERR_MAX 127 /* err table base max offset for protocol err codes */ + + /* +diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c +index 50cc252..dd83844 100644 +--- a/src/kdc/kdc_preauth.c ++++ b/src/kdc/kdc_preauth.c +@@ -1000,6 +1000,8 @@ finish_check_padata(struct padata_state *state, krb5_error_code code) + case KRB5KDC_ERR_DISCARD: + /* pkinit alg-agility */ + case KRB5KDC_ERR_NO_ACCEPTABLE_KDF: ++ /* rfc 6113 */ ++ case KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED: + (*oldrespond)(oldarg, code); + return; + default: +diff --git a/src/lib/krb5/error_tables/krb5_err.et b/src/lib/krb5/error_tables/krb5_err.et +index 5c6f10b..7ba7c1e 100644 +--- a/src/lib/krb5/error_tables/krb5_err.et ++++ b/src/lib/krb5/error_tables/krb5_err.et +@@ -132,7 +132,7 @@ error_code KRB5PLACEHOLD_87, "KRB5 error code 87" + error_code KRB5PLACEHOLD_88, "KRB5 error code 88" + error_code KRB5PLACEHOLD_89, "KRB5 error code 89" + error_code KRB5PLACEHOLD_90, "KRB5 error code 90" +-error_code KRB5PLACEHOLD_91, "KRB5 error code 91" ++error_code KRB5KDC_ERR_MORE_PREAUTH_DATA_REQUIRED, "More preauthentication data is required" + error_code KRB5PLACEHOLD_92, "KRB5 error code 92" + error_code KRB5KDC_ERR_UNKNOWN_CRITICAL_FAST_OPTION, "An unsupported critical FAST option was requested" + error_code KRB5PLACEHOLD_94, "KRB5 error code 94" +diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c +index f9bc027..fa8afcc 100644 +--- a/src/lib/krb5/krb/get_in_tkt.c ++++ b/src/lib/krb5/krb/get_in_tkt.c +@@ -1239,7 +1239,8 @@ init_creds_step_request(krb5_context context, + clear_cc_config_out_data(context, ctx); + + if (ctx->err_reply == NULL) { +- /* either our first attempt, or retrying after PREAUTH_NEEDED */ ++ /* Either our first attempt, or retrying after KDC_ERR_PREAUTH_REQUIRED ++ * or KDC_ERR_MORE_PREAUTH_DATA_REQUIRED. */ + code = k5_preauth(context, ctx, ctx->preauth_to_use, + ctx->preauth_required, &ctx->request->padata, + &ctx->selected_preauth_type); +@@ -1408,6 +1409,7 @@ init_creds_step_reply(krb5_context context, + krb5_preauthtype kdc_pa_type; + krb5_boolean retry = FALSE; + int canon_flag = 0; ++ uint32_t reply_code; + krb5_keyblock *strengthen_key = NULL; + krb5_keyblock encrypting_key; + krb5_boolean fast_avail; +@@ -1431,6 +1433,7 @@ init_creds_step_reply(krb5_context context, + &retry); + if (code != 0) + goto cleanup; ++ reply_code = ctx->err_reply->error; + if (negotiation_requests_restart(context, ctx, ctx->err_padata)) { + ctx->have_restarted = 1; + k5_preauth_request_context_fini(context); +@@ -1441,9 +1444,10 @@ init_creds_step_reply(krb5_context context, + ctx->err_reply = NULL; + krb5_free_pa_data(context, ctx->err_padata); + ctx->err_padata = NULL; +- } else if (ctx->err_reply->error == KDC_ERR_PREAUTH_REQUIRED && +- retry) { ++ } else if ((reply_code == KDC_ERR_MORE_PREAUTH_DATA_REQUIRED || ++ reply_code == KDC_ERR_PREAUTH_REQUIRED) && retry) { + /* reset the list of preauth types to try */ ++ k5_reset_preauth_types_tried(context); + krb5_free_pa_data(context, ctx->preauth_to_use); + ctx->preauth_to_use = ctx->err_padata; + ctx->err_padata = NULL; +@@ -1480,8 +1484,7 @@ init_creds_step_reply(krb5_context context, + code = 0; + } else { + /* error + no hints = give up */ +- code = (krb5_error_code)ctx->err_reply->error + +- ERROR_TABLE_BASE_krb5; ++ code = (krb5_error_code)reply_code + ERROR_TABLE_BASE_krb5; + } + } + diff --git a/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch b/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch new file mode 100644 index 0000000..2aa2b93 --- /dev/null +++ b/SOURCES/krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch @@ -0,0 +1,22 @@ +# Fix for RH Bug #1250154 ("[s390x, ppc64, ppc64le]: kadmind does not +# accept ACL if kadm5.acl does not end with EOL") +# The code "accidently" works on x86/AMD64 because declaring a variable +# |char| results in an |unsigned char| by default while most other platforms +# (e.g. { s390x, ppc64, ppc64le, ...} ) default to |signed char|. +# Lesson learned: Use lint(1) for development by default (saying that +# because Sun Studio lint(1) has found 38 more of these issues in +# krb1.13.2... ;-( ) +# Written by Roland Mainz +--- a/src/lib/kadm5/srv/server_acl.c ++++ b/src/lib/kadm5/srv/server_acl.c +@@ -115,7 +115,7 @@ + int byte; + byte = fgetc(fp); + acl_buf[i] = byte; +- if (byte == (char)EOF) { ++ if (byte == EOF) { + if (i > 0 && acl_buf[i-1] == '\\') + i--; + break; /* it gets nulled-out below */ + + diff --git a/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch b/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch new file mode 100644 index 0000000..72ee35b --- /dev/null +++ b/SOURCES/krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch @@ -0,0 +1,205 @@ +# Note: This file contains TWO patches, first the fix for the original +# issue and then the valgrind fixes (modifed from the upstream commit +# to match krb5 1.13.2) +####################################################################### +#### Patch1: +From 50f426ac17a81ff5b7c212c24645b9874ea911f0 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Mon, 17 Aug 2015 13:21:42 -0400 +Subject: [PATCH] Resolve krb5 GSS creds if time_rec is requested + +The code normally tries to defer credential acquisition to a later +time. However, if the application requests the lifetime, the code +needs to resolve the credential and return the actual expiration time. +Returning 0 would cause the application to think credentials are +expired. + +In the mechglue, pass through null time_rec pointers to the mech so +that the mech knows whether it was requested. In SPNEGO, pass through +time_rec to the mech when acquiring creds, via a new parameter to +get_available_mechs(). + +[ghudson@mit.edu: minor style changes; edit and expand commit message] + +ticket: 8235 (new) +--- +# Comments: +# - Added to fix RedHat bug #1252454 ('testsuite complains "Lifetime has +# increased by 32436 sec while 0 sec passed!", while rhel5-libkrb5 passes') +# - Original upstream URL https://github.com/krb5/krb5/commit/50f426ac17a81ff5b7c212c24645b9874ea911f0 +--- + src/lib/gssapi/krb5/acquire_cred.c | 9 ++++++++- + src/lib/gssapi/mechglue/g_acquire_cred.c | 14 +++++++++----- + src/lib/gssapi/spnego/spnego_mech.c | 15 ++++++++------- + 3 files changed, 25 insertions(+), 13 deletions(-) + +diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c +index 5bcfec9..6e83fb9 100644 +--- a/src/lib/gssapi/krb5/acquire_cred.c ++++ b/src/lib/gssapi/krb5/acquire_cred.c +@@ -825,8 +825,15 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, + if (code != 0) + goto krb_error_out; + +- if (time_rec) ++ if (time_rec) { ++ /* Resolve cred now to determine the expiration time. */ ++ ret = kg_cred_resolve(minor_status, context, (gss_cred_id_t)cred, ++ GSS_C_NO_NAME); ++ if (GSS_ERROR(ret)) ++ goto error_out; + *time_rec = (cred->expire > now) ? (cred->expire - now) : 0; ++ k5_mutex_unlock(&cred->lock); ++ } + } + + *minor_status = 0; +diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c +index ff250de..d29856c 100644 +--- a/src/lib/gssapi/mechglue/g_acquire_cred.c ++++ b/src/lib/gssapi/mechglue/g_acquire_cred.c +@@ -190,8 +190,9 @@ OM_uint32 * time_rec; + major = gss_add_cred_from(&tmpMinor, (gss_cred_id_t)creds, + desired_name, &mechs->elements[i], + cred_usage, time_req, time_req, +- cred_store, NULL, NULL, &initTimeOut, +- &acceptTimeOut); ++ cred_store, NULL, NULL, ++ time_rec ? &initTimeOut : NULL, ++ time_rec ? &acceptTimeOut : NULL); + if (major == GSS_S_COMPLETE) { + /* update the credential's time */ + if (cred_usage == GSS_C_ACCEPT) { +@@ -356,7 +357,7 @@ gss_add_cred_from(minor_status, input_cred_handle, + OM_uint32 *acceptor_time_rec; + { + OM_uint32 status, temp_minor_status; +- OM_uint32 time_req, time_rec; ++ OM_uint32 time_req, time_rec = 0, *time_recp = NULL; + gss_union_name_t union_name; + gss_union_cred_t new_union_cred, union_cred; + gss_name_t internal_name = GSS_C_NO_NAME; +@@ -447,15 +448,18 @@ gss_add_cred_from(minor_status, input_cred_handle, + if (status != GSS_S_COMPLETE) + goto errout; + ++ if (initiator_time_rec != NULL || acceptor_time_rec != NULL) ++ time_recp = &time_rec; ++ + if (mech->gss_acquire_cred_from) { + status = mech->gss_acquire_cred_from(minor_status, internal_name, + time_req, target_mechs, + cred_usage, cred_store, &cred, +- NULL, &time_rec); ++ NULL, time_recp); + } else if (cred_store == GSS_C_NO_CRED_STORE) { + status = mech->gss_acquire_cred(minor_status, internal_name, time_req, + target_mechs, cred_usage, &cred, NULL, +- &time_rec); ++ time_recp); + } else { + return GSS_S_UNAVAILABLE; + } +diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c +index 8ade245..f3d5f09 100644 +--- a/src/lib/gssapi/spnego/spnego_mech.c ++++ b/src/lib/gssapi/spnego/spnego_mech.c +@@ -96,7 +96,8 @@ static gss_OID_set get_mech_set(OM_uint32 *, unsigned char **, unsigned int); + static OM_uint32 get_req_flags(unsigned char **, OM_uint32, OM_uint32 *); + static OM_uint32 get_available_mechs(OM_uint32 *, gss_name_t, gss_cred_usage_t, + gss_const_key_value_set_t, +- gss_cred_id_t *, gss_OID_set *); ++ gss_cred_id_t *, gss_OID_set *, ++ OM_uint32 *); + static OM_uint32 get_negotiable_mechs(OM_uint32 *, spnego_gss_cred_id_t, + gss_cred_usage_t, gss_OID_set *); + static void release_spnego_ctx(spnego_gss_ctx_id_t *); +@@ -399,7 +400,7 @@ spnego_gss_acquire_cred_from(OM_uint32 *minor_status, + */ + status = get_available_mechs(minor_status, desired_name, + cred_usage, cred_store, &mcred, +- &amechs); ++ &amechs, time_rec); + + if (actual_mechs && amechs != GSS_C_NULL_OID_SET) { + (void) gssint_copy_oid_set(&tmpmin, amechs, actual_mechs); +@@ -2009,7 +2010,7 @@ spnego_gss_inquire_cred( + GSS_C_BOTH, + GSS_C_NO_CRED_STORE, + &creds, +- mechanisms); ++ mechanisms, NULL); + if (status != GSS_S_COMPLETE) { + dsyslog("Leaving inquire_cred\n"); + return (status); +@@ -2637,7 +2638,7 @@ spnego_gss_acquire_cred_with_password(OM_uint32 *minor_status, + + status = get_available_mechs(minor_status, desired_name, + cred_usage, GSS_C_NO_CRED_STORE, +- NULL, &amechs); ++ NULL, &amechs, NULL); + if (status != GSS_S_COMPLETE) + goto cleanup; + +@@ -3006,7 +3007,7 @@ static OM_uint32 + get_available_mechs(OM_uint32 *minor_status, + gss_name_t name, gss_cred_usage_t usage, + gss_const_key_value_set_t cred_store, +- gss_cred_id_t *creds, gss_OID_set *rmechs) ++ gss_cred_id_t *creds, gss_OID_set *rmechs, OM_uint32 *time_rec) + { + unsigned int i; + int found = 0; +@@ -3060,7 +3061,7 @@ get_available_mechs(OM_uint32 *minor_status, + GSS_C_INDEFINITE, + *rmechs, usage, + cred_store, creds, +- &goodmechs, NULL); ++ &goodmechs, time_rec); + + /* + * Drop the old list in favor of the new +@@ -3110,7 +3111,7 @@ get_negotiable_mechs(OM_uint32 *minor_status, spnego_gss_cred_id_t spcred, + credptr = (usage == GSS_C_INITIATE) ? &creds : NULL; + ret = get_available_mechs(minor_status, GSS_C_NO_NAME, usage, + GSS_C_NO_CRED_STORE, credptr, +- rmechs); ++ rmechs, NULL); + gss_release_cred(&tmpmin, &creds); + return (ret); + } +####################################################################### +#### Patch2: +From 042e9fc95a662acb54dc9168749c6725f17ae34a Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Fri, 21 Aug 2015 12:16:07 -0400 +Subject: [PATCH] Keep valgrind happy after time_rec change + +In gss_acquire_cred_from(), initialize initTimeOut and acceptTimeOut +so valgrind does not complain. All these values are ignored if +time_rec is NULL, so not having those variables initialized is +harmless, but it is annoying to get noise in the valgrind output. + +[ghudson@mit.edu: clarify commit message] + +ticket: 8235 +--- +# Comments: +# - modifed by Roland Mainz to match krb5 1.13.2 +--- + src/lib/gssapi/mechglue/g_acquire_cred.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/lib/gssapi/mechglue/g_acquire_cred.c b/src/lib/gssapi/mechglue/g_acquire_cred.c +index d29856c..9bd500b 100644 +--- a/src/lib/gssapi/mechglue/g_acquire_cred.c ++++ b/src/lib/gssapi/mechglue/g_acquire_cred.c +@@ -133,7 +133,7 @@ OM_uint32 * time_rec; + { + OM_uint32 major = GSS_S_FAILURE, tmpMinor; + OM_uint32 first_major = GSS_S_COMPLETE, first_minor = 0; +- OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE; ++ OM_uint32 initTimeOut = 0, acceptTimeOut = 0, outTime = GSS_C_INDEFINITE; + gss_OID_set mechs = GSS_C_NO_OID_SET; + unsigned int i; + gss_union_cred_t creds = NULL; diff --git a/SOURCES/krb5-1.3.4-send-pr-tempfile.patch b/SOURCES/krb5-1.3.4-send-pr-tempfile.patch deleted file mode 100644 index a9ffa31..0000000 --- a/SOURCES/krb5-1.3.4-send-pr-tempfile.patch +++ /dev/null @@ -1,41 +0,0 @@ -Use mktemp to create our temporary files instead of basing them on our PID. -Only portable if you assume the presence of a mktemp helper. -diff -ur krb5-1.3.4/src/util/send-pr/send-pr.sh krb5-1.3.4/src/util/send-pr/send-pr.sh ---- krb5-1.3.4/src/util/send-pr/send-pr.sh 1997-03-20 01:13:56.000000000 +0100 -+++ krb5-1.3.4/src/util/send-pr/send-pr.sh 2004-09-20 11:28:56.000000000 +0200 -@@ -96,9 +96,9 @@ - fi - fi - --TEMP=$TMPDIR/p$$ --BAD=$TMPDIR/pbad$$ --REF=$TMPDIR/pf$$ -+TEMP=`mktemp "$TMPDIR"/p.XXXXXX` || exit 1 -+BAD=`mktemp "$TMPDIR"/pbad.XXXXXX` || exit 1 -+REF=`mktemp "$TMPDIR"/pf.XXXXXX` || exit 1 - - # find a user name - if [ "$LOGNAME" = "" ]; then -@@ -122,9 +122,10 @@ - else - # Must use temp file due to incompatibilities in quoting behavior - # and to protect shell metacharacters in the expansion of $LOGNAME -- $PASSWD | grep "^$LOGNAME:" | awk -F: '{print $5}' | sed -e 's/,.*//' > $TEMP -- ORIGINATOR="`cat $TEMP`" -- rm -f $TEMP -+ TEMP2=`mktemp "$TMPDIR"/plogname.XXXXXX` || exit 1 -+ $PASSWD | grep "^$LOGNAME:" | awk -F: '{print $5}' | sed -e 's/,.*//' > $TEMP2 -+ ORIGINATOR="`cat $TEMP2`" -+ rm -f $TEMP2 - fi - - if [ -n "$ORGANIZATION" ]; then -@@ -280,7 +281,7 @@ - # Catch some signals. ($xs kludge needed by Sun /bin/sh) - xs=0 - trap 'rm -f $REF $TEMP; exit $xs' 0 --trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15 -+trap 'echo "$COMMAND: Aborting ..."; rm -f "$REF" "$BAD" "$TEMP"; xs=1; exit' 1 2 3 13 15 - - # If they told us to use a specific file, then do so. - if [ -n "$IN_FILE" ]; then diff --git a/SOURCES/krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch b/SOURCES/krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch deleted file mode 100644 index e96c360..0000000 --- a/SOURCES/krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch +++ /dev/null @@ -1,63 +0,0 @@ -From d1f707024f1d0af6e54a18885322d70fa15ec4d3 Mon Sep 17 00:00:00 2001 -From: Greg Hudson -Date: Fri, 5 Dec 2014 14:01:39 -0500 -Subject: [PATCH] Fix LDAP misused policy name crash [CVE-2014-5353] - -In krb5_ldap_get_password_policy_from_dn, if LDAP_SEARCH returns -successfully with no results, return KRB5_KDB_NOENTRY instead of -returning success with a zeroed-out policy object. This fixes a null -dereference when an admin attempts to use an LDAP ticket policy name -as a password policy name. - -CVE-2014-5353: - -In MIT krb5, when kadmind is configured to use LDAP for the KDC -database, an authenticated remote attacker can cause a NULL dereference -by attempting to use a named ticket policy object as a password policy -for a principal. The attacker needs to be authenticated as a user who -has the elevated privilege for setting password policy by adding or -modifying principals. - -Queries to LDAP scoped to the krbPwdPolicy object class will correctly -not return entries of other classes, such as ticket policy objects, but -may return success with no returned elements if an object with the -requested DN exists in a different object class. In this case, the -routine to retrieve a password policy returned success with a password -policy object that consisted entirely of zeroed memory. In particular, -accesses to the policy name will dereference a NULL pointer. KDC -operation does not access the policy name field, but most kadmin -operations involving the principal with incorrect password policy -will trigger the crash. - -Thanks to Patrik Kis for reporting this problem. - -CVSSv2 Vector: AV:N/AC:M/Au:S/C:N/I:N/A:C/E:H/RL:OF/RC:C - -[kaduk@mit.edu: CVE description and CVSS score] - -ticket: 8051 (new) -target_version: 1.13.1 -tags: pullup ---- - src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c -index 522773e..6779f51 100644 ---- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c -+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c -@@ -314,10 +314,11 @@ krb5_ldap_get_password_policy_from_dn(krb5_context context, char *pol_name, - LDAP_SEARCH(pol_dn, LDAP_SCOPE_BASE, "(objectclass=krbPwdPolicy)", password_policy_attributes); - - ent=ldap_first_entry(ld, result); -- if (ent != NULL) { -- if ((st = populate_policy(context, ld, ent, pol_name, *policy)) != 0) -- goto cleanup; -+ if (ent == NULL) { -+ st = KRB5_KDB_NOENTRY; -+ goto cleanup; - } -+ st = populate_policy(context, ld, ent, pol_name, *policy); - - cleanup: - ldap_msgfree(result); diff --git a/SOURCES/krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch b/SOURCES/krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch deleted file mode 100644 index 01aef2c..0000000 --- a/SOURCES/krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 04038bf3633c4b909b5ded3072dc88c8c419bf16 Mon Sep 17 00:00:00 2001 -From: Ben Kaduk -Date: Wed, 19 Nov 2014 12:04:46 -0500 -Subject: [PATCH] Support keyless principals in LDAP [CVE-2014-5354] - -Operations like "kadmin -q 'addprinc -nokey foo'" or -"kadmin -q 'purgekeys -all foo'" result in principal entries with -no keys present, so krb5_encode_krbsecretkey() would just return -NULL, which then got unconditionally dereferenced in -krb5_add_ber_mem_ldap_mod(). - -Apply some fixes to krb5_encode_krbsecretkey() to handle zero-key -principals better, correct the test for an allocation failure, and -slightly restructure the cleanup handler to be shorter and more -appropriate for the usage. Once it no longer short-circuits when -n_key_data is zero, it will produce an array of length two with both -entries NULL, which is treated as an empty list by the LDAP library, -the correct behavior for a keyless principal. - -However, attributes with empty values are only handled by the LDAP -library for Modify operations, not Add operations (which only get -a sequence of Attribute, with no operation field). Therefore, only -add an empty krbprincipalkey to the modlist when we will be performing a -Modify, and not when we will be performing an Add, which is conditional -on the (misspelled) create_standalone_prinicipal boolean. - -CVE-2014-5354: - -In MIT krb5, when kadmind is configured to use LDAP for the KDC -database, an authenticated remote attacker can cause a NULL -dereference by inserting into the database a principal entry which -contains no long-term keys. - -In order for the LDAP KDC backend to translate a principal entry -from the database abstraction layer into the form expected by the -LDAP schema, the principal's keys are encoded into a -NULL-terminated array of length-value entries to be stored in the -LDAP database. However, the subroutine which produced this array -did not correctly handle the case where no keys were present, -returning NULL instead of an empty array, and the array was -unconditionally dereferenced while adding to the list of LDAP -operations to perform. - -Versions of MIT krb5 prior to 1.12 did not expose a way for -principal entries to have no long-term key material, and -therefore are not vulnerable. - - CVSSv2 Vector: AV:N/AC:M/Au:S/C:N/I:N/A:P/E:H/RL:OF/RC:C - -ticket: 8041 (new) -tags: pullup -target_version: 1.13.1 -subject: kadmind with ldap backend crashes when putting keyless entries ---- - src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c | 25 +++++++++++++++------- - 1 file changed, 17 insertions(+), 8 deletions(-) - -diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c -index 3e560d9..10b5982 100644 ---- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c -+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c -@@ -406,14 +406,14 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int n_key_data, - int num_versions = 1; - int i, j, last; - krb5_error_code err = 0; -- krb5_key_data *key_data; -+ krb5_key_data *key_data = NULL; - -- if (n_key_data <= 0) -+ if (n_key_data < 0) - return NULL; - - /* Make a shallow copy of the key data so we can alter it. */ - key_data = k5calloc(n_key_data, sizeof(*key_data), &err); -- if (key_data_in == NULL) -+ if (key_data == NULL) - goto cleanup; - memcpy(key_data, key_data_in, n_key_data * sizeof(*key_data)); - -@@ -467,9 +467,8 @@ krb5_encode_krbsecretkey(krb5_key_data *key_data_in, int n_key_data, - free(key_data); - if (err != 0) { - if (ret != NULL) { -- for (i = 0; i <= num_versions; i++) -- if (ret[i] != NULL) -- free (ret[i]); -+ for (i = 0; ret[i] != NULL; i++) -+ free (ret[i]); - free (ret); - ret = NULL; - } -@@ -1036,9 +1035,19 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, - bersecretkey = krb5_encode_krbsecretkey (entry->key_data, - entry->n_key_data, mkvno); - -- if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey", -- LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, bersecretkey)) != 0) -+ if (bersecretkey == NULL) { -+ st = ENOMEM; - goto cleanup; -+ } -+ /* An empty list of bervals is only accepted for modify operations, -+ * not add operations. */ -+ if (bersecretkey[0] != NULL || !create_standalone_prinicipal) { -+ st = krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey", -+ LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, -+ bersecretkey); -+ if (st != 0) -+ goto cleanup; -+ } - - if (!(entry->mask & KADM5_PRINCIPAL)) { - memset(strval, 0, sizeof(strval)); diff --git a/SOURCES/krb5-ksu_not_working_with_default_principal.patch b/SOURCES/krb5-ksu_not_working_with_default_principal.patch deleted file mode 100644 index 01ecdac..0000000 --- a/SOURCES/krb5-ksu_not_working_with_default_principal.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 3a32e1e6e644c6092f48cf6b6f2d0b8635b3dd52 Mon Sep 17 00:00:00 2001 -From: Nalin Dahyabhai -Date: Wed, 30 Jul 2014 17:12:31 -0400 -Subject: [PATCH] In ksu, without the -e flag, also check .k5users - -When ksu was explicitly told to spawn a shell, a line in .k5users which -listed "*" as the allowed command would cause the principal named on the -line to be considered as a candidate for authentication. - -When ksu was not passed a command to run, which implicitly meant that -the invoking user wanted to run the target user's login shell, knowledge -that the principal was a valid candidate was ignored, which could cause -a less optimal choice of the default target principal. - -This doesn't impact the authorization checks which we perform later. - -ticket: 7983 (new) ---- - src/clients/ksu/heuristic.c | 19 ++++++------------- - 1 file changed, 6 insertions(+), 13 deletions(-) - -diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c -index c7e691c..99b54e5 100644 ---- a/src/clients/ksu/heuristic.c -+++ b/src/clients/ksu/heuristic.c -@@ -264,20 +264,13 @@ get_authorized_princ_names(luser, cmd, princ_list) - - close_time(k5users_flag,users_fp, k5login_flag, login_fp); - -- if (cmd) { -- retval = list_union(k5login_list, k5users_filt_list, &combined_list); -- if (retval){ -- close_time(k5users_flag,users_fp, k5login_flag,login_fp); -- return retval; -- } -- *princ_list = combined_list; -- return 0; -- } else { -- if (k5users_filt_list != NULL) -- free(k5users_filt_list); -- *princ_list = k5login_list; -- return 0; -+ retval = list_union(k5login_list, k5users_filt_list, &combined_list); -+ if (retval){ -+ close_time(k5users_flag,users_fp, k5login_flag,login_fp); -+ return retval; - } -+ *princ_list = combined_list; -+ return 0; - } - - static void close_time(k5users_flag, users_fp, k5login_flag, login_fp) diff --git a/SOURCES/krb5-master-compatible-keys.patch b/SOURCES/krb5-master-compatible-keys.patch deleted file mode 100644 index 7c36e05..0000000 --- a/SOURCES/krb5-master-compatible-keys.patch +++ /dev/null @@ -1,56 +0,0 @@ -commit 4f99c75eb6b1a53d78b26648e39309261e37755c -Author: Nalin Dahyabhai -Date: Tue Mar 18 16:39:47 2014 -0400 - - Try compatible keys in rd_req_dec "any" path - - When we go to decrypt a ticket using a keytab, we have two code paths. - - In the first (traditional) one, we try to read an entry that exactly - matches the principal name, enctype, and kvno from the ticket, and then - attempt to decrypt the ticket using the entry's key. The keytab - routines helpfully return an entry so long as it's of a key type that's - compatible with the ticket being decrypted, fixing up the enctype in the - entry structure while doing so, allowing us to decrypt a DES-CBC-CRC - ticket with a DES-CBC-MD5 key. - - In the second code path, we try the key of every entry which loosely - matches the principal name from the ticket and which exactly matches its - enctype, meaning that the ticket/keytab pair above won't work if the - principal name is one which suggests we shouldn't be matching entries - exactly. - - This change modifies the "any" path to also try to decrypt the ticket - with compatible keys. - - [ghudson@mit.edu: avoid stuffing too much logic in one conditional] - - ticket: 7883 (new) - -diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c -index 4b952f5..fbd088d 100644 ---- a/src/lib/krb5/krb/rd_req_dec.c -+++ b/src/lib/krb5/krb/rd_req_dec.c -@@ -167,6 +167,8 @@ decrypt_ticket(krb5_context context, const krb5_ap_req *req, - krb5_error_code ret; - krb5_keytab_entry ent; - krb5_kt_cursor cursor; -+ krb5_boolean similar; -+ krb5_enctype req_etype = req->ticket->enc_part.enctype; - - #ifdef LEAN_CLIENT - return KRB5KRB_AP_WRONG_PRINC; -@@ -189,8 +191,12 @@ decrypt_ticket(krb5_context context, const krb5_ap_req *req, - goto cleanup; - - while ((ret = krb5_kt_next_entry(context, keytab, &ent, &cursor)) == 0) { -- if (ent.key.enctype == req->ticket->enc_part.enctype && -+ ret = krb5_c_enctype_compare(context, ent.key.enctype, req_etype, -+ &similar); -+ if (ret == 0 && similar && - krb5_sname_match(context, server, ent.principal)) { -+ /* Coerce inexact matches to the request enctype. */ -+ ent.key.enctype = req_etype; - ret = try_one_entry(context, req, &ent, keyblock_out); - if (ret == 0) { - TRACE_RD_REQ_DECRYPT_ANY(context, ent.principal, &ent.key); diff --git a/SOURCES/krb5-master-mechd.patch b/SOURCES/krb5-master-mechd.patch deleted file mode 100644 index 965a436..0000000 --- a/SOURCES/krb5-master-mechd.patch +++ /dev/null @@ -1,275 +0,0 @@ -commit 123c14fd8862ee8f11f6084d25958cb380655f35 -Author: Günther Deschner -Date: Wed Mar 5 16:21:55 2014 +0100 - - Remove dead code from the mechglue initialization - - The stat check in gss_indicate_mechs had no consequent and would have - been redundant with logic in updateMechList if it did. - - [ghudson@mit.edu: elaborated commit message; removed unused - g_mechSetTime and now-irrelevant comment] - -diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c -index 48a825e..c6904e0 100644 ---- a/src/lib/gssapi/mechglue/g_initialize.c -+++ b/src/lib/gssapi/mechglue/g_initialize.c -@@ -91,7 +91,6 @@ static gss_mech_info g_mechListTail = NULL; - static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER; - static time_t g_confFileModTime = (time_t)0; - --static time_t g_mechSetTime = (time_t)0; - static gss_OID_set_desc g_mechSet = { 0, NULL }; - static k5_mutex_t g_mechSetLock = K5_MUTEX_PARTIAL_INITIALIZER; - -@@ -213,8 +212,6 @@ gss_indicate_mechs(minorStatus, mechSet_out) - OM_uint32 *minorStatus; - gss_OID_set *mechSet_out; - { -- char *fileName; -- struct stat fileInfo; - OM_uint32 status; - - /* Initialize outputs. */ -@@ -233,16 +230,6 @@ gss_OID_set *mechSet_out; - if (*minorStatus != 0) - return (GSS_S_FAILURE); - -- fileName = MECH_CONF; -- -- /* -- * If we have already computed the mechanisms supported and if it -- * is still valid; make a copy and return to caller, -- * otherwise build it first. -- */ -- if ((stat(fileName, &fileInfo) == 0 && -- fileInfo.st_mtime > g_mechSetTime)) { -- } /* if g_mechSet is out of date or not initialized */ - if (build_mechSet()) - return GSS_S_FAILURE; - -@@ -289,20 +276,6 @@ build_mechSet(void) - */ - k5_mutex_lock(&g_mechListLock); - --#if 0 -- /* -- * this checks for the case when we need to re-construct the -- * g_mechSet structure, but the mechanism list is upto date -- * (because it has been read by someone calling -- * gssint_get_mechanism) -- */ -- if (fileInfo.st_mtime > g_confFileModTime) -- { -- g_confFileModTime = fileInfo.st_mtime; -- loadConfigFile(fileName); -- } --#endif -- - updateMechList(); - - /* - -commit 05cbef80d53f49d30a5d0563501226dc173734d4 -Author: Günther Deschner -Date: Wed Mar 5 15:25:43 2014 +0100 - - Load mechglue config files from /etc/gss/mech.d - - In addition to loading /etc/gss/mech, glob for *.conf files in - /etc/gss/mech.d. Load only config files which have changed since the - highest mtime we saw in the previous scan. Scan at most once per - second to avoid excessive numbers of filesystem syscalls for busy - GSSAPI applications. - - [ghudson@mit.edu: rewrote commit message; style changes; added - once-per-second throttle on glob/stat calls] - - ticket: 7882 (new) - -diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c -index c6904e0..f0acf1a 100644 ---- a/src/lib/gssapi/mechglue/g_initialize.c -+++ b/src/lib/gssapi/mechglue/g_initialize.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - - #define M_DEFAULT "default" - -@@ -58,6 +59,7 @@ - #ifndef MECH_CONF - #define MECH_CONF "/etc/gss/mech" - #endif -+#define MECH_CONF_PATTERN MECH_CONF ".d/*.conf" - - /* Local functions */ - static void addConfigEntry(const char *oidStr, const char *oid, -@@ -90,6 +92,7 @@ static gss_mech_info g_mechList = NULL; - static gss_mech_info g_mechListTail = NULL; - static k5_mutex_t g_mechListLock = K5_MUTEX_PARTIAL_INITIALIZER; - static time_t g_confFileModTime = (time_t)0; -+static time_t g_confLastCall = (time_t)0; - - static gss_OID_set_desc g_mechSet = { 0, NULL }; - static k5_mutex_t g_mechSetLock = K5_MUTEX_PARTIAL_INITIALIZER; -@@ -383,6 +386,56 @@ const gss_OID oid; - return (modOptions); - } /* gssint_get_modOptions */ - -+/* Return the mtime of filename or its eventual symlink target (if it is a -+ * symlink), whichever is larger. Return (time_t)-1 if lstat or stat fails. */ -+static time_t -+check_link_mtime(const char *filename, time_t *mtime_out) -+{ -+ struct stat st1, st2; -+ -+ if (lstat(filename, &st1) != 0) -+ return (time_t)-1; -+ if (!S_ISLNK(st1.st_mode)) -+ return st1.st_mtime; -+ if (stat(filename, &st2) != 0) -+ return (time_t)-1; -+ return (st1.st_mtime > st2.st_mtime) ? st1.st_mtime : st2.st_mtime; -+} -+ -+/* Try to load any config files which have changed since the last call. Config -+ * files are MECH_CONF and any files matching MECH_CONF_PATTERN. */ -+static void -+loadConfigFiles() -+{ -+ glob_t globbuf; -+ time_t highest_mtime = 0, mtime, now; -+ char **pathptr; -+ -+ /* Don't glob and stat more than once per second. */ -+ if (time(&now) == (time_t)-1 || now == g_confLastCall) -+ return; -+ g_confLastCall = now; -+ -+ globbuf.gl_offs = 1; -+ if (glob(MECH_CONF_PATTERN, GLOB_DOOFFS, NULL, &globbuf) != 0) -+ return; -+ globbuf.gl_pathv[0] = MECH_CONF; -+ -+ for (pathptr = globbuf.gl_pathv; *pathptr != NULL; pathptr++) { -+ mtime = check_link_mtime(*pathptr, &mtime); -+ if (mtime == (time_t)-1) -+ continue; -+ if (mtime > highest_mtime) -+ highest_mtime = mtime; -+ if (mtime > g_confFileModTime) -+ loadConfigFile(*pathptr); -+ } -+ g_confFileModTime = highest_mtime; -+ -+ globbuf.gl_pathv[0] = NULL; -+ globfree(&globbuf); -+} -+ - /* - * determines if the mechList needs to be updated from file - * and performs the update. -@@ -401,17 +454,7 @@ updateMechList(void) - loadConfigFromRegistry(HKEY_CURRENT_USER, MECH_KEY); - loadConfigFromRegistry(HKEY_LOCAL_MACHINE, MECH_KEY); - #else /* _WIN32 */ -- char *fileName; -- struct stat fileInfo; -- -- fileName = MECH_CONF; -- -- /* check if mechList needs updating */ -- if (stat(fileName, &fileInfo) != 0 || -- g_confFileModTime >= fileInfo.st_mtime) -- return; -- g_confFileModTime = fileInfo.st_mtime; -- loadConfigFile(fileName); -+ loadConfigFiles(); - #endif /* !_WIN32 */ - - /* Load any unloaded interposer mechanisms immediately, to make sure we - -commit ac98187641f6943ae571606c0b6a97f236f9b60c -Author: Greg Hudson -Date: Wed May 28 23:51:49 2014 -0400 - - Read /etc/gss/mech if no mech.d/*.conf found - - Always read /etc/gss/mech, even if globbing /etc/gss/mech.d/*.conf - doesn't work. Doing this using GLOB_DOOFFS proved error-prone, so use - a simpler approach: factor out the per-pathname handling into a helper - function load_if_changed, call it with MECH_CONF before the glob, then - pass each glob result through the helper. - - ticket: 7925 - -diff --git a/src/lib/gssapi/mechglue/g_initialize.c b/src/lib/gssapi/mechglue/g_initialize.c -index f0acf1a..8bce14c 100644 ---- a/src/lib/gssapi/mechglue/g_initialize.c -+++ b/src/lib/gssapi/mechglue/g_initialize.c -@@ -402,38 +402,45 @@ check_link_mtime(const char *filename, time_t *mtime_out) - return (st1.st_mtime > st2.st_mtime) ? st1.st_mtime : st2.st_mtime; - } - -+/* Load pathname if it is newer than last. Update *highest to the maximum of -+ * its current value and pathname's mod time. */ -+static void -+load_if_changed(const char *pathname, time_t last, time_t *highest) -+{ -+ time_t mtime; -+ -+ mtime = check_link_mtime(pathname, &mtime); -+ if (mtime == (time_t)-1) -+ return; -+ if (mtime > *highest) -+ *highest = mtime; -+ if (mtime > last) -+ loadConfigFile(pathname); -+} -+ - /* Try to load any config files which have changed since the last call. Config - * files are MECH_CONF and any files matching MECH_CONF_PATTERN. */ - static void - loadConfigFiles() - { - glob_t globbuf; -- time_t highest_mtime = 0, mtime, now; -- char **pathptr; -+ time_t highest = 0, now; -+ char **path; - - /* Don't glob and stat more than once per second. */ - if (time(&now) == (time_t)-1 || now == g_confLastCall) - return; - g_confLastCall = now; - -- globbuf.gl_offs = 1; -- if (glob(MECH_CONF_PATTERN, GLOB_DOOFFS, NULL, &globbuf) != 0) -- return; -- globbuf.gl_pathv[0] = MECH_CONF; -+ load_if_changed(MECH_CONF, g_confFileModTime, &highest); - -- for (pathptr = globbuf.gl_pathv; *pathptr != NULL; pathptr++) { -- mtime = check_link_mtime(*pathptr, &mtime); -- if (mtime == (time_t)-1) -- continue; -- if (mtime > highest_mtime) -- highest_mtime = mtime; -- if (mtime > g_confFileModTime) -- loadConfigFile(*pathptr); -+ if (glob(MECH_CONF_PATTERN, 0, NULL, &globbuf) == 0) { -+ for (path = globbuf.gl_pathv; *path != NULL; path++) -+ load_if_changed(*path, g_confFileModTime, &highest); -+ globfree(&globbuf); - } -- g_confFileModTime = highest_mtime; - -- globbuf.gl_pathv[0] = NULL; -- globfree(&globbuf); -+ g_confFileModTime = highest; - } - - /* diff --git a/SOURCES/krb5-master-move-otp-sockets.patch b/SOURCES/krb5-master-move-otp-sockets.patch deleted file mode 100644 index 8d86930..0000000 --- a/SOURCES/krb5-master-move-otp-sockets.patch +++ /dev/null @@ -1,203 +0,0 @@ -Adjusted to apply to 1.12.2. - -commit 1e4bdcfed2c7bda94d5c135cc32a5993ca032501 -Author: Nathaniel McCallum -Date: Wed Feb 5 10:59:46 2014 -0500 - - Move OTP sockets to KDC_RUN_DIR - - Some system configurations expect Unix-domain sockets to live under - /run or /var/run, and not other parts of /var where persistent - application state lives. Define a new directory KDC_RUN_DIR using - $runstatedir (new in autoconf 2.70, so fall back to $localstatedir/run - if it's not set) and use that for the default socket path. - - [ghudson@mit.edu: commit message, otp.rst formatting fix] - - ticket: 7859 (new) - -diff --git a/doc/admin/otp.rst b/doc/admin/otp.rst -index 0abd5ff..f12c36d 100644 ---- a/doc/admin/otp.rst -+++ b/doc/admin/otp.rst -@@ -23,7 +23,7 @@ the following format:: - - [otp] - = { -- server = (default: $KDCDIR/.socket) -+ server = (default: see below) - secret = - timeout = (default: 5 [seconds]) - retries = (default: 3) -@@ -33,7 +33,8 @@ the following format:: - If the server field begins with '/', it will be interpreted as a UNIX - socket. Otherwise, it is assumed to be in the format host:port. When - a UNIX domain socket is specified, the secret field is optional and an --empty secret is used by default. -+empty secret is used by default. If the server field is not -+specified, it defaults to |kdcrundir|\ ``/.socket``. - - When forwarding the request over RADIUS, by default the principal is - used in the User-Name attribute of the RADIUS packet. The strip_realm -diff --git a/doc/conf.py b/doc/conf.py -index f015fc8..bc8b2bd 100644 ---- a/doc/conf.py -+++ b/doc/conf.py -@@ -231,6 +231,7 @@ if 'mansubs' in tags: - sbindir = '``@SBINDIR@``' - libdir = '``@LIBDIR@``' - localstatedir = '``@LOCALSTATEDIR@``' -+ runstatedir = '``@RUNSTATEDIR@``' - sysconfdir = '``@SYSCONFDIR@``' - ccache = '``@CCNAME@``' - keytab = '``@KTNAME@``' -@@ -243,6 +244,7 @@ else: - sbindir = ':ref:`SBINDIR `' - libdir = ':ref:`LIBDIR `' - localstatedir = ':ref:`LOCALSTATEDIR `' -+ runstatedir = ':ref:`RUNSTATEDIR `' - sysconfdir = ':ref:`SYSCONFDIR `' - ccache = ':ref:`DEFCCNAME `' - keytab = ':ref:`DEFKTNAME `' -@@ -262,6 +264,7 @@ else: - rst_epilog += '.. |sbindir| replace:: %s\n' % sbindir - rst_epilog += '.. |libdir| replace:: %s\n' % libdir - rst_epilog += '.. |kdcdir| replace:: %s\\ ``/krb5kdc``\n' % localstatedir -+ rst_epilog += '.. |kdcrundir| replace:: %s\\ ``/krb5kdc``\n' % runstatedir - rst_epilog += '.. |sysconfdir| replace:: %s\n' % sysconfdir - rst_epilog += '.. |ccache| replace:: %s\n' % ccache - rst_epilog += '.. |keytab| replace:: %s\n' % keytab -diff --git a/doc/mitK5defaults.rst b/doc/mitK5defaults.rst -index 89b8f4c..838dabb 100644 ---- a/doc/mitK5defaults.rst -+++ b/doc/mitK5defaults.rst -@@ -17,6 +17,7 @@ KDC config file :ref:`kdc.conf(5)` |kdcdir|\ ``/kdc.conf`` **KRB - KDC database path (DB2) |kdcdir|\ ``/principal`` - Master key :ref:`stash_definition` |kdcdir|\ ``/.k5.``\ *realm* - Admin server ACL file :ref:`kadm5.acl(5)` |kdcdir|\ ``/kadm5.acl`` -+OTP socket directory |kdcrundir| - Plugin base directory |libdir|\ ``/krb5/plugins`` - :ref:`rcache_definition` directory ``/var/tmp`` **KRB5RCACHEDIR** - Master key default enctype |defmkey| -@@ -64,6 +65,7 @@ Description Symbolic name Custom build path Typical - 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}`` -diff --git a/src/Makefile.in b/src/Makefile.in -index a8bc990..1725093 100644 ---- a/src/Makefile.in -+++ b/src/Makefile.in -@@ -64,6 +64,7 @@ INSTALLMKDIRS = $(KRB5ROOT) $(KRB5MANROOT) $(KRB5OTHERMKDIRS) \ - $(KRB5_AD_MODULE_DIR) \ - $(KRB5_LIBKRB5_MODULE_DIR) $(KRB5_TLS_MODULE_DIR) \ - @localstatedir@ @localstatedir@/krb5kdc \ -+ @runstatedir@ @runstatedir@/krb5kdc \ - $(KRB5_INCSUBDIRS) $(datadir) $(EXAMPLEDIR) \ - $(PKGCONFIG_DIR) - -diff --git a/src/configure.in b/src/configure.in -index 2145d54..c2eaf78 100644 ---- a/src/configure.in -+++ b/src/configure.in -@@ -9,6 +9,12 @@ - fi - AC_SUBST(SYSCONFCONF) - -+# If $runstatedir isn't set by autoconf (<2.70), set it manually. -+if test x"$runstatedir" == x; then -+ runstatedir=$localstatedir/run -+fi -+AC_SUBST(runstatedir) -+ - CONFIG_RULES - KRB5_VERSION=K5_VERSION - AC_SUBST(KRB5_VERSION) -diff --git a/src/doc/Makefile.in b/src/doc/Makefile.in -index a6bb7c5..b07e16a 100644 ---- a/src/doc/Makefile.in -+++ b/src/doc/Makefile.in -@@ -7,6 +7,7 @@ DOXYGEN=doxygen - - docsrc=$(top_srcdir)/../doc - localstatedir=@localstatedir@ -+runstatedir=@runstatedir@ - sysconfdir=@sysconfdir@ - DEFCCNAME=@DEFCCNAME@ - DEFKTNAME=@DEFKTNAME@ -@@ -113,6 +114,7 @@ paths.py: - echo 'sbindir = "``$(SERVER_BINDIR)``"' >> $@ - echo 'libdir = "``$(KRB5_LIBDIR)``"' >> $@ - echo 'localstatedir = "``$(localstatedir)``"' >> $@ -+ echo 'runstatedir = "``$(runstatedir)``"' >> $@ - echo 'sysconfdir = "``$(sysconfdir)``"' >> $@ - echo 'ccache = "``$(DEFCCNAME)``"' >> $@ - echo 'keytab = "``$(DEFKTNAME)``"' >> $@ -diff --git a/src/include/Makefile.in b/src/include/Makefile.in -index e13042a..f83ff4e 100644 ---- a/src/include/Makefile.in -+++ b/src/include/Makefile.in -@@ -53,6 +53,7 @@ autoconf.stamp: $(srcdir)/autoconf.h.in $(BUILDTOP)/config.status - - SYSCONFDIR = @sysconfdir@ - LOCALSTATEDIR = @localstatedir@ -+RUNSTATEDIR = @runstatedir@ - BINDIR = @bindir@ - SBINDIR = @sbindir@ - LIBDIR = @libdir@ -@@ -66,6 +67,7 @@ PROCESS_REPLACE = -e "s+@KRB5RCTMPDIR+$(KRB5RCTMPDIR)+" \ - -e "s+@MODULEDIR+$(MODULE_DIR)+" \ - -e "s+@GSSMODULEDIR+$(GSS_MODULE_DIR)+" \ - -e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \ -+ -e 's+@RUNSTATEDIR+$(RUNSTATEDIR)+' \ - -e 's+@SYSCONFDIR+$(SYSCONFDIR)+' \ - -e 's+@DYNOBJEXT+$(DYNOBJEXT)+' \ - -e 's+@SYSCONFCONF+$(SYSCONFCONF)+' -diff --git a/src/include/osconf.hin b/src/include/osconf.hin -index 90ab86d..871503a 100644 ---- a/src/include/osconf.hin -+++ b/src/include/osconf.hin -@@ -59,6 +59,7 @@ - #define PLUGIN_EXT "@DYNOBJEXT" - - #define KDC_DIR "@LOCALSTATEDIR/krb5kdc" -+#define KDC_RUN_DIR "@RUNSTATEDIR/krb5kdc" - #define DEFAULT_KDB_FILE KDC_DIR "/principal" - #define DEFAULT_KEYFILE_STUB KDC_DIR "/.k5." - #define KRB5_DEFAULT_ADMIN_ACL KDC_DIR "/krb5_adm.acl" -diff --git a/src/man/Makefile.in b/src/man/Makefile.in -index 4dd2448..2b9c892 100644 ---- a/src/man/Makefile.in -+++ b/src/man/Makefile.in -@@ -5,6 +5,7 @@ SPHINX_BUILD=sphinx-build - GROFF=@GROFF@ - GROFF_MAN=$(GROFF) -mtty-char -Tascii -mandoc -c - localstatedir=@localstatedir@ -+runstatedir=@runstatedir@ - sysconfdir=@sysconfdir@ - DEFCCNAME=@DEFCCNAME@ - DEFKTNAME=@DEFKTNAME@ -@@ -44,6 +45,7 @@ $(docsrc)/version.py: $(top_srcdir)/patchlevel.h - -e 's|@SBINDIR@|$(SERVER_BINDIR)|g' \ - -e 's|@LIBDIR@|$(KRB5_LIBDIR)|g' \ - -e 's|@LOCALSTATEDIR@|$(localstatedir)|g' \ -+ -e 's|@RUNSTATEDIR@|$(runstatedir)|g' \ - -e 's|@SYSCONFDIR@|$(sysconfdir)|g' \ - -e 's|@CCNAME@|$(DEFCCNAME)|g' \ - -e 's|@KTNAME@|$(DEFKTNAME)|g' \ -diff --git a/src/plugins/preauth/otp/otp_state.c b/src/plugins/preauth/otp/otp_state.c -index a4d7e3b..4643dff 100644 ---- a/src/plugins/preauth/otp/otp_state.c -+++ b/src/plugins/preauth/otp/otp_state.c -@@ -40,7 +40,7 @@ - #endif - - #define DEFAULT_TYPE_NAME "DEFAULT" --#define DEFAULT_SOCKET_FMT KDC_DIR "/%s.socket" -+#define DEFAULT_SOCKET_FMT KDC_RUN_DIR "/%s.socket" - #define DEFAULT_TIMEOUT 5 - #define DEFAULT_RETRIES 3 - #define MAX_SECRET_LEN 1024 diff --git a/SOURCES/krb5-master-rcache-acquirecred-cleanup.patch b/SOURCES/krb5-master-rcache-acquirecred-cleanup.patch deleted file mode 100644 index 72b97d3..0000000 --- a/SOURCES/krb5-master-rcache-acquirecred-cleanup.patch +++ /dev/null @@ -1,105 +0,0 @@ -commit ef8e19af863158e4c1abc15fc710aa8cfad38406 -Author: Greg Hudson -Date: Wed Jan 15 12:51:42 2014 -0500 - - Clean up GSS krb5 acquire_accept_cred - - Use a cleanup handler instead of releasing kt in multiple error - clauses. Wrap a long line and fix a comment with a missing word. - Rewrap the function arguments to use fewer lines. - -diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c -index 9547207..37cc6b5 100644 ---- a/src/lib/gssapi/krb5/acquire_cred.c -+++ b/src/lib/gssapi/krb5/acquire_cred.c -@@ -179,13 +179,13 @@ cleanup: - */ - - static OM_uint32 --acquire_accept_cred(krb5_context context, -- OM_uint32 *minor_status, -- krb5_keytab req_keytab, -- krb5_gss_cred_id_rec *cred) -+acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, -+ krb5_keytab req_keytab, krb5_gss_cred_id_rec *cred) - { -+ OM_uint32 major; - krb5_error_code code; -- krb5_keytab kt; -+ krb5_keytab kt = NULL; -+ krb5_rcache rc = NULL; - - assert(cred->keytab == NULL); - -@@ -202,46 +202,54 @@ acquire_accept_cred(krb5_context context, - } - } - if (code) { -- *minor_status = code; -- return GSS_S_CRED_UNAVAIL; -+ major = GSS_S_CRED_UNAVAIL; -+ goto cleanup; - } - - if (cred->name != NULL) { -- /* Make sure we keys matching the desired name in the keytab. */ -+ /* Make sure we have keys matching the desired name in the keytab. */ - code = check_keytab(context, kt, cred->name); - if (code) { -- krb5_kt_close(context, kt); - if (code == KRB5_KT_NOTFOUND) { - char *errstr = (char *)krb5_get_error_message(context, code); -- krb5_set_error_message(context, KG_KEYTAB_NOMATCH, "%s", errstr); -+ krb5_set_error_message(context, KG_KEYTAB_NOMATCH, "%s", -+ errstr); - krb5_free_error_message(context, errstr); -- *minor_status = KG_KEYTAB_NOMATCH; -- } else -- *minor_status = code; -- return GSS_S_CRED_UNAVAIL; -+ code = KG_KEYTAB_NOMATCH; -+ } -+ major = GSS_S_CRED_UNAVAIL; -+ goto cleanup; - } - - /* Open the replay cache for this principal. */ - code = krb5_get_server_rcache(context, &cred->name->princ->data[0], -- &cred->rcache); -+ &rc); - if (code) { -- krb5_kt_close(context, kt); -- *minor_status = code; -- return GSS_S_FAILURE; -+ major = GSS_S_FAILURE; -+ goto cleanup; - } - } else { - /* Make sure we have a keytab with keys in it. */ - code = krb5_kt_have_content(context, kt); - if (code) { -- krb5_kt_close(context, kt); -- *minor_status = code; -- return GSS_S_CRED_UNAVAIL; -+ major = GSS_S_CRED_UNAVAIL; -+ goto cleanup; - } - } - - cred->keytab = kt; -+ kt = NULL; -+ cred->rcache = rc; -+ rc = NULL; -+ major = GSS_S_COMPLETE; - -- return GSS_S_COMPLETE; -+cleanup: -+ if (kt != NULL) -+ krb5_kt_close(context, kt); -+ if (rc != NULL) -+ krb5_rc_close(context, rc); -+ *minor_status = code; -+ return major; - } - #endif /* LEAN_CLIENT */ - diff --git a/SOURCES/krb5-master-rcache-acquirecred-source.patch b/SOURCES/krb5-master-rcache-acquirecred-source.patch deleted file mode 100644 index 71c3876..0000000 --- a/SOURCES/krb5-master-rcache-acquirecred-source.patch +++ /dev/null @@ -1,136 +0,0 @@ -commit 7dad0bee30fbbde8cfc0eacd2d1487c198a004a1 -Author: Simo Sorce -Date: Thu Dec 26 19:05:34 2013 -0500 - - Add rcache feature to gss_acquire_cred_from - - The "rcache" cred store entry can specify a replay cache type and name - to be used with the credentials being acquired. - - [ghudson@mit.edu: split up, simplified, and altered to fit preparatory - commits] - - ticket: 7819 (new) - -diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c -index f625c0c..5d680f9 100644 ---- a/src/lib/gssapi/krb5/acquire_cred.c -+++ b/src/lib/gssapi/krb5/acquire_cred.c -@@ -180,7 +180,8 @@ cleanup: - - static OM_uint32 - acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, -- krb5_keytab req_keytab, krb5_gss_cred_id_rec *cred) -+ krb5_keytab req_keytab, const char *rcname, -+ krb5_gss_cred_id_rec *cred) - { - OM_uint32 major; - krb5_error_code code; -@@ -189,6 +190,20 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, - - assert(cred->keytab == NULL); - -+ /* If we have an explicit rcache name, open it. */ -+ if (rcname != NULL) { -+ code = krb5_rc_resolve_full(context, &rc, rcname); -+ if (code) { -+ major = GSS_S_FAILURE; -+ goto cleanup; -+ } -+ code = krb5_rc_recover_or_initialize(context, rc, context->clockskew); -+ if (code) { -+ major = GSS_S_FAILURE; -+ goto cleanup; -+ } -+ } -+ - if (req_keytab != NULL) { - code = krb5_kt_dup(context, req_keytab, &kt); - } else { -@@ -221,12 +236,14 @@ acquire_accept_cred(krb5_context context, OM_uint32 *minor_status, - goto cleanup; - } - -- /* Open the replay cache for this principal. */ -- code = krb5_get_server_rcache(context, &cred->name->princ->data[0], -- &rc); -- if (code) { -- major = GSS_S_FAILURE; -- goto cleanup; -+ if (rc == NULL) { -+ /* Open the replay cache for this principal. */ -+ code = krb5_get_server_rcache(context, &cred->name->princ->data[0], -+ &rc); -+ if (code) { -+ major = GSS_S_FAILURE; -+ goto cleanup; -+ } - } - } else { - /* Make sure we have a keytab with keys in it. */ -@@ -718,8 +735,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, - gss_name_t desired_name, gss_buffer_t password, - OM_uint32 time_req, gss_cred_usage_t cred_usage, - krb5_ccache ccache, krb5_keytab client_keytab, -- krb5_keytab keytab, krb5_boolean iakerb, -- gss_cred_id_t *output_cred_handle, -+ krb5_keytab keytab, const char *rcname, -+ krb5_boolean iakerb, gss_cred_id_t *output_cred_handle, - OM_uint32 *time_rec) - { - krb5_gss_cred_id_t cred = NULL; -@@ -775,7 +792,7 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status, - * in cred->name if desired_princ is specified. - */ - if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) { -- ret = acquire_accept_cred(context, minor_status, keytab, cred); -+ ret = acquire_accept_cred(context, minor_status, keytab, rcname, cred); - if (ret != GSS_S_COMPLETE) - goto error_out; - } -@@ -867,7 +884,7 @@ acquire_cred(OM_uint32 *minor_status, gss_name_t desired_name, - - ret = acquire_cred_context(context, minor_status, desired_name, password, - time_req, cred_usage, ccache, NULL, keytab, -- iakerb, output_cred_handle, time_rec); -+ NULL, iakerb, output_cred_handle, time_rec); - - out: - krb5_free_context(context); -@@ -1135,7 +1152,7 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status, - krb5_keytab client_keytab = NULL; - krb5_keytab keytab = NULL; - krb5_ccache ccache = NULL; -- const char *value; -+ const char *rcname, *value; - OM_uint32 ret; - - code = gss_krb5int_initialize_library(); -@@ -1191,9 +1208,14 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status, - } - } - -+ ret = kg_value_from_cred_store(cred_store, KRB5_CS_RCACHE_URN, &rcname); -+ if (GSS_ERROR(ret)) -+ goto out; -+ - ret = acquire_cred_context(context, minor_status, desired_name, NULL, - time_req, cred_usage, ccache, client_keytab, -- keytab, 0, output_cred_handle, time_rec); -+ keytab, rcname, 0, output_cred_handle, -+ time_rec); - - out: - if (ccache != NULL) -diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h -index 0167816..8e4f6d9 100644 ---- a/src/lib/gssapi/krb5/gssapiP_krb5.h -+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h -@@ -1260,6 +1260,7 @@ data_to_gss(krb5_data *input_k5data, gss_buffer_t output_buffer) - #define KRB5_CS_CLI_KEYTAB_URN "client_keytab" - #define KRB5_CS_KEYTAB_URN "keytab" - #define KRB5_CS_CCACHE_URN "ccache" -+#define KRB5_CS_RCACHE_URN "rcache" - - OM_uint32 - kg_value_from_cred_store(gss_const_key_value_set_t cred_store, diff --git a/SOURCES/krb5-master-rcache-acquirecred-test.patch b/SOURCES/krb5-master-rcache-acquirecred-test.patch deleted file mode 100644 index e8eef5e..0000000 --- a/SOURCES/krb5-master-rcache-acquirecred-test.patch +++ /dev/null @@ -1,82 +0,0 @@ -commit 6f8d5135334c9ddb674f9824e750872b3b0642ea -Author: Greg Hudson -Date: Thu Jan 16 11:49:55 2014 -0500 - - Add test for gss_acquire_cred_from rcache feature - -diff --git a/src/tests/gssapi/t_credstore.c b/src/tests/gssapi/t_credstore.c -index 575f96d..e28f5d0 100644 ---- a/src/tests/gssapi/t_credstore.c -+++ b/src/tests/gssapi/t_credstore.c -@@ -46,7 +46,9 @@ main(int argc, char *argv[]) - gss_cred_usage_t cred_usage = GSS_C_BOTH; - gss_OID_set mechs = GSS_C_NO_OID_SET; - gss_cred_id_t cred = GSS_C_NO_CREDENTIAL; -- krb5_boolean store_creds = FALSE; -+ gss_ctx_id_t ictx = GSS_C_NO_CONTEXT, actx = GSS_C_NO_CONTEXT; -+ gss_buffer_desc itok, atok; -+ krb5_boolean store_creds = FALSE, replay = FALSE; - char opt; - - /* Parse options. */ -@@ -54,6 +56,8 @@ main(int argc, char *argv[]) - opt = (*argv)[1]; - if (opt == 's') - store_creds = TRUE; -+ else if (opt == 'r') -+ replay = TRUE; - else if (opt == 'a') - cred_usage = GSS_C_ACCEPT; - else if (opt == 'b') -@@ -101,6 +105,31 @@ main(int argc, char *argv[]) - &store, &cred, NULL, NULL); - check_gsserr("gss_acquire_cred_from", major, minor); - -+ if (replay) { -+ /* Induce a replay using cred as the acceptor cred, to test the replay -+ * cache indicated by the store. */ -+ major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ictx, name, -+ &mech_krb5, 0, GSS_C_INDEFINITE, -+ GSS_C_NO_CHANNEL_BINDINGS, -+ GSS_C_NO_BUFFER, NULL, &itok, NULL, NULL); -+ check_gsserr("gss_init_sec_context", major, minor); -+ (void)gss_delete_sec_context(&minor, &ictx, NULL); -+ -+ major = gss_accept_sec_context(&minor, &actx, cred, &itok, -+ GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, -+ &atok, NULL, NULL, NULL); -+ check_gsserr("gss_accept_sec_context(1)", major, minor); -+ (void)gss_release_buffer(&minor, &atok); -+ (void)gss_delete_sec_context(&minor, &actx, NULL); -+ -+ major = gss_accept_sec_context(&minor, &actx, cred, &itok, -+ GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL, -+ &atok, NULL, NULL, NULL); -+ check_gsserr("gss_accept_sec_context(2)", major, minor); -+ (void)gss_release_buffer(&minor, &atok); -+ (void)gss_delete_sec_context(&minor, &actx, NULL); -+ } -+ - gss_release_name(&minor, &name); - gss_release_cred(&minor, &cred); - free(store.elements); -diff --git a/src/tests/gssapi/t_gssapi.py b/src/tests/gssapi/t_gssapi.py -index 74139e4..106910d 100755 ---- a/src/tests/gssapi/t_gssapi.py -+++ b/src/tests/gssapi/t_gssapi.py -@@ -91,6 +91,15 @@ realm.kinit(service_cs, None, ['-k', '-t', servicekeytab]) - realm.run(['./t_credstore', '-s', 'p:' + service_cs, 'ccache', storagecache, - 'keytab', servicekeytab]) - -+# Test rcache feature of cred stores. t_credstore -r should produce a -+# replay error normally, but not with rcache set to "none:". -+output = realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ], -+ expected_code=1) -+if 'gss_accept_sec_context(2): Request is a replay' not in output: -+ fail('Expected replay error not seen in t_credstore output') -+realm.run(['./t_credstore', '-r', '-a', 'p:' + realm.host_princ, -+ 'rcache', 'none:']) -+ - # Verify that we can't acquire acceptor creds without a keytab. - os.remove(realm.keytab) - output = realm.run(['./t_accname', 'p:abc'], expected_code=1) diff --git a/SOURCES/krb5-master-rcache-internal-const.patch b/SOURCES/krb5-master-rcache-internal-const.patch deleted file mode 100644 index 5cb1108..0000000 --- a/SOURCES/krb5-master-rcache-internal-const.patch +++ /dev/null @@ -1,46 +0,0 @@ -commit 74ff6c4accb68bd1d6c652c55e66519720db9fc4 -Author: Greg Hudson -Date: Wed Jan 15 12:31:41 2014 -0500 - - Make rcache resolve functions take const char * - -diff --git a/src/include/k5-int.h b/src/include/k5-int.h -index bbc7fab..b4757a9 100644 ---- a/src/include/k5-int.h -+++ b/src/include/k5-int.h -@@ -1887,8 +1887,10 @@ krb5_error_code KRB5_CALLCONV - krb5int_cc_user_set_default_name(krb5_context context, const char *name); - - krb5_error_code krb5_rc_default(krb5_context, krb5_rcache *); --krb5_error_code krb5_rc_resolve_type(krb5_context, krb5_rcache *,char *); --krb5_error_code krb5_rc_resolve_full(krb5_context, krb5_rcache *,char *); -+krb5_error_code krb5_rc_resolve_type(krb5_context, krb5_rcache *, -+ const char *); -+krb5_error_code krb5_rc_resolve_full(krb5_context, krb5_rcache *, -+ const char *); - char *krb5_rc_get_type(krb5_context, krb5_rcache); - char *krb5_rc_default_type(krb5_context); - char *krb5_rc_default_name(krb5_context); -diff --git a/src/lib/krb5/rcache/rc_base.c b/src/lib/krb5/rcache/rc_base.c -index 2fc96c5..373ac30 100644 ---- a/src/lib/krb5/rcache/rc_base.c -+++ b/src/lib/krb5/rcache/rc_base.c -@@ -65,7 +65,8 @@ krb5_rc_register_type(krb5_context context, const krb5_rc_ops *ops) - } - - krb5_error_code --krb5_rc_resolve_type(krb5_context context, krb5_rcache *idptr, char *type) -+krb5_rc_resolve_type(krb5_context context, krb5_rcache *idptr, -+ const char *type) - { - struct krb5_rc_typelist *t; - krb5_error_code err; -@@ -146,7 +147,7 @@ krb5_rc_default(krb5_context context, krb5_rcache *idptr) - - krb5_error_code - krb5_rc_resolve_full(krb5_context context, krb5_rcache *idptr, -- char *string_name) -+ const char *string_name) - { - char *type; - char *residual; diff --git a/SOURCES/krb5-master-strdupcheck.patch b/SOURCES/krb5-master-strdupcheck.patch deleted file mode 100644 index 4c9d0c1..0000000 --- a/SOURCES/krb5-master-strdupcheck.patch +++ /dev/null @@ -1,23 +0,0 @@ -commit b6810da129512b6d0200580d78d22d38cc214e21 -Author: Lukas Slebodnik -Date: Sat Jun 21 17:09:31 2014 +0200 - - Fix error check in krb5_ldap_parse_principal_name - - Test the correct variable for NULL to detect a strdup failure. - - [ghudson@mit.edu: clarified commit message] - -diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c -index 21695a9..44bf339 100644 ---- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c -+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c -@@ -412,7 +412,7 @@ krb5_ldap_parse_principal_name(char *i_princ_name, char **o_princ_name) - at_rlm_name = strrchr(i_princ_name, '@'); - if (!at_rlm_name) { - *o_princ_name = strdup(i_princ_name); -- if (!o_princ_name) -+ if (!*o_princ_name) - return ENOMEM; - } else { - k5_buf_init_dynamic(&buf); diff --git a/SOURCES/krb5-tests_use_libs_from_build.patch b/SOURCES/krb5-tests_use_libs_from_build.patch new file mode 100644 index 0000000..4538b1d --- /dev/null +++ b/SOURCES/krb5-tests_use_libs_from_build.patch @@ -0,0 +1,96 @@ +# +# krb5-tests_use_libs_from_build.patch - patch to ensure the tests +# in the upstream sources use the libraries from the local tree +# and not those from the underlying build system. +3 +# Originally repoted as RedHat Bug #1164304 ("Upstream unit tests loads +# the installed shared libraries instead the ones from the build") +# +# +# Description of problem: +# krb5-1.12.2/src/lib/kadm5/unit-test fails (segfaults) when +# krb5-pkinit is installed on the sysytem. +# Monitoring via audit showed that unit tests from this directory +# loads pkinit.so from the installed package and not the one that +# was built. +# On top of that, monitoring showed that libs from the installed +# krb5-libs (whatever version installed) are loaded too. +# This questions the effectiveness of upstream testing. +# +# Version-Release number of selected component (if applicable): +# krb5-libs-1.12.2-8.el7 +# +# How reproducible: +# always +# +# Steps to Reproduce: +# +# # rpm -qa krb5\* +# krb5-devel-1.11.3-49.el7.ppc64 +# krb5-libs-1.11.3-49.el7.ppc64 +# krb5-pkinit-1.11.3-49.el7.ppc64 +# # +# # rpm -ivh krb5-1.12.2-8.el7.src.rpm +# ... snip ... +# # rpmbuild -bc ~/rpmbuild/SPECS/krb5.spec +# ... snip ... +# # +# # cd ~/rpmbuild/BUILD/krb5-1.12.2/src/ +# # make runenv.py +# LD_LIBRARY_PATH=`echo -L./lib | sed -e "s/-L//g" -e "s/ /:/g"`; export LD_LIBRARY_PATH; \ +# for i in LD_LIBRARY_PATH; do \ +# eval echo 'env['\\\'$i\\\''] = '\\\'\$$i\\\'; \ +# done > pyrunenv.vals +# echo "proxy_tls_impl = 'openssl'" >> pyrunenv.vals +# echo 'env = {}' > runenv.py +# cat pyrunenv.vals >> runenv.py +# # cd lib/kadm5/unit-test/ +# # make check +# .. snip ... +# KINIT=../../../clients/kinit/kinit \ +# KDESTROY=../../../clients/kdestroy/kdestroy \ +# KADMIN_LOCAL=../../../kadmin/cli/kadmin.local \ +# PRIOCNTL_HACK=0 VALGRIND="" \ +# +# WARNING: Couldn't find the global config file. +# WARNING: Couldn't find tool init file +# Test Run By root on Fri Nov 14 10:30:35 2014 +# Native configuration is powerpc64-redhat-linux-gnu +# +# === api tests === +# +# Schedule of variations: +# unix +# +# Running target unix +# Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target. +# Using /usr/share/dejagnu/config/unix.exp as generic interface file for target. +# Using ./config/unix.exp as tool-and-target-specific interface file. +# Running ./api.2/crte-policy.exp ... +# FAIL: create-policy 1: eof +# ERROR: create-policy 1: unexpected failure in init +# ERROR: create-policy 2: unexpected failure in init +# ERROR: create-policy 3: unexpected failure in init +# +diff -ur krb5/src/kadmin/testing/proto/krb5.conf.proto krb5/src/kadmin/testing/proto/krb5.conf.proto +--- krb5/src/kadmin/testing/proto/krb5.conf.proto 2014-11-14 10:16:22.106948323 -0500 ++++ krb5/src/kadmin/testing/proto/krb5.conf.proto 2014-11-14 10:14:16.955948323 -0500 +@@ -2,6 +2,7 @@ + default_realm = __REALM__ + default_keytab_name = FILE:__K5ROOT__/v5srvtab + dns_fallback = no ++ plugin_base_dir = __PLUGIN_DIR__ + + [realms] + __REALM__ = { +diff -ur krb5/src/kadmin/testing/scripts/start_servers krb5/src/kadmin/testing/scripts/start_servers +--- krb5/src/kadmin/testing/scripts/start_servers 2014-08-11 18:46:27.000000000 -0400 ++++ krb5/src/kadmin/testing/scripts/start_servers 2014-11-14 10:14:56.409948323 -0500 +@@ -40,6 +40,7 @@ + -e "s/__KDCHOST__/$hostname/g" \ + -e "s/__LOCALHOST__/$localname/g" \ + -e "s#__MODDIR__#$TOP/../plugins/kdb#g"\ ++ -e "s#__PLUGIN_DIR__#$TOP/../plugins#g"\ + < $STESTDIR/proto/krb5.conf.proto > $K5ROOT/krb5.conf + + # Using /usr/ucb/rsh and getting rid of "-k $REALM" until we get diff --git a/SOURCES/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch b/SOURCES/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch deleted file mode 100644 index c7bb9a2..0000000 --- a/SOURCES/krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch +++ /dev/null @@ -1,331 +0,0 @@ -diff --git a/src/kadmin/server/kadm_rpc_svc.c b/src/kadmin/server/kadm_rpc_svc.c -index 3837931..f4d2a7c 100644 ---- a/src/kadmin/server/kadm_rpc_svc.c -+++ b/src/kadmin/server/kadm_rpc_svc.c -@@ -4,7 +4,7 @@ - * - */ - --#include -+#include - #include - #include /* for gss_nt_krb5_name */ - #include -@@ -296,14 +296,8 @@ check_rpcsec_auth(struct svc_req *rqstp) - c1 = krb5_princ_component(kctx, princ, 0); - c2 = krb5_princ_component(kctx, princ, 1); - realm = krb5_princ_realm(kctx, princ); -- if (strncmp(handle->params.realm, realm->data, realm->length) == 0 -- && strncmp("kadmin", c1->data, c1->length) == 0) { -- -- if (strncmp("history", c2->data, c2->length) == 0) -- goto fail_princ; -- else -- success = 1; -- } -+ success = data_eq_string(*realm, handle->params.realm) && -+ data_eq_string(*c1, "kadmin") && !data_eq_string(*c2, "history"); - - fail_princ: - if (!success) { -diff --git a/src/lib/gssapi/krb5/context_time.c b/src/lib/gssapi/krb5/context_time.c -index b3d1db0..a18cfb0 100644 ---- a/src/lib/gssapi/krb5/context_time.c -+++ b/src/lib/gssapi/krb5/context_time.c -@@ -40,7 +40,7 @@ krb5_gss_context_time(minor_status, context_handle, time_rec) - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - -- if (! ctx->established) { -+ if (ctx->terminated || !ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } -diff --git a/src/lib/gssapi/krb5/export_sec_context.c b/src/lib/gssapi/krb5/export_sec_context.c -index 18a3a34..1b3de68 100644 ---- a/src/lib/gssapi/krb5/export_sec_context.c -+++ b/src/lib/gssapi/krb5/export_sec_context.c -@@ -45,6 +45,11 @@ krb5_gss_export_sec_context(minor_status, context_handle, interprocess_token) - *minor_status = 0; - - ctx = (krb5_gss_ctx_id_t) *context_handle; -+ if (ctx->terminated) { -+ *minor_status = KG_CTX_INCOMPLETE; -+ return (GSS_S_NO_CONTEXT); -+ } -+ - context = ctx->k5_context; - kret = krb5_gss_ser_init(context); - if (kret) -diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h -index 0167816..42d16ad 100644 ---- a/src/lib/gssapi/krb5/gssapiP_krb5.h -+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h -@@ -204,6 +204,7 @@ typedef struct _krb5_gss_ctx_id_rec { - unsigned int established : 1; - unsigned int have_acceptor_subkey : 1; - unsigned int seed_init : 1; /* XXX tested but never actually set */ -+ unsigned int terminated : 1; - OM_uint32 gss_flags; - unsigned char seed[16]; - krb5_gss_name_t here; -diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c -index a408259..088219a 100644 ---- a/src/lib/gssapi/krb5/gssapi_krb5.c -+++ b/src/lib/gssapi/krb5/gssapi_krb5.c -@@ -369,7 +369,7 @@ krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status, - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - -- if (!ctx->established) -+ if (ctx->terminated || !ctx->established) - return GSS_S_NO_CONTEXT; - - for (i = 0; i < sizeof(krb5_gss_inquire_sec_context_by_oid_ops)/ -diff --git a/src/lib/gssapi/krb5/inq_context.c b/src/lib/gssapi/krb5/inq_context.c -index eacb0fd..096df2a 100644 ---- a/src/lib/gssapi/krb5/inq_context.c -+++ b/src/lib/gssapi/krb5/inq_context.c -@@ -105,7 +105,7 @@ krb5_gss_inquire_context(minor_status, context_handle, initiator_name, - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - -- if (! ctx->established) { -+ if (ctx->terminated || !ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } -diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c -index bd1e2a6..b11b615 100644 ---- a/src/lib/gssapi/krb5/k5seal.c -+++ b/src/lib/gssapi/krb5/k5seal.c -@@ -342,7 +342,7 @@ kg_seal(minor_status, context_handle, conf_req_flag, qop_req, - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - -- if (! ctx->established) { -+ if (ctx->terminated || !ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } -diff --git a/src/lib/gssapi/krb5/k5sealiov.c b/src/lib/gssapi/krb5/k5sealiov.c -index 0b99a77..0f80095 100644 ---- a/src/lib/gssapi/krb5/k5sealiov.c -+++ b/src/lib/gssapi/krb5/k5sealiov.c -@@ -284,7 +284,7 @@ kg_seal_iov(OM_uint32 *minor_status, - } - - ctx = (krb5_gss_ctx_id_rec *)context_handle; -- if (!ctx->established) { -+ if (ctx->terminated || !ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return GSS_S_NO_CONTEXT; - } -diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c -index b65c83c..9e78550 100644 ---- a/src/lib/gssapi/krb5/k5unseal.c -+++ b/src/lib/gssapi/krb5/k5unseal.c -@@ -492,7 +492,7 @@ kg_unseal(minor_status, context_handle, input_token_buffer, - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - -- if (! ctx->established) { -+ if (ctx->terminated || !ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } -diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c -index 8d6a2da..191de2c 100644 ---- a/src/lib/gssapi/krb5/k5unsealiov.c -+++ b/src/lib/gssapi/krb5/k5unsealiov.c -@@ -628,7 +628,7 @@ kg_unseal_iov(OM_uint32 *minor_status, - OM_uint32 code; - - ctx = (krb5_gss_ctx_id_rec *)context_handle; -- if (!ctx->established) { -+ if (ctx->terminated || !ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return GSS_S_NO_CONTEXT; - } -diff --git a/src/lib/gssapi/krb5/lucid_context.c b/src/lib/gssapi/krb5/lucid_context.c -index dc129e1..50d8cc9 100644 ---- a/src/lib/gssapi/krb5/lucid_context.c -+++ b/src/lib/gssapi/krb5/lucid_context.c -@@ -75,6 +75,11 @@ gss_krb5int_export_lucid_sec_context( - *minor_status = 0; - *data_set = GSS_C_NO_BUFFER_SET; - -+ if (ctx->terminated || !ctx->established) { -+ *minor_status = KG_CTX_INCOMPLETE; -+ return GSS_S_NO_CONTEXT; -+ } -+ - retval = generic_gss_oid_decompose(minor_status, - GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID, - GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH, -diff --git a/src/lib/gssapi/krb5/prf.c b/src/lib/gssapi/krb5/prf.c -index a0fbcda..4831f9f 100644 ---- a/src/lib/gssapi/krb5/prf.c -+++ b/src/lib/gssapi/krb5/prf.c -@@ -60,6 +60,10 @@ krb5_gss_pseudo_random(OM_uint32 *minor_status, - ns.data = NULL; - - ctx = (krb5_gss_ctx_id_t)context; -+ if (ctx->terminated || !ctx->established) { -+ *minor_status = KG_CTX_INCOMPLETE; -+ return GSS_S_NO_CONTEXT; -+ } - - switch (prf_key) { - case GSS_C_PRF_KEY_FULL: -diff --git a/src/lib/gssapi/krb5/process_context_token.c b/src/lib/gssapi/krb5/process_context_token.c -index ae33180..a672f48 100644 ---- a/src/lib/gssapi/krb5/process_context_token.c -+++ b/src/lib/gssapi/krb5/process_context_token.c -@@ -39,11 +39,18 @@ krb5_gss_process_context_token(minor_status, context_handle, - - ctx = (krb5_gss_ctx_id_t) context_handle; - -- if (! ctx->established) { -+ if (ctx->terminated || !ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } - -+ /* We only support context deletion tokens for now, and RFC 4121 does not -+ * define a context deletion token. */ -+ if (ctx->proto) { -+ *minor_status = 0; -+ return(GSS_S_DEFECTIVE_TOKEN); -+ } -+ - /* "unseal" the token */ - - if (GSS_ERROR(majerr = kg_unseal(minor_status, context_handle, -@@ -52,8 +59,8 @@ krb5_gss_process_context_token(minor_status, context_handle, - KG_TOK_DEL_CTX))) - return(majerr); - -- /* that's it. delete the context */ -- -- return(krb5_gss_delete_sec_context(minor_status, &context_handle, -- GSS_C_NO_BUFFER)); -+ /* Mark the context as terminated, but do not delete it (as that would -+ * leave the caller with a dangling context handle). */ -+ ctx->terminated = 1; -+ return(GSS_S_COMPLETE); - } -diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c -index 7bc4221..ed5c599 100644 ---- a/src/lib/gssapi/krb5/wrap_size_limit.c -+++ b/src/lib/gssapi/krb5/wrap_size_limit.c -@@ -95,7 +95,7 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, - } - - ctx = (krb5_gss_ctx_id_rec *) context_handle; -- if (! ctx->established) { -+ if (ctx->terminated || !ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } -diff --git a/src/lib/gssapi/mechglue/mglueP.h b/src/lib/gssapi/mechglue/mglueP.h -index e56b9c1..2b5145e 100644 ---- a/src/lib/gssapi/mechglue/mglueP.h -+++ b/src/lib/gssapi/mechglue/mglueP.h -@@ -25,7 +25,6 @@ do { \ - */ - typedef struct gss_union_ctx_id_struct { - struct gss_union_ctx_id_struct *loopback; -- struct gss_union_ctx_id_struct *interposer; - gss_OID mech_type; - gss_ctx_id_t internal_ctx_id; - } gss_union_ctx_id_desc, *gss_union_ctx_id_t; -diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c -index 42ac783..975f94c 100644 ---- a/src/lib/kadm5/kadm_rpc_xdr.c -+++ b/src/lib/kadm5/kadm_rpc_xdr.c -@@ -320,6 +320,7 @@ bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head) - free(tl); - tl = tl2; - } -+ *tl_data_head = NULL; - break; - - case XDR_ENCODE: -@@ -1096,6 +1097,7 @@ xdr_krb5_principal(XDR *xdrs, krb5_principal *objp) - case XDR_FREE: - if(*objp != NULL) - krb5_free_principal(context, *objp); -+ *objp = NULL; - break; - } - return TRUE; -diff --git a/src/lib/rpc/auth_gssapi_misc.c b/src/lib/rpc/auth_gssapi_misc.c -index 53bdb98..a05ea19 100644 ---- a/src/lib/rpc/auth_gssapi_misc.c -+++ b/src/lib/rpc/auth_gssapi_misc.c -@@ -322,7 +322,6 @@ bool_t auth_gssapi_unwrap_data( - if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) { - PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n")); - gss_release_buffer(minor, &out_buf); -- xdr_free(xdr_func, xdr_ptr); - XDR_DESTROY(&temp_xdrs); - return FALSE; - } -diff --git a/src/lib/rpc/svc_auth_gss.c b/src/lib/rpc/svc_auth_gss.c -index 8da7003..ea8149b 100644 ---- a/src/lib/rpc/svc_auth_gss.c -+++ b/src/lib/rpc/svc_auth_gss.c -@@ -68,16 +68,6 @@ extern const gss_OID_desc * const gss_mech_spkm3; - - extern SVCAUTH svc_auth_none; - --/* -- * from mit-krb5-1.2.1 mechglue/mglueP.h: -- * Array of context IDs typed by mechanism OID -- */ --typedef struct gss_union_ctx_id_t { -- gss_OID mech_type; -- gss_ctx_id_t internal_ctx_id; --} gss_union_ctx_id_desc, *gss_union_ctx_id_t; -- -- - static auth_gssapi_log_badauth_func log_badauth = NULL; - static caddr_t log_badauth_data = NULL; - static auth_gssapi_log_badauth2_func log_badauth2 = NULL; -@@ -242,16 +232,8 @@ svcauth_gss_accept_sec_context(struct svc_req *rqst, - gd->ctx = GSS_C_NO_CONTEXT; - goto errout; - } -- /* -- * ANDROS: krb5 mechglue returns ctx of size 8 - two pointers, -- * one to the mechanism oid, one to the internal_ctx_id -- */ -- if ((gr->gr_ctx.value = mem_alloc(sizeof(gss_union_ctx_id_desc))) == NULL) { -- fprintf(stderr, "svcauth_gss_accept_context: out of memory\n"); -- goto errout; -- } -- memcpy(gr->gr_ctx.value, gd->ctx, sizeof(gss_union_ctx_id_desc)); -- gr->gr_ctx.length = sizeof(gss_union_ctx_id_desc); -+ gr->gr_ctx.value = "xxxx"; -+ gr->gr_ctx.length = 4; - - /* gr->gr_win = 0x00000005; ANDROS: for debugging linux kernel version... */ - gr->gr_win = sizeof(gd->seqmask) * 8; -@@ -523,8 +505,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, - - if (!svcauth_gss_nextverf(rqst, htonl(gr.gr_win))) { - gss_release_buffer(&min_stat, &gr.gr_token); -- mem_free(gr.gr_ctx.value, -- sizeof(gss_union_ctx_id_desc)); - ret_freegc (AUTH_FAILED); - } - *no_dispatch = TRUE; -@@ -534,7 +514,6 @@ gssrpc__svcauth_gss(struct svc_req *rqst, struct rpc_msg *msg, - - gss_release_buffer(&min_stat, &gr.gr_token); - gss_release_buffer(&min_stat, &gd->checksum); -- mem_free(gr.gr_ctx.value, sizeof(gss_union_ctx_id_desc)); - if (!call_stat) - ret_freegc (AUTH_FAILED); - diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec index dd47276..a0195cd 100644 --- a/SPECS/krb5.spec +++ b/SPECS/krb5.spec @@ -40,16 +40,19 @@ Summary: The Kerberos network authentication system Name: krb5 -Version: 1.12.2 -Release: 15%{?dist} -# Maybe we should explode from the now-available-to-everybody tarball instead? -# http://web.mit.edu/kerberos/dist/krb5/1.12/krb5-1.12.2-signed.tar +Version: 1.13.2 +Release: 10%{?dist} +# - Maybe we should explode from the now-available-to-everybody tarball instead? +# http://web.mit.edu/kerberos/dist/krb5/1.13/krb5-1.13.2-signed.tar +# - The sources below are stored in a lookaside cache. Upload with +# $ rhpkg upload krb5-1.13.2.tar.gz krb5-1.13.2.tar.gz.asc # (and don't +# remove, otherwise you can't go back or branch from a previous point) Source0: krb5-%{version}.tar.gz Source1: krb5-%{version}.tar.gz.asc -# Use a dummy krb5-%{version}-pdf.tar.xz the first time through, then -# tar cvJf $RPM_SOURCE_DIR/krb5-%%{version}-pdf.tar.xz build-pdf/*.pdf +# Use a dummy krb5-%{version}-pdf.pax.xz the first time through, then +# $ pax -wv -x ustar build-pdf/*.pdf | xz -9 >"krb5-%{version}-pdf.pax.xz.new" # # after the build phase finishes. -Source3: krb5-%{version}-pdf.tar.xz +Source3: krb5-%{version}-pdf.pax.xz Source2: kprop.service Source4: kadmin.service Source5: krb5kdc.service @@ -70,70 +73,34 @@ Source37: kadmind.init Source38: krb5kdc.init Source39: krb5-krb5kdc.conf -BuildRequires: cmake +BuildRequires: cmake pax xz # Carry this locally until it's available in a packaged form. Source100: nss_wrapper-0.0-20140204195100.git3d58327.tar.xz Source101: noport.c Source102: socket_wrapper-0.0-20140204194748.gitf3b2ece.tar.xz -Patch1: krb5-1.12-pwdch-fast.patch Patch6: krb5-1.12-ksu-path.patch Patch12: krb5-1.12-ktany.patch Patch16: krb5-1.12-buildconf.patch Patch23: krb5-1.3.1-dns.patch -Patch29: krb5-1.10-kprop-mktemp.patch -Patch30: krb5-1.3.4-send-pr-tempfile.patch Patch39: krb5-1.12-api.patch -Patch59: krb5-1.12ish-kpasswd_tcp.patch Patch60: krb5-1.12.1-pam.patch -Patch63: krb5-1.12-selinux-label.patch -Patch71: krb5-1.11-dirsrv-accountlock.patch +Patch63: krb5-1.13-selinux-label.patch +Patch71: krb5-1.13-dirsrv-accountlock.patch Patch86: krb5-1.9-debuginfo.patch Patch105: krb5-kvno-230379.patch Patch129: krb5-1.11-run_user_0.patch Patch134: krb5-1.11-kpasswdtest.patch -Patch136: krb5-master-rcache-internal-const.patch -Patch137: krb5-master-rcache-acquirecred-cleanup.patch -Patch139: krb5-master-rcache-acquirecred-source.patch -Patch141: krb5-master-rcache-acquirecred-test.patch -Patch142: krb5-master-move-otp-sockets.patch -Patch145: krb5-master-mechd.patch -Patch146: krb5-master-strdupcheck.patch -Patch147: krb5-master-compatible-keys.patch -Patch148: krb5-1.12-system-exts.patch -Patch201: 0001-In-ksu-merge-krb5_ccache_copy-and-_restricted.patch -Patch202: 0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals.patch -Patch203: 0003-Use-an-intermediate-memory-cache-in-ksu.patch -Patch204: 0004-Make-ksu-respect-the-default_ccache_name-setting.patch -Patch205: 0005-Copy-config-entries-to-the-ksu-target-ccache.patch -Patch206: 0006-Use-more-randomness-for-ksu-secondary-cache-names.patch -Patch207: 0007-Make-krb5_cc_new_unique-create-DIR-directories.patch -Patch300: krb5-1.12-kpasswd-skip-address-check.patch -Patch301: 0000-Refactor-cm-functions-in-sendto_kdc.c.patch -Patch302: 0001-Simplify-sendto_kdc.c.patch -Patch303: 0002-Add-helper-to-determine-if-a-KDC-is-the-master.patch -Patch304: 0003-Use-k5_transport-_strategy-enums-for-k5_sendto.patch -Patch305: 0004-Build-support-for-TLS-used-by-HTTPS-proxy-support.patch -Patch306: 0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE.patch -Patch307: 0006-Dispatch-style-protocol-switching-for-transport.patch -Patch308: 0007-HTTPS-transport-Microsoft-KKDCPP-implementation.patch -Patch309: 0008-Load-custom-anchors-when-using-KKDCP.patch -Patch310: 0009-Check-names-in-the-server-s-cert-when-using-KKDCP.patch -Patch311: 0010-Add-some-longer-form-docs-for-HTTPS.patch -Patch312: 0011-Have-k5test.py-provide-runenv-to-python-tests.patch -Patch313: 0012-Add-a-simple-KDC-proxy-test-server.patch -Patch314: 0013-Add-tests-for-MS-KKDCP-client-support.patch -Patch315: krb5-1.12ish-tls-plugins.patch -Patch316: krb5-1.12-nodelete-plugins.patch -Patch317: krb5-1.12-ksu-untyped-default-ccache-name.patch -Patch318: krb5-1.12-ksu-no-ccache.patch Patch319: krb5-kadm5clntmit_libsoname_version_downgrade.patch -Patch320: krb5-ksu_not_working_with_default_principal.patch -Patch321: krb5-CVE_2014_5353_fix_LDAP_misused_policy_name_crash.patch -Patch322: krb5-CVE_2014_5354_support_keyless_principals_in_LDAP.patch -Patch323: krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final.patch -Patch324: krb5-1.13_kinit_C_loop_krb5bug243.patch -Patch325: krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad.patch + +Patch140: krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED.patch +Patch143: krb5-tests_use_libs_from_build.patch +Patch144: krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial.patch +Patch145: krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad.patch +Patch146: krb5-1.14-resolve_krb5_GSS_creds_if_time_rec_is_requested.patch +Patch147: krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char.patch +Patch148: krb5-1.13.3-client_referrals.patch +Patch149: krb5-1.13.3-client_referrals_test.patch License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -143,7 +110,7 @@ BuildRequires: autoconf, bison, flex, gawk, gettext, pkgconfig, sed %if 0%{?fedora} >= 12 || 0%{?rhel} >= 6 BuildRequires: libcom_err-devel, libedit-devel, libss-devel %endif -BuildRequires: gzip, ncurses-devel, tar +BuildRequires: gzip, ncurses-devel BuildRequires: python-sphinx, texlive-pdftex # The texlive package got a lot more complicated here. %if 0%{?fedora} > 17 || 0%{?rhel} > 6 @@ -266,8 +233,6 @@ Requires: chkconfig # we drop files in its directory, but we don't want to own that directory Requires: logrotate Requires(preun): initscripts -# mktemp is used by krb5-send-pr -Requires: coreutils # we specify /usr/share/dict/words as the default dict_file in kdc.conf Requires: /usr/share/dict/words %if %{WITH_SYSVERTO} @@ -275,6 +240,15 @@ Requires: /usr/share/dict/words BuildRequires: libverto-module-base Requires: libverto-module-base %endif +%ifarch x86_64 +Obsoletes: krb5-server-1.11.3-49.el7.i686 +%endif +%ifarch ppc64 +Obsoletes: krb5-server-1.11.3-49.el7.ppc +%endif +%ifarch s390x +Obsoletes: krb5-server-1.11.3-49.el7.s390 +%endif %description server Kerberos is a network authentication system. The krb5-server package @@ -288,6 +262,15 @@ Group: System Environment/Daemons Summary: The LDAP storage plugin for the Kerberos 5 KDC Requires: %{name}-server%{?_isa} = %{version}-%{release} Requires: %{name}-libs%{?_isa} = %{version}-%{release} +%ifarch x86_64 +Obsoletes: krb5-server-ldap-1.11.3-49.el7.i686 +%endif +%ifarch ppc64 +Obsoletes: krb5-server-ldap-1.11.3-49.el7.ppc +%endif +%ifarch s390x +Obsoletes: krb5-server-ldap-1.11.3-49.el7.s390 +%endif %description server-ldap Kerberos is a network authentication system. The krb5-server package @@ -336,37 +319,8 @@ certificate. %setup -q -a 3 -a 100 -a 102 ln NOTICE LICENSE -%patch201 -p1 -b .In-ksu-merge-krb5_ccache_copy-and-_restricted -%patch202 -p1 -b .In-ksu-don-t-stat-not-on-disk-ccache-residuals -%patch203 -p1 -b .Use-an-intermediate-memory-cache-in-ksu -%patch204 -p1 -b .Make-ksu-respect-the-default_ccache_name-setting -%patch205 -p1 -b .Copy-config-entries-to-the-ksu-target-ccache -%patch206 -p1 -b .Use-more-randomness-for-ksu-secondary-cache-names -%patch207 -p1 -b .Make-krb5_cc_new_unique-create-DIR-directories - -%patch300 -p1 -b .kpasswd-skip-address-check -%patch301 -p1 -b .Refactor-cm-functions-in-sendto_kdc.c -%patch302 -p1 -b .Simplify-sendto_kdc.c -%patch303 -p1 -b .Add-helper-to-determine-if-a-KDC-is-the-master -%patch304 -p1 -b .Use-k5_transport-_strategy-enums-for-k5_sendto -%patch305 -p1 -b .Build-support-for-TLS-used-by-HTTPS-proxy-support -%patch306 -p1 -b .Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE -%patch307 -p1 -b .Dispatch-style-protocol-switching-for-transport -%patch308 -p1 -b .HTTPS-transport-Microsoft-KKDCPP-implementation -%patch309 -p1 -b .Load-custom-anchors-when-using-KKDCP -%patch310 -p1 -b .Check-names-in-the-server-s-cert-when-using-KKDCP -%patch311 -p1 -b .Add-some-longer-form-docs-for-HTTPS -%patch312 -p1 -b .Have-k5test.py-provide-runenv-to-python-tests -%patch313 -p1 -b .Add-a-simple-KDC-proxy-test-server -%patch314 -p1 -b .Add-tests-for-MS-KKDCP-client-support -%patch315 -p1 -b .tls-plugins -%patch316 -p1 -b .nodelete-plugins -%patch317 -p1 -b .ksu-untyped-default-ccache-name -%patch318 -p1 -b .ksu-no-ccache chmod u+x src/util/paste-kdcproxy.py -%patch1 -p1 -b .pwdch-fast - %patch60 -p1 -b .pam %patch63 -p1 -b .selinux-label @@ -375,10 +329,7 @@ chmod u+x src/util/paste-kdcproxy.py %patch12 -p1 -b .ktany %patch16 -p1 -b .buildconf %{?_rawbuild} %patch23 -p1 -b .dns %{?_rawbuild} -%patch29 -p1 -b .kprop-mktemp -%patch30 -p1 -b .send-pr-tempfile %patch39 -p1 -b .api -%patch59 -p1 -b .kpasswd_tcp %patch71 -p1 -b .dirsrv-accountlock %{?_rawbuild} %patch86 -p0 -b .debuginfo %patch105 -p1 -b .kvno @@ -389,30 +340,24 @@ chmod u+x src/util/paste-kdcproxy.py %patch134 -p1 -b .kpasswdtest -%patch136 -p1 -b .rcache-internal-const -%patch137 -p1 -b .rcache-acquirecred-cleanup -%patch139 -p1 -b .rcache-acquirecred-source -%patch141 -p1 -b .rcache-acquirecred-test -%patch142 -p1 -b .move-otp-sockets -%patch145 -p1 -b .master-mechd -%patch146 -p1 -b .master-strdupcheck -%patch147 -p1 -b .master-compatible-keys -%patch148 -p1 -b .system-exts %patch319 -p1 -b .krb5-kadm5clntmit_libsoname_version_downgrade -%patch320 -p1 -b .krb5-ksu_not_working_with_default_principal -%patch321 -p1 -b .krb5-cve_2014_5353_fix_ldap_misused_policy_name_crash -%patch322 -p1 -b .krb5-cve_2014_5354_support_keyless_principals_in_ldap -%patch323 -p1 -b .krb5_cve_2014_9421_2014_9422_2014_9423_2014_5352_krb5-1.12.2-final -%patch324 -p1 -b .krb5_1_13_kinit_C_loop_krb5bug243 -%patch325 -p1 -b .krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad - + +%patch140 -p1 -b .krb5-1.14-support-kdc_err_more_preauth_data_required +%patch143 -p1 -b .krb5-tests_use_libs_from_build +%patch144 -p1 -b .krb5-1.13.3-bindresvport_sa_port_byte_swap_bug_triggering_selinux_avc_denial +%patch145 -p1 -b .krb5-1.13.3-do_not_allow_stream_socket_retries_in_libkrad +%patch146 -p1 -b .krb5-1.14-resolve_krb5_gss_creds_if_time_rec_is_requested +%patch147 -p1 -b .krb5-1.14-kadmind_defunct_on_platforms_where_char_is_signed_char + +%patch148 -p1 -b .krb5-1.13.3-client_referrals +%patch149 -p1 -b .krb5-1.13.3-client_referrals_test # Take the execute bit off of documentation. chmod -x doc/krb5-protocol/*.txt doc/ccapi/*.html # Generate an FDS-compatible LDIF file. inldif=src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif -cat > 60kerberos.ldif << EOF +cat > '60kerberos.ldif' << EOF # This is a variation on kerberos.ldif which 389 Directory Server will like. dn: cn=schema EOF @@ -437,9 +382,7 @@ mkdir -p socket_wrapper/build cfg="src/kadmin/testing/proto/kdc.conf.proto \ src/kadmin/testing/proto/krb5.conf.proto \ src/lib/kadm5/unit-test/api.current/init-v2.exp \ - src/util/k5test.py \ - src/tests/mk_migr/ldap_backend/input_conf/*.conf \ - src/tests/mk_migr/db2_backend/input_conf/*.conf" + src/util/k5test.py" LONG_BIT=`getconf LONG_BIT` PORT=`expr 61000 + $LONG_BIT - 48` sed -i -e s,61000,`expr "$PORT" + 0`,g $cfg @@ -457,7 +400,7 @@ sed -i -e s,7778,`expr "$PORT" + 1`,g $cfg %build # Go ahead and supply tcl info, because configure doesn't know how to find it. -. %{_libdir}/tclConfig.sh +source %{_libdir}/tclConfig.sh pushd src # Keep the old default if the package is built against older releases. %if 0%{?compile_default_ccache_name} @@ -501,9 +444,11 @@ CPPFLAGS="`echo $DEFINES $INCLUDES`" %endif %if %{WITH_OPENSSL} --with-pkinit-crypto-impl=openssl \ + --with-tls-impl=openssl \ %endif %if %{WITH_NSS} --with-crypto-impl=nss \ + --without-tls-impl \ %endif %if %{WITH_SYSVERTO} --with-system-verto \ @@ -535,6 +480,9 @@ sphinx-build -a -b latex -t pathsubs doc build-pdf for pdf in admin appdev basic build plugindev user ; do test -s build-pdf/$pdf.pdf || make -C build-pdf done +# new krb5-%{version}-pdf.pax.xz, see above +pax -wv -x ustar build-pdf/*.pdf | xz -9 >"krb5-%{version}-pdf.pax.xz.new" +# false # Build the test wrappers. pushd nss_wrapper/build @@ -577,7 +525,7 @@ make -C src/clients check TMPDIR=%{_tmppath} keyctl session - make -C src/util check TMPDIR=%{_tmppath} %install -[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- $RPM_BUILD_ROOT # Sample KDC config files (bundled kdc.conf and kadm5.acl). mkdir -p $RPM_BUILD_ROOT%{_var}/kerberos/krb5kdc @@ -682,7 +630,6 @@ done # Plug-in directories. install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/preauth install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/kdb -install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/tls install -pdm 755 $RPM_BUILD_ROOT/%{_libdir}/krb5/plugins/authdata # The rest of the binaries, headers, libraries, and docs. @@ -693,6 +640,16 @@ make -C src DESTDIR=$RPM_BUILD_ROOT EXAMPLEDIR=%{libsdocdir}/examples install # list of link flags, and it helps prevent file conflicts on multilib systems. sed -r -i -e 's|^libdir=/usr/lib(64)?$|libdir=/usr/lib|g' $RPM_BUILD_ROOT%{_bindir}/krb5-config +# FIXME: Temporay workaround for RH bug #1204646 ("krb5-config +# returns wrong -specs path") so that development of krb5 +# dependicies gets unstuck. +sed -r -i -e "s/-specs=\/.+?\/redhat-hardened-ld//g" $RPM_BUILD_ROOT%{_bindir}/krb5-config + +if [[ "$(< $RPM_BUILD_ROOT%{_bindir}/krb5-config )" == *redhat-hardened-ld* ]] ; then + printf '# redhat-hardened-ld for krb5-config failed' 1>&2 + exit 1 +fi + %if %{separate_usr} # Move specific libraries from %%{_libdir} to /%%{_lib}, and fixup the symlinks. touch $RPM_BUILD_ROOT/rootfile @@ -700,7 +657,7 @@ rellibdir=.. while ! test -r $RPM_BUILD_ROOT/%{_libdir}/${rellibdir}/rootfile ; do rellibdir=../${rellibdir} done -rm -f $RPM_BUILD_ROOT/rootfile +rm -f -- $RPM_BUILD_ROOT/rootfile mkdir -p $RPM_BUILD_ROOT/%{_lib} for library in libgssapi_krb5 libgssrpc libk5crypto libkrb5 libkrb5support ; do mv $RPM_BUILD_ROOT/%{_libdir}/${library}.so.* $RPM_BUILD_ROOT/%{_lib}/ @@ -716,10 +673,14 @@ for section in 1 5 8 ; do $RPM_BUILD_ROOT/%{_mandir}/man${section}/ done +# This script just tells you to send bug reports to krb5-bugs@mit.edu, but +# since we don't have a man page for it, just drop it. +rm -- $RPM_BUILD_ROOT/%{_sbindir}/krb5-send-pr + %find_lang %{gettext_domain} %clean -[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT +[ "$RPM_BUILD_ROOT" != '/' ] && rm -rf -- $RPM_BUILD_ROOT %post libs -p /sbin/ldconfig @@ -765,7 +726,7 @@ if ! grep -q default_ccache_name /etc/krb5.conf ; then fi fi if test -n "$tmpfile" ; then - rm -f "$tmpfile" + rm -f -- "$tmpfile" fi %endif @@ -891,12 +852,6 @@ exit 0 %{_mandir}/man1/ksu.1* %config(noreplace) /etc/pam.d/ksu -# Problem-reporting tool. -%{_sbindir}/krb5-send-pr -%dir %{_datadir}/gnats -%{_datadir}/gnats/mit -%{_mandir}/man1/krb5-send-pr.1* - %files server %defattr(-,root,root,-) %docdir %{_mandir} @@ -931,13 +886,6 @@ exit 0 %dir %{_libdir}/krb5/plugins/authdata %{_libdir}/krb5/plugins/preauth/otp.so - -# Problem-reporting tool. -%{_sbindir}/krb5-send-pr -%dir %{_datadir}/gnats -%{_datadir}/gnats/mit -%{_mandir}/man1/krb5-send-pr.1* - # KDC binaries and configuration. %{_mandir}/man5/kadm5.acl.5* %{_mandir}/man5/kdc.conf.5* @@ -1085,12 +1033,147 @@ exit 0 %changelog -* Wed Aug 26 2015 Roland Mainz - 1.12.2-15 -- Add a patch to fix RedHat bug #1256870 ("KDC sends multiple +* Fri Sep 04 2015 Robbie Harwood 1.13.2-9 +- Add patch and test case for "KDC does not return proper + client principal for client referrals" +- Resolves: #1259846 + +* Mon Aug 31 2015 Roland Mainz - 1.13.2-9 +- Ammend patch for RedHat bug #1252454 ('testsuite complains + "Lifetime has increased by 32436 sec while 0 sec passed!", + while rhel5-libkrb5 passes') to handle the newly introduced + valgrind hits. + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-8 +- Add a patch to fix RH Bug #1250154 ("[s390x, ppc64, ppc64le]: + kadmind does not accept ACL if kadm5.acl does not end with EOL") + The code "accidently" works on x86/AMD64 because declaring a + variable |char| results in an |unsigned char| by default while + most other platforms (e.g. { s390x, ppc64, ppc64le, ...}) + default to |signed char| (still have to use lint(1) to clean + up 38 more instances of this kind of bug). + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-7 +- Obsolete multilib versions of server packages to fix RH + bug #1251913 ("krb5 should obsolete the multilib versions + of krb5-server and krb5-server-ldap"). + The following packages are declared obsolete: + - krb5-server-1.11.3-49.el7.i686 + - krb5-server-1.11.3-49.el7.ppc + - krb5-server-1.11.3-49.el7.s390 + - krb5-server-ldap-1.11.3-49.el7.i686 + - krb5-server-ldap-1.11.3-49.el7.ppc + - krb5-server-ldap-1.11.3-49.el7.s390 + +* Wed Aug 19 2015 Roland Mainz - 1.13.2-6 +- Add a patch to fix RedHat bug #1252454 ('testsuite complains + "Lifetime has increased by 32436 sec while 0 sec passed!", + while rhel5-libkrb5 passes') so that krb5 resolves GSS creds + if |time_rec| is requested. + +* Fri Aug 7 2015 Roland Mainz - 1.13.2-5 +- Add a patch to fix RedHat bug #1251586 ("KDC sends multiple requests to ipa-otpd for the same authentication") which causes the KDC to send multiple retries to ipa-otpd for TCP transports while it should only be done for UDP. +* Tue Jul 28 2015 Roland Mainz - 1.13.2-4 +- the rebase to krb5 1.13.2 in vers 1.13.2-0 also fixed: + - Redhat Bug #1247761 ("RFE: Minor krb5 spec file cleanup and sync + with recent Fedora 22/23 changes") + - Redhat Bug #1247751 ("krb5-config returns wrong -specs path") + - Redhat Bug #1247608 ('Add support for multi-hop preauth mechs + via |KDC_ERR_MORE_PREAUTH_DATA_REQUIRED| for RFC 6113 ("A + Generalized Framework for Kerberos Pre-Authentication")') +- Removed "krb5-1.10-kprop-mktemp.patch" and + "krb5-1.3.4-send-pr-tempfile.patch", both are no longer used since + the rebase to krb5 1.13.1 + +* Fri May 29 2015 Roland Mainz - 1.13.2-3 +- Add patch to fix Redhat Bug #1222903 ("[SELinux] AVC denials may appear + when kadmind starts"). The issue was caused by an unneeded |htons()| + which triggered SELinux AVC denials due to the "random" port usage. + +* Thu May 21 2015 Roland Mainz - 1.13.2-2 +- Add fix for RedHat Bug #1164304 ("Upstream unit tests loads + the installed shared libraries instead the ones from the build") + +* Fri May 15 2015 Roland Mainz - 1.13.2-1 +- the rebase to krb5 1.13.1 in vers 1.13.1-0 also fixed: + - Bug 1144498 ("Fix the race condition in the libkrb5 replay cache") + - Bug 1163402 ("kdb5_ldap_util view_policy does not shows ticket flags on s390x and ppc64") + - Bug 1185770 ("Missing upstream test in krb5-1.12.2: src/tests/gssapi/t_invalid.c") + - Bug 1204211 ("CVE-2014-5355 krb5: unauthenticated denial of service in recvauth_common() and other") + +* Fri May 15 2015 Roland Mainz - 1.13.2-0 +- Update to krb5-1.13.2 + - drop patch for krb5-1.13.2-CVE_2015_2694_requires_preauth_bypass_in_PKINIT_enabled_KDC, fixed in krb5-1.13.2 + - drop patch for krb5-1.12.1-CVE_2014_5355_fix_krb5_read_message_handling, fixed in krb5-1.13.2 + +* Thu May 14 2015 Roland Mainz - 1.13.1-2 +- the rebase to krb5 1.13.1 in vers 1.13.1-0 also fixed RH + bug #1156144 ("krb5 upstream test t_kdb.py failure") + +* Mon May 4 2015 Roland Mainz - 1.13.1-1 +- fix for CVE-2015-2694 (#1218020) "requires_preauth bypass + in PKINIT-enabled KDC". + In MIT krb5 1.12 and later, when the KDC is configured with + PKINIT support, an unauthenticated remote attacker can + bypass the requires_preauth flag on a client principal and + obtain a ciphertext encrypted in the principal's long-term + key. This ciphertext could be used to conduct an off-line + dictionary attack against the user's password. + +* Fri Apr 24 2015 Roland Mainz - 1.13.1-0 +- Update to krb5-1.13.1 + - patch krb5-1.12-selinux-label was updated and renamed to krb5-1.13-selinux-label + - patch krb5-1.11-dirsrv-accountlock was updated and renamed to krb5-1.13-dirsrv-accountlock + - drop patch for krb5-1.12-pwdch-fast, fixed in krb5-1.13 + - drop patch for krb5-1.12ish-kpasswd_tcp, fixed in krb5-1.13 + - drop patch for krb5-master-rcache-internal-const, no longer needed + - drop patch for krb5-master-rcache-acquirecred-cleanup, no longer needed + - drop patch for krb5-master-rcache-acquirecred-source, no longer needed + - drop patch for krb5-master-rcache-acquirecred-test, no longer needed + - drop patch for krb5-master-move-otp-sockets, no longer needed + - drop patch for krb5-master-mechd, no longer needed + - drop patch for krb5-master-strdupcheck, no longer needed + - drop patch for krb5-master-compatible-keys, no longer needed + - drop patch for krb5-1.12-system-exts, fixed in krb5-1.13 + - drop patch for 0001-In-ksu-merge-krb5_ccache_copy-and-_restricted, no longer needed + - drop patch for 0002-In-ksu-don-t-stat-not-on-disk-ccache-residuals, no longer needed + - drop patch for 0003-Use-an-intermediate-memory-cache-in-ksu, no longer needed + - drop patch for 0004-Make-ksu-respect-the-default_ccache_name-setting, no longer needed + - drop patch for 0005-Copy-config-entries-to-the-ksu-target-ccache, no longer needed + - drop patch for 0006-Use-more-randomness-for-ksu-secondary-cache-names, no longer needed + - drop patch for 0007-Make-krb5_cc_new_unique-create-DIR-directories, no longer needed + - drop patch for krb5-1.12-kpasswd-skip-address-check, fixed in krb5-1.13 + - drop patch for 0000-Refactor-cm-functions-in-sendto_kdc.c, no longer needed + - drop patch for 0001-Simplify-sendto_kdc.c, no longer needed + - drop patch for 0002-Add-helper-to-determine-if-a-KDC-is-the-master, no longer needed + - drop patch for 0003-Use-k5_transport-_strategy-enums-for-k5_sendto, no longer needed + - drop patch for 0004-Build-support-for-TLS-used-by-HTTPS-proxy-support, no longer needed + - drop patch for 0005-Add-ASN.1-codec-for-KKDCP-s-KDC-PROXY-MESSAGE, no longer needed + - drop patch for 0006-Dispatch-style-protocol-switching-for-transport, no longer needed + - drop patch for 0007-HTTPS-transport-Microsoft-KKDCPP-implementation, no longer needed + - drop patch for 0008-Load-custom-anchors-when-using-KKDCP, no longer needed + - drop patch for 0009-Check-names-in-the-server-s-cert-when-using-KKDCP, no longer needed + - drop patch for 0010-Add-some-longer-form-docs-for-HTTPS, no longer needed + - drop patch for 0011-Have-k5test.py-provide-runenv-to-python-tests, no longer needed + - drop patch for 0012-Add-a-simple-KDC-proxy-test-server, no longer needed + - drop patch for 0013-Add-tests-for-MS-KKDCP-client-support, no longer needed + - drop patch for krb5-1.12ish-tls-plugins, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-nodelete-plugins, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-ksu-untyped-default-ccache-name, fixed in krb5-1.13.1 + - drop patch for krb5-1.12-ksu-no-ccache, fixed in krb5-1.13.1 + - drop patch for krb5-ksu_not_working_with_default_principal, fixed in krb5-1.13.1 + - drop patch for CVE_2014_5353_fix_LDAP_misused_policy_name_crash, fixed in krb5-1.13.1 + - drop patch for CVE_2014_5354_support_keyless_principals_in_ldap, fixed in krb5-1.13.1 + - drop patch for kinit -C loops (MIT/krb5 bug #243), fixed in krb5-1.13.1 + - drop patch for CVEs { 2014-9421, 2014-9422, 2014-9423, 2014-5352 }, fixed in krb5-1.13.1 + - added patch krb5-1.14-Support-KDC_ERR_MORE_PREAUTH_DATA_REQUIRED + - added patch krb5-1.12.1-CVE_2014_5355_fix_krb5_read_message_handling +- Minor spec cleanup + * Mon Jan 26 2015 Roland Mainz - 1.12.2-14 - fix for kinit -C loops (#1184629, MIT/krb5 issue 243, "Do not loop on principal unknown errors").