Security fixies.
Generate new salt for every password. Support different salt for passwords. Support SHA512 for hashing.
This commit is contained in:
parent
e0941ddffd
commit
e14a7b3df8
@ -47,11 +47,9 @@ use = egg:swauth#swauth
|
||||
# max_token_life = <same as token_life>
|
||||
# Specifies how the user key is stored. The default is 'plaintext', leaving the
|
||||
# key unsecured but available for key-signing features if such are ever added.
|
||||
# An alternative is 'sha1' 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.
|
||||
# auth_type = plaintext
|
||||
# Used if the auth_type is sha1 or another method that can make use of a salt.
|
||||
# auth_type_salt = swauthsalt
|
||||
# This allows middleware higher in the WSGI pipeline to override auth
|
||||
# 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,
|
||||
|
@ -28,13 +28,10 @@ conditions:
|
||||
- Write a match(key, creds) method that will take two arguments: the user's
|
||||
key, and the user's retrieved credentials. Return a boolean value that
|
||||
indicates whether the match is True or False.
|
||||
|
||||
Note that, since some of the encodings will be hashes, swauth supports the
|
||||
notion of salts. Thus, self.salt will be set to either a user-specified salt
|
||||
value or to a default value.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
|
||||
#: Maximum length any valid token should ever be.
|
||||
@ -80,6 +77,20 @@ class Sha1(object):
|
||||
must be capitalized. encode and match methods must be provided and are
|
||||
the only ones that will be used by swauth.
|
||||
"""
|
||||
|
||||
def encode_w_salt(self, salt, key):
|
||||
"""
|
||||
Encodes a user key with salt into a particular format. The result of
|
||||
this method will be used internally.
|
||||
|
||||
:param salt: Salt for hashing
|
||||
:param key: User's secret key
|
||||
:returns: A string representing user credentials
|
||||
"""
|
||||
enc_key = '%s%s' % (salt, key)
|
||||
enc_val = hashlib.sha1(enc_key).hexdigest()
|
||||
return "sha1:%s$%s" % (salt, enc_val)
|
||||
|
||||
def encode(self, key):
|
||||
"""
|
||||
Encodes a user key into a particular format. The result of this method
|
||||
@ -88,9 +99,8 @@ class Sha1(object):
|
||||
:param key: User's secret key
|
||||
:returns: A string representing user credentials
|
||||
"""
|
||||
enc_key = '%s%s' % (self.salt, key)
|
||||
enc_val = hashlib.sha1(enc_key).hexdigest()
|
||||
return "sha1:%s$%s" % (self.salt, enc_val)
|
||||
salt = os.urandom(32).encode('base64').rstrip();
|
||||
return self.encode_w_salt(salt, key)
|
||||
|
||||
def match(self, key, creds):
|
||||
"""
|
||||
@ -100,4 +110,56 @@ class Sha1(object):
|
||||
:param creds: User's stored credentials
|
||||
:returns: True if the supplied key is valid, False otherwise
|
||||
"""
|
||||
return self.encode(key) == creds
|
||||
|
||||
[type, rest] = creds.split(':')
|
||||
[salt, enc] = rest.split('$')
|
||||
|
||||
return self.encode_w_salt(salt, key) == creds
|
||||
|
||||
class Sha512(object):
|
||||
"""
|
||||
Provides a particular auth type for encoding format for encoding and
|
||||
matching user keys.
|
||||
|
||||
This class must be all lowercase except for the first character, which
|
||||
must be capitalized. encode and match methods must be provided and are
|
||||
the only ones that will be used by swauth.
|
||||
"""
|
||||
|
||||
def encode_w_salt(self, salt, key):
|
||||
"""
|
||||
Encodes a user key with salt into a particular format. The result of
|
||||
this method will be used internal.
|
||||
|
||||
:param salt: Salt for hashing
|
||||
:param key: User's secret key
|
||||
:returns: A string representing user credentials
|
||||
"""
|
||||
enc_key = '%s%s' % (salt, key)
|
||||
enc_val = hashlib.sha512(enc_key).hexdigest()
|
||||
return "sha512:%s$%s" % (salt, enc_val)
|
||||
|
||||
def encode(self, key):
|
||||
"""
|
||||
Encodes a user key into a particular format. The result of this method
|
||||
will be used by swauth for storing user credentials.
|
||||
|
||||
:param key: User's secret key
|
||||
:returns: A string representing user credentials
|
||||
"""
|
||||
salt = os.urandom(32).encode('base64').rstrip();
|
||||
return self.encode_w_salt(salt, key)
|
||||
|
||||
def match(self, key, creds):
|
||||
"""
|
||||
Checks whether the user-provided key matches the user's credentials
|
||||
|
||||
:param key: User-supplied key
|
||||
:param creds: User's stored credentials
|
||||
:returns: True if the supplied key is valid, False otherwise
|
||||
"""
|
||||
|
||||
[type, rest] = creds.split(':')
|
||||
[salt, enc] = rest.split('$')
|
||||
|
||||
return self.encode_w_salt(salt, key) == creds
|
||||
|
@ -140,7 +140,6 @@ class Swauth(object):
|
||||
if self.auth_encoder is None:
|
||||
raise Exception('Invalid auth_type in config file: %s'
|
||||
% self.auth_type)
|
||||
self.auth_encoder.salt = conf.get('auth_type_salt', 'swauthsalt')
|
||||
self.allow_overrides = \
|
||||
conf.get('allow_overrides', 't').lower() in TRUE_VALUES
|
||||
self.agent = '%(orig)s Swauth'
|
||||
|
Loading…
x
Reference in New Issue
Block a user