diff -Nru pykerberos-1.1+svn10616/debian/changelog pykerberos-1.1+svn10616/debian/changelog --- pykerberos-1.1+svn10616/debian/changelog 2014-01-13 18:11:51.000000000 +0000 +++ pykerberos-1.1+svn10616/debian/changelog 2017-10-13 19:27:41.000000000 +0000 @@ -1,3 +1,14 @@ +pykerberos (1.1+svn10616-2ubuntu0.1) trusty-security; urgency=medium + + * SECURITY UPDATE: The checkPassword function does not authenticate the + KDC it attempts to communicate with (LP: #1716429) + - Add-KDC-authenticity-verification-support-CVE-2015-3206.patch + retrieved from xenial version (1.1.5-2build1). + - CVE-2015-3206 + - debian/NEWS: add explanation of issue and default chosen + + -- Mathieu Lafon Thu, 05 Oct 2017 09:32:55 +0200 + pykerberos (1.1+svn10616-2) unstable; urgency=low [ Dr. Torge Szczepanek ] diff -Nru pykerberos-1.1+svn10616/debian/control pykerberos-1.1+svn10616/debian/control --- pykerberos-1.1+svn10616/debian/control 2014-01-08 16:44:36.000000000 +0000 +++ pykerberos-1.1+svn10616/debian/control 2017-10-13 19:03:51.000000000 +0000 @@ -1,7 +1,8 @@ Source: pykerberos Section: python Priority: optional -Maintainer: Calendarserver Maintainers +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Calendarserver Maintainers Uploaders: Dr. Torge Szczepanek , Guido Günther Build-Depends: debhelper (>= 9), libkrb5-dev, python-all-dev, python (>= 2.6.6-3~) Standards-Version: 3.9.5 diff -Nru pykerberos-1.1+svn10616/debian/NEWS pykerberos-1.1+svn10616/debian/NEWS --- pykerberos-1.1+svn10616/debian/NEWS 1970-01-01 00:00:00.000000000 +0000 +++ pykerberos-1.1+svn10616/debian/NEWS 2017-10-13 19:27:02.000000000 +0000 @@ -0,0 +1,42 @@ +pykerberos (1.1+svn10616-2ubuntu0.1) trusty-security; urgency=medium + + The python-kerberos checkPassword() method has been badly insecure in + previous releases. It used to do (and still does by default) a kinit + (AS-REQ) to ask a KDC for a TGT for the given user principal, and + interprets the success or failure of that as indicating whether the + password is correct. It does not, however, verify that it actually spoke + to a trusted KDC: an attacker may simply reply instead with an AS-REP + which matches the password he just gave you. + . + Imagine you were verifying a password using LDAP authentication rather + than Kerberos: you would, of course, use TLS in conjunction with LDAP to + make sure you were talking to a real, trusted LDAP server. The same + requirement applies here. kinit is not a password-verification service. + . + The usual way of doing this is to take the TGT you've obtained with the + user's password, and then obtain a ticket for a principal for which the + verifier has keys (e.g. a web server processing a username/password form + login might get a ticket for its own HTTP/host@REALM principal), which + it can then verify. Note that this requires that the verifier has its + own Kerberos identity, which is mandated by the symmetric nature of + Kerberos (whereas in the LDAP case, the use of public-key cryptography + allows anonymous verification). + . + The fact of pykerberos being susceptible to KDC spoofing attacks has + been filed as CVE-2015-3206. + . + With this version of the pykerberos package a new option is introduced + for the checkPassword() method. Setting verify to True when using + checkPassword() will perform a KDC verification. For this to work, you + need to provide a krb5.keytab file containing service principal keys for + the service you intend to use. + . + As the default krb5.keytab file in /etc is normally not accessible by + non-root users/processes, you have to make sure a custom krb5.keytab + file containing the correct principal keys is provided to your + application using the KRB5_KTNAME environment variable. + . + Note: In Ubuntu 14.04 LTS, KDC verification support is disabled by + default in order not to break existing setups. + + -- Guido Günther Sat, 22 Aug 2015 12:08:41 +0200 diff -Nru pykerberos-1.1+svn10616/debian/patches/Add-KDC-authenticity-verification-support-CVE-2015-3206.patch pykerberos-1.1+svn10616/debian/patches/Add-KDC-authenticity-verification-support-CVE-2015-3206.patch --- pykerberos-1.1+svn10616/debian/patches/Add-KDC-authenticity-verification-support-CVE-2015-3206.patch 1970-01-01 00:00:00.000000000 +0000 +++ pykerberos-1.1+svn10616/debian/patches/Add-KDC-authenticity-verification-support-CVE-2015-3206.patch 2017-10-13 19:02:37.000000000 +0000 @@ -0,0 +1,159 @@ +Description: Add KDC authenticity verification support (CVE-2015-3206) +Origin: upstream, https://github.com/02strich/pykerberos/ +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/pykerberos/+bug/1716429 +Applied-Upstream: 1.1.6 +Forwarded: not-needed +Last-Update: 2017-10-05 + +* https://github.com/02strich/pykerberos/commit/02d13860b25fab58e739f0e000bed0067b7c6f9c +* https://github.com/02strich/pykerberos/commit/5867201f1b9c682402aa9b495a654b8f346c8784 +* https://github.com/02strich/pykerberos/commit/873fca96cb42ff1c163859a5618dc9983796f438 + +[Updated to not verify by default, to match the default in Ubuntu 12.04 + LTS (before reacing EoL) and in debian Jessie, so as to not break + existing configurations. --sbeattie] + +--- + pysrc/kerberos.py | 4 +++- + src/kerberos.c | 5 +++-- + src/kerberosbasic.c | 41 ++++++++++++++++++++++++++++++++++------- + src/kerberosbasic.h | 2 +- + 4 files changed, 41 insertions(+), 11 deletions(-) + +diff --git a/pysrc/kerberos.py b/pysrc/kerberos.py +index 8c6a712..4fa9df3 100644 +--- a/pysrc/kerberos.py ++++ b/pysrc/kerberos.py +@@ -27,7 +27,7 @@ class BasicAuthError(KrbError): + class GSSError(KrbError): + pass + +-def checkPassword(user, pswd, service, default_realm): ++def checkPassword(user, pswd, service, default_realm, verify=False): + """ + This function provides a simple way to verify that a user name and password match + those normally used for Kerberos authentication. It does this by checking that the +@@ -49,6 +49,8 @@ def checkPassword(user, pswd, service, default_realm): + @param default_realm: a string containing the default realm to use if one is not + supplied in the user argument. Note that Kerberos realms are normally all + uppercase (e.g., 'EXAMPLE.COM'). ++ @param verify: a boolean flagging KDC verification to enabled or disabled ++ (default: False). + @return: True if authentication succeeds, False otherwise. + """ + +diff --git a/src/kerberos.c b/src/kerberos.c +index 740d9e1..4427797 100644 +--- a/src/kerberos.c ++++ b/src/kerberos.c +@@ -31,12 +31,13 @@ static PyObject *checkPassword(PyObject *self, PyObject *args) + const char *pswd = NULL; + const char *service = NULL; + const char *default_realm = NULL; ++ int verify = 0; + int result = 0; + +- if (!PyArg_ParseTuple(args, "ssss", &user, &pswd, &service, &default_realm)) ++ if (!PyArg_ParseTuple(args, "ssss|b", &user, &pswd, &service, &default_realm, &verify)) + return NULL; + +- result = authenticate_user_krb5pwd(user, pswd, service, default_realm); ++ result = authenticate_user_krb5pwd(user, pswd, service, default_realm, verify); + + if (result) + return Py_INCREF(Py_True), Py_True; +diff --git a/src/kerberosbasic.c b/src/kerberosbasic.c +index 0c7bdd7..27d7c4f 100644 +--- a/src/kerberosbasic.c ++++ b/src/kerberosbasic.c +@@ -26,9 +26,9 @@ + extern PyObject *BasicAuthException_class; + static void set_basicauth_error(krb5_context context, krb5_error_code code); + +-static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal principal, const char *password, krb5_principal server); ++static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal principal, const char *password, krb5_principal server, unsigned char verify); + +-int authenticate_user_krb5pwd(const char *user, const char *pswd, const char *service, const char *default_realm) ++int authenticate_user_krb5pwd(const char *user, const char *pswd, const char *service, const char *default_realm, unsigned char verify) + { + krb5_context kcontext = NULL; + krb5_error_code code; +@@ -87,7 +87,7 @@ int authenticate_user_krb5pwd(const char *user, const char *pswd, const char *se + goto end; + } + +- code = verify_krb5_user(kcontext, client, pswd, server); ++ code = verify_krb5_user(kcontext, client, pswd, server, verify); + + if (code) + { +@@ -113,10 +113,11 @@ end: + } + + /* Inspired by krb5_verify_user from Heimdal */ +-static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal principal, const char *password, krb5_principal server) ++static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal principal, const char *password, krb5_principal server, unsigned char verify) + { + krb5_creds creds; +- krb5_get_init_creds_opt gic_options; ++ krb5_get_init_creds_opt *gic_options; ++ krb5_verify_init_creds_opt vic_options; + krb5_error_code ret; + char *name = NULL; + +@@ -131,17 +132,43 @@ static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal pri + free(name); + } + +- krb5_get_init_creds_opt_init(&gic_options); +- ret = krb5_get_init_creds_password(context, &creds, principal, (char *)password, NULL, NULL, 0, NULL, &gic_options); ++ // verify passed in server principal if needed ++ if (verify) { ++ ret = krb5_unparse_name(context, server, &name); ++ if (ret == 0) { ++#ifdef PRINTFS ++ printf("Trying to get TGT for service %s\n", name); ++#endif ++ free(name); ++ } ++ } ++ ++ // verify password ++ krb5_get_init_creds_opt_alloc(context, &gic_options); ++ ret = krb5_get_init_creds_password(context, &creds, principal, (char *)password, NULL, NULL, 0, NULL, gic_options); + if (ret) + { + set_basicauth_error(context, ret); + goto end; + } + ++ // verify response authenticity ++ if (verify) { ++ krb5_verify_init_creds_opt_init(&vic_options); ++ krb5_verify_init_creds_opt_set_ap_req_nofail(&vic_options, 1); ++ ret = krb5_verify_init_creds(context, &creds, server, NULL, NULL, &vic_options); ++ if (ret) { ++ set_basicauth_error(context, ret); ++ } ++ } ++ + end: ++ // clean up + krb5_free_cred_contents(context, &creds); + ++ if (gic_options) ++ krb5_get_init_creds_opt_free(context, gic_options); ++ + return ret; + } + +diff --git a/src/kerberosbasic.h b/src/kerberosbasic.h +index 0a91455..f3cfce5 100644 +--- a/src/kerberosbasic.h ++++ b/src/kerberosbasic.h +@@ -20,4 +20,4 @@ + + #define krb5_get_err_text(context,code) error_message(code) + +-int authenticate_user_krb5pwd(const char *user, const char *pswd, const char *service, const char *default_realm); ++int authenticate_user_krb5pwd(const char *user, const char *pswd, const char *service, const char *default_realm, unsigned char verify); diff -Nru pykerberos-1.1+svn10616/debian/patches/series pykerberos-1.1+svn10616/debian/patches/series --- pykerberos-1.1+svn10616/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ pykerberos-1.1+svn10616/debian/patches/series 2017-10-13 17:01:21.000000000 +0000 @@ -0,0 +1 @@ +Add-KDC-authenticity-verification-support-CVE-2015-3206.patch