diff options
author | markus@openbsd.org <markus@openbsd.org> | 2018-07-09 21:20:26 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2018-07-10 15:19:12 +1000 |
commit | 89dd615b8b531979be63f05f9d5624367c9b28e6 (patch) | |
tree | d807c8d1c948fdf71794cd410b9518e9b6499d69 /ttymodes.c | |
parent | f4608a7065480516ab46214f554e5f853fb7870f (diff) |
upstream: ttymodes: switch to sshbuf API; ok djm@
OpenBSD-Commit-ID: 5df340c5965e822c9da21e19579d08dea3cbe429
Diffstat (limited to 'ttymodes.c')
-rw-r--r-- | ttymodes.c | 129 |
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 | */ |
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) |