From f35bbd5a3f572a6283c1cec3bcd967dcce2547ad Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 28 Feb 2022 11:29:38 -0700 Subject: [PATCH] Move the cvtsudoers/sudoers/testsudoers/visudo tests into a script. It is easier to maintain these tests in script form. The output now more closely matches that of the other tests. The harness script can be invoked directly and supports running specific tests. --- .gitignore | 1 + .hgignore | 2 +- MANIFEST | 1 + configure | 3 +- configure.ac | 2 +- plugins/sudoers/Makefile.in | 128 +----------------------- plugins/sudoers/harness.in | 193 ++++++++++++++++++++++++++++++++++++ 7 files changed, 203 insertions(+), 127 deletions(-) create mode 100755 plugins/sudoers/harness.in diff --git a/.gitignore b/.gitignore index e5ba2ae30..a51b27425 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,7 @@ logsrvd/sudo_sendlog logsrvd/fuzz_[a-z]* plugins/sudoers/cvtsudoers +plugins/sudoers/harness plugins/sudoers/sudoers plugins/sudoers/sudoreplay plugins/sudoers/testsudoers diff --git a/.hgignore b/.hgignore index c0e733ef0..44db85ee5 100644 --- a/.hgignore +++ b/.hgignore @@ -65,7 +65,7 @@ Makefile$ ^logsrvd/sudo_(logsrvd|sendlog)$ ^logsrvd/fuzz_logsrvd_conf$ -^plugins/sudoers/(cvtsudoers|sudoers|sudoreplay|testsudoers|tsdump|visudo|prologue|check_[a-z0-9_]+)$ +^plugins/sudoers/(cvtsudoers|harness|sudoers|sudoreplay|testsudoers|tsdump|visudo|prologue|check_[a-z0-9_]+)$ ^plugins/sudoers/fuzz_(policy|sudoers(_ldif)?)$ ^plugins/sudoers/.*\.(out|toke|err|json|ldif|sudo|ldif2sudo)$ ^plugins/sudoers/regress/iolog_plugin/iolog$ diff --git a/MANIFEST b/MANIFEST index 1f1c968da..e9f765885 100644 --- a/MANIFEST +++ b/MANIFEST @@ -602,6 +602,7 @@ plugins/sudoers/gram.c plugins/sudoers/gram.h plugins/sudoers/gram.y plugins/sudoers/group_plugin.c +plugins/sudoers/harness.in plugins/sudoers/hexchar.c plugins/sudoers/ins_2001.h plugins/sudoers/ins_classic.h diff --git a/configure b/configure index 975dfdd9d..ddbe08ce9 100755 --- a/configure +++ b/configure @@ -32257,7 +32257,7 @@ elif test X"$TMPFILES_D" != X""; then fi -ac_config_files="$ac_config_files Makefile docs/Makefile examples/Makefile examples/sudoers examples/sudo.conf examples/sudo_logsrvd.conf examples/syslog.conf include/Makefile lib/eventlog/Makefile lib/fuzzstub/Makefile lib/iolog/Makefile lib/logsrv/Makefile lib/protobuf-c/Makefile lib/util/Makefile lib/util/util.exp logsrvd/Makefile src/intercept.exp src/sudo_usage.h src/Makefile plugins/audit_json/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/sample_approval/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers" +ac_config_files="$ac_config_files Makefile docs/Makefile examples/Makefile examples/sudoers examples/sudo.conf examples/sudo_logsrvd.conf examples/syslog.conf include/Makefile lib/eventlog/Makefile lib/fuzzstub/Makefile lib/iolog/Makefile lib/logsrv/Makefile lib/protobuf-c/Makefile lib/util/Makefile lib/util/util.exp logsrvd/Makefile src/intercept.exp src/sudo_usage.h src/Makefile plugins/audit_json/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/sample_approval/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/harness plugins/sudoers/sudoers" cat >confcache <<\_ACEOF @@ -33273,6 +33273,7 @@ do "plugins/sample_approval/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sample_approval/Makefile" ;; "plugins/system_group/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/system_group/Makefile" ;; "plugins/sudoers/Makefile") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/Makefile" ;; + "plugins/sudoers/harness") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/harness" ;; "plugins/sudoers/sudoers") CONFIG_FILES="$CONFIG_FILES plugins/sudoers/sudoers" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; diff --git a/configure.ac b/configure.ac index c2adf23ae..02c6c2fc7 100644 --- a/configure.ac +++ b/configure.ac @@ -5114,7 +5114,7 @@ elif test X"$TMPFILES_D" != X""; then AC_CONFIG_FILES([etc/init.d/sudo.conf]) fi -AC_CONFIG_FILES([Makefile docs/Makefile examples/Makefile examples/sudoers examples/sudo.conf examples/sudo_logsrvd.conf examples/syslog.conf include/Makefile lib/eventlog/Makefile lib/fuzzstub/Makefile lib/iolog/Makefile lib/logsrv/Makefile lib/protobuf-c/Makefile lib/util/Makefile lib/util/util.exp logsrvd/Makefile src/intercept.exp src/sudo_usage.h src/Makefile plugins/audit_json/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/sample_approval/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/sudoers]) +AC_CONFIG_FILES([Makefile docs/Makefile examples/Makefile examples/sudoers examples/sudo.conf examples/sudo_logsrvd.conf examples/syslog.conf include/Makefile lib/eventlog/Makefile lib/fuzzstub/Makefile lib/iolog/Makefile lib/logsrv/Makefile lib/protobuf-c/Makefile lib/util/Makefile lib/util/util.exp logsrvd/Makefile src/intercept.exp src/sudo_usage.h src/Makefile plugins/audit_json/Makefile plugins/sample/Makefile plugins/group_file/Makefile plugins/sample_approval/Makefile plugins/system_group/Makefile plugins/sudoers/Makefile plugins/sudoers/harness plugins/sudoers/sudoers]) AC_OUTPUT diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in index a61ba3c3f..7b24e4265 100644 --- a/plugins/sudoers/Makefile.in +++ b/plugins/sudoers/Makefile.in @@ -673,130 +673,10 @@ check: $(TEST_PROGS) visudo testsudoers cvtsudoers check-fuzzer if test -f check_symbols; then \ ./check_symbols .libs/sudoers.so $(shlib_exp) || rval=`expr $$rval + $$?`; \ fi; \ - passed=0; failed=0; total=0; \ - mkdir -p regress/sudoers; \ - dir=sudoers; \ - for t in $(srcdir)/regress/$$dir/*.in; do \ - base=`basename $$t .in`; \ - out="regress/sudoers/$${base}.out"; \ - toke="regress/sudoers/$${base}.toke"; \ - json="regress/sudoers/$${base}.json"; \ - ldif="regress/sudoers/$${base}.ldif"; \ - sudo="regress/sudoers/$${base}.sudo"; \ - ldif2sudo="regress/sudoers/$${base}.ldif2sudo"; \ - ./testsudoers -dt <$$t >$$out 2>$$toke || true; \ - if cmp $$out $(srcdir)/$$out.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (parse): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (parse): FAIL"; \ - diff $$out $(srcdir)/$$out.ok || true; \ - fi; \ - total=`expr $$total + 1`; \ - if cmp $$toke $(srcdir)/$$toke.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (toke): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (toke): FAIL"; \ - diff $$toke $(srcdir)/$$toke.ok || true; \ - fi; \ - total=`expr $$total + 1`; \ - ./cvtsudoers -c "" -f json $$t >$$json 2>/dev/null || true; \ - total=`expr $$total + 1`; \ - if cmp $$json $(srcdir)/$$json.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (json): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (json): FAIL"; \ - diff $$json $(srcdir)/$$json.ok || true; \ - fi; \ - SUDOERS_BASE="ou=SUDOers,dc=sudo,dc=ws" \ - ./cvtsudoers -c "" -f ldif < $$t >$$ldif 2>/dev/null || true; \ - total=`expr $$total + 1`; \ - if cmp $$ldif $(srcdir)/$$ldif.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (ldif): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base: (ldif) FAIL"; \ - diff $$ldif $(srcdir)/$$ldif.ok || true; \ - fi; \ - ./cvtsudoers -c "" -f sudoers $$t >$$sudo 2>/dev/null || true; \ - total=`expr $$total + 1`; \ - if ./visudo -qcf $$sudo; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (reparse): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base: (reparse) FAIL"; \ - ./visudo -cf $$sudo || true; \ - fi; \ - if test -s $(srcdir)/$$ldif.ok; then \ - ./cvtsudoers -c "" -i ldif -f sudoers $(srcdir)/$$ldif.ok >$$ldif2sudo || true; \ - total=`expr $$total + 1`; \ - if cmp $$ldif2sudo $(srcdir)/$$ldif2sudo.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (ldif2sudo): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base: (ldif2sudo) FAIL"; \ - diff $$ldif $(srcdir)/$$ldif.ok || true; \ - fi; \ - fi; \ - done; \ - echo "$$dir: $$passed/$$total tests passed; $$failed/$$total tests failed"; \ - if test $$failed -ne 0; then \ - rval=`expr $$rval + $$failed`; \ - fi; \ - for dir in testsudoers visudo cvtsudoers; do \ - mkdir -p regress/$$dir; \ - passed=0; failed=0; total=0; \ - for t in $(srcdir)/regress/$$dir/*.sh; do \ - base=`basename $$t .sh`; \ - out="regress/$$dir/$${base}.out"; \ - err="regress/$$dir/$${base}.err"; \ - status=0; \ - TESTSUDOERS=./testsudoers VISUDO=./visudo \ - CVTSUDOERS=./cvtsudoers TESTDIR=$(srcdir)/regress/$$dir \ - $(SHELL) $$t >$$out 2>$$err || status=$$?; \ - if cmp $$out $(srcdir)/$$out.ok >/dev/null; then \ - if test $$status -ne 0; then \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (exit $$status): FAIL"; \ - else \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base: OK"; \ - fi; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base: FAIL"; \ - diff $$out $(srcdir)/$$out.ok || true; \ - fi; \ - total=`expr $$total + 1`; \ - if test -s $(srcdir)/$$err.ok; then \ - if cmp $$err $(srcdir)/$$err.ok >/dev/null; then \ - passed=`expr $$passed + 1`; \ - echo "$$dir/$$base (stderr): OK"; \ - else \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (stderr): FAIL"; \ - diff $$err $(srcdir)/$$err.ok || true; \ - fi; \ - total=`expr $$total + 1`; \ - elif test -s $$err; then \ - failed=`expr $$failed + 1`; \ - echo "$$dir/$$base (stderr): FAIL"; \ - cat $$err 1>&2; \ - fi; \ - done; \ - echo "$$dir: $$passed/$$total tests passed; $$failed/$$total tests failed"; \ - if test $$failed -ne 0; then \ - rval=`expr $$rval + $$failed`; \ - fi; \ - done; \ + AWK=$(AWK) $(SHELL) harness sudoers || rval=`expr $$rval + $$?`; \ + AWK=$(AWK) $(SHELL) harness testsudoers || rval=`expr $$rval + $$?`; \ + AWK=$(AWK) $(SHELL) harness visudo || rval=`expr $$rval + $$?`; \ + AWK=$(AWK) $(SHELL) harness cvtsudoers || rval=`expr $$rval + $$?`; \ exit $$rval; \ fi diff --git a/plugins/sudoers/harness.in b/plugins/sudoers/harness.in new file mode 100755 index 000000000..4d005989b --- /dev/null +++ b/plugins/sudoers/harness.in @@ -0,0 +1,193 @@ +#!/bin/sh +# +# Simple test harness for sudoers tests. +# usage: harness [-v] test_group [test_name ...] +# +srcdir="@srcdir@" +SHELL=@SHELL@ +verbose=0 +rval=0 +ntests=0 +errors=0 + +umask 022 + +if [ "$1" = "-v" ]; then + verbose=1 + shift +fi + +if [ $# -eq 0 ]; then + echo "usage: harness test_group [test_name ...]" >&2 + exit 1 +fi +group="$1" +shift + +if [ ! -d "$srcdir/regress/$group" ]; then + echo "missing test group: $srcdir/regress/$group" >&2 + exit 1 +fi + +case "$group" in +sudoers) + mkdir -p "regress/$group" + if [ $# -eq 0 ]; then + tests= + for t in $srcdir/regress/$group/*.in; do + tests="$tests `basename $t .in`" + done + set -- $tests + fi + while [ $# -ne 0 ]; do + test="$1" + shift + in="$srcdir/regress/sudoers/${test}.in" + out="regress/sudoers/${test}.out" + toke="regress/sudoers/${test}.toke" + json="regress/sudoers/${test}.json" + ldif="regress/sudoers/${test}.ldif" + sudo="regress/sudoers/${test}.sudo" + ldif2sudo="regress/sudoers/${test}.ldif2sudo" + + ./testsudoers -dt <$in >$out 2>$toke || true + ntests=`expr $ntests + 1` + if cmp $out $srcdir/$out.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (parse): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (parse): FAIL" + diff $out $srcdir/$out.ok || true + fi + ntests=`expr $ntests + 1` + if cmp $toke $srcdir/$toke.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (toke): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (toke): FAIL" + diff $toke $srcdir/$toke.ok || true + fi + + ./cvtsudoers -c "" -f json $in >$json 2>/dev/null || true + ntests=`expr $ntests + 1` + if cmp $json $srcdir/$json.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (json): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (json): FAIL" + diff $json $srcdir/$json.ok || true + fi + + SUDOERS_BASE="ou=SUDOers,dc=sudo,dc=ws" \ + ./cvtsudoers -c "" -f ldif < $in >$ldif 2>/dev/null || true + ntests=`expr $ntests + 1` + if cmp $ldif $srcdir/$ldif.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (ldif): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test: (ldif) FAIL" + diff $ldif $srcdir/$ldif.ok || true + fi + + ./cvtsudoers -c "" -f sudoers $in >$sudo 2>/dev/null || true + ntests=`expr $ntests + 1` + if ./visudo -qcf $sudo; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (reparse): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test: (reparse) FAIL" + ./visudo -cf $sudo || true + fi + + if test -s $srcdir/$ldif.ok; then + ./cvtsudoers -c "" -i ldif -f sudoers $srcdir/$ldif.ok >$ldif2sudo || true + ntests=`expr $ntests + 1` + if cmp $ldif2sudo $srcdir/$ldif2sudo.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (ldif2sudo): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test: (ldif2sudo) FAIL" + diff $ldif $srcdir/$ldif.ok || true + fi + fi + done + ${AWK-awk} -v group=$group -v ntests=$ntests -v errors=$errors \ + 'END {printf("%s: %d tests run, %d errors, %d%% success rate\n", group, ntests, errors, (ntests - errors) * 100 / ntests)}' < /dev/null + if test $errors -ne 0; then + rval=`expr $rval + $errors` + fi + ;; +*) + TESTSUDOERS=./testsudoers; export TESTSUDOERS + VISUDO=./visudo; export VISUDO + CVTSUDOERS=./cvtsudoers; export CVTSUDOERS + mkdir -p "regress/$group" + if [ $# -eq 0 ]; then + tests= + for t in $srcdir/regress/$group/*.sh; do + tests="$tests `basename $t .sh`" + done + set -- $tests + fi + while [ $# -ne 0 ]; do + test="$1" + shift + + cmd="$srcdir/regress/$group/${test}.sh" + out="regress/$group/${test}.out" + err="regress/$group/${test}.err" + status=0 + TESTDIR=$srcdir/regress/$group $SHELL $cmd >$out 2>$err || status=$? + ntests=`expr $ntests + 1` + if cmp $out $srcdir/$out.ok >/dev/null; then + if test $status -eq 0; then + if [ $verbose -eq 1 ]; then + echo "$group/$test: OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (exit $status): FAIL" + fi + else + errors=`expr $errors + 1` + echo "$group/$test: FAIL" + diff $out $srcdir/$out.ok || true + fi + if test -s $srcdir/$err.ok; then + ntests=`expr $ntests + 1` + if cmp $err $srcdir/$err.ok >/dev/null; then + if [ $verbose -eq 1 ]; then + echo "$group/$test (stderr): OK" + fi + else + errors=`expr $errors + 1` + echo "$group/$test (stderr): FAIL" + diff $err $srcdir/$err.ok || true + fi + elif test -s $err; then + errors=`expr $errors + 1` + echo "$group/$test (stderr): FAIL" + cat $err 1>&2 + fi + done + ${AWK-awk} -v group=$group -v ntests=$ntests -v errors=$errors \ + 'END {printf("%s: %d tests run, %d errors, %d%% success rate\n", group, ntests, errors, (ntests - errors) * 100 / ntests)}' < /dev/null + if test $errors -ne 0; then + rval=`expr $rval + $errors` + fi + ;; +esac + +exit $rval