diff options
Diffstat (limited to 'sys-auth/keystone/files/keystone-cve-2013-4294-folsom.patch')
-rw-r--r-- | sys-auth/keystone/files/keystone-cve-2013-4294-folsom.patch | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/sys-auth/keystone/files/keystone-cve-2013-4294-folsom.patch b/sys-auth/keystone/files/keystone-cve-2013-4294-folsom.patch new file mode 100644 index 000000000000..2d9e9b5a1ea4 --- /dev/null +++ b/sys-auth/keystone/files/keystone-cve-2013-4294-folsom.patch @@ -0,0 +1,143 @@ +From 8ef8be4af315d50edd661d8a5e846d260a5a3ce2 Mon Sep 17 00:00:00 2001 +From: Morgan Fainberg <m@metacloud.com> +Date: Fri, 23 Aug 2013 14:10:28 -0700 +Subject: [PATCH] Fix and test token revocation list API + +Change-Id: I07257b3704895a2af2654aa863f0b910122666da +--- + keystone/token/backends/kvs.py | 2 +- + keystone/token/backends/memcache.py | 12 ++++++---- + tests/test_backend.py | 48 +++++++++++++++++++++++++++++++++---- + 3 files changed, 51 insertions(+), 11 deletions(-) + +diff --git a/keystone/token/backends/kvs.py b/keystone/token/backends/kvs.py +index 123e12f..e5e0ee2 100644 +--- a/keystone/token/backends/kvs.py ++++ b/keystone/token/backends/kvs.py +@@ -81,7 +81,7 @@ class Token(kvs.Base, token.Driver): + if not token.startswith('revoked-token-'): + continue + record = {} +- record['id'] = token_ref['id'] ++ record['id'] = token[len('revoked-token-'):] + record['expires'] = token_ref['expires'] + tokens.append(record) + return tokens +diff --git a/keystone/token/backends/memcache.py b/keystone/token/backends/memcache.py +index e4fa69a..815c392 100644 +--- a/keystone/token/backends/memcache.py ++++ b/keystone/token/backends/memcache.py +@@ -82,8 +82,9 @@ class Token(token.Driver): + raise exception.UnexpectedError(msg) + return copy.deepcopy(data_copy) + +- def _add_to_revocation_list(self, data): +- data_json = jsonutils.dumps(data) ++ def _add_to_revocation_list(self, token_id, token_data): ++ data_json = jsonutils.dumps({'id': token_id, ++ 'expires': token_data['expires']}) + if not self.client.append(self.revocation_key, ',%s' % data_json): + if not self.client.add(self.revocation_key, data_json): + if not self.client.append(self.revocation_key, +@@ -93,10 +94,11 @@ class Token(token.Driver): + + def delete_token(self, token_id): + # Test for existence +- data = self.get_token(self.token_to_key(token_id)) +- ptk = self._prefix_token_id(self.token_to_key(token_id)) ++ token_id = self.token_to_key(token_id) ++ data = self.get_token(token_id) ++ ptk = self._prefix_token_id(token_id) + result = self.client.delete(ptk) +- self._add_to_revocation_list(data) ++ self._add_to_revocation_list(token_id, data) + return result + + def list_tokens(self, user_id, tenant_id=None): +diff --git a/tests/test_backend.py b/tests/test_backend.py +index 0a56cdb..3798e37 100644 +--- a/tests/test_backend.py ++++ b/tests/test_backend.py +@@ -14,9 +14,11 @@ + # License for the specific language governing permissions and limitations + # under the License. + ++import copy + import datetime +-import uuid + import default_fixtures ++import hashlib ++import uuid + + from keystone.catalog import core + from keystone import exception +@@ -628,19 +630,29 @@ class IdentityTests(object): + + + class TokenTests(object): ++ def _create_token_id(self): ++ # Token must start with MII here otherwise it fails the asn1 test ++ # and is not hashed in a SQL backend. ++ token_id = "MII" ++ for i in range(1, 20): ++ token_id += uuid.uuid4().hex ++ return token_id ++ + def test_token_crud(self): + token_id = uuid.uuid4().hex + data = {'id': token_id, 'a': 'b', + 'user': {'id': 'testuserid'}} + data_ref = self.token_api.create_token(token_id, data) +- expires = data_ref.pop('expires') ++ data_ref_copy = copy.deepcopy(data_ref) ++ expires = data_ref_copy.pop('expires') + self.assertTrue(isinstance(expires, datetime.datetime)) +- self.assertDictEqual(data_ref, data) ++ self.assertDictEqual(data_ref_copy, data) + + new_data_ref = self.token_api.get_token(token_id) +- expires = new_data_ref.pop('expires') ++ new_data_ref_copy = copy.deepcopy(new_data_ref) ++ expires = new_data_ref_copy.pop('expires') + self.assertTrue(isinstance(expires, datetime.datetime)) +- self.assertEquals(new_data_ref, data) ++ self.assertEquals(new_data_ref_copy, data) + + self.token_api.delete_token(token_id) + self.assertRaises(exception.TokenNotFound, +@@ -758,6 +770,32 @@ class TokenTests(object): + self.check_list_revoked_tokens([self.delete_token() + for x in xrange(2)]) + ++ def test_predictable_revoked_pki_token_id(self): ++ token_id = self._create_token_id() ++ token_id_hash = hashlib.md5(token_id).hexdigest() ++ token = {'user': {'id': uuid.uuid4().hex}} ++ ++ self.token_api.create_token(token_id, token) ++ self.token_api.delete_token(token_id) ++ ++ revoked_ids = [x['id'] for x in self.token_api.list_revoked_tokens()] ++ self.assertIn(token_id_hash, revoked_ids) ++ self.assertNotIn(token_id, revoked_ids) ++ for t in self.token_api.list_revoked_tokens(): ++ self.assertIn('expires', t) ++ ++ def test_predictable_revoked_uuid_token_id(self): ++ token_id = uuid.uuid4().hex ++ token = {'user': {'id': uuid.uuid4().hex}} ++ ++ self.token_api.create_token(token_id, token) ++ self.token_api.delete_token(token_id) ++ ++ revoked_ids = [x['id'] for x in self.token_api.list_revoked_tokens()] ++ self.assertIn(token_id, revoked_ids) ++ for t in self.token_api.list_revoked_tokens(): ++ self.assertIn('expires', t) ++ + + class CommonHelperTests(test.TestCase): + def test_format_helper_raises_malformed_on_missing_key(self): +-- +1.8.2.1 (Apple Git-45) + |