diff --git a/nova/auth/signer.py b/nova/auth/signer.py index c0468021b..accc808b3 100644 --- a/nova/auth/signer.py +++ b/nova/auth/signer.py @@ -53,8 +53,8 @@ import boto # NOTE(vish): for old boto import boto.utils +from nova import exception from nova import log as logging -from nova.exception import Error LOG = logging.getLogger('nova.signer') @@ -81,8 +81,7 @@ class Signer(object): def generate(self, params, verb, server_string, path): """Generate auth string according to what SignatureVersion is given. - The signature method defaults to SHA256 if available, or falls back to - SHA1 if not. + The signature method must be SHA1 or SHA256. """ if params['SignatureVersion'] == '0': @@ -91,7 +90,7 @@ class Signer(object): return self._calc_signature_1(params) if params['SignatureVersion'] == '2': return self._calc_signature_2(params, verb, server_string, path) - raise Error('Unknown Signature Version: %s' % + raise exception.Error('Unknown Signature Version: %s' % params['SignatureVersion']) @staticmethod @@ -132,12 +131,20 @@ class Signer(object): """Generate AWS signature version 2 string.""" LOG.debug('using _calc_signature_2') string_to_sign = '%s\n%s\n%s\n' % (verb, server_string, path) - if self.hmac_256: + + if 'SignatureMethod' not in params: + raise exception.Error('No SignatureMethod specified') + + if params['SignatureMethod'] == 'HmacSHA256': + if not self.hmac_256: + raise exception.Error('SHA256 not supported on this server') current_hmac = self.hmac_256 - params['SignatureMethod'] = 'HmacSHA256' - else: + elif params['SignatureMethod'] == 'HmacSHA1': current_hmac = self.hmac - params['SignatureMethod'] = 'HmacSHA1' + else: + raise exception.Error('SignatureMethod %s not supported' + % params['SignatureMethod']) + keys = params.keys() keys.sort() pairs = [] @@ -157,5 +164,6 @@ class Signer(object): if __name__ == '__main__': - print Signer('foo').generate({'SignatureVersion': '2'}, 'get', 'server', - '/foo') + print Signer('foo').generate({'SignatureVersion': '2', + 'SignatureMethod': 'HmacSHA256'}, + 'get', 'server', '/foo') diff --git a/nova/tests/test_signer.py b/nova/tests/test_signer.py index 8a223f60d..80573e4a8 100644 --- a/nova/tests/test_signer.py +++ b/nova/tests/test_signer.py @@ -54,14 +54,33 @@ class SignerTestCase(test.TestCase): 'PUT', '/johnsmith/photos/puppy.jpg')) - def test_generate_using_version_2(self): + def test_generate_HmacSHA256(self): self.assertEquals('clXalhbLZXxEuI32OoX+OeXsN6Mr2q4jzGyIDAr4RZg=', self.signer.generate( {'SignatureMethod': 'HmacSHA256', 'SignatureVersion': '2'}, 'GET', 'server', '/foo')) - def test_generate_force_HmacSHA1(self): + def test_generate_HmacSHA1(self): + self.assertEquals('uJTByiDIcgB65STrS5i2egQgd+U=', + self.signer.generate({'SignatureVersion': '2', + 'SignatureMethod': 'HmacSHA1'}, + 'GET', 'server', '/foo')) + + def test_generate_invalid_signature_method_defined(self): + self.assertRaises(exception.Error, + self.signer.generate, + {'SignatureVersion': '2', + 'SignatureMethod': 'invalid_method'}, + 'GET', 'server', '/foo') + + def test_generate_no_signature_method_defined(self): + self.assertRaises(exception.Error, + self.signer.generate, + {'SignatureVersion': '2'}, + 'GET', 'server', '/foo') + + def test_generate_HmacSHA256_missing_hashlib_sha256(self): # Stub out haslib.sha256 import hashlib self.stubs.Set(hashlib, 'sha256', None) @@ -69,20 +88,24 @@ class SignerTestCase(test.TestCase): # Create Signer again now that hashlib.sha256 is None self.signer = signer.Signer( 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o') - self.assertEquals('uJTByiDIcgB65STrS5i2egQgd+U=', - self.signer.generate({'SignatureVersion': '2'}, - 'GET', 'server', '/foo')) + self.assertRaises(exception.Error, + self.signer.generate, + {'SignatureVersion': '2', + 'SignatureMethod': 'HmacSHA256'}, + 'GET', 'server', '/foo') def test_generate_with_unicode_param(self): self.assertEquals('clXalhbLZXxEuI32OoX+OeXsN6Mr2q4jzGyIDAr4RZg=', - self.signer.generate({'SignatureVersion': u'2'}, - 'GET', 'server', '/foo')) + self.signer.generate({'SignatureVersion': u'2', + 'SignatureMethod': 'HmacSHA256'}, + 'GET', 'server', '/foo')) def test_generate_with_non_string_or_unicode_param(self): self.assertEquals('99IAgCkhTR2aMTgRobnzKGuNxVFSdb7vlQRvnj3Urqk=', self.signer.generate( {'AnotherParam': ClassWithStrRepr(), - 'SignatureVersion': '2'}, + 'SignatureVersion': '2', + 'SignatureMethod': 'HmacSHA256'}, 'GET', 'server', '/foo')) def test_generate_unknown_version(self):