diff -Nru python-requests-kerberos-0.5/debian/changelog python-requests-kerberos-0.7.0/debian/changelog --- python-requests-kerberos-0.5/debian/changelog 2015-04-09 08:01:07.000000000 +0000 +++ python-requests-kerberos-0.7.0/debian/changelog 2015-10-16 10:46:17.000000000 +0000 @@ -1,3 +1,17 @@ +python-requests-kerberos (0.7.0-2) unstable; urgency=medium + + * Uploading to unstable. + + -- Thomas Goirand Fri, 16 Oct 2015 10:45:31 +0000 + +python-requests-kerberos (0.7.0-1) experimental; urgency=medium + + * New upstream release. + * Removed CVE-2014-8650_Handle_mutual_authentication.patch applied upstream. + * Some (build-)depends updates. + + -- Thomas Goirand Wed, 02 Sep 2015 19:50:21 +0000 + python-requests-kerberos (0.5-3) unstable; urgency=medium * Fixed swapped short package descriptions of python2.x and python3.x binary diff -Nru python-requests-kerberos-0.5/debian/control python-requests-kerberos-0.7.0/debian/control --- python-requests-kerberos-0.5/debian/control 2015-04-09 08:01:07.000000000 +0000 +++ python-requests-kerberos-0.7.0/debian/control 2015-10-16 10:46:17.000000000 +0000 @@ -4,7 +4,7 @@ Maintainer: PKG OpenStack Uploaders: Thomas Goirand Build-Depends: debhelper (>= 9), - python-all (>= 2.6.6-3~), + python-all, python-setuptools, python3-all, python3-setuptools @@ -14,14 +14,13 @@ python3-kerberos (>= 1.1.1), python3-mock, python3-requests (>= 1.1.0) -Standards-Version: 3.9.5 +Standards-Version: 3.9.6 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=openstack/python-requests-kerberos.git Vcs-Git: git://anonscm.debian.org/openstack/python-requests-kerberos.git Homepage: https://github.com/requests/requests-kerberos Package: python-requests-kerberos Architecture: all -Pre-Depends: dpkg (>= 1.15.6~) Depends: python-kerberos (>= 1.1.1), python-requests (>= 1.1.0), ${misc:Depends}, @@ -35,7 +34,6 @@ Package: python3-requests-kerberos Architecture: all -Pre-Depends: dpkg (>= 1.15.6~) Depends: python3-kerberos (>= 1.1.1), python3-requests (>= 1.1.0), ${misc:Depends}, diff -Nru python-requests-kerberos-0.5/debian/gbp.conf python-requests-kerberos-0.7.0/debian/gbp.conf --- python-requests-kerberos-0.5/debian/gbp.conf 2015-04-09 08:01:07.000000000 +0000 +++ python-requests-kerberos-0.7.0/debian/gbp.conf 2015-10-16 10:46:17.000000000 +0000 @@ -4,6 +4,6 @@ upstream-tag = %(version)s compression = xz -[git-buildpackage] +[buildpackage] export-dir = ../build-area/ diff -Nru python-requests-kerberos-0.5/debian/patches/CVE-2014-8650_Handle_mutual_authentication.patch python-requests-kerberos-0.7.0/debian/patches/CVE-2014-8650_Handle_mutual_authentication.patch --- python-requests-kerberos-0.5/debian/patches/CVE-2014-8650_Handle_mutual_authentication.patch 2015-04-09 08:01:07.000000000 +0000 +++ python-requests-kerberos-0.7.0/debian/patches/CVE-2014-8650_Handle_mutual_authentication.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -Description: CVE-2014-8650: Handle mutual authentication - Make certain that responses always pass through handle_other() to provide - mutual authentication before returning them to the user. -Origin: upstream, https://github.com/mkomitee/requests-kerberos/commit/9c1e08cc17bb6950455a85d33d391ecd2bce6eb6.patch -Author: Michael Komitee -Date: Fri, 8 Aug 2014 17:47:42 -0400 -Bug-Debian: https://bugs.debian.org/768408 -Index: python-requests-kerberos/requests_kerberos/kerberos_.py -=================================================================== ---- python-requests-kerberos.orig/requests_kerberos/kerberos_.py 2014-06-12 09:10:24.000000000 +0800 -+++ python-requests-kerberos/requests_kerberos/kerberos_.py 2014-11-10 21:24:56.000000000 +0800 -@@ -251,7 +251,7 @@ - if response.status_code == 401: - _r = self.handle_401(response, **kwargs) - log.debug("handle_response(): returning {0}".format(_r)) -- return _r -+ return self.handle_response(_r, **kwargs) - else: - _r = self.handle_other(response) - log.debug("handle_response(): returning {0}".format(_r)) -Index: python-requests-kerberos/test_requests_kerberos.py -=================================================================== ---- python-requests-kerberos.orig/test_requests_kerberos.py 2014-11-10 21:24:56.000000000 +0800 -+++ python-requests-kerberos/test_requests_kerberos.py 2014-11-10 21:24:56.000000000 +0800 -@@ -403,10 +403,14 @@ - response.connection = connection - response._content = "" - response.raw = raw -+ - auth = requests_kerberos.HTTPKerberosAuth() -+ auth.handle_other = Mock(return_value=response_ok) -+ - r = auth.handle_response(response) - - self.assertTrue(response in r.history) -+ auth.handle_other.assert_called_with(response_ok) - self.assertEqual(r, response_ok) - self.assertEqual(request.headers['Authorization'], 'Negotiate GSSRESPONSE') - connection.send.assert_called_with(request) diff -Nru python-requests-kerberos-0.5/debian/patches/fix-setup.py-to-work-with-python3.patch python-requests-kerberos-0.7.0/debian/patches/fix-setup.py-to-work-with-python3.patch --- python-requests-kerberos-0.5/debian/patches/fix-setup.py-to-work-with-python3.patch 2015-04-09 08:01:07.000000000 +0000 +++ python-requests-kerberos-0.7.0/debian/patches/fix-setup.py-to-work-with-python3.patch 2015-10-16 10:46:17.000000000 +0000 @@ -5,9 +5,11 @@ Forwarded: no Last-Update: 2014-06-17 ---- python-requests-kerberos-0.5.orig/setup.py -+++ python-requests-kerberos-0.5/setup.py -@@ -29,7 +29,7 @@ def get_version(): +Index: python-requests-kerberos/setup.py +=================================================================== +--- python-requests-kerberos.orig/setup.py ++++ python-requests-kerberos/setup.py +@@ -35,7 +35,7 @@ def get_version(): """ reg = re.compile(r'__version__ = [\'"]([^\'"]*)[\'"]') with open('requests_kerberos/__init__.py') as fd: diff -Nru python-requests-kerberos-0.5/debian/patches/series python-requests-kerberos-0.7.0/debian/patches/series --- python-requests-kerberos-0.5/debian/patches/series 2015-04-09 08:01:07.000000000 +0000 +++ python-requests-kerberos-0.7.0/debian/patches/series 2015-10-16 10:46:17.000000000 +0000 @@ -1,3 +1,2 @@ disable-broken-test-in-python3.patch fix-setup.py-to-work-with-python3.patch -CVE-2014-8650_Handle_mutual_authentication.patch diff -Nru python-requests-kerberos-0.5/HISTORY.rst python-requests-kerberos-0.7.0/HISTORY.rst --- python-requests-kerberos-0.5/HISTORY.rst 2014-05-21 01:09:55.000000000 +0000 +++ python-requests-kerberos-0.7.0/HISTORY.rst 2015-05-04 15:57:44.000000000 +0000 @@ -1,6 +1,39 @@ History ======= +0.7.0: 2015-05-04 +----------------- + +- Added Windows native authentication support by adding kerberos-sspi as an + alternative backend. + +- Prevent infinite recursion when a server returns 401 to an authorization + attempt. + +- Reduce the logging during successful responses. + +0.6.1: 2014-11-14 +----------------- + +- Fix HTTPKerberosAuth not to treat non-file as a file + +- Prevent infinite recursion when GSSErrors occurs + +0.6: 2014-11-04 +--------------- + +- Handle mutual authentication (see pull request 36_) + + All users should upgrade immediately. This has been reported to + oss-security_ and we are awaiting a proper CVE identifier. + + **Update**: We were issued CVE-2014-8650 + +- Distribute as a wheel. + +.. _36: https://github.com/requests/requests-kerberos/pull/36 +.. _oss-security: http://www.openwall.com/lists/oss-security/ + 0.5: 2014-05-14 --------------- diff -Nru python-requests-kerberos-0.5/requests_kerberos/__init__.py python-requests-kerberos-0.7.0/requests_kerberos/__init__.py --- python-requests-kerberos-0.5/requests_kerberos/__init__.py 2014-05-21 01:09:55.000000000 +0000 +++ python-requests-kerberos-0.7.0/requests_kerberos/__init__.py 2015-05-04 15:57:44.000000000 +0000 @@ -20,6 +20,6 @@ logging.getLogger(__name__).addHandler(NullHandler()) -__all__ = [HTTPKerberosAuth, MutualAuthenticationError, REQUIRED, OPTIONAL, - DISABLED] -__version__ = '0.5' +__all__ = ('HTTPKerberosAuth', 'MutualAuthenticationError', 'REQUIRED', + 'OPTIONAL', 'DISABLED') +__version__ = '0.7.0' diff -Nru python-requests-kerberos-0.5/requests_kerberos/kerberos_.py python-requests-kerberos-0.7.0/requests_kerberos/kerberos_.py --- python-requests-kerberos-0.5/requests_kerberos/kerberos_.py 2014-05-21 01:09:55.000000000 +0000 +++ python-requests-kerberos-0.7.0/requests_kerberos/kerberos_.py 2015-05-04 15:57:44.000000000 +0000 @@ -1,4 +1,7 @@ -import kerberos +try: + import kerberos +except ImportError: + import kerberos_sspi as kerberos import re import logging @@ -99,9 +102,8 @@ try: result, self.context[host] = kerberos.authGSSClientInit( "{0}@{1}".format(self.service, host)) - except kerberos.GSSError as e: - log.error("generate_request_header(): authGSSClientInit() failed:") - log.exception(e) + except kerberos.GSSError: + log.exception("generate_request_header(): authGSSClientInit() failed:") return None if result < 1: @@ -112,9 +114,8 @@ try: result = kerberos.authGSSClientStep(self.context[host], _negotiate_value(response)) - except kerberos.GSSError as e: - log.error("generate_request_header(): authGSSClientStep() failed:") - log.exception(e) + except kerberos.GSSError: + log.exception("generate_request_header(): authGSSClientStep() failed:") return None if result < 0: @@ -124,10 +125,9 @@ try: gss_response = kerberos.authGSSClientResponse(self.context[host]) - except kerberos.GSSError as e: - log.error("generate_request_header(): authGSSClientResponse() " + except kerberos.GSSError: + log.exception("generate_request_header(): authGSSClientResponse() " "failed:") - log.exception(e) return None return "Negotiate {0}".format(gss_response) @@ -194,8 +194,9 @@ return response elif is_http_error or self.mutual_authentication == OPTIONAL: - log.error("handle_other(): Mutual authentication unavailable " - "on {0} response".format(response.status_code)) + if not response.ok: + log.error("handle_other(): Mutual authentication unavailable " + "on {0} response".format(response.status_code)) if self.mutual_authentication == REQUIRED: return SanitizedResponse(response) @@ -227,13 +228,12 @@ try: result = kerberos.authGSSClientStep(self.context[host], _negotiate_value(response)) - except kerberos.GSSError as e: - log.error("authenticate_server(): authGSSClientStep() failed:") - log.exception(e) + except kerberos.GSSError: + log.exception("authenticate_server(): authGSSClientStep() failed:") return False if result < 1: - log.error("auhenticate_server(): authGSSClientStep() failed: " + log.error("authenticate_server(): authGSSClientStep() failed: " "{0}".format(result)) return False @@ -242,19 +242,29 @@ def handle_response(self, response, **kwargs): """Takes the given response and tries kerberos-auth, as needed.""" + num_401s = kwargs.pop('num_401s', 0) if self.pos is not None: # Rewind the file position indicator of the body to where # it was to resend the request. response.request.body.seek(self.pos) - if response.status_code == 401: + if response.status_code == 401 and num_401s < 2: + # 401 Unauthorized. Handle it, and if it still comes back as 401, + # that means authentication failed. _r = self.handle_401(response, **kwargs) - log.debug("handle_response(): returning {0}".format(_r)) - return _r + log.debug("handle_response(): returning %s", _r) + log.debug("handle_response() has seen %d 401 responses", num_401s) + num_401s += 1 + return self.handle_response(_r, num_401s=num_401s, **kwargs) + elif response.status_code == 401 and num_401s >= 2: + # Still receiving 401 responses after attempting to handle them. + # Authentication has failed. Return the 401 response. + log.debug("handle_response(): returning 401 %s", response) + return response else: _r = self.handle_other(response) - log.debug("handle_response(): returning {0}".format(_r)) + log.debug("handle_response(): returning %s", _r) return _r def deregister(self, response): @@ -266,5 +276,9 @@ try: self.pos = request.body.tell() except AttributeError: - pass + # In the case of HTTPKerberosAuth being reused and the body + # of the previous request was a file-like object, pos has + # the file position of the previous body. Ensure it's set to + # None. + self.pos = None return request diff -Nru python-requests-kerberos-0.5/requirements.txt python-requests-kerberos-0.7.0/requirements.txt --- python-requests-kerberos-0.5/requirements.txt 2014-05-21 01:09:55.000000000 +0000 +++ python-requests-kerberos-0.7.0/requirements.txt 2015-05-04 15:57:44.000000000 +0000 @@ -1,2 +1 @@ requests>=1.1.0 -kerberos==1.1.1 diff -Nru python-requests-kerberos-0.5/setup.cfg python-requests-kerberos-0.7.0/setup.cfg --- python-requests-kerberos-0.5/setup.cfg 1970-01-01 00:00:00.000000000 +0000 +++ python-requests-kerberos-0.7.0/setup.cfg 2015-05-04 15:57:44.000000000 +0000 @@ -0,0 +1,2 @@ +[wheel] +universal = 1 diff -Nru python-requests-kerberos-0.5/setup.py python-requests-kerberos-0.7.0/setup.py --- python-requests-kerberos-0.5/setup.py 2014-05-21 01:09:55.000000000 +0000 +++ python-requests-kerberos-0.7.0/setup.py 2015-05-04 15:57:44.000000000 +0000 @@ -1,12 +1,18 @@ #!/usr/bin/env python # coding: utf-8 import os +import sys import re from setuptools import setup with open('requirements.txt') as requirements: requires = [line.strip() for line in requirements if line.strip()] +if sys.platform == 'win32': + requires.append('kerberos-sspi') +else: + requires.append('kerberos==1.1.1') + path = os.path.dirname(__file__) desc_fd = os.path.join(path, 'README.rst') hist_fd = os.path.join(path, 'HISTORY.rst') @@ -43,6 +49,8 @@ name='requests-kerberos', description=short_desc, long_description=long_desc, + author='Ian Cordasco, Cory Benfield, Michael Komitee', + author_email='graffatcolmingov@gmail.com', url='https://github.com/requests/requests-kerberos', packages=['requests_kerberos'], package_data={'': ['LICENSE', 'AUTHORS']}, diff -Nru python-requests-kerberos-0.5/test_requests_kerberos.py python-requests-kerberos-0.7.0/test_requests_kerberos.py --- python-requests-kerberos-0.5/test_requests_kerberos.py 2014-05-21 01:09:55.000000000 +0000 +++ python-requests-kerberos-0.7.0/test_requests_kerberos.py 2015-05-04 15:57:44.000000000 +0000 @@ -377,6 +377,7 @@ def test_handle_response_401(self): + # Get a 401 from server, authenticate, and get a 200 back. with patch.multiple('kerberos', authGSSClientInit=clientInit_complete, authGSSClientResponse=clientResponse, @@ -402,15 +403,64 @@ response.connection = connection response._content = "" response.raw = raw + auth = requests_kerberos.HTTPKerberosAuth() + auth.handle_other = Mock(return_value=response_ok) + r = auth.handle_response(response) self.assertTrue(response in r.history) + auth.handle_other.assert_called_once_with(response_ok) self.assertEqual(r, response_ok) self.assertEqual(request.headers['Authorization'], 'Negotiate GSSRESPONSE') connection.send.assert_called_with(request) raw.release_conn.assert_called_with() clientInit_complete.assert_called_with("HTTP@www.example.org") + clientStep_continue.assert_called_with("CTX", "token") + clientResponse.assert_called_with("CTX") + + def test_handle_response_401_rejected(self): + # Get a 401 from server, authenticate, and get another 401 back. + # Ensure there is no infinite recursion. + with patch.multiple('kerberos', + authGSSClientInit=clientInit_complete, + authGSSClientResponse=clientResponse, + authGSSClientStep=clientStep_continue): + + connection = Mock() + + def connection_send(self, *args, **kwargs): + reject = requests.Response() + reject.url = "http://www.example.org/" + reject.status_code = 401 + reject.connection = connection + return reject + + connection.send.side_effect = connection_send + + raw = Mock() + raw.release_conn.return_value = None + + request = requests.Request() + response = requests.Response() + response.request = request + response.url = "http://www.example.org/" + response.headers = {'www-authenticate': 'negotiate token'} + response.status_code = 401 + response.connection = connection + response._content = "" + response.raw = raw + + auth = requests_kerberos.HTTPKerberosAuth() + + r = auth.handle_response(response) + + self.assertEqual(r.status_code, 401) + self.assertEqual(request.headers['Authorization'], + 'Negotiate GSSRESPONSE') + connection.send.assert_called_with(request) + raw.release_conn.assert_called_with() + clientInit_complete.assert_called_with("HTTP@www.example.org") clientStep_continue.assert_called_with("CTX", "token") clientResponse.assert_called_with("CTX") diff -Nru python-requests-kerberos-0.5/.travis.yml python-requests-kerberos-0.7.0/.travis.yml --- python-requests-kerberos-0.5/.travis.yml 2014-05-21 01:09:55.000000000 +0000 +++ python-requests-kerberos-0.7.0/.travis.yml 2015-05-04 15:57:44.000000000 +0000 @@ -3,4 +3,6 @@ - "2.6" - "2.7" +install: + - pip install . script: py.test test_requests_kerberos.py