diff --git a/mig/shared/pwcrypto.py b/mig/shared/pwcrypto.py index abb1a6a1a..f30dad457 100644 --- a/mig/shared/pwcrypto.py +++ b/mig/shared/pwcrypto.py @@ -114,10 +114,10 @@ def best_crypt_salt(configuration): return salt_data -def make_hash(password): +def make_hash(password, _urandom=urandom): """Generate a random salt and return a new hash for the password.""" # NOTE: urandom already returns bytes as required for base64 encode - salt = b64encode(urandom(SALT_LENGTH)) + salt = b64encode(_urandom(SALT_LENGTH)) # NOTE: hashlib functions require bytes, and post string format needs # native strings to avoid actually inserting string type markers. derived = b64encode(hashlib.pbkdf2_hmac(HASH_FUNCTION, diff --git a/tests/test_mig_shared_pwcrypto.py b/tests/test_mig_shared_pwcrypto.py new file mode 100644 index 000000000..d81dbbe4a --- /dev/null +++ b/tests/test_mig_shared_pwcrypto.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# +# --- BEGIN_HEADER --- +# +# test_mig_shared_pwcrypto - unit test of the corresponding mig shared module +# Copyright (C) 2003-2025 The MiG Project by the Science HPC Center at UCPH +# +# This file is part of MiG. +# +# MiG is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# MiG is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. +# +# --- END_HEADER --- +# + +"""Unit test pwcrypto functions""" + +import os +import sys + +sys.path.append(os.path.realpath(os.path.join(os.path.dirname(__file__), "."))) + +from support import MigTestCase, temppath, testmain + +from mig.shared.pwcrypto import * + +class MigSharedPwcrypto_make_hash(MigTestCase): + def test_pickle_string(self): + expected = "PBKDF2$sha256$10000$MDAwMDAwMDAwMDAw$epib2rEg/HYTQZFnCp7hmIGZ6rzHnViy" + + actual = make_hash('foobar', _urandom=lambda vlen: b'0' * vlen) + + self.assertEqual(actual, expected, "mismatch pickling string") + + +if __name__ == '__main__': + testmain()