diff options
author | Alan Somers <asomers@FreeBSD.org> | 2016-07-13 17:09:20 +0000 |
---|---|---|
committer | Alan Somers <asomers@FreeBSD.org> | 2016-07-13 17:09:20 +0000 |
commit | 80285e3e194993731e573e5ffa1eba819e283ddd (patch) | |
tree | a6022c60d1351f1b86c630d2144fa0d1ef11de95 /pw/tests | |
parent | 2a6f15e0cafa2da2bd94b00b1a7285cb9715b5aa (diff) | |
download | pw-darwin-80285e3e194993731e573e5ffa1eba819e283ddd.tar.gz pw-darwin-80285e3e194993731e573e5ffa1eba819e283ddd.tar.zst pw-darwin-80285e3e194993731e573e5ffa1eba819e283ddd.zip |
pw should sanitize the argument of -w.
Otherwise, it will silently disable the login for the selected account if
the argument is unrecognizable.
usr.sbin/pw/pw.h
usr.sbin/pw/pw_conf.c
usr.sbin/pw/pw_user.c
Use separate rules to validate boolean parameters and passwd
parameters. Error out if a password parameter cannot be parsed.
usr.sbin/pw/tests/Makefile
usr.sbin/pw/tests/crypt.c
usr.sbin/pw/tests/pw_useradd.sh
usr.sbin/pw/tests/pw_usermod.sh
Add tests for the validation. Also, enhance existing
password-related tests to actually validate that the correct hash is
written to master.passwd.
Reviewed by: bapt
MFC after: 4 weeks
Sponsored by: Spectra Logic Corp
Differential Revision: https://reviews.freebsd.org/D6840
Diffstat (limited to 'pw/tests')
-rw-r--r-- | pw/tests/Makefile | 5 | ||||
-rw-r--r-- | pw/tests/crypt.c | 45 | ||||
-rwxr-xr-x | pw/tests/pw_useradd.sh | 57 | ||||
-rwxr-xr-x | pw/tests/pw_usermod.sh | 60 |
4 files changed, 155 insertions, 12 deletions
diff --git a/pw/tests/Makefile b/pw/tests/Makefile index 1c69d50..1ae14f3 100644 --- a/pw/tests/Makefile +++ b/pw/tests/Makefile @@ -2,6 +2,11 @@ PACKAGE= tests +BINDIR= ${TESTSDIR} + +PROGS+= crypt +LIBADD+= crypt + ATF_TESTS_SH= pw_etcdir \ pw_lock \ pw_config \ diff --git a/pw/tests/crypt.c b/pw/tests/crypt.c new file mode 100644 index 0000000..586fccd --- /dev/null +++ b/pw/tests/crypt.c @@ -0,0 +1,45 @@ +/*- + * Copyright (c) 2016 Spectra Logic Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <err.h> +#include <stdio.h> +#include <unistd.h> + +int main(int argc, char** argv) +{ + char *salt, *pass, *hash; + + if (argc < 3) + errx(1, "Usage: crypt <salt> <password>"); + salt = argv[1]; + pass = argv[2]; + + hash = crypt(pass, salt); + printf("%s", hash); + return (hash == NULL ? 1 : 0); +} diff --git a/pw/tests/pw_useradd.sh b/pw/tests/pw_useradd.sh index cb62944..b1ff8d4 100755 --- a/pw/tests/pw_useradd.sh +++ b/pw/tests/pw_useradd.sh @@ -235,9 +235,12 @@ atf_test_case user_add_password_from_h user_add_password_from_h_body() { populate_etc_skel - atf_check -s exit:0 ${PW} useradd test -h 0 <<-EOF - $(echo test) + atf_check -s exit:0 ${PW} useradd foo -h 0 <<-EOF + $(echo mypassword) EOF + passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd` + atf_check -s exit:0 -o inline:$passhash \ + $(atf_get_srcdir)/crypt $passhash "mypassword" } atf_test_case user_add_R @@ -325,17 +328,47 @@ user_add_already_exists_body() { ${PW} useradd foo } +atf_test_case user_add_w_error +user_add_w_error_body() { + populate_etc_skel + + atf_check -s exit:1 -e match:"pw: Invalid value for default password" \ + ${PW} useradd foo -w invalid_value +} + +atf_test_case user_add_w_no +user_add_w_no_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo -w no + atf_check -s exit:0 -o match:"^foo:\*" grep "^foo:" $HOME/master.passwd +} + +atf_test_case user_add_w_none +user_add_w_none_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo -w none + atf_check -s exit:0 -o match:"^foo::" grep "^foo:" $HOME/master.passwd +} + +atf_test_case user_add_w_random +user_add_w_random_body() { + populate_etc_skel + + password=`${PW} useradd foo -w random | cat` + passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd` + atf_check -s exit:0 -o inline:$passhash \ + $(atf_get_srcdir)/crypt $passhash "$password" +} + atf_test_case user_add_w_yes user_add_w_yes_body() { populate_etc_skel - atf_check -s exit:0 ${PW} useradd foo -w yes - atf_check -s exit:0 \ - -o match:'^foo:\$.*' \ - grep "^foo" ${HOME}/master.passwd - atf_check -s exit:0 ${PW} usermod foo -w yes - atf_check -s exit:0 \ - -o match:'^foo:\$.*' \ - grep "^foo" ${HOME}/master.passwd + password=`${PW} useradd foo -w random | cat` + passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd` + atf_check -s exit:0 -o inline:$passhash \ + $(atf_get_srcdir)/crypt $passhash "$password" } atf_test_case user_add_with_pw_conf @@ -380,6 +413,10 @@ atf_init_test_cases() { atf_add_test_case user_add_uid_too_large atf_add_test_case user_add_bad_shell atf_add_test_case user_add_already_exists + atf_add_test_case user_add_w_error + atf_add_test_case user_add_w_no + atf_add_test_case user_add_w_none + atf_add_test_case user_add_w_random atf_add_test_case user_add_w_yes atf_add_test_case user_add_with_pw_conf } diff --git a/pw/tests/pw_usermod.sh b/pw/tests/pw_usermod.sh index 236fd27..df056e0 100755 --- a/pw/tests/pw_usermod.sh +++ b/pw/tests/pw_usermod.sh @@ -157,8 +157,9 @@ user_mod_h_body() { atf_check -s exit:0 ${PW} usermod foo -h 0 <<- EOF $(echo a) EOF - atf_check -s exit:0 -o not-match:"^foo:\*:.*" \ - grep "^foo" ${HOME}/master.passwd + passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd` + atf_check -s exit:0 -o inline:$passhash \ + $(atf_get_srcdir)/crypt $passhash "a" atf_check -s exit:0 ${PW} usermod foo -h - <<- EOF $(echo b) EOF @@ -203,6 +204,56 @@ user_mod_uid_body() { atf_check -s exit:0 ${PW} usermod foo -u 5000 } +atf_test_case user_mod_w_error +user_mod_w_error_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:1 -e match:"pw: Invalid value for default password" \ + ${PW} usermod foo -w invalid_value +} + +atf_test_case user_mod_w_no +user_mod_w_no_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:0 ${PW} usermod foo -w no + atf_check -s exit:0 -o match:"^foo:\*" grep "^foo:" $HOME/master.passwd +} + +atf_test_case user_mod_w_none +user_mod_w_none_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:0 ${PW} usermod foo -w none + atf_check -s exit:0 -o match:"^foo::" grep "^foo:" $HOME/master.passwd +} + +atf_test_case user_mod_w_random +user_mod_w_random_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + password=`${PW} usermod foo -w random | cat` + passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd` + atf_check -s exit:0 -o inline:$passhash \ + $(atf_get_srcdir)/crypt $passhash "$password" +} + +atf_test_case user_mod_w_yes +user_mod_w_yes_body() { + populate_etc_skel + + atf_check -s exit:0 ${PW} useradd foo + atf_check -s exit:0 ${PW} usermod foo -w yes + passhash=`awk -F ':' '/^foo:/ {print $2}' $HOME/master.passwd` + atf_check -s exit:0 -o inline:$passhash \ + $(atf_get_srcdir)/crypt $passhash "foo" +} + + atf_init_test_cases() { atf_add_test_case user_mod atf_add_test_case user_mod_noupdate @@ -219,4 +270,9 @@ atf_init_test_cases() { atf_add_test_case user_mod_H atf_add_test_case user_mod_renamehome atf_add_test_case user_mod_uid + atf_add_test_case user_mod_w_error + atf_add_test_case user_mod_w_no + atf_add_test_case user_mod_w_none + atf_add_test_case user_mod_w_random + atf_add_test_case user_mod_w_yes } |