summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2019-06-05 06:41:44 +0100
committerColin Watson <cjwatson@debian.org>2019-06-05 06:41:44 +0100
commit102062f825fb26a74295a1c089c00c4c4c76b68a (patch)
tree3db66bc8c8483cce66516dff36f6ef56065143d9 /clientloop.c
parent3d246f10429fc9a37b98eabef94fe8dc7c61002b (diff)
parentfd0fa130ecf06d7d092932adcd5d77f1549bfc8d (diff)
Import openssh_8.0p1.orig.tar.gz
Diffstat (limited to 'clientloop.c')
-rw-r--r--clientloop.c353
1 files changed, 201 insertions, 152 deletions
diff --git a/clientloop.c b/clientloop.c
index 8d312cdaa..086c0dfe8 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.318 2018/09/21 12:46:22 djm Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.322 2019/03/29 11:31:40 djm 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
@@ -160,7 +160,7 @@ static int need_rekeying; /* Set to non-zero if rekeying is requested. */
160static int session_closed; /* In SSH2: login session closed. */ 160static int session_closed; /* In SSH2: login session closed. */
161static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ 161static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
162 162
163static void client_init_dispatch(void); 163static void client_init_dispatch(struct ssh *ssh);
164int session_ident = -1; 164int session_ident = -1;
165 165
166/* Track escape per proto2 channel */ 166/* Track escape per proto2 channel */
@@ -364,7 +364,7 @@ client_x11_get_proto(struct ssh *ssh, const char *display,
364 SSH_X11_PROTO, x11_timeout_real, 364 SSH_X11_PROTO, x11_timeout_real,
365 _PATH_DEVNULL); 365 _PATH_DEVNULL);
366 } 366 }
367 debug2("%s: %s", __func__, cmd); 367 debug2("%s: xauth command: %s", __func__, cmd);
368 368
369 if (timeout != 0 && x11_refuse_time == 0) { 369 if (timeout != 0 && x11_refuse_time == 0) {
370 now = monotime() + 1; 370 now = monotime() + 1;
@@ -475,21 +475,24 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
475 free(gc); 475 free(gc);
476 } 476 }
477 477
478 packet_set_alive_timeouts(0); 478 ssh_packet_set_alive_timeouts(ssh, 0);
479 return 0; 479 return 0;
480} 480}
481 481
482static void 482static void
483server_alive_check(void) 483server_alive_check(struct ssh *ssh)
484{ 484{
485 if (packet_inc_alive_timeouts() > options.server_alive_count_max) { 485 int r;
486
487 if (ssh_packet_inc_alive_timeouts(ssh) > options.server_alive_count_max) {
486 logit("Timeout, server %s not responding.", host); 488 logit("Timeout, server %s not responding.", host);
487 cleanup_exit(255); 489 cleanup_exit(255);
488 } 490 }
489 packet_start(SSH2_MSG_GLOBAL_REQUEST); 491 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
490 packet_put_cstring("keepalive@openssh.com"); 492 (r = sshpkt_put_cstring(ssh, "keepalive@openssh.com")) != 0 ||
491 packet_put_char(1); /* boolean: want reply */ 493 (r = sshpkt_put_u8(ssh, 1)) != 0 || /* boolean: want reply */
492 packet_send(); 494 (r = sshpkt_send(ssh)) != 0)
495 fatal("%s: send packet: %s", __func__, ssh_err(r));
493 /* Insert an empty placeholder to maintain ordering */ 496 /* Insert an empty placeholder to maintain ordering */
494 client_register_global_confirm(NULL, NULL); 497 client_register_global_confirm(NULL, NULL);
495} 498}
@@ -509,12 +512,12 @@ client_wait_until_can_do_something(struct ssh *ssh,
509 int r, ret; 512 int r, ret;
510 513
511 /* Add any selections by the channel mechanism. */ 514 /* Add any selections by the channel mechanism. */
512 channel_prepare_select(active_state, readsetp, writesetp, maxfdp, 515 channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
513 nallocp, &minwait_secs); 516 nallocp, &minwait_secs);
514 517
515 /* channel_prepare_select could have closed the last channel */ 518 /* channel_prepare_select could have closed the last channel */
516 if (session_closed && !channel_still_open(ssh) && 519 if (session_closed && !channel_still_open(ssh) &&
517 !packet_have_data_to_write()) { 520 !ssh_packet_have_data_to_write(ssh)) {
518 /* clear mask since we did not call select() */ 521 /* clear mask since we did not call select() */
519 memset(*readsetp, 0, *nallocp); 522 memset(*readsetp, 0, *nallocp);
520 memset(*writesetp, 0, *nallocp); 523 memset(*writesetp, 0, *nallocp);
@@ -524,7 +527,7 @@ client_wait_until_can_do_something(struct ssh *ssh,
524 FD_SET(connection_in, *readsetp); 527 FD_SET(connection_in, *readsetp);
525 528
526 /* Select server connection if have data to write to the server. */ 529 /* Select server connection if have data to write to the server. */
527 if (packet_have_data_to_write()) 530 if (ssh_packet_have_data_to_write(ssh))
528 FD_SET(connection_out, *writesetp); 531 FD_SET(connection_out, *writesetp);
529 532
530 /* 533 /*
@@ -539,7 +542,8 @@ client_wait_until_can_do_something(struct ssh *ssh,
539 server_alive_time = now + options.server_alive_interval; 542 server_alive_time = now + options.server_alive_interval;
540 } 543 }
541 if (options.rekey_interval > 0 && !rekeying) 544 if (options.rekey_interval > 0 && !rekeying)
542 timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); 545 timeout_secs = MINIMUM(timeout_secs,
546 ssh_packet_get_rekey_timeout(ssh));
543 set_control_persist_exit_time(ssh); 547 set_control_persist_exit_time(ssh);
544 if (control_persist_exit_time > 0) { 548 if (control_persist_exit_time > 0) {
545 timeout_secs = MINIMUM(timeout_secs, 549 timeout_secs = MINIMUM(timeout_secs,
@@ -580,7 +584,7 @@ client_wait_until_can_do_something(struct ssh *ssh,
580 * Keepalive we check here, rekeying is checked in clientloop. 584 * Keepalive we check here, rekeying is checked in clientloop.
581 */ 585 */
582 if (server_alive_time != 0 && server_alive_time <= monotime()) 586 if (server_alive_time != 0 && server_alive_time <= monotime())
583 server_alive_check(); 587 server_alive_check(ssh);
584 } 588 }
585 589
586} 590}
@@ -612,7 +616,7 @@ client_suspend_self(struct sshbuf *bin, struct sshbuf *bout, struct sshbuf *berr
612} 616}
613 617
614static void 618static void
615client_process_net_input(fd_set *readset) 619client_process_net_input(struct ssh *ssh, fd_set *readset)
616{ 620{
617 char buf[SSH_IOBUFSZ]; 621 char buf[SSH_IOBUFSZ];
618 int r, len; 622 int r, len;
@@ -658,7 +662,7 @@ client_process_net_input(fd_set *readset)
658 quit_pending = 1; 662 quit_pending = 1;
659 return; 663 return;
660 } 664 }
661 packet_process_incoming(buf, len); 665 ssh_packet_process_incoming(ssh, buf, len);
662 } 666 }
663} 667}
664 668
@@ -1031,7 +1035,7 @@ process_escapes(struct ssh *ssh, Channel *c,
1031 channel_request_start(ssh, c->self, "break", 0); 1035 channel_request_start(ssh, c->self, "break", 0);
1032 if ((r = sshpkt_put_u32(ssh, 1000)) != 0 || 1036 if ((r = sshpkt_put_u32(ssh, 1000)) != 0 ||
1033 (r = sshpkt_send(ssh)) != 0) 1037 (r = sshpkt_send(ssh)) != 0)
1034 fatal("%s: %s", __func__, 1038 fatal("%s: send packet: %s", __func__,
1035 ssh_err(r)); 1039 ssh_err(r));
1036 continue; 1040 continue;
1037 1041
@@ -1182,9 +1186,9 @@ process_escapes(struct ssh *ssh, Channel *c,
1182 */ 1186 */
1183 1187
1184static void 1188static void
1185client_process_buffered_input_packets(void) 1189client_process_buffered_input_packets(struct ssh *ssh)
1186{ 1190{
1187 ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, &quit_pending); 1191 ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, &quit_pending);
1188} 1192}
1189 1193
1190/* scan buf[] for '~' before sending data to the peer */ 1194/* scan buf[] for '~' before sending data to the peer */
@@ -1281,8 +1285,8 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1281 /* Initialize variables. */ 1285 /* Initialize variables. */
1282 last_was_cr = 1; 1286 last_was_cr = 1;
1283 exit_status = -1; 1287 exit_status = -1;
1284 connection_in = packet_get_connection_in(); 1288 connection_in = ssh_packet_get_connection_in(ssh);
1285 connection_out = packet_get_connection_out(); 1289 connection_out = ssh_packet_get_connection_out(ssh);
1286 max_fd = MAXIMUM(connection_in, connection_out); 1290 max_fd = MAXIMUM(connection_in, connection_out);
1287 1291
1288 quit_pending = 0; 1292 quit_pending = 0;
@@ -1291,7 +1295,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1291 if ((stderr_buffer = sshbuf_new()) == NULL) 1295 if ((stderr_buffer = sshbuf_new()) == NULL)
1292 fatal("%s: sshbuf_new failed", __func__); 1296 fatal("%s: sshbuf_new failed", __func__);
1293 1297
1294 client_init_dispatch(); 1298 client_init_dispatch(ssh);
1295 1299
1296 /* 1300 /*
1297 * Set signal handlers, (e.g. to restore non-blocking mode) 1301 * Set signal handlers, (e.g. to restore non-blocking mode)
@@ -1327,7 +1331,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1327 while (!quit_pending) { 1331 while (!quit_pending) {
1328 1332
1329 /* Process buffered packets sent by the server. */ 1333 /* Process buffered packets sent by the server. */
1330 client_process_buffered_input_packets(); 1334 client_process_buffered_input_packets(ssh);
1331 1335
1332 if (session_closed && !channel_still_open(ssh)) 1336 if (session_closed && !channel_still_open(ssh))
1333 break; 1337 break;
@@ -1346,7 +1350,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1346 * Make packets from buffered channel data, and 1350 * Make packets from buffered channel data, and
1347 * enqueue them for sending to the server. 1351 * enqueue them for sending to the server.
1348 */ 1352 */
1349 if (packet_not_very_much_data_to_write()) 1353 if (ssh_packet_not_very_much_data_to_write(ssh))
1350 channel_output_poll(ssh); 1354 channel_output_poll(ssh);
1351 1355
1352 /* 1356 /*
@@ -1374,7 +1378,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1374 channel_after_select(ssh, readset, writeset); 1378 channel_after_select(ssh, readset, writeset);
1375 1379
1376 /* Buffer input from the connection. */ 1380 /* Buffer input from the connection. */
1377 client_process_net_input(readset); 1381 client_process_net_input(ssh, readset);
1378 1382
1379 if (quit_pending) 1383 if (quit_pending)
1380 break; 1384 break;
@@ -1384,7 +1388,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1384 * sender. 1388 * sender.
1385 */ 1389 */
1386 if (FD_ISSET(connection_out, writeset)) 1390 if (FD_ISSET(connection_out, writeset))
1387 packet_write_poll(); 1391 ssh_packet_write_poll(ssh);
1388 1392
1389 /* 1393 /*
1390 * If we are a backgrounded control master, and the 1394 * If we are a backgrounded control master, and the
@@ -1406,12 +1410,13 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1406 /* Stop watching for window change. */ 1410 /* Stop watching for window change. */
1407 signal(SIGWINCH, SIG_DFL); 1411 signal(SIGWINCH, SIG_DFL);
1408 1412
1409 packet_start(SSH2_MSG_DISCONNECT); 1413 if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
1410 packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); 1414 (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_BY_APPLICATION)) != 0 ||
1411 packet_put_cstring("disconnected by user"); 1415 (r = sshpkt_put_cstring(ssh, "disconnected by user")) != 0 ||
1412 packet_put_cstring(""); /* language tag */ 1416 (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language tag */
1413 packet_send(); 1417 (r = sshpkt_send(ssh)) != 0 ||
1414 packet_write_wait(); 1418 (r = ssh_packet_write_wait(ssh)) != 0)
1419 fatal("%s: send disconnect: %s", __func__, ssh_err(r));
1415 1420
1416 channel_free_all(ssh); 1421 channel_free_all(ssh);
1417 1422
@@ -1468,7 +1473,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1468 1473
1469 /* Report bytes transferred, and transfer rates. */ 1474 /* Report bytes transferred, and transfer rates. */
1470 total_time = monotime_double() - start_time; 1475 total_time = monotime_double() - start_time;
1471 packet_get_bytes(&ibytes, &obytes); 1476 ssh_packet_get_bytes(ssh, &ibytes, &obytes);
1472 verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", 1477 verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
1473 (unsigned long long)obytes, (unsigned long long)ibytes, total_time); 1478 (unsigned long long)obytes, (unsigned long long)ibytes, total_time);
1474 if (total_time > 0) 1479 if (total_time > 0)
@@ -1488,21 +1493,29 @@ client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
1488 Channel *c = NULL; 1493 Channel *c = NULL;
1489 struct sshbuf *b = NULL; 1494 struct sshbuf *b = NULL;
1490 char *listen_address, *originator_address; 1495 char *listen_address, *originator_address;
1491 u_short listen_port, originator_port; 1496 u_int listen_port, originator_port;
1492 int r; 1497 int r;
1493 1498
1494 /* Get rest of the packet */ 1499 /* Get rest of the packet */
1495 listen_address = packet_get_string(NULL); 1500 if ((r = sshpkt_get_cstring(ssh, &listen_address, NULL)) != 0 ||
1496 listen_port = packet_get_int(); 1501 (r = sshpkt_get_u32(ssh, &listen_port)) != 0 ||
1497 originator_address = packet_get_string(NULL); 1502 (r = sshpkt_get_cstring(ssh, &originator_address, NULL)) != 0 ||
1498 originator_port = packet_get_int(); 1503 (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
1499 packet_check_eom(); 1504 (r = sshpkt_get_end(ssh)) != 0)
1505 fatal("%s: parse packet: %s", __func__, ssh_err(r));
1500 1506
1501 debug("%s: listen %s port %d, originator %s port %d", __func__, 1507 debug("%s: listen %s port %d, originator %s port %d", __func__,
1502 listen_address, listen_port, originator_address, originator_port); 1508 listen_address, listen_port, originator_address, originator_port);
1503 1509
1504 c = channel_connect_by_listen_address(ssh, listen_address, listen_port, 1510 if (listen_port > 0xffff)
1505 "forwarded-tcpip", originator_address); 1511 error("%s: invalid listen port", __func__);
1512 else if (originator_port > 0xffff)
1513 error("%s: invalid originator port", __func__);
1514 else {
1515 c = channel_connect_by_listen_address(ssh,
1516 listen_address, listen_port, "forwarded-tcpip",
1517 originator_address);
1518 }
1506 1519
1507 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { 1520 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
1508 if ((b = sshbuf_new()) == NULL) { 1521 if ((b = sshbuf_new()) == NULL) {
@@ -1540,15 +1553,15 @@ client_request_forwarded_streamlocal(struct ssh *ssh,
1540{ 1553{
1541 Channel *c = NULL; 1554 Channel *c = NULL;
1542 char *listen_path; 1555 char *listen_path;
1556 int r;
1543 1557
1544 /* Get the remote path. */ 1558 /* Get the remote path. */
1545 listen_path = packet_get_string(NULL); 1559 if ((r = sshpkt_get_cstring(ssh, &listen_path, NULL)) != 0 ||
1546 /* XXX: Skip reserved field for now. */ 1560 (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* reserved */
1547 if (packet_get_string_ptr(NULL) == NULL) 1561 (r = sshpkt_get_end(ssh)) != 0)
1548 fatal("%s: packet_get_string_ptr failed", __func__); 1562 fatal("%s: parse packet: %s", __func__, ssh_err(r));
1549 packet_check_eom();
1550 1563
1551 debug("%s: %s", __func__, listen_path); 1564 debug("%s: request: %s", __func__, listen_path);
1552 1565
1553 c = channel_connect_by_listen_path(ssh, listen_path, 1566 c = channel_connect_by_listen_path(ssh, listen_path,
1554 "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); 1567 "forwarded-streamlocal@openssh.com", "forwarded-streamlocal");
@@ -1561,8 +1574,8 @@ client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
1561{ 1574{
1562 Channel *c = NULL; 1575 Channel *c = NULL;
1563 char *originator; 1576 char *originator;
1564 u_short originator_port; 1577 u_int originator_port;
1565 int sock; 1578 int r, sock;
1566 1579
1567 if (!options.forward_x11) { 1580 if (!options.forward_x11) {
1568 error("Warning: ssh server tried X11 forwarding."); 1581 error("Warning: ssh server tried X11 forwarding.");
@@ -1575,11 +1588,13 @@ client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
1575 "expired"); 1588 "expired");
1576 return NULL; 1589 return NULL;
1577 } 1590 }
1578 originator = packet_get_string(NULL); 1591 if ((r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
1579 originator_port = packet_get_int(); 1592 (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
1580 packet_check_eom(); 1593 (r = sshpkt_get_end(ssh)) != 0)
1594 fatal("%s: parse packet: %s", __func__, ssh_err(r));
1581 /* XXX check permission */ 1595 /* XXX check permission */
1582 debug("client_request_x11: request from %s %d", originator, 1596 /* XXX range check originator port? */
1597 debug("client_request_x11: request from %s %u", originator,
1583 originator_port); 1598 originator_port);
1584 free(originator); 1599 free(originator);
1585 sock = x11_connect_display(ssh); 1600 sock = x11_connect_display(ssh);
@@ -1623,7 +1638,7 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
1623 int local_tun, int remote_tun) 1638 int local_tun, int remote_tun)
1624{ 1639{
1625 Channel *c; 1640 Channel *c;
1626 int fd; 1641 int r, fd;
1627 char *ifname = NULL; 1642 char *ifname = NULL;
1628 1643
1629 if (tun_mode == SSH_TUNMODE_NO) 1644 if (tun_mode == SSH_TUNMODE_NO)
@@ -1648,14 +1663,15 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
1648 sys_tun_outfilter, NULL, NULL); 1663 sys_tun_outfilter, NULL, NULL);
1649#endif 1664#endif
1650 1665
1651 packet_start(SSH2_MSG_CHANNEL_OPEN); 1666 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
1652 packet_put_cstring("tun@openssh.com"); 1667 (r = sshpkt_put_cstring(ssh, "tun@openssh.com")) != 0 ||
1653 packet_put_int(c->self); 1668 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
1654 packet_put_int(c->local_window_max); 1669 (r = sshpkt_put_u32(ssh, c->local_window_max)) != 0 ||
1655 packet_put_int(c->local_maxpacket); 1670 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
1656 packet_put_int(tun_mode); 1671 (r = sshpkt_put_u32(ssh, tun_mode)) != 0 ||
1657 packet_put_int(remote_tun); 1672 (r = sshpkt_put_u32(ssh, remote_tun)) != 0 ||
1658 packet_send(); 1673 (r = sshpkt_send(ssh)) != 0)
1674 sshpkt_fatal(ssh, r, "%s: send reply", __func__);
1659 1675
1660 return ifname; 1676 return ifname;
1661} 1677}
@@ -1665,14 +1681,17 @@ static int
1665client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) 1681client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
1666{ 1682{
1667 Channel *c = NULL; 1683 Channel *c = NULL;
1668 char *ctype; 1684 char *ctype = NULL;
1669 int rchan; 1685 int r;
1670 u_int rmaxpack, rwindow, len; 1686 u_int rchan;
1671 1687 size_t len;
1672 ctype = packet_get_string(&len); 1688 u_int rmaxpack, rwindow;
1673 rchan = packet_get_int(); 1689
1674 rwindow = packet_get_int(); 1690 if ((r = sshpkt_get_cstring(ssh, &ctype, &len)) != 0 ||
1675 rmaxpack = packet_get_int(); 1691 (r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
1692 (r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
1693 (r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
1694 goto out;
1676 1695
1677 debug("client_input_channel_open: ctype %s rchan %d win %d max %d", 1696 debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
1678 ctype, rchan, rwindow, rmaxpack); 1697 ctype, rchan, rwindow, rmaxpack);
@@ -1696,57 +1715,66 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
1696 c->remote_window = rwindow; 1715 c->remote_window = rwindow;
1697 c->remote_maxpacket = rmaxpack; 1716 c->remote_maxpacket = rmaxpack;
1698 if (c->type != SSH_CHANNEL_CONNECTING) { 1717 if (c->type != SSH_CHANNEL_CONNECTING) {
1699 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 1718 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
1700 packet_put_int(c->remote_id); 1719 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1701 packet_put_int(c->self); 1720 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
1702 packet_put_int(c->local_window); 1721 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
1703 packet_put_int(c->local_maxpacket); 1722 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
1704 packet_send(); 1723 (r = sshpkt_send(ssh)) != 0)
1724 sshpkt_fatal(ssh, r, "%s: send reply", __func__);
1705 } 1725 }
1706 } else { 1726 } else {
1707 debug("failure %s", ctype); 1727 debug("failure %s", ctype);
1708 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 1728 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
1709 packet_put_int(rchan); 1729 (r = sshpkt_put_u32(ssh, rchan)) != 0 ||
1710 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); 1730 (r = sshpkt_put_u32(ssh, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED)) != 0 ||
1711 packet_put_cstring("open failed"); 1731 (r = sshpkt_put_cstring(ssh, "open failed")) != 0 ||
1712 packet_put_cstring(""); 1732 (r = sshpkt_put_cstring(ssh, "")) != 0 ||
1713 packet_send(); 1733 (r = sshpkt_send(ssh)) != 0)
1734 sshpkt_fatal(ssh, r, "%s: send failure", __func__);
1714 } 1735 }
1736 r = 0;
1737 out:
1715 free(ctype); 1738 free(ctype);
1716 return 0; 1739 return r;
1717} 1740}
1718 1741
1719static int 1742static int
1720client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) 1743client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
1721{ 1744{
1722 Channel *c = NULL; 1745 Channel *c = NULL;
1723 int exitval, id, reply, success = 0; 1746 char *rtype = NULL;
1724 char *rtype; 1747 u_char reply;
1725 1748 u_int id, exitval;
1726 id = packet_get_int(); 1749 int r, success = 0;
1727 c = channel_lookup(ssh, id); 1750
1751 if ((r = sshpkt_get_u32(ssh, &id)) != 0)
1752 return r;
1753 if (id <= INT_MAX)
1754 c = channel_lookup(ssh, id);
1728 if (channel_proxy_upstream(c, type, seq, ssh)) 1755 if (channel_proxy_upstream(c, type, seq, ssh))
1729 return 0; 1756 return 0;
1730 rtype = packet_get_string(NULL); 1757 if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
1731 reply = packet_get_char(); 1758 (r = sshpkt_get_u8(ssh, &reply)) != 0)
1759 goto out;
1732 1760
1733 debug("client_input_channel_req: channel %d rtype %s reply %d", 1761 debug("client_input_channel_req: channel %u rtype %s reply %d",
1734 id, rtype, reply); 1762 id, rtype, reply);
1735 1763
1736 if (id == -1) { 1764 if (c == NULL) {
1737 error("client_input_channel_req: request for channel -1");
1738 } else if (c == NULL) {
1739 error("client_input_channel_req: channel %d: " 1765 error("client_input_channel_req: channel %d: "
1740 "unknown channel", id); 1766 "unknown channel", id);
1741 } else if (strcmp(rtype, "eow@openssh.com") == 0) { 1767 } else if (strcmp(rtype, "eow@openssh.com") == 0) {
1742 packet_check_eom(); 1768 if ((r = sshpkt_get_end(ssh)) != 0)
1769 goto out;
1743 chan_rcvd_eow(ssh, c); 1770 chan_rcvd_eow(ssh, c);
1744 } else if (strcmp(rtype, "exit-status") == 0) { 1771 } else if (strcmp(rtype, "exit-status") == 0) {
1745 exitval = packet_get_int(); 1772 if ((r = sshpkt_get_u32(ssh, &exitval)) != 0)
1773 goto out;
1746 if (c->ctl_chan != -1) { 1774 if (c->ctl_chan != -1) {
1747 mux_exit_message(ssh, c, exitval); 1775 mux_exit_message(ssh, c, exitval);
1748 success = 1; 1776 success = 1;
1749 } else if (id == session_ident) { 1777 } else if ((int)id == session_ident) {
1750 /* Record exit value of local session */ 1778 /* Record exit value of local session */
1751 success = 1; 1779 success = 1;
1752 exit_status = exitval; 1780 exit_status = exitval;
@@ -1755,19 +1783,23 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
1755 debug("%s: no sink for exit-status on channel %d", 1783 debug("%s: no sink for exit-status on channel %d",
1756 __func__, id); 1784 __func__, id);
1757 } 1785 }
1758 packet_check_eom(); 1786 if ((r = sshpkt_get_end(ssh)) != 0)
1787 goto out;
1759 } 1788 }
1760 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) { 1789 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {
1761 if (!c->have_remote_id) 1790 if (!c->have_remote_id)
1762 fatal("%s: channel %d: no remote_id", 1791 fatal("%s: channel %d: no remote_id",
1763 __func__, c->self); 1792 __func__, c->self);
1764 packet_start(success ? 1793 if ((r = sshpkt_start(ssh, success ?
1765 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 1794 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
1766 packet_put_int(c->remote_id); 1795 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1767 packet_send(); 1796 (r = sshpkt_send(ssh)) != 0)
1797 sshpkt_fatal(ssh, r, "%s: send failure", __func__);
1768 } 1798 }
1799 r = 0;
1800 out:
1769 free(rtype); 1801 free(rtype);
1770 return 0; 1802 return r;
1771} 1803}
1772 1804
1773struct hostkeys_update_ctx { 1805struct hostkeys_update_ctx {
@@ -1984,7 +2016,10 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
1984 if (ndone != ctx->nnew) 2016 if (ndone != ctx->nnew)
1985 fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__, 2017 fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__,
1986 ndone, ctx->nnew); /* Shouldn't happen */ 2018 ndone, ctx->nnew); /* Shouldn't happen */
1987 ssh_packet_check_eom(ssh); 2019 if ((r = sshpkt_get_end(ssh)) != 0) {
2020 error("%s: protocol error", __func__);
2021 goto out;
2022 }
1988 2023
1989 /* Make the edits to known_hosts */ 2024 /* Make the edits to known_hosts */
1990 update_known_hosts(ctx); 2025 update_known_hosts(ctx);
@@ -2018,9 +2053,8 @@ key_accepted_by_hostkeyalgs(const struct sshkey *key)
2018 * HostkeyAlgorithms preference before they are accepted. 2053 * HostkeyAlgorithms preference before they are accepted.
2019 */ 2054 */
2020static int 2055static int
2021client_input_hostkeys(void) 2056client_input_hostkeys(struct ssh *ssh)
2022{ 2057{
2023 struct ssh *ssh = active_state; /* XXX */
2024 const u_char *blob = NULL; 2058 const u_char *blob = NULL;
2025 size_t i, len = 0; 2059 size_t i, len = 0;
2026 struct sshbuf *buf = NULL; 2060 struct sshbuf *buf = NULL;
@@ -2171,23 +2205,27 @@ static int
2171client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) 2205client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
2172{ 2206{
2173 char *rtype; 2207 char *rtype;
2174 int want_reply; 2208 u_char want_reply;
2175 int success = 0; 2209 int r, success = 0;
2176 2210
2177 rtype = packet_get_cstring(NULL); 2211 if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
2178 want_reply = packet_get_char(); 2212 (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
2213 goto out;
2179 debug("client_input_global_request: rtype %s want_reply %d", 2214 debug("client_input_global_request: rtype %s want_reply %d",
2180 rtype, want_reply); 2215 rtype, want_reply);
2181 if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) 2216 if (strcmp(rtype, "hostkeys-00@openssh.com") == 0)
2182 success = client_input_hostkeys(); 2217 success = client_input_hostkeys(ssh);
2183 if (want_reply) { 2218 if (want_reply) {
2184 packet_start(success ? 2219 if ((r = sshpkt_start(ssh, success ? SSH2_MSG_REQUEST_SUCCESS :
2185 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 2220 SSH2_MSG_REQUEST_FAILURE)) != 0 ||
2186 packet_send(); 2221 (r = sshpkt_send(ssh)) != 0 ||
2187 packet_write_wait(); 2222 (r = ssh_packet_write_wait(ssh)) != 0)
2223 goto out;
2188 } 2224 }
2225 r = 0;
2226 out:
2189 free(rtype); 2227 free(rtype);
2190 return 0; 2228 return r;
2191} 2229}
2192 2230
2193void 2231void
@@ -2195,7 +2233,7 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2195 const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd, 2233 const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd,
2196 char **env) 2234 char **env)
2197{ 2235{
2198 int i, j, matched, len; 2236 int i, j, matched, len, r;
2199 char *name, *val; 2237 char *name, *val;
2200 Channel *c = NULL; 2238 Channel *c = NULL;
2201 2239
@@ -2204,7 +2242,7 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2204 if ((c = channel_lookup(ssh, id)) == NULL) 2242 if ((c = channel_lookup(ssh, id)) == NULL)
2205 fatal("%s: channel %d: unknown channel", __func__, id); 2243 fatal("%s: channel %d: unknown channel", __func__, id);
2206 2244
2207 packet_set_interactive(want_tty, 2245 ssh_packet_set_interactive(ssh, want_tty,
2208 options.ip_qos_interactive, options.ip_qos_bulk); 2246 options.ip_qos_interactive, options.ip_qos_bulk);
2209 2247
2210 if (want_tty) { 2248 if (want_tty) {
@@ -2216,15 +2254,18 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2216 2254
2217 channel_request_start(ssh, id, "pty-req", 1); 2255 channel_request_start(ssh, id, "pty-req", 1);
2218 client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY); 2256 client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY);
2219 packet_put_cstring(term != NULL ? term : ""); 2257 if ((r = sshpkt_put_cstring(ssh, term != NULL ? term : ""))
2220 packet_put_int((u_int)ws.ws_col); 2258 != 0 ||
2221 packet_put_int((u_int)ws.ws_row); 2259 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
2222 packet_put_int((u_int)ws.ws_xpixel); 2260 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 ||
2223 packet_put_int((u_int)ws.ws_ypixel); 2261 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
2262 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0)
2263 fatal("%s: build packet: %s", __func__, ssh_err(r));
2224 if (tiop == NULL) 2264 if (tiop == NULL)
2225 tiop = get_saved_tio(); 2265 tiop = get_saved_tio();
2226 ssh_tty_make_modes(ssh, -1, tiop); 2266 ssh_tty_make_modes(ssh, -1, tiop);
2227 packet_send(); 2267 if ((r = sshpkt_send(ssh)) != 0)
2268 fatal("%s: send packet: %s", __func__, ssh_err(r));
2228 /* XXX wait for reply */ 2269 /* XXX wait for reply */
2229 c->client_tty = 1; 2270 c->client_tty = 1;
2230 } 2271 }
@@ -2256,9 +2297,12 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2256 2297
2257 debug("Sending env %s = %s", name, val); 2298 debug("Sending env %s = %s", name, val);
2258 channel_request_start(ssh, id, "env", 0); 2299 channel_request_start(ssh, id, "env", 0);
2259 packet_put_cstring(name); 2300 if ((r = sshpkt_put_cstring(ssh, name)) != 0 ||
2260 packet_put_cstring(val); 2301 (r = sshpkt_put_cstring(ssh, val)) != 0 ||
2261 packet_send(); 2302 (r = sshpkt_send(ssh)) != 0) {
2303 fatal("%s: send packet: %s",
2304 __func__, ssh_err(r));
2305 }
2262 free(name); 2306 free(name);
2263 } 2307 }
2264 } 2308 }
@@ -2273,9 +2317,10 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2273 2317
2274 debug("Setting env %s = %s", name, val); 2318 debug("Setting env %s = %s", name, val);
2275 channel_request_start(ssh, id, "env", 0); 2319 channel_request_start(ssh, id, "env", 0);
2276 packet_put_cstring(name); 2320 if ((r = sshpkt_put_cstring(ssh, name)) != 0 ||
2277 packet_put_cstring(val); 2321 (r = sshpkt_put_cstring(ssh, val)) != 0 ||
2278 packet_send(); 2322 (r = sshpkt_send(ssh)) != 0)
2323 fatal("%s: send packet: %s", __func__, ssh_err(r));
2279 free(name); 2324 free(name);
2280 } 2325 }
2281 2326
@@ -2295,39 +2340,43 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2295 channel_request_start(ssh, id, "exec", 1); 2340 channel_request_start(ssh, id, "exec", 1);
2296 client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE); 2341 client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE);
2297 } 2342 }
2298 packet_put_string(sshbuf_ptr(cmd), sshbuf_len(cmd)); 2343 if ((r = sshpkt_put_stringb(ssh, cmd)) != 0 ||
2299 packet_send(); 2344 (r = sshpkt_send(ssh)) != 0)
2345 fatal("%s: send command: %s", __func__, ssh_err(r));
2300 } else { 2346 } else {
2301 channel_request_start(ssh, id, "shell", 1); 2347 channel_request_start(ssh, id, "shell", 1);
2302 client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE); 2348 client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE);
2303 packet_send(); 2349 if ((r = sshpkt_send(ssh)) != 0) {
2350 fatal("%s: send shell request: %s",
2351 __func__, ssh_err(r));
2352 }
2304 } 2353 }
2305} 2354}
2306 2355
2307static void 2356static void
2308client_init_dispatch(void) 2357client_init_dispatch(struct ssh *ssh)
2309{ 2358{
2310 dispatch_init(&dispatch_protocol_error); 2359 ssh_dispatch_init(ssh, &dispatch_protocol_error);
2311 2360
2312 dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); 2361 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
2313 dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); 2362 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data);
2314 dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); 2363 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
2315 dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); 2364 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
2316 dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); 2365 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
2317 dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 2366 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
2318 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 2367 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
2319 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); 2368 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
2320 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 2369 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
2321 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); 2370 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
2322 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); 2371 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
2323 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); 2372 ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
2324 2373
2325 /* rekeying */ 2374 /* rekeying */
2326 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 2375 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
2327 2376
2328 /* global request reply messages */ 2377 /* global request reply messages */
2329 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); 2378 ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
2330 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 2379 ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
2331} 2380}
2332 2381
2333void 2382void