diff options
-rw-r--r-- | clientloop.c | 4 | ||||
-rw-r--r-- | packet.h | 6 | ||||
-rw-r--r-- | session.c | 6 | ||||
-rw-r--r-- | ttymodes.c | 129 |
4 files changed, 81 insertions, 64 deletions
diff --git a/clientloop.c b/clientloop.c index 8da5d914e..7262a856f 100644 --- a/clientloop.c +++ b/clientloop.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: clientloop.c,v 1.315 2018/07/09 21:03:30 markus Exp $ */ | 1 | /* $OpenBSD: clientloop.c,v 1.316 2018/07/09 21:20:26 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.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 |
@@ -2210,7 +2210,7 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem, | |||
2210 | packet_put_int((u_int)ws.ws_ypixel); | 2210 | packet_put_int((u_int)ws.ws_ypixel); |
2211 | if (tiop == NULL) | 2211 | if (tiop == NULL) |
2212 | tiop = get_saved_tio(); | 2212 | tiop = get_saved_tio(); |
2213 | tty_make_modes(-1, tiop); | 2213 | ssh_tty_make_modes(ssh, -1, tiop); |
2214 | packet_send(); | 2214 | packet_send(); |
2215 | /* XXX wait for reply */ | 2215 | /* XXX wait for reply */ |
2216 | c->client_tty = 1; | 2216 | c->client_tty = 1; |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.h,v 1.85 2018/07/06 09:03:02 sf Exp $ */ | 1 | /* $OpenBSD: packet.h,v 1.86 2018/07/09 21:20:26 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -147,8 +147,8 @@ int ssh_packet_not_very_much_data_to_write(struct ssh *); | |||
147 | int ssh_packet_connection_is_on_socket(struct ssh *); | 147 | int ssh_packet_connection_is_on_socket(struct ssh *); |
148 | int ssh_packet_remaining(struct ssh *); | 148 | int ssh_packet_remaining(struct ssh *); |
149 | 149 | ||
150 | void tty_make_modes(int, struct termios *); | 150 | void ssh_tty_make_modes(struct ssh *, int, struct termios *); |
151 | void tty_parse_modes(int, int *); | 151 | void ssh_tty_parse_modes(struct ssh *, int); |
152 | 152 | ||
153 | void ssh_packet_set_alive_timeouts(struct ssh *, int); | 153 | void ssh_packet_set_alive_timeouts(struct ssh *, int); |
154 | int ssh_packet_inc_alive_timeouts(struct ssh *); | 154 | int ssh_packet_inc_alive_timeouts(struct ssh *); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: session.c,v 1.301 2018/07/03 10:59:35 djm Exp $ */ | 1 | /* $OpenBSD: session.c,v 1.302 2018/07/09 21:20:26 markus Exp $ */ |
2 | /* | 2 | /* |
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 |
@@ -1912,7 +1912,6 @@ static int | |||
1912 | session_pty_req(struct ssh *ssh, Session *s) | 1912 | session_pty_req(struct ssh *ssh, Session *s) |
1913 | { | 1913 | { |
1914 | u_int len; | 1914 | u_int len; |
1915 | int n_bytes; | ||
1916 | 1915 | ||
1917 | if (!auth_opts->permit_pty_flag || !options.permit_tty) { | 1916 | if (!auth_opts->permit_pty_flag || !options.permit_tty) { |
1918 | debug("Allocating a pty not permitted for this connection."); | 1917 | debug("Allocating a pty not permitted for this connection."); |
@@ -1947,8 +1946,7 @@ session_pty_req(struct ssh *ssh, Session *s) | |||
1947 | } | 1946 | } |
1948 | debug("session_pty_req: session %d alloc %s", s->self, s->tty); | 1947 | debug("session_pty_req: session %d alloc %s", s->self, s->tty); |
1949 | 1948 | ||
1950 | n_bytes = packet_remaining(); | 1949 | ssh_tty_parse_modes(ssh, s->ttyfd); |
1951 | tty_parse_modes(s->ttyfd, &n_bytes); | ||
1952 | 1950 | ||
1953 | if (!use_privsep) | 1951 | if (!use_privsep) |
1954 | pty_setowner(s->pw, s->tty); | 1952 | pty_setowner(s->pw, s->tty); |
diff --git a/ttymodes.c b/ttymodes.c index f9fdb92de..f0c2a5d37 100644 --- a/ttymodes.c +++ b/ttymodes.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ttymodes.c,v 1.33 2018/02/16 04:43:11 dtucker Exp $ */ | 1 | /* $OpenBSD: ttymodes.c,v 1.34 2018/07/09 21:20:26 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.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 |
@@ -55,8 +55,8 @@ | |||
55 | #include "packet.h" | 55 | #include "packet.h" |
56 | #include "log.h" | 56 | #include "log.h" |
57 | #include "compat.h" | 57 | #include "compat.h" |
58 | #include "buffer.h" | 58 | #include "sshbuf.h" |
59 | #include "compat.h" | 59 | #include "ssherr.h" |
60 | 60 | ||
61 | #define TTY_OP_END 0 | 61 | #define TTY_OP_END 0 |
62 | /* | 62 | /* |
@@ -276,17 +276,18 @@ special_char_decode(u_int c) | |||
276 | * being constructed. | 276 | * being constructed. |
277 | */ | 277 | */ |
278 | void | 278 | void |
279 | tty_make_modes(int fd, struct termios *tiop) | 279 | ssh_tty_make_modes(struct ssh *ssh, int fd, struct termios *tiop) |
280 | { | 280 | { |
281 | struct termios tio; | 281 | struct termios tio; |
282 | int baud; | 282 | struct sshbuf *buf; |
283 | Buffer buf; | 283 | int r, ibaud, obaud; |
284 | 284 | ||
285 | buffer_init(&buf); | 285 | if ((buf = sshbuf_new()) == NULL) |
286 | fatal("%s: sshbuf_new failed", __func__); | ||
286 | 287 | ||
287 | if (tiop == NULL) { | 288 | if (tiop == NULL) { |
288 | if (fd == -1) { | 289 | if (fd == -1) { |
289 | debug("tty_make_modes: no fd or tio"); | 290 | debug("%s: no fd or tio", __func__); |
290 | goto end; | 291 | goto end; |
291 | } | 292 | } |
292 | if (tcgetattr(fd, &tio) == -1) { | 293 | if (tcgetattr(fd, &tio) == -1) { |
@@ -297,27 +298,29 @@ tty_make_modes(int fd, struct termios *tiop) | |||
297 | tio = *tiop; | 298 | tio = *tiop; |
298 | 299 | ||
299 | /* Store input and output baud rates. */ | 300 | /* Store input and output baud rates. */ |
300 | baud = speed_to_baud(cfgetospeed(&tio)); | 301 | obaud = speed_to_baud(cfgetospeed(&tio)); |
301 | buffer_put_char(&buf, TTY_OP_OSPEED); | 302 | ibaud = speed_to_baud(cfgetispeed(&tio)); |
302 | buffer_put_int(&buf, baud); | 303 | if ((r = sshbuf_put_u8(buf, TTY_OP_OSPEED)) != 0 || |
303 | baud = speed_to_baud(cfgetispeed(&tio)); | 304 | (r = sshbuf_put_u32(buf, obaud)) != 0 || |
304 | buffer_put_char(&buf, TTY_OP_ISPEED); | 305 | (r = sshbuf_put_u8(buf, TTY_OP_ISPEED)) != 0 || |
305 | buffer_put_int(&buf, baud); | 306 | (r = sshbuf_put_u32(buf, ibaud)) != 0) |
307 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
306 | 308 | ||
307 | /* Store values of mode flags. */ | 309 | /* Store values of mode flags. */ |
308 | #define TTYCHAR(NAME, OP) \ | 310 | #define TTYCHAR(NAME, OP) \ |
309 | buffer_put_char(&buf, OP); \ | 311 | if ((r = sshbuf_put_u8(buf, OP)) != 0 || \ |
310 | buffer_put_int(&buf, special_char_encode(tio.c_cc[NAME])); | 312 | (r = sshbuf_put_u32(buf, \ |
313 | special_char_encode(tio.c_cc[NAME]))) != 0) \ | ||
314 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); \ | ||
311 | 315 | ||
312 | #define SSH_TTYMODE_IUTF8 42 /* for SSH_BUG_UTF8TTYMODE */ | 316 | #define SSH_TTYMODE_IUTF8 42 /* for SSH_BUG_UTF8TTYMODE */ |
313 | 317 | ||
314 | #define TTYMODE(NAME, FIELD, OP) \ | 318 | #define TTYMODE(NAME, FIELD, OP) \ |
315 | if (OP == SSH_TTYMODE_IUTF8 && (datafellows & SSH_BUG_UTF8TTYMODE)) { \ | 319 | if (OP == SSH_TTYMODE_IUTF8 && (datafellows & SSH_BUG_UTF8TTYMODE)) { \ |
316 | debug3("%s: SSH_BUG_UTF8TTYMODE", __func__); \ | 320 | debug3("%s: SSH_BUG_UTF8TTYMODE", __func__); \ |
317 | } else { \ | 321 | } else if ((r = sshbuf_put_u8(buf, OP)) != 0 || \ |
318 | buffer_put_char(&buf, OP); \ | 322 | (r = sshbuf_put_u32(buf, ((tio.FIELD & NAME) != 0))) != 0) \ |
319 | buffer_put_int(&buf, ((tio.FIELD & NAME) != 0)); \ | 323 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); \ |
320 | } | ||
321 | 324 | ||
322 | #include "ttymodes.h" | 325 | #include "ttymodes.h" |
323 | 326 | ||
@@ -326,9 +329,10 @@ tty_make_modes(int fd, struct termios *tiop) | |||
326 | 329 | ||
327 | end: | 330 | end: |
328 | /* Mark end of mode data. */ | 331 | /* Mark end of mode data. */ |
329 | buffer_put_char(&buf, TTY_OP_END); | 332 | if ((r = sshbuf_put_u8(buf, TTY_OP_END)) != 0 || |
330 | packet_put_string(buffer_ptr(&buf), buffer_len(&buf)); | 333 | (r = sshpkt_put_stringb(ssh, buf)) != 0) |
331 | buffer_free(&buf); | 334 | fatal("%s: packet error: %s", __func__, ssh_err(r)); |
335 | sshbuf_free(buf); | ||
332 | } | 336 | } |
333 | 337 | ||
334 | /* | 338 | /* |
@@ -336,16 +340,24 @@ end: | |||
336 | * manner from a packet being read. | 340 | * manner from a packet being read. |
337 | */ | 341 | */ |
338 | void | 342 | void |
339 | tty_parse_modes(int fd, int *n_bytes_ptr) | 343 | ssh_tty_parse_modes(struct ssh *ssh, int fd) |
340 | { | 344 | { |
341 | struct termios tio; | 345 | struct termios tio; |
342 | int opcode, baud; | 346 | struct sshbuf *buf; |
343 | int n_bytes = 0; | 347 | const u_char *data; |
344 | int failure = 0; | 348 | u_char opcode; |
345 | 349 | u_int baud, u; | |
346 | *n_bytes_ptr = packet_get_int(); | 350 | int r, failure = 0; |
347 | if (*n_bytes_ptr == 0) | 351 | size_t len; |
352 | |||
353 | if ((r = sshpkt_get_string_direct(ssh, &data, &len)) != 0) | ||
354 | fatal("%s: packet error: %s", __func__, ssh_err(r)); | ||
355 | if (len == 0) | ||
356 | return; | ||
357 | if ((buf = sshbuf_from(data, len)) == NULL) { | ||
358 | error("%s: sshbuf_from failed", __func__); | ||
348 | return; | 359 | return; |
360 | } | ||
349 | 361 | ||
350 | /* | 362 | /* |
351 | * Get old attributes for the terminal. We will modify these | 363 | * Get old attributes for the terminal. We will modify these |
@@ -357,42 +369,48 @@ tty_parse_modes(int fd, int *n_bytes_ptr) | |||
357 | failure = -1; | 369 | failure = -1; |
358 | } | 370 | } |
359 | 371 | ||
360 | for (;;) { | 372 | while (sshbuf_len(buf) > 0) { |
361 | n_bytes += 1; | 373 | if ((r = sshbuf_get_u8(buf, &opcode)) != 0) |
362 | opcode = packet_get_char(); | 374 | fatal("%s: packet error: %s", __func__, ssh_err(r)); |
363 | switch (opcode) { | 375 | switch (opcode) { |
364 | case TTY_OP_END: | 376 | case TTY_OP_END: |
365 | goto set; | 377 | goto set; |
366 | 378 | ||
367 | case TTY_OP_ISPEED: | 379 | case TTY_OP_ISPEED: |
368 | n_bytes += 4; | 380 | if ((r = sshbuf_get_u32(buf, &baud)) != 0) |
369 | baud = packet_get_int(); | 381 | fatal("%s: packet error: %s", |
382 | __func__, ssh_err(r)); | ||
370 | if (failure != -1 && | 383 | if (failure != -1 && |
371 | cfsetispeed(&tio, baud_to_speed(baud)) == -1) | 384 | cfsetispeed(&tio, baud_to_speed(baud)) == -1) |
372 | error("cfsetispeed failed for %d", baud); | 385 | error("cfsetispeed failed for %d", baud); |
373 | break; | 386 | break; |
374 | 387 | ||
375 | case TTY_OP_OSPEED: | 388 | case TTY_OP_OSPEED: |
376 | n_bytes += 4; | 389 | if ((r = sshbuf_get_u32(buf, &baud)) != 0) |
377 | baud = packet_get_int(); | 390 | fatal("%s: packet error: %s", |
391 | __func__, ssh_err(r)); | ||
378 | if (failure != -1 && | 392 | if (failure != -1 && |
379 | cfsetospeed(&tio, baud_to_speed(baud)) == -1) | 393 | cfsetospeed(&tio, baud_to_speed(baud)) == -1) |
380 | error("cfsetospeed failed for %d", baud); | 394 | error("cfsetospeed failed for %d", baud); |
381 | break; | 395 | break; |
382 | 396 | ||
383 | #define TTYCHAR(NAME, OP) \ | 397 | #define TTYCHAR(NAME, OP) \ |
384 | case OP: \ | 398 | case OP: \ |
385 | n_bytes += 4; \ | 399 | if ((r = sshbuf_get_u32(buf, &u)) != 0) \ |
386 | tio.c_cc[NAME] = special_char_decode(packet_get_int()); \ | 400 | fatal("%s: packet error: %s", __func__, \ |
387 | break; | 401 | ssh_err(r)); \ |
402 | tio.c_cc[NAME] = special_char_decode(u); \ | ||
403 | break; | ||
388 | #define TTYMODE(NAME, FIELD, OP) \ | 404 | #define TTYMODE(NAME, FIELD, OP) \ |
389 | case OP: \ | 405 | case OP: \ |
390 | n_bytes += 4; \ | 406 | if ((r = sshbuf_get_u32(buf, &u)) != 0) \ |
391 | if (packet_get_int()) \ | 407 | fatal("%s: packet error: %s", __func__, \ |
392 | tio.FIELD |= NAME; \ | 408 | ssh_err(r)); \ |
393 | else \ | 409 | if (u) \ |
394 | tio.FIELD &= ~NAME; \ | 410 | tio.FIELD |= NAME; \ |
395 | break; | 411 | else \ |
412 | tio.FIELD &= ~NAME; \ | ||
413 | break; | ||
396 | 414 | ||
397 | #include "ttymodes.h" | 415 | #include "ttymodes.h" |
398 | 416 | ||
@@ -410,11 +428,12 @@ tty_parse_modes(int fd, int *n_bytes_ptr) | |||
410 | * to stop. | 428 | * to stop. |
411 | */ | 429 | */ |
412 | if (opcode > 0 && opcode < 160) { | 430 | if (opcode > 0 && opcode < 160) { |
413 | n_bytes += 4; | 431 | if ((r = sshbuf_get_u32(buf, NULL)) != 0) |
414 | (void) packet_get_int(); | 432 | fatal("%s: packet error: %s", __func__, |
433 | ssh_err(r)); | ||
415 | break; | 434 | break; |
416 | } else { | 435 | } else { |
417 | logit("parse_tty_modes: unknown opcode %d", | 436 | logit("%s: unknown opcode %d", __func__, |
418 | opcode); | 437 | opcode); |
419 | goto set; | 438 | goto set; |
420 | } | 439 | } |
@@ -422,10 +441,10 @@ tty_parse_modes(int fd, int *n_bytes_ptr) | |||
422 | } | 441 | } |
423 | 442 | ||
424 | set: | 443 | set: |
425 | if (*n_bytes_ptr != n_bytes) { | 444 | len = sshbuf_len(buf); |
426 | *n_bytes_ptr = n_bytes; | 445 | sshbuf_free(buf); |
427 | logit("parse_tty_modes: n_bytes_ptr != n_bytes: %d %d", | 446 | if (len > 0) { |
428 | *n_bytes_ptr, n_bytes); | 447 | logit("%s: %zu bytes left", __func__, len); |
429 | return; /* Don't process bytes passed */ | 448 | return; /* Don't process bytes passed */ |
430 | } | 449 | } |
431 | if (failure == -1) | 450 | if (failure == -1) |