From b604149555704f892ef993cc059d4a3bb00730b3 Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Thu, 14 Dec 2017 15:24:57 -0500 Subject: [PATCH 1/3] Properly use base64 for request headers This wasn't needed for requests-kerberos because pykerberos automatically base64 encodes and decodes messages from Kerberos, which is a behavior I do not like at all. Signed-off-by: Robbie Harwood --- requests_gssapi/gssapi_.py | 6 +- test_requests_gssapi.py | 123 ++++++++++++++++++++----------------- 2 files changed, 69 insertions(+), 60 deletions(-) diff --git a/requests_gssapi/gssapi_.py b/requests_gssapi/gssapi_.py index 1a9bc04..b53d553 100644 --- a/requests_gssapi/gssapi_.py +++ b/requests_gssapi/gssapi_.py @@ -1,6 +1,8 @@ import re import logging +from base64 import b64encode, b64decode + import gssapi from requests.auth import AuthBase @@ -73,7 +75,7 @@ def _negotiate_value(response): if authreq: match_obj = regex.search(authreq) if match_obj: - return match_obj.group(1) + return b64decode(match_obj.group(1)) return None @@ -144,7 +146,7 @@ def generate_request_header(self, response, host, is_preemptive=False): gss_response = self.context[host].step( _negotiate_value(response)) - return "Negotiate {0}".format(gss_response) + return "Negotiate {0}".format(b64encode(gss_response).decode()) except gssapi.exceptions.GSSError as error: msg = error.gen_message() diff --git a/test_requests_gssapi.py b/test_requests_gssapi.py index bdc5d31..a21fc13 100644 --- a/test_requests_gssapi.py +++ b/test_requests_gssapi.py @@ -3,6 +3,7 @@ """Tests for requests_gssapi.""" +from base64 import b64encode from mock import Mock, patch from requests.compat import urlparse import requests @@ -18,8 +19,8 @@ # > -- sigmavirus24 in https://github.com/requests/requests-kerberos/issues/1 fake_init = Mock(return_value=None) -fake_creds = Mock(return_value="fake creds") -fake_resp = Mock(return_value="GSSRESPONSE") +fake_creds = Mock(return_value=b"fake creds") +fake_resp = Mock(return_value=b"GSSRESPONSE") # GSSAPI exceptions require a major and minor status code for their # construction, so construct a *really* fake one @@ -29,6 +30,12 @@ gssapi.RequirementFlag.out_of_sequence_detection] gssdelegflags = gssflags + [gssapi.RequirementFlag.delegate_to_peer] +# The base64 behavior we want is that encoding produces a string, but decoding +# produces bytes. Remember, GSSAPI tokens are opaque here. +b64_negotiate_response = "Negotiate " + b64encode(b"GSSRESPONSE").decode() +b64_negotiate_token = "negotiate " + b64encode(b"token").decode() +b64_negotiate_server = "negotiate " + b64encode(b"servertoken").decode() + class GSSAPITestCase(unittest.TestCase): def setUp(self): @@ -44,10 +51,10 @@ def tearDown(self): def test_negotate_value_extraction(self): response = requests.Response() - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} self.assertEqual( requests_gssapi.gssapi_._negotiate_value(response), - 'token' + b'token' ) def test_negotate_value_extraction_none(self): @@ -67,7 +74,7 @@ def test_force_preemptive(self): self.assertTrue('Authorization' in request.headers) self.assertEqual(request.headers.get('Authorization'), - 'Negotiate GSSRESPONSE') + b64_negotiate_response) def test_no_force_preemptive(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -85,23 +92,23 @@ def test_generate_request_header(self): step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth() self.assertEqual( auth.generate_request_header(response, host), - "Negotiate GSSRESPONSE") + b64_negotiate_response) fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), creds=None, flags=gssflags, usage="initiate") - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") def test_generate_request_header_init_error(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fail_resp): response = requests.Response() response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth() self.assertRaises(requests_gssapi.exceptions.SPNEGOExchangeError, @@ -115,7 +122,7 @@ def test_generate_request_header_step_error(self): step=fail_resp): response = requests.Response() response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth() self.assertRaises(requests_gssapi.exceptions.SPNEGOExchangeError, @@ -123,7 +130,7 @@ def test_generate_request_header_step_error(self): fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=None) - fail_resp.assert_called_with("token") + fail_resp.assert_called_with(b"token") def test_authenticate_user(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -131,7 +138,7 @@ def test_authenticate_user(self): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 - response_ok.headers = {'www-authenticate': 'negotiate servertoken'} + response_ok.headers = {'www-authenticate': b64_negotiate_server} connection = Mock() connection.send = Mock(return_value=response_ok) @@ -143,7 +150,7 @@ def test_authenticate_user(self): response = requests.Response() response.request = request response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} response.status_code = 401 response.connection = connection response._content = "" @@ -154,13 +161,13 @@ def test_authenticate_user(self): self.assertTrue(response in r.history) self.assertEqual(r, response_ok) self.assertEqual(request.headers['Authorization'], - 'Negotiate GSSRESPONSE') + b64_negotiate_response) connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), flags=gssflags, usage="initiate", creds=None) - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") def test_handle_401(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -168,7 +175,7 @@ def test_handle_401(self): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 - response_ok.headers = {'www-authenticate': 'negotiate servertoken'} + response_ok.headers = {'www-authenticate': b64_negotiate_server} connection = Mock() connection.send = Mock(return_value=response_ok) @@ -180,7 +187,7 @@ def test_handle_401(self): response = requests.Response() response.request = request response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} response.status_code = 401 response.connection = connection response._content = "" @@ -191,13 +198,13 @@ def test_handle_401(self): self.assertTrue(response in r.history) self.assertEqual(r, response_ok) self.assertEqual(request.headers['Authorization'], - 'Negotiate GSSRESPONSE') + b64_negotiate_response) connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), creds=None, flags=gssflags, usage="initiate") - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") def test_authenticate_server(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -206,15 +213,15 @@ def test_authenticate_server(self): response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = { - 'www-authenticate': 'negotiate servertoken', - 'authorization': 'Negotiate GSSRESPONSE'} + 'www-authenticate': b64_negotiate_server, + 'authorization': b64_negotiate_response} auth = requests_gssapi.HTTPKerberosAuth() auth.context = {"www.example.org": gssapi.SecurityContext} result = auth.authenticate_server(response_ok) self.assertTrue(result) - fake_resp.assert_called_with("servertoken") + fake_resp.assert_called_with(b"servertoken") def test_handle_other(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -223,8 +230,8 @@ def test_handle_other(self): response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = { - 'www-authenticate': 'negotiate servertoken', - 'authorization': 'Negotiate GSSRESPONSE'} + 'www-authenticate': b64_negotiate_server, + 'authorization': b64_negotiate_response} auth = requests_gssapi.HTTPKerberosAuth() auth.context = {"www.example.org": gssapi.SecurityContext} @@ -232,7 +239,7 @@ def test_handle_other(self): r = auth.handle_other(response_ok) self.assertEqual(r, response_ok) - fake_resp.assert_called_with("servertoken") + fake_resp.assert_called_with(b"servertoken") def test_handle_response_200(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -241,8 +248,8 @@ def test_handle_response_200(self): response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = { - 'www-authenticate': 'negotiate servertoken', - 'authorization': 'Negotiate GSSRESPONSE'} + 'www-authenticate': b64_negotiate_server, + 'authorization': b64_negotiate_response} auth = requests_gssapi.HTTPKerberosAuth() auth.context = {"www.example.org": gssapi.SecurityContext} @@ -250,7 +257,7 @@ def test_handle_response_200(self): r = auth.handle_response(response_ok) self.assertEqual(r, response_ok) - fake_resp.assert_called_with("servertoken") + fake_resp.assert_called_with(b"servertoken") def test_handle_response_200_mutual_auth_required_failure(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -276,8 +283,8 @@ def test_handle_response_200_mutual_auth_required_failure_2(self): response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = { - 'www-authenticate': 'negotiate servertoken', - 'authorization': 'Negotiate GSSRESPONSE'} + 'www-authenticate': b64_negotiate_server, + 'authorization': b64_negotiate_response} auth = requests_gssapi.HTTPKerberosAuth() auth.context = {"www.example.org": gssapi.SecurityContext} @@ -285,7 +292,7 @@ def test_handle_response_200_mutual_auth_required_failure_2(self): self.assertRaises(requests_gssapi.MutualAuthenticationError, auth.handle_response, response_ok) - fail_resp.assert_called_with("servertoken") + fail_resp.assert_called_with(b"servertoken") def test_handle_response_200_mutual_auth_optional_hard_failure(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -294,8 +301,8 @@ def test_handle_response_200_mutual_auth_optional_hard_failure(self): response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = { - 'www-authenticate': 'negotiate servertoken', - 'authorization': 'Negotiate GSSRESPONSE'} + 'www-authenticate': b64_negotiate_server, + 'authorization': b64_negotiate_response} auth = requests_gssapi.HTTPKerberosAuth( requests_gssapi.OPTIONAL) @@ -304,7 +311,7 @@ def test_handle_response_200_mutual_auth_optional_hard_failure(self): self.assertRaises(requests_gssapi.MutualAuthenticationError, auth.handle_response, response_ok) - fail_resp.assert_called_with("servertoken") + fail_resp.assert_called_with(b"servertoken") def test_handle_response_200_mutual_auth_optional_soft_failure(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -398,7 +405,7 @@ def test_handle_response_401(self): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 - response_ok.headers = {'www-authenticate': 'negotiate servertoken'} + response_ok.headers = {'www-authenticate': b64_negotiate_server} connection = Mock() connection.send = Mock(return_value=response_ok) @@ -410,7 +417,7 @@ def test_handle_response_401(self): response = requests.Response() response.request = request response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} response.status_code = 401 response.connection = connection response._content = "" @@ -425,13 +432,13 @@ def test_handle_response_401(self): auth.handle_other.assert_called_once_with(response_ok) self.assertEqual(r, response_ok) self.assertEqual(request.headers['Authorization'], - 'Negotiate GSSRESPONSE') + b64_negotiate_response) connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=None) - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") def test_handle_response_401_rejected(self): # Get a 401 from server, authenticate, and get another 401 back. @@ -456,7 +463,7 @@ def connection_send(self, *args, **kwargs): response = requests.Response() response.request = request response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} response.status_code = 401 response.connection = connection response._content = "" @@ -468,27 +475,27 @@ def connection_send(self, *args, **kwargs): self.assertEqual(r.status_code, 401) self.assertEqual(request.headers['Authorization'], - 'Negotiate GSSRESPONSE') + b64_negotiate_response) connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=None) - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") def test_generate_request_header_custom_service(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth(service="barfoo") auth.generate_request_header(response, host), fake_init.assert_called_with( name=gssapi.Name("barfoo@www.example.org"), usage="initiate", flags=gssflags, creds=None) - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") def test_delegation(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -496,7 +503,7 @@ def test_delegation(self): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 - response_ok.headers = {'www-authenticate': 'negotiate servertoken'} + response_ok.headers = {'www-authenticate': b64_negotiate_server} connection = Mock() connection.send = Mock(return_value=response_ok) @@ -508,7 +515,7 @@ def test_delegation(self): response = requests.Response() response.request = request response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} response.status_code = 401 response.connection = connection response._content = "" @@ -519,13 +526,13 @@ def test_delegation(self): self.assertTrue(response in r.history) self.assertEqual(r, response_ok) self.assertEqual(request.headers['Authorization'], - 'Negotiate GSSRESPONSE') + b64_negotiate_response) connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), usage="initiate", flags=gssdelegflags, creds=None) - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") def test_principal_override(self): with patch.multiple("gssapi.Credentials", __new__=fake_creds), \ @@ -533,7 +540,7 @@ def test_principal_override(self): step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth(principal="user@REALM") auth.generate_request_header(response, host) @@ -542,15 +549,15 @@ def test_principal_override(self): name=gssapi.Name("user@REALM")) fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), - usage="initiate", flags=gssflags, creds="fake creds") - fake_resp.assert_called_with("token") + usage="initiate", flags=gssflags, creds=b"fake creds") + fake_resp.assert_called_with(b"token") def test_realm_override(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth( hostname_override="otherhost.otherdomain.org") @@ -558,7 +565,7 @@ def test_realm_override(self): fake_init.assert_called_with( name=gssapi.Name("HTTP@otherhost.otherdomain.org"), usage="initiate", flags=gssflags, creds=None) - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") def test_opportunistic_auth(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -571,7 +578,7 @@ def test_opportunistic_auth(self): self.assertTrue('Authorization' in request.headers) self.assertEqual(request.headers.get('Authorization'), - 'Negotiate GSSRESPONSE') + b64_negotiate_response) def test_explicit_creds(self): with patch.multiple("gssapi.Credentials", __new__=fake_creds), \ @@ -579,22 +586,22 @@ def test_explicit_creds(self): step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname creds = gssapi.Credentials() auth = requests_gssapi.HTTPSPNEGOAuth(creds=creds) auth.generate_request_header(response, host) fake_init.assert_called_with( name=gssapi.Name("HTTP@www.example.org"), - usage="initiate", flags=gssflags, creds="fake creds") - fake_resp.assert_called_with("token") + usage="initiate", flags=gssflags, creds=b"fake creds") + fake_resp.assert_called_with(b"token") def test_target_name(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" - response.headers = {'www-authenticate': 'negotiate token'} + response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPSPNEGOAuth( target_name="HTTP@otherhost.otherdomain.org") @@ -602,7 +609,7 @@ def test_target_name(self): fake_init.assert_called_with( name=gssapi.Name("HTTP@otherhost.otherdomain.org"), usage="initiate", flags=gssflags, creds=None) - fake_resp.assert_called_with("token") + fake_resp.assert_called_with(b"token") if __name__ == '__main__': From 891daf454fdec5d8ae81b00ca512599de67c499c Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Thu, 14 Dec 2017 15:47:22 -0500 Subject: [PATCH 2/3] Use the correct GSSAPI nametype (hostbased_service) Signed-off-by: Robbie Harwood --- README.rst | 3 ++- requests_gssapi/compat.py | 6 ++++-- requests_gssapi/gssapi_.py | 3 ++- test_requests_gssapi.py | 33 ++++++++++++++++++--------------- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/README.rst b/README.rst index 47c87d4..0d3e37d 100644 --- a/README.rst +++ b/README.rst @@ -133,7 +133,8 @@ applicable). However, an explicit credential can be in instead, if desired. >>> import gssapi >>> import requests >>> from requests_gssapi import HTTPSPNEGOAuth, REQUIRED - >>> creds = gssapi.Credentials(name=gssapi.Name("user@REALM"), usage="initiate") + >>> name = gssapi.Name("user@REALM", gssapi.NameType.hostbased_service) + >>> creds = gssapi.Credentials(name=name, usage="initiate") >>> gssapi_auth = HTTPSPNEGOAuth(creds=creds) >>> r = requests.get("http://example.org", auth=gssapi_auth) ... diff --git a/requests_gssapi/compat.py b/requests_gssapi/compat.py index ed18142..99eb7b7 100644 --- a/requests_gssapi/compat.py +++ b/requests_gssapi/compat.py @@ -45,7 +45,8 @@ def generate_request_header(self, response, host, is_preemptive=False): try: if self.principal is not None: gss_stage = "acquiring credentials" - name = gssapi.Name(self.principal) + name = gssapi.Name( + self.principal, gssapi.NameType.hostbased_service) self.creds = gssapi.Credentials(name=name, usage="initiate") # contexts still need to be stored by host, but hostname_override @@ -59,7 +60,8 @@ def generate_request_header(self, response, host, is_preemptive=False): kerb_host = self.hostname_override kerb_spn = "{0}@{1}".format(self.service, kerb_host) - self.target_name = gssapi.Name(kerb_spn) + self.target_name = gssapi.Name( + kerb_spn, gssapi.NameType.hostbased_service) return HTTPSPNEGOAuth.generate_request_header(self, response, host, is_preemptive) diff --git a/requests_gssapi/gssapi_.py b/requests_gssapi/gssapi_.py index b53d553..8457f30 100644 --- a/requests_gssapi/gssapi_.py +++ b/requests_gssapi/gssapi_.py @@ -134,7 +134,8 @@ def generate_request_header(self, response, host, is_preemptive=False): if '@' not in self.target_name: self.target_name = "%s@%s" % (self.target_name, host) - self.target_name = gssapi.Name(self.target_name) + self.target_name = gssapi.Name( + self.target_name, gssapi.NameType.hostbased_service) self.context[host] = gssapi.SecurityContext( usage="initiate", flags=gssflags, name=self.target_name, creds=self.creds) diff --git a/test_requests_gssapi.py b/test_requests_gssapi.py index a21fc13..cd4adcd 100644 --- a/test_requests_gssapi.py +++ b/test_requests_gssapi.py @@ -37,6 +37,10 @@ b64_negotiate_server = "negotiate " + b64encode(b"servertoken").decode() +def gssapi_name(s): + return gssapi.Name(s, gssapi.NameType.hostbased_service) + + class GSSAPITestCase(unittest.TestCase): def setUp(self): """Setup.""" @@ -99,7 +103,7 @@ def test_generate_request_header(self): auth.generate_request_header(response, host), b64_negotiate_response) fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), creds=None, flags=gssflags, usage="initiate") fake_resp.assert_called_with(b"token") @@ -114,7 +118,7 @@ def test_generate_request_header_init_error(self): self.assertRaises(requests_gssapi.exceptions.SPNEGOExchangeError, auth.generate_request_header, response, host) fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=None) def test_generate_request_header_step_error(self): @@ -128,7 +132,7 @@ def test_generate_request_header_step_error(self): self.assertRaises(requests_gssapi.exceptions.SPNEGOExchangeError, auth.generate_request_header, response, host) fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=None) fail_resp.assert_called_with(b"token") @@ -165,7 +169,7 @@ def test_authenticate_user(self): connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), flags=gssflags, usage="initiate", creds=None) fake_resp.assert_called_with(b"token") @@ -202,7 +206,7 @@ def test_handle_401(self): connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), creds=None, flags=gssflags, usage="initiate") fake_resp.assert_called_with(b"token") @@ -436,7 +440,7 @@ def test_handle_response_401(self): connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=None) fake_resp.assert_called_with(b"token") @@ -479,7 +483,7 @@ def connection_send(self, *args, **kwargs): connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=None) fake_resp.assert_called_with(b"token") @@ -493,7 +497,7 @@ def test_generate_request_header_custom_service(self): auth = requests_gssapi.HTTPKerberosAuth(service="barfoo") auth.generate_request_header(response, host), fake_init.assert_called_with( - name=gssapi.Name("barfoo@www.example.org"), + name=gssapi_name("barfoo@www.example.org"), usage="initiate", flags=gssflags, creds=None) fake_resp.assert_called_with(b"token") @@ -530,7 +534,7 @@ def test_delegation(self): connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), usage="initiate", flags=gssdelegflags, creds=None) fake_resp.assert_called_with(b"token") @@ -546,11 +550,10 @@ def test_principal_override(self): auth.generate_request_header(response, host) fake_creds.assert_called_with(gssapi.creds.Credentials, usage="initiate", - name=gssapi.Name("user@REALM")) + name=gssapi_name("user@REALM")) fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=b"fake creds") - fake_resp.assert_called_with(b"token") def test_realm_override(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, @@ -563,7 +566,7 @@ def test_realm_override(self): hostname_override="otherhost.otherdomain.org") auth.generate_request_header(response, host) fake_init.assert_called_with( - name=gssapi.Name("HTTP@otherhost.otherdomain.org"), + name=gssapi_name("HTTP@otherhost.otherdomain.org"), usage="initiate", flags=gssflags, creds=None) fake_resp.assert_called_with(b"token") @@ -592,7 +595,7 @@ def test_explicit_creds(self): auth = requests_gssapi.HTTPSPNEGOAuth(creds=creds) auth.generate_request_header(response, host) fake_init.assert_called_with( - name=gssapi.Name("HTTP@www.example.org"), + name=gssapi_name("HTTP@www.example.org"), usage="initiate", flags=gssflags, creds=b"fake creds") fake_resp.assert_called_with(b"token") @@ -607,7 +610,7 @@ def test_target_name(self): target_name="HTTP@otherhost.otherdomain.org") auth.generate_request_header(response, host) fake_init.assert_called_with( - name=gssapi.Name("HTTP@otherhost.otherdomain.org"), + name=gssapi_name("HTTP@otherhost.otherdomain.org"), usage="initiate", flags=gssflags, creds=None) fake_resp.assert_called_with(b"token") From 4092b2d4e27931313f4bbd27e4c9e4d8d8f1722b Mon Sep 17 00:00:00 2001 From: Robbie Harwood Date: Thu, 14 Dec 2017 15:52:52 -0500 Subject: [PATCH 3/3] Release version 1.0.0 Signed-off-by: Robbie Harwood Resolves: #5 --- HISTORY.rst | 8 ++++++++ requests_gssapi/__init__.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index e9d1e2d..e30c626 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,14 @@ History ======= +1.0.0: 2017-12-14 +----------------- + +- Fork project to requests-gssapi +- Replace pykerberos with python-gssapi +- Add HTTPSPNEGOAuth interface. HTTPKerberosAuth is retained as a shim, but + bump the major version anyway for clarity. + 0.11.0: 2016-11-02 ------------------ diff --git a/requests_gssapi/__init__.py b/requests_gssapi/__init__.py index 4c69401..b1839af 100644 --- a/requests_gssapi/__init__.py +++ b/requests_gssapi/__init__.py @@ -22,4 +22,4 @@ __all__ = ('HTTPSPNEGOAuth', 'HTTPKerberosAuth', 'MutualAuthenticationError', 'REQUIRED', 'OPTIONAL', 'DISABLED') -__version__ = '0.11.0' +__version__ = '1.0.0'