components/openstack/keystone/patches/03-CVE-2013-6391.patch
branchs11-update
changeset 3178 77584387a894
parent 3175 1ff833d174d4
child 3179 07c03b663108
--- a/components/openstack/keystone/patches/03-CVE-2013-6391.patch	Wed Jun 11 05:34:04 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-Upstream patch fixed in Havana 2013.2
-
-commit 8fcc18c42bde2db34e4b29236dc2e971d40f146b
-Author: Steven Hardy <[email protected]>
-Date:   Sun Oct 13 10:44:52 2013 +0100
-
-    Fix v2 token user ref with trust impersonation=True
-    
-    The v2 token controller incorrectly checks for a string instead
-    of a boolean, which results in the wrong user ID (trustee, when
-    it should be the trustor) when impersonation=True.  So fix the
-    comparison and tests, adding a test which illustrates the issue.
-    
-    This patchset also closes the gap that allows EC2 credentials to
-    be issued from trust-scoped tokens, allowing privilege escalation
-    since EC2 tokens have no concept of trust-scoping/role
-    restrictions in the Grizzly release.
-    
-    Change-Id: Ic94f30f2354c9fda20531bb598387368fde8a096
-    Closes-Bug: #1239303
-    Related-Bug: #1242597
-
-diff --git a/keystone/contrib/ec2/core.py b/keystone/contrib/ec2/core.py
-index 246587a..2ef9820 100644
---- a/keystone/contrib/ec2/core.py
-+++ b/keystone/contrib/ec2/core.py
-@@ -207,6 +207,9 @@ class Ec2Controller(controller.V2Controller):
-         if not self._is_admin(context):
-             self._assert_identity(context, user_id)
- 
-+        # Disallow trust-scoped tokens from creating credentials.
-+        self._assert_not_trust_scoped(context)
-+
-         self._assert_valid_user_id(context, user_id)
-         self._assert_valid_project_id(context, tenant_id)
- 
-@@ -308,6 +311,22 @@ class Ec2Controller(controller.V2Controller):
-         except exception.Forbidden:
-             return False
- 
-+    def _assert_not_trust_scoped(self, context):
-+        try:
-+            token_ref = self.token_api.get_token(
-+                context, token_id=context['token_id'])
-+        except exception.TokenNotFound as e:
-+            raise exception.Unauthorized(e)
-+
-+        # NOTE(morganfainberg): In Grizzly, it is not allowed to use a
-+        # trust scoped token to create an EC2 credential, this is due to
-+        # privilege escalation possibility (there is no way to correlate
-+        # the trust to the EC2 credential and limit roles to the trust).
-+        if 'trust' in token_ref:
-+            raise exception.Forbidden()
-+        if 'trust_id' in token_ref.get('metadata', {}):
-+            raise exception.Forbidden()
-+
-     def _assert_owner(self, context, user_id, credential_id):
-         """Ensure the provided user owns the credential.
- 
-diff --git a/keystone/token/controllers.py b/keystone/token/controllers.py
-index 1ae1d4f..e42ca7d 100644
---- a/keystone/token/controllers.py
-+++ b/keystone/token/controllers.py
-@@ -201,7 +201,7 @@ class Auth(controller.V2Controller):
-                 context, trust_ref['trustee_user_id'])
-             if not trustee_user_ref['enabled']:
-                 raise exception.Forbidden()()
--            if trust_ref['impersonation'] == 'True':
-+            if trust_ref['impersonation'] is True:
-                 current_user_ref = trustor_user_ref
-             else:
-                 current_user_ref = trustee_user_ref
-diff --git a/tests/test_auth.py b/tests/test_auth.py
-index 3d4ec87..8a810a4 100644
---- a/tests/test_auth.py
-+++ b/tests/test_auth.py
-@@ -19,6 +19,7 @@ import uuid
- 
- from keystone import auth
- from keystone import config
-+from keystone.contrib import ec2
- from keystone import exception
- from keystone import identity
- from keystone.openstack.common import timeutils
-@@ -517,7 +518,7 @@ class AuthWithTrust(AuthTest):
-         self.sample_data = {'trustor_user_id': self.trustor['id'],
-                             'trustee_user_id': self.trustee['id'],
-                             'project_id': self.tenant_bar['id'],
--                            'impersonation': 'True',
-+                            'impersonation': True,
-                             'roles': [{'id': self.role_browser['id']},
-                                       {'name': self.role_member['name']}]}
-         expires_at = timeutils.strtime(timeutils.utcnow() +
-@@ -525,7 +526,7 @@ class AuthWithTrust(AuthTest):
-                                        fmt=TIME_FORMAT)
-         self.create_trust(expires_at=expires_at)
- 
--    def create_trust(self, expires_at=None, impersonation='True'):
-+    def create_trust(self, expires_at=None, impersonation=True):
-         username = self.trustor['name'],
-         password = 'foo2'
-         body_dict = _build_user_auth(username=username, password=password)
-@@ -586,20 +587,42 @@ class AuthWithTrust(AuthTest):
-             self.assertIn(role['id'], role_ids)
- 
-     def test_create_trust_no_impersonation(self):
--        self.create_trust(expires_at=None, impersonation='False')
-+        self.create_trust(expires_at=None, impersonation=False)
-         self.assertEquals(self.new_trust['trustor_user_id'],
-                           self.trustor['id'])
-         self.assertEquals(self.new_trust['trustee_user_id'],
-                           self.trustee['id'])
--        self.assertEquals(self.new_trust['impersonation'],
--                          'False')
-+        self.assertIs(self.new_trust['impersonation'], False)
-         auth_response = self.fetch_v2_token_from_trust()
-         token_user = auth_response['access']['user']
-         self.assertEquals(token_user['id'],
-                           self.new_trust['trustee_user_id'])
--
-         #TODO Endpoints
- 
-+    def test_create_trust_impersonation(self):
-+        self.create_trust(expires_at=None)
-+        self.assertEqual(self.new_trust['trustor_user_id'], self.trustor['id'])
-+        self.assertEqual(self.new_trust['trustee_user_id'], self.trustee['id'])
-+        self.assertIs(self.new_trust['impersonation'], True)
-+        auth_response = self.fetch_v2_token_from_trust()
-+        token_user = auth_response['access']['user']
-+        self.assertEqual(token_user['id'], self.new_trust['trustor_user_id'])
-+
-+    def test_disallow_ec2_credential_from_trust_scoped_token(self):
-+        ec2_manager = ec2.Manager()
-+        self.ec2_controller = ec2.Ec2Controller()
-+        self.test_create_trust_impersonation()
-+        auth_response = self.fetch_v2_token_from_trust()
-+        # ensure it is not possible to create an ec2 token from a trust
-+        context = {'token_id': auth_response['access']['token']['id'],
-+                   'is_admin': False}
-+
-+        self.assertRaises(exception.Forbidden,
-+                          self.ec2_controller.create_credential,
-+                          context=context,
-+                          user_id=self.user_foo['id'],
-+                          tenant_id=self.tenant_bar['id'])
-+
-     def test_token_from_trust_wrong_user_fails(self):
-         new_trust = self.create_trust()
-         request_body = self.build_v2_token_request('FOO', 'foo2')