From: Greg Hudson Date: Thu, 19 Dec 2019 18:52:32 +0000 (-0500) Subject: Work around macOS SIP in the test suite X-Git-Tag: krb5-1.18-beta1~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c423f13cc2f3fbdbf48390535cb1629b99b0eb27;p=thirdparty%2Fkrb5.git 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 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. --- diff --git a/src/config/post.in b/src/config/post.in index 2afff8ba34..4d0cb75353 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 47736f5585..234f4281c2 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 fd0fd2934e..6359305112 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 571cab5dbe..e65826c963 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 c5efc8e2cf..998ef9164d 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 117a8f561e..c560741245 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 8803e33253..53da7da832 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 c685687327..6b18dfe30b 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 ebf31fcfd6..68fa097ff6 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 996e2b0e69..ca67095923 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 1cd1e042ad..3444775cfa 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 7734a4785b..f63de8ab83 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 001b773895..e9c6f1c0e2 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 /* 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 8ffb9c351e..dc5fab682f 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 17f6eae115..f316d80cd1 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 46f2f1d4bc..0b6e5203da 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 ed179bbe3e..18da62be49 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 58eaf6f5b7..d7a22b1fc7 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 8d9225706a..ebce8e27c9 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 4cd7775c09..c24651737b 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 211cda6c3c..573bdbd49a 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 46cb075502..371f3a22b6 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 b37233b212..baa40b62ca 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 1a82ad019e..dc56561386 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()