multiplex.sh revision 294328
1294328Sdes# $OpenBSD: multiplex.sh,v 1.25 2014/07/22 01:32:12 djm Exp $ 2137015Sdes# Placed in the Public Domain. 3137015Sdes 4147001SdesCTL=/tmp/openssh.regress.ctl-sock.$$ 5137015Sdes 6137015Sdestid="connection multiplexing" 7137015Sdes 8294328Sdesif have_prog nc ; then 9294328Sdes if nc -h 2>&1 | grep -- -N >/dev/null; then 10294328Sdes NC="nc -N"; 11294328Sdes elif nc -h 2>&1 | grep -- "-U.*Use UNIX" >/dev/null ; then 12294328Sdes NC="nc" 13294328Sdes else 14294328Sdes echo "nc is incompatible" 15294328Sdes fi 16294328Sdesfi 17294328Sdes 18294328Sdesif test -z "$NC" ; then 19294328Sdes echo "skipped (no compatible nc found)" 20294328Sdes exit 0 21294328Sdesfi 22294328Sdes 23294328Sdestrace "will use ProxyCommand $proxycmd" 24218767Sdesif config_defined DISABLE_FD_PASSING ; then 25146998Sdes echo "skipped (not supported on this platform)" 26146998Sdes exit 0 27146998Sdesfi 28146998Sdes 29255670SdesP=3301 # test port 30137015Sdes 31248613Sdeswait_for_mux_master_ready() 32248613Sdes{ 33248613Sdes for i in 1 2 3 4 5; do 34248613Sdes ${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \ 35248613Sdes >/dev/null 2>&1 && return 0 36248613Sdes sleep $i 37248613Sdes done 38248613Sdes fatal "mux master never becomes ready" 39248613Sdes} 40248613Sdes 41137015Sdesstart_sshd 42137015Sdes 43255670Sdesstart_mux_master() 44255670Sdes{ 45255670Sdes trace "start master, fork to background" 46255670Sdes ${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \ 47255670Sdes -E $TEST_REGRESS_LOGFILE 2>&1 & 48294328Sdes # NB. $SSH_PID will be killed by test-exec.sh:cleanup on fatal errors. 49294328Sdes SSH_PID=$! 50255670Sdes wait_for_mux_master_ready 51255670Sdes} 52137015Sdes 53255670Sdesstart_mux_master 54255670Sdes 55137015Sdesverbose "test $tid: envpass" 56137015Sdestrace "env passing over multiplexed connection" 57204861Sdes_XXX_TEST=blah ${SSH} -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF' 58137015Sdes test X"$_XXX_TEST" = X"blah" 59137015SdesEOF 60137015Sdesif [ $? -ne 0 ]; then 61137015Sdes fail "environment not found" 62137015Sdesfi 63137015Sdes 64137015Sdesverbose "test $tid: transfer" 65137015Sdesrm -f ${COPY} 66137015Sdestrace "ssh transfer over multiplexed connection and check result" 67204861Sdes${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY} 68137015Sdestest -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}" 69137015Sdescmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}" 70137015Sdes 71137015Sdesrm -f ${COPY} 72137015Sdestrace "ssh transfer over multiplexed connection and check result" 73204861Sdes${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY} 74137015Sdestest -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}" 75137015Sdescmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}" 76137015Sdes 77137015Sdesrm -f ${COPY} 78137015Sdestrace "sftp transfer over multiplexed connection and check result" 79137015Sdesecho "get ${DATA} ${COPY}" | \ 80255670Sdes ${SFTP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost >>$TEST_REGRESS_LOGFILE 2>&1 81137015Sdestest -f ${COPY} || fail "sftp: failed copy ${DATA}" 82137015Sdescmp ${DATA} ${COPY} || fail "sftp: corrupted copy of ${DATA}" 83137015Sdes 84137015Sdesrm -f ${COPY} 85137015Sdestrace "scp transfer over multiplexed connection and check result" 86255670Sdes${SCP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost:${DATA} ${COPY} >>$TEST_REGRESS_LOGFILE 2>&1 87137015Sdestest -f ${COPY} || fail "scp: failed copy ${DATA}" 88137015Sdescmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}" 89137015Sdes 90137015Sdesrm -f ${COPY} 91294328Sdesverbose "test $tid: forward" 92294328Sdestrace "forward over TCP/IP and check result" 93294328Sdes$NC -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} & 94294328Sdesnetcat_pid=$! 95294328Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L127.0.0.1:$((${PORT} + 2)):127.0.0.1:$((${PORT} + 1)) otherhost >>$TEST_SSH_LOGFILE 2>&1 96294328Sdes$NC -d 127.0.0.1 $((${PORT} + 2)) > ${COPY} < /dev/null 97294328Sdescmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" 98294328Sdeskill $netcat_pid 2>/dev/null 99294328Sdesrm -f ${COPY} $OBJ/unix-[123].fwd 100137015Sdes 101294328Sdestrace "forward over UNIX and check result" 102294328Sdes$NC -Ul $OBJ/unix-1.fwd < ${DATA} & 103294328Sdesnetcat_pid=$! 104294328Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 105294328Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1 106294328Sdes$NC -d -U $OBJ/unix-3.fwd > ${COPY} </dev/null 107294328Sdescmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}" 108294328Sdeskill $netcat_pid 2>/dev/null 109294328Sdesrm -f ${COPY} $OBJ/unix-[123].fwd 110294328Sdes 111137015Sdesfor s in 0 1 4 5 44; do 112137015Sdes trace "exit status $s over multiplexed connection" 113137015Sdes verbose "test $tid: status $s" 114204861Sdes ${SSH} -F $OBJ/ssh_config -S $CTL otherhost exit $s 115137015Sdes r=$? 116137015Sdes if [ $r -ne $s ]; then 117137015Sdes fail "exit code mismatch for protocol $p: $r != $s" 118137015Sdes fi 119137015Sdes 120137015Sdes # same with early close of stdout/err 121137015Sdes trace "exit status $s with early close over multiplexed connection" 122204861Sdes ${SSH} -F $OBJ/ssh_config -S $CTL -n otherhost \ 123137015Sdes exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\' 124137015Sdes r=$? 125137015Sdes if [ $r -ne $s ]; then 126137015Sdes fail "exit code (with sleep) mismatch for protocol $p: $r != $s" 127137015Sdes fi 128137015Sdesdone 129137015Sdes 130248613Sdesverbose "test $tid: cmd check" 131255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ 132248613Sdes || fail "check command failed" 133146998Sdes 134294328Sdesverbose "test $tid: cmd forward local (TCP)" 135255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \ 136255670Sdes || fail "request local forward failed" 137255670Sdes${SSH} -F $OBJ/ssh_config -p$P otherhost true \ 138255670Sdes || fail "connect to local forward port failed" 139255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $P:localhost:$PORT otherhost \ 140255670Sdes || fail "cancel local forward failed" 141255670Sdes${SSH} -F $OBJ/ssh_config -p$P otherhost true \ 142255670Sdes && fail "local forward port still listening" 143255670Sdes 144294328Sdesverbose "test $tid: cmd forward remote (TCP)" 145255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \ 146255670Sdes || fail "request remote forward failed" 147255670Sdes${SSH} -F $OBJ/ssh_config -p$P otherhost true \ 148255670Sdes || fail "connect to remote forwarded port failed" 149255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $P:localhost:$PORT otherhost \ 150255670Sdes || fail "cancel remote forward failed" 151255670Sdes${SSH} -F $OBJ/ssh_config -p$P otherhost true \ 152255670Sdes && fail "remote forward port still listening" 153255670Sdes 154294328Sdesverbose "test $tid: cmd forward local (UNIX)" 155294328Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \ 156294328Sdes || fail "request local forward failed" 157294328Sdesecho "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \ 158294328Sdes || fail "connect to local forward path failed" 159294328Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \ 160294328Sdes || fail "cancel local forward failed" 161294328SdesN=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l) 162294328Sdestest ${N} -eq 0 || fail "local forward path still listening" 163294328Sdesrm -f $OBJ/unix-1.fwd 164294328Sdes 165294328Sdesverbose "test $tid: cmd forward remote (UNIX)" 166294328Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \ 167294328Sdes || fail "request remote forward failed" 168294328Sdesecho "" | $NC -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/dev/null 2>&1 \ 169294328Sdes || fail "connect to remote forwarded path failed" 170294328Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \ 171294328Sdes || fail "cancel remote forward failed" 172294328SdesN=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l) 173294328Sdestest ${N} -eq 0 || fail "remote forward path still listening" 174294328Sdesrm -f $OBJ/unix-1.fwd 175294328Sdes 176248613Sdesverbose "test $tid: cmd exit" 177255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ 178248613Sdes || fail "send exit command failed" 179146998Sdes 180146998Sdes# Wait for master to exit 181294328Sdeswait $SSH_PID 182294328Sdeskill -0 $SSH_PID >/dev/null 2>&1 && fail "exit command failed" 183146998Sdes 184248613Sdes# Restart master and test -O stop command with master using -N 185248613Sdesverbose "test $tid: cmd stop" 186248613Sdestrace "restart master, fork to background" 187255670Sdesstart_mux_master 188248613Sdes 189248613Sdes# start a long-running command then immediately request a stop 190248613Sdes${SSH} -F $OBJ/ssh_config -S $CTL otherhost "sleep 10; exit 0" \ 191255670Sdes >>$TEST_REGRESS_LOGFILE 2>&1 & 192248613SdesSLEEP_PID=$! 193255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \ 194248613Sdes || fail "send stop command failed" 195248613Sdes 196248613Sdes# wait until both long-running command and master have exited. 197248613Sdeswait $SLEEP_PID 198248613Sdes[ $! != 0 ] || fail "waiting for concurrent command" 199294328Sdeswait $SSH_PID 200248613Sdes[ $! != 0 ] || fail "waiting for master stop" 201294328Sdeskill -0 $SSH_PID >/dev/null 2>&1 && fatal "stop command failed" 202294328SdesSSH_PID="" # Already gone, so don't kill in cleanup 203294328Sdes 204