Merge lp:~blamar/nova/lp732866 into lp:~hudson-openstack/nova/trunk

Proposed by Brian Lamar
Status: Merged
Approved by: Rick Harris
Approved revision: 792
Merged at revision: 807
Proposed branch: lp:~blamar/nova/lp732866
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 168 lines (+44/-25)
3 files modified
nova/api/openstack/auth.py (+5/-1)
nova/tests/api/openstack/fakes.py (+4/-1)
nova/tests/api/openstack/test_auth.py (+35/-23)
To merge this branch: bzr merge lp:~blamar/nova/lp732866
Reviewer Review Type Date Requested Status
Rick Harris (community) Approve
Jay Pipes (community) Approve
justinsb (community) Approve
Brian Waldon (community) Approve
Review via email: mp+53101@code.launchpad.net

Description of the change

Fixed lp732866 by catching relevant `exception.NotFound` exception. Tests did not uncover this vulnerability due to "incorrect" FakeAuthManager. I say "incorrect" because potentially different implementations (LDAP or Database driven) of AuthManager might return different errors from `get_user_from_access_key`.

Also, removed all references to 'bacon', 'ham', 'herp', and 'derp' and replaced them with hopefully more helpful terms.

Long story short it addresses the immediate issue while throughly ignoring the larger issue, which is correctly testing all implementations of Auth. I find this acceptable as currently the future of auth is in flux.

To post a comment you must log in.
lp:~blamar/nova/lp732866 updated
792. By Brian Lamar

Removed EOL whitespace in accordance with PEP-8.

Revision history for this message
Brian Waldon (bcwaldon) wrote :

This seems like a good fix to the issue at hand. It's probably a great idea to at least *seem* professional with regards to test strings, too.

review: Approve
Revision history for this message
justinsb (justin-fathomdb) wrote :

LGTM.

I also tried cleaning up some of the FakeAuthManager issues, and currently I have a test that is neutered until this goes through. Happy to fix up both once this goes in - I'd prefer to see this go in first actually.

review: Approve
Revision history for this message
Jay Pipes (jaypipes) wrote :

Excellent work, Brian! :)

review: Approve
Revision history for this message
Rick Harris (rconradharris) wrote :

Great job, Brian.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'nova/api/openstack/auth.py'
2--- nova/api/openstack/auth.py 2011-03-11 19:49:32 +0000
3+++ nova/api/openstack/auth.py 2011-03-11 22:44:32 +0000
4@@ -135,7 +135,11 @@
5 req - wsgi.Request object
6 """
7 ctxt = context.get_admin_context()
8- user = self.auth.get_user_from_access_key(key)
9+
10+ try:
11+ user = self.auth.get_user_from_access_key(key)
12+ except exception.NotFound:
13+ user = None
14
15 if user and user.name == username:
16 token_hash = hashlib.sha1('%s%s%f' % (username, key,
17
18=== modified file 'nova/tests/api/openstack/fakes.py'
19--- nova/tests/api/openstack/fakes.py 2011-03-11 19:49:32 +0000
20+++ nova/tests/api/openstack/fakes.py 2011-03-11 22:44:32 +0000
21@@ -321,7 +321,10 @@
22 (user.id == p.project_manager_id)]
23
24 def get_user_from_access_key(self, key):
25- return FakeAuthManager.auth_data.get(key, None)
26+ try:
27+ return FakeAuthManager.auth_data[key]
28+ except KeyError:
29+ raise exc.NotFound
30
31
32 class FakeRateLimiter(object):
33
34=== modified file 'nova/tests/api/openstack/test_auth.py'
35--- nova/tests/api/openstack/test_auth.py 2011-03-10 22:33:45 +0000
36+++ nova/tests/api/openstack/test_auth.py 2011-03-11 22:44:32 +0000
37@@ -51,11 +51,12 @@
38
39 def test_authorize_user(self):
40 f = fakes.FakeAuthManager()
41- f.add_user('derp', nova.auth.manager.User(1, 'herp', None, None, None))
42+ f.add_user('user1_key',
43+ nova.auth.manager.User(1, 'user1', None, None, None))
44
45 req = webob.Request.blank('/v1.0/')
46- req.headers['X-Auth-User'] = 'herp'
47- req.headers['X-Auth-Key'] = 'derp'
48+ req.headers['X-Auth-User'] = 'user1'
49+ req.headers['X-Auth-Key'] = 'user1_key'
50 result = req.get_response(fakes.wsgi_app())
51 self.assertEqual(result.status, '204 No Content')
52 self.assertEqual(len(result.headers['X-Auth-Token']), 40)
53@@ -65,13 +66,13 @@
54
55 def test_authorize_token(self):
56 f = fakes.FakeAuthManager()
57- u = nova.auth.manager.User(1, 'herp', None, None, None)
58- f.add_user('derp', u)
59- f.create_project('test', u)
60+ u = nova.auth.manager.User(1, 'user1', None, None, None)
61+ f.add_user('user1_key', u)
62+ f.create_project('user1_project', u)
63
64 req = webob.Request.blank('/v1.0/', {'HTTP_HOST': 'foo'})
65- req.headers['X-Auth-User'] = 'herp'
66- req.headers['X-Auth-Key'] = 'derp'
67+ req.headers['X-Auth-User'] = 'user1'
68+ req.headers['X-Auth-Key'] = 'user1_key'
69 result = req.get_response(fakes.wsgi_app())
70 self.assertEqual(result.status, '204 No Content')
71 self.assertEqual(len(result.headers['X-Auth-Token']), 40)
72@@ -92,7 +93,7 @@
73
74 def test_token_expiry(self):
75 self.destroy_called = False
76- token_hash = 'bacon'
77+ token_hash = 'token_hash'
78
79 def destroy_token_mock(meh, context, token):
80 self.destroy_called = True
81@@ -109,15 +110,26 @@
82 bad_token)
83
84 req = webob.Request.blank('/v1.0/')
85- req.headers['X-Auth-Token'] = 'bacon'
86+ req.headers['X-Auth-Token'] = 'token_hash'
87 result = req.get_response(fakes.wsgi_app())
88 self.assertEqual(result.status, '401 Unauthorized')
89 self.assertEqual(self.destroy_called, True)
90
91- def test_bad_user(self):
92- req = webob.Request.blank('/v1.0/')
93- req.headers['X-Auth-User'] = 'herp'
94- req.headers['X-Auth-Key'] = 'derp'
95+ def test_bad_user_bad_key(self):
96+ req = webob.Request.blank('/v1.0/')
97+ req.headers['X-Auth-User'] = 'unknown_user'
98+ req.headers['X-Auth-Key'] = 'unknown_user_key'
99+ result = req.get_response(fakes.wsgi_app())
100+ self.assertEqual(result.status, '401 Unauthorized')
101+
102+ def test_bad_user_good_key(self):
103+ f = fakes.FakeAuthManager()
104+ u = nova.auth.manager.User(1, 'user1', None, None, None)
105+ f.add_user('user1_key', u)
106+
107+ req = webob.Request.blank('/v1.0/')
108+ req.headers['X-Auth-User'] = 'unknown_user'
109+ req.headers['X-Auth-Key'] = 'user1_key'
110 result = req.get_response(fakes.wsgi_app())
111 self.assertEqual(result.status, '401 Unauthorized')
112
113@@ -128,7 +140,7 @@
114
115 def test_bad_token(self):
116 req = webob.Request.blank('/v1.0/')
117- req.headers['X-Auth-Token'] = 'baconbaconbacon'
118+ req.headers['X-Auth-Token'] = 'unknown_token'
119 result = req.get_response(fakes.wsgi_app())
120 self.assertEqual(result.status, '401 Unauthorized')
121
122@@ -137,11 +149,11 @@
123 def test_token_expiry(self):
124 ctx = context.get_admin_context()
125 tok = db.auth_token_create(ctx, dict(
126- token_hash='bacon',
127+ token_hash='test_token_hash',
128 cdn_management_url='',
129 server_management_url='',
130 storage_url='',
131- user_id='ham',
132+ user_id='user1',
133 ))
134
135 db.auth_token_update(ctx, tok.token_hash, dict(
136@@ -149,13 +161,13 @@
137 ))
138
139 req = webob.Request.blank('/v1.0/')
140- req.headers['X-Auth-Token'] = 'bacon'
141+ req.headers['X-Auth-Token'] = 'test_token_hash'
142 result = req.get_response(fakes.wsgi_app())
143 self.assertEqual(result.status, '401 Unauthorized')
144
145 def test_token_doesnotexist(self):
146 req = webob.Request.blank('/v1.0/')
147- req.headers['X-Auth-Token'] = 'ham'
148+ req.headers['X-Auth-Token'] = 'nonexistant_token_hash'
149 result = req.get_response(fakes.wsgi_app())
150 self.assertEqual(result.status, '401 Unauthorized')
151
152@@ -178,13 +190,13 @@
153
154 def test_authorize_token(self):
155 f = fakes.FakeAuthManager()
156- u = nova.auth.manager.User(1, 'herp', None, None, None)
157- f.add_user('derp', u)
158+ u = nova.auth.manager.User(1, 'user1', None, None, None)
159+ f.add_user('user1_key', u)
160 f.create_project('test', u)
161
162 req = webob.Request.blank('/v1.0/')
163- req.headers['X-Auth-User'] = 'herp'
164- req.headers['X-Auth-Key'] = 'derp'
165+ req.headers['X-Auth-User'] = 'user1'
166+ req.headers['X-Auth-Key'] = 'user1_key'
167 result = req.get_response(fakes.wsgi_app())
168 self.assertEqual(len(result.headers['X-Auth-Token']), 40)
169