Hello community, here is the log from the commit of package krb5.4619 for openSUSE:13.2:Update checked in at 2016-02-10 12:48:50 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:13.2:Update/krb5.4619 (Old) and /work/SRC/openSUSE:13.2:Update/.krb5.4619.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "krb5.4619" Changes: -------- New Changes file: --- /dev/null 2016-01-27 19:41:03.648095915 +0100 +++ /work/SRC/openSUSE:13.2:Update/.krb5.4619.new/krb5-mini.changes 2016-02-10 12:48:51.000000000 +0100 @@ -0,0 +1,1304 @@ +------------------------------------------------------------------- +Wed Mar 11 19:45:44 UTC 2015 - [email protected] + +- bnc#918595 VUL-0: CVE-2014-5355: krb5: denial of service in krb5_read_message +patches: +0001-Fix-krb5_read_message-handling-CVE-2014-5355.patch + +------------------------------------------------------------------- +Mon Feb 16 12:51:51 UTC 2015 - [email protected] + +- bnc#910457: CVE-2014-5353: NULL pointer dereference when using a ticket policy name as password name +- bnc#910458: CVE-2014-5354: NULL pointer dereference when using keyless entries + +patches: +krb5-1.12.2-CVE-2014-5353.patch +krb5-1.12.2-CVE-2014-5354.patch + +------------------------------------------------------------------- +Mon Feb 2 22:44:46 UTC 2015 - [email protected] + +- bnc#912002 VUL-0: CVE-2014-5352 CVE-2014-9421 CVE-2014-9422 CVE-2014-9423: + krb5: Vulnerabilities in kadmind, libgssrpc, gss_process_context_token +- added patches: + * bnc#912002.diff + +------------------------------------------------------------------- +Thu Sep 25 12:48:32 UTC 2014 - [email protected] + +- Work around replay cache creation race; (bnc#898439). + krb5-1.13-work-around-replay-cache-creation-race.patch + +------------------------------------------------------------------- +Tue Sep 23 13:25:33 UTC 2014 - [email protected] + +- bnc#897874 CVE-2014-5351: krb5: current keys returned when randomizing the keys for a service principal +- added patches: + * bnc#897874-CVE-2014-5351.diff +------------------------------------------------------------------- +Sat Aug 30 22:29:28 UTC 2014 - [email protected] + +- krb5 5.12.2: + * Work around a gcc optimizer bug that could cause DB2 KDC + database operations to spin in an infinite loop + * Fix a backward compatibility problem with the LDAP KDB schema + that could prevent krb5-1.11 and later from decoding entries + created by krb5-1.6. + * Avoid an infinite loop under some circumstances when the GSS + mechglue loads a dynamic mechanism. + * Fix krb5kdc argument parsing so "-w" and "-r" options work + togetherreliably. +- Vulnerability fixes previously fixed in package via patches: + * Handle certain invalid RFC 1964 GSS tokens correctly to avoid + invalid memory reference vulnerabilities. [CVE-2014-4341 + CVE-2014-4342] + * Fix memory management vulnerabilities in GSSAPI SPNEGO. + [CVE-2014-4343 CVE-2014-4344] + * Fix buffer overflow vulnerability in LDAP KDB back end. + [CVE-2014-4345] +- updated patches: + * krb5-1.7-doublelog.patch for context change + * krb5-1.6.3-ktutil-manpage.dif, same +- removed patches, in upstream: + * krb5-master-keyring-kdcsync.patch + * krb5-1.12-CVE-2014-4341-CVE-2014-4342.patch + * krb5-1.12-CVE-2014-4343-Fix-double-free-in-SPNEGO.patch + * krb5-1.12-CVE-2014-4344-Fix-null-deref-in-SPNEGO-acceptor.patch + * krb5-1.12-CVE-2014-4345-buffer-overrun-in-kadmind-with-LDAP-backend.patch +- Fix build with doxygen 1.8.8 - adding krb5-1.12-doxygen.patch + from upstream + +------------------------------------------------------------------- +Fri Aug 8 15:55:01 UTC 2014 - [email protected] + +- buffer overrun in kadmind with LDAP backend + CVE-2014-4345 (bnc#891082) + krb5-1.12-CVE-2014-4345-buffer-overrun-in-kadmind-with-LDAP-backend.patch + +------------------------------------------------------------------- +Mon Jul 28 09:22:06 UTC 2014 - [email protected] + +- Fix double-free in SPNEGO [CVE-2014-4343] (bnc#888697) + krb5-1.12-CVE-2014-4343-Fix-double-free-in-SPNEGO.patch + Fix null deref in SPNEGO acceptor [CVE-2014-4344] + krb5-1.12-CVE-2014-4344-Fix-null-deref-in-SPNEGO-acceptor.patch + +------------------------------------------------------------------- +Sat Jul 19 12:38:21 UTC 2014 - [email protected] + +- Do not depend of insserv if systemd is used + +------------------------------------------------------------------- +Thu Jul 10 15:59:52 UTC 2014 - [email protected] + +- denial of service flaws when handling RFC 1964 tokens (bnc#886016) + krb5-1.12-CVE-2014-4341-CVE-2014-4342.patch +- start krb5kdc after slapd (bnc#886102) + +------------------------------------------------------------------- +Fri Jun 6 11:08:08 UTC 2014 - [email protected] + +- obsolete krb5-plugin-preauth-pkinit-nss (bnc#881674) + similar functionality is provided by krb5-plugin-preauth-pkinit + +------------------------------------------------------------------- +Tue Feb 18 15:25:57 UTC 2014 - [email protected] + +- don't deliver SysV init files to systemd distributions + +------------------------------------------------------------------- +Tue Jan 21 14:23:37 UTC 2014 - [email protected] + +- update to version 1.12.1 + * Make KDC log service principal names more consistently during + some error conditions, instead of "<unknown server>" + * Fix several bugs related to building AES-NI support on less + common configurations + * Fix several bugs related to keyring credential caches +- upstream obsoletes: + krb5-1.12-copy_context.patch + krb5-1.12-enable-NX.patch + krb5-1.12-pic-aes-ni.patch + krb5-master-no-malloc0.patch + krb5-master-ignore-empty-unnecessary-final-token.patch + krb5-master-gss_oid_leak.patch + krb5-master-keytab_close.patch + krb5-master-spnego_error_messages.patch +- Fix Get time offsets for all keyring ccaches + krb5-master-keyring-kdcsync.patch (RT#7820) + +------------------------------------------------------------------- +Mon Jan 13 15:37:16 UTC 2014 - [email protected] + +- update to version 1.12 + * Add GSSAPI extensions for constructing MIC tokens using IOV lists + * Add a FAST OTP preauthentication module for the KDC which uses + RADIUS to validate OTP token values. + * The AES-based encryption types will use AES-NI instructions + when possible for improved performance. +- revert dependency on libcom_err-mini-devel since it's not yet + available +- update and rebase patches + * krb5-1.10-buildconf.patch -> krb5-1.12-buildconf.patch + * krb5-1.11-pam.patch -> krb5-1.12-pam.patch + * krb5-1.11-selinux-label.patch -> krb5-1.12-selinux-label.patch + * krb5-1.8-api.patch -> krb5-1.12-api.patch + * krb5-1.9-ksu-path.patch -> krb5-1.12-ksu-path.patch + * krb5-1.9-debuginfo.patch + * krb5-1.9-kprop-mktemp.patch + * krb5-kvno-230379.patch +- added upstream patches + - Fix krb5_copy_context + * krb5-1.12-copy_context.patch + - Mark AESNI files as not needing executable stacks + * krb5-1.12-enable-NX.patch + * krb5-1.12-pic-aes-ni.patch + - Fix memory leak in SPNEGO initiator + * krb5-master-gss_oid_leak.patch + - Fix SPNEGO one-hop interop against old IIS + * krb5-master-ignore-empty-unnecessary-final-token.patch + - Fix GSS krb5 acceptor acquire_cred error handling + * krb5-master-keytab_close.patch + - Avoid malloc(0) in SPNEGO get_input_token + * krb5-master-no-malloc0.patch + - Test SPNEGO error message in t_s4u.py + * krb5-master-spnego_error_messages.patch + +------------------------------------------------------------------- +Tue Dec 10 02:43:32 UTC 2013 - [email protected] + +- Reduce build dependencies for krb5-mini by removing + doxygen and changing libcom_err-devel to + libcom_err-mini-devel +- Small fix to pre_checkin.sh so krb5-mini.spec is correct. + +------------------------------------------------------------------- +Fri Nov 15 13:33:53 UTC 2013 - [email protected] + +- update to version 1.11.4 + - Fix a KDC null pointer dereference [CVE-2013-1417] that could + affect realms with an uncommon configuration. + - Fix a KDC null pointer dereference [CVE-2013-1418] that could + affect KDCs that serve multiple realms. + - Fix a number of bugs related to KDC master key rollover. + +------------------------------------------------------------------- +Mon Jun 24 16:21:07 UTC 2013 - [email protected] + +- install and enable systemd service files also in -mini package + +------------------------------------------------------------------- +Fri Jun 21 02:12:03 UTC 2013 - [email protected] + +- remove fstack-protector-all from CFLAGS, just use the + lighter/fast version already present in %optflags + +- Use LFS_CFLAGS to build in 32 bit archs. + ++++ 1107 more lines (skipped) ++++ between /dev/null ++++ and /work/SRC/openSUSE:13.2:Update/.krb5.4619.new/krb5-mini.changes New Changes file: --- /dev/null 2016-01-27 19:41:03.648095915 +0100 +++ /work/SRC/openSUSE:13.2:Update/.krb5.4619.new/krb5.changes 2016-02-10 12:48:52.000000000 +0100 @@ -0,0 +1,1334 @@ +------------------------------------------------------------------- +Tue Feb 2 08:37:15 UTC 2016 - [email protected] + +- Fix CVE-2015-8629: krb5: xdr_nullstring() doesn't check for terminating null character + with patch 0104-Verify-decoded-kadmin-C-strings-CVE-2015-8629.patch + (bsc#963968) +- Fix CVE-2015-8631: krb5: Memory leak caused by supplying a null principal name in request + with patch 0105-Fix-leaks-in-kadmin-server-stubs-CVE-2015-8631.patch + (bsc#963975) +- Fix CVE-2015-8630: krb5: krb5 doesn't check for null policy when KADM5_POLICY is set in the mask + with patch 0106-Check-for-null-kadm5-policy-name-CVE-2015-8630.patch + (bsc#963964) + +------------------------------------------------------------------- +Tue Nov 10 14:54:51 UTC 2015 - [email protected] + +- Apply patch 0103-Fix-IAKERB-context-export-import-CVE-2015-2698.patch + to fix a memory corruption regression introduced by resolution of + CVE-2015-2698. bsc#954204 + +------------------------------------------------------------------- +Wed Oct 28 14:42:38 UTC 2015 - [email protected] + +- Apply patch 0100-Fix-build_principal-memory-bug-CVE-2015-2697.patch + to fix build_principal memory bug [CVE-2015-2697] bsc#952190 +- Apply patch 0101-Fix-IAKERB-context-aliasing-bugs-CVE-2015-2696.patch + to fix IAKERB context aliasing bugs [CVE-2015-2696] bsc#952189 +- Apply patch 0102-Fix-SPNEGO-context-aliasing-bugs-CVE-2015-2695.patch + to fix SPNEGO context aliasing bugs [CVE-2015-2695] bsc#952188 + +------------------------------------------------------------------- +Wed Mar 11 19:45:44 UTC 2015 - [email protected] + +- bnc#918595 VUL-0: CVE-2014-5355: krb5: denial of service in krb5_read_message +patches: +0001-Fix-krb5_read_message-handling-CVE-2014-5355.patch + +------------------------------------------------------------------- +Mon Feb 16 12:51:51 UTC 2015 - [email protected] + +- bnc#910457: CVE-2014-5353: NULL pointer dereference when using a ticket policy name as password name +- bnc#910458: CVE-2014-5354: NULL pointer dereference when using keyless entries + +patches: +krb5-1.12.2-CVE-2014-5353.patch +krb5-1.12.2-CVE-2014-5354.patch + +------------------------------------------------------------------- +Mon Feb 2 22:44:46 UTC 2015 - [email protected] + +- bnc#912002 VUL-0: CVE-2014-5352 CVE-2014-9421 CVE-2014-9422 CVE-2014-9423: + krb5: Vulnerabilities in kadmind, libgssrpc, gss_process_context_token +- added patches: + * bnc#912002.diff + +------------------------------------------------------------------- +Thu Sep 25 12:48:32 UTC 2014 - [email protected] + +- Work around replay cache creation race; (bnc#898439). + krb5-1.13-work-around-replay-cache-creation-race.patch + +------------------------------------------------------------------- +Tue Sep 23 13:25:33 UTC 2014 - [email protected] + +- bnc#897874 CVE-2014-5351: krb5: current keys returned when randomizing the keys for a service principal +- added patches: + * bnc#897874-CVE-2014-5351.diff +------------------------------------------------------------------- +Sat Aug 30 22:29:28 UTC 2014 - [email protected] + +- krb5 5.12.2: + * Work around a gcc optimizer bug that could cause DB2 KDC + database operations to spin in an infinite loop + * Fix a backward compatibility problem with the LDAP KDB schema + that could prevent krb5-1.11 and later from decoding entries + created by krb5-1.6. + * Avoid an infinite loop under some circumstances when the GSS + mechglue loads a dynamic mechanism. + * Fix krb5kdc argument parsing so "-w" and "-r" options work + togetherreliably. +- Vulnerability fixes previously fixed in package via patches: + * Handle certain invalid RFC 1964 GSS tokens correctly to avoid + invalid memory reference vulnerabilities. [CVE-2014-4341 + CVE-2014-4342] + * Fix memory management vulnerabilities in GSSAPI SPNEGO. + [CVE-2014-4343 CVE-2014-4344] + * Fix buffer overflow vulnerability in LDAP KDB back end. + [CVE-2014-4345] +- updated patches: + * krb5-1.7-doublelog.patch for context change + * krb5-1.6.3-ktutil-manpage.dif, same +- removed patches, in upstream: + * krb5-master-keyring-kdcsync.patch + * krb5-1.12-CVE-2014-4341-CVE-2014-4342.patch + * krb5-1.12-CVE-2014-4343-Fix-double-free-in-SPNEGO.patch + * krb5-1.12-CVE-2014-4344-Fix-null-deref-in-SPNEGO-acceptor.patch + * krb5-1.12-CVE-2014-4345-buffer-overrun-in-kadmind-with-LDAP-backend.patch +- Fix build with doxygen 1.8.8 - adding krb5-1.12-doxygen.patch + from upstream + +------------------------------------------------------------------- +Fri Aug 8 15:55:01 UTC 2014 - [email protected] + +- buffer overrun in kadmind with LDAP backend + CVE-2014-4345 (bnc#891082) + krb5-1.12-CVE-2014-4345-buffer-overrun-in-kadmind-with-LDAP-backend.patch + +------------------------------------------------------------------- +Mon Jul 28 09:22:06 UTC 2014 - [email protected] + +- Fix double-free in SPNEGO [CVE-2014-4343] (bnc#888697) + krb5-1.12-CVE-2014-4343-Fix-double-free-in-SPNEGO.patch + Fix null deref in SPNEGO acceptor [CVE-2014-4344] + krb5-1.12-CVE-2014-4344-Fix-null-deref-in-SPNEGO-acceptor.patch + +------------------------------------------------------------------- +Sat Jul 19 12:38:21 UTC 2014 - [email protected] + +- Do not depend of insserv if systemd is used + +------------------------------------------------------------------- +Thu Jul 10 15:59:52 UTC 2014 - [email protected] + +- denial of service flaws when handling RFC 1964 tokens (bnc#886016) + krb5-1.12-CVE-2014-4341-CVE-2014-4342.patch +- start krb5kdc after slapd (bnc#886102) + +------------------------------------------------------------------- +Fri Jun 6 11:08:08 UTC 2014 - [email protected] + +- obsolete krb5-plugin-preauth-pkinit-nss (bnc#881674) + similar functionality is provided by krb5-plugin-preauth-pkinit + +------------------------------------------------------------------- +Tue Feb 18 15:25:57 UTC 2014 - [email protected] + +- don't deliver SysV init files to systemd distributions + +------------------------------------------------------------------- +Tue Jan 21 14:23:37 UTC 2014 - [email protected] + +- update to version 1.12.1 + * Make KDC log service principal names more consistently during + some error conditions, instead of "<unknown server>" + * Fix several bugs related to building AES-NI support on less + common configurations + * Fix several bugs related to keyring credential caches +- upstream obsoletes: + krb5-1.12-copy_context.patch + krb5-1.12-enable-NX.patch + krb5-1.12-pic-aes-ni.patch + krb5-master-no-malloc0.patch + krb5-master-ignore-empty-unnecessary-final-token.patch + krb5-master-gss_oid_leak.patch + krb5-master-keytab_close.patch + krb5-master-spnego_error_messages.patch +- Fix Get time offsets for all keyring ccaches + krb5-master-keyring-kdcsync.patch (RT#7820) + +------------------------------------------------------------------- +Mon Jan 13 15:37:16 UTC 2014 - [email protected] + +- update to version 1.12 + * Add GSSAPI extensions for constructing MIC tokens using IOV lists + * Add a FAST OTP preauthentication module for the KDC which uses + RADIUS to validate OTP token values. + * The AES-based encryption types will use AES-NI instructions + when possible for improved performance. +- revert dependency on libcom_err-mini-devel since it's not yet + available +- update and rebase patches + * krb5-1.10-buildconf.patch -> krb5-1.12-buildconf.patch + * krb5-1.11-pam.patch -> krb5-1.12-pam.patch + * krb5-1.11-selinux-label.patch -> krb5-1.12-selinux-label.patch + * krb5-1.8-api.patch -> krb5-1.12-api.patch + * krb5-1.9-ksu-path.patch -> krb5-1.12-ksu-path.patch + * krb5-1.9-debuginfo.patch + * krb5-1.9-kprop-mktemp.patch + * krb5-kvno-230379.patch +- added upstream patches + - Fix krb5_copy_context + * krb5-1.12-copy_context.patch + - Mark AESNI files as not needing executable stacks + * krb5-1.12-enable-NX.patch + * krb5-1.12-pic-aes-ni.patch + - Fix memory leak in SPNEGO initiator + * krb5-master-gss_oid_leak.patch + - Fix SPNEGO one-hop interop against old IIS + * krb5-master-ignore-empty-unnecessary-final-token.patch + - Fix GSS krb5 acceptor acquire_cred error handling + * krb5-master-keytab_close.patch + - Avoid malloc(0) in SPNEGO get_input_token + * krb5-master-no-malloc0.patch + - Test SPNEGO error message in t_s4u.py + * krb5-master-spnego_error_messages.patch + +------------------------------------------------------------------- ++++ 1137 more lines (skipped) ++++ between /dev/null ++++ and /work/SRC/openSUSE:13.2:Update/.krb5.4619.new/krb5.changes New: ---- 0001-Fix-krb5_read_message-handling-CVE-2014-5355.patch 0100-Fix-build_principal-memory-bug-CVE-2015-2697.patch 0101-Fix-IAKERB-context-aliasing-bugs-CVE-2015-2696.patch 0102-Fix-SPNEGO-context-aliasing-bugs-CVE-2015-2695.patch 0103-Fix-IAKERB-context-export-import-CVE-2015-2698.patch 0104-Verify-decoded-kadmin-C-strings-CVE-2015-8629.patch 0105-Fix-leaks-in-kadmin-server-stubs-CVE-2015-8631.patch 0106-Check-for-null-kadm5-policy-name-CVE-2015-8630.patch baselibs.conf bnc#897874-CVE-2014-5351.diff bnc#912002.diff krb5-1.10-kpasswd_tcp.patch krb5-1.10-ksu-access.patch krb5-1.12-api.patch krb5-1.12-buildconf.patch krb5-1.12-doxygen.patch krb5-1.12-ksu-path.patch krb5-1.12-pam.patch krb5-1.12-selinux-label.patch krb5-1.12.2-CVE-2014-5353.patch krb5-1.12.2-CVE-2014-5354.patch krb5-1.12.2.tar.gz krb5-1.13-work-around-replay-cache-creation-race.patch krb5-1.6.3-gssapi_improve_errormessages.dif krb5-1.6.3-ktutil-manpage.dif krb5-1.7-doublelog.patch krb5-1.9-debuginfo.patch krb5-1.9-kprop-mktemp.patch krb5-1.9-manpaths.dif krb5-kvno-230379.patch krb5-mini.changes krb5-mini.spec krb5-rpmlintrc krb5.changes krb5.spec pre_checkin.sh vendor-files.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ krb5-mini.spec ++++++ ++++ 733 lines (skipped) krb5.spec: same change ++++++ 0001-Fix-krb5_read_message-handling-CVE-2014-5355.patch ++++++ >From 102bb6ebf20f9174130c85c3b052ae104e5073ec Mon Sep 17 00:00:00 2001 From: Greg Hudson <[email protected]> Date: Tue, 9 Dec 2014 12:37:44 -0500 Subject: [PATCH] Fix krb5_read_message handling [CVE-2014-5355] In recvauth_common, do not use strcmp against the data fields of krb5_data objects populated by krb5_read_message(), as there is no guarantee that they are C strings. Instead, create an expected krb5_data value and use data_eq(). In the sample user-to-user server application, check that the received client principal name is null-terminated before using it with printf and krb5_parse_name. CVE-2014-5355: In MIT krb5, when a server process uses the krb5_recvauth function, an unauthenticated remote attacker can cause a NULL dereference by sending a zero-byte version string, or a read beyond the end of allocated storage by sending a non-null-terminated version string. The example user-to-user server application (uuserver) is similarly vulnerable to a zero-length or non-null-terminated principal name string. The krb5_recvauth function reads two version strings from the client using krb5_read_message(), which produces a krb5_data structure containing a length and a pointer to an octet sequence. krb5_recvauth assumes that the data pointer is a valid C string and passes it to strcmp() to verify the versions. If the client sends an empty octet sequence, the data pointer will be NULL and strcmp() will dereference a NULL pointer, causing the process to crash. If the client sends a non-null-terminated octet sequence, strcmp() will read beyond the end of the allocated storage, possibly causing the process to crash. uuserver similarly uses krb5_read_message() to read a client principal name, and then passes it to printf() and krb5_parse_name() without verifying that it is a valid C string. The krb5_recvauth function is used by kpropd and the Kerberized versions of the BSD rlogin and rsh daemons. These daemons are usually run out of inetd or in a mode which forks before processing incoming connections, so a process crash will generally not result in a complete denial of service. Thanks to Tim Uglow for discovering this issue. CVSSv2: AV:N/AC:L/Au:N/C:N/I:N/A:P/E:POC/RL:OF/RC:C [[email protected]: CVSS score] ticket: 8050 (new) target_version: 1.13.1 tags: pullup --- src/appl/user_user/server.c | 4 +++- src/lib/krb5/krb/recvauth.c | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/appl/user_user/server.c b/src/appl/user_user/server.c index 09ea4e0..f2b5b61 100644 --- a/src/appl/user_user/server.c +++ b/src/appl/user_user/server.c @@ -111,8 +111,10 @@ int main(argc, argv) } #endif + /* principal name must be sent null-terminated. */ retval = krb5_read_message(context, (krb5_pointer) &sock, &pname_data); - if (retval) { + if (retval || pname_data.length == 0 || + pname_data.data[pname_data.length - 1] != '\0') { com_err ("uu-server", retval, "reading pname"); return 2; } diff --git a/src/lib/krb5/krb/recvauth.c b/src/lib/krb5/krb/recvauth.c index da836283..5adc6dd 100644 --- a/src/lib/krb5/krb/recvauth.c +++ b/src/lib/krb5/krb/recvauth.c @@ -59,6 +59,7 @@ recvauth_common(krb5_context context, krb5_rcache rcache = 0; krb5_octet response; krb5_data null_server; + krb5_data d; int need_error_free = 0; int local_rcache = 0, local_authcon = 0; @@ -77,7 +78,8 @@ recvauth_common(krb5_context context, */ if ((retval = krb5_read_message(context, fd, &inbuf))) return(retval); - if (strcmp(inbuf.data, sendauth_version)) { + d = make_data((char *)sendauth_version, strlen(sendauth_version) + 1); + if (!data_eq(inbuf, d)) { problem = KRB5_SENDAUTH_BADAUTHVERS; response = 1; } @@ -93,8 +95,9 @@ recvauth_common(krb5_context context, */ if ((retval = krb5_read_message(context, fd, &inbuf))) return(retval); - if (appl_version && strcmp(inbuf.data, appl_version)) { - if (!problem) { + if (appl_version != NULL && !problem) { + d = make_data(appl_version, strlen(appl_version) + 1); + if (!data_eq(inbuf, d)) { problem = KRB5_SENDAUTH_BADAPPLVERS; response = 2; } -- 1.8.5.2 ++++++ 0100-Fix-build_principal-memory-bug-CVE-2015-2697.patch ++++++ >From f0c094a1b745d91ef2f9a4eae2149aac026a5789 Mon Sep 17 00:00:00 2001 From: Greg Hudson <[email protected]> Date: Fri, 25 Sep 2015 12:51:47 -0400 Subject: [PATCH] Fix build_principal memory bug [CVE-2015-2697] In build_principal_va(), use k5memdup0() instead of strdup() to make a copy of the realm, to ensure that we allocate the correct number of bytes and do not read past the end of the input string. This bug affects krb5_build_principal(), krb5_build_principal_va(), and krb5_build_principal_alloc_va(). krb5_build_principal_ext() is not affected. CVE-2015-2697: In MIT krb5 1.7 and later, an authenticated attacker may be able to cause a KDC to crash using a TGS request with a large realm field beginning with a null byte. If the KDC attempts to find a referral to answer the request, it constructs a principal name for lookup using krb5_build_principal() with the requested realm. Due to a bug in this function, the null byte causes only one byte be allocated for the realm field of the constructed principal, far less than its length. Subsequent operations on the lookup principal may cause a read beyond the end of the mapped memory region, causing the KDC process to crash. CVSSv2: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C ticket: 8252 (new) target_version: 1.14 tags: pullup diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c index ab6fed8..8604268 100644 --- a/src/lib/krb5/krb/bld_princ.c +++ b/src/lib/krb5/krb/bld_princ.c @@ -40,10 +40,8 @@ build_principal_va(krb5_context context, krb5_principal princ, data = malloc(size * sizeof(krb5_data)); if (!data) { retval = ENOMEM; } - if (!retval) { - r = strdup(realm); - if (!r) { retval = ENOMEM; } - } + if (!retval) + r = k5memdup0(realm, rlen, &retval); while (!retval && (component = va_arg(ap, char *))) { if (count == size) { -- 2.6.2 ++++++ 0101-Fix-IAKERB-context-aliasing-bugs-CVE-2015-2696.patch ++++++ ++++ 729 lines (skipped) ++++++ 0102-Fix-SPNEGO-context-aliasing-bugs-CVE-2015-2695.patch ++++++ >From b51b33f2bc5d1497ddf5bd107f791c101695000d Mon Sep 17 00:00:00 2001 From: Nicolas Williams <[email protected]> Date: Mon, 14 Sep 2015 12:27:52 -0400 Subject: [PATCH] Fix SPNEGO context aliasing bugs [CVE-2015-2695] The SPNEGO mechanism currently replaces its context handle with the mechanism context handle upon establishment, under the assumption that most GSS functions are only called after context establishment. This assumption is incorrect, and can lead to aliasing violations for some programs. Maintain the SPNEGO context structure after context establishment and refer to it in all GSS methods. Add initiate and opened flags to the SPNEGO context structure for use in gss_inquire_context() prior to context establishment. CVE-2015-2695: In MIT krb5 1.5 and later, applications which call gss_inquire_context() on a partially-established SPNEGO context can cause the GSS-API library to read from a pointer using the wrong type, generally causing a process crash. This bug may go unnoticed, because the most common SPNEGO authentication scenario establishes the context after just one call to gss_accept_sec_context(). Java server applications using the native JGSS provider are vulnerable to this bug. A carefully crafted SPNEGO packet might allow the gss_inquire_context() call to succeed with attacker-determined results, but applications should not make access control decisions based on gss_inquire_context() results prior to context establishment. CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C [[email protected]: several bugfixes, style changes, and edge-case behavior changes; commit message and CVE description] ticket: 8244 target_version: 1.14 tags: pullup diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h index 57372de..5c82764 100644 --- a/src/lib/gssapi/spnego/gssapiP_spnego.h +++ b/src/lib/gssapi/spnego/gssapiP_spnego.h @@ -103,6 +103,8 @@ typedef struct { int firstpass; int mech_complete; int nego_done; + int initiate; + int opened; OM_uint32 ctx_flags; gss_name_t internal_name; gss_OID actual_mech; diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c index ef76e1f..7849c85 100644 --- a/src/lib/gssapi/spnego/spnego_mech.c +++ b/src/lib/gssapi/spnego/spnego_mech.c @@ -102,7 +102,7 @@ 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 *); static void check_spnego_options(spnego_gss_ctx_id_t); -static spnego_gss_ctx_id_t create_spnego_ctx(void); +static spnego_gss_ctx_id_t create_spnego_ctx(int); static int put_mech_set(gss_OID_set mechSet, gss_buffer_t buf); static int put_input_token(unsigned char **, gss_buffer_t, unsigned int); static int put_mech_oid(unsigned char **, gss_OID_const, unsigned int); @@ -454,7 +454,7 @@ check_spnego_options(spnego_gss_ctx_id_t spnego_ctx) } static spnego_gss_ctx_id_t -create_spnego_ctx(void) +create_spnego_ctx(int initiate) { spnego_gss_ctx_id_t spnego_ctx = NULL; spnego_ctx = (spnego_gss_ctx_id_t) @@ -477,6 +477,8 @@ create_spnego_ctx(void) spnego_ctx->mic_rcvd = 0; spnego_ctx->mech_complete = 0; spnego_ctx->nego_done = 0; + spnego_ctx->opened = 0; + spnego_ctx->initiate = initiate; spnego_ctx->internal_name = GSS_C_NO_NAME; spnego_ctx->actual_mech = GSS_C_NO_OID; @@ -642,7 +644,7 @@ init_ctx_new(OM_uint32 *minor_status, OM_uint32 ret; spnego_gss_ctx_id_t sc = NULL; - sc = create_spnego_ctx(); + sc = create_spnego_ctx(1); if (sc == NULL) return GSS_S_FAILURE; @@ -659,10 +661,7 @@ init_ctx_new(OM_uint32 *minor_status, ret = GSS_S_FAILURE; goto cleanup; } - /* - * The actual context is not yet determined, set the output - * context handle to refer to the spnego context itself. - */ + sc->ctx_handle = GSS_C_NO_CONTEXT; *ctx = (gss_ctx_id_t)sc; sc = NULL; @@ -1108,16 +1107,11 @@ cleanup: } gss_release_buffer(&tmpmin, &mechtok_out); if (ret == GSS_S_COMPLETE) { - /* - * Now, switch the output context to refer to the - * negotiated mechanism's context. - */ - *context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle; + spnego_ctx->opened = 1; if (actual_mech != NULL) *actual_mech = spnego_ctx->actual_mech; if (ret_flags != NULL) *ret_flags = spnego_ctx->ctx_flags; - release_spnego_ctx(&spnego_ctx); } else if (ret != GSS_S_CONTINUE_NEEDED) { if (spnego_ctx != NULL) { gss_delete_sec_context(&tmpmin, @@ -1285,7 +1279,7 @@ acc_ctx_hints(OM_uint32 *minor_status, if (ret != GSS_S_COMPLETE) goto cleanup; - sc = create_spnego_ctx(); + sc = create_spnego_ctx(0); if (sc == NULL) { ret = GSS_S_FAILURE; goto cleanup; @@ -1367,7 +1361,7 @@ acc_ctx_new(OM_uint32 *minor_status, gss_release_buffer(&tmpmin, &sc->DER_mechTypes); assert(mech_wanted != GSS_C_NO_OID); } else - sc = create_spnego_ctx(); + sc = create_spnego_ctx(0); if (sc == NULL) { ret = GSS_S_FAILURE; *return_token = NO_TOKEN_SEND; @@ -1750,13 +1744,12 @@ cleanup: ret = GSS_S_FAILURE; } if (ret == GSS_S_COMPLETE) { - *context_handle = (gss_ctx_id_t)sc->ctx_handle; + sc->opened = 1; if (sc->internal_name != GSS_C_NO_NAME && src_name != NULL) { *src_name = sc->internal_name; sc->internal_name = GSS_C_NO_NAME; } - release_spnego_ctx(&sc); } else if (ret != GSS_S_CONTINUE_NEEDED) { if (sc != NULL) { gss_delete_sec_context(&tmpmin, &sc->ctx_handle, @@ -2069,8 +2062,13 @@ spnego_gss_unwrap( gss_qop_t *qop_state) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_unwrap(minor_status, - context_handle, + sc->ctx_handle, input_message_buffer, output_message_buffer, conf_state, @@ -2090,8 +2088,13 @@ spnego_gss_wrap( gss_buffer_t output_message_buffer) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_wrap(minor_status, - context_handle, + sc->ctx_handle, conf_req_flag, qop_req, input_message_buffer, @@ -2108,8 +2111,14 @@ spnego_gss_process_context_token( const gss_buffer_t token_buffer) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + /* SPNEGO doesn't have its own context tokens. */ + if (!sc->opened) + return (GSS_S_DEFECTIVE_TOKEN); + ret = gss_process_context_token(minor_status, - context_handle, + sc->ctx_handle, token_buffer); return (ret); @@ -2133,19 +2142,9 @@ spnego_gss_delete_sec_context( if (*ctx == NULL) return (GSS_S_COMPLETE); - /* - * If this is still an SPNEGO mech, release it locally. - */ - if ((*ctx)->magic_num == SPNEGO_MAGIC_ID) { - (void) gss_delete_sec_context(minor_status, - &(*ctx)->ctx_handle, - output_token); - (void) release_spnego_ctx(ctx); - } else { - ret = gss_delete_sec_context(minor_status, - context_handle, - output_token); - } + (void) gss_delete_sec_context(minor_status, &(*ctx)->ctx_handle, + output_token); + (void) release_spnego_ctx(ctx); return (ret); } @@ -2157,8 +2156,13 @@ spnego_gss_context_time( OM_uint32 *time_rec) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_context_time(minor_status, - context_handle, + sc->ctx_handle, time_rec); return (ret); } @@ -2170,9 +2174,20 @@ spnego_gss_export_sec_context( gss_buffer_t interprocess_token) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = *(spnego_gss_ctx_id_t *)context_handle; + + /* We don't currently support exporting partially established + * contexts. */ + if (!sc->opened) + return GSS_S_UNAVAILABLE; + ret = gss_export_sec_context(minor_status, - context_handle, + &sc->ctx_handle, interprocess_token); + if (sc->ctx_handle == GSS_C_NO_CONTEXT) { + release_spnego_ctx(&sc); + *context_handle = GSS_C_NO_CONTEXT; + } return (ret); } @@ -2182,11 +2197,12 @@ spnego_gss_import_sec_context( const gss_buffer_t interprocess_token, gss_ctx_id_t *context_handle) { - OM_uint32 ret; - ret = gss_import_sec_context(minor_status, - interprocess_token, - context_handle); - return (ret); + /* + * Until we implement partial context exports, there are no SPNEGO + * exported context tokens, only tokens for underlying mechs. So just + * return an error for now. + */ + return GSS_S_UNAVAILABLE; } #endif /* LEAN_CLIENT */ @@ -2203,16 +2219,48 @@ spnego_gss_inquire_context( int *opened) { OM_uint32 ret = GSS_S_COMPLETE; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (src_name != NULL) + *src_name = GSS_C_NO_NAME; + if (targ_name != NULL) + *targ_name = GSS_C_NO_NAME; + if (lifetime_rec != NULL) + *lifetime_rec = 0; + if (mech_type != NULL) + *mech_type = (gss_OID)gss_mech_spnego; + if (ctx_flags != NULL) + *ctx_flags = 0; + if (locally_initiated != NULL) + *locally_initiated = sc->initiate; + if (opened != NULL) + *opened = sc->opened; + + if (sc->ctx_handle != GSS_C_NO_CONTEXT) { + ret = gss_inquire_context(minor_status, sc->ctx_handle, + src_name, targ_name, lifetime_rec, + mech_type, ctx_flags, NULL, NULL); + } - ret = gss_inquire_context(minor_status, - context_handle, - src_name, - targ_name, - lifetime_rec, - mech_type, - ctx_flags, - locally_initiated, - opened); + if (!sc->opened) { + /* + * We are still doing SPNEGO negotiation, so report SPNEGO as + * the OID. After negotiation is complete we will report the + * underlying mechanism OID. + */ + if (mech_type != NULL) + *mech_type = (gss_OID)gss_mech_spnego; + + /* + * Remove flags we don't support with partially-established + * contexts. (Change this to keep GSS_C_TRANS_FLAG if we add + * support for exporting partial SPNEGO contexts.) + */ + if (ctx_flags != NULL) { + *ctx_flags &= ~GSS_C_PROT_READY_FLAG; + *ctx_flags &= ~GSS_C_TRANS_FLAG; + } + } return (ret); } @@ -2227,8 +2275,13 @@ spnego_gss_wrap_size_limit( OM_uint32 *max_input_size) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_wrap_size_limit(minor_status, - context_handle, + sc->ctx_handle, conf_req_flag, qop_req, req_output_size, @@ -2245,8 +2298,13 @@ spnego_gss_get_mic( gss_buffer_t message_token) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_get_mic(minor_status, - context_handle, + sc->ctx_handle, qop_req, message_buffer, message_token); @@ -2262,8 +2320,13 @@ spnego_gss_verify_mic( gss_qop_t *qop_state) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_verify_mic(minor_status, - context_handle, + sc->ctx_handle, msg_buffer, token_buffer, qop_state); @@ -2278,8 +2341,14 @@ spnego_gss_inquire_sec_context_by_oid( gss_buffer_set_t *data_set) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + /* There are no SPNEGO-specific OIDs for this function. */ + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_UNAVAILABLE); + ret = gss_inquire_sec_context_by_oid(minor_status, - context_handle, + sc->ctx_handle, desired_object, data_set); return (ret); @@ -2359,8 +2428,15 @@ spnego_gss_set_sec_context_option( const gss_buffer_t value) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)*context_handle; + + /* There are no SPNEGO-specific OIDs for this function, and we cannot + * construct an empty SPNEGO context with it. */ + if (sc == NULL || sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_UNAVAILABLE); + ret = gss_set_sec_context_option(minor_status, - context_handle, + &sc->ctx_handle, desired_object, value); return (ret); @@ -2377,8 +2453,13 @@ spnego_gss_wrap_aead(OM_uint32 *minor_status, gss_buffer_t output_message_buffer) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_wrap_aead(minor_status, - context_handle, + sc->ctx_handle, conf_req_flag, qop_req, input_assoc_buffer, @@ -2399,8 +2480,13 @@ spnego_gss_unwrap_aead(OM_uint32 *minor_status, gss_qop_t *qop_state) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_unwrap_aead(minor_status, - context_handle, + sc->ctx_handle, input_message_buffer, input_assoc_buffer, output_payload_buffer, @@ -2419,8 +2505,13 @@ spnego_gss_wrap_iov(OM_uint32 *minor_status, int iov_count) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_wrap_iov(minor_status, - context_handle, + sc->ctx_handle, conf_req_flag, qop_req, conf_state, @@ -2438,8 +2529,13 @@ spnego_gss_unwrap_iov(OM_uint32 *minor_status, int iov_count) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_unwrap_iov(minor_status, - context_handle, + sc->ctx_handle, conf_state, qop_state, iov, @@ -2457,8 +2553,13 @@ spnego_gss_wrap_iov_length(OM_uint32 *minor_status, int iov_count) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_wrap_iov_length(minor_status, - context_handle, + sc->ctx_handle, conf_req_flag, qop_req, conf_state, @@ -2475,8 +2576,13 @@ spnego_gss_complete_auth_token( gss_buffer_t input_message_buffer) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_UNAVAILABLE); + ret = gss_complete_auth_token(minor_status, - context_handle, + sc->ctx_handle, input_message_buffer); return (ret); } @@ -2721,8 +2827,13 @@ spnego_gss_pseudo_random(OM_uint32 *minor_status, gss_buffer_t prf_out) { OM_uint32 ret; + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + ret = gss_pseudo_random(minor_status, - context, + sc->ctx_handle, prf_key, prf_in, desired_output_len, @@ -2863,7 +2974,12 @@ spnego_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t qop_req, gss_iov_buffer_desc *iov, int iov_count) { - return gss_get_mic_iov(minor_status, context_handle, qop_req, iov, + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + + return gss_get_mic_iov(minor_status, sc->ctx_handle, qop_req, iov, iov_count); } @@ -2872,7 +2988,12 @@ spnego_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t *qop_state, gss_iov_buffer_desc *iov, int iov_count) { - return gss_verify_mic_iov(minor_status, context_handle, qop_state, iov, + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + + return gss_verify_mic_iov(minor_status, sc->ctx_handle, qop_state, iov, iov_count); } @@ -2881,7 +3002,12 @@ spnego_gss_get_mic_iov_length(OM_uint32 *minor_status, gss_ctx_id_t context_handle, gss_qop_t qop_req, gss_iov_buffer_desc *iov, int iov_count) { - return gss_get_mic_iov_length(minor_status, context_handle, qop_req, iov, + spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle; + + if (sc->ctx_handle == GSS_C_NO_CONTEXT) + return (GSS_S_NO_CONTEXT); + + return gss_get_mic_iov_length(minor_status, sc->ctx_handle, qop_req, iov, iov_count); } -- 2.6.2 ++++++ 0103-Fix-IAKERB-context-export-import-CVE-2015-2698.patch ++++++ >From 3db8dfec1ef50ddd78d6ba9503185995876a39fd Mon Sep 17 00:00:00 2001 From: Greg Hudson <[email protected]> Date: Sun, 1 Nov 2015 22:45:21 -0500 Subject: [PATCH] Fix IAKERB context export/import [CVE-2015-2698] The patches for CVE-2015-2696 contained a regression in the newly added IAKERB iakerb_gss_export_sec_context() function, which could cause it to corrupt memory. Fix the regression by properly dereferencing the context_handle pointer before casting it. Also, the patches did not implement an IAKERB gss_import_sec_context() function, under the erroneous belief that an exported IAKERB context would be tagged as a krb5 context. Implement it now to allow IAKERB contexts to be successfully exported and imported after establishment. CVE-2015-2698: In any MIT krb5 release with the patches for CVE-2015-2696 applied, an application which calls gss_export_sec_context() may experience memory corruption if the context was established using the IAKERB mechanism. Historically, some vulnerabilities of this nature can be translated into remote code execution, though the necessary exploits must be tailored to the individual application and are usually quite complicated. CVSSv2 Vector: AV:N/AC:H/Au:S/C:C/I:C/A:C/E:POC/RL:OF/RC:C ticket: 8273 (new) target_version: 1.14 tags: pullup Line numbers are adjusted by Howard Guo <[email protected]> to fit into this older Kerberos version distributed on SLE 12. diff -rupN krb5-1.12.1/src/lib/gssapi/krb5/gssapi_krb5.c krb5-1.12.1-patched/src/lib/gssapi/krb5/gssapi_krb5.c --- krb5-1.12.1/src/lib/gssapi/krb5/gssapi_krb5.c 2015-11-10 15:37:32.209657599 +0100 +++ krb5-1.12.1-patched/src/lib/gssapi/krb5/gssapi_krb5.c 2015-11-10 15:38:52.106323672 +0100 @@ -945,7 +945,7 @@ static struct gss_config iakerb_mechanis NULL, #else iakerb_gss_export_sec_context, - NULL, + iakerb_gss_import_sec_context, #endif krb5_gss_inquire_cred_by_mech, krb5_gss_inquire_names_for_mech, diff -rupN krb5-1.12.1/src/lib/gssapi/krb5/gssapiP_krb5.h krb5-1.12.1-patched/src/lib/gssapi/krb5/gssapiP_krb5.h --- krb5-1.12.1/src/lib/gssapi/krb5/gssapiP_krb5.h 2015-11-10 15:37:32.209657599 +0100 +++ krb5-1.12.1-patched/src/lib/gssapi/krb5/gssapiP_krb5.h 2015-11-10 15:38:52.106323672 +0100 @@ -1393,6 +1393,11 @@ OM_uint32 KRB5_CALLCONV iakerb_gss_export_sec_context(OM_uint32 *minor_status, gss_ctx_id_t *context_handle, gss_buffer_t interprocess_token); + +OM_uint32 KRB5_CALLCONV +iakerb_gss_import_sec_context(OM_uint32 *minor_status, + const gss_buffer_t interprocess_token, + gss_ctx_id_t *context_handle); #endif /* LEAN_CLIENT */ OM_uint32 KRB5_CALLCONV diff -rupN krb5-1.12.1/src/lib/gssapi/krb5/iakerb.c krb5-1.12.1-patched/src/lib/gssapi/krb5/iakerb.c --- krb5-1.12.1/src/lib/gssapi/krb5/iakerb.c 2015-11-10 15:37:32.209657599 +0100 +++ krb5-1.12.1-patched/src/lib/gssapi/krb5/iakerb.c 2015-11-10 15:41:43.431752632 +0100 @@ -1061,7 +1061,7 @@ iakerb_gss_export_sec_context(OM_uint32 gss_buffer_t interprocess_token) { OM_uint32 maj; - iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle; + iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle; /* We don't currently support exporting partially established contexts. */ if (!ctx->established) @@ -1076,12 +1076,41 @@ iakerb_gss_export_sec_context(OM_uint32 return maj; } -/* - * Until we implement partial context exports, there are no SPNEGO exported - * context tokens, only tokens for the underlying krb5 context. So we do not - * need to implement an iakerb_gss_import_sec_context() yet; it would be - * unreachable except via a manually constructed token. - */ +OM_uint32 KRB5_CALLCONV +iakerb_gss_import_sec_context(OM_uint32 *minor_status, + gss_buffer_t interprocess_token, + gss_ctx_id_t *context_handle) +{ + OM_uint32 maj, tmpmin; + krb5_error_code code; + gss_ctx_id_t gssc; + krb5_gss_ctx_id_t kctx; + iakerb_ctx_id_t ctx; + + maj = krb5_gss_import_sec_context(minor_status, interprocess_token, &gssc); + if (maj != GSS_S_COMPLETE) + return maj; + kctx = (krb5_gss_ctx_id_t)gssc; + + if (!kctx->established) { + /* We don't currently support importing partially established + * contexts. */ + krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); + return GSS_S_FAILURE; + } + + code = iakerb_alloc_context(&ctx, kctx->initiate); + if (code != 0) { + krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER); + *minor_status = code; + return GSS_S_FAILURE; + } + + ctx->gssc = gssc; + ctx->established = 1; + *context_handle = (gss_ctx_id_t)ctx; + return GSS_S_COMPLETE; +} #endif /* LEAN_CLIENT */ ++++++ 0104-Verify-decoded-kadmin-C-strings-CVE-2015-8629.patch ++++++ >From df17a1224a3406f57477bcd372c61e04c0e5a5bb Mon Sep 17 00:00:00 2001 From: Greg Hudson <[email protected]> Date: Fri, 8 Jan 2016 12:45:25 -0500 Subject: [PATCH] Verify decoded kadmin C strings [CVE-2015-8629] In xdr_nullstring(), check that the decoded string is terminated with a zero byte and does not contain any internal zero bytes. CVE-2015-8629: In all versions of MIT krb5, an authenticated attacker can cause kadmind to read beyond the end of allocated memory by sending a string without a terminating zero byte. Information leakage may be possible for an attacker with permission to modify the database. CVSSv2 Vector: AV:N/AC:H/Au:S/C:P/I:N/A:N/E:POC/RL:OF/RC:C ticket: 8341 (new) target_version: 1.14-next target_version: 1.13-next tags: pullup diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c index 2bef858..ba67084 100644 --- a/src/lib/kadm5/kadm_rpc_xdr.c +++ b/src/lib/kadm5/kadm_rpc_xdr.c @@ -64,7 +64,14 @@ bool_t xdr_nullstring(XDR *xdrs, char **objp) return FALSE; } } - return (xdr_opaque(xdrs, *objp, size)); + if (!xdr_opaque(xdrs, *objp, size)) + return FALSE; + /* Check that the unmarshalled bytes are a C string. */ + if ((*objp)[size - 1] != '\0') + return FALSE; + if (memchr(*objp, '\0', size - 1) != NULL) + return FALSE; + return TRUE; case XDR_ENCODE: if (size != 0) -- 2.7.0 ++++++ 0105-Fix-leaks-in-kadmin-server-stubs-CVE-2015-8631.patch ++++++ >From 83ed75feba32e46f736fcce0d96a0445f29b96c2 Mon Sep 17 00:00:00 2001 From: Greg Hudson <[email protected]> Date: Fri, 8 Jan 2016 13:16:54 -0500 Subject: [PATCH] Fix leaks in kadmin server stubs [CVE-2015-8631] In each kadmind server stub, initialize the client_name and server_name variables, and release them in the cleanup handler. Many of the stubs will otherwise leak the client and server name if krb5_unparse_name() fails. Also make sure to free the prime_arg variables in rename_principal_2_svc(), or we can leak the first one if unparsing the second one fails. Discovered by Simo Sorce. CVE-2015-8631: In all versions of MIT krb5, an authenticated attacker can cause kadmind to leak memory by supplying a null principal name in a request which uses one. Repeating these requests will eventually cause kadmind to exhaust all available memory. CVSSv2 Vector: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C ticket: 8343 (new) target_version: 1.14-next target_version: 1.13-next tags: pullup diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c index 1879dc6..6ac797e 100644 --- a/src/kadmin/server/server_stubs.c +++ b/src/kadmin/server/server_stubs.c @@ -334,7 +334,8 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; restriction_t *rp; @@ -382,10 +383,10 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); free_server_handle(handle); return &ret; } @@ -395,7 +396,8 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; restriction_t *rp; @@ -444,10 +446,10 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); free_server_handle(handle); return &ret; } @@ -457,8 +459,8 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -501,10 +503,10 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp) } free(prime_arg); - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); free_server_handle(handle); return &ret; } @@ -514,8 +516,8 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; restriction_t *rp; @@ -559,9 +561,9 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -570,10 +572,9 @@ generic_ret * rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp) { static generic_ret ret; - char *prime_arg1, - *prime_arg2; - gss_buffer_desc client_name, - service_name; + char *prime_arg1 = NULL, *prime_arg2 = NULL; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; restriction_t *rp; @@ -655,11 +656,11 @@ rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } +exit_func: free(prime_arg1); free(prime_arg2); gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -669,8 +670,8 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp) { static gprinc_ret ret; char *prime_arg, *funcname; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -719,9 +720,9 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -731,8 +732,8 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp) { static gprincs_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -777,9 +778,9 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -789,8 +790,8 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -840,9 +841,9 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp) } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -852,8 +853,8 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -909,9 +910,9 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp) } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -921,8 +922,8 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -969,9 +970,9 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp) } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -981,8 +982,8 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1029,9 +1030,9 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp) } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1041,8 +1042,8 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1092,9 +1093,9 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp) } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1106,8 +1107,8 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp) krb5_keyblock *k; int nkeys; char *prime_arg, *funcname; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1164,9 +1165,9 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1178,8 +1179,8 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp) krb5_keyblock *k; int nkeys; char *prime_arg, *funcname; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1241,9 +1242,9 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1253,8 +1254,8 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1295,9 +1296,9 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp) if (errmsg != NULL) krb5_free_error_message(handle->context, errmsg); } +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1307,8 +1308,8 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1347,9 +1348,9 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp) if (errmsg != NULL) krb5_free_error_message(handle->context, errmsg); } +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1359,8 +1360,8 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1400,9 +1401,9 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp) if (errmsg != NULL) krb5_free_error_message(handle->context, errmsg); } +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1413,8 +1414,8 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp) static gpol_ret ret; kadm5_ret_t ret2; char *prime_arg, *funcname; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_principal_ent_rec caller_ent; kadm5_server_handle_t handle; @@ -1475,9 +1476,9 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp) log_unauth(funcname, prime_arg, &client_name, &service_name, rqstp); } +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; @@ -1488,8 +1489,8 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp) { static gpols_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1531,9 +1532,9 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp) if (errmsg != NULL) krb5_free_error_message(handle->context, errmsg); } +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1541,7 +1542,8 @@ exit_func: getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) { static getprivs_ret ret; - gss_buffer_desc client_name, service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1571,9 +1573,9 @@ getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) if (errmsg != NULL) krb5_free_error_message(handle->context, errmsg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1583,7 +1585,8 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg, *funcname; - gss_buffer_desc client_name, service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; @@ -1629,9 +1632,9 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1641,8 +1644,8 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp) { static gstrings_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1688,9 +1691,9 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1700,8 +1703,8 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp) { static generic_ret ret; char *prime_arg; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; OM_uint32 minor_stat; kadm5_server_handle_t handle; const char *errmsg = NULL; @@ -1744,9 +1747,9 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp) krb5_free_error_message(handle->context, errmsg); } free(prime_arg); +exit_func: gss_release_buffer(&minor_stat, &client_name); gss_release_buffer(&minor_stat, &service_name); -exit_func: free_server_handle(handle); return &ret; } @@ -1754,8 +1757,8 @@ exit_func: generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) { static generic_ret ret; - gss_buffer_desc client_name, - service_name; + gss_buffer_desc client_name = GSS_C_EMPTY_BUFFER; + gss_buffer_desc service_name = GSS_C_EMPTY_BUFFER; kadm5_server_handle_t handle; OM_uint32 minor_stat; const char *errmsg = NULL; @@ -1797,10 +1800,10 @@ generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp) rqstp->rq_cred.oa_flavor); if (errmsg != NULL) krb5_free_error_message(NULL, errmsg); - gss_release_buffer(&minor_stat, &client_name); - gss_release_buffer(&minor_stat, &service_name); exit_func: + gss_release_buffer(&minor_stat, &client_name); + gss_release_buffer(&minor_stat, &service_name); return(&ret); } -- 2.7.0 ++++++ 0106-Check-for-null-kadm5-policy-name-CVE-2015-8630.patch ++++++ >From b863de7fbf080b15e347a736fdda0a82d42f4f6b Mon Sep 17 00:00:00 2001 From: Greg Hudson <[email protected]> Date: Fri, 8 Jan 2016 12:52:28 -0500 Subject: [PATCH] Check for null kadm5 policy name [CVE-2015-8630] In kadm5_create_principal_3() and kadm5_modify_principal(), check for entry->policy being null when KADM5_POLICY is included in the mask. CVE-2015-8630: In MIT krb5 1.12 and later, an authenticated attacker with permission to modify a principal entry can cause kadmind to dereference a null pointer by supplying a null policy value but including KADM5_POLICY in the mask. CVSSv2 Vector: AV:N/AC:H/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C ticket: 8342 (new) target_version: 1.14-next target_version: 1.13-next tags: pullup diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index 5b95fa3..1d4365c 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -395,6 +395,8 @@ kadm5_create_principal_3(void *server_handle, /* * Argument sanity checking, and opening up the DB */ + if (entry == NULL) + return EINVAL; if(!(mask & KADM5_PRINCIPAL) || (mask & KADM5_MOD_NAME) || (mask & KADM5_MOD_TIME) || (mask & KADM5_LAST_PWD_CHANGE) || (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) || @@ -403,12 +405,12 @@ kadm5_create_principal_3(void *server_handle, return KADM5_BAD_MASK; if ((mask & KADM5_KEY_DATA) && entry->n_key_data != 0) return KADM5_BAD_MASK; + if((mask & KADM5_POLICY) && entry->policy == NULL) + return KADM5_BAD_MASK; if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR)) return KADM5_BAD_MASK; if((mask & ~ALL_PRINC_MASK)) return KADM5_BAD_MASK; - if (entry == NULL) - return EINVAL; /* * Check to see if the principal exists @@ -643,6 +645,8 @@ kadm5_modify_principal(void *server_handle, krb5_clear_error_message(handle->context); + if(entry == NULL) + return EINVAL; if((mask & KADM5_PRINCIPAL) || (mask & KADM5_LAST_PWD_CHANGE) || (mask & KADM5_MOD_TIME) || (mask & KADM5_MOD_NAME) || (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) || @@ -651,10 +655,10 @@ kadm5_modify_principal(void *server_handle, return KADM5_BAD_MASK; if((mask & ~ALL_PRINC_MASK)) return KADM5_BAD_MASK; + if((mask & KADM5_POLICY) && entry->policy == NULL) + return KADM5_BAD_MASK; if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR)) return KADM5_BAD_MASK; - if(entry == (kadm5_principal_ent_t) NULL) - return EINVAL; if (mask & KADM5_TL_DATA) { tl_data_orig = entry->tl_data; while (tl_data_orig) { -- 2.7.0 ++++++ baselibs.conf ++++++ krb5 obsoletes "heimdal-lib-<targettype>" provides "heimdal-lib-<targettype>" krb5-devel ++++++ bnc#897874-CVE-2014-5351.diff ++++++ diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index 5d358bd..d4e74cc 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -344,6 +344,20 @@ check_1_6_dummy(kadm5_principal_ent_t entry, long mask, *passptr = NULL; } +/* Return the number of keys with the newest kvno. Assumes that all key data + * with the newest kvno are at the front of the key data array. */ +static int +count_new_keys(int n_key_data, krb5_key_data *key_data) +{ + int n; + + for (n = 1; n < n_key_data; n++) { + if (key_data[n - 1].key_data_kvno != key_data[n].key_data_kvno) + return n; + } + return n_key_data; +} + kadm5_ret_t kadm5_create_principal(void *server_handle, kadm5_principal_ent_t entry, long mask, @@ -1593,7 +1607,7 @@ kadm5_randkey_principal_3(void *server_handle, osa_princ_ent_rec adb; krb5_int32 now; kadm5_policy_ent_rec pol; - int ret, last_pwd; + int ret, last_pwd, n_new_keys; krb5_boolean have_pol = FALSE; kadm5_server_handle_t handle = server_handle; krb5_keyblock *act_mkey; @@ -1686,8 +1700,9 @@ kadm5_randkey_principal_3(void *server_handle, kdb->fail_auth_count = 0; if (keyblocks) { - ret = decrypt_key_data(handle->context, - kdb->n_key_data, kdb->key_data, + /* Return only the new keys added by krb5_dbe_crk. */ + n_new_keys = count_new_keys(kdb->n_key_data, kdb->key_data); + ret = decrypt_key_data(handle->context, n_new_keys, kdb->key_data, keyblocks, n_keys); if (ret) goto done; -- 1.8.5.2 ++++++ bnc#912002.diff ++++++ 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 <k5-platform.h> +#include <k5-int.h> #include <gssrpc/rpc.h> #include <gssapi/gssapi_krb5.h> /* for gss_nt_krb5_name */ #include <syslog.h> @@ -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 7e807cc..a0e8625 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -206,6 +206,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 6456b23..77b7fff 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 7665cba..f1c74dd 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 a129670..b53e348 100644 --- a/src/lib/gssapi/krb5/k5sealiov.c +++ b/src/lib/gssapi/krb5/k5sealiov.c @@ -281,7 +281,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 0573958..673c883 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 f34d802..8b67042 100644 --- a/src/lib/gssapi/krb5/k5unsealiov.c +++ b/src/lib/gssapi/krb5/k5unsealiov.c @@ -625,7 +625,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/prf.c b/src/lib/gssapi/krb5/prf.c index e19291f..e897074 100644 --- a/src/lib/gssapi/krb5/prf.c +++ b/src/lib/gssapi/krb5/prf.c @@ -58,6 +58,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 09a3534..b81c4a3 100644 --- a/src/lib/rpc/svc_auth_gss.c +++ b/src/lib/rpc/svc_auth_gss.c @@ -65,16 +65,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; @@ -239,16 +229,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; @@ -520,8 +502,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; @@ -531,7 +511,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); --- krb5-1.12.1/src/lib/gssapi/krb5/lucid_context.c.orig 2015-01-07 11:30:04.873975606 +0100 +++ krb5-1.12.1/src/lib/gssapi/krb5/lucid_context.c 2015-01-07 12:59:59.957371445 +0100 @@ -75,6 +75,11 @@ *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, ++++++ krb5-1.10-kpasswd_tcp.patch ++++++ 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. Index: krb5-1.10.2/src/lib/krb5/os/changepw.c =================================================================== --- krb5-1.10.2.orig/src/lib/krb5/os/changepw.c +++ krb5-1.10.2/src/lib/krb5/os/changepw.c @@ -274,10 +274,22 @@ change_set_password(krb5_context context &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 (!use_tcp) { + 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); + use_tcp = 1; + continue; + default: + break; + } + } break; } ++++++ krb5-1.10-ksu-access.patch ++++++ The idea is to not complain about problems in the default ticket file if we couldn't read it, because the client would be able to tell if it's there or not, and we're implicitly letting the client tell us where it is. Still needs work, I think. Index: krb5-1.11.1/src/clients/ksu/ccache.c =================================================================== --- krb5-1.11.1.orig/src/clients/ksu/ccache.c +++ krb5-1.11.1/src/clients/ksu/ccache.c @@ -77,7 +77,7 @@ krb5_error_code krb5_ccache_copy (contex 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 ( ! access(cc_def_name, R_OK) && ! stat(cc_def_name, &st_temp)){ if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){ return retval; } Index: krb5-1.11.1/src/clients/ksu/heuristic.c =================================================================== --- krb5-1.11.1.orig/src/clients/ksu/heuristic.c +++ krb5-1.11.1/src/clients/ksu/heuristic.c @@ -409,7 +409,7 @@ krb5_error_code find_either_ticket (cont cc_source_name = krb5_cc_get_name(context, cc); - if ( ! stat(cc_source_name, &st_temp)){ + if ( ! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, &st_temp)){ retval = find_ticket(context, cc, client, end_server, &temp_found); if (retval) @@ -569,7 +569,7 @@ krb5_error_code get_best_princ_for_targe cc_source_name = krb5_cc_get_name(context, cc_source); - if (! stat(cc_source_name, &st_temp)) { + if (! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, &st_temp)) { retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ); if (retval) return retval; Index: krb5-1.11.1/src/clients/ksu/main.c =================================================================== --- krb5-1.11.1.orig/src/clients/ksu/main.c +++ krb5-1.11.1/src/clients/ksu/main.c @@ -271,7 +271,7 @@ 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( access( cc_source_tag_tmp, F_OK | R_OK) || stat( cc_source_tag_tmp, &st_temp)){ com_err(prog_name, errno, _("while looking for credentials file %s"), cc_source_tag_tmp); ++++++ krb5-1.12-api.patch ++++++ Reference docs don't define what happens if you call krb5_realm_compare() with malformed krb5_principal structures. Define a behavior which keeps it from crashing if applications don't check ahead of time. --- krb5/src/lib/krb5/krb/princ_comp.c +++ krb5/src/lib/krb5/krb/princ_comp.c @@ -41,6 +41,10 @@ realm_compare_flags(krb5_context context const krb5_data *realm1 = &princ1->realm; const krb5_data *realm2 = &princ2->realm; + if (princ1 == NULL || princ2 == NULL) + return FALSE; + if (realm1 == NULL || realm2 == NULL) + return FALSE; if (realm1->length != realm2->length) return FALSE; if (realm1->length == 0) @@ -92,6 +98,9 @@ krb5_principal_compare_flags(krb5_contex krb5_principal upn2 = NULL; krb5_boolean ret = FALSE; + if (princ1 == NULL || princ2 == NULL) + return FALSE; + if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) { /* Treat UPNs as if they were real principals */ if (princ1->type == KRB5_NT_ENTERPRISE_PRINCIPAL) { ++++++ krb5-1.12-buildconf.patch ++++++ Build binaries in this package as RELRO PIEs, libraries as partial RELRO, and install shared libraries with the execute bit set on them. Prune out the -L/usr/lib* and PIE flags where they might leak out and affect apps which just want to link with the libraries. FIXME: needs to check and not just assume that the compiler supports using these flags. --- krb5/src/config/shlib.conf +++ krb5/src/config/shlib.conf @@ -419,7 +419,7 @@ mips-*-netbsd*) SHLIBEXT=.so # Linux ld doesn't default to stuffing the SONAME field... # Use objdump -x to examine the fields of the library - LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT),--no-undefined' + LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT),--no-undefined -Wl,-z,relro' # LDCOMBINE_TAIL='-Wl,--version-script binutils.versions && $(PERL) -w $(top_srcdir)/util/export-check.pl $(SHLIB_EXPORT_FILE) $@' SHLIB_EXPORT_FILE_DEP=binutils.versions @@ -430,7 +430,8 @@ SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)' - CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)' + CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)' + INSTALL_SHLIB='${INSTALL} -m755' CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)' CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)' CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)' --- krb5/src/build-tools/krb5-config.in +++ krb5/src/build-tools/krb5-config.in @@ -189,6 +189,13 @@ if test -n "$do_libs"; then -e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \ -e 's#\$(CFLAGS)##'` + if test `dirname $libdir` = /usr ; then + lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"` + fi + lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"` + lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"` + lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"` + if test $library = 'kdb'; then lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB" library=krb5 --- krb5/src/config/pre.in +++ krb5/src/config/pre.in @@ -188,7 +188,7 @@ INSTALL_SCRIPT=@INSTALL_PROGRAM@ INSTALL_DATA=@INSTALL_DATA@ INSTALL_SHLIB=@INSTALL_SHLIB@ -INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root +INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 ## This is needed because autoconf will sometimes define @exec_prefix@ to be ## ${prefix}. prefix=@prefix@ ++++++ krb5-1.12-doxygen.patch ++++++ commit b7a4d695263f1a5b7fe72b1eadce4acdc3f0490b From: Ben Kaduk <[email protected]> Date: Thu Aug 28 17:54:39 2014 -0400 Subject: Map .hin files to the C language for doxygen Upstream: Committed References: https://github.com/krb5/krb5/commit/b7a4d695263f1a5b7fe72b1eadce4acdc3f0490b https://github.com/krb5/krb5/pull/198 Doxygen 1.8.8 is unhappy with the generated Doxyfile, and does not handle krb5.hin in the expected fashion (as a C header). Work around this issue by explicitly specifying that files with the .hin extension are to be treated as C language files. Fixes the following build failure with doxygen 1.8.8: [ 326s] cp rst_apiref/*.rst rst_composite/appdev/refs/api [ 326s] cp: cannot stat 'rst_apiref/*.rst': No such file or directory [ 326s] Makefile:692: recipe for target 'composite' failed [ 326s] make: *** [composite] Error 1 diff --git a/src/doc/Doxyfile.in b/src/doc/Doxyfile.in index 2082b6d..c225864 100644 --- a/src/doc/Doxyfile.in +++ b/src/doc/Doxyfile.in @@ -4,6 +4,7 @@ JAVADOC_AUTOBRIEF = YES OPTIMIZE_OUTPUT_FOR_C = YES WARN_IF_UNDOCUMENTED = NO SHOW_FILES = NO +EXTENSION_MAPPING = hin=C INPUT = @SRC@/include/krb5/krb5.hin @DOC@/doxy_examples EXAMPLE_PATH = @DOC@/doxy_examples GENERATE_HTML = NO lines 1-28/28 (END) ++++++ krb5-1.12-ksu-path.patch ++++++ Set the default PATH to the one set by login. --- krb5/src/clients/ksu/Makefile.in +++ krb5/src/clients/ksu/Makefile.in @@ -1,6 +1,6 @@ mydir=clients$(S)ksu BUILDTOP=$(REL)..$(S).. -DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"' +DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"' KSU_LIBS=@KSU_LIBS@ PAM_LIBS=@PAM_LIBS@ ++++++ krb5-1.12-pam.patch ++++++ ++++ 752 lines (skipped) ++++++ krb5-1.12-selinux-label.patch ++++++ ++++ 979 lines (skipped) ++++++ krb5-1.12.2-CVE-2014-5353.patch ++++++ >From d1f707024f1d0af6e54a18885322d70fa15ec4d3 Mon Sep 17 00:00:00 2001 From: Greg Hudson <[email protected]> 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 [[email protected]: 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); ++++++ krb5-1.12.2-CVE-2014-5354.patch ++++++ >From 04038bf3633c4b909b5ded3072dc88c8c419bf16 Mon Sep 17 00:00:00 2001 From: Ben Kaduk <[email protected]> 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)); ++++++ krb5-1.13-work-around-replay-cache-creation-race.patch ++++++ >From 99e08376c14240e2141c6fa9289fafab8245c754 Mon Sep 17 00:00:00 2001 From: Greg Hudson <[email protected]> Date: Wed, 17 Sep 2014 10:45:28 -0400 Subject: [PATCH] Work around replay cache creation race If two processes try to initialize the same replay cache at the same time, krb5_rc_io_creat can race between unlink and open, leading to a KRB5_RC_IO_PERM error. When this happens, make the losing process retry so that it can continue. This does not solve the replay cache creation race, nor is that the only replay cache race issue. It simply prevents the race from causing a spurious failure. (cherry picked from commit c61e8c0c6ad5fda8d23dd896c4aed0ac5b470020) ticket: 3498 version_fixed: 1.13 status: resolved --- src/lib/krb5/rcache/rc_io.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lib/krb5/rcache/rc_io.c b/src/lib/krb5/rcache/rc_io.c index 7e3b7e9..b9859fe 100644 --- a/src/lib/krb5/rcache/rc_io.c +++ b/src/lib/krb5/rcache/rc_io.c @@ -158,7 +158,7 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn) { krb5_int16 rc_vno = htons(KRB5_RC_VNO); krb5_error_code retval = 0; - int do_not_unlink = 0; + int flags, do_not_unlink = 0; char *dir; size_t dirlen; @@ -166,9 +166,13 @@ krb5_rc_io_creat(krb5_context context, krb5_rc_iostuff *d, char **fn) if (fn && *fn) { if (asprintf(&d->fn, "%s%s%s", dir, PATH_SEPARATOR, *fn) < 0) return KRB5_RC_IO_MALLOC; - unlink(d->fn); - d->fd = THREEPARAMOPEN(d->fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | - O_BINARY, 0600); + d->fd = -1; + do { + if (unlink(d->fn) == -1 && errno != ENOENT) + break; + flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL | O_BINARY; + d->fd = THREEPARAMOPEN(d->fn, flags, 0600); + } while (d->fd == -1 && errno == EEXIST); } else { retval = krb5_rc_io_mkstemp(context, d, dir); if (retval) -- 1.8.4.5 ++++++ krb5-1.6.3-gssapi_improve_errormessages.dif ++++++ Index: krb5-1.10.2/src/lib/gssapi/generic/disp_com_err_status.c =================================================================== --- krb5-1.10.2.orig/src/lib/gssapi/generic/disp_com_err_status.c +++ krb5-1.10.2/src/lib/gssapi/generic/disp_com_err_status.c @@ -52,7 +52,7 @@ g_display_com_err_status(OM_uint32 *mino status_string->value = NULL; if (! g_make_string_buffer(((status_value == 0)?no_error: - error_message(status_value)), + error_message((long)status_value)), status_string)) { *minor_status = ENOMEM; return(GSS_S_FAILURE); ++++++ krb5-1.6.3-ktutil-manpage.dif ++++++ --- src/man/ktutil.man | 12 ++++++++++++ 1 file changed, 12 insertions(+) Index: krb5-1.12.2/src/man/ktutil.man =================================================================== --- krb5-1.12.2.orig/src/man/ktutil.man 2014-08-30 23:06:53.000000000 +0100 +++ krb5-1.12.2/src/man/ktutil.man 2014-08-30 23:07:00.000000000 +0100 @@ -162,6 +162,18 @@ ktutil: .UNINDENT .UNINDENT .UNINDENT +.SH REMARKS +Changes to the keytab are appended to the keytab file (i.e., the keytab file +is never overwritten). To directly modify a keytab, save the changes to a +temporary file and then overwrite the keytab file of interest. +.TP +.nf +Example: +ktutil> rkt /etc/krb5.keytab +(modifications to keytab) +ktutil> wkt /tmp/krb5.newtab +ktutil> q +# mv /tmp/krb5.newtab /etc/krb5.keytab .SH SEE ALSO .sp \fIkadmin(1)\fP, \fIkdb5_util(8)\fP ++++++ krb5-1.7-doublelog.patch ++++++ Don't double-log (actually, don't process /etc/krb5.conf twice) just because we built with --sysconfdir=/etc. RT#3277 --- src/include/Makefile.in | 2 ++ 1 file changed, 2 insertions(+) Index: krb5-1.12.2/src/include/Makefile.in =================================================================== --- krb5-1.12.2.orig/src/include/Makefile.in 2014-08-30 23:08:41.000000000 +0100 +++ krb5-1.12.2/src/include/Makefile.in 2014-08-30 23:09:04.000000000 +0100 @@ -68,6 +68,8 @@ PROCESS_REPLACE = -e "s+@KRB5RCTMPDIR+$( -e "s+@GSSMODULEDIR+$(GSS_MODULE_DIR)+" \ -e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \ -e 's+@SYSCONFDIR+$(SYSCONFDIR)+' \ + -e 's+:/etc/krb5.conf:/etc/krb5.conf"+:/etc/krb5.conf"+' \ + -e 's+"/etc/krb5.conf:/etc/krb5.conf"+"/etc/krb5.conf"+' \ -e 's+@DYNOBJEXT+$(DYNOBJEXT)+' \ -e 's+@SYSCONFCONF+$(SYSCONFCONF)+' ++++++ krb5-1.9-debuginfo.patch ++++++ We want to keep these y.tab.c files around because the debuginfo points to them. It would be more elegant at the end to use symbolic links, but that could mess up people working in the tree on other things. Index: src/kadmin/cli/Makefile.in =================================================================== --- src/kadmin/cli/Makefile.in.orig +++ src/kadmin/cli/Makefile.in @@ -43,3 +43,8 @@ clean-unix:: # CC_LINK is not meant for compilation and this use may break in the future. datetest: getdate.c $(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c + +%.c: %.y + $(RM) y.tab.c $@ + $(YACC.y) $< + $(CP) y.tab.c $@ Index: src/plugins/kdb/ldap/ldap_util/Makefile.in =================================================================== --- src/plugins/kdb/ldap/ldap_util/Makefile.in.orig +++ src/plugins/kdb/ldap/ldap_util/Makefile.in @@ -22,7 +22,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KR getdate.c: $(GETDATE) $(RM) getdate.c y.tab.c $(YACC) $(GETDATE) - $(MV) y.tab.c getdate.c + $(CP) y.tab.c getdate.c install:: $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG) ++++++ krb5-1.9-kprop-mktemp.patch ++++++ Use an in-memory ccache to silence a compiler warning, for RT#6414. Index: krb5-1.11/src/slave/kprop.c =================================================================== --- krb5-1.11.orig/src/slave/kprop.c +++ krb5-1.11/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); ++++++ krb5-1.9-manpaths.dif ++++++ Change the absolute paths included in the man pages so that the correct values can be dropped in by config.status. After applying this patch, these files should be renamed to their ".in" counterparts, and then the configure scripts should be rebuilt. Originally RT#6525 Index: krb5-1.11/src/man/kpropd.man =================================================================== --- krb5-1.11.orig/src/man/kpropd.man +++ krb5-1.11/src/man/kpropd.man @@ -63,7 +63,7 @@ the \fB/etc/inetd.conf\fP file which loo .sp .nf .ft C -kprop stream tcp nowait root /usr/local/sbin/kpropd kpropd +kprop stream tcp nowait root @SBINDIR@/kpropd kpropd .ft P .fi .UNINDENT ++++++ krb5-kvno-230379.patch ++++++ >From patch attached to http://krbdev.mit.edu/rt/Ticket/Display.html?id=3349, at http://krbdev.mit.edu/rt/Ticket/Attachment/23851/13214/kvno.diff, adjusted as needed to apply to 1.10. FIXME: I'd like to better handle cases where we have a new key with the right version stored later in the keytab file. Currently, we're setting up to overlook that possibility. Note that this only affects the path taken when krb5_rd_rep() is passed a server principal name, as without a server principal name it already tries all of the keys it finds in the keytab, regardless of version numbers. Index: krb5-1.11.1/src/kadmin/ktutil/ktutil.c =================================================================== --- krb5-1.11.1.orig/src/kadmin/ktutil/ktutil.c +++ krb5-1.11.1/src/kadmin/ktutil/ktutil.c @@ -155,7 +155,7 @@ void ktutil_add_entry(argc, argv) char *princ = NULL; char *enctype = NULL; krb5_kvno kvno = 0; - int use_pass = 0, use_key = 0, i; + int use_pass = 0, use_key = 0, use_kvno = 0, i; for (i = 1; i < argc; i++) { if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) { @@ -164,6 +164,7 @@ void ktutil_add_entry(argc, argv) } if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) { kvno = (krb5_kvno) atoi(argv[++i]); + use_kvno++; continue; } if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) { @@ -180,7 +181,7 @@ void ktutil_add_entry(argc, argv) } } - if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) { + if (argc != 8 || !(princ && use_kvno && enctype) || (use_pass+use_key != 1)) { fprintf(stderr, _("usage: %s (-key | -password) -p principal " "-k kvno -e enctype\n"), argv[0]); return; Index: krb5-1.11.1/src/lib/krb5/keytab/kt_file.c =================================================================== --- krb5-1.11.1.orig/src/lib/krb5/keytab/kt_file.c +++ krb5-1.11.1/src/lib/krb5/keytab/kt_file.c @@ -349,7 +349,7 @@ krb5_ktfile_get_entry(krb5_context conte higher than that. Short-term workaround: only compare the low 8 bits. */ - if (new_entry.vno == (kvno & 0xff)) { + if (new_entry.vno == (kvno & 0xff) || new_entry.vno == IGNORE_VNO) { krb5_kt_free_entry(context, &cur_entry); cur_entry = new_entry; break; ++++++ krb5-rpmlintrc ++++++ addFilter("devel-file-in-non-devel-package .*libgssapi_krb5.so") addFilter("hidden-file-or-dir .*/usr/share/man/man5/.k5login.5.gz") addFilter("files-duplicate .*css") addFilter("files-duplicate .*img.*png") addFilter("devel-file-in-non-devel-package .*libkdb_ldap.so") addFilter("shlib-policy-missing-suffix") ++++++ pre_checkin.sh ++++++ #!/bin/sh sed -e 's/Name:.*/Name: krb5-mini/g;' \ -e 's/spec file for package.*/&-mini/' \ -e 's/%define.*build_mini.*/%define build_mini 1/g' krb5.spec > krb5-mini.spec cp krb5.changes krb5-mini.changes
