diff --git a/SOURCES/Prefer-TCP-to-UDP-for-password-changes.patch b/SOURCES/Prefer-TCP-to-UDP-for-password-changes.patch new file mode 100644 index 0000000..9efa19f --- /dev/null +++ b/SOURCES/Prefer-TCP-to-UDP-for-password-changes.patch @@ -0,0 +1,169 @@ +From c00a81874675b4c9c1c488863fc2ef780db1834d Mon Sep 17 00:00:00 2001 +From: Robbie Harwood +Date: Mon, 8 Oct 2018 16:02:12 -0400 +Subject: [PATCH] Prefer TCP to UDP for password changes + +When password changes are performed over UDP, spotty networks may +cause the client to retransmit. This leads to replay errors if the +kpasswd server receives both requests, which hide the actual request +status and make it appear that the password has not been changed, when +it may in fact have been. Use TCP instead with UDP fallback to avoid +this issue. + +ticket: 7905 +(cherry picked from commit d7b3018d338fc9c989c3fa17505870f23c3759a8) +(cherry picked from commit 8afeaa2eecbeae486320947892ace490870fefe8) +--- + src/lib/krb5/os/changepw.c | 110 ++++++++++++++----------------------- + 1 file changed, 42 insertions(+), 68 deletions(-) + +diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c +index e4db57084..9f968da7f 100644 +--- a/src/lib/krb5/os/changepw.c ++++ b/src/lib/krb5/os/changepw.c +@@ -59,13 +59,12 @@ struct sendto_callback_context { + + static krb5_error_code + locate_kpasswd(krb5_context context, const krb5_data *realm, +- struct serverlist *serverlist, krb5_boolean no_udp) ++ struct serverlist *serverlist) + { + krb5_error_code code; + + code = k5_locate_server(context, realm, serverlist, locate_service_kpasswd, +- no_udp); +- ++ FALSE); + if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) { + code = k5_locate_server(context, realm, serverlist, + locate_service_kadmin, TRUE); +@@ -76,7 +75,7 @@ locate_kpasswd(krb5_context context, const krb5_data *realm, + for (i = 0; i < serverlist->nservers; i++) { + struct server_entry *s = &serverlist->servers[i]; + +- if (!no_udp && s->transport == TCP) ++ if (s->transport == TCP) + s->transport = TCP_OR_UDP; + if (s->hostname != NULL) + s->port = DEFAULT_KPASSWD_PORT; +@@ -214,7 +213,6 @@ change_set_password(krb5_context context, + krb5_data *result_string) + { + krb5_data chpw_rep; +- krb5_boolean no_udp = FALSE; + GETSOCKNAME_ARG3_TYPE addrlen; + krb5_error_code code = 0; + char *code_string; +@@ -246,73 +244,49 @@ change_set_password(krb5_context context, + callback_ctx.remote_seq_num = callback_ctx.auth_context->remote_seq_number; + callback_ctx.local_seq_num = callback_ctx.auth_context->local_seq_number; + +- do { +- k5_transport_strategy strategy = no_udp ? NO_UDP : UDP_FIRST; ++ code = locate_kpasswd(callback_ctx.context, &creds->server->realm, &sl); ++ if (code) ++ goto cleanup; + +- code = locate_kpasswd(callback_ctx.context, &creds->server->realm, &sl, +- no_udp); ++ addrlen = sizeof(remote_addr); ++ ++ callback_info.data = &callback_ctx; ++ callback_info.pfn_callback = kpasswd_sendto_msg_callback; ++ callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup; ++ krb5_free_data_contents(callback_ctx.context, &chpw_rep); ++ ++ code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, ++ &sl, UDP_LAST, &callback_info, &chpw_rep, ++ ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); ++ if (code) ++ goto cleanup; ++ ++ code = krb5int_rd_chpw_rep(callback_ctx.context, ++ callback_ctx.auth_context, ++ &chpw_rep, &local_result_code, ++ result_string); ++ ++ if (code) ++ goto cleanup; ++ ++ if (result_code) ++ *result_code = local_result_code; ++ ++ if (result_code_string) { ++ code = krb5_chpw_result_code_string(callback_ctx.context, ++ local_result_code, ++ &code_string); + if (code) +- break; ++ goto cleanup; + +- addrlen = sizeof(remote_addr); +- +- callback_info.data = &callback_ctx; +- callback_info.pfn_callback = kpasswd_sendto_msg_callback; +- callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup; +- krb5_free_data_contents(callback_ctx.context, &chpw_rep); +- +- code = k5_sendto(callback_ctx.context, NULL, &creds->server->realm, +- &sl, strategy, &callback_info, &chpw_rep, +- ss2sa(&remote_addr), &addrlen, NULL, NULL, NULL); +- if (code) { +- /* +- * Here we may want to switch to TCP on some errors. +- * right? +- */ +- break; ++ result_code_string->length = strlen(code_string); ++ result_code_string->data = malloc(result_code_string->length); ++ if (result_code_string->data == NULL) { ++ code = ENOMEM; ++ goto cleanup; + } +- +- code = krb5int_rd_chpw_rep(callback_ctx.context, +- callback_ctx.auth_context, +- &chpw_rep, &local_result_code, +- result_string); +- +- if (code) { +- if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !no_udp) { +- k5_free_serverlist(&sl); +- no_udp = 1; +- continue; +- } +- +- break; +- } +- +- if (result_code) +- *result_code = local_result_code; +- +- if (result_code_string) { +- code = krb5_chpw_result_code_string(callback_ctx.context, +- local_result_code, +- &code_string); +- if (code) +- goto cleanup; +- +- result_code_string->length = strlen(code_string); +- result_code_string->data = malloc(result_code_string->length); +- if (result_code_string->data == NULL) { +- code = ENOMEM; +- goto cleanup; +- } +- strncpy(result_code_string->data, code_string, result_code_string->length); +- } +- +- if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !no_udp) { +- k5_free_serverlist(&sl); +- no_udp = 1; +- } else { +- break; +- } +- } while (TRUE); ++ strncpy(result_code_string->data, code_string, result_code_string->length); ++ } + + cleanup: + if (callback_ctx.auth_context != NULL) diff --git a/SOURCES/Remove-incorrect-KDC-assertion.patch b/SOURCES/Remove-incorrect-KDC-assertion.patch new file mode 100644 index 0000000..ae39781 --- /dev/null +++ b/SOURCES/Remove-incorrect-KDC-assertion.patch @@ -0,0 +1,61 @@ +From cf528eaa89db56d5825f2b04e8d46b50bd52bd08 Mon Sep 17 00:00:00 2001 +From: Isaac Boukris +Date: Sat, 15 Dec 2018 11:56:36 +0200 +Subject: [PATCH] Remove incorrect KDC assertion + +The assertion in return_enc_padata() is reachable because +kdc_make_s4u2self_rep() may have previously added encrypted padata. +It is no longer necessary because the code uses add_pa_data_element() +instead of allocating a new list. + +CVE-2018-20217: + +In MIT krb5 1.8 or later, an authenticated user who can obtain a TGT +using an older encryption type (DES, DES3, or RC4) can cause an +assertion failure in the KDC by sending an S4U2Self request. + +[ghudson@mit.edu: rewrote commit message with CVE description] + +(cherry picked from commit 94e5eda5bb94d1d44733a49c3d9b6d1e42c74def) + +ticket: 8767 +version_fixed: 1.16.3 + +(cherry picked from commit 56870f9456da78d77a667dfc03a6d90f948dc3a5) +(cherry picked from commit 2a96564f6fd53f2e1e8424d865c02349bfe5b818) +(cherry picked from commit a2749226a5930d15a1e31a4a4f3d9ecfb4cb250e) +--- + src/kdc/kdc_preauth.c | 1 - + src/tests/gssapi/t_s4u.py | 7 +++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c +index 81d0b8cff..787a09684 100644 +--- a/src/kdc/kdc_preauth.c ++++ b/src/kdc/kdc_preauth.c +@@ -1640,7 +1640,6 @@ return_enc_padata(krb5_context context, krb5_data *req_pkt, + krb5_error_code code = 0; + /* This should be initialized and only used for Win2K compat and other + * specific standardized uses such as FAST negotiation. */ +- assert(reply_encpart->enc_padata == NULL); + if (is_referral) { + code = return_referral_enc_padata(context, reply_encpart, server); + if (code) +diff --git a/src/tests/gssapi/t_s4u.py b/src/tests/gssapi/t_s4u.py +index 7366e3915..9f8591f6c 100755 +--- a/src/tests/gssapi/t_s4u.py ++++ b/src/tests/gssapi/t_s4u.py +@@ -144,6 +144,13 @@ if 'auth1: user@' not in out or 'auth2: user@' not in out: + + realm.stop() + ++for realm in multipass_realms(create_host=False, get_creds=False): ++ service1 = 'service/1@%s' % realm.realm ++ realm.addprinc(service1) ++ realm.extract_keytab(service1, realm.keytab) ++ realm.kinit(service1, None, ['-k']) ++ realm.run(['./t_s4u', 'p:user', '-']) ++ + # Exercise cross-realm S4U2Self. The query in the foreign realm will + # fail, but we can check that the right server principal was used. + r1, r2 = cross_realms(2, create_user=False) diff --git a/SPECS/krb5.spec b/SPECS/krb5.spec index bc5177a..9378cf8 100644 --- a/SPECS/krb5.spec +++ b/SPECS/krb5.spec @@ -12,7 +12,7 @@ Summary: The Kerberos network authentication system Name: krb5 Version: 1.15.1 -Release: 37%{?dist} +Release: 37%{?dist}.2 # - Maybe we should explode from the now-available-to-everybody tarball instead? # http://web.mit.edu/kerberos/dist/krb5/1.13/krb5-1.13.2-signed.tar @@ -127,6 +127,8 @@ Patch213: Don-t-include-all-MEMORY-ccaches-in-collection.patch Patch214: Add-libkrb5support-hex-functions-and-tests.patch Patch215: Add-a-hash-table-implementation-to-libkrb5support.patch Patch216: Use-a-hash-table-for-MEMORY-ccache-resolution.patch +Patch217: Remove-incorrect-KDC-assertion.patch +Patch218: Prefer-TCP-to-UDP-for-password-changes.patch License: MIT URL: http://web.mit.edu/kerberos/www/ @@ -387,6 +389,8 @@ ONLY by kerberos itself. Do not depend on this package. %patch214 -p1 -b .Add-libkrb5support-hex-functions-and-tests %patch215 -p1 -b .Add-a-hash-table-implementation-to-libkrb5support %patch216 -p1 -b .Use-a-hash-table-for-MEMORY-ccache-resolution +%patch217 -p1 -b .Remove-incorrect-KDC-assertion +%patch218 -p1 -b .Prefer-TCP-to-UDP-for-password-changes ln NOTICE LICENSE @@ -892,17 +896,25 @@ exit 0 %{_libdir}/libkadm5srv_mit.so.* %changelog +* Thu Jul 25 2019 Robbie Harwood - 1.15.1-37.el_7_7.2 +- Prefer TCP to UDP for password changes +- Resolves: #1732743 + +* Thu Jul 25 2019 Robbie Harwood - 1.15.1-37.el7_7.1 +- Remove incorrect KDC assertion +- Resolves: #1732339 + * Tue Dec 18 2018 Robbie Harwood - 1.15.1-37 - Bring back builtin crypto (openssl broke too many FIPS setups) -- Resolves: #1657890 +- Resolves: #1645711 * Mon Dec 17 2018 Robbie Harwood - 1.15.1-36 - Clean up MEMORY ccache behavior to match upstream more closely -- Resolves: #1657890 +- Resolves: #1605756 * Tue Dec 11 2018 Robbie Harwood - 1.15.1-35 - Fix bugs with concurrent use of MEMORY ccaches -- Resolves: #1657890 +- Resolves: #1605756 * Wed Aug 01 2018 Robbie Harwood - 1.15.1-34 - In FIPS mode, add plaintext fallback for RC4 usages and taint