summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clientloop.c4
-rw-r--r--packet.h6
-rw-r--r--session.c6
-rw-r--r--ttymodes.c129
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;
diff --git a/packet.h b/packet.h
index bf9aebdb2..170203cab 100644
--- a/packet.h
+++ b/packet.h
@@ -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 *);
147int ssh_packet_connection_is_on_socket(struct ssh *); 147int ssh_packet_connection_is_on_socket(struct ssh *);
148int ssh_packet_remaining(struct ssh *); 148int ssh_packet_remaining(struct ssh *);
149 149
150void tty_make_modes(int, struct termios *); 150void ssh_tty_make_modes(struct ssh *, int, struct termios *);
151void tty_parse_modes(int, int *); 151void ssh_tty_parse_modes(struct ssh *, int);
152 152
153void ssh_packet_set_alive_timeouts(struct ssh *, int); 153void ssh_packet_set_alive_timeouts(struct ssh *, int);
154int ssh_packet_inc_alive_timeouts(struct ssh *); 154int ssh_packet_inc_alive_timeouts(struct ssh *);
diff --git a/session.c b/session.c
index 18a106f6b..882359025 100644
--- a/session.c
+++ b/session.c
@@ -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
1912session_pty_req(struct ssh *ssh, Session *s) 1912session_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 */
278void 278void
279tty_make_modes(int fd, struct termios *tiop) 279ssh_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
327end: 330end:
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 */
338void 342void
339tty_parse_modes(int fd, int *n_bytes_ptr) 343ssh_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
424set: 443set:
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)