Commit 95511943 authored by Valentin Samir's avatar Valentin Samir

Add a utils function to test crypt salts

parent a5ed74ee
......@@ -181,3 +181,11 @@ class UtilsTestCase(TestCase):
url3 = utils.update_url(u"https://www.example.com?toto=1", {u"toto": u"2"})
self.assertEqual(url3, u"https://www.example.com?toto=2")
def test_crypt_salt_is_valid(self):
"""test the function crypt_salt_is_valid who test if a crypt salt is valid"""
self.assertFalse(utils.crypt_salt_is_valid("")) # len 0
self.assertFalse(utils.crypt_salt_is_valid("a")) # len 1
self.assertFalse(utils.crypt_salt_is_valid("$$")) # start with $ followed by $
self.assertFalse(utils.crypt_salt_is_valid("$toto")) # start with $ but no secondary $
self.assertFalse(utils.crypt_salt_is_valid("$toto$toto")) # algorithm toto not known
......@@ -89,7 +89,7 @@ def update_url(url, params):
query = list(query.items())
query.sort()
url_query = urlencode(query)
if not isinstance(url_query, bytes):
if not isinstance(url_query, bytes): # pragma: no cover in python3 urlencode return an unicode
url_query = url_query.encode("utf-8")
url_parts[4] = url_query
return urlunparse(url_parts).decode('utf-8')
......@@ -152,6 +152,27 @@ def gen_saml_id():
return _gen_ticket('_')
def crypt_salt_is_valid(salt):
"""Return True is salt is valid has a crypt salt, False otherwise"""
if len(salt) < 2:
return False
else:
if salt[0] == '$':
if salt[1] == '$':
return False
else:
if '$' not in salt[1:]:
return False
else:
hashed = crypt.crypt("", salt)
if not hashed or '$' not in hashed[1:]:
return False
else:
return True
else:
return True
class LdapHashUserPassword(object):
"""Please see https://tools.ietf.org/id/draft-stroeder-hashed-userpassword-values-01.html"""
......@@ -252,9 +273,9 @@ class LdapHashUserPassword(object):
if six.PY3:
password = password.decode(charset)
salt = salt.decode(charset)
hashed_password = crypt.crypt(password, salt)
if hashed_password is None:
if not crypt_salt_is_valid(salt):
raise cls.BadSalt("System crypt implementation do not support the salt %r" % salt)
hashed_password = crypt.crypt(password, salt)
if six.PY3:
hashed_password = hashed_password.encode(charset)
return scheme + hashed_password
......@@ -306,9 +327,9 @@ def check_password(method, password, hashed_password, charset):
password = password.decode(charset)
salt = salt.decode(charset)
hashed_password = hashed_password.decode(charset)
crypted_password = crypt.crypt(password, salt)
if crypted_password is None:
if not crypt_salt_is_valid(salt):
raise ValueError("System crypt implementation do not support the salt %r" % salt)
crypted_password = crypt.crypt(password, salt)
return crypted_password == hashed_password
elif method == "ldap":
scheme = LdapHashUserPassword.get_scheme(hashed_password)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment