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>
|
# max_token_life = <same as token_life>
|
||||||
# Specifies how the user key is stored. The default is 'plaintext', leaving the
|
# 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.
|
# 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.
|
# it secure but unavailable for key-signing.
|
||||||
# auth_type = plaintext
|
# 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
|
# 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,
|
||||||
|
@ -28,13 +28,10 @@ conditions:
|
|||||||
- Write a match(key, creds) method that will take two arguments: the user's
|
- 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
|
key, and the user's retrieved credentials. Return a boolean value that
|
||||||
indicates whether the match is True or False.
|
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 hashlib
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
#: Maximum length any valid token should ever be.
|
#: 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
|
must be capitalized. encode and match methods must be provided and are
|
||||||
the only ones that will be used by swauth.
|
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):
|
def encode(self, key):
|
||||||
"""
|
"""
|
||||||
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
|
||||||
@ -88,9 +99,8 @@ class Sha1(object):
|
|||||||
:param key: User's secret key
|
:param key: User's secret key
|
||||||
:returns: A string representing user credentials
|
:returns: A string representing user credentials
|
||||||
"""
|
"""
|
||||||
enc_key = '%s%s' % (self.salt, key)
|
salt = os.urandom(32).encode('base64').rstrip();
|
||||||
enc_val = hashlib.sha1(enc_key).hexdigest()
|
return self.encode_w_salt(salt, key)
|
||||||
return "sha1:%s$%s" % (self.salt, enc_val)
|
|
||||||
|
|
||||||
def match(self, key, creds):
|
def match(self, key, creds):
|
||||||
"""
|
"""
|
||||||
@ -100,4 +110,56 @@ class Sha1(object):
|
|||||||
:param creds: User's stored credentials
|
:param creds: User's stored credentials
|
||||||
:returns: True if the supplied key is valid, False otherwise
|
: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:
|
if self.auth_encoder is None:
|
||||||
raise Exception('Invalid auth_type in config file: %s'
|
raise Exception('Invalid auth_type in config file: %s'
|
||||||
% self.auth_type)
|
% self.auth_type)
|
||||||
self.auth_encoder.salt = conf.get('auth_type_salt', 'swauthsalt')
|
|
||||||
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'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user