mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-09-19 04:59:01 +00:00
Use bcrypt for login form. Add tests to check that salts and hashes are random, and check handling of invalid passwords or salts.
This commit is contained in:
parent
8ba1d318ec
commit
4a9177a257
@ -7,7 +7,8 @@
|
|||||||
# on 1 February 2011.
|
# on 1 February 2011.
|
||||||
|
|
||||||
import cherrypy
|
import cherrypy
|
||||||
import urllib, hashlib
|
import urllib
|
||||||
|
from passlib.hash import bcrypt
|
||||||
import cfg
|
import cfg
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
@ -31,7 +32,7 @@ def check_credentials(username, passphrase):
|
|||||||
u = None
|
u = None
|
||||||
# hash the password whether the user exists, to foil timing
|
# hash the password whether the user exists, to foil timing
|
||||||
# side-channel attacks
|
# side-channel attacks
|
||||||
pass_hash = hashlib.md5(passphrase).hexdigest()
|
pass_hash = bcrypt.encrypt(passphrase, salt=u['salt'])
|
||||||
|
|
||||||
if u is None or u['passphrase'] != pass_hash:
|
if u is None or u['passphrase'] != pass_hash:
|
||||||
error = "Bad user-name or password."
|
error = "Bad user-name or password."
|
||||||
|
|||||||
70
tests/auth_test.py
Normal file
70
tests/auth_test.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
# -*- mode: python; mode: auto-fill; fill-column: 80 -*-
|
||||||
|
|
||||||
|
import user_store, auth
|
||||||
|
from passlib.hash import bcrypt
|
||||||
|
from logger import Logger
|
||||||
|
import cfg
|
||||||
|
import unittest
|
||||||
|
import cherrypy
|
||||||
|
import plugin_mount
|
||||||
|
import os
|
||||||
|
from model import User
|
||||||
|
cfg.log = Logger()
|
||||||
|
|
||||||
|
cherrypy.log.access_file = None
|
||||||
|
|
||||||
|
class Auth(unittest.TestCase):
|
||||||
|
"""Test check_credentials function of auth to confirm it works as expected"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
cfg.user_db = os.path.join(cfg.file_root, "tests/testdata/users");
|
||||||
|
cfg.users = plugin_mount.UserStoreModule.get_plugins()[0]
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
for user in cfg.users.get_all():
|
||||||
|
cfg.users.remove(user[0])
|
||||||
|
cfg.users.close()
|
||||||
|
|
||||||
|
def test_password_check(self):
|
||||||
|
self.add_user("test_user", "password")
|
||||||
|
|
||||||
|
# check_credentials returns None if there is no error, or returns error string
|
||||||
|
self.assertIsNone(auth.check_credentials("test_user", "password"))
|
||||||
|
self.assertIsNotNone(auth.check_credentials("test_user", "wrong"))
|
||||||
|
|
||||||
|
def test_salt_check(self):
|
||||||
|
test_user = self.add_user("test_user", "password", "abcdefghijklmnopqrstuv")
|
||||||
|
self.assertIsNotNone(auth.check_credentials("test_user", "password"))
|
||||||
|
|
||||||
|
def test_salt_is_random(self):
|
||||||
|
test_user1 = self.add_user("test_user1", "password")
|
||||||
|
test_user2 = self.add_user("test_user2", "password")
|
||||||
|
self.assertNotEqual(test_user1["salt"], test_user2["salt"])
|
||||||
|
|
||||||
|
def test_hash_is_random(self):
|
||||||
|
test_user1 = self.add_user("test_user1", "password")
|
||||||
|
test_user2 = self.add_user("test_user2", "password")
|
||||||
|
self.assertNotEqual(test_user1["passphrase"], test_user2["passphrase"])
|
||||||
|
|
||||||
|
# set fake_salt if you want to store an invalid salt
|
||||||
|
def add_user(self, test_username, passphrase='', fake_salt=None):
|
||||||
|
test_user = self.create_user(test_username, passphrase, fake_salt)
|
||||||
|
cfg.users.set(test_username,test_user)
|
||||||
|
return test_user
|
||||||
|
|
||||||
|
def create_user(self, username, passphrase='', fake_salt=None):
|
||||||
|
test_user = User()
|
||||||
|
test_user["username"] = username
|
||||||
|
pass_hash = bcrypt.encrypt(passphrase)
|
||||||
|
test_user["passphrase"] = pass_hash
|
||||||
|
if fake_salt:
|
||||||
|
test_user["salt"] = fake_salt
|
||||||
|
else:
|
||||||
|
# for bcrypt, the salt is output as part of the hash
|
||||||
|
test_user["salt"] = pass_hash[7:29]
|
||||||
|
|
||||||
|
return test_user
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Loading…
x
Reference in New Issue
Block a user