1 |
prometheanfire 13/05/28 16:34:39 |
2 |
|
3 |
Added: keystone-folsom-4-CVE-2013-2104.patch |
4 |
Log: |
5 |
fix for keystone 2012.2.4 CVE-2013-2104 |
6 |
|
7 |
(Portage version: 2.1.11.62/cvs/Linux x86_64, signed Manifest commit with key 0x2471eb3e40ac5ac3) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 sys-auth/keystone/files/keystone-folsom-4-CVE-2013-2104.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-auth/keystone/files/keystone-folsom-4-CVE-2013-2104.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-auth/keystone/files/keystone-folsom-4-CVE-2013-2104.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: keystone-folsom-4-CVE-2013-2104.patch |
16 |
=================================================================== |
17 |
From 1d15ee512d0bebba23bdb997ae839bd6ab5d9317 Mon Sep 17 00:00:00 2001 |
18 |
From: Adam Young <ayoung@××××××.com> |
19 |
Date: Mon, 13 May 2013 16:07:51 -0400 |
20 |
Subject: [PATCH] Check token Expiration |
21 |
|
22 |
Backport for Folsom. |
23 |
|
24 |
Bug 1179615 |
25 |
|
26 |
Change-Id: I8516d87ffc72cf35d3bff6fc21cb5324da4ad2bb |
27 |
--- |
28 |
keystone/middleware/auth_token.py | 26 +++++++++++------- |
29 |
tests/signing/Makefile | 2 +- |
30 |
tests/signing/auth_token_revoked.pem | 10 +++---- |
31 |
tests/signing/auth_token_scoped_expired.json | 1 + |
32 |
tests/signing/auth_token_scoped_expired.pem | 40 ++++++++++++++++++++++++++++ |
33 |
tests/test_auth_token_middleware.py | 10 +++++++ |
34 |
6 files changed, 74 insertions(+), 15 deletions(-) |
35 |
create mode 100644 tests/signing/auth_token_scoped_expired.json |
36 |
create mode 100644 tests/signing/auth_token_scoped_expired.pem |
37 |
|
38 |
diff --git a/keystone/middleware/auth_token.py b/keystone/middleware/auth_token.py |
39 |
index 01e6c58..f5e631a 100644 |
40 |
--- a/keystone/middleware/auth_token.py |
41 |
+++ b/keystone/middleware/auth_token.py |
42 |
@@ -512,7 +512,8 @@ class AuthProtocol(object): |
43 |
data = json.loads(verified) |
44 |
else: |
45 |
data = self.verify_uuid_token(user_token, retry) |
46 |
- self._cache_put(token_id, data) |
47 |
+ expires = self._confirm_token_not_expired(data) |
48 |
+ self._cache_put(token_id, data, expires) |
49 |
return data |
50 |
except Exception as e: |
51 |
LOG.debug('Token validation failure.', exc_info=True) |
52 |
@@ -642,7 +643,19 @@ class AuthProtocol(object): |
53 |
else: |
54 |
LOG.debug('Cached Token %s seems expired', token) |
55 |
|
56 |
- def _cache_put(self, token, data): |
57 |
+ def _confirm_token_not_expired(self, data): |
58 |
+ if 'token' in data.get('access', {}): |
59 |
+ timestamp = data['access']['token']['expires'] |
60 |
+ expires = self._iso8601.parse_date(timestamp).strftime('%s') |
61 |
+ else: |
62 |
+ LOG.error('invalid token format') |
63 |
+ raise InvalidUserToken('Token authorization failed') |
64 |
+ if time.time() >= float(expires): |
65 |
+ self.LOG.debug('Token expired a %s', timestamp) |
66 |
+ raise InvalidUserToken('Token authorization failed') |
67 |
+ return expires |
68 |
+ |
69 |
+ def _cache_put(self, token, data, expires): |
70 |
"""Put token data into the cache. |
71 |
|
72 |
Stores the parsed expire date in cache allowing |
73 |
@@ -650,12 +663,6 @@ class AuthProtocol(object): |
74 |
""" |
75 |
if self._cache and data: |
76 |
key = 'tokens/%s' % token |
77 |
- if 'token' in data.get('access', {}): |
78 |
- timestamp = data['access']['token']['expires'] |
79 |
- expires = self._iso8601.parse_date(timestamp).strftime('%s') |
80 |
- else: |
81 |
- LOG.error('invalid token format') |
82 |
- return |
83 |
LOG.debug('Storing %s token in memcache', token) |
84 |
self._cache.set(key, |
85 |
(data, expires), |
86 |
@@ -693,7 +700,8 @@ class AuthProtocol(object): |
87 |
additional_headers=headers) |
88 |
|
89 |
if response.status == 200: |
90 |
- self._cache_put(user_token, data) |
91 |
+ expires = self._confirm_token_not_expired(data) |
92 |
+ self._cache_put(user_token, data, expires) |
93 |
return data |
94 |
if response.status == 404: |
95 |
# FIXME(ja): I'm assuming the 404 status means that user_token is |
96 |
diff --git a/tests/signing/Makefile b/tests/signing/Makefile |
97 |
index b56c000..27f5ff8 100644 |
98 |
--- a/tests/signing/Makefile |
99 |
+++ b/tests/signing/Makefile |
100 |
@@ -19,7 +19,7 @@ |
101 |
|
102 |
.SUFFIXES: .json .pem |
103 |
|
104 |
-SOURCES=auth_token_unscoped.json auth_token_scoped.json revocation_list.json |
105 |
+SOURCES=auth_token_unscoped.json auth_token_scoped.json auth_token_scoped.json auth_token_scoped_expired.json revocation_list.json |
106 |
SIGNED=$(SOURCES:.json=.pem) |
107 |
TARGETS=$(SIGNED) |
108 |
|
109 |
diff --git a/tests/signing/auth_token_revoked.pem b/tests/signing/auth_token_revoked.pem |
110 |
index 186c080..27cef18 100644 |
111 |
--- a/tests/signing/auth_token_revoked.pem |
112 |
+++ b/tests/signing/auth_token_revoked.pem |
113 |
@@ -24,7 +24,7 @@ MC4wLjE6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVy |
114 |
bmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUzNTcvdjIuMCIsICJwdWJsaWNV |
115 |
UkwiOiAiaHR0cDovLzEyNy4wLjAuMTo1MDAwL3YyLjAifV0sICJlbmRwb2ludHNf |
116 |
bGlua3MiOiBbXSwgInR5cGUiOiAiaWRlbnRpdHkiLCAibmFtZSI6ICJrZXlzdG9u |
117 |
-ZSJ9XSwidG9rZW4iOiB7ImV4cGlyZXMiOiAiMjAxMi0wNi0wMlQxNDo0NzozNFoi |
118 |
+ZSJ9XSwidG9rZW4iOiB7ImV4cGlyZXMiOiAiMjExMi0wNi0wMlQxNDo0NzozNFoi |
119 |
LCAiaWQiOiAicGxhY2Vob2xkZXIiLCAidGVuYW50IjogeyJlbmFibGVkIjogdHJ1 |
120 |
ZSwgImRlc2NyaXB0aW9uIjogbnVsbCwgIm5hbWUiOiAidGVuYW50X25hbWUxIiwg |
121 |
ImlkIjogInRlbmFudF9pZDEifX0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJyZXZv |
122 |
@@ -33,8 +33,8 @@ LCAiaWQiOiAicmV2b2tlZF91c2VyX2lkMSIsICJyb2xlcyI6IFt7Im5hbWUiOiAi |
123 |
cm9sZTEifSwgeyJuYW1lIjogInJvbGUyIn1dLCAibmFtZSI6ICJyZXZva2VkX3Vz |
124 |
ZXJuYW1lMSJ9fX0NCjGB9zCB9AIBATBUME8xFTATBgNVBAoTDFJlZCBIYXQsIElu |
125 |
YzERMA8GA1UEBxMIV2VzdGZvcmQxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxCzAJ |
126 |
-BgNVBAYTAlVTAgEBMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIGAXstA+yZ5N/cS |
127 |
-+i7Mmlhi585cckvwSVAGj9huPTpqBItpbO44+U3yUojEwcghomtpygI/wzUa8Z40 |
128 |
-UW/L3nGlATlOG833zhGvLKrp76GIitYMgk1e0OEmzGXeAWLnQZFev8ooMPs9rwYW |
129 |
-MgEdAfDMWWqX+Tb7exdboLpRUiCQx1c= |
130 |
+BgNVBAYTAlVTAgEBMAcGBSsOAwIaMA0GCSqGSIb3DQEBAQUABIGAdnQ5zU60aOc+ |
131 |
+TGK+5ESmYbOllqe7QGkcB2fWzuiIY4/9l53X0m3ThYNzxeloJ0NgETLWoHO24xIi |
132 |
+YoCUtAGP8BQI0D21Amg4Nb3jBxiwObzdONytEpAYOXxMq8pDMgboi8eU0esch1jJ |
133 |
+r+9/uR3R/xksWkPtPsl+qnt/KpUsL+A= |
134 |
-----END CMS----- |
135 |
diff --git a/tests/signing/auth_token_scoped_expired.json b/tests/signing/auth_token_scoped_expired.json |
136 |
new file mode 100644 |
137 |
index 0000000..d36d8cf |
138 |
--- /dev/null |
139 |
+++ b/tests/signing/auth_token_scoped_expired.json |
140 |
@@ -0,0 +1 @@ |
141 |
+{"access": {"serviceCatalog": [{"endpoints": [{"adminURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", "region": "regionOne", "internalURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a", "publicURL": "http://127.0.0.1:8776/v1/64b6f3fbcc53435e8a60fcf89bb6617a"}], "endpoints_links": [], "type": "volume", "name": "volume"}, {"endpoints": [{"adminURL": "http://127.0.0.1:9292/v1", "region": "regionOne", "internalURL": "http://127.0.0.1:9292/v1", "publicURL": "http://127.0.0.1:9292/v1"}], "endpoints_links": [], "type": "image", "name": "glance"}, {"endpoints": [{"adminURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", "region": "regionOne", "internalURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a", "publicURL": "http://127.0.0.1:8774/v1.1/64b6f3fbcc53435e8a60fcf89bb6617a"}], "endpoints_links": [], "type": "compute", "name": "nova"}, {"endpoints": [{"adminURL": "http://127.0.0.1:35357/v2.0", "region": "RegionOne", "intern |
142 |
alURL": "http://127.0.0.1:35357/v2.0", "publicURL": "http://127.0.0.1:5000/v2.0"}], "endpoints_links": [], "type": "identity", "name": "keystone"}],"token": {"expires": "2010-06-02T14:47:34Z", "id": "placeholder", "tenant": {"enabled": true, "description": null, "name": "tenant_name1", "id": "tenant_id1"}}, "user": {"username": "user_name1", "roles_links": ["role1","role2"], "id": "user_id1", "roles": [{"name": "role1"}, {"name": "role2"}], "name": "user_name1"}}} |
143 |
diff --git a/tests/signing/auth_token_scoped_expired.pem b/tests/signing/auth_token_scoped_expired.pem |
144 |
new file mode 100644 |
145 |
index 0000000..8116b11 |
146 |
--- /dev/null |
147 |
+++ b/tests/signing/auth_token_scoped_expired.pem |
148 |
@@ -0,0 +1,40 @@ |
149 |
+-----BEGIN CMS----- |
150 |
+MIIG9QYJKoZIhvcNAQcCoIIG5jCCBuICAQExCTAHBgUrDgMCGjCCBc4GCSqGSIb3 |
151 |
+DQEHAaCCBb8EggW7eyJhY2Nlc3MiOiB7InNlcnZpY2VDYXRhbG9nIjogW3siZW5k |
152 |
+cG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2L3Yx |
153 |
+LzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInJlZ2lvbiI6ICJy |
154 |
+ZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2 |
155 |
+L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInB1YmxpY1VS |
156 |
+TCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3NzYvdjEvNjRiNmYzZmJjYzUzNDM1ZThh |
157 |
+NjBmY2Y4OWJiNjYxN2EifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUi |
158 |
+OiAidm9sdW1lIiwgIm5hbWUiOiAidm9sdW1lIn0sIHsiZW5kcG9pbnRzIjogW3si |
159 |
+YWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo5MjkyL3YxIiwgInJlZ2lvbiI6 |
160 |
+ICJyZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo5 |
161 |
+MjkyL3YxIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjkyOTIvdjEi |
162 |
+fV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiaW1hZ2UiLCAibmFt |
163 |
+ZSI6ICJnbGFuY2UifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRw |
164 |
+Oi8vMTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5 |
165 |
+YmI2NjE3YSIsICJyZWdpb24iOiAicmVnaW9uT25lIiwgImludGVybmFsVVJMIjog |
166 |
+Imh0dHA6Ly8xMjcuMC4wLjE6ODc3NC92MS4xLzY0YjZmM2ZiY2M1MzQzNWU4YTYw |
167 |
+ZmNmODliYjY2MTdhIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3 |
168 |
+NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSJ9XSwgImVu |
169 |
+ZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAi |
170 |
+bm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xMjcu |
171 |
+MC4wLjE6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVy |
172 |
+bmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUzNTcvdjIuMCIsICJwdWJsaWNV |
173 |
+UkwiOiAiaHR0cDovLzEyNy4wLjAuMTo1MDAwL3YyLjAifV0sICJlbmRwb2ludHNf |
174 |
+bGlua3MiOiBbXSwgInR5cGUiOiAiaWRlbnRpdHkiLCAibmFtZSI6ICJrZXlzdG9u |
175 |
+ZSJ9XSwidG9rZW4iOiB7ImV4cGlyZXMiOiAiMjAxMC0wNi0wMlQxNDo0NzozNFoi |
176 |
+LCAiaWQiOiAicGxhY2Vob2xkZXIiLCAidGVuYW50IjogeyJlbmFibGVkIjogdHJ1 |
177 |
+ZSwgImRlc2NyaXB0aW9uIjogbnVsbCwgIm5hbWUiOiAidGVuYW50X25hbWUxIiwg |
178 |
+ImlkIjogInRlbmFudF9pZDEifX0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJ1c2Vy |
179 |
+X25hbWUxIiwgInJvbGVzX2xpbmtzIjogWyJyb2xlMSIsInJvbGUyIl0sICJpZCI6 |
180 |
+ICJ1c2VyX2lkMSIsICJyb2xlcyI6IFt7Im5hbWUiOiAicm9sZTEifSwgeyJuYW1l |
181 |
+IjogInJvbGUyIn1dLCAibmFtZSI6ICJ1c2VyX25hbWUxIn19fQ0KMYH/MIH8AgEB |
182 |
+MFwwVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVVuc2V0MQ4wDAYDVQQHEwVVbnNl |
183 |
+dDEOMAwGA1UEChMFVW5zZXQxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbQIBATAH |
184 |
+BgUrDgMCGjANBgkqhkiG9w0BAQEFAASBgJP+wKRwFaPY8xXAolDd6gmlID41yuAw |
185 |
+nd+IKeD54Ack0NI9h/M0Iv2LzTo0l84VbMOijmq++kbtdnDJ2pn4VAoNk7dQcTTy |
186 |
+lz2c78Xnu0NXvq7gsPRF4zDtIpjHbUXJ3ZRPHs342suG7Tb4nvQAbxYMJQHSN10k |
187 |
+W6w+gEeN7t7V |
188 |
+-----END CMS----- |
189 |
diff --git a/tests/test_auth_token_middleware.py b/tests/test_auth_token_middleware.py |
190 |
index e6893ee..dfe424f 100644 |
191 |
--- a/tests/test_auth_token_middleware.py |
192 |
+++ b/tests/test_auth_token_middleware.py |
193 |
@@ -154,6 +154,9 @@ def setUpModule(self): |
194 |
signing_path = os.path.join(os.path.dirname(__file__), 'signing') |
195 |
with open(os.path.join(signing_path, 'auth_token_scoped.pem')) as f: |
196 |
self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read()) |
197 |
+ with open(os.path.join(signing_path, |
198 |
+ 'auth_token_scoped_expired.pem')) as f: |
199 |
+ self.SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read()) |
200 |
with open(os.path.join(signing_path, 'auth_token_unscoped.pem')) as f: |
201 |
self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read()) |
202 |
with open(os.path.join(signing_path, 'auth_token_revoked.pem')) as f: |
203 |
@@ -612,6 +615,13 @@ class AuthTokenMiddlewareTest(BaseAuthTokenMiddlewareTest): |
204 |
self.middleware(req.environ, self.start_fake_response) |
205 |
self.assertEqual(self.middleware._cache.set_value, None) |
206 |
|
207 |
+ def test_expired(self): |
208 |
+ req = webob.Request.blank('/') |
209 |
+ token = SIGNED_TOKEN_SCOPED_EXPIRED |
210 |
+ req.headers['X-Auth-Token'] = token |
211 |
+ self.middleware(req.environ, self.start_fake_response) |
212 |
+ self.assertEqual(self.response_status, 401) |
213 |
+ |
214 |
def test_memcache_set_invalid(self): |
215 |
req = webob.Request.blank('/') |
216 |
req.headers['X-Auth-Token'] = 'invalid-token' |
217 |
-- |
218 |
1.8.1.5 |