~ubuntu-branches/ubuntu/quantal/keystone/quantal-security

« back to all changes in this revision

Viewing changes to debian/patches/CVE-2013-2104.patch

  • Committer: Package Import Robot
  • Author(s): Jamie Strandboge
  • Date: 2013-06-13 13:42:44 UTC
  • mfrom: (35.1.6 quantal-proposed)
  • Revision ID: package-import@ubuntu.com-20130613134244-mle4ueu39urzeknr
Tags: 2012.2.4-0ubuntu3.1
* SECURITY UPDATE: fix auth_token middleware neglects to check expiry of
  signed token when using PKI
  - debian/patches/CVE-2013-2104.patch: explicitly check the expiry on the
    tokens, and reject tokens that have expired. Also update test data
  - CVE-2013-2104
  - LP: #1179615
* debian/patches/fix-testsuite-for-2038-problem.patch: Adjust json example
  cert data to use 2037 instead of 2112 and regenerate the certs. Also
  adjust token expiry data to use 2037 instead of 2999.
* SECURITY UPDATE: fix authentication bypass when using LDAP backend
  - debian/patches/CVE-2013-2157.patch: identity/backends/ldap/core.py is
    adjusted to raise an assertion for invalid password when using LDAP and
    an empty password is submitted
  - CVE-2013-2157
  - LP: #1187305

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From: Adam Young <ayoung@redhat.com>
 
2
Date: Mon, 13 May 2013 20:07:51 +0000 (-0400)
 
3
Subject: Check token Expiration
 
4
X-Git-Url: https://review.openstack.org/gitweb?p=openstack%2Fkeystone.git;a=commitdiff_plain;h=8d23da1302dde9d38bbc227d9aba30da919b60c8
 
5
 
 
6
Check token Expiration
 
7
 
 
8
Backport for Folsom.
 
9
 
 
10
Bug 1179615
 
11
 
 
12
Change-Id: I8516d87ffc72cf35d3bff6fc21cb5324da4ad2bb
 
13
---
 
14
 
 
15
Index: keystone-2012.2.4/keystone/middleware/auth_token.py
 
16
===================================================================
 
17
--- keystone-2012.2.4.orig/keystone/middleware/auth_token.py    2013-06-10 16:30:52.000000000 -0500
 
18
+++ keystone-2012.2.4/keystone/middleware/auth_token.py 2013-06-10 16:30:52.000000000 -0500
 
19
@@ -95,6 +95,7 @@
 
20
 
 
21
 import datetime
 
22
 import httplib
 
23
+import iso8601
 
24
 import json
 
25
 import logging
 
26
 import os
 
27
@@ -254,13 +255,12 @@
 
28
         self._token_revocation_list_fetched_time = None
 
29
         self.token_revocation_list_cache_timeout = \
 
30
             datetime.timedelta(seconds=0)
 
31
+        self._iso8601 = iso8601
 
32
         if memcache_servers:
 
33
             try:
 
34
                 import memcache
 
35
-                import iso8601
 
36
                 LOG.info('Using memcache for caching token')
 
37
                 self._cache = memcache.Client(memcache_servers.split(','))
 
38
-                self._iso8601 = iso8601
 
39
             except ImportError as e:
 
40
                 LOG.warn('disabled caching due to missing libraries %s', e)
 
41
 
 
42
@@ -507,7 +507,8 @@
 
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
@@ -637,7 +638,19 @@
 
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
+            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
@@ -645,12 +658,6 @@
 
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
@@ -688,7 +695,8 @@
 
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
Index: keystone-2012.2.4/tests/signing/Makefile
 
97
===================================================================
 
98
--- keystone-2012.2.4.orig/tests/signing/Makefile       2013-06-10 16:30:52.000000000 -0500
 
99
+++ keystone-2012.2.4/tests/signing/Makefile    2013-06-10 16:30:52.000000000 -0500
 
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
Index: keystone-2012.2.4/tests/signing/auth_token_revoked.pem
 
110
===================================================================
 
111
--- keystone-2012.2.4.orig/tests/signing/auth_token_revoked.pem 2013-06-10 16:30:52.000000000 -0500
 
112
+++ keystone-2012.2.4/tests/signing/auth_token_revoked.pem      2013-06-10 16:30:52.000000000 -0500
 
113
@@ -24,7 +24,7 @@
 
114
 bmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUzNTcvdjIuMCIsICJwdWJsaWNV
 
115
 UkwiOiAiaHR0cDovLzEyNy4wLjAuMTo1MDAwL3YyLjAifV0sICJlbmRwb2ludHNf
 
116
 bGlua3MiOiBbXSwgInR5cGUiOiAiaWRlbnRpdHkiLCAibmFtZSI6ICJrZXlzdG9u
 
117
-ZSJ9XSwidG9rZW4iOiB7ImV4cGlyZXMiOiAiMjAxMi0wNi0wMlQxNDo0NzozNFoi
 
118
+ZSJ9XSwidG9rZW4iOiB7ImV4cGlyZXMiOiAiMjExMi0wNi0wMlQxNDo0NzozNFoi
 
119
 LCAiaWQiOiAicGxhY2Vob2xkZXIiLCAidGVuYW50IjogeyJlbmFibGVkIjogdHJ1
 
120
 ZSwgImRlc2NyaXB0aW9uIjogbnVsbCwgIm5hbWUiOiAidGVuYW50X25hbWUxIiwg
 
121
 ImlkIjogInRlbmFudF9pZDEifX0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJyZXZv
 
122
@@ -33,8 +33,8 @@
 
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
Index: keystone-2012.2.4/tests/signing/auth_token_scoped_expired.json
 
136
===================================================================
 
137
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
138
+++ keystone-2012.2.4/tests/signing/auth_token_scoped_expired.json      2013-06-10 16:30:52.000000000 -0500
 
139
@@ -0,0 +1 @@
 
140
+{"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", "internalURL": "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"}}}
 
141
Index: keystone-2012.2.4/tests/signing/auth_token_scoped_expired.pem
 
142
===================================================================
 
143
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
 
144
+++ keystone-2012.2.4/tests/signing/auth_token_scoped_expired.pem       2013-06-10 16:30:52.000000000 -0500
 
145
@@ -0,0 +1,40 @@
 
146
+-----BEGIN CMS-----
 
147
+MIIG9QYJKoZIhvcNAQcCoIIG5jCCBuICAQExCTAHBgUrDgMCGjCCBc4GCSqGSIb3
 
148
+DQEHAaCCBb8EggW7eyJhY2Nlc3MiOiB7InNlcnZpY2VDYXRhbG9nIjogW3siZW5k
 
149
+cG9pbnRzIjogW3siYWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2L3Yx
 
150
+LzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInJlZ2lvbiI6ICJy
 
151
+ZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo4Nzc2
 
152
+L3YxLzY0YjZmM2ZiY2M1MzQzNWU4YTYwZmNmODliYjY2MTdhIiwgInB1YmxpY1VS
 
153
+TCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3NzYvdjEvNjRiNmYzZmJjYzUzNDM1ZThh
 
154
+NjBmY2Y4OWJiNjYxN2EifV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUi
 
155
+OiAidm9sdW1lIiwgIm5hbWUiOiAidm9sdW1lIn0sIHsiZW5kcG9pbnRzIjogW3si
 
156
+YWRtaW5VUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo5MjkyL3YxIiwgInJlZ2lvbiI6
 
157
+ICJyZWdpb25PbmUiLCAiaW50ZXJuYWxVUkwiOiAiaHR0cDovLzEyNy4wLjAuMTo5
 
158
+MjkyL3YxIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjkyOTIvdjEi
 
159
+fV0sICJlbmRwb2ludHNfbGlua3MiOiBbXSwgInR5cGUiOiAiaW1hZ2UiLCAibmFt
 
160
+ZSI6ICJnbGFuY2UifSwgeyJlbmRwb2ludHMiOiBbeyJhZG1pblVSTCI6ICJodHRw
 
161
+Oi8vMTI3LjAuMC4xOjg3NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5
 
162
+YmI2NjE3YSIsICJyZWdpb24iOiAicmVnaW9uT25lIiwgImludGVybmFsVVJMIjog
 
163
+Imh0dHA6Ly8xMjcuMC4wLjE6ODc3NC92MS4xLzY0YjZmM2ZiY2M1MzQzNWU4YTYw
 
164
+ZmNmODliYjY2MTdhIiwgInB1YmxpY1VSTCI6ICJodHRwOi8vMTI3LjAuMC4xOjg3
 
165
+NzQvdjEuMS82NGI2ZjNmYmNjNTM0MzVlOGE2MGZjZjg5YmI2NjE3YSJ9XSwgImVu
 
166
+ZHBvaW50c19saW5rcyI6IFtdLCAidHlwZSI6ICJjb21wdXRlIiwgIm5hbWUiOiAi
 
167
+bm92YSJ9LCB7ImVuZHBvaW50cyI6IFt7ImFkbWluVVJMIjogImh0dHA6Ly8xMjcu
 
168
+MC4wLjE6MzUzNTcvdjIuMCIsICJyZWdpb24iOiAiUmVnaW9uT25lIiwgImludGVy
 
169
+bmFsVVJMIjogImh0dHA6Ly8xMjcuMC4wLjE6MzUzNTcvdjIuMCIsICJwdWJsaWNV
 
170
+UkwiOiAiaHR0cDovLzEyNy4wLjAuMTo1MDAwL3YyLjAifV0sICJlbmRwb2ludHNf
 
171
+bGlua3MiOiBbXSwgInR5cGUiOiAiaWRlbnRpdHkiLCAibmFtZSI6ICJrZXlzdG9u
 
172
+ZSJ9XSwidG9rZW4iOiB7ImV4cGlyZXMiOiAiMjAxMC0wNi0wMlQxNDo0NzozNFoi
 
173
+LCAiaWQiOiAicGxhY2Vob2xkZXIiLCAidGVuYW50IjogeyJlbmFibGVkIjogdHJ1
 
174
+ZSwgImRlc2NyaXB0aW9uIjogbnVsbCwgIm5hbWUiOiAidGVuYW50X25hbWUxIiwg
 
175
+ImlkIjogInRlbmFudF9pZDEifX0sICJ1c2VyIjogeyJ1c2VybmFtZSI6ICJ1c2Vy
 
176
+X25hbWUxIiwgInJvbGVzX2xpbmtzIjogWyJyb2xlMSIsInJvbGUyIl0sICJpZCI6
 
177
+ICJ1c2VyX2lkMSIsICJyb2xlcyI6IFt7Im5hbWUiOiAicm9sZTEifSwgeyJuYW1l
 
178
+IjogInJvbGUyIn1dLCAibmFtZSI6ICJ1c2VyX25hbWUxIn19fQ0KMYH/MIH8AgEB
 
179
+MFwwVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgTBVVuc2V0MQ4wDAYDVQQHEwVVbnNl
 
180
+dDEOMAwGA1UEChMFVW5zZXQxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbQIBATAH
 
181
+BgUrDgMCGjANBgkqhkiG9w0BAQEFAASBgJP+wKRwFaPY8xXAolDd6gmlID41yuAw
 
182
+nd+IKeD54Ack0NI9h/M0Iv2LzTo0l84VbMOijmq++kbtdnDJ2pn4VAoNk7dQcTTy
 
183
+lz2c78Xnu0NXvq7gsPRF4zDtIpjHbUXJ3ZRPHs342suG7Tb4nvQAbxYMJQHSN10k
 
184
+W6w+gEeN7t7V
 
185
+-----END CMS-----
 
186
Index: keystone-2012.2.4/tests/test_auth_token_middleware.py
 
187
===================================================================
 
188
--- keystone-2012.2.4.orig/tests/test_auth_token_middleware.py  2013-06-10 16:30:52.000000000 -0500
 
189
+++ keystone-2012.2.4/tests/test_auth_token_middleware.py       2013-06-10 16:30:52.000000000 -0500
 
190
@@ -154,6 +154,9 @@
 
191
     signing_path = os.path.join(os.path.dirname(__file__), 'signing')
 
192
     with open(os.path.join(signing_path, 'auth_token_scoped.pem')) as f:
 
193
         self.SIGNED_TOKEN_SCOPED = cms.cms_to_token(f.read())
 
194
+    with open(os.path.join(signing_path,
 
195
+                           'auth_token_scoped_expired.pem')) as f:
 
196
+        self.SIGNED_TOKEN_SCOPED_EXPIRED = cms.cms_to_token(f.read())
 
197
     with open(os.path.join(signing_path, 'auth_token_unscoped.pem')) as f:
 
198
         self.SIGNED_TOKEN_UNSCOPED = cms.cms_to_token(f.read())
 
199
     with open(os.path.join(signing_path, 'auth_token_revoked.pem')) as f:
 
200
@@ -612,6 +615,13 @@
 
201
         self.middleware(req.environ, self.start_fake_response)
 
202
         self.assertEqual(self.middleware._cache.set_value, None)
 
203
 
 
204
+    def test_expired(self):
 
205
+        req = webob.Request.blank('/')
 
206
+        token = SIGNED_TOKEN_SCOPED_EXPIRED
 
207
+        req.headers['X-Auth-Token'] = token
 
208
+        self.middleware(req.environ, self.start_fake_response)
 
209
+        self.assertEqual(self.response_status, 401)
 
210
+
 
211
     def test_memcache_set_invalid(self):
 
212
         req = webob.Request.blank('/')
 
213
         req.headers['X-Auth-Token'] = 'invalid-token'