summaryrefslogtreecommitdiff
path: root/ttymodes.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2018-07-09 21:20:26 +0000
committerDamien Miller <djm@mindrot.org>2018-07-10 15:19:12 +1000
commit89dd615b8b531979be63f05f9d5624367c9b28e6 (patch)
treed807c8d1c948fdf71794cd410b9518e9b6499d69 /ttymodes.c
parentf4608a7065480516ab46214f554e5f853fb7870f (diff)
upstream: ttymodes: switch to sshbuf API; ok djm@
OpenBSD-Commit-ID: 5df340c5965e822c9da21e19579d08dea3cbe429
Diffstat (limited to 'ttymodes.c')
-rw-r--r--ttymodes.c129
1 files changed, 74 insertions, 55 deletions
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)