1# $OpenBSD: test-exec.sh,v 1.94 2023/01/13 04:47:34 dtucker Exp $ 2# Placed in the Public Domain. 3 4#SUDO=sudo 5 6if [ ! -z "$TEST_SSH_ELAPSED_TIMES" ]; then 7 STARTTIME=`date '+%s'` 8fi 9 10if [ ! -z "$TEST_SSH_PORT" ]; then 11 PORT="$TEST_SSH_PORT" 12else 13 PORT=4242 14fi 15 16OBJ=$1 17if [ "x$OBJ" = "x" ]; then 18 echo '$OBJ not defined' 19 exit 2 20fi 21if [ ! -d $OBJ ]; then 22 echo "not a directory: $OBJ" 23 exit 2 24fi 25SCRIPT=$2 26if [ "x$SCRIPT" = "x" ]; then 27 echo '$SCRIPT not defined' 28 exit 2 29fi 30if [ ! -f $SCRIPT ]; then 31 echo "not a file: $SCRIPT" 32 exit 2 33fi 34if $TEST_SHELL -n $SCRIPT; then 35 true 36else 37 echo "syntax error in $SCRIPT" 38 exit 2 39fi 40unset SSH_AUTH_SOCK 41 42# Portable-specific settings. 43 44if [ -x /usr/ucb/whoami ]; then 45 USER=`/usr/ucb/whoami` 46elif whoami >/dev/null 2>&1; then 47 USER=`whoami` 48elif logname >/dev/null 2>&1; then 49 USER=`logname` 50else 51 USER=`id -un` 52fi 53if test -z "$LOGNAME"; then 54 LOGNAME="${USER}" 55 export LOGNAME 56fi 57 58# Unbreak GNU head(1) 59_POSIX2_VERSION=199209 60export _POSIX2_VERSION 61 62case `uname -s 2>/dev/null` in 63OSF1*) 64 BIN_SH=xpg4 65 export BIN_SH 66 ;; 67CYGWIN*) 68 os=cygwin 69 ;; 70esac 71 72# If configure tells us to use a different egrep, create a wrapper function 73# to call it. This means we don't need to change all the tests that depend 74# on a good implementation. 75if test "x${EGREP}" != "x"; then 76 egrep () 77{ 78 ${EGREP} "$@" 79} 80fi 81 82SRC=`dirname ${SCRIPT}` 83 84# defaults 85SSH=ssh 86SSHD=sshd 87SSHAGENT=ssh-agent 88SSHADD=ssh-add 89SSHKEYGEN=ssh-keygen 90SSHKEYSCAN=ssh-keyscan 91SFTP=sftp 92SFTPSERVER=/usr/libexec/openssh/sftp-server 93SCP=scp 94 95# Set by make_tmpdir() on demand (below). 96SSH_REGRESS_TMP= 97 98# Interop testing 99PLINK=plink 100PUTTYGEN=puttygen 101CONCH=conch 102 103# Tools used by multiple tests 104NC=$OBJ/netcat 105OPENSSL_BIN="${OPENSSL_BIN:-openssl}" 106 107if [ "x$TEST_SSH_SSH" != "x" ]; then 108 SSH="${TEST_SSH_SSH}" 109fi 110if [ "x$TEST_SSH_SSHD" != "x" ]; then 111 SSHD="${TEST_SSH_SSHD}" 112fi 113if [ "x$TEST_SSH_SSHAGENT" != "x" ]; then 114 SSHAGENT="${TEST_SSH_SSHAGENT}" 115fi 116if [ "x$TEST_SSH_SSHADD" != "x" ]; then 117 SSHADD="${TEST_SSH_SSHADD}" 118fi 119if [ "x$TEST_SSH_SSHKEYGEN" != "x" ]; then 120 SSHKEYGEN="${TEST_SSH_SSHKEYGEN}" 121fi 122if [ "x$TEST_SSH_SSHKEYSCAN" != "x" ]; then 123 SSHKEYSCAN="${TEST_SSH_SSHKEYSCAN}" 124fi 125if [ "x$TEST_SSH_SFTP" != "x" ]; then 126 SFTP="${TEST_SSH_SFTP}" 127fi 128if [ "x$TEST_SSH_SFTPSERVER" != "x" ]; then 129 SFTPSERVER="${TEST_SSH_SFTPSERVER}" 130fi 131if [ "x$TEST_SSH_SCP" != "x" ]; then 132 SCP="${TEST_SSH_SCP}" 133fi 134if [ "x$TEST_SSH_PLINK" != "x" ]; then 135 # Find real binary, if it exists 136 case "${TEST_SSH_PLINK}" in 137 /*) PLINK="${TEST_SSH_PLINK}" ;; 138 *) PLINK=`which ${TEST_SSH_PLINK} 2>/dev/null` ;; 139 esac 140fi 141if [ "x$TEST_SSH_PUTTYGEN" != "x" ]; then 142 # Find real binary, if it exists 143 case "${TEST_SSH_PUTTYGEN}" in 144 /*) PUTTYGEN="${TEST_SSH_PUTTYGEN}" ;; 145 *) PUTTYGEN=`which ${TEST_SSH_PUTTYGEN} 2>/dev/null` ;; 146 esac 147fi 148if [ "x$TEST_SSH_CONCH" != "x" ]; then 149 # Find real binary, if it exists 150 case "${TEST_SSH_CONCH}" in 151 /*) CONCH="${TEST_SSH_CONCH}" ;; 152 *) CONCH=`which ${TEST_SSH_CONCH} 2>/dev/null` ;; 153 esac 154fi 155if [ "x$TEST_SSH_PKCS11_HELPER" != "x" ]; then 156 SSH_PKCS11_HELPER="${TEST_SSH_PKCS11_HELPER}" 157fi 158if [ "x$TEST_SSH_SK_HELPER" != "x" ]; then 159 SSH_SK_HELPER="${TEST_SSH_SK_HELPER}" 160fi 161if [ "x$TEST_SSH_OPENSSL" != "x" ]; then 162 OPENSSL_BIN="${TEST_SSH_OPENSSL}" 163fi 164 165# Path to sshd must be absolute for rexec 166case "$SSHD" in 167/*) ;; 168*) SSHD=`which $SSHD` ;; 169esac 170 171case "$SSHAGENT" in 172/*) ;; 173*) SSHAGENT=`which $SSHAGENT` ;; 174esac 175 176# Record the actual binaries used. 177SSH_BIN=${SSH} 178SSHD_BIN=${SSHD} 179SSHAGENT_BIN=${SSHAGENT} 180SSHADD_BIN=${SSHADD} 181SSHKEYGEN_BIN=${SSHKEYGEN} 182SSHKEYSCAN_BIN=${SSHKEYSCAN} 183SFTP_BIN=${SFTP} 184SFTPSERVER_BIN=${SFTPSERVER} 185SCP_BIN=${SCP} 186 187if [ "x$USE_VALGRIND" != "x" ]; then 188 rm -rf $OBJ/valgrind-out $OBJ/valgrind-vgdb 189 mkdir -p $OBJ/valgrind-out $OBJ/valgrind-vgdb 190 # When using sudo ensure low-priv tests can write pipes and logs. 191 if [ "x$SUDO" != "x" ]; then 192 chmod 777 $OBJ/valgrind-out $OBJ/valgrind-vgdb 193 fi 194 VG_TEST=`basename $SCRIPT .sh` 195 196 # Some tests are difficult to fix. 197 case "$VG_TEST" in 198 reexec) 199 VG_SKIP=1 ;; 200 sftp-chroot) 201 if [ "x${SUDO}" != "x" ]; then 202 VG_SKIP=1 203 fi ;; 204 esac 205 206 if [ x"$VG_SKIP" = "x" ]; then 207 VG_LEAK="--leak-check=no" 208 if [ x"$VALGRIND_CHECK_LEAKS" != "x" ]; then 209 VG_LEAK="--leak-check=full" 210 fi 211 VG_IGNORE="/bin/*,/sbin/*,/usr/*,/var/*" 212 VG_LOG="$OBJ/valgrind-out/${VG_TEST}." 213 VG_OPTS="--track-origins=yes $VG_LEAK" 214 VG_OPTS="$VG_OPTS --trace-children=yes" 215 VG_OPTS="$VG_OPTS --trace-children-skip=${VG_IGNORE}" 216 VG_OPTS="$VG_OPTS --vgdb-prefix=$OBJ/valgrind-vgdb/" 217 VG_PATH="valgrind" 218 if [ "x$VALGRIND_PATH" != "x" ]; then 219 VG_PATH="$VALGRIND_PATH" 220 fi 221 VG="$VG_PATH $VG_OPTS" 222 SSH="$VG --log-file=${VG_LOG}ssh.%p $SSH" 223 SSHD="$VG --log-file=${VG_LOG}sshd.%p $SSHD" 224 SSHAGENT="$VG --log-file=${VG_LOG}ssh-agent.%p $SSHAGENT" 225 SSHADD="$VG --log-file=${VG_LOG}ssh-add.%p $SSHADD" 226 SSHKEYGEN="$VG --log-file=${VG_LOG}ssh-keygen.%p $SSHKEYGEN" 227 SSHKEYSCAN="$VG --log-file=${VG_LOG}ssh-keyscan.%p $SSHKEYSCAN" 228 SFTP="$VG --log-file=${VG_LOG}sftp.%p ${SFTP}" 229 SCP="$VG --log-file=${VG_LOG}scp.%p $SCP" 230 cat > $OBJ/valgrind-sftp-server.sh << EOF 231#!/bin/sh 232exec $VG --log-file=${VG_LOG}sftp-server.%p $SFTPSERVER "\$@" 233EOF 234 chmod a+rx $OBJ/valgrind-sftp-server.sh 235 SFTPSERVER="$OBJ/valgrind-sftp-server.sh" 236 fi 237fi 238 239# Logfiles. 240# SSH_LOGFILE should be the debug output of ssh(1) only 241# SSHD_LOGFILE should be the debug output of sshd(8) only 242# REGRESS_LOGFILE is the output of the test itself stdout and stderr 243if [ "x$TEST_SSH_LOGFILE" = "x" ]; then 244 TEST_SSH_LOGFILE=$OBJ/ssh.log 245fi 246if [ "x$TEST_SSHD_LOGFILE" = "x" ]; then 247 TEST_SSHD_LOGFILE=$OBJ/sshd.log 248fi 249if [ "x$TEST_REGRESS_LOGFILE" = "x" ]; then 250 TEST_REGRESS_LOGFILE=$OBJ/regress.log 251fi 252 253# If set, keep track of successful tests and skip them them if we've 254# previously completed that test. 255if [ "x$TEST_REGRESS_CACHE_DIR" != "x" ]; then 256 if [ ! -d "$TEST_REGRESS_CACHE_DIR" ]; then 257 mkdir -p "$TEST_REGRESS_CACHE_DIR" 258 fi 259 TEST="`basename $SCRIPT .sh`" 260 CACHE="${TEST_REGRESS_CACHE_DIR}/${TEST}.cache" 261 for i in ${SSH} ${SSHD} ${SSHAGENT} ${SSHADD} ${SSHKEYGEN} ${SCP} \ 262 ${SFTP} ${SFTPSERVER} ${SSHKEYSCAN}; do 263 case $i in 264 /*) bin="$i" ;; 265 *) bin="`which $i`" ;; 266 esac 267 if [ "$bin" -nt "$CACHE" ]; then 268 rm -f "$CACHE" 269 fi 270 done 271 if [ -f "$CACHE" ]; then 272 echo ok cached $CACHE 273 exit 0 274 fi 275fi 276 277# truncate logfiles 278>$TEST_SSH_LOGFILE 279>$TEST_SSHD_LOGFILE 280>$TEST_REGRESS_LOGFILE 281 282# Create wrapper ssh with logging. We can't just specify "SSH=ssh -E..." 283# because sftp and scp don't handle spaces in arguments. scp and sftp like 284# to use -q so we remove those to preserve our debug logging. In the rare 285# instance where -q is desirable -qq is equivalent and is not removed. 286SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh 287cat >$SSHLOGWRAP <<EOD 288#!/bin/sh 289echo "Executing: ${SSH} \$@" >>${TEST_SSH_LOGFILE} 290for i in "\$@";do shift;case "\$i" in -q):;; *) set -- "\$@" "\$i";;esac;done 291exec ${SSH} -E${TEST_SSH_LOGFILE} "\$@" 292EOD 293 294chmod a+rx $OBJ/ssh-log-wrapper.sh 295REAL_SSH="$SSH" 296REAL_SSHD="$SSHD" 297SSH="$SSHLOGWRAP" 298 299# Some test data. We make a copy because some tests will overwrite it. 300# The tests may assume that $DATA exists and is writable and $COPY does 301# not exist. Tests requiring larger data files can call increase_datafile_size 302# [kbytes] to ensure the file is at least that large. 303DATANAME=data 304DATA=$OBJ/${DATANAME} 305cat ${SSHAGENT_BIN} >${DATA} 306chmod u+w ${DATA} 307COPY=$OBJ/copy 308rm -f ${COPY} 309 310increase_datafile_size() 311{ 312 while [ `du -k ${DATA} | cut -f1` -lt $1 ]; do 313 cat ${SSHAGENT_BIN} >>${DATA} 314 done 315} 316 317# these should be used in tests 318export SSH SSHD SSHAGENT SSHADD SSHKEYGEN SSHKEYSCAN SFTP SFTPSERVER SCP 319export SSH_PKCS11_HELPER SSH_SK_HELPER 320#echo $SSH $SSHD $SSHAGENT $SSHADD $SSHKEYGEN $SSHKEYSCAN $SFTP $SFTPSERVER $SCP 321 322# Portable specific functions 323which() 324{ 325 saved_IFS="$IFS" 326 IFS=":" 327 for i in $PATH 328 do 329 if [ -x $i/$1 ]; then 330 IFS="$saved_IFS" 331 echo "$i/$1" 332 return 0 333 fi 334 done 335 IFS="$saved_IFS" 336 echo "$i/$1" 337 return 1 338} 339 340have_prog() 341{ 342 which "$1" >/dev/null 2>&1 343 return $? 344} 345 346jot() { 347 awk "BEGIN { for (i = $2; i < $2 + $1; i++) { printf \"%d\n\", i } exit }" 348} 349if [ ! -x "`which rev`" ]; then 350rev() 351{ 352 awk '{for (i=length; i>0; i--) printf "%s", substr($0, i, 1); print ""}' 353} 354fi 355 356# Check whether preprocessor symbols are defined in config.h. 357config_defined () 358{ 359 str=$1 360 while test "x$2" != "x" ; do 361 str="$str|$2" 362 shift 363 done 364 egrep "^#define.*($str)" ${BUILDDIR}/config.h >/dev/null 2>&1 365} 366 367md5 () { 368 if have_prog md5sum; then 369 md5sum 370 elif have_prog openssl; then 371 openssl md5 372 elif have_prog cksum; then 373 cksum 374 elif have_prog sum; then 375 sum 376 elif [ -x ${OPENSSL_BIN} ]; then 377 ${OPENSSL_BIN} md5 378 else 379 wc -c 380 fi 381} 382 383# Some platforms don't have hostname at all, but on others uname -n doesn't 384# provide the fully qualified name we need, so in the former case we create 385# our own hostname function. 386if ! have_prog hostname; then 387 hostname() { 388 uname -n 389 } 390fi 391 392make_tmpdir () 393{ 394 SSH_REGRESS_TMP="$($OBJ/mkdtemp openssh-XXXXXXXX)" || \ 395 fatal "failed to create temporary directory" 396} 397# End of portable specific functions 398 399stop_sshd () 400{ 401 if [ -f $PIDFILE ]; then 402 pid=`$SUDO cat $PIDFILE` 403 if [ "X$pid" = "X" ]; then 404 echo no sshd running 405 else 406 if [ $pid -lt 2 ]; then 407 echo bad pid for sshd: $pid 408 else 409 $SUDO kill $pid 410 trace "wait for sshd to exit" 411 i=0; 412 while [ -f $PIDFILE -a $i -lt 5 ]; do 413 i=`expr $i + 1` 414 sleep $i 415 done 416 if test -f $PIDFILE; then 417 if $SUDO kill -0 $pid; then 418 echo "sshd didn't exit " \ 419 "port $PORT pid $pid" 420 else 421 echo "sshd died without cleanup" 422 fi 423 exit 1 424 fi 425 fi 426 fi 427 fi 428} 429 430# helper 431cleanup () 432{ 433 if [ "x$SSH_PID" != "x" ]; then 434 if [ $SSH_PID -lt 2 ]; then 435 echo bad pid for ssh: $SSH_PID 436 else 437 kill $SSH_PID 438 fi 439 fi 440 if [ "x$SSH_REGRESS_TMP" != "x" ]; then 441 rm -rf "$SSH_REGRESS_TMP" 442 fi 443 stop_sshd 444 if [ ! -z "$TEST_SSH_ELAPSED_TIMES" ]; then 445 now=`date '+%s'` 446 elapsed=$(($now - $STARTTIME)) 447 echo elapsed $elapsed `basename $SCRIPT .sh` 448 fi 449} 450 451start_debug_log () 452{ 453 echo "trace: $@" >$TEST_REGRESS_LOGFILE 454 echo "trace: $@" >$TEST_SSH_LOGFILE 455 echo "trace: $@" >$TEST_SSHD_LOGFILE 456} 457 458save_debug_log () 459{ 460 echo $@ >>$TEST_REGRESS_LOGFILE 461 echo $@ >>$TEST_SSH_LOGFILE 462 echo $@ >>$TEST_SSHD_LOGFILE 463 (cat $TEST_REGRESS_LOGFILE; echo) >>$OBJ/failed-regress.log 464 (cat $TEST_SSH_LOGFILE; echo) >>$OBJ/failed-ssh.log 465 (cat $TEST_SSHD_LOGFILE; echo) >>$OBJ/failed-sshd.log 466} 467 468trace () 469{ 470 start_debug_log $@ 471 if [ "X$TEST_SSH_TRACE" = "Xyes" ]; then 472 echo "$@" 473 fi 474} 475 476verbose () 477{ 478 start_debug_log $@ 479 if [ "X$TEST_SSH_QUIET" != "Xyes" ]; then 480 echo "$@" 481 fi 482} 483 484fail () 485{ 486 save_debug_log "FAIL: $@" 487 RESULT=1 488 echo "$@" 489 if test "x$TEST_SSH_FAIL_FATAL" != "x" ; then 490 cleanup 491 exit $RESULT 492 fi 493} 494 495fatal () 496{ 497 save_debug_log "FATAL: $@" 498 printf "FATAL: " 499 fail "$@" 500 cleanup 501 exit $RESULT 502} 503 504# Skip remaining tests in script. 505skip () 506{ 507 echo "SKIPPED: $@" 508 cleanup 509 exit $RESULT 510} 511 512maybe_add_scp_path_to_sshd () 513{ 514 # If we're testing a non-installed scp, add its directory to sshd's 515 # PATH so we can test it. We don't do this for all tests as it 516 # breaks the SetEnv tests. 517 case "$SCP" in 518 /*) PATH_WITH_SCP="`dirname $SCP`:$PATH" 519 echo " SetEnv PATH='$PATH_WITH_SCP'" >>$OBJ/sshd_config 520 echo " SetEnv PATH='$PATH_WITH_SCP'" >>$OBJ/sshd_proxy ;; 521 esac 522} 523 524RESULT=0 525PIDFILE=$OBJ/pidfile 526 527trap fatal 3 2 528 529# create server config 530cat << EOF > $OBJ/sshd_config 531 StrictModes no 532 Port $PORT 533 AddressFamily inet 534 ListenAddress 127.0.0.1 535 #ListenAddress ::1 536 PidFile $PIDFILE 537 AuthorizedKeysFile $OBJ/authorized_keys_%u 538 LogLevel DEBUG3 539 AcceptEnv _XXX_TEST_* 540 AcceptEnv _XXX_TEST 541 Subsystem sftp $SFTPSERVER 542EOF 543 544# This may be necessary if /usr/src and/or /usr/obj are group-writable, 545# but if you aren't careful with permissions then the unit tests could 546# be abused to locally escalate privileges. 547if [ ! -z "$TEST_SSH_UNSAFE_PERMISSIONS" ]; then 548 echo " StrictModes no" >> $OBJ/sshd_config 549else 550 # check and warn if excessive permissions are likely to cause failures. 551 unsafe="" 552 dir="${OBJ}" 553 while test ${dir} != "/"; do 554 if test -d "${dir}" && ! test -h "${dir}"; then 555 perms=`ls -ld ${dir}` 556 case "${perms}" in 557 ?????w????*|????????w?*) unsafe="${unsafe} ${dir}" ;; 558 esac 559 fi 560 dir=`dirname ${dir}` 561 done 562 if ! test -z "${unsafe}"; then 563 cat <<EOD 564 565WARNING: Unsafe (group or world writable) directory permissions found: 566${unsafe} 567 568These could be abused to locally escalate privileges. If you are 569sure that this is not a risk (eg there are no other users), you can 570bypass this check by setting TEST_SSH_UNSAFE_PERMISSIONS=1 571 572EOD 573 fi 574fi 575 576if [ ! -z "$TEST_SSH_MODULI_FILE" ]; then 577 trace "adding modulifile='$TEST_SSH_MODULI_FILE' to sshd_config" 578 echo " ModuliFile '$TEST_SSH_MODULI_FILE'" >> $OBJ/sshd_config 579fi 580 581if [ ! -z "$TEST_SSH_SSHD_CONFOPTS" ]; then 582 trace "adding sshd_config option $TEST_SSH_SSHD_CONFOPTS" 583 echo "$TEST_SSH_SSHD_CONFOPTS" >> $OBJ/sshd_config 584fi 585 586# server config for proxy connects 587cp $OBJ/sshd_config $OBJ/sshd_proxy 588 589# allow group-writable directories in proxy-mode 590echo 'StrictModes no' >> $OBJ/sshd_proxy 591 592# create client config 593cat << EOF > $OBJ/ssh_config 594Host * 595 Hostname 127.0.0.1 596 HostKeyAlias localhost-with-alias 597 Port $PORT 598 User $USER 599 GlobalKnownHostsFile $OBJ/known_hosts 600 UserKnownHostsFile $OBJ/known_hosts 601 PubkeyAuthentication yes 602 ChallengeResponseAuthentication no 603 PasswordAuthentication no 604 BatchMode yes 605 StrictHostKeyChecking yes 606 LogLevel DEBUG3 607EOF 608 609if [ ! -z "$TEST_SSH_SSH_CONFOPTS" ]; then 610 trace "adding ssh_config option $TEST_SSH_SSH_CONFOPTS" 611 echo "$TEST_SSH_SSH_CONFOPTS" >> $OBJ/ssh_config 612fi 613 614rm -f $OBJ/known_hosts $OBJ/authorized_keys_$USER 615 616SSH_SK_PROVIDER= 617if ! config_defined ENABLE_SK; then 618 trace skipping sk-dummy 619elif [ -f "${SRC}/misc/sk-dummy/obj/sk-dummy.so" ] ; then 620 SSH_SK_PROVIDER="${SRC}/misc/sk-dummy/obj/sk-dummy.so" 621elif [ -f "${OBJ}/misc/sk-dummy/sk-dummy.so" ] ; then 622 SSH_SK_PROVIDER="${OBJ}/misc/sk-dummy/sk-dummy.so" 623elif [ -f "${SRC}/misc/sk-dummy/sk-dummy.so" ] ; then 624 SSH_SK_PROVIDER="${SRC}/misc/sk-dummy/sk-dummy.so" 625fi 626export SSH_SK_PROVIDER 627 628if ! test -z "$SSH_SK_PROVIDER"; then 629 EXTRA_AGENT_ARGS='-P/*' # XXX want realpath(1)... 630 echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/ssh_config 631 echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/sshd_config 632 echo "SecurityKeyProvider $SSH_SK_PROVIDER" >> $OBJ/sshd_proxy 633fi 634export EXTRA_AGENT_ARGS 635 636maybe_filter_sk() { 637 if test -z "$SSH_SK_PROVIDER" ; then 638 grep -v ^sk 639 else 640 cat 641 fi 642} 643 644SSH_KEYTYPES=`$SSH -Q key-plain | maybe_filter_sk` 645SSH_HOSTKEY_TYPES=`$SSH -Q key-plain | maybe_filter_sk` 646 647for t in ${SSH_KEYTYPES}; do 648 # generate user key 649 if [ ! -f $OBJ/$t ] || [ ${SSHKEYGEN_BIN} -nt $OBJ/$t ]; then 650 trace "generating key type $t" 651 rm -f $OBJ/$t 652 ${SSHKEYGEN} -q -N '' -t $t -f $OBJ/$t ||\ 653 fail "ssh-keygen for $t failed" 654 else 655 trace "using cached key type $t" 656 fi 657 658 # setup authorized keys 659 cat $OBJ/$t.pub >> $OBJ/authorized_keys_$USER 660 echo IdentityFile $OBJ/$t >> $OBJ/ssh_config 661done 662 663for t in ${SSH_HOSTKEY_TYPES}; do 664 # known hosts file for client 665 ( 666 printf 'localhost-with-alias,127.0.0.1,::1 ' 667 cat $OBJ/$t.pub 668 ) >> $OBJ/known_hosts 669 670 # use key as host key, too 671 (umask 077; $SUDO cp $OBJ/$t $OBJ/host.$t) 672 echo HostKey $OBJ/host.$t >> $OBJ/sshd_config 673 674 # don't use SUDO for proxy connect 675 echo HostKey $OBJ/$t >> $OBJ/sshd_proxy 676done 677chmod 644 $OBJ/authorized_keys_$USER 678 679# Activate Twisted Conch tests if the binary is present 680REGRESS_INTEROP_CONCH=no 681if test -x "$CONCH" ; then 682 REGRESS_INTEROP_CONCH=yes 683fi 684 685# If PuTTY is present, new enough and we are running a PuTTY test, prepare 686# keys and configuration. 687REGRESS_INTEROP_PUTTY=no 688if test -x "$PUTTYGEN" -a -x "$PLINK" && 689 "$PUTTYGEN" --help 2>&1 | grep -- --new-passphrase >/dev/null; then 690 REGRESS_INTEROP_PUTTY=yes 691fi 692case "$SCRIPT" in 693*putty*) ;; 694*) REGRESS_INTEROP_PUTTY=no ;; 695esac 696 697if test "$REGRESS_INTEROP_PUTTY" = "yes" ; then 698 mkdir -p ${OBJ}/.putty 699 700 # Add a PuTTY key to authorized_keys 701 rm -f ${OBJ}/putty.rsa2 702 if ! "$PUTTYGEN" -t rsa -o ${OBJ}/putty.rsa2 \ 703 --random-device=/dev/urandom \ 704 --new-passphrase /dev/null < /dev/null > /dev/null; then 705 echo "Your installed version of PuTTY is too old to support --new-passphrase, skipping test" >&2 706 exit 1 707 fi 708 "$PUTTYGEN" -O public-openssh ${OBJ}/putty.rsa2 \ 709 >> $OBJ/authorized_keys_$USER 710 711 # Convert rsa2 host key to PuTTY format 712 cp $OBJ/ssh-rsa $OBJ/ssh-rsa_oldfmt 713 ${SSHKEYGEN} -p -N '' -m PEM -f $OBJ/ssh-rsa_oldfmt >/dev/null 714 ${SRC}/ssh2putty.sh 127.0.0.1 $PORT $OBJ/ssh-rsa_oldfmt > \ 715 ${OBJ}/.putty/sshhostkeys 716 ${SRC}/ssh2putty.sh 127.0.0.1 22 $OBJ/ssh-rsa_oldfmt >> \ 717 ${OBJ}/.putty/sshhostkeys 718 rm -f $OBJ/ssh-rsa_oldfmt 719 720 # Setup proxied session 721 mkdir -p ${OBJ}/.putty/sessions 722 rm -f ${OBJ}/.putty/sessions/localhost_proxy 723 echo "Protocol=ssh" >> ${OBJ}/.putty/sessions/localhost_proxy 724 echo "HostName=127.0.0.1" >> ${OBJ}/.putty/sessions/localhost_proxy 725 echo "PortNumber=$PORT" >> ${OBJ}/.putty/sessions/localhost_proxy 726 echo "ProxyMethod=5" >> ${OBJ}/.putty/sessions/localhost_proxy 727 echo "ProxyTelnetCommand=sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy" >> ${OBJ}/.putty/sessions/localhost_proxy 728 echo "ProxyLocalhost=1" >> ${OBJ}/.putty/sessions/localhost_proxy 729 730 PUTTYDIR=${OBJ}/.putty 731 export PUTTYDIR 732fi 733 734# create a proxy version of the client config 735( 736 cat $OBJ/ssh_config 737 echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" sh ${SRC}/sshd-log-wrapper.sh ${TEST_SSHD_LOGFILE} ${SSHD} -i -f $OBJ/sshd_proxy 738) > $OBJ/ssh_proxy 739 740# check proxy config 741${SSHD} -t -f $OBJ/sshd_proxy || fatal "sshd_proxy broken" 742 743start_sshd () 744{ 745 # start sshd 746 $SUDO ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken" 747 $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" \ 748 ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE 749 750 trace "wait for sshd" 751 i=0; 752 while [ ! -f $PIDFILE -a $i -lt 10 ]; do 753 i=`expr $i + 1` 754 sleep $i 755 done 756 757 test -f $PIDFILE || fatal "no sshd running on port $PORT" 758} 759 760# source test body 761. $SCRIPT 762 763# kill sshd 764cleanup 765 766if [ "x$USE_VALGRIND" != "x" ]; then 767 # If there is an EXIT trap handler, invoke it now. 768 # Some tests set these to clean up processes such as ssh-agent. We 769 # need to wait for all valgrind processes to complete so we can check 770 # their logs, but since the EXIT traps are not invoked until 771 # test-exec.sh exits, waiting here will deadlock. 772 # This is not very portable but then neither is valgrind itself. 773 # As a bonus, dash (as used on the runners) has a "trap" that doesn't 774 # work in a pipeline (hence the temp file) or a subshell. 775 exithandler="" 776 trap >/tmp/trap.$$ && exithandler=$(cat /tmp/trap.$$ | \ 777 awk -F "'" '/EXIT$/{print $2}') 778 rm -f /tmp/trap.$$ 779 if [ "x${exithandler}" != "x" ]; then 780 verbose invoking EXIT trap handler early: ${exithandler} 781 eval "${exithandler}" 782 trap '' EXIT 783 fi 784 785 # wait for any running process to complete 786 wait; sleep 1 787 VG_RESULTS=$(find $OBJ/valgrind-out -type f -print) 788 VG_RESULT_COUNT=0 789 VG_FAIL_COUNT=0 790 for i in $VG_RESULTS; do 791 if grep "ERROR SUMMARY" $i >/dev/null; then 792 VG_RESULT_COUNT=$(($VG_RESULT_COUNT + 1)) 793 if ! grep "ERROR SUMMARY: 0 errors" $i >/dev/null; then 794 VG_FAIL_COUNT=$(($VG_FAIL_COUNT + 1)) 795 RESULT=1 796 verbose valgrind failure $i 797 cat $i 798 fi 799 fi 800 done 801 if [ x"$VG_SKIP" != "x" ]; then 802 verbose valgrind skipped 803 else 804 verbose valgrind results $VG_RESULT_COUNT failures $VG_FAIL_COUNT 805 fi 806fi 807 808if [ $RESULT -eq 0 ]; then 809 verbose ok $tid 810 if [ "x$CACHE" != "x" ]; then 811 touch "$CACHE" 812 fi 813else 814 echo failed $tid 815fi 816exit $RESULT 817