components/openstack/keystone/patches/08-CVE-2014-3621.patch
changeset 4063 12e03e5492b8
parent 4062 f45bb9cec48c
parent 4061 5ac5027dc3e3
--- a/components/openstack/keystone/patches/08-CVE-2014-3621.patch	Fri Mar 20 22:56:27 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-This upstream patch addresses CVE-2014-3621 and is tracked under
-Launchpad bug 1354208.  It is addressed in Icehouse 2014.1.3 and
-Havana 2013.2.4
-
-From 52714633c9a4dae5e60279217090859aa6dbcb4f Mon Sep 17 00:00:00 2001
-From: David Stanek <[email protected]>
-Date: Fri, 15 Aug 2014 13:30:33 -0500
-Subject: [PATCH] Adds a whitelist for endpoint catalog substitution
-
-Change-Id: If02327d70d0143d805969fe927898f08eb84c4c2
-Closes-Bug: #1354208
----
- etc/keystone.conf.sample                 |    7 ++++
- keystone/catalog/core.py                 |    4 ++
- keystone/common/config.py                |   14 ++++++-
- keystone/common/utils.py                 |   12 ++++++
- keystone/tests/unit/catalog/test_core.py |   62 ++++++++++++++++++++++++++++++
- 5 files changed, 97 insertions(+), 2 deletions(-)
- create mode 100644 keystone/tests/unit/__init__.py
- create mode 100644 keystone/tests/unit/catalog/__init__.py
- create mode 100644 keystone/tests/unit/catalog/test_core.py
-
-diff --git a/etc/keystone.conf.sample b/etc/keystone.conf.sample
-index d7e1c44..c24f8ff 100644
---- a/etc/keystone.conf.sample
-+++ b/etc/keystone.conf.sample
-@@ -190,6 +190,13 @@
- 
- # template_file = default_catalog.templates
- 
-+# (Deprecated) List of possible substitutions for use in
-+# formatting endpoints. Use caution when modifying this list.
-+# It will give users with permission to create endpoints the
-+# ability to see those values in your configuration file. This
-+# option will be removed in Juno. (list value)
-+#endpoint_substitution_whitelist=tenant_id,user_id,public_bind_host,admin_bind_hostompute_hostompute_port,admin_port,public_port,public_endpoint,admin_endpoint
-+
- [endpoint_filter]
- # extension for creating associations between project and endpoints in order to
- # provide a tailored catalog for project-scoped token requests.
-diff --git a/keystone/catalog/core.py b/keystone/catalog/core.py
-index 7cc49d5..ebd56ed 100644
---- a/keystone/catalog/core.py
-+++ b/keystone/catalog/core.py
-@@ -19,6 +19,7 @@
- 
- from keystone.common import dependency
- from keystone.common import manager
-+from keystone.common import utils
- from keystone import config
- from keystone import exception
- from keystone.openstack.common import log as logging
-@@ -30,6 +31,9 @@ LOG = logging.getLogger(__name__)
- 
- def format_url(url, data):
-     """Safely string formats a user-defined URL with the given data."""
-+    data = utils.WhiteListedItemFilter(
-+        CONF.catalog.endpoint_substitution_whitelist,
-+        data)
-     try:
-         result = url.replace('$(', '%(') % data
-     except AttributeError:
-diff --git a/keystone/common/config.py b/keystone/common/config.py
-index f1a7b74..7199c43 100644
---- a/keystone/common/config.py
-+++ b/keystone/common/config.py
-@@ -260,8 +260,18 @@ FILE_OPTIONS = {
-         cfg.StrOpt('template_file',
-                    default='default_catalog.templates'),
-         cfg.StrOpt('driver',
--                   default='keystone.catalog.backends.sql.Catalog')]}
--
-+                   default='keystone.catalog.backends.sql.Catalog'),
-+        cfg.ListOpt('endpoint_substitution_whitelist',
-+                    default=['tenant_id', 'user_id', 'public_bind_host',
-+                             'admin_bind_host', 'compute_host', 'compute_port',
-+                             'admin_port', 'public_port', 'public_endpoint',
-+                             'admin_endpoint'],
-+                    help='(Deprecated) List of possible substitutions for use '
-+                         'in formatting endpoints. Use caution when modifying '
-+                         'this list. It will give users with permission to '
-+                         'create endpoints the ability to see those values '
-+                         'in your configuration file. This option will be '
-+                         'removed in Juno.')]}
- 
- CONF = cfg.CONF
- 
-diff --git a/keystone/common/utils.py b/keystone/common/utils.py
-index 402f8a2..3d4a62a 100644
---- a/keystone/common/utils.py
-+++ b/keystone/common/utils.py
-@@ -516,3 +516,15 @@ def make_dirs(path, mode=None, user=None, group=None, log=None):
-             raise EnvironmentError("makedirs('%s'): %s" % (path, exc.strerror))
- 
-     set_permissions(path, mode, user, group, log)
-+
-+
-+class WhiteListedItemFilter(object):
-+
-+    def __init__(self, whitelist, data):
-+        self._whitelist = set(whitelist or [])
-+        self._data = data
-+
-+    def __getitem__(self, name):
-+        if name not in self._whitelist:
-+            raise KeyError
-+        return self._data[name]
-diff --git a/keystone/tests/unit/__init__.py b/keystone/tests/unit/__init__.py
-new file mode 100644
-index 0000000..e69de29
-diff --git a/keystone/tests/unit/catalog/__init__.py b/keystone/tests/unit/catalog/__init__.py
-new file mode 100644
-index 0000000..e69de29
-diff --git a/keystone/tests/unit/catalog/test_core.py b/keystone/tests/unit/catalog/test_core.py
-new file mode 100644
-index 0000000..b4372b9
---- /dev/null
-+++ b/keystone/tests/unit/catalog/test_core.py
-@@ -0,0 +1,62 @@
-+# Licensed under the Apache License, Version 2.0 (the "License"); you may
-+# not use this file except in compliance with the License. You may obtain
-+# a copy of the License at
-+#
-+#      http://www.apache.org/licenses/LICENSE-2.0
-+#
-+# Unless required by applicable law or agreed to in writing, software
-+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-+# License for the specific language governing permissions and limitations
-+# under the License.
-+
-+from keystone.catalog import core
-+from keystone import config
-+from keystone import exception
-+from keystone import tests
-+
-+
-+CONF = config.CONF
-+
-+
-+class FormatUrlTests(tests.TestCase):
-+
-+    def setUp(self):
-+        super(FormatUrlTests, self).setUp()
-+        whitelist = ['host', 'port', 'part1', 'part2']
-+        self.opt_in_group('catalog', endpoint_substitution_whitelist=whitelist)
-+
-+    def test_successful_formatting(self):
-+        url_template = 'http://%(host)s:%(port)d/%(part1)s/%(part2)s'
-+        values = {'host': 'server', 'port': 9090, 'part1': 'A', 'part2': 'B'}
-+        actual_url = core.format_url(url_template, values)
-+
-+        expected_url = 'http://server:9090/A/B'
-+        self.assertEqual(actual_url, expected_url)
-+
-+    def test_raises_malformed_on_missing_key(self):
-+        self.assertRaises(exception.MalformedEndpoint,
-+                          core.format_url,
-+                          "http://%(foo)s/%(bar)s",
-+                          {"foo": "1"})
-+
-+    def test_raises_malformed_on_wrong_type(self):
-+        self.assertRaises(exception.MalformedEndpoint,
-+                          core.format_url,
-+                          "http://%foo%s",
-+                          {"foo": "1"})
-+
-+    def test_raises_malformed_on_incomplete_format(self):
-+        self.assertRaises(exception.MalformedEndpoint,
-+                          core.format_url,
-+                          "http://%(foo)",
-+                          {"foo": "1"})
-+
-+    def test_substitution_with_key_not_whitelisted(self):
-+        url_template = 'http://%(host)s:%(port)d/%(part1)s/%(part2)s/%(part3)s'
-+        values = {'host': 'server', 'port': 9090,
-+                  'part1': 'A', 'part2': 'B', 'part3': 'C'}
-+        self.assertRaises(exception.MalformedEndpoint,
-+                          core.format_url,
-+                          url_template,
-+                          values)
--- 
-1.7.9.5
-