From d16282445984028e3194659c4cddde480ef0ade9 Mon Sep 17 00:00:00 2001 From: Nikos Skalkotos Date: Thu, 31 Oct 2013 16:41:38 +0200 Subject: [PATCH] Add support for sha1 hashing method This is the default password hashing method for NetBSD. --- snf-image-helper/snf-passtohash.py | 40 +++++++++++++--------------- snf-image-helper/tasks/50ChangePassword.in | 16 +++++++++-- snf-image-host/multistrap.conf | 2 +- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/snf-image-helper/snf-passtohash.py b/snf-image-helper/snf-passtohash.py index baf8fad..6b2fb57 100755 --- a/snf-image-helper/snf-passtohash.py +++ b/snf-image-helper/snf-passtohash.py @@ -26,39 +26,39 @@ To do this, it generates a random salt internally. """ import sys -import crypt -import bcrypt + +import passlib.hash from string import ascii_letters, digits from random import choice from os.path import basename from optparse import OptionParser - -# This dictionary maps the hashing algorithm method -# with its as documented in: -# http://www.akkadia.org/drepper/SHA-crypt.txt -HASH_ID_FROM_METHOD = { - 'md5': '1', - 'blowfish': '2a', - 'sha256': '5', - 'sha512': '6' -} - - def random_salt(length=8): pool = ascii_letters + digits + "/" + "." return ''.join(choice(pool) for i in range(length)) +METHOD = { +# Name: (algoritm, options) + 'md5': (passlib.hash.md5_crypt, {}), + 'blowfish': (passlib.hash.bcrypt, {}), + 'sha256': ( + passlib.hash.sha256_crypt, + {'rounds': 5000, 'implicit_rounds': True, 'salt': random_salt()}), + 'sha512': ( + passlib.hash.sha512_crypt, + {'rounds': 5000, 'implicit_rounds': True, 'salt': random_salt()}), + 'sha1': (passlib.hash.sha1_crypt, {}) +} def parse_arguments(input_args): usage = "usage: %prog [-h] [-m encrypt-method] " parser = OptionParser(usage=usage) parser.add_option( "-m", "--encrypt-method", dest="encrypt_method", type='choice', - default="sha512", choices=HASH_ID_FROM_METHOD.keys(), + default="sha512", choices=METHOD.keys(), help="encrypt password with ENCRYPT_METHOD [%default] (supported: " + - ", ".join(HASH_ID_FROM_METHOD.keys()) + ")" + ", ".join(METHOD.keys()) + ")" ) (opts, args) = parser.parse_args(input_args) @@ -72,13 +72,9 @@ def parse_arguments(input_args): def main(): (passwd, method) = parse_arguments(sys.argv[1:]) - if method != 'blowfish' : - hash = crypt.crypt( - passwd,"$" + HASH_ID_FROM_METHOD[method] + "$" + random_salt()) - else: - hash = bcrypt.hashpw(passwd, bcrypt.gensalt(8)) + algorithm, options = METHOD[method] + print algorithm.encrypt(passwd, **options) - sys.stdout.write("%s\n" % (hash)) return 0 if __name__ == "__main__": diff --git a/snf-image-helper/tasks/50ChangePassword.in b/snf-image-helper/tasks/50ChangePassword.in index f152e5a..46d1ab0 100644 --- a/snf-image-helper/tasks/50ChangePassword.in +++ b/snf-image-helper/tasks/50ChangePassword.in @@ -103,9 +103,12 @@ unix_password() { linux|freebsd) hash=$("@scriptsdir@/snf-passtohash.py" "$password") ;; - openbsd|netbsd) + openbsd) hash=$("@scriptsdir@/snf-passtohash.py" -m blowfish "$password") ;; + netbsd) + hash=$("@scriptsdir@/snf-passtohash.py" -m sha1 "$password") + ;; *) log_error "Unknown unix flavor: \`$flavor'" ;; @@ -173,10 +176,19 @@ else unix_password "$SNF_IMAGE_PROPERTY_OSFAMILY" "$SNF_IMAGE_TARGET" "$SNF_IMAGE_PASSWORD" fi -# For FreeBSD, OpenBSD and NetBSD we need to recreate the password database too +# For FreeBSD, OpenBSD and NetBSD we need to recreate the password databases too if [[ "$SNF_IMAGE_PROPERTY_OSFAMILY" == *bsd ]]; then rm -f "$SNF_IMAGE_TARGET/etc/spwd.db" + # NetBSD is very strict about the existence & non-existence of the db files + if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "netbsd" ]; then + rm -f "$SNF_IMAGE_TARGET/etc/pwd.db.tmp" + rm -f "$SNF_IMAGE_TARGET/etc/spwd.db.tmp" + + touch "$SNF_IMAGE_TARGET/etc/spwd.db" + fi + + # Make sure /etc/spwd.db is recreated on first boot rc_local=$(cat <