mirror of
git://anongit.mindrot.org/openssh.git
synced 2024-12-25 03:12:10 +00:00
a6f4ac8a2b
Previously we would log to ssh.log and sshd.log, but that is insufficient for tests that have more than one concurent ssh/sshd. Instead, we'll log to separate datestamped files in a $OBJ/log/ and leave a symlink at the previous location pointing at the most recent instance with an entry in regress.log showing which files were created at each point. This should be sufficient to reconstruct what happened even for tests that use multiple instances of each program. If the test fails, tar up all of the logs for later analysis. This will let us also capture the output from some of the other tools which was previously sent to /dev/null although most of those will be in future commits. OpenBSD-Regress-ID: f802aa9e7fa51d1a01225c05fb0412d015c33e24
211 lines
7.7 KiB
Bash
211 lines
7.7 KiB
Bash
# $OpenBSD: multiplex.sh,v 1.36 2023/03/01 09:29:32 dtucker Exp $
|
|
# Placed in the Public Domain.
|
|
|
|
make_tmpdir
|
|
CTL=${SSH_REGRESS_TMP}/ctl-sock
|
|
|
|
tid="connection multiplexing"
|
|
|
|
trace "will use ProxyCommand $proxycmd"
|
|
if config_defined DISABLE_FD_PASSING ; then
|
|
echo "skipped (not supported on this platform)"
|
|
exit 0
|
|
fi
|
|
|
|
P=3301 # test port
|
|
|
|
wait_for_mux_master_ready()
|
|
{
|
|
for i in 1 2 3 4 5 6 7 8 9; do
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \
|
|
>/dev/null 2>&1 && return 0
|
|
sleep $i
|
|
done
|
|
fatal "mux master never becomes ready"
|
|
}
|
|
|
|
maybe_add_scp_path_to_sshd
|
|
start_sshd
|
|
|
|
start_mux_master()
|
|
{
|
|
trace "start master, fork to background"
|
|
${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \
|
|
-E $TEST_REGRESS_LOGFILE 2>&1 &
|
|
# NB. $SSH_PID will be killed by test-exec.sh:cleanup on fatal errors.
|
|
SSH_PID=$!
|
|
wait_for_mux_master_ready
|
|
}
|
|
|
|
start_mux_master
|
|
|
|
verbose "test $tid: setenv"
|
|
trace "setenv over multiplexed connection"
|
|
_XXX_TEST=blah ${SSH} -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF'
|
|
test X"$_XXX_TEST" = X"blah"
|
|
EOF
|
|
if [ $? -ne 0 ]; then
|
|
fail "environment not found"
|
|
fi
|
|
|
|
verbose "test $tid: envpass"
|
|
trace "env passing over multiplexed connection"
|
|
${SSH} -F $OBJ/ssh_config -oSetEnv="_XXX_TEST=foo" -S$CTL otherhost sh << 'EOF'
|
|
test X"$_XXX_TEST" = X"foo"
|
|
EOF
|
|
if [ $? -ne 0 ]; then
|
|
fail "environment not found"
|
|
fi
|
|
|
|
|
|
verbose "test $tid: transfer"
|
|
rm -f ${COPY}
|
|
trace "ssh transfer over multiplexed connection and check result"
|
|
${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY}
|
|
test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}"
|
|
cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}"
|
|
|
|
rm -f ${COPY}
|
|
trace "ssh transfer over multiplexed connection and check result"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY}
|
|
test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}"
|
|
cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}"
|
|
|
|
rm -f ${COPY}
|
|
trace "sftp transfer over multiplexed connection and check result"
|
|
echo "get ${DATA} ${COPY}" | \
|
|
${SFTP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost >>$TEST_REGRESS_LOGFILE 2>&1
|
|
test -f ${COPY} || fail "sftp: failed copy ${DATA}"
|
|
cmp ${DATA} ${COPY} || fail "sftp: corrupted copy of ${DATA}"
|
|
|
|
rm -f ${COPY}
|
|
trace "scp transfer over multiplexed connection and check result"
|
|
${SCP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost:${DATA} ${COPY} >>$TEST_REGRESS_LOGFILE 2>&1
|
|
test -f ${COPY} || fail "scp: failed copy ${DATA}"
|
|
cmp ${DATA} ${COPY} || fail "scp: corrupted copy of ${DATA}"
|
|
|
|
rm -f ${COPY}
|
|
verbose "test $tid: forward"
|
|
trace "forward over TCP/IP and check result"
|
|
$NC -N -l 127.0.0.1 $((${PORT} + 1)) < ${DATA} >`ssh_logfile nc` &
|
|
netcat_pid=$!
|
|
${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
|
|
sleep 1 # XXX remove once race fixed
|
|
$NC 127.0.0.1 $((${PORT} + 2)) < /dev/null > ${COPY}
|
|
cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}"
|
|
kill $netcat_pid 2>/dev/null
|
|
rm -f ${COPY} $OBJ/unix-[123].fwd
|
|
|
|
trace "forward over UNIX and check result"
|
|
$NC -N -Ul $OBJ/unix-1.fwd < ${DATA} > /dev/null &
|
|
netcat_pid=$!
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L$OBJ/unix-2.fwd:$OBJ/unix-1.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R$OBJ/unix-3.fwd:$OBJ/unix-2.fwd otherhost >>$TEST_SSH_LOGFILE 2>&1
|
|
sleep 1 # XXX remove once race fixed
|
|
$NC -U $OBJ/unix-3.fwd < /dev/null > ${COPY}
|
|
cmp ${DATA} ${COPY} || fail "ssh: corrupted copy of ${DATA}"
|
|
kill $netcat_pid 2>/dev/null
|
|
rm -f ${COPY} $OBJ/unix-[123].fwd
|
|
|
|
for s in 0 1 4 5 44; do
|
|
for mode in "" "-Oproxy"; do
|
|
trace "exit status $s over multiplexed connection ($mode)"
|
|
verbose "test $tid: status $s ($mode)"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL $mode otherhost exit $s
|
|
r=$?
|
|
if [ $r -ne $s ]; then
|
|
fail "exit code mismatch: $r != $s"
|
|
fi
|
|
|
|
# same with early close of stdout/err
|
|
trace "exit status $s with early close over multiplexed connection ($mode)"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -n $mode otherhost \
|
|
exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\'
|
|
r=$?
|
|
if [ $r -ne $s ]; then
|
|
fail "exit code (with sleep) mismatch: $r != $s"
|
|
fi
|
|
done
|
|
done
|
|
|
|
verbose "test $tid: cmd check"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
|
|
|| fail "check command failed"
|
|
|
|
verbose "test $tid: cmd forward local (TCP)"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \
|
|
|| fail "request local forward failed"
|
|
sleep 1 # XXX remove once race fixed
|
|
${SSH} -F $OBJ/ssh_config -p$P otherhost true \
|
|
|| fail "connect to local forward port failed"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $P:localhost:$PORT otherhost \
|
|
|| fail "cancel local forward failed"
|
|
${SSH} -F $OBJ/ssh_config -p$P otherhost true \
|
|
&& fail "local forward port still listening"
|
|
|
|
verbose "test $tid: cmd forward remote (TCP)"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \
|
|
|| fail "request remote forward failed"
|
|
sleep 1 # XXX remove once race fixed
|
|
${SSH} -F $OBJ/ssh_config -p$P otherhost true \
|
|
|| fail "connect to remote forwarded port failed"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $P:localhost:$PORT otherhost \
|
|
|| fail "cancel remote forward failed"
|
|
${SSH} -F $OBJ/ssh_config -p$P otherhost true \
|
|
&& fail "remote forward port still listening"
|
|
|
|
verbose "test $tid: cmd forward local (UNIX)"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \
|
|
|| fail "request local forward failed"
|
|
sleep 1 # XXX remove once race fixed
|
|
echo "" | $NC -U $OBJ/unix-1.fwd | \
|
|
grep "Invalid SSH identification string" >/dev/null 2>&1 \
|
|
|| fail "connect to local forward path failed"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $OBJ/unix-1.fwd:localhost:$PORT otherhost \
|
|
|| fail "cancel local forward failed"
|
|
N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l)
|
|
test ${N} -eq 0 || fail "local forward path still listening"
|
|
rm -f $OBJ/unix-1.fwd
|
|
|
|
verbose "test $tid: cmd forward remote (UNIX)"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \
|
|
|| fail "request remote forward failed"
|
|
sleep 1 # XXX remove once race fixed
|
|
echo "" | $NC -U $OBJ/unix-1.fwd | \
|
|
grep "Invalid SSH identification string" >/dev/null 2>&1 \
|
|
|| fail "connect to remote forwarded path failed"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $OBJ/unix-1.fwd:localhost:$PORT otherhost \
|
|
|| fail "cancel remote forward failed"
|
|
N=$(echo "xyzzy" | $NC -U $OBJ/unix-1.fwd 2>&1 | grep "xyzzy" | wc -l)
|
|
test ${N} -eq 0 || fail "remote forward path still listening"
|
|
rm -f $OBJ/unix-1.fwd
|
|
|
|
verbose "test $tid: cmd exit"
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
|
|
|| fail "send exit command failed"
|
|
|
|
# Wait for master to exit
|
|
wait $SSH_PID
|
|
kill -0 $SSH_PID >/dev/null 2>&1 && fail "exit command failed"
|
|
|
|
# Restart master and test -O stop command with master using -N
|
|
verbose "test $tid: cmd stop"
|
|
trace "restart master, fork to background"
|
|
start_mux_master
|
|
|
|
# start a long-running command then immediately request a stop
|
|
${SSH} -F $OBJ/ssh_config -S $CTL otherhost "sleep 10; exit 0" \
|
|
>>$TEST_REGRESS_LOGFILE 2>&1 &
|
|
SLEEP_PID=$!
|
|
${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
|
|
|| fail "send stop command failed"
|
|
|
|
# wait until both long-running command and master have exited.
|
|
wait $SLEEP_PID
|
|
[ $! != 0 ] || fail "waiting for concurrent command"
|
|
wait $SSH_PID
|
|
[ $! != 0 ] || fail "waiting for master stop"
|
|
kill -0 $SSH_PID >/dev/null 2>&1 && fatal "stop command failed"
|
|
SSH_PID="" # Already gone, so don't kill in cleanup
|
|
|