summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCerberus <matt.dietz@rackspace.com>2011-05-10 15:42:08 -0500
committerCerberus <matt.dietz@rackspace.com>2011-05-10 15:42:08 -0500
commit90d7e6771cf28725a6b4296b44e5d078f2ed9544 (patch)
treeb4e5686befe36bd81d64b317abefe7e2903031ce
parent3d756a8343845acfead201621a6d658c8ac616fb (diff)
parent21f18f77e7d729107742fa9157b531ce56f3272a (diff)
Merge from trunk
-rw-r--r--nova/auth/manager.py22
-rw-r--r--nova/tests/test_auth.py40
-rw-r--r--nova/tests/test_utils.py25
-rw-r--r--nova/utils.py30
4 files changed, 108 insertions, 9 deletions
diff --git a/nova/auth/manager.py b/nova/auth/manager.py
index 98d5f6eb6..07235a2a7 100644
--- a/nova/auth/manager.py
+++ b/nova/auth/manager.py
@@ -305,9 +305,9 @@ class AuthManager(object):
if check_type == 's3':
sign = signer.Signer(user.secret.encode())
expected_signature = sign.s3_authorization(headers, verb, path)
- LOG.debug('user.secret: %s', user.secret)
- LOG.debug('expected_signature: %s', expected_signature)
- LOG.debug('signature: %s', signature)
+ LOG.debug(_('user.secret: %s'), user.secret)
+ LOG.debug(_('expected_signature: %s'), expected_signature)
+ LOG.debug(_('signature: %s'), signature)
if signature != expected_signature:
LOG.audit(_("Invalid signature for user %s"), user.name)
raise exception.InvalidSignature(signature=signature,
@@ -317,10 +317,20 @@ class AuthManager(object):
# secret isn't unicode
expected_signature = signer.Signer(user.secret.encode()).generate(
params, verb, server_string, path)
- LOG.debug('user.secret: %s', user.secret)
- LOG.debug('expected_signature: %s', expected_signature)
- LOG.debug('signature: %s', signature)
+ LOG.debug(_('user.secret: %s'), user.secret)
+ LOG.debug(_('expected_signature: %s'), expected_signature)
+ LOG.debug(_('signature: %s'), signature)
if signature != expected_signature:
+ (addr_str, port_str) = utils.parse_server_string(server_string)
+ # If the given server_string contains port num, try without it.
+ if port_str != '':
+ host_only_signature = signer.Signer(
+ user.secret.encode()).generate(params, verb,
+ addr_str, path)
+ LOG.debug(_('host_only_signature: %s'),
+ host_only_signature)
+ if signature == host_only_signature:
+ return (user, project)
LOG.audit(_("Invalid signature for user %s"), user.name)
raise exception.InvalidSignature(signature=signature,
user=user)
diff --git a/nova/tests/test_auth.py b/nova/tests/test_auth.py
index f8a1b1564..f02dd94b7 100644
--- a/nova/tests/test_auth.py
+++ b/nova/tests/test_auth.py
@@ -101,9 +101,43 @@ class _AuthManagerBaseTestCase(test.TestCase):
self.assertEqual('private-party', u.access)
def test_004_signature_is_valid(self):
- #self.assertTrue(self.manager.authenticate(**boto.generate_url ...? ))
- pass
- #raise NotImplementedError
+ with user_generator(self.manager, name='admin', secret='admin',
+ access='admin'):
+ with project_generator(self.manager, name="admin",
+ manager_user='admin'):
+ accesskey = 'admin:admin'
+ expected_result = (self.manager.get_user('admin'),
+ self.manager.get_project('admin'))
+ # captured sig and query string using boto 1.9b/euca2ools 1.2
+ sig = 'd67Wzd9Bwz8xid9QU+lzWXcF2Y3tRicYABPJgrqfrwM='
+ auth_params = {'AWSAccessKeyId': 'admin:admin',
+ 'Action': 'DescribeAvailabilityZones',
+ 'SignatureMethod': 'HmacSHA256',
+ 'SignatureVersion': '2',
+ 'Timestamp': '2011-04-22T11:29:29',
+ 'Version': '2009-11-30'}
+ self.assertTrue(expected_result, self.manager.authenticate(
+ accesskey,
+ sig,
+ auth_params,
+ 'GET',
+ '127.0.0.1:8773',
+ '/services/Cloud/'))
+ # captured sig and query string using RightAWS 1.10.0
+ sig = 'ECYLU6xdFG0ZqRVhQybPJQNJ5W4B9n8fGs6+/fuGD2c='
+ auth_params = {'AWSAccessKeyId': 'admin:admin',
+ 'Action': 'DescribeAvailabilityZones',
+ 'SignatureMethod': 'HmacSHA256',
+ 'SignatureVersion': '2',
+ 'Timestamp': '2011-04-22T11:29:49.000Z',
+ 'Version': '2008-12-01'}
+ self.assertTrue(expected_result, self.manager.authenticate(
+ accesskey,
+ sig,
+ auth_params,
+ 'GET',
+ '127.0.0.1',
+ '/services/Cloud'))
def test_005_can_get_credentials(self):
return
diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py
index e08d229b0..e7b5c826e 100644
--- a/nova/tests/test_utils.py
+++ b/nova/tests/test_utils.py
@@ -250,3 +250,28 @@ class GetFromPathTestCase(test.TestCase):
input = {'a': [1, 2, {'b': 'b_1'}]}
self.assertEquals([1, 2, {'b': 'b_1'}], f(input, "a"))
self.assertEquals(['b_1'], f(input, "a/b"))
+
+
+class GenericUtilsTestCase(test.TestCase):
+ def test_parse_server_string(self):
+ result = utils.parse_server_string('::1')
+ self.assertEqual(('::1', ''), result)
+ result = utils.parse_server_string('[::1]:8773')
+ self.assertEqual(('::1', '8773'), result)
+ result = utils.parse_server_string('2001:db8::192.168.1.1')
+ self.assertEqual(('2001:db8::192.168.1.1', ''), result)
+ result = utils.parse_server_string('[2001:db8::192.168.1.1]:8773')
+ self.assertEqual(('2001:db8::192.168.1.1', '8773'), result)
+ result = utils.parse_server_string('192.168.1.1')
+ self.assertEqual(('192.168.1.1', ''), result)
+ result = utils.parse_server_string('192.168.1.2:8773')
+ self.assertEqual(('192.168.1.2', '8773'), result)
+ result = utils.parse_server_string('192.168.1.3')
+ self.assertEqual(('192.168.1.3', ''), result)
+ result = utils.parse_server_string('www.example.com:8443')
+ self.assertEqual(('www.example.com', '8443'), result)
+ result = utils.parse_server_string('www.example.com')
+ self.assertEqual(('www.example.com', ''), result)
+ # error case
+ result = utils.parse_server_string('www.exa:mple.com:8443')
+ self.assertEqual(('', ''), result)
diff --git a/nova/utils.py b/nova/utils.py
index bfcf79216..80bf1197f 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -709,3 +709,33 @@ def check_isinstance(obj, cls):
raise Exception(_('Expected object of type: %s') % (str(cls)))
# TODO(justinsb): Can we make this better??
return cls() # Ugly PyLint hack
+
+
+def parse_server_string(server_str):
+ """
+ Parses the given server_string and returns a list of host and port.
+ If it's not a combination of host part and port, the port element
+ is a null string. If the input is invalid expression, return a null
+ list.
+ """
+ try:
+ # First of all, exclude pure IPv6 address (w/o port).
+ if netaddr.valid_ipv6(server_str):
+ return (server_str, '')
+
+ # Next, check if this is IPv6 address with a port number combination.
+ if server_str.find("]:") != -1:
+ (address, port) = server_str.replace('[', '', 1).split(']:')
+ return (address, port)
+
+ # Third, check if this is a combination of an address and a port
+ if server_str.find(':') == -1:
+ return (server_str, '')
+
+ # This must be a combination of an address and a port
+ (address, port) = server_str.split(':')
+ return (address, port)
+
+ except:
+ LOG.debug(_('Invalid server_string: %s' % server_str))
+ return ('', '')