1255670Sdes#	$OpenBSD: multiplex.sh,v 1.21 2013/05/17 04:29:14 dtucker Exp $
2137015Sdes#	Placed in the Public Domain.
3137015Sdes
4147001SdesCTL=/tmp/openssh.regress.ctl-sock.$$
5137015Sdes
6137015Sdestid="connection multiplexing"
7137015Sdes
8218767Sdesif config_defined DISABLE_FD_PASSING ; then
9146998Sdes	echo "skipped (not supported on this platform)"
10146998Sdes	exit 0
11146998Sdesfi
12146998Sdes
13255670SdesP=3301  # test port
14137015Sdes
15248613Sdeswait_for_mux_master_ready()
16248613Sdes{
17248613Sdes	for i in 1 2 3 4 5; do
18248613Sdes		${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost \
19248613Sdes		    >/dev/null 2>&1 && return 0
20248613Sdes		sleep $i
21248613Sdes	done
22248613Sdes	fatal "mux master never becomes ready"
23248613Sdes}
24248613Sdes
25137015Sdesstart_sshd
26137015Sdes
27255670Sdesstart_mux_master()
28255670Sdes{
29255670Sdes	trace "start master, fork to background"
30255670Sdes	${SSH} -Nn2 -MS$CTL -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" somehost \
31255670Sdes	    -E $TEST_REGRESS_LOGFILE 2>&1 &
32255670Sdes	MASTER_PID=$!
33255670Sdes	wait_for_mux_master_ready
34255670Sdes}
35137015Sdes
36255670Sdesstart_mux_master
37255670Sdes
38137015Sdesverbose "test $tid: envpass"
39137015Sdestrace "env passing over multiplexed connection"
40204861Sdes_XXX_TEST=blah ${SSH} -F $OBJ/ssh_config -oSendEnv="_XXX_TEST" -S$CTL otherhost sh << 'EOF'
41137015Sdes	test X"$_XXX_TEST" = X"blah"
42137015SdesEOF
43137015Sdesif [ $? -ne 0 ]; then
44137015Sdes	fail "environment not found"
45137015Sdesfi
46137015Sdes
47137015Sdesverbose "test $tid: transfer"
48137015Sdesrm -f ${COPY}
49137015Sdestrace "ssh transfer over multiplexed connection and check result"
50204861Sdes${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY}
51137015Sdestest -f ${COPY}			|| fail "ssh -Sctl: failed copy ${DATA}" 
52137015Sdescmp ${DATA} ${COPY}		|| fail "ssh -Sctl: corrupted copy of ${DATA}"
53137015Sdes
54137015Sdesrm -f ${COPY}
55137015Sdestrace "ssh transfer over multiplexed connection and check result"
56204861Sdes${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY}
57137015Sdestest -f ${COPY}			|| fail "ssh -S ctl: failed copy ${DATA}" 
58137015Sdescmp ${DATA} ${COPY}		|| fail "ssh -S ctl: corrupted copy of ${DATA}"
59137015Sdes
60137015Sdesrm -f ${COPY}
61137015Sdestrace "sftp transfer over multiplexed connection and check result"
62137015Sdesecho "get ${DATA} ${COPY}" | \
63255670Sdes	${SFTP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost >>$TEST_REGRESS_LOGFILE 2>&1
64137015Sdestest -f ${COPY}			|| fail "sftp: failed copy ${DATA}" 
65137015Sdescmp ${DATA} ${COPY}		|| fail "sftp: corrupted copy of ${DATA}"
66137015Sdes
67137015Sdesrm -f ${COPY}
68137015Sdestrace "scp transfer over multiplexed connection and check result"
69255670Sdes${SCP} -S ${SSH} -F $OBJ/ssh_config -oControlPath=$CTL otherhost:${DATA} ${COPY} >>$TEST_REGRESS_LOGFILE 2>&1
70137015Sdestest -f ${COPY}			|| fail "scp: failed copy ${DATA}" 
71137015Sdescmp ${DATA} ${COPY}		|| fail "scp: corrupted copy of ${DATA}"
72137015Sdes
73137015Sdesrm -f ${COPY}
74137015Sdes
75137015Sdesfor s in 0 1 4 5 44; do
76137015Sdes	trace "exit status $s over multiplexed connection"
77137015Sdes	verbose "test $tid: status $s"
78204861Sdes	${SSH} -F $OBJ/ssh_config -S $CTL otherhost exit $s
79137015Sdes	r=$?
80137015Sdes	if [ $r -ne $s ]; then
81137015Sdes		fail "exit code mismatch for protocol $p: $r != $s"
82137015Sdes	fi
83137015Sdes
84137015Sdes	# same with early close of stdout/err
85137015Sdes	trace "exit status $s with early close over multiplexed connection"
86204861Sdes	${SSH} -F $OBJ/ssh_config -S $CTL -n otherhost \
87137015Sdes                exec sh -c \'"sleep 2; exec > /dev/null 2>&1; sleep 3; exit $s"\'
88137015Sdes	r=$?
89137015Sdes	if [ $r -ne $s ]; then
90137015Sdes		fail "exit code (with sleep) mismatch for protocol $p: $r != $s"
91137015Sdes	fi
92137015Sdesdone
93137015Sdes
94248613Sdesverbose "test $tid: cmd check"
95255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
96248613Sdes    || fail "check command failed" 
97146998Sdes
98255670Sdesverbose "test $tid: cmd forward local"
99255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -L $P:localhost:$PORT otherhost \
100255670Sdes     || fail "request local forward failed"
101255670Sdes${SSH} -F $OBJ/ssh_config -p$P otherhost true \
102255670Sdes     || fail "connect to local forward port failed"
103255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -L $P:localhost:$PORT otherhost \
104255670Sdes     || fail "cancel local forward failed"
105255670Sdes${SSH} -F $OBJ/ssh_config -p$P otherhost true \
106255670Sdes     && fail "local forward port still listening"
107255670Sdes
108255670Sdesverbose "test $tid: cmd forward remote"
109255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oforward -R $P:localhost:$PORT otherhost \
110255670Sdes     || fail "request remote forward failed"
111255670Sdes${SSH} -F $OBJ/ssh_config -p$P otherhost true \
112255670Sdes     || fail "connect to remote forwarded port failed"
113255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ocancel -R $P:localhost:$PORT otherhost \
114255670Sdes     || fail "cancel remote forward failed"
115255670Sdes${SSH} -F $OBJ/ssh_config -p$P otherhost true \
116255670Sdes     && fail "remote forward port still listening"
117255670Sdes
118248613Sdesverbose "test $tid: cmd exit"
119255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Oexit otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
120248613Sdes    || fail "send exit command failed" 
121146998Sdes
122146998Sdes# Wait for master to exit
123248613Sdeswait $MASTER_PID
124248613Sdeskill -0 $MASTER_PID >/dev/null 2>&1 && fail "exit command failed"
125146998Sdes
126248613Sdes# Restart master and test -O stop command with master using -N
127248613Sdesverbose "test $tid: cmd stop"
128248613Sdestrace "restart master, fork to background"
129255670Sdesstart_mux_master
130248613Sdes
131248613Sdes# start a long-running command then immediately request a stop
132248613Sdes${SSH} -F $OBJ/ssh_config -S $CTL otherhost "sleep 10; exit 0" \
133255670Sdes     >>$TEST_REGRESS_LOGFILE 2>&1 &
134248613SdesSLEEP_PID=$!
135255670Sdes${SSH} -F $OBJ/ssh_config -S $CTL -Ostop otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
136248613Sdes    || fail "send stop command failed"
137248613Sdes
138248613Sdes# wait until both long-running command and master have exited.
139248613Sdeswait $SLEEP_PID
140248613Sdes[ $! != 0 ] || fail "waiting for concurrent command"
141248613Sdeswait $MASTER_PID
142248613Sdes[ $! != 0 ] || fail "waiting for master stop"
143248613Sdeskill -0 $MASTER_PID >/dev/null 2>&1 && fail "stop command failed"
144