diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2001-04-14 23:13:02 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2001-04-14 23:13:02 +0000 |
commit | ae8e2d30db561a556ee0a82dce0dcda3d6f82623 (patch) | |
tree | ccb6c556b05f7f6a77c5500a3bbe68fc5114c22c | |
parent | 7457f2af01d77c4bdeaef3a6c211bb2f1e215a9c (diff) |
- stevesk@cvs.openbsd.org 2001/04/14 16:33:20
[clientloop.c packet.h session.c ssh.c ttymodes.c ttymodes.h]
protocol 2 tty modes support; ok markus@
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | clientloop.c | 56 | ||||
-rw-r--r-- | packet.h | 6 | ||||
-rw-r--r-- | session.c | 13 | ||||
-rw-r--r-- | ssh.c | 9 | ||||
-rw-r--r-- | ttymodes.c | 231 | ||||
-rw-r--r-- | ttymodes.h | 39 |
7 files changed, 229 insertions, 130 deletions
@@ -9,6 +9,9 @@ | |||
9 | - markus@cvs.openbsd.org 2001/04/14 16:27:57 | 9 | - markus@cvs.openbsd.org 2001/04/14 16:27:57 |
10 | [ssh-add.c] | 10 | [ssh-add.c] |
11 | use clear_pass instead of xfree() | 11 | use clear_pass instead of xfree() |
12 | - stevesk@cvs.openbsd.org 2001/04/14 16:33:20 | ||
13 | [clientloop.c packet.h session.c ssh.c ttymodes.c ttymodes.h] | ||
14 | protocol 2 tty modes support; ok markus@ | ||
12 | 15 | ||
13 | 20010414 | 16 | 20010414 |
14 | - Sync with OpenBSD glob.c, strlcat.c and vis.c changes | 17 | - Sync with OpenBSD glob.c, strlcat.c and vis.c changes |
@@ -5075,4 +5078,4 @@ | |||
5075 | - Wrote replacements for strlcpy and mkdtemp | 5078 | - Wrote replacements for strlcpy and mkdtemp |
5076 | - Released 1.0pre1 | 5079 | - Released 1.0pre1 |
5077 | 5080 | ||
5078 | $Id: ChangeLog,v 1.1113 2001/04/14 23:10:09 mouring Exp $ | 5081 | $Id: ChangeLog,v 1.1114 2001/04/14 23:13:02 mouring Exp $ |
diff --git a/clientloop.c b/clientloop.c index 94d2ec60b..24ea0dec0 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -59,7 +59,7 @@ | |||
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "includes.h" | 61 | #include "includes.h" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.61 2001/04/08 11:27:33 markus Exp $"); | 62 | RCSID("$OpenBSD: clientloop.c,v 1.62 2001/04/14 16:33:20 stevesk Exp $"); |
63 | 63 | ||
64 | #include "ssh.h" | 64 | #include "ssh.h" |
65 | #include "ssh1.h" | 65 | #include "ssh1.h" |
@@ -79,6 +79,7 @@ RCSID("$OpenBSD: clientloop.c,v 1.61 2001/04/08 11:27:33 markus Exp $"); | |||
79 | #include "clientloop.h" | 79 | #include "clientloop.h" |
80 | #include "authfd.h" | 80 | #include "authfd.h" |
81 | #include "atomicio.h" | 81 | #include "atomicio.h" |
82 | #include "sshtty.h" | ||
82 | 83 | ||
83 | /* import options */ | 84 | /* import options */ |
84 | extern Options options; | 85 | extern Options options; |
@@ -101,15 +102,6 @@ extern char *host; | |||
101 | */ | 102 | */ |
102 | static volatile int received_window_change_signal = 0; | 103 | static volatile int received_window_change_signal = 0; |
103 | 104 | ||
104 | /* Terminal modes, as saved by enter_raw_mode. */ | ||
105 | static struct termios saved_tio; | ||
106 | |||
107 | /* | ||
108 | * Flag indicating whether we are in raw mode. This is used by | ||
109 | * enter_raw_mode and leave_raw_mode. | ||
110 | */ | ||
111 | static int in_raw_mode = 0; | ||
112 | |||
113 | /* Flag indicating whether the user\'s terminal is in non-blocking mode. */ | 105 | /* Flag indicating whether the user\'s terminal is in non-blocking mode. */ |
114 | static int in_non_blocking_mode = 0; | 106 | static int in_non_blocking_mode = 0; |
115 | 107 | ||
@@ -136,46 +128,6 @@ int session_ident = -1; | |||
136 | /*XXX*/ | 128 | /*XXX*/ |
137 | extern Kex *xxx_kex; | 129 | extern Kex *xxx_kex; |
138 | 130 | ||
139 | /* Returns the user\'s terminal to normal mode if it had been put in raw mode. */ | ||
140 | |||
141 | void | ||
142 | leave_raw_mode(void) | ||
143 | { | ||
144 | if (!in_raw_mode) | ||
145 | return; | ||
146 | in_raw_mode = 0; | ||
147 | if (tcsetattr(fileno(stdin), TCSADRAIN, &saved_tio) < 0) | ||
148 | perror("tcsetattr"); | ||
149 | |||
150 | fatal_remove_cleanup((void (*) (void *)) leave_raw_mode, NULL); | ||
151 | } | ||
152 | |||
153 | /* Puts the user\'s terminal in raw mode. */ | ||
154 | |||
155 | void | ||
156 | enter_raw_mode(void) | ||
157 | { | ||
158 | struct termios tio; | ||
159 | |||
160 | if (tcgetattr(fileno(stdin), &tio) < 0) | ||
161 | perror("tcgetattr"); | ||
162 | saved_tio = tio; | ||
163 | tio.c_iflag |= IGNPAR; | ||
164 | tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF); | ||
165 | tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); | ||
166 | #ifdef IEXTEN | ||
167 | tio.c_lflag &= ~IEXTEN; | ||
168 | #endif /* IEXTEN */ | ||
169 | tio.c_oflag &= ~OPOST; | ||
170 | tio.c_cc[VMIN] = 1; | ||
171 | tio.c_cc[VTIME] = 0; | ||
172 | if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) < 0) | ||
173 | perror("tcsetattr"); | ||
174 | in_raw_mode = 1; | ||
175 | |||
176 | fatal_add_cleanup((void (*) (void *)) leave_raw_mode, NULL); | ||
177 | } | ||
178 | |||
179 | /* Restores stdin to blocking mode. */ | 131 | /* Restores stdin to blocking mode. */ |
180 | 132 | ||
181 | void | 133 | void |
@@ -218,7 +170,7 @@ window_change_handler(int sig) | |||
218 | void | 170 | void |
219 | signal_handler(int sig) | 171 | signal_handler(int sig) |
220 | { | 172 | { |
221 | if (in_raw_mode) | 173 | if (in_raw_mode()) |
222 | leave_raw_mode(); | 174 | leave_raw_mode(); |
223 | if (in_non_blocking_mode) | 175 | if (in_non_blocking_mode) |
224 | leave_non_blocking(); | 176 | leave_non_blocking(); |
@@ -796,7 +748,7 @@ client_channel_closed(int id, void *arg) | |||
796 | error("client_channel_closed: id %d != session_ident %d", | 748 | error("client_channel_closed: id %d != session_ident %d", |
797 | id, session_ident); | 749 | id, session_ident); |
798 | session_closed = 1; | 750 | session_closed = 1; |
799 | if (in_raw_mode) | 751 | if (in_raw_mode()) |
800 | leave_raw_mode(); | 752 | leave_raw_mode(); |
801 | } | 753 | } |
802 | 754 | ||
@@ -11,7 +11,7 @@ | |||
11 | * called by a name other than "ssh" or "Secure Shell". | 11 | * called by a name other than "ssh" or "Secure Shell". |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* RCSID("$OpenBSD: packet.h,v 1.21 2001/02/28 21:27:47 markus Exp $"); */ | 14 | /* RCSID("$OpenBSD: packet.h,v 1.22 2001/04/14 16:33:20 stevesk Exp $"); */ |
15 | 15 | ||
16 | #ifndef PACKET_H | 16 | #ifndef PACKET_H |
17 | #define PACKET_H | 17 | #define PACKET_H |
@@ -178,8 +178,8 @@ extern int max_packet_size; | |||
178 | int packet_set_maxsize(int s); | 178 | int packet_set_maxsize(int s); |
179 | #define packet_get_maxsize() max_packet_size | 179 | #define packet_get_maxsize() max_packet_size |
180 | 180 | ||
181 | /* Stores tty modes from the fd into current packet. */ | 181 | /* Stores tty modes from the fd or tiop into current packet. */ |
182 | void tty_make_modes(int fd); | 182 | void tty_make_modes(int fd, struct termios *tiop); |
183 | 183 | ||
184 | /* Parses tty modes for the fd from the current packet. */ | 184 | /* Parses tty modes for the fd from the current packet. */ |
185 | void tty_parse_modes(int fd, int *n_bytes_ptr); | 185 | void tty_parse_modes(int fd, int *n_bytes_ptr); |
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include "includes.h" | 35 | #include "includes.h" |
36 | RCSID("$OpenBSD: session.c,v 1.71 2001/04/06 21:00:12 markus Exp $"); | 36 | RCSID("$OpenBSD: session.c,v 1.72 2001/04/14 16:33:20 stevesk Exp $"); |
37 | 37 | ||
38 | #include "ssh.h" | 38 | #include "ssh.h" |
39 | #include "ssh1.h" | 39 | #include "ssh1.h" |
@@ -1603,7 +1603,7 @@ int | |||
1603 | session_pty_req(Session *s) | 1603 | session_pty_req(Session *s) |
1604 | { | 1604 | { |
1605 | u_int len; | 1605 | u_int len; |
1606 | char *term_modes; /* encoded terminal modes */ | 1606 | int n_bytes; |
1607 | 1607 | ||
1608 | if (no_pty_flag) | 1608 | if (no_pty_flag) |
1609 | return 0; | 1609 | return 0; |
@@ -1614,8 +1614,6 @@ session_pty_req(Session *s) | |||
1614 | s->row = packet_get_int(); | 1614 | s->row = packet_get_int(); |
1615 | s->xpixel = packet_get_int(); | 1615 | s->xpixel = packet_get_int(); |
1616 | s->ypixel = packet_get_int(); | 1616 | s->ypixel = packet_get_int(); |
1617 | term_modes = packet_get_string(&len); | ||
1618 | packet_done(); | ||
1619 | 1617 | ||
1620 | if (strcmp(s->term, "") == 0) { | 1618 | if (strcmp(s->term, "") == 0) { |
1621 | xfree(s->term); | 1619 | xfree(s->term); |
@@ -1628,7 +1626,6 @@ session_pty_req(Session *s) | |||
1628 | s->ptyfd = -1; | 1626 | s->ptyfd = -1; |
1629 | s->ttyfd = -1; | 1627 | s->ttyfd = -1; |
1630 | error("session_pty_req: session %d alloc failed", s->self); | 1628 | error("session_pty_req: session %d alloc failed", s->self); |
1631 | xfree(term_modes); | ||
1632 | return 0; | 1629 | return 0; |
1633 | } | 1630 | } |
1634 | debug("session_pty_req: session %d alloc %s", s->self, s->tty); | 1631 | debug("session_pty_req: session %d alloc %s", s->self, s->tty); |
@@ -1641,10 +1638,12 @@ session_pty_req(Session *s) | |||
1641 | /* Get window size from the packet. */ | 1638 | /* Get window size from the packet. */ |
1642 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); | 1639 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); |
1643 | 1640 | ||
1641 | /* Get tty modes from the packet. */ | ||
1642 | tty_parse_modes(s->ttyfd, &n_bytes); | ||
1643 | packet_done(); | ||
1644 | |||
1644 | session_proctitle(s); | 1645 | session_proctitle(s); |
1645 | 1646 | ||
1646 | /* XXX parse and set terminal modes */ | ||
1647 | xfree(term_modes); | ||
1648 | return 1; | 1647 | return 1; |
1649 | } | 1648 | } |
1650 | 1649 | ||
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: ssh.c,v 1.114 2001/04/13 01:26:17 stevesk Exp $"); | 42 | RCSID("$OpenBSD: ssh.c,v 1.115 2001/04/14 16:33:20 stevesk Exp $"); |
43 | 43 | ||
44 | #include <openssl/evp.h> | 44 | #include <openssl/evp.h> |
45 | #include <openssl/err.h> | 45 | #include <openssl/err.h> |
@@ -67,6 +67,7 @@ RCSID("$OpenBSD: ssh.c,v 1.114 2001/04/13 01:26:17 stevesk Exp $"); | |||
67 | #include "misc.h" | 67 | #include "misc.h" |
68 | #include "kex.h" | 68 | #include "kex.h" |
69 | #include "mac.h" | 69 | #include "mac.h" |
70 | #include "sshtty.h" | ||
70 | 71 | ||
71 | #ifdef HAVE___PROGNAME | 72 | #ifdef HAVE___PROGNAME |
72 | extern char *__progname; | 73 | extern char *__progname; |
@@ -879,7 +880,7 @@ ssh_session(void) | |||
879 | packet_put_int(ws.ws_ypixel); | 880 | packet_put_int(ws.ws_ypixel); |
880 | 881 | ||
881 | /* Store tty modes in the packet. */ | 882 | /* Store tty modes in the packet. */ |
882 | tty_make_modes(fileno(stdin)); | 883 | tty_make_modes(fileno(stdin), NULL); |
883 | 884 | ||
884 | /* Send the packet, and wait for it to leave. */ | 885 | /* Send the packet, and wait for it to leave. */ |
885 | packet_send(); | 886 | packet_send(); |
@@ -983,6 +984,7 @@ ssh_session2_callback(int id, void *arg) | |||
983 | { | 984 | { |
984 | int len; | 985 | int len; |
985 | int interactive = 0; | 986 | int interactive = 0; |
987 | struct termios tio; | ||
986 | 988 | ||
987 | debug("client_init id %d arg %ld", id, (long)arg); | 989 | debug("client_init id %d arg %ld", id, (long)arg); |
988 | 990 | ||
@@ -1002,7 +1004,8 @@ ssh_session2_callback(int id, void *arg) | |||
1002 | packet_put_int(ws.ws_row); | 1004 | packet_put_int(ws.ws_row); |
1003 | packet_put_int(ws.ws_xpixel); | 1005 | packet_put_int(ws.ws_xpixel); |
1004 | packet_put_int(ws.ws_ypixel); | 1006 | packet_put_int(ws.ws_ypixel); |
1005 | packet_put_cstring(""); /* XXX: encode terminal modes */ | 1007 | tio = get_saved_tio(); |
1008 | tty_make_modes(/*ignored*/ 0, &tio); | ||
1006 | packet_send(); | 1009 | packet_send(); |
1007 | interactive = 1; | 1010 | interactive = 1; |
1008 | /* XXX wait for reply */ | 1011 | /* XXX wait for reply */ |
diff --git a/ttymodes.c b/ttymodes.c index 65caf2ff8..9ce3fbcc4 100644 --- a/ttymodes.c +++ b/ttymodes.c | |||
@@ -2,10 +2,6 @@ | |||
2 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 2 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
5 | * Encoding and decoding of terminal modes in a portable way. | ||
6 | * Much of the format is defined in ttymodes.h; it is included multiple times | ||
7 | * into this file with the appropriate macro definitions to generate the | ||
8 | * suitable code. | ||
9 | * | 5 | * |
10 | * As far as I am concerned, the code I have written for this software | 6 | * As far as I am concerned, the code I have written for this software |
11 | * can be used freely for any purpose. Any derived versions of this | 7 | * can be used freely for any purpose. Any derived versions of this |
@@ -14,16 +10,56 @@ | |||
14 | * called by a name other than "ssh" or "Secure Shell". | 10 | * called by a name other than "ssh" or "Secure Shell". |
15 | */ | 11 | */ |
16 | 12 | ||
13 | /* | ||
14 | * SSH2 tty modes support by Kevin Steves. | ||
15 | * Copyright (c) 2001 Kevin Steves. All rights reserved. | ||
16 | * | ||
17 | * Redistribution and use in source and binary forms, with or without | ||
18 | * modification, are permitted provided that the following conditions | ||
19 | * are met: | ||
20 | * 1. Redistributions of source code must retain the above copyright | ||
21 | * notice, this list of conditions and the following disclaimer. | ||
22 | * 2. Redistributions in binary form must reproduce the above copyright | ||
23 | * notice, this list of conditions and the following disclaimer in the | ||
24 | * documentation and/or other materials provided with the distribution. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
27 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
28 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
29 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
30 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
31 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
32 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
35 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | */ | ||
37 | |||
38 | /* | ||
39 | * Encoding and decoding of terminal modes in a portable way. | ||
40 | * Much of the format is defined in ttymodes.h; it is included multiple times | ||
41 | * into this file with the appropriate macro definitions to generate the | ||
42 | * suitable code. | ||
43 | */ | ||
44 | |||
17 | #include "includes.h" | 45 | #include "includes.h" |
18 | RCSID("$OpenBSD: ttymodes.c,v 1.11 2001/03/10 15:02:05 stevesk Exp $"); | 46 | RCSID("$OpenBSD: ttymodes.c,v 1.12 2001/04/14 16:33:20 stevesk Exp $"); |
19 | 47 | ||
20 | #include "packet.h" | 48 | #include "packet.h" |
21 | #include "log.h" | 49 | #include "log.h" |
22 | #include "ssh1.h" | 50 | #include "ssh1.h" |
51 | #include "compat.h" | ||
52 | #include "buffer.h" | ||
53 | #include "bufaux.h" | ||
23 | 54 | ||
24 | #define TTY_OP_END 0 | 55 | #define TTY_OP_END 0 |
25 | #define TTY_OP_ISPEED 192 /* int follows */ | 56 | /* |
26 | #define TTY_OP_OSPEED 193 /* int follows */ | 57 | * uint32 (u_int) follows speed in SSH1 and SSH2 |
58 | */ | ||
59 | #define TTY_OP_ISPEED_PROTO1 192 | ||
60 | #define TTY_OP_OSPEED_PROTO1 193 | ||
61 | #define TTY_OP_ISPEED_PROTO2 128 | ||
62 | #define TTY_OP_OSPEED_PROTO2 129 | ||
27 | 63 | ||
28 | /* | 64 | /* |
29 | * Converts POSIX speed_t to a baud rate. The values of the | 65 | * Converts POSIX speed_t to a baud rate. The values of the |
@@ -122,7 +158,7 @@ static speed_t | |||
122 | baud_to_speed(int baud) | 158 | baud_to_speed(int baud) |
123 | { | 159 | { |
124 | switch (baud) { | 160 | switch (baud) { |
125 | case 0: | 161 | case 0: |
126 | return B0; | 162 | return B0; |
127 | case 50: | 163 | case 50: |
128 | return B50; | 164 | return B50; |
@@ -206,41 +242,72 @@ baud_to_speed(int baud) | |||
206 | 242 | ||
207 | /* | 243 | /* |
208 | * Encodes terminal modes for the terminal referenced by fd | 244 | * Encodes terminal modes for the terminal referenced by fd |
209 | * in a portable manner, and appends the modes to a packet | 245 | * or tiop in a portable manner, and appends the modes to a packet |
210 | * being constructed. | 246 | * being constructed. |
211 | */ | 247 | */ |
212 | void | 248 | void |
213 | tty_make_modes(int fd) | 249 | tty_make_modes(int fd, struct termios *tiop) |
214 | { | 250 | { |
215 | struct termios tio; | 251 | struct termios tio; |
216 | int baud; | 252 | int baud; |
253 | Buffer buf; | ||
254 | int tty_op_ospeed, tty_op_ispeed; | ||
255 | void (*put_arg)(Buffer *, u_int); | ||
217 | 256 | ||
218 | if (tcgetattr(fd, &tio) < 0) { | 257 | buffer_init(&buf); |
219 | packet_put_char(TTY_OP_END); | 258 | if (compat20) { |
220 | log("tcgetattr: %.100s", strerror(errno)); | 259 | tty_op_ospeed = TTY_OP_OSPEED_PROTO2; |
221 | return; | 260 | tty_op_ispeed = TTY_OP_ISPEED_PROTO2; |
261 | put_arg = buffer_put_int; | ||
262 | } else { | ||
263 | tty_op_ospeed = TTY_OP_OSPEED_PROTO1; | ||
264 | tty_op_ispeed = TTY_OP_ISPEED_PROTO1; | ||
265 | put_arg = (void (*)(Buffer *, u_int)) buffer_put_char; | ||
222 | } | 266 | } |
267 | |||
268 | if (tiop == NULL) { | ||
269 | if (tcgetattr(fd, &tio) == -1) { | ||
270 | log("tcgetattr: %.100s", strerror(errno)); | ||
271 | goto end; | ||
272 | } | ||
273 | } else | ||
274 | tio = *tiop; | ||
275 | |||
223 | /* Store input and output baud rates. */ | 276 | /* Store input and output baud rates. */ |
224 | baud = speed_to_baud(cfgetospeed(&tio)); | 277 | baud = speed_to_baud(cfgetospeed(&tio)); |
225 | packet_put_char(TTY_OP_OSPEED); | 278 | debug2("tty_make_modes: ospeed %d", baud); |
226 | packet_put_int(baud); | 279 | buffer_put_char(&buf, tty_op_ospeed); |
280 | buffer_put_int(&buf, baud); | ||
227 | baud = speed_to_baud(cfgetispeed(&tio)); | 281 | baud = speed_to_baud(cfgetispeed(&tio)); |
228 | packet_put_char(TTY_OP_ISPEED); | 282 | debug2("tty_make_modes: ispeed %d", baud); |
229 | packet_put_int(baud); | 283 | buffer_put_char(&buf, tty_op_ispeed); |
284 | buffer_put_int(&buf, baud); | ||
230 | 285 | ||
231 | /* Store values of mode flags. */ | 286 | /* Store values of mode flags. */ |
232 | #define TTYCHAR(NAME, OP) \ | 287 | #define TTYCHAR(NAME, OP) \ |
233 | packet_put_char(OP); packet_put_char(tio.c_cc[NAME]); | 288 | debug2("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \ |
289 | buffer_put_char(&buf, OP); \ | ||
290 | put_arg(&buf, tio.c_cc[NAME]); | ||
291 | |||
234 | #define TTYMODE(NAME, FIELD, OP) \ | 292 | #define TTYMODE(NAME, FIELD, OP) \ |
235 | packet_put_char(OP); packet_put_char((tio.FIELD & NAME) != 0); | 293 | debug2("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \ |
294 | buffer_put_char(&buf, OP); \ | ||
295 | put_arg(&buf, ((tio.FIELD & NAME) != 0)); | ||
236 | 296 | ||
237 | #include "ttymodes.h" | 297 | #include "ttymodes.h" |
238 | 298 | ||
239 | #undef TTYCHAR | 299 | #undef TTYCHAR |
240 | #undef TTYMODE | 300 | #undef TTYMODE |
241 | 301 | ||
302 | end: | ||
242 | /* Mark end of mode data. */ | 303 | /* Mark end of mode data. */ |
243 | packet_put_char(TTY_OP_END); | 304 | buffer_put_char(&buf, TTY_OP_END); |
305 | if (compat20) | ||
306 | packet_put_string(buffer_ptr(&buf), buffer_len(&buf)); | ||
307 | else | ||
308 | packet_put_raw(buffer_ptr(&buf), buffer_len(&buf)); | ||
309 | buffer_free(&buf); | ||
310 | return; | ||
244 | } | 311 | } |
245 | 312 | ||
246 | /* | 313 | /* |
@@ -254,14 +321,30 @@ tty_parse_modes(int fd, int *n_bytes_ptr) | |||
254 | int opcode, baud; | 321 | int opcode, baud; |
255 | int n_bytes = 0; | 322 | int n_bytes = 0; |
256 | int failure = 0; | 323 | int failure = 0; |
324 | u_int (*get_arg)(void); | ||
325 | int arg, arg_size; | ||
326 | |||
327 | if (compat20) { | ||
328 | *n_bytes_ptr = packet_get_int(); | ||
329 | debug2("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr); | ||
330 | if (*n_bytes_ptr == 0) | ||
331 | return; | ||
332 | get_arg = packet_get_int; | ||
333 | arg_size = 4; | ||
334 | } else { | ||
335 | get_arg = packet_get_char; | ||
336 | arg_size = 1; | ||
337 | } | ||
257 | 338 | ||
258 | /* | 339 | /* |
259 | * Get old attributes for the terminal. We will modify these | 340 | * Get old attributes for the terminal. We will modify these |
260 | * flags. I am hoping that if there are any machine-specific | 341 | * flags. I am hoping that if there are any machine-specific |
261 | * modes, they will initially have reasonable values. | 342 | * modes, they will initially have reasonable values. |
262 | */ | 343 | */ |
263 | if (tcgetattr(fd, &tio) < 0) | 344 | if (tcgetattr(fd, &tio) == -1) { |
345 | log("tcgetattr: %.100s", strerror(errno)); | ||
264 | failure = -1; | 346 | failure = -1; |
347 | } | ||
265 | 348 | ||
266 | for (;;) { | 349 | for (;;) { |
267 | n_bytes += 1; | 350 | n_bytes += 1; |
@@ -270,32 +353,40 @@ tty_parse_modes(int fd, int *n_bytes_ptr) | |||
270 | case TTY_OP_END: | 353 | case TTY_OP_END: |
271 | goto set; | 354 | goto set; |
272 | 355 | ||
273 | case TTY_OP_ISPEED: | 356 | /* XXX: future conflict possible */ |
357 | case TTY_OP_ISPEED_PROTO1: | ||
358 | case TTY_OP_ISPEED_PROTO2: | ||
274 | n_bytes += 4; | 359 | n_bytes += 4; |
275 | baud = packet_get_int(); | 360 | baud = packet_get_int(); |
276 | if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) < 0) | 361 | debug2("tty_parse_modes: ispeed %d", baud); |
362 | if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1) | ||
277 | error("cfsetispeed failed for %d", baud); | 363 | error("cfsetispeed failed for %d", baud); |
278 | break; | 364 | break; |
279 | 365 | ||
280 | case TTY_OP_OSPEED: | 366 | /* XXX: future conflict possible */ |
367 | case TTY_OP_OSPEED_PROTO1: | ||
368 | case TTY_OP_OSPEED_PROTO2: | ||
281 | n_bytes += 4; | 369 | n_bytes += 4; |
282 | baud = packet_get_int(); | 370 | baud = packet_get_int(); |
283 | if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) < 0) | 371 | debug2("tty_parse_modes: ospeed %d", baud); |
372 | if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1) | ||
284 | error("cfsetospeed failed for %d", baud); | 373 | error("cfsetospeed failed for %d", baud); |
285 | break; | 374 | break; |
286 | 375 | ||
287 | #define TTYCHAR(NAME, OP) \ | 376 | #define TTYCHAR(NAME, OP) \ |
288 | case OP: \ | 377 | case OP: \ |
289 | n_bytes += 1; \ | 378 | n_bytes += arg_size; \ |
290 | tio.c_cc[NAME] = packet_get_char(); \ | 379 | tio.c_cc[NAME] = get_arg(); \ |
380 | debug2("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \ | ||
291 | break; | 381 | break; |
292 | #define TTYMODE(NAME, FIELD, OP) \ | 382 | #define TTYMODE(NAME, FIELD, OP) \ |
293 | case OP: \ | 383 | case OP: \ |
294 | n_bytes += 1; \ | 384 | n_bytes += arg_size; \ |
295 | if (packet_get_char()) \ | 385 | if ((arg = get_arg())) \ |
296 | tio.FIELD |= NAME; \ | 386 | tio.FIELD |= NAME; \ |
297 | else \ | 387 | else \ |
298 | tio.FIELD &= ~NAME; \ | 388 | tio.FIELD &= ~NAME; \ |
389 | debug2("tty_parse_modes: %d %d", OP, arg); \ | ||
299 | break; | 390 | break; |
300 | 391 | ||
301 | #include "ttymodes.h" | 392 | #include "ttymodes.h" |
@@ -306,48 +397,66 @@ tty_parse_modes(int fd, int *n_bytes_ptr) | |||
306 | default: | 397 | default: |
307 | debug("Ignoring unsupported tty mode opcode %d (0x%x)", | 398 | debug("Ignoring unsupported tty mode opcode %d (0x%x)", |
308 | opcode, opcode); | 399 | opcode, opcode); |
309 | /* | 400 | if (!compat20) { |
310 | * Opcodes 0 to 127 are defined to have | 401 | /* |
311 | * a one-byte argument. | 402 | * SSH1: |
312 | */ | 403 | * Opcodes 1 to 127 are defined to have |
313 | if (opcode >= 0 && opcode < 128) { | 404 | * a one-byte argument. |
314 | n_bytes += 1; | 405 | * Opcodes 128 to 159 are defined to have |
315 | (void) packet_get_char(); | 406 | * an integer argument. |
316 | break; | 407 | */ |
408 | if (opcode > 0 && opcode < 128) { | ||
409 | n_bytes += 1; | ||
410 | (void) packet_get_char(); | ||
411 | break; | ||
412 | } else if (opcode >= 128 && opcode < 160) { | ||
413 | n_bytes += 4; | ||
414 | (void) packet_get_int(); | ||
415 | break; | ||
416 | } else { | ||
417 | /* | ||
418 | * It is a truly undefined opcode (160 to 255). | ||
419 | * We have no idea about its arguments. So we | ||
420 | * must stop parsing. Note that some data may be | ||
421 | * left in the packet; hopefully there is nothing | ||
422 | * more coming after the mode data. | ||
423 | */ | ||
424 | log("parse_tty_modes: unknown opcode %d", opcode); | ||
425 | packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY); | ||
426 | goto set; | ||
427 | } | ||
317 | } else { | 428 | } else { |
318 | /* | 429 | /* |
319 | * Opcodes 128 to 159 are defined to have | 430 | * SSH2: |
320 | * an integer argument. | 431 | * Opcodes 0 to 159 are defined to have |
432 | * a uint32 argument. | ||
433 | * Opcodes 160 to 255 are undefined and | ||
434 | * cause parsing to stop. | ||
321 | */ | 435 | */ |
322 | if (opcode >= 128 && opcode < 160) { | 436 | if (opcode > 0 && opcode < 160) { |
323 | n_bytes += 4; | 437 | n_bytes += 4; |
324 | (void) packet_get_int(); | 438 | (void) packet_get_int(); |
325 | break; | 439 | break; |
440 | } else { | ||
441 | log("parse_tty_modes: unknown opcode %d", opcode); | ||
442 | goto set; | ||
326 | } | 443 | } |
327 | } | 444 | } |
328 | /* | ||
329 | * It is a truly undefined opcode (160 to 255). | ||
330 | * We have no idea about its arguments. So we | ||
331 | * must stop parsing. Note that some data may be | ||
332 | * left in the packet; hopefully there is nothing | ||
333 | * more coming after the mode data. | ||
334 | */ | ||
335 | log("parse_tty_modes: unknown opcode %d", opcode); | ||
336 | packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY); | ||
337 | goto set; | ||
338 | } | 445 | } |
339 | } | 446 | } |
340 | 447 | ||
341 | set: | 448 | set: |
342 | if (*n_bytes_ptr != n_bytes) { | 449 | if (*n_bytes_ptr != n_bytes) { |
343 | *n_bytes_ptr = n_bytes; | 450 | *n_bytes_ptr = n_bytes; |
451 | log("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", | ||
452 | *n_bytes_ptr, n_bytes); | ||
344 | return; /* Don't process bytes passed */ | 453 | return; /* Don't process bytes passed */ |
345 | } | 454 | } |
346 | if (failure == -1) | 455 | if (failure == -1) |
347 | return; /* Packet parsed ok but tty stuff failed */ | 456 | return; /* Packet parsed ok but tty stuff failed */ |
348 | 457 | ||
349 | /* Set the new modes for the terminal. */ | 458 | /* Set the new modes for the terminal. */ |
350 | if (tcsetattr(fd, TCSANOW, &tio) < 0) | 459 | if (tcsetattr(fd, TCSANOW, &tio) == -1) |
351 | log("Setting tty modes failed: %.100s", strerror(errno)); | 460 | log("Setting tty modes failed: %.100s", strerror(errno)); |
352 | return; | 461 | return; |
353 | } | 462 | } |
diff --git a/ttymodes.h b/ttymodes.h index 860fd0a9c..ad980e98c 100644 --- a/ttymodes.h +++ b/ttymodes.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* RCSID("$OpenBSD: ttymodes.h,v 1.11 2001/04/14 16:33:20 stevesk Exp $"); */ | ||
1 | /* | 2 | /* |
2 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
3 | * SGTTY stuff contributed by Janne Snabb <snabb@niksula.hut.fi> | ||
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | * All rights reserved | 5 | * All rights reserved |
6 | * | 6 | * |
@@ -11,14 +11,47 @@ | |||
11 | * called by a name other than "ssh" or "Secure Shell". | 11 | * called by a name other than "ssh" or "Secure Shell". |
12 | */ | 12 | */ |
13 | 13 | ||
14 | /* RCSID("$OpenBSD: ttymodes.h,v 1.10 2001/03/10 15:02:05 stevesk Exp $"); */ | 14 | /* |
15 | * SSH2 tty modes support by Kevin Steves. | ||
16 | * Copyright (c) 2001 Kevin Steves. All rights reserved. | ||
17 | * | ||
18 | * Redistribution and use in source and binary forms, with or without | ||
19 | * modification, are permitted provided that the following conditions | ||
20 | * are met: | ||
21 | * 1. Redistributions of source code must retain the above copyright | ||
22 | * notice, this list of conditions and the following disclaimer. | ||
23 | * 2. Redistributions in binary form must reproduce the above copyright | ||
24 | * notice, this list of conditions and the following disclaimer in the | ||
25 | * documentation and/or other materials provided with the distribution. | ||
26 | * | ||
27 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
28 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
29 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
30 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
31 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
32 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
36 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
37 | */ | ||
15 | 38 | ||
16 | /* The tty mode description is a stream of bytes. The stream consists of | 39 | /* |
40 | * SSH1: | ||
41 | * The tty mode description is a stream of bytes. The stream consists of | ||
17 | * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). | 42 | * opcode-arguments pairs. It is terminated by opcode TTY_OP_END (0). |
18 | * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer | 43 | * Opcodes 1-127 have one-byte arguments. Opcodes 128-159 have integer |
19 | * arguments. Opcodes 160-255 are not yet defined, and cause parsing to | 44 | * arguments. Opcodes 160-255 are not yet defined, and cause parsing to |
20 | * stop (they should only be used after any other data). | 45 | * stop (they should only be used after any other data). |
21 | * | 46 | * |
47 | * SSH2: | ||
48 | * Differences between SSH1 and SSH2 terminal mode encoding include: | ||
49 | * 1. Encoded terminal modes are represented as a string, and a stream | ||
50 | * of bytes within that string. | ||
51 | * 2. Opcode arguments are uint32 (1-159); 160-255 remain undefined. | ||
52 | * 3. The values for TTY_OP_ISPEED and TTY_OP_OSPEED are different; | ||
53 | * 128 and 129 vs. 192 and 193 respectively. | ||
54 | * | ||
22 | * The client puts in the stream any modes it knows about, and the | 55 | * The client puts in the stream any modes it knows about, and the |
23 | * server ignores any modes it does not know about. This allows some degree | 56 | * server ignores any modes it does not know about. This allows some degree |
24 | * of machine-independence, at least between systems that use a posix-like | 57 | * of machine-independence, at least between systems that use a posix-like |