From 918c9d9dd632d346909d2429647758352d753a42 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 1 Feb 2013 17:38:11 -0700 Subject: Update documentation for include_ip Add a note that using the include_ip functionality with IPv6 is not a good idea due to the users network expiring IPv6 addresses quickly. See preferred lifetime/valid lifetime for routers doing SLAAC in IPv6 for more information. --- pyramid/authentication.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyramid/authentication.py b/pyramid/authentication.py index 4f6ed2c1d..190298f98 100644 --- a/pyramid/authentication.py +++ b/pyramid/authentication.py @@ -450,6 +450,10 @@ class AuthTktAuthenticationPolicy(CallbackAuthenticationPolicy): Default: ``False``. Make the requesting IP address part of the authentication data in the cookie. Optional. + For IPv6 this option is not recommended. It ties the authentication + ticket to that individual's IPv6 address. Depending on the network they + are on, the IPv6 address that a user is using may expire quickly. + ``timeout`` Default: ``None``. Maximum number of seconds which a newly -- cgit v1.2.3 From fbd5b4a8023f3ff3c42ab66b1a660d587e9c331b Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 1 Feb 2013 18:00:22 -0700 Subject: Add test for AuthTktCookieHelper for IPv6 compat Add an extra test that sets environ['REMOTE_ADDR'] to an IPv6 address "::1". --- pyramid/tests/test_authentication.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py index 123e4f9f5..37e088934 100644 --- a/pyramid/tests/test_authentication.py +++ b/pyramid/tests/test_authentication.py @@ -561,9 +561,13 @@ class TestAuthTktCookieHelper(unittest.TestCase): helper.BadTicket = auth_tkt.BadTicket return helper - def _makeRequest(self, cookie=None): + def _makeRequest(self, cookie=None, ipv6=False): environ = {'wsgi.version': (1,0)} - environ['REMOTE_ADDR'] = '1.1.1.1' + + if ipv6 is False: + environ['REMOTE_ADDR'] = '1.1.1.1' + else: + environ['REMOTE_ADDR'] = '::1' environ['SERVER_NAME'] = 'localhost' return DummyRequest(environ, cookie=cookie) @@ -612,6 +616,23 @@ class TestAuthTktCookieHelper(unittest.TestCase): self.assertEqual(environ['REMOTE_USER_DATA'],'') self.assertEqual(environ['AUTH_TYPE'],'cookie') + def test_identify_good_cookie_include_ipv6(self): + helper = self._makeOne('secret', include_ip=True) + request = self._makeRequest('ticket', ipv6=True) + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], 'userid') + self.assertEqual(result['userdata'], '') + self.assertEqual(result['timestamp'], 0) + self.assertEqual(helper.auth_tkt.value, 'ticket') + self.assertEqual(helper.auth_tkt.remote_addr, '::1') + self.assertEqual(helper.auth_tkt.secret, 'secret') + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + def test_identify_good_cookie_dont_include_ip(self): helper = self._makeOne('secret', include_ip=False) request = self._makeRequest('ticket') -- cgit v1.2.3 From 54d31379c1c10879ba89b6616b033152d9bb69bf Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 1 Feb 2013 18:30:42 -0700 Subject: Add tests for AuthTicket/parse_ticket for IPv6 compat Add some simple tests that test IPv6 compatibility with the AuthTicket class and the parse_ticket function. --- pyramid/tests/test_authentication.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pyramid/tests/test_authentication.py b/pyramid/tests/test_authentication.py index 37e088934..cfabf9a9d 100644 --- a/pyramid/tests/test_authentication.py +++ b/pyramid/tests/test_authentication.py @@ -1119,6 +1119,20 @@ class TestAuthTicket(unittest.TestCase): self.assertEqual(result, '66f9cc3e423dc57c91df696cf3d1f0d80000000auserid!a,b!') + def test_ipv4(self): + ticket = self._makeOne('secret', 'userid', '198.51.100.1', + time=10, hashalg='sha256') + result = ticket.cookie_value() + self.assertEqual(result, 'b3e7156db4f8abde4439c4a6499a0668f9e7ffd7fa27b'\ + '798400ecdade8d76c530000000auserid!') + + def test_ipv6(self): + ticket = self._makeOne('secret', 'userid', '2001:db8::1', + time=10, hashalg='sha256') + result = ticket.cookie_value() + self.assertEqual(result, 'd025b601a0f12ca6d008aa35ff3a22b7d8f3d1c1456c8'\ + '5becf8760cd7a2fa4910000000auserid!') + class TestBadTicket(unittest.TestCase): def _makeOne(self, msg, expected=None): from pyramid.authentication import BadTicket @@ -1162,6 +1176,19 @@ class Test_parse_ticket(unittest.TestCase): result = self._callFUT('secret', ticket, '0.0.0.0', 'sha512') self.assertEqual(result, (10, 'userid', ['a', 'b'], '')) + def test_ipv4(self): + ticket = 'b3e7156db4f8abde4439c4a6499a0668f9e7ffd7fa27b798400ecdade8d7'\ + '6c530000000auserid!' + result = self._callFUT('secret', ticket, '198.51.100.1', 'sha256') + self.assertEqual(result, (10, 'userid', [''], '')) + + def test_ipv6(self): + ticket = 'd025b601a0f12ca6d008aa35ff3a22b7d8f3d1c1456c85becf8760cd7a2f'\ + 'a4910000000auserid!' + result = self._callFUT('secret', ticket, '2001:db8::1', 'sha256') + self.assertEqual(result, (10, 'userid', [''], '')) + pass + class TestSessionAuthenticationPolicy(unittest.TestCase): def _getTargetClass(self): from pyramid.authentication import SessionAuthenticationPolicy -- cgit v1.2.3 From c0151a32b4cf30fe58dbe63f2c58f1f862c3f82e Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 1 Feb 2013 18:33:23 -0700 Subject: Fix IPv6 compatibility in calculate_digest() This is a quick fix for adding IPv6 compatibility so that if the AuthTktAuthenticationPolicy is used with include_ip enabled then it won't throw an error. --- pyramid/authentication.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/pyramid/authentication.py b/pyramid/authentication.py index 190298f98..43353f3e2 100644 --- a/pyramid/authentication.py +++ b/pyramid/authentication.py @@ -740,9 +740,17 @@ def calculate_digest(ip, timestamp, secret, userid, tokens, user_data, tokens = bytes_(tokens, 'utf-8') user_data = bytes_(user_data, 'utf-8') hash_obj = hashlib.new(hashalg) - hash_obj.update( - encode_ip_timestamp(ip, timestamp) + secret + userid + b'\0' - + tokens + b'\0' + user_data) + + # Check to see if this is an IPv6 address + if ':' in ip: + ip_timestamp = ip + str(int(timestamp)) + ip_timestamp = bytes_(ip_timestamp) + else: + # encode_ip_timestamp not required, left in for backwards compatibility + ip_timestamp = encode_ip_timestamp(ip, timestamp) + + hash_obj.update(ip_timestamp + secret + userid + b'\0' + + tokens + b'\0' + user_data) digest = hash_obj.hexdigest() hash_obj2 = hashlib.new(hashalg) hash_obj2.update(bytes_(digest) + secret) -- cgit v1.2.3 From 4b711020a33bcbcc931132c2333d9c819dbac344 Mon Sep 17 00:00:00 2001 From: Bert JW Regeer Date: Fri, 1 Feb 2013 18:38:00 -0700 Subject: Sign CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 971c172f8..02fb81528 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -192,3 +192,5 @@ Contributors - Robert Jackiewicz, 2012/11/12 - John Anderson, 2012/11/14 + +- Bert JW Regeer, 2013/02/01 -- cgit v1.2.3