krb5 commit: Work around macOS SIP in the test suite
Greg Hudson <[email protected]>
| Newsgroups | gmane.comp.encryption.kerberos.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://github.com/krb5/krb5/commit/c423f13cc2f3fbdbf48390535cb1629b99b0eb27 commit c423f13cc2f3fbdbf48390535cb1629b99b0eb27 Author: Greg Hudson <[email protected]> Date: Thu Dec 19 13:52:32 2019 -0500 Work around macOS SIP in the test suite In macOS 10.11 and later with System Integrity Protection enabled, system programs (including the shell) purge DYLD_LIBRARY_PATH from the environment at startup. As a result, any part of "make check" which runs via a shell script must explicitly restore the runtime environment. Add a common rule for runenv.sh, and create and source it where shell scripts are run. Dejagnu's runtest is a shell script, so create a tcl file for the kadmin and RPC unit tests and source it from unix.exp. Avoid using the shell to run commands in several places. Use return_trace=True for tests that previously indirected through /usr/bin/env. Do not include <malloc.h> in t_parse_host_string.c, as it does not exist on macOS and is not needed. Skip the iprop tests on macOS when SIP is enabled, as signal restrictions appear to prevent the kpropd child process from informing the parent process that a full resync has completed. In net-server.c, set SO_REUSEPORT as well as SO_REUSEADDR on listener sockets. Otherwise the krb5kdc processes run by the test suite sometimes fail to start with "address in use" errors. In configure.ac, only generate po/Makefile if we will descend into it. src/config/post.in | 14 +++++++++++++- src/configure.ac | 2 +- src/kadmin/testing/scripts/Makefile.in | 2 +- src/kadmin/testing/scripts/init_db | 2 ++ src/kadmin/testing/scripts/start_servers_local | 6 ++++-- src/kdc/Makefile.in | 2 +- src/kdc/rtscript | 1 + src/lib/apputils/net-server.c | 12 +++++++++++- src/lib/kadm5/unit-test/Makefile.in | 12 ++++++++---- src/lib/kadm5/unit-test/config/unix.exp | 2 ++ src/lib/kadm5/unit-test/lib/lib.t | 2 +- src/lib/krb5/krb/Makefile.in | 2 +- src/lib/krb5/krb/t_parse_host_string.c | 1 - src/lib/krb5/krb/transit-tests | 2 ++ src/lib/krb5/krb/walktree-tests | 2 ++ src/lib/rpc/unit-test/Makefile.in | 8 ++++++-- src/lib/rpc/unit-test/config/unix.exp | 2 ++ src/plugins/kdb/db2/libdb2/test/Makefile.in | 2 +- src/plugins/kdb/db2/libdb2/test/run.test | 2 ++ src/tests/dejagnu/config/default.exp | 3 +-- src/tests/t_changepw.py | 8 ++------ src/tests/t_iprop.py | 10 ++++++++++ src/tests/t_keydata.py | 20 ++++++++------------ src/tests/t_referral.py | 8 ++------ 24 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/config/post.in b/src/config/post.in index 2afff8b..4d0cb75 100644 --- a/src/config/post.in +++ b/src/config/post.in @@ -7,6 +7,18 @@ all: check-windows: +# In a few parts of "make check" we run shell scripts which run +# programs linked against krb5 libraries. On macOS 10.11 and higher, +# DYLD_LIBRARY_PATH is cleared by the shell unless System Integrity +# Protection is turned off, so we need to set runtime linker +# environment variables from within test scripts. A Makefile.in which +# runs shell script tests should make its check rule depend on +# runenv.sh and make each script begin with ". ./runenv.sh". +runenv.sh: + $(RUN_SETUP); for i in $(RUN_VARS); do \ + eval echo "$$i=\\\"\$$$$i\\\""; \ + echo "export $$i"; done > $@ + ############################## # dependency generation # @@ -156,7 +168,7 @@ clean: clean-$(WHAT) clean-unix:: $(RM) $(OBJS) $(DEPTARGETS_CLEAN) $(EXTRA_FILES) - $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog testtrace + $(RM) et-[ch]-*.et et-[ch]-*.[ch] testlog testtrace runenv.sh -$(RM) -r testdir clean-windows:: diff --git a/src/configure.ac b/src/configure.ac index 47736f5..234f428 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -134,6 +134,7 @@ if test "$enable_nls" != no; then AC_CHECK_PROG(MSGFMT,msgfmt,msgfmt) if test x"$MSGFMT" != x; then + K5_GEN_MAKEFILE(po) po=po fi @@ -1537,5 +1538,4 @@ V5_AC_OUTPUT_MAKEFILE(. tests tests/resolve tests/asn.1 tests/create tests/hammer tests/verify tests/gssapi tests/dejagnu tests/threads tests/shlib tests/gss-threads tests/misc - po ) diff --git a/src/kadmin/testing/scripts/Makefile.in b/src/kadmin/testing/scripts/Makefile.in index fd0fd29..6359305 100644 --- a/src/kadmin/testing/scripts/Makefile.in +++ b/src/kadmin/testing/scripts/Makefile.in @@ -1,7 +1,7 @@ mydir=kadmin$(S)testing$(S)scripts BUILDTOP=$(REL)..$(S)..$(S).. -all: env-setup.sh $(GEN_SCRIPTS) +all: env-setup.sh runenv.sh $(GEN_SCRIPTS) # Should only rebuild env_setup.sh here (use CONFIG_FILES=), but the weird krb5 # makefile post-processing is unconditional and would trash the makefile. diff --git a/src/kadmin/testing/scripts/init_db b/src/kadmin/testing/scripts/init_db index 571cab5..e65826c 100755 --- a/src/kadmin/testing/scripts/init_db +++ b/src/kadmin/testing/scripts/init_db @@ -31,6 +31,8 @@ MODDIR=$TOP/../plugins/kdb SBIN=$TOP/keytab:$TOP/server DUMMY=${REALM=SECURE-TEST.OV.COM}; export REALM +. ./runenv.sh + if [ ! -d $MODDIR ]; then echo "+++" 1>&2 echo "+++ Error! $MODDIR does not exist!" 1>&2 diff --git a/src/kadmin/testing/scripts/start_servers_local b/src/kadmin/testing/scripts/start_servers_local index c5efc8e..998ef91 100755 --- a/src/kadmin/testing/scripts/start_servers_local +++ b/src/kadmin/testing/scripts/start_servers_local @@ -7,6 +7,8 @@ DUMMY=${SRVTCL=$TESTDIR/util/kadm5_srv_tcl}; export SRVTCL DUMMY=${STOP_SERVERS_LOCAL=$STESTDIR/scripts/stop_servers_local} DUMMY=${KRB5RCACHEDIR=$TESTDIR} ; export KRB5RCACHEDIR +. ./runenv.sh + if [ -d /usr/tmp ]; then usrtmp=/usr/tmp else @@ -108,7 +110,7 @@ fi kdc_args="-R dfl:kdc_rcache.$USER" -(trap "" 2; cd $TOP/../kdc; ./krb5kdc $kdc_args; touch $kdc_start_file) \ +(trap "" 2; $TOP/../kdc/krb5kdc $kdc_args; touch $kdc_start_file) \ < /dev/null > $usrtmp/kdc-log.$USER 2>&1 & s=1 @@ -120,7 +122,7 @@ ovadm_args=-W rm -f $adm_start_file -(sleep 1; cd $TOP/server; ./kadmind $ovadm_args; \ +(sleep 1; $TOP/server/kadmind $ovadm_args; \ touch $adm_start_file) < /dev/null > $usrtmp/kadm-log.$USER 2>&1 & # wait until they start diff --git a/src/kdc/Makefile.in b/src/kdc/Makefile.in index 117a8f5..c560741 100644 --- a/src/kdc/Makefile.in +++ b/src/kdc/Makefile.in @@ -69,7 +69,7 @@ krb5kdc: $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB) $(VE rtest: $(RT_OBJS) $(KDB5_DEPLIBS) $(KADM_COMM_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o rtest $(RT_OBJS) $(KDB5_LIBS) $(KADM_COMM_LIBS) $(KRB5_BASE_LIBS) -check-unix: rtest +check-unix: rtest runenv.sh $(RUN_TEST) $(srcdir)/rtscript > test.out cmp test.out $(srcdir)/rtest.good $(RM) test.out diff --git a/src/kdc/rtscript b/src/kdc/rtscript index 8803e33..53da7da 100755 --- a/src/kdc/rtscript +++ b/src/kdc/rtscript @@ -26,6 +26,7 @@ # # should print out contents of rtest.good # +. ./runenv.sh ./rtest "" ATHENA.MIT.EDU SUB1W.CS.WASHINGTON.EDU SUB1M.ATHENA.MIT.EDU ./rtest ATHENA.MIT.EDU MIT.EDU SUB1W.CS.WASHINGTON.EDU SUB1M.ATHENA.MIT.EDU ./rtest "MIT.EDU,ATHENA." EDU SUB1W.CS.WASHINGTON.EDU SUB1M.ATHENA.MIT.EDU diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c index c685687..6b18dfe 100644 --- a/src/lib/apputils/net-server.c +++ b/src/lib/apputils/net-server.c @@ -73,7 +73,17 @@ static int max_tcp_or_rpc_data_connections = 45; static int setreuseaddr(int sock, int value) { - return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); + int st; + + st = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)); + if (st) + return st; +#ifdef SO_REUSEPORT + st = setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &value, sizeof(value)); + if (st) + return st; +#endif + return 0; } #if defined(IPV6_V6ONLY) diff --git a/src/lib/kadm5/unit-test/Makefile.in b/src/lib/kadm5/unit-test/Makefile.in index ebf31fc..68fa097 100644 --- a/src/lib/kadm5/unit-test/Makefile.in +++ b/src/lib/kadm5/unit-test/Makefile.in @@ -56,6 +56,10 @@ server-setkey-test: setkey-test.o $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o server-setkey-test setkey-test.o \ $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) +runenv.exp: Makefile + $(RUN_SETUP); for i in $(RUN_VARS); do \ + eval echo "set env\($$i\) \$$$$i"; done > runenv.exp + # # The unit-test targets # @@ -94,20 +98,20 @@ test-destroy: destroy-test test-setkey-client: client-setkey-test $(ENV_SETUP) $(VALGRIND) ./client-setkey-test testkeys admin admin -unit-test-client-setup: +unit-test-client-setup: runenv.sh $(ENV_SETUP) $(VALGRIND) $(START_SERVERS) unit-test-client-cleanup: $(ENV_SETUP) $(STOP_SERVERS) -unit-test-server-setup: +unit-test-server-setup: runenv.sh $(ENV_SETUP) $(VALGRIND) $(START_SERVERS_LOCAL) unit-test-server-cleanup: $(ENV_SETUP) $(STOP_SERVERS_LOCAL) unit-test-client-body: site.exp test-noauth test-destroy test-handle-client \ - test-setkey-client + test-setkey-client runenv.exp $(ENV_SETUP) $(RUNTEST) --tool api RPC=1 API=$(CLNTTCL) \ KINIT=$(BUILDTOP)/clients/kinit/kinit \ KDESTROY=$(BUILDTOP)/clients/kdestroy/kdestroy \ @@ -136,4 +140,4 @@ clean: $(RM) lock-test lock-test.o $(RM) server-iter-test iter-test.o $(RM) server-setkey-test client-setkey-test setkey-test.o - $(RM) *.log *.plog *.sum *.psum unit-test-log.* + $(RM) *.log *.plog *.sum *.psum unit-test-log.* runenv.exp diff --git a/src/lib/kadm5/unit-test/config/unix.exp b/src/lib/kadm5/unit-test/config/unix.exp index 996e2b0..ca67095 100644 --- a/src/lib/kadm5/unit-test/config/unix.exp +++ b/src/lib/kadm5/unit-test/config/unix.exp @@ -1,3 +1,5 @@ +source runenv.exp + set prompt "% " set stty_init {-onlcr -opost intr \^C kill \^U} set kadmin_local $KADMIN_LOCAL diff --git a/src/lib/kadm5/unit-test/lib/lib.t b/src/lib/kadm5/unit-test/lib/lib.t index 1cd1e04..3444775 100644 --- a/src/lib/kadm5/unit-test/lib/lib.t +++ b/src/lib/kadm5/unit-test/lib/lib.t @@ -264,7 +264,7 @@ proc kdestroy {} { if {[info exists errorInfo]} { set saveErrorInfo $errorInfo } - catch "system $KDESTROY -5 2>/dev/null" + catch "exec $KDESTROY -5 2>/dev/null" if {[info exists saveErrorCode]} { set errorCode $saveErrorCode } elseif {[info exists errorCode]} { diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index 7734a47..f63de8a 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -475,7 +475,7 @@ TEST_PROGS= t_walk_rtree t_kerb t_ser t_deltat t_expand t_authdata t_pac \ t_in_ccache t_cc_config t_copy_context t_princ t_etypes t_vfy_increds \ t_response_items t_sname_match t_valid_times t_get_etype_info -check-unix: $(TEST_PROGS) +check-unix: $(TEST_PROGS) runenv.sh $(RUN_TEST_LOCAL_CONF) ./t_kerb \ parse_name tytso \ parse_name tytso@SHAZAAM \ diff --git a/src/lib/krb5/krb/t_parse_host_string.c b/src/lib/krb5/krb/t_parse_host_string.c index 001b773..e9c6f1c 100644 --- a/src/lib/krb5/krb/t_parse_host_string.c +++ b/src/lib/krb5/krb/t_parse_host_string.c @@ -32,7 +32,6 @@ #include "k5-int.h" #include "k5-cmocka.h" -#include <malloc.h> /* Call k5_parse_host_string() and check the result against the expected code, * hostname, and port. */ diff --git a/src/lib/krb5/krb/transit-tests b/src/lib/krb5/krb/transit-tests index 8ffb9c3..dc5fab6 100755 --- a/src/lib/krb5/krb/transit-tests +++ b/src/lib/krb5/krb/transit-tests @@ -1,5 +1,7 @@ #!/bin/sh +. ./runenv.sh + # Test the chk_trans.c code. # BUG: Currently only tests expansion, not validation. diff --git a/src/lib/krb5/krb/walktree-tests b/src/lib/krb5/krb/walktree-tests index 17f6eae..f316d80 100644 --- a/src/lib/krb5/krb/walktree-tests +++ b/src/lib/krb5/krb/walktree-tests @@ -1,5 +1,7 @@ #!/bin/sh +. ./runenv.sh + # Test the walk_rtree.c code. # diff --git a/src/lib/rpc/unit-test/Makefile.in b/src/lib/rpc/unit-test/Makefile.in index 46f2f1d..0b6e520 100644 --- a/src/lib/rpc/unit-test/Makefile.in +++ b/src/lib/rpc/unit-test/Makefile.in @@ -16,6 +16,10 @@ server: server.o rpc_test_svc.o $(GSSRPC_DEPLIBS) $(KRB5_BASE_DEPLIBS) client.o server.o: rpc_test.h +runenv.exp: Makefile + $(RUN_SETUP); for i in $(RUN_VARS); do \ + eval echo "set env\($$i\) \$$$$i"; done > runenv.exp + # If rpc_test.h and rpc_test_*.c do not work on your system, you can # try using rpcgen by uncommenting these lines (be sure to uncomment # then in the generated not Makefile.in). @@ -42,7 +46,7 @@ unit-test-: unit-test-ok: unit-test-body PASS=@PASS@ -unit-test-body: +unit-test-body: runenv.sh runenv.exp $(RM) krb5cc_rpc_test_* $(ENV_SETUP) $(VALGRIND) $(START_SERVERS) RPC_TEST_KEYTAB=/tmp/rpc_test_keytab.$$$$ ; export RPC_TEST_KEYTAB ; \ @@ -62,5 +66,5 @@ unit-test-body: clean: $(RM) server client - $(RM) dbg.log rpc_test.log rpc_test.sum + $(RM) dbg.log rpc_test.log rpc_test.sum runenv.exp diff --git a/src/lib/rpc/unit-test/config/unix.exp b/src/lib/rpc/unit-test/config/unix.exp index ed179bb..18da62b 100644 --- a/src/lib/rpc/unit-test/config/unix.exp +++ b/src/lib/rpc/unit-test/config/unix.exp @@ -2,6 +2,8 @@ # $Id$ # +source runenv.exp + set kill /bin/kill set sleep /bin/sleep set kinit $KINIT diff --git a/src/plugins/kdb/db2/libdb2/test/Makefile.in b/src/plugins/kdb/db2/libdb2/test/Makefile.in index 58eaf6f..d7a22b1 100644 --- a/src/plugins/kdb/db2/libdb2/test/Makefile.in +++ b/src/plugins/kdb/db2/libdb2/test/Makefile.in @@ -22,7 +22,7 @@ t.le.db: $(srcdir)/t.le.txt t.be.db t.le.db: $(PERL) -ne 'chomp; print pack("H*", $$_);' $? > $@ -check: dbtest t.be.db t.le.db +check: dbtest t.be.db t.le.db runenv.sh $(RUN_SETUP) srcdir=$(srcdir) TMPDIR=$(TMPDIR) $(VALGRIND) $(FCTSH) $(srcdir)/run.test bttest.o: $(srcdir)/btree.tests/main.c diff --git a/src/plugins/kdb/db2/libdb2/test/run.test b/src/plugins/kdb/db2/libdb2/test/run.test index 8d92257..ebce8e2 100644 --- a/src/plugins/kdb/db2/libdb2/test/run.test +++ b/src/plugins/kdb/db2/libdb2/test/run.test @@ -3,6 +3,8 @@ # @(#)run.test 8.13 (Berkeley) 11/2/95 # +. ./runenv.sh + # db regression tests main() { diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp index 4cd7775..c246517 100644 --- a/src/tests/dejagnu/config/default.exp +++ b/src/tests/dejagnu/config/default.exp @@ -1333,7 +1333,6 @@ proc start_kpropd {} { # success, 0 on failure. proc start_kerberos_daemons { standalone } { - global BINSH global REALMNAME global KRB5KDC global KADMIND @@ -1425,7 +1424,7 @@ proc start_kerberos_daemons { standalone } { envstack_push setup_kerberos_env kdc file delete $kadmind_pidfile - spawn $BINSH -c "exec $KADMIND -r $REALMNAME -W -nofork -P $kadmind_pidfile" + spawn $KADMIND -r $REALMNAME -W -nofork -P $kadmind_pidfile envstack_pop set kadmind_pid [exp_pid] set kadmind_spawn_id $spawn_id diff --git a/src/tests/t_changepw.py b/src/tests/t_changepw.py index 211cda6..573bdbd 100755 --- a/src/tests/t_changepw.py +++ b/src/tests/t_changepw.py @@ -13,15 +13,11 @@ realm.run([kinit, realm.user_princ], input=pwinput) # Do the same thing with FAST, with tracing turned on. realm.run([kadminl, 'modprinc', '-pwexpire', '1 day ago', 'user']) pwinput = 'abcd\nefgh\nefgh\n' -tracefile = os.path.join(realm.testdir, 'trace') -realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-T', realm.ccache, - realm.user_princ], input=pwinput) +out, trace = realm.run([kinit, '-T', realm.ccache, realm.user_princ], + input=pwinput, return_trace=True) # Read the trace and check that FAST was used when getting the # kadmin/changepw ticket. -f = open(tracefile, 'r') -trace = f.read() -f.close() getting_changepw = fast_used_for_changepw = False for line in trace.splitlines(): if 'Getting initial credentials for user@' in line: diff --git a/src/tests/t_iprop.py b/src/tests/t_iprop.py index 46cb075..371f3a2 100755 --- a/src/tests/t_iprop.py +++ b/src/tests/t_iprop.py @@ -3,6 +3,16 @@ import re from k5test import * +# On macOS with System Integrity Protection enabled, this script hangs +# in the wait_for_prop() call after starting the first kpropd process, +# most likely due to signal restrictions preventing the listening +# child from informing the parent that a full resync was processed. +if which('csrutil'): + out = subprocess.check_output(['csrutil', 'status'], + universal_newlines=True) + if 'status: enabled' in out: + skip_rest('iprop tests', 'System Integrity Protection is enabled') + # Read lines from kpropd output until we are synchronized. Error if # full_expected is true and we didn't see a full propagation or vice # versa. diff --git a/src/tests/t_keydata.py b/src/tests/t_keydata.py index b37233b..baa40b6 100755 --- a/src/tests/t_keydata.py +++ b/src/tests/t_keydata.py @@ -20,34 +20,30 @@ realm.run([kadminl, 'getprinc', 'user'], expected_msg='vno 1') # Return true if patype appears to have been received in a hint list # from a KDC error message, based on the trace file fname. -def preauth_type_received(fname, patype): - f = open(fname, 'r') +def preauth_type_received(trace, patype): found = False - for line in f: + for line in trace.splitlines(): if 'Processing preauth types:' in line: ind = line.find('types:') - patypes = line[ind + 6:].strip().split(', ') + patypes = line[ind + 6:].split(', ') if str(patype) in patypes: found = True - f.close() return found # Make sure the KDC doesn't offer encrypted timestamp for a principal # with no keys. -tracefile = os.path.join(realm.testdir, 'trace') realm.run([kadminl, 'purgekeys', '-all', 'user']) realm.run([kadminl, 'modprinc', '+requires_preauth', 'user']) -realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, 'user'], expected_code=1) -if preauth_type_received(tracefile, 2): +out, trace = realm.run([kinit, 'user'], expected_code=1, return_trace=True) +if preauth_type_received(trace, 2): fail('encrypted timestamp') # Make sure it doesn't offer encrypted challenge either. realm.run([kadminl, 'addprinc', '-pw', 'fast', 'armor']) realm.kinit('armor', 'fast') -os.remove(tracefile) -realm.run(['env', 'KRB5_TRACE=' + tracefile, kinit, '-T', realm.ccache, - 'user'], expected_code=1) -if preauth_type_received(tracefile, 138): +out, trace = realm.run([kinit, '-T', realm.ccache, 'user'], expected_code=1, + return_trace=True) +if preauth_type_received(trace, 138): fail('encrypted challenge') success('Key data tests') diff --git a/src/tests/t_referral.py b/src/tests/t_referral.py index 1a82ad0..dc56561 100755 --- a/src/tests/t_referral.py +++ b/src/tests/t_referral.py @@ -100,12 +100,8 @@ refrealm.stop() mark('#7483 regression test') drealm = {'domain_realm': {'d': 'KRBTEST.COM'}} realm = K5Realm(kdc_conf=drealm, create_host=False) -tracefile = os.path.join(realm.testdir, 'trace') -realm.run(['env', 'KRB5_TRACE=' + tracefile, './gcred', 'srv-hst', 'a/x.d@'], - expected_code=1) -f = open(tracefile, 'r') -trace = f.read() -f.close() +out, trace = realm.run(['./gcred', 'srv-hst', 'a/x.d@'], expected_code=1, + return_trace=True) if 'back to same realm' in trace: fail('KDC returned referral to service realm') realm.stop()