- millert@cvs.openbsd.org 2014/07/15 15:54:15
     [forwarding.sh multiplex.sh]
     Add support for Unix domain socket forwarding.  A remote TCP port
     may be forwarded to a local Unix domain socket and vice versa or
     both ends may be a Unix domain socket.  This is a reimplementation
     of the streamlocal patches by William Ahern from:
         http://www.25thandclement.com/~william/projects/streamlocal.html
     OK djm@ markus@
diff --git a/ChangeLog b/ChangeLog
index d402c42..a22bef5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,15 @@
 20140721
+ - OpenBSD CVS Sync
+   - millert@cvs.openbsd.org 2014/07/15 15:54:15
+     [forwarding.sh multiplex.sh]
+     Add support for Unix domain socket forwarding.  A remote TCP port
+     may be forwarded to a local Unix domain socket and vice versa or
+     both ends may be a Unix domain socket.  This is a reimplementation
+     of the streamlocal patches by William Ahern from:
+         http://www.25thandclement.com/~william/projects/streamlocal.html
+     OK djm@ markus@
+
+20140721
  - (dtucker) [cipher.c openbsd-compat/openssl-compat.h] Restore the bits
    needed to build AES CTR mode against OpenSSL 0.9.8f and above.  ok djm
  - (dtucker) [regress/unittests/sshkey/
diff --git a/regress/forwarding.sh b/regress/forwarding.sh
index 94873f2..f799d49 100644
--- a/regress/forwarding.sh
+++ b/regress/forwarding.sh
@@ -1,4 +1,4 @@
-#	$OpenBSD: forwarding.sh,v 1.11 2013/06/10 21:56:43 dtucker Exp $
+#	$OpenBSD: forwarding.sh,v 1.12 2014/07/15 15:54:15 millert Exp $
 #	Placed in the Public Domain.
 
 tid="local and remote forwarding"
@@ -28,7 +28,7 @@
 	trace "transfer over forwarded channels and check result"
 	${SSH} -$q -F $OBJ/ssh_config -p$last -o 'ConnectionAttempts=4' \
 		somehost cat ${DATA} > ${COPY}
-	test -f ${COPY}		|| fail "failed copy of ${DATA}"
+	test -s ${COPY}		|| fail "failed copy of ${DATA}"
 	cmp ${DATA} ${COPY}	|| fail "corrupted copy of ${DATA}"
 
 	sleep 10
@@ -114,8 +114,24 @@
 	trace "config file: transfer over forwarded channels and check result"
 	${SSH} -F $OBJ/ssh_config -p${base}02 -o 'ConnectionAttempts=4' \
 		somehost cat ${DATA} > ${COPY}
-	test -f ${COPY}		|| fail "failed copy of ${DATA}"
+	test -s ${COPY}		|| fail "failed copy of ${DATA}"
 	cmp ${DATA} ${COPY}	|| fail "corrupted copy of ${DATA}"
 
 	wait
 done
+
+for p in 2; do
+	trace "transfer over chained unix domain socket forwards and check result"
+	rm -f $OBJ/unix-[123].fwd
+	${SSH} -f -F $OBJ/ssh_config -R${base}01:[$OBJ/unix-1.fwd] somehost sleep 10
+	${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-1.fwd]:[$OBJ/unix-2.fwd] somehost sleep 10
+	${SSH} -f -F $OBJ/ssh_config -R[$OBJ/unix-2.fwd]:[$OBJ/unix-3.fwd] somehost sleep 10
+	${SSH} -f -F $OBJ/ssh_config -L[$OBJ/unix-3.fwd]:127.0.0.1:$PORT somehost sleep 10
+	${SSH} -F $OBJ/ssh_config -p${base}01 -o 'ConnectionAttempts=4' \
+		somehost cat ${DATA} > ${COPY}
+	test -s ${COPY}			|| fail "failed copy ${DATA}"
+	cmp ${DATA} ${COPY}		|| fail "corrupted copy of ${DATA}"
+
+	#wait
+	sleep 10
+done
diff --git a/regress/multiplex.sh b/regress/multiplex.sh
index 0a9ed2f..9f5fc38 100644
--- a/regress/multiplex.sh
+++ b/regress/multiplex.sh
@@ -1,4 +1,4 @@
-#	$OpenBSD: multiplex.sh,v 1.23 2014/07/07 08:15:26 djm Exp $
+#	$OpenBSD: multiplex.sh,v 1.24 2014/07/15 15:54:15 millert Exp $
 #	Placed in the Public Domain.
 
 CTL=/tmp/openssh.regress.ctl-sock.$$
@@ -72,6 +72,25 @@
 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} &
+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
+nc 127.0.0.1 $((${PORT} + 2)) > ${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} &
+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
+nc -U $OBJ/unix-3.fwd > ${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
 	trace "exit status $s over multiplexed connection"
@@ -96,7 +115,7 @@
 ${SSH} -F $OBJ/ssh_config -S $CTL -Ocheck otherhost >>$TEST_REGRESS_LOGFILE 2>&1 \
     || fail "check command failed" 
 
-verbose "test $tid: cmd forward local"
+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"
 ${SSH} -F $OBJ/ssh_config -p$P otherhost true \
@@ -106,7 +125,7 @@
 ${SSH} -F $OBJ/ssh_config -p$P otherhost true \
      && fail "local forward port still listening"
 
-verbose "test $tid: cmd forward remote"
+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"
 ${SSH} -F $OBJ/ssh_config -p$P otherhost true \
@@ -116,6 +135,28 @@
 ${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"
+echo "" | nc -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/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 "" | nc -U $OBJ/unix-1.fwd 2>&1 | 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"
+echo "" | nc -U $OBJ/unix-1.fwd | grep "Protocol mismatch" >/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 "" | nc -U $OBJ/unix-1.fwd 2>&1 | 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"