[openssh-commits] [openssh] branch master updated: upstream: regression test for "interactive" ssh with a PTY attached,
git+noreply at mindrot.org
git+noreply at mindrot.org
Mon Oct 20 11:48:36 AEDT 2025
This is an automated email from the git hooks/post-receive script.
djm pushed a commit to branch master
in repository openssh.
The following commit(s) were added to refs/heads/master by this push:
new 74369b2b7 upstream: regression test for "interactive" ssh with a PTY attached,
74369b2b7 is described below
commit 74369b2b7c366887211ef5c092b0aaa60f31ef11
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Mon Oct 20 00:45:10 2025 +0000
upstream: regression test for "interactive" ssh with a PTY attached,
using tmux
would have likely caught the ControlPersist regression in 10.1.
feedback nicm@
OpenBSD-Regress-ID: d4d709c08657769cb5691893cc98f34b6f537e76
---
regress/Makefile | 6 ++-
regress/ssh-tty.sh | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 156 insertions(+), 2 deletions(-)
diff --git a/regress/Makefile b/regress/Makefile
index 0bb90bcb4..bd44b0489 100644
--- a/regress/Makefile
+++ b/regress/Makefile
@@ -19,6 +19,7 @@ clean:
for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done
rm -rf $(OBJ).putty
rm -rf $(OBJ).dropbear
+ rm -rf $(OBJ).fakehome
distclean: clean
@@ -115,7 +116,8 @@ LTESTS= connect \
penalty \
penalty-expire \
connect-bigconf \
- ssh-pkcs11
+ ssh-pkcs11 \
+ ssh-tty
INTEROP_TESTS= putty-transfer putty-ciphers putty-kex conch-ciphers
INTEROP_TESTS+= dropbear-ciphers dropbear-kex dropbear-server
@@ -153,7 +155,7 @@ CLEANFILES= *.core actual agent-key.* authorized_keys_${USERNAME} \
t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub \
t8.out t8.out.pub t9.out t9.out.pub \
timestamp testdata user_*key* user_ca* user_key* \
- pin.sh nopin.sh wrongpin.sh key.pub
+ pin.sh nopin.sh wrongpin.sh key.pub test.sh ctl-sock
# Enable all malloc(3) randomisations and checks
TEST_ENV= "MALLOC_OPTIONS=CFGJRSUX"
diff --git a/regress/ssh-tty.sh b/regress/ssh-tty.sh
new file mode 100644
index 000000000..2864f5001
--- /dev/null
+++ b/regress/ssh-tty.sh
@@ -0,0 +1,152 @@
+# $OpenBSD: ssh-tty.sh,v 1.1 2025/10/20 00:45:10 djm Exp $
+# Placed in the Public Domain.
+
+# Basic TTY smoke test
+
+tid="ssh-tty"
+
+# Fake home directory to avoid user shell configuration.
+FAKEHOME="$OBJ/.fakehome"
+rm -rf "$FAKEHOME"
+mkdir -m 0700 -p "$FAKEHOME"
+
+# tmux stuff
+TMUX=tmux
+test -x $TMUX || skip "tmux not found"
+CLEANENV="env -i HOME=$HOME LOGNAME=$USER USER=$USER PATH=$PATH SHELL=$SHELL"
+TMUX_TEST="$CLEANENV $TMUX -f/dev/null -Lopenssh-regress-ssh-tty"
+sess="regress-ssh-tty$$"
+
+# Multiplexing control socket.
+CTL=$OBJ/ctl-sock
+
+# Some randomish strings used for signalling back and forth.
+# We use the octal variants via printf(1).
+MAGIC1="XY23zzY"
+MAGIC1_OCTAL="\130\131\062\063\172\172\131"
+MAGIC2="99sMarT86"
+MAGIC2_OCTAL="\071\071\163\115\141\162\124\070\066"
+MAGIC3="woLF1701d"
+MAGIC3_OCTAL="\167\157\114\106\061\067\060\061\144"
+MAGIC4="lUh4thX4evR"
+MAGIC4_OCTAL="\154\125\150\064\164\150\130\064\145\166\122"
+
+# Wait for a mux process to become ready.
+wait_for_mux_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 never becomes ready"
+}
+
+# Wait for a mux process to have finished.
+wait_for_mux_done()
+{
+ for i in 1 2 3 4 5 6 7 8 9; do
+ test -S $CTL || return 0
+ sleep $i
+ done
+ fatal "mux socket never removed"
+}
+
+# Wait for a regex to appear in terminal output.
+wait_for_regex() {
+ string="$1"
+ errors_are_fatal="$2"
+ for x in 1 2 3 4 5 6 7 8 9 10 ; do
+ $TMUX_TEST capture-pane -pt $sess | grep "$string" >/dev/null
+ [ $? -eq 0 ] && return
+ sleep 1
+ done
+ if test -z "$errors_are_fatal"; then
+ fail "failed to match \"$string\" in terminal output"
+ return
+ fi
+ fatal "failed to match \"$string\" in terminal output"
+}
+
+# Check that a regex does *not* appear in terminal output
+not_in_term() {
+ string="$1"
+ error="$2"
+ errors_are_fatal="$3"
+ $TMUX_TEST capture-pane -pt $sess | grep "$string" > /dev/null
+ [ $? -ne 0 ] && return
+ if test -z "$errors_are_fatal"; then
+ fail "$error"
+ return
+ fi
+ fatal "$error"
+}
+
+trap "$TMUX_TEST kill-session -t $sess 2>/dev/null" EXIT
+
+run_test() {
+ tag="$1"
+ ssh_args="$2"
+ # Prepare a tmux session.
+ $TMUX_TEST kill-session -t $sess 2>/dev/null
+ $TMUX_TEST new-session -d -s $sess
+ #echo XXXXXXXXXX $sess; sleep 10
+
+ # Command to start SSH; sent as keystrokes to tmux session.
+ RCMD="$CLEANENV $SHELL"
+ CMD="$SSH -F $OBJ/ssh_proxy $ssh_args -S $CTL x -tt $RCMD"
+
+ verbose "${tag}: start connection"
+ # arrange for the shell to print something after ssh completes.
+ $TMUX_TEST send-keys -t $sess "$CMD && printf '$MAGIC1_OCTAL\n'" ENTER
+ wait_for_mux_ready
+
+ verbose "${tag}: send string"
+ $TMUX_TEST send-keys -t $sess "printf '$MAGIC2_OCTAL\n'" ENTER
+ wait_for_regex "$MAGIC2"
+
+ verbose "${tag}: ^c interrupts process"
+ # ^c should interrupt the sleep and prevent the magic string
+ # from appearing.
+ $TMUX_TEST send-keys -t $sess "sleep 30 || printf '$MAGIC3_OCTAL\n'"
+ $TMUX_TEST send-keys -t $sess ENTER
+ $TMUX_TEST send-keys -t $sess "C-c"
+ # send another string to let us know that the sleep has finished.
+ $TMUX_TEST send-keys -t $sess "printf '$MAGIC4_OCTAL\n'" ENTER
+ wait_for_regex "$MAGIC4"
+ not_in_term "$MAGIC3" "^c did not interrupt"
+
+ verbose "${tag}: ~? produces help"
+ $TMUX_TEST send-keys -t $sess ENTER "~?"
+ wait_for_regex "^Supported escape sequences:$"
+
+ verbose "${tag}: ~. terminates session"
+ $TMUX_TEST send-keys -t $sess ENTER "~."
+ wait_for_mux_done
+ not_in_term "$MAGIC1" "ssh unexpectedly exited successfully after ~."
+
+ verbose "${tag}: restart session"
+ $TMUX_TEST send-keys -t $sess "$CMD && printf '$MAGIC1_OCTAL\n'" ENTER
+ wait_for_mux_ready
+
+ verbose "${tag}: eof terminates session successfully"
+ $TMUX_TEST send-keys -t $sess ENTER "C-d"
+ wait_for_regex "$MAGIC1"
+}
+
+# Make sure tmux is working as expected before we start.
+$TMUX_TEST kill-session -t $sess 2>/dev/null
+$TMUX_TEST new-session -d -s $sess
+# Make sure the session doesn't contain the magic strings we will use
+# for signalling or any #? output.
+not_in_term "$MAGIC1" "terminal already contains magic1 string" fatal
+not_in_term "$MAGIC2" "terminal already contains magic2 string" fatal
+not_in_term "$MAGIC3" "terminal already contains magic3 string" fatal
+not_in_term "$MAGIC4" "terminal already contains magic4 string" fatal
+not_in_term "^Supported escape" "terminal already contains escape help" fatal
+$TMUX_TEST send-keys -t $sess "printf '$MAGIC1_OCTAL\n'" ENTER
+wait_for_regex "$MAGIC1" fatal
+$TMUX_TEST kill-session -t $sess 2>/dev/null
+
+run_test "basic" "-oControlMaster=yes"
+run_test "ControlPersist" "-oControlMaster=auto -oControlPersist=1s"
--
To stop receiving notification emails like this one, please contact
djm at mindrot.org.
More information about the openssh-commits
mailing list