summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Steves <stevesk@cvs.openbsd.org>2001-04-14 16:33:21 +0000
committerKevin Steves <stevesk@cvs.openbsd.org>2001-04-14 16:33:21 +0000
commitf38e8ebb4d051ef9b25d767d54567fdc712a6a67 (patch)
tree493e9c83b7b855518498c03b186480c4582a7977
parentf9e9c12e9fea79bc7c95093f1e2b5a84e0bcf82c (diff)
protocol 2 tty modes support; ok markus@
-rw-r--r--usr.bin/ssh/clientloop.c56
-rw-r--r--usr.bin/ssh/packet.h6
-rw-r--r--usr.bin/ssh/session.c13
-rw-r--r--usr.bin/ssh/ssh.c9
-rw-r--r--usr.bin/ssh/ssh/Makefile4
-rw-r--r--usr.bin/ssh/sshtty.c96
-rw-r--r--usr.bin/ssh/sshtty.h65
-rw-r--r--usr.bin/ssh/ttymodes.c231
-rw-r--r--usr.bin/ssh/ttymodes.h39
9 files changed, 388 insertions, 131 deletions
diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c
index 94d2ec60bb0..24ea0dec0e1 100644
--- a/usr.bin/ssh/clientloop.c
+++ b/usr.bin/ssh/clientloop.c
@@ -59,7 +59,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.61 2001/04/08 11:27:33 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.62 2001/04/14 16:33:20 stevesk Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -79,6 +79,7 @@ RCSID("$OpenBSD: clientloop.c,v 1.61 2001/04/08 11:27:33 markus Exp $");
#include "clientloop.h"
#include "authfd.h"
#include "atomicio.h"
+#include "sshtty.h"
/* import options */
extern Options options;
@@ -101,15 +102,6 @@ extern char *host;
*/
static volatile int received_window_change_signal = 0;
-/* Terminal modes, as saved by enter_raw_mode. */
-static struct termios saved_tio;
-
-/*
- * Flag indicating whether we are in raw mode. This is used by
- * enter_raw_mode and leave_raw_mode.
- */
-static int in_raw_mode = 0;
-
/* Flag indicating whether the user\'s terminal is in non-blocking mode. */
static int in_non_blocking_mode = 0;
@@ -136,46 +128,6 @@ int session_ident = -1;
/*XXX*/
extern Kex *xxx_kex;
-/* Returns the user\'s terminal to normal mode if it had been put in raw mode. */
-
-void
-leave_raw_mode(void)
-{
- if (!in_raw_mode)
- return;
- in_raw_mode = 0;
- if (tcsetattr(fileno(stdin), TCSADRAIN, &saved_tio) < 0)
- perror("tcsetattr");
-
- fatal_remove_cleanup((void (*) (void *)) leave_raw_mode, NULL);
-}
-
-/* Puts the user\'s terminal in raw mode. */
-
-void
-enter_raw_mode(void)
-{
- struct termios tio;
-
- if (tcgetattr(fileno(stdin), &tio) < 0)
- perror("tcgetattr");
- saved_tio = tio;
- tio.c_iflag |= IGNPAR;
- tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
- tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
-#ifdef IEXTEN
- tio.c_lflag &= ~IEXTEN;
-#endif /* IEXTEN */
- tio.c_oflag &= ~OPOST;
- tio.c_cc[VMIN] = 1;
- tio.c_cc[VTIME] = 0;
- if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0)
- perror("tcsetattr");
- in_raw_mode = 1;
-
- fatal_add_cleanup((void (*) (void *)) leave_raw_mode, NULL);
-}
-
/* Restores stdin to blocking mode. */
void
@@ -218,7 +170,7 @@ window_change_handler(int sig)
void
signal_handler(int sig)
{
- if (in_raw_mode)
+ if (in_raw_mode())
leave_raw_mode();
if (in_non_blocking_mode)
leave_non_blocking();
@@ -796,7 +748,7 @@ client_channel_closed(int id, void *arg)
error("client_channel_closed: id %d != session_ident %d",
id, session_ident);
session_closed = 1;
- if (in_raw_mode)
+ if (in_raw_mode())
leave_raw_mode();
}
diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h
index e5432714e90..0f5e7104997 100644
--- a/usr.bin/ssh/packet.h
+++ b/usr.bin/ssh/packet.h
@@ -11,7 +11,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: packet.h,v 1.21 2001/02/28 21:27:47 markus Exp $"); */
+/* RCSID("$OpenBSD: packet.h,v 1.22 2001/04/14 16:33:20 stevesk Exp $"); */
#ifndef PACKET_H
#define PACKET_H
@@ -178,8 +178,8 @@ extern int max_packet_size;
int packet_set_maxsize(int s);
#define packet_get_maxsize() max_packet_size
-/* Stores tty modes from the fd into current packet. */
-void tty_make_modes(int fd);
+/* Stores tty modes from the fd or tiop into current packet. */
+void tty_make_modes(int fd, struct termios *tiop);
/* Parses tty modes for the fd from the current packet. */
void tty_parse_modes(int fd, int *n_bytes_ptr);
diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c
index 03252789231..38a6b94fd0d 100644
--- a/usr.bin/ssh/session.c
+++ b/usr.bin/ssh/session.c
@@ -33,7 +33,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.71 2001/04/06 21:00:12 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.72 2001/04/14 16:33:20 stevesk Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -1265,7 +1265,7 @@ int
session_pty_req(Session *s)
{
u_int len;
- char *term_modes; /* encoded terminal modes */
+ int n_bytes;
if (no_pty_flag)
return 0;
@@ -1276,8 +1276,6 @@ session_pty_req(Session *s)
s->row = packet_get_int();
s->xpixel = packet_get_int();
s->ypixel = packet_get_int();
- term_modes = packet_get_string(&len);
- packet_done();
if (strcmp(s->term, "") == 0) {
xfree(s->term);
@@ -1290,7 +1288,6 @@ session_pty_req(Session *s)
s->ptyfd = -1;
s->ttyfd = -1;
error("session_pty_req: session %d alloc failed", s->self);
- xfree(term_modes);
return 0;
}
debug("session_pty_req: session %d alloc %s", s->self, s->tty);
@@ -1303,10 +1300,12 @@ session_pty_req(Session *s)
/* Get window size from the packet. */
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
+ /* Get tty modes from the packet. */
+ tty_parse_modes(s->ttyfd, &n_bytes);
+ packet_done();
+
session_proctitle(s);
- /* XXX parse and set terminal modes */
- xfree(term_modes);
return 1;
}
diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c
index 512a5af0dbc..470a4d41259 100644
--- a/usr.bin/ssh/ssh.c
+++ b/usr.bin/ssh/ssh.c
@@ -39,7 +39,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.114 2001/04/13 01:26:17 stevesk Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.115 2001/04/14 16:33:20 stevesk Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@@ -67,6 +67,7 @@ RCSID("$OpenBSD: ssh.c,v 1.114 2001/04/13 01:26:17 stevesk Exp $");
#include "misc.h"
#include "kex.h"
#include "mac.h"
+#include "sshtty.h"
extern char *__progname;
@@ -858,7 +859,7 @@ ssh_session(void)
packet_put_int(ws.ws_ypixel);
/* Store tty modes in the packet. */
- tty_make_modes(fileno(stdin));
+ tty_make_modes(fileno(stdin), NULL);
/* Send the packet, and wait for it to leave. */
packet_send();
@@ -962,6 +963,7 @@ ssh_session2_callback(int id, void *arg)
{
int len;
int interactive = 0;
+ struct termios tio;
debug("client_init id %d arg %ld", id, (long)arg);
@@ -981,7 +983,8 @@ ssh_session2_callback(int id, void *arg)
packet_put_int(ws.ws_row);
packet_put_int(ws.ws_xpixel);
packet_put_int(ws.ws_ypixel);
- packet_put_cstring(""); /* XXX: encode terminal modes */
+ tio = get_saved_tio();
+ tty_make_modes(/*ignored*/ 0, &tio);
packet_send();
interactive = 1;
/* XXX wait for reply */
diff --git a/usr.bin/ssh/ssh/Makefile b/usr.bin/ssh/ssh/Makefile
index 85d8cbcf64a..2cf80e10f82 100644
--- a/usr.bin/ssh/ssh/Makefile
+++ b/usr.bin/ssh/ssh/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.29 2001/03/04 00:51:25 markus Exp $
+# $OpenBSD: Makefile,v 1.30 2001/04/14 16:33:20 stevesk Exp $
.PATH: ${.CURDIR}/..
@@ -12,7 +12,7 @@ MAN= ssh.1
LINKS= ${BINDIR}/ssh ${BINDIR}/slogin
MLINKS= ssh.1 slogin.1
-SRCS= ssh.c readconf.c clientloop.c \
+SRCS= ssh.c readconf.c clientloop.c sshtty.c \
sshconnect.c sshconnect1.c sshconnect2.c
.include <bsd.own.mk> # for AFS
diff --git a/usr.bin/ssh/sshtty.c b/usr.bin/ssh/sshtty.c
new file mode 100644
index 00000000000..78498908fc6
--- /dev/null
+++ b/usr.bin/ssh/sshtty.c
@@ -0,0 +1,96 @@
+/* $OpenBSD: sshtty.c,v 1.1 2001/04/14 16:33:20 stevesk Exp $ */
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ * All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose. Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ * Copyright (c) 2001 Kevin Steves. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+#include "sshtty.h"
+#include "log.h"
+
+static struct termios _saved_tio;
+static int _in_raw_mode = 0;
+
+int
+in_raw_mode(void)
+{
+ return _in_raw_mode;
+}
+
+struct termios
+get_saved_tio(void)
+{
+ return _saved_tio;
+}
+
+void
+leave_raw_mode(void)
+{
+ if (!_in_raw_mode)
+ return;
+ if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1)
+ perror("tcsetattr");
+ else
+ _in_raw_mode = 0;
+
+ fatal_remove_cleanup((void (*) (void *)) leave_raw_mode, NULL);
+}
+
+void
+enter_raw_mode(void)
+{
+ struct termios tio;
+
+ if (tcgetattr(fileno(stdin), &tio) == -1) {
+ perror("tcgetattr");
+ return;
+ }
+ _saved_tio = tio;
+ tio.c_iflag |= IGNPAR;
+ tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
+ tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
+#ifdef IEXTEN
+ tio.c_lflag &= ~IEXTEN;
+#endif
+ tio.c_oflag &= ~OPOST;
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 0;
+ if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1)
+ perror("tcsetattr");
+ else
+ _in_raw_mode = 1;
+
+ fatal_add_cleanup((void (*) (void *)) leave_raw_mode, NULL);
+}
diff --git a/usr.bin/ssh/sshtty.h b/usr.bin/ssh/sshtty.h
new file mode 100644
index 00000000000..e29385e3522
--- /dev/null
+++ b/usr.bin/ssh/sshtty.h
@@ -0,0 +1,65 @@
+/* $OpenBSD: sshtty.h,v 1.1 2001/04/14 16:33:20 stevesk Exp $ */
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ * All rights reserved
+ *
+ * As far as I am concerned, the code I have written for this software
+ * can be used freely for any purpose. Any derived versions of this
+ * software must be clearly marked as such, and if the derived work is
+ * incompatible with the protocol description in the RFC file, it must be
+ * called by a name other than "ssh" or "Secure Shell".
+ */
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ * Copyright (c) 2001 Kevin Steves. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SSHTTY_H
+#define SSHTTY_H
+
+#include <termios.h>
+
+/*
+ * Accessor function indicating whether we are in raw mode. Set by
+ * enter_raw_mode() and leave_raw_mode().
+ */
+int in_raw_mode(void);
+
+/*
+ * Return terminal modes, as saved by enter_raw_mode().
+ */
+struct termios get_saved_tio(void);
+
+/*
+ * Returns the user's terminal to normal mode if it had been
+ * put in raw mode.
+ */
+void leave_raw_mode(void);
+
+/*
+ * Puts the user's terminal in raw mode.
+ */
+void enter_raw_mode(void);
+
+#endif
diff --git a/usr.bin/ssh/ttymodes.c b/usr.bin/ssh/ttymodes.c
index 65caf2ff852..9ce3fbcc47e 100644
--- a/usr.bin/ssh/ttymodes.c
+++ b/usr.bin/ssh/ttymodes.c
@@ -2,10 +2,6 @@
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
- * Encoding and decoding of terminal modes in a portable way.
- * Much of the format is defined in ttymodes.h; it is included multiple times
- * into this file with the appropriate macro definitions to generate the
- * suitable code.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
@@ -14,16 +10,56 @@
* called by a name other than "ssh" or "Secure Shell".
*/
+/*
+ * SSH2 tty modes support by Kevin Steves.
+ * Copyright (c) 2001 Kevin Steves. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Encoding and decoding of terminal modes in a portable way.
+ * Much of the format is defined in ttymodes.h; it is included multiple times
+ * into this file with the appropriate macro definitions to generate the
+ * suitable code.
+ */
+
#include "includes.h"
-RCSID("$OpenBSD: ttymodes.c,v 1.11 2001/03/10 15:02:05 stevesk Exp $");
+RCSID("$OpenBSD: ttymodes.c,v 1.12 2001/04/14 16:33:20 stevesk Exp $");
#include "packet.h"
#include "log.h"
#include "ssh1.h"
+#include "compat.h"
+#include "buffer.h"
+#include "bufaux.h"
-#define TTY_OP_END 0
-#define TTY_OP_ISPEED 192 /* int follows */
-#define TTY_OP_OSPEED 193 /* int follows */
+#define TTY_OP_END 0
+/*
+ * uint32 (u_int) follows speed in SSH1 and SSH2
+ */
+#define TTY_OP_ISPEED_PROTO1 192
+#define TTY_OP_OSPEED_PROTO1 193
+#define TTY_OP_ISPEED_PROTO2 128
+#define TTY_OP_OSPEED_PROTO2 129
/*
* Converts POSIX speed_t to a baud rate. The values of the
@@ -122,7 +158,7 @@ static speed_t
baud_to_speed(int baud)
{
switch (baud) {
- case 0:
+ case 0:
return B0;
case 50:
return B50;
@@ -206,41 +242,72 @@ baud_to_speed(int baud)
/*
* Encodes terminal modes for the terminal referenced by fd
- * in a portable manner, and appends the modes to a packet
+ * or tiop in a portable manner, and appends the modes to a packet
* being constructed.
*/
void
-tty_make_modes(int fd)
+tty_make_modes(int fd, struct termios *tiop)
{
struct termios tio;
int baud;
+ Buffer buf;
+ int tty_op_ospeed, tty_op_ispeed;
+ void (*put_arg)(Buffer *, u_int);
- if (tcgetattr(fd, &tio) < 0) {
- packet_put_char(TTY_OP_END);
- log("tcgetattr: %.100s", strerror(errno));
- return;
+ buffer_init(&buf);
+ if (compat20) {
+ tty_op_ospeed = TTY_OP_OSPEED_PROTO2;
+ tty_op_ispeed = TTY_OP_ISPEED_PROTO2;
+ put_arg = buffer_put_int;
+ } else {
+ tty_op_ospeed = TTY_OP_OSPEED_PROTO1;
+ tty_op_ispeed = TTY_OP_ISPEED_PROTO1;
+ put_arg = (void (*)(Buffer *, u_int)) buffer_put_char;
}
+
+ if (tiop == NULL) {
+ if (tcgetattr(fd, &tio) == -1) {
+ log("tcgetattr: %.100s", strerror(errno));
+ goto end;
+ }
+ } else
+ tio = *tiop;
+
/* Store input and output baud rates. */
baud = speed_to_baud(cfgetospeed(&tio));
- packet_put_char(TTY_OP_OSPEED);
- packet_put_int(baud);
+ debug2("tty_make_modes: ospeed %d", baud);
+ buffer_put_char(&buf, tty_op_ospeed);
+ buffer_put_int(&buf, baud);
baud = speed_to_baud(cfgetispeed(&tio));
- packet_put_char(TTY_OP_ISPEED);
- packet_put_int(baud);
+ debug2("tty_make_modes: ispeed %d", baud);
+ buffer_put_char(&buf, tty_op_ispeed);
+ buffer_put_int(&buf, baud);
/* Store values of mode flags. */
#define TTYCHAR(NAME, OP) \
- packet_put_char(OP); packet_put_char(tio.c_cc[NAME]);
+ debug2("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \
+ buffer_put_char(&buf, OP); \
+ put_arg(&buf, tio.c_cc[NAME]);
+
#define TTYMODE(NAME, FIELD, OP) \
- packet_put_char(OP); packet_put_char((tio.FIELD & NAME) != 0);
+ debug2("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \
+ buffer_put_char(&buf, OP); \
+ put_arg(&buf, ((tio.FIELD & NAME) != 0));
#include "ttymodes.h"
#undef TTYCHAR
#undef TTYMODE
+end:
/* Mark end of mode data. */
- packet_put_char(TTY_OP_END);
+ buffer_put_char(&buf, TTY_OP_END);
+ if (compat20)
+ packet_put_string(buffer_ptr(&buf), buffer_len(&buf));
+ else
+ packet_put_raw(buffer_ptr(&buf), buffer_len(&buf));
+ buffer_free(&buf);
+ return;
}
/*
@@ -254,14 +321,30 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
int opcode, baud;
int n_bytes = 0;
int failure = 0;
+ u_int (*get_arg)(void);
+ int arg, arg_size;
+
+ if (compat20) {
+ *n_bytes_ptr = packet_get_int();
+ debug2("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr);
+ if (*n_bytes_ptr == 0)
+ return;
+ get_arg = packet_get_int;
+ arg_size = 4;
+ } else {
+ get_arg = packet_get_char;
+ arg_size = 1;
+ }
/*
* Get old attributes for the terminal. We will modify these
* flags. I am hoping that if there are any machine-specific
* modes, they will initially have reasonable values.
*/
- if (tcgetattr(fd, &tio) < 0)
+ if (tcgetattr(fd, &tio) == -1) {
+ log("tcgetattr: %.100s", strerror(errno));
failure = -1;
+ }
for (;;) {
n_bytes += 1;
@@ -270,32 +353,40 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
case TTY_OP_END:
goto set;
- case TTY_OP_ISPEED:
+ /* XXX: future conflict possible */
+ case TTY_OP_ISPEED_PROTO1:
+ case TTY_OP_ISPEED_PROTO2:
n_bytes += 4;
baud = packet_get_int();
- if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0)
+ debug2("tty_parse_modes: ispeed %d", baud);
+ if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1)
error("cfsetispeed failed for %d", baud);
break;
- case TTY_OP_OSPEED:
+ /* XXX: future conflict possible */
+ case TTY_OP_OSPEED_PROTO1:
+ case TTY_OP_OSPEED_PROTO2:
n_bytes += 4;
baud = packet_get_int();
- if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0)
+ debug2("tty_parse_modes: ospeed %d", baud);
+ if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1)
error("cfsetospeed failed for %d", baud);
break;
-#define TTYCHAR(NAME, OP) \
- case OP: \
- n_bytes += 1; \
- tio.c_cc[NAME] = packet_get_char(); \
+#define TTYCHAR(NAME, OP) \
+ case OP: \
+ n_bytes += arg_size; \
+ tio.c_cc[NAME] = get_arg(); \
+ debug2("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \
break;
-#define TTYMODE(NAME, FIELD, OP) \
- case OP: \
- n_bytes += 1; \
- if (packet_get_char()) \
- tio.FIELD |= NAME; \
- else \
- tio.FIELD &= ~NAME; \
+#define TTYMODE(NAME, FIELD, OP) \
+ case OP: \
+ n_bytes += arg_size; \
+ if ((arg = get_arg())) \
+ tio.FIELD |= NAME; \
+ else \
+ tio.FIELD &= ~NAME; \
+ debug2("tty_parse_modes: %d %d", OP, arg); \
break;
#include "ttymodes.h"
@@ -306,48 +397,66 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
default:
debug("Ignoring unsupported tty mode opcode %d (0x%x)",
opcode, opcode);
- /*
- * Opcodes 0 to 127 are defined to have
- * a one-byte argument.
- */
- if (opcode >= 0 && opcode < 128) {
- n_bytes += 1;
- (void) packet_get_char();
- break;
+ if (!compat20) {
+ /*
+ * SSH1:
+ * Opcodes 1 to 127 are defined to have
+ * a one-byte argument.
+ * Opcodes 128 to 159 are defined to have
+ * an integer argument.
+ */
+ if (opcode > 0 && opcode < 128) {
+ n_bytes += 1;
+ (void) packet_get_char();
+ break;
+ } else if (opcode >= 128 && opcode < 160) {
+ n_bytes += 4;
+ (void) packet_get_int();
+ break;
+ } else {
+ /*
+ * It is a truly undefined opcode (160 to 255).
+ * We have no idea about its arguments. So we
+ * must stop parsing. Note that some data may be
+ * left in the packet; hopefully there is nothing
+ * more coming after the mode data.
+ */
+ log("parse_tty_modes: unknown opcode %d", opcode);
+ packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY);
+ goto set;
+ }
} else {
/*
- * Opcodes 128 to 159 are defined to have
- * an integer argument.
+ * SSH2:
+ * Opcodes 0 to 159 are defined to have
+ * a uint32 argument.
+ * Opcodes 160 to 255 are undefined and
+ * cause parsing to stop.
*/
- if (opcode >= 128 && opcode < 160) {
+ if (opcode > 0 && opcode < 160) {
n_bytes += 4;
(void) packet_get_int();
break;
+ } else {
+ log("parse_tty_modes: unknown opcode %d", opcode);
+ goto set;
}
- }
- /*
- * It is a truly undefined opcode (160 to 255).
- * We have no idea about its arguments. So we
- * must stop parsing. Note that some data may be
- * left in the packet; hopefully there is nothing
- * more coming after the mode data.
- */
- log("parse_tty_modes: unknown opcode %d", opcode);
- packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY);
- goto set;
+ }
}
}
set:
if (*n_bytes_ptr != n_bytes) {
*n_bytes_ptr = n_bytes;
+ log("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d",
+ *n_bytes_ptr, n_bytes);
return; /* Don't process bytes passed */
}
if (failure == -1)
return; /* Packet parsed ok but tty stuff failed */
/* Set the new modes for the terminal. */
- if (tcsetattr(fd, TCSANOW, &tio) < 0)
+ if (tcsetattr(fd, TCSANOW, &tio) == -1)
log("Setting tty modes failed: %.100s", strerror(errno));
return;
}
diff --git a/usr.bin/ssh/ttymodes.h b/usr.bin/ssh/ttymodes.h
index 860fd0a9cc6..ad980e98cfe 100644
--- a/usr.bin/ssh/ttymodes.h
+++ b/usr.bin/ssh/ttymodes.h
@@ -1,6 +1,6 @@
+/* RCSID("$OpenBSD: ttymodes.h,v 1.11 2001/04/14 16:33:20 stevesk Exp $"); */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
- * SGTTY stuff contributed by Janne Snabb <snabb@niksula.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
*
@@ -11,14 +11,47 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: ttymodes.h,v 1.10 2001/03/10 15:02:05 stevesk Exp $"); */
+/*
+ * SSH2 tty modes support by Kevin Steves.
+ * Copyright (c) 2001 Kevin Steves. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
-/* The tty mode description is a stream of bytes. The stream consists of
+/*
+ * SSH1:
+ * The tty mode description is a stream of bytes. The stream consists of
* opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0).
* Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer
* arguments. Opcodes 160-255 are not yet defined, and cause parsing to
* stop (they should only be used after any other data).
*
+ * SSH2:
+ * Differences between SSH1 and SSH2 terminal mode encoding include:
+ * 1. Encoded terminal modes are represented as a string, and a stream
+ * of bytes within that string.
+ * 2. Opcode arguments are uint32 (1-159); 160-255 remain undefined.
+ * 3. The values for TTY_OP_ISPEED and TTY_OP_OSPEED are different;
+ * 128 and 129 vs. 192 and 193 respectively.
+ *
* The client puts in the stream any modes it knows about, and the
* server ignores any modes it does not know about. This allows some degree
* of machine-independence, at least between systems that use a posix-like