[PATCH] ANSI terminal escape sequences do not affect processing of SSH escapes

Alex Dowad alexinbeijing at gmail.com
Tue Oct 13 05:51:18 AEDT 2015

Even when the user has not pressed a key, ANSI-compatible terminal emulators
can send escape sequences to ssh's stdin at any time. For example, any time that
the server sends an "<ESC>[6n" (query cursor position) sequence, an
ANSI-compatible terminal will send back "<ESC>[<ROW>;<COLUMN>R". ssh sees these
escape sequences just as if they were characters typed in by the user. This
causes problems if the user is attempting to type an SSH escape sequence,
starting with "<ENTER>~".

Therefore, when scanning user input for SSH escape sequences, skip over any
ANSI terminal control sequences which appear in the input.

Dear OpenSSH-Portable Devs,

Please CC replies as I am not (yet) a subscriber!

I should probably send this upstream, but I've been searching for the right
mailing list and haven't found anything. Your feedback will be appreciated.
I've read your style guidelines and attempted to follow them.

This patch was prompted by the observation that SSH escapes (using ~) don't work
at all when the remote shell is BusyBox ash (used by Alpine Linux and some
other minimalist and/or embedded Linux distributions).

This is because the BusyBox shell *always* sends a "query cursor position"
terminal control escape sequence each time you press the <ENTER> key.
Quick as a flash, as your pinky finger is descending towards the tilda key,
the terminal sends back a "report cursor position" sequence. The result is
that the SSH client *never* sees your tilda as immediately following the

Those ANSI terminal control sequences always begin with "<ESC>[" and end
with an alphabetic character. Hence the call to isalpha() in my code.
Can someone confirm that isalpha() *always* treats a-z and A-Z as alphabetic,
no matter what the locale is?

Thank you,
Alex Dowad

 clientloop.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/clientloop.c b/clientloop.c
index 87ceb3d..b15e470 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1096,7 +1096,17 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr,
 		/* Get one character at a time. */
 		ch = buf[i];
-		if (*escape_pendingp) {
+		/* ANSI terminal escape sequences may appear anywhere in input stream. */
+		/* They do not affect our processing of our own escapes. */
+		if (ch == 0x1B && buf[i+1] == '[') {
+			for (; i < (u_int)len; i++) {
+				ch = buf[i];
+				buffer_put_char(bin, ch);
+				if (isalpha(ch))
+					break;
+			}
+			continue;
+		} else if (*escape_pendingp) {
 			/* We have previously seen an escape character. */
 			/* Clear the flag now. */
 			*escape_pendingp = 0;

More information about the openssh-unix-dev mailing list