Merge "Allow configuring salt manually"

This commit is contained in:
Jenkins 2016-03-08 09:27:13 +00:00 committed by Gerrit Code Review
commit 64eab78a92
4 changed files with 48 additions and 2 deletions

View File

@ -51,6 +51,10 @@ use = egg:swauth#swauth
# An alternative is 'sha512' which stores only a one-way hash of the key leaving # An alternative is 'sha512' which stores only a one-way hash of the key leaving
# it secure but unavailable for key-signing. # it secure but unavailable for key-signing.
# auth_type = plaintext # auth_type = plaintext
# Used if the auth_type is sha1 or sha512. Salt is data(text) that is used as
# an additional input to the one-way encoding function. If not set, a random
# salt will be generated for each password.
# auth_type_salt =
# This allows middleware higher in the WSGI pipeline to override auth # This allows middleware higher in the WSGI pipeline to override auth
# processing, useful for middleware such as tempurl and formpost. If you know # processing, useful for middleware such as tempurl and formpost. If you know
# you're not going to use such middleware and you want a bit of extra security, # you're not going to use such middleware and you want a bit of extra security,

View File

@ -89,10 +89,13 @@ class Sha1(object):
"""Encodes a user key into a particular format. The result of this method """Encodes a user key into a particular format. The result of this method
will be used by swauth for storing user credentials. will be used by swauth for storing user credentials.
If salt is not manually set in conf file, a random salt will be
generated and used.
:param key: User's secret key :param key: User's secret key
:returns: A string representing user credentials :returns: A string representing user credentials
""" """
salt = os.urandom(32).encode('base64').rstrip() salt = self.salt or os.urandom(32).encode('base64').rstrip()
return self.encode_w_salt(salt, key) return self.encode_w_salt(salt, key)
def match(self, key, creds): def match(self, key, creds):
@ -134,10 +137,13 @@ class Sha512(object):
"""Encodes a user key into a particular format. The result of this method """Encodes a user key into a particular format. The result of this method
will be used by swauth for storing user credentials. will be used by swauth for storing user credentials.
If salt is not manually set in conf file, a random salt will be
generated and used.
:param key: User's secret key :param key: User's secret key
:returns: A string representing user credentials :returns: A string representing user credentials
""" """
salt = os.urandom(32).encode('base64').rstrip() salt = self.salt or os.urandom(32).encode('base64').rstrip()
return self.encode_w_salt(salt, key) return self.encode_w_salt(salt, key)
def match(self, key, creds): def match(self, key, creds):

View File

@ -165,6 +165,9 @@ class Swauth(object):
if self.auth_encoder is None: if self.auth_encoder is None:
raise ValueError('Invalid auth_type in config file: %s' raise ValueError('Invalid auth_type in config file: %s'
% self.auth_type) % self.auth_type)
# If auth_type_salt is not set in conf file, a random salt will be
# generated for each new password to be encoded.
self.auth_encoder.salt = conf.get('auth_type_salt', None)
self.allow_overrides = \ self.allow_overrides = \
conf.get('allow_overrides', 't').lower() in TRUE_VALUES conf.get('allow_overrides', 't').lower() in TRUE_VALUES
self.agent = '%(orig)s Swauth' self.agent = '%(orig)s Swauth'

View File

@ -119,6 +119,39 @@ class TestAuth(unittest.TestCase):
'token_life': str(DEFAULT_TOKEN_LIFE), 'token_life': str(DEFAULT_TOKEN_LIFE),
'max_token_life': str(MAX_TOKEN_LIFE)})(FakeApp()) 'max_token_life': str(MAX_TOKEN_LIFE)})(FakeApp())
def test_salt(self):
for auth_type in ('sha1', 'sha512'):
# Salt not manually set
test_auth = \
auth.filter_factory({
'super_admin_key': 'supertest',
'token_life': str(DEFAULT_TOKEN_LIFE),
'max_token_life': str(MAX_TOKEN_LIFE),
'auth_type': auth_type})(FakeApp())
self.assertEqual(test_auth.auth_encoder.salt, None)
mock_urandom = mock.Mock(return_value="abc")
with mock.patch("os.urandom", mock_urandom):
h_key = test_auth.auth_encoder().encode("key")
self.assertTrue(mock_urandom.called)
prefix = auth_type + ":" + "abc".encode('base64').rstrip() + '$'
self.assertTrue(h_key.startswith(prefix))
# Salt manually set
test_auth = \
auth.filter_factory({
'super_admin_key': 'supertest',
'token_life': str(DEFAULT_TOKEN_LIFE),
'max_token_life': str(MAX_TOKEN_LIFE),
'auth_type': auth_type,
'auth_type_salt': "mysalt"})(FakeApp())
self.assertEqual(test_auth.auth_encoder.salt, "mysalt")
mock_urandom = mock.Mock()
with mock.patch("os.urandom", mock_urandom):
h_key = test_auth.auth_encoder().encode("key")
self.assertFalse(mock_urandom.called)
prefix = auth_type + ":" + "mysalt" + '$'
self.assertTrue(h_key.startswith(prefix))
def test_swift_version(self): def test_swift_version(self):
app = FakeApp() app = FakeApp()