summaryrefslogtreecommitdiff
path: root/clientloop.c
diff options
context:
space:
mode:
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 1464634b0..9b90c64f3 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
@@ -164,7 +164,7 @@ static int need_rekeying; /* Set to non-zero if rekeying is requested. */
164static int session_closed; /* In SSH2: login session closed. */ 164static int session_closed; /* In SSH2: login session closed. */
165static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */ 165static u_int x11_refuse_time; /* If >0, refuse x11 opens after this time. */
166 166
167static void client_init_dispatch(void); 167static void client_init_dispatch(struct ssh *ssh);
168int session_ident = -1; 168int session_ident = -1;
169 169
170/* Track escape per proto2 channel */ 170/* Track escape per proto2 channel */
@@ -368,7 +368,7 @@ client_x11_get_proto(struct ssh *ssh, const char *display,
368 SSH_X11_PROTO, x11_timeout_real, 368 SSH_X11_PROTO, x11_timeout_real,
369 _PATH_DEVNULL); 369 _PATH_DEVNULL);
370 } 370 }
371 debug2("%s: %s", __func__, cmd); 371 debug2("%s: xauth command: %s", __func__, cmd);
372 372
373 if (timeout != 0 && x11_refuse_time == 0) { 373 if (timeout != 0 && x11_refuse_time == 0) {
374 now = monotime() + 1; 374 now = monotime() + 1;
@@ -479,21 +479,24 @@ client_global_request_reply(int type, u_int32_t seq, struct ssh *ssh)
479 free(gc); 479 free(gc);
480 } 480 }
481 481
482 packet_set_alive_timeouts(0); 482 ssh_packet_set_alive_timeouts(ssh, 0);
483 return 0; 483 return 0;
484} 484}
485 485
486static void 486static void
487server_alive_check(void) 487server_alive_check(struct ssh *ssh)
488{ 488{
489 if (packet_inc_alive_timeouts() > options.server_alive_count_max) { 489 int r;
490
491 if (ssh_packet_inc_alive_timeouts(ssh) > options.server_alive_count_max) {
490 logit("Timeout, server %s not responding.", host); 492 logit("Timeout, server %s not responding.", host);
491 cleanup_exit(255); 493 cleanup_exit(255);
492 } 494 }
493 packet_start(SSH2_MSG_GLOBAL_REQUEST); 495 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
494 packet_put_cstring("keepalive@openssh.com"); 496 (r = sshpkt_put_cstring(ssh, "keepalive@openssh.com")) != 0 ||
495 packet_put_char(1); /* boolean: want reply */ 497 (r = sshpkt_put_u8(ssh, 1)) != 0 || /* boolean: want reply */
496 packet_send(); 498 (r = sshpkt_send(ssh)) != 0)
499 fatal("%s: send packet: %s", __func__, ssh_err(r));
497 /* Insert an empty placeholder to maintain ordering */ 500 /* Insert an empty placeholder to maintain ordering */
498 client_register_global_confirm(NULL, NULL); 501 client_register_global_confirm(NULL, NULL);
499} 502}
@@ -513,12 +516,12 @@ client_wait_until_can_do_something(struct ssh *ssh,
513 int r, ret; 516 int r, ret;
514 517
515 /* Add any selections by the channel mechanism. */ 518 /* Add any selections by the channel mechanism. */
516 channel_prepare_select(active_state, readsetp, writesetp, maxfdp, 519 channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
517 nallocp, &minwait_secs); 520 nallocp, &minwait_secs);
518 521
519 /* channel_prepare_select could have closed the last channel */ 522 /* channel_prepare_select could have closed the last channel */
520 if (session_closed && !channel_still_open(ssh) && 523 if (session_closed && !channel_still_open(ssh) &&
521 !packet_have_data_to_write()) { 524 !ssh_packet_have_data_to_write(ssh)) {
522 /* clear mask since we did not call select() */ 525 /* clear mask since we did not call select() */
523 memset(*readsetp, 0, *nallocp); 526 memset(*readsetp, 0, *nallocp);
524 memset(*writesetp, 0, *nallocp); 527 memset(*writesetp, 0, *nallocp);
@@ -528,7 +531,7 @@ client_wait_until_can_do_something(struct ssh *ssh,
528 FD_SET(connection_in, *readsetp); 531 FD_SET(connection_in, *readsetp);
529 532
530 /* Select server connection if have data to write to the server. */ 533 /* Select server connection if have data to write to the server. */
531 if (packet_have_data_to_write()) 534 if (ssh_packet_have_data_to_write(ssh))
532 FD_SET(connection_out, *writesetp); 535 FD_SET(connection_out, *writesetp);
533 536
534 /* 537 /*
@@ -543,7 +546,8 @@ client_wait_until_can_do_something(struct ssh *ssh,
543 server_alive_time = now + options.server_alive_interval; 546 server_alive_time = now + options.server_alive_interval;
544 } 547 }
545 if (options.rekey_interval > 0 && !rekeying) 548 if (options.rekey_interval > 0 && !rekeying)
546 timeout_secs = MINIMUM(timeout_secs, packet_get_rekey_timeout()); 549 timeout_secs = MINIMUM(timeout_secs,
550 ssh_packet_get_rekey_timeout(ssh));
547 set_control_persist_exit_time(ssh); 551 set_control_persist_exit_time(ssh);
548 if (control_persist_exit_time > 0) { 552 if (control_persist_exit_time > 0) {
549 timeout_secs = MINIMUM(timeout_secs, 553 timeout_secs = MINIMUM(timeout_secs,
@@ -584,7 +588,7 @@ client_wait_until_can_do_something(struct ssh *ssh,
584 * Keepalive we check here, rekeying is checked in clientloop. 588 * Keepalive we check here, rekeying is checked in clientloop.
585 */ 589 */
586 if (server_alive_time != 0 && server_alive_time <= monotime()) 590 if (server_alive_time != 0 && server_alive_time <= monotime())
587 server_alive_check(); 591 server_alive_check(ssh);
588 } 592 }
589 593
590} 594}
@@ -616,7 +620,7 @@ client_suspend_self(struct sshbuf *bin, struct sshbuf *bout, struct sshbuf *berr
616} 620}
617 621
618static void 622static void
619client_process_net_input(fd_set *readset) 623client_process_net_input(struct ssh *ssh, fd_set *readset)
620{ 624{
621 char buf[SSH_IOBUFSZ]; 625 char buf[SSH_IOBUFSZ];
622 int r, len; 626 int r, len;
@@ -662,7 +666,7 @@ client_process_net_input(fd_set *readset)
662 quit_pending = 1; 666 quit_pending = 1;
663 return; 667 return;
664 } 668 }
665 packet_process_incoming(buf, len); 669 ssh_packet_process_incoming(ssh, buf, len);
666 } 670 }
667} 671}
668 672
@@ -1035,7 +1039,7 @@ process_escapes(struct ssh *ssh, Channel *c,
1035 channel_request_start(ssh, c->self, "break", 0); 1039 channel_request_start(ssh, c->self, "break", 0);
1036 if ((r = sshpkt_put_u32(ssh, 1000)) != 0 || 1040 if ((r = sshpkt_put_u32(ssh, 1000)) != 0 ||
1037 (r = sshpkt_send(ssh)) != 0) 1041 (r = sshpkt_send(ssh)) != 0)
1038 fatal("%s: %s", __func__, 1042 fatal("%s: send packet: %s", __func__,
1039 ssh_err(r)); 1043 ssh_err(r));
1040 continue; 1044 continue;
1041 1045
@@ -1186,9 +1190,9 @@ process_escapes(struct ssh *ssh, Channel *c,
1186 */ 1190 */
1187 1191
1188static void 1192static void
1189client_process_buffered_input_packets(void) 1193client_process_buffered_input_packets(struct ssh *ssh)
1190{ 1194{
1191 ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, &quit_pending); 1195 ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, &quit_pending);
1192} 1196}
1193 1197
1194/* scan buf[] for '~' before sending data to the peer */ 1198/* scan buf[] for '~' before sending data to the peer */
@@ -1285,8 +1289,8 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1285 /* Initialize variables. */ 1289 /* Initialize variables. */
1286 last_was_cr = 1; 1290 last_was_cr = 1;
1287 exit_status = -1; 1291 exit_status = -1;
1288 connection_in = packet_get_connection_in(); 1292 connection_in = ssh_packet_get_connection_in(ssh);
1289 connection_out = packet_get_connection_out(); 1293 connection_out = ssh_packet_get_connection_out(ssh);
1290 max_fd = MAXIMUM(connection_in, connection_out); 1294 max_fd = MAXIMUM(connection_in, connection_out);
1291 1295
1292 quit_pending = 0; 1296 quit_pending = 0;
@@ -1295,7 +1299,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1295 if ((stderr_buffer = sshbuf_new()) == NULL) 1299 if ((stderr_buffer = sshbuf_new()) == NULL)
1296 fatal("%s: sshbuf_new failed", __func__); 1300 fatal("%s: sshbuf_new failed", __func__);
1297 1301
1298 client_init_dispatch(); 1302 client_init_dispatch(ssh);
1299 1303
1300 /* 1304 /*
1301 * Set signal handlers, (e.g. to restore non-blocking mode) 1305 * Set signal handlers, (e.g. to restore non-blocking mode)
@@ -1331,7 +1335,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1331 while (!quit_pending) { 1335 while (!quit_pending) {
1332 1336
1333 /* Process buffered packets sent by the server. */ 1337 /* Process buffered packets sent by the server. */
1334 client_process_buffered_input_packets(); 1338 client_process_buffered_input_packets(ssh);
1335 1339
1336 if (session_closed && !channel_still_open(ssh)) 1340 if (session_closed && !channel_still_open(ssh))
1337 break; 1341 break;
@@ -1350,7 +1354,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1350 * Make packets from buffered channel data, and 1354 * Make packets from buffered channel data, and
1351 * enqueue them for sending to the server. 1355 * enqueue them for sending to the server.
1352 */ 1356 */
1353 if (packet_not_very_much_data_to_write()) 1357 if (ssh_packet_not_very_much_data_to_write(ssh))
1354 channel_output_poll(ssh); 1358 channel_output_poll(ssh);
1355 1359
1356 /* 1360 /*
@@ -1387,7 +1391,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1387 } 1391 }
1388 1392
1389 /* Buffer input from the connection. */ 1393 /* Buffer input from the connection. */
1390 client_process_net_input(readset); 1394 client_process_net_input(ssh, readset);
1391 1395
1392 if (quit_pending) 1396 if (quit_pending)
1393 break; 1397 break;
@@ -1397,7 +1401,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1397 * sender. 1401 * sender.
1398 */ 1402 */
1399 if (FD_ISSET(connection_out, writeset)) 1403 if (FD_ISSET(connection_out, writeset))
1400 packet_write_poll(); 1404 ssh_packet_write_poll(ssh);
1401 1405
1402 /* 1406 /*
1403 * If we are a backgrounded control master, and the 1407 * If we are a backgrounded control master, and the
@@ -1419,12 +1423,13 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1419 /* Stop watching for window change. */ 1423 /* Stop watching for window change. */
1420 signal(SIGWINCH, SIG_DFL); 1424 signal(SIGWINCH, SIG_DFL);
1421 1425
1422 packet_start(SSH2_MSG_DISCONNECT); 1426 if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
1423 packet_put_int(SSH2_DISCONNECT_BY_APPLICATION); 1427 (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_BY_APPLICATION)) != 0 ||
1424 packet_put_cstring("disconnected by user"); 1428 (r = sshpkt_put_cstring(ssh, "disconnected by user")) != 0 ||
1425 packet_put_cstring(""); /* language tag */ 1429 (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language tag */
1426 packet_send(); 1430 (r = sshpkt_send(ssh)) != 0 ||
1427 packet_write_wait(); 1431 (r = ssh_packet_write_wait(ssh)) != 0)
1432 fatal("%s: send disconnect: %s", __func__, ssh_err(r));
1428 1433
1429 channel_free_all(ssh); 1434 channel_free_all(ssh);
1430 1435
@@ -1481,7 +1486,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg,
1481 1486
1482 /* Report bytes transferred, and transfer rates. */ 1487 /* Report bytes transferred, and transfer rates. */
1483 total_time = monotime_double() - start_time; 1488 total_time = monotime_double() - start_time;
1484 packet_get_bytes(&ibytes, &obytes); 1489 ssh_packet_get_bytes(ssh, &ibytes, &obytes);
1485 verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds", 1490 verbose("Transferred: sent %llu, received %llu bytes, in %.1f seconds",
1486 (unsigned long long)obytes, (unsigned long long)ibytes, total_time); 1491 (unsigned long long)obytes, (unsigned long long)ibytes, total_time);
1487 if (total_time > 0) 1492 if (total_time > 0)
@@ -1501,21 +1506,29 @@ client_request_forwarded_tcpip(struct ssh *ssh, const char *request_type,
1501 Channel *c = NULL; 1506 Channel *c = NULL;
1502 struct sshbuf *b = NULL; 1507 struct sshbuf *b = NULL;
1503 char *listen_address, *originator_address; 1508 char *listen_address, *originator_address;
1504 u_short listen_port, originator_port; 1509 u_int listen_port, originator_port;
1505 int r; 1510 int r;
1506 1511
1507 /* Get rest of the packet */ 1512 /* Get rest of the packet */
1508 listen_address = packet_get_string(NULL); 1513 if ((r = sshpkt_get_cstring(ssh, &listen_address, NULL)) != 0 ||
1509 listen_port = packet_get_int(); 1514 (r = sshpkt_get_u32(ssh, &listen_port)) != 0 ||
1510 originator_address = packet_get_string(NULL); 1515 (r = sshpkt_get_cstring(ssh, &originator_address, NULL)) != 0 ||
1511 originator_port = packet_get_int(); 1516 (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
1512 packet_check_eom(); 1517 (r = sshpkt_get_end(ssh)) != 0)
1518 fatal("%s: parse packet: %s", __func__, ssh_err(r));
1513 1519
1514 debug("%s: listen %s port %d, originator %s port %d", __func__, 1520 debug("%s: listen %s port %d, originator %s port %d", __func__,
1515 listen_address, listen_port, originator_address, originator_port); 1521 listen_address, listen_port, originator_address, originator_port);
1516 1522
1517 c = channel_connect_by_listen_address(ssh, listen_address, listen_port, 1523 if (listen_port > 0xffff)
1518 "forwarded-tcpip", originator_address); 1524 error("%s: invalid listen port", __func__);
1525 else if (originator_port > 0xffff)
1526 error("%s: invalid originator port", __func__);
1527 else {
1528 c = channel_connect_by_listen_address(ssh,
1529 listen_address, listen_port, "forwarded-tcpip",
1530 originator_address);
1531 }
1519 1532
1520 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) { 1533 if (c != NULL && c->type == SSH_CHANNEL_MUX_CLIENT) {
1521 if ((b = sshbuf_new()) == NULL) { 1534 if ((b = sshbuf_new()) == NULL) {
@@ -1553,15 +1566,15 @@ client_request_forwarded_streamlocal(struct ssh *ssh,
1553{ 1566{
1554 Channel *c = NULL; 1567 Channel *c = NULL;
1555 char *listen_path; 1568 char *listen_path;
1569 int r;
1556 1570
1557 /* Get the remote path. */ 1571 /* Get the remote path. */
1558 listen_path = packet_get_string(NULL); 1572 if ((r = sshpkt_get_cstring(ssh, &listen_path, NULL)) != 0 ||
1559 /* XXX: Skip reserved field for now. */ 1573 (r = sshpkt_get_string(ssh, NULL, NULL)) != 0 || /* reserved */
1560 if (packet_get_string_ptr(NULL) == NULL) 1574 (r = sshpkt_get_end(ssh)) != 0)
1561 fatal("%s: packet_get_string_ptr failed", __func__); 1575 fatal("%s: parse packet: %s", __func__, ssh_err(r));
1562 packet_check_eom();
1563 1576
1564 debug("%s: %s", __func__, listen_path); 1577 debug("%s: request: %s", __func__, listen_path);
1565 1578
1566 c = channel_connect_by_listen_path(ssh, listen_path, 1579 c = channel_connect_by_listen_path(ssh, listen_path,
1567 "forwarded-streamlocal@openssh.com", "forwarded-streamlocal"); 1580 "forwarded-streamlocal@openssh.com", "forwarded-streamlocal");
@@ -1574,8 +1587,8 @@ client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
1574{ 1587{
1575 Channel *c = NULL; 1588 Channel *c = NULL;
1576 char *originator; 1589 char *originator;
1577 u_short originator_port; 1590 u_int originator_port;
1578 int sock; 1591 int r, sock;
1579 1592
1580 if (!options.forward_x11) { 1593 if (!options.forward_x11) {
1581 error("Warning: ssh server tried X11 forwarding."); 1594 error("Warning: ssh server tried X11 forwarding.");
@@ -1588,11 +1601,13 @@ client_request_x11(struct ssh *ssh, const char *request_type, int rchan)
1588 "expired"); 1601 "expired");
1589 return NULL; 1602 return NULL;
1590 } 1603 }
1591 originator = packet_get_string(NULL); 1604 if ((r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
1592 originator_port = packet_get_int(); 1605 (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
1593 packet_check_eom(); 1606 (r = sshpkt_get_end(ssh)) != 0)
1607 fatal("%s: parse packet: %s", __func__, ssh_err(r));
1594 /* XXX check permission */ 1608 /* XXX check permission */
1595 debug("client_request_x11: request from %s %d", originator, 1609 /* XXX range check originator port? */
1610 debug("client_request_x11: request from %s %u", originator,
1596 originator_port); 1611 originator_port);
1597 free(originator); 1612 free(originator);
1598 sock = x11_connect_display(ssh); 1613 sock = x11_connect_display(ssh);
@@ -1636,7 +1651,7 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
1636 int local_tun, int remote_tun) 1651 int local_tun, int remote_tun)
1637{ 1652{
1638 Channel *c; 1653 Channel *c;
1639 int fd; 1654 int r, fd;
1640 char *ifname = NULL; 1655 char *ifname = NULL;
1641 1656
1642 if (tun_mode == SSH_TUNMODE_NO) 1657 if (tun_mode == SSH_TUNMODE_NO)
@@ -1661,14 +1676,15 @@ client_request_tun_fwd(struct ssh *ssh, int tun_mode,
1661 sys_tun_outfilter, NULL, NULL); 1676 sys_tun_outfilter, NULL, NULL);
1662#endif 1677#endif
1663 1678
1664 packet_start(SSH2_MSG_CHANNEL_OPEN); 1679 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN)) != 0 ||
1665 packet_put_cstring("tun@openssh.com"); 1680 (r = sshpkt_put_cstring(ssh, "tun@openssh.com")) != 0 ||
1666 packet_put_int(c->self); 1681 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
1667 packet_put_int(c->local_window_max); 1682 (r = sshpkt_put_u32(ssh, c->local_window_max)) != 0 ||
1668 packet_put_int(c->local_maxpacket); 1683 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
1669 packet_put_int(tun_mode); 1684 (r = sshpkt_put_u32(ssh, tun_mode)) != 0 ||
1670 packet_put_int(remote_tun); 1685 (r = sshpkt_put_u32(ssh, remote_tun)) != 0 ||
1671 packet_send(); 1686 (r = sshpkt_send(ssh)) != 0)
1687 sshpkt_fatal(ssh, r, "%s: send reply", __func__);
1672 1688
1673 return ifname; 1689 return ifname;
1674} 1690}
@@ -1678,14 +1694,17 @@ static int
1678client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) 1694client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
1679{ 1695{
1680 Channel *c = NULL; 1696 Channel *c = NULL;
1681 char *ctype; 1697 char *ctype = NULL;
1682 int rchan; 1698 int r;
1683 u_int rmaxpack, rwindow, len; 1699 u_int rchan;
1684 1700 size_t len;
1685 ctype = packet_get_string(&len); 1701 u_int rmaxpack, rwindow;
1686 rchan = packet_get_int(); 1702
1687 rwindow = packet_get_int(); 1703 if ((r = sshpkt_get_cstring(ssh, &ctype, &len)) != 0 ||
1688 rmaxpack = packet_get_int(); 1704 (r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
1705 (r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
1706 (r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
1707 goto out;
1689 1708
1690 debug("client_input_channel_open: ctype %s rchan %d win %d max %d", 1709 debug("client_input_channel_open: ctype %s rchan %d win %d max %d",
1691 ctype, rchan, rwindow, rmaxpack); 1710 ctype, rchan, rwindow, rmaxpack);
@@ -1709,57 +1728,66 @@ client_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
1709 c->remote_window = rwindow; 1728 c->remote_window = rwindow;
1710 c->remote_maxpacket = rmaxpack; 1729 c->remote_maxpacket = rmaxpack;
1711 if (c->type != SSH_CHANNEL_CONNECTING) { 1730 if (c->type != SSH_CHANNEL_CONNECTING) {
1712 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 1731 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
1713 packet_put_int(c->remote_id); 1732 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1714 packet_put_int(c->self); 1733 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
1715 packet_put_int(c->local_window); 1734 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
1716 packet_put_int(c->local_maxpacket); 1735 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
1717 packet_send(); 1736 (r = sshpkt_send(ssh)) != 0)
1737 sshpkt_fatal(ssh, r, "%s: send reply", __func__);
1718 } 1738 }
1719 } else { 1739 } else {
1720 debug("failure %s", ctype); 1740 debug("failure %s", ctype);
1721 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 1741 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
1722 packet_put_int(rchan); 1742 (r = sshpkt_put_u32(ssh, rchan)) != 0 ||
1723 packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED); 1743 (r = sshpkt_put_u32(ssh, SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED)) != 0 ||
1724 packet_put_cstring("open failed"); 1744 (r = sshpkt_put_cstring(ssh, "open failed")) != 0 ||
1725 packet_put_cstring(""); 1745 (r = sshpkt_put_cstring(ssh, "")) != 0 ||
1726 packet_send(); 1746 (r = sshpkt_send(ssh)) != 0)
1747 sshpkt_fatal(ssh, r, "%s: send failure", __func__);
1727 } 1748 }
1749 r = 0;
1750 out:
1728 free(ctype); 1751 free(ctype);
1729 return 0; 1752 return r;
1730} 1753}
1731 1754
1732static int 1755static int
1733client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) 1756client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
1734{ 1757{
1735 Channel *c = NULL; 1758 Channel *c = NULL;
1736 int exitval, id, reply, success = 0; 1759 char *rtype = NULL;
1737 char *rtype; 1760 u_char reply;
1738 1761 u_int id, exitval;
1739 id = packet_get_int(); 1762 int r, success = 0;
1740 c = channel_lookup(ssh, id); 1763
1764 if ((r = sshpkt_get_u32(ssh, &id)) != 0)
1765 return r;
1766 if (id <= INT_MAX)
1767 c = channel_lookup(ssh, id);
1741 if (channel_proxy_upstream(c, type, seq, ssh)) 1768 if (channel_proxy_upstream(c, type, seq, ssh))
1742 return 0; 1769 return 0;
1743 rtype = packet_get_string(NULL); 1770 if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
1744 reply = packet_get_char(); 1771 (r = sshpkt_get_u8(ssh, &reply)) != 0)
1772 goto out;
1745 1773
1746 debug("client_input_channel_req: channel %d rtype %s reply %d", 1774 debug("client_input_channel_req: channel %u rtype %s reply %d",
1747 id, rtype, reply); 1775 id, rtype, reply);
1748 1776
1749 if (id == -1) { 1777 if (c == NULL) {
1750 error("client_input_channel_req: request for channel -1");
1751 } else if (c == NULL) {
1752 error("client_input_channel_req: channel %d: " 1778 error("client_input_channel_req: channel %d: "
1753 "unknown channel", id); 1779 "unknown channel", id);
1754 } else if (strcmp(rtype, "eow@openssh.com") == 0) { 1780 } else if (strcmp(rtype, "eow@openssh.com") == 0) {
1755 packet_check_eom(); 1781 if ((r = sshpkt_get_end(ssh)) != 0)
1782 goto out;
1756 chan_rcvd_eow(ssh, c); 1783 chan_rcvd_eow(ssh, c);
1757 } else if (strcmp(rtype, "exit-status") == 0) { 1784 } else if (strcmp(rtype, "exit-status") == 0) {
1758 exitval = packet_get_int(); 1785 if ((r = sshpkt_get_u32(ssh, &exitval)) != 0)
1786 goto out;
1759 if (c->ctl_chan != -1) { 1787 if (c->ctl_chan != -1) {
1760 mux_exit_message(ssh, c, exitval); 1788 mux_exit_message(ssh, c, exitval);
1761 success = 1; 1789 success = 1;
1762 } else if (id == session_ident) { 1790 } else if ((int)id == session_ident) {
1763 /* Record exit value of local session */ 1791 /* Record exit value of local session */
1764 success = 1; 1792 success = 1;
1765 exit_status = exitval; 1793 exit_status = exitval;
@@ -1768,19 +1796,23 @@ client_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
1768 debug("%s: no sink for exit-status on channel %d", 1796 debug("%s: no sink for exit-status on channel %d",
1769 __func__, id); 1797 __func__, id);
1770 } 1798 }
1771 packet_check_eom(); 1799 if ((r = sshpkt_get_end(ssh)) != 0)
1800 goto out;
1772 } 1801 }
1773 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) { 1802 if (reply && c != NULL && !(c->flags & CHAN_CLOSE_SENT)) {
1774 if (!c->have_remote_id) 1803 if (!c->have_remote_id)
1775 fatal("%s: channel %d: no remote_id", 1804 fatal("%s: channel %d: no remote_id",
1776 __func__, c->self); 1805 __func__, c->self);
1777 packet_start(success ? 1806 if ((r = sshpkt_start(ssh, success ?
1778 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 1807 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
1779 packet_put_int(c->remote_id); 1808 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
1780 packet_send(); 1809 (r = sshpkt_send(ssh)) != 0)
1810 sshpkt_fatal(ssh, r, "%s: send failure", __func__);
1781 } 1811 }
1812 r = 0;
1813 out:
1782 free(rtype); 1814 free(rtype);
1783 return 0; 1815 return r;
1784} 1816}
1785 1817
1786struct hostkeys_update_ctx { 1818struct hostkeys_update_ctx {
@@ -1997,7 +2029,10 @@ client_global_hostkeys_private_confirm(struct ssh *ssh, int type,
1997 if (ndone != ctx->nnew) 2029 if (ndone != ctx->nnew)
1998 fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__, 2030 fatal("%s: ndone != ctx->nnew (%zu / %zu)", __func__,
1999 ndone, ctx->nnew); /* Shouldn't happen */ 2031 ndone, ctx->nnew); /* Shouldn't happen */
2000 ssh_packet_check_eom(ssh); 2032 if ((r = sshpkt_get_end(ssh)) != 0) {
2033 error("%s: protocol error", __func__);
2034 goto out;
2035 }
2001 2036
2002 /* Make the edits to known_hosts */ 2037 /* Make the edits to known_hosts */
2003 update_known_hosts(ctx); 2038 update_known_hosts(ctx);
@@ -2031,9 +2066,8 @@ key_accepted_by_hostkeyalgs(const struct sshkey *key)
2031 * HostkeyAlgorithms preference before they are accepted. 2066 * HostkeyAlgorithms preference before they are accepted.
2032 */ 2067 */
2033static int 2068static int
2034client_input_hostkeys(void) 2069client_input_hostkeys(struct ssh *ssh)
2035{ 2070{
2036 struct ssh *ssh = active_state; /* XXX */
2037 const u_char *blob = NULL; 2071 const u_char *blob = NULL;
2038 size_t i, len = 0; 2072 size_t i, len = 0;
2039 struct sshbuf *buf = NULL; 2073 struct sshbuf *buf = NULL;
@@ -2184,23 +2218,27 @@ static int
2184client_input_global_request(int type, u_int32_t seq, struct ssh *ssh) 2218client_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
2185{ 2219{
2186 char *rtype; 2220 char *rtype;
2187 int want_reply; 2221 u_char want_reply;
2188 int success = 0; 2222 int r, success = 0;
2189 2223
2190 rtype = packet_get_cstring(NULL); 2224 if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
2191 want_reply = packet_get_char(); 2225 (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
2226 goto out;
2192 debug("client_input_global_request: rtype %s want_reply %d", 2227 debug("client_input_global_request: rtype %s want_reply %d",
2193 rtype, want_reply); 2228 rtype, want_reply);
2194 if (strcmp(rtype, "hostkeys-00@openssh.com") == 0) 2229 if (strcmp(rtype, "hostkeys-00@openssh.com") == 0)
2195 success = client_input_hostkeys(); 2230 success = client_input_hostkeys(ssh);
2196 if (want_reply) { 2231 if (want_reply) {
2197 packet_start(success ? 2232 if ((r = sshpkt_start(ssh, success ? SSH2_MSG_REQUEST_SUCCESS :
2198 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 2233 SSH2_MSG_REQUEST_FAILURE)) != 0 ||
2199 packet_send(); 2234 (r = sshpkt_send(ssh)) != 0 ||
2200 packet_write_wait(); 2235 (r = ssh_packet_write_wait(ssh)) != 0)
2236 goto out;
2201 } 2237 }
2238 r = 0;
2239 out:
2202 free(rtype); 2240 free(rtype);
2203 return 0; 2241 return r;
2204} 2242}
2205 2243
2206void 2244void
@@ -2208,7 +2246,7 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2208 const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd, 2246 const char *term, struct termios *tiop, int in_fd, struct sshbuf *cmd,
2209 char **env) 2247 char **env)
2210{ 2248{
2211 int i, j, matched, len; 2249 int i, j, matched, len, r;
2212 char *name, *val; 2250 char *name, *val;
2213 Channel *c = NULL; 2251 Channel *c = NULL;
2214 2252
@@ -2217,7 +2255,7 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2217 if ((c = channel_lookup(ssh, id)) == NULL) 2255 if ((c = channel_lookup(ssh, id)) == NULL)
2218 fatal("%s: channel %d: unknown channel", __func__, id); 2256 fatal("%s: channel %d: unknown channel", __func__, id);
2219 2257
2220 packet_set_interactive(want_tty, 2258 ssh_packet_set_interactive(ssh, want_tty,
2221 options.ip_qos_interactive, options.ip_qos_bulk); 2259 options.ip_qos_interactive, options.ip_qos_bulk);
2222 2260
2223 if (want_tty) { 2261 if (want_tty) {
@@ -2229,15 +2267,18 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2229 2267
2230 channel_request_start(ssh, id, "pty-req", 1); 2268 channel_request_start(ssh, id, "pty-req", 1);
2231 client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY); 2269 client_expect_confirm(ssh, id, "PTY allocation", CONFIRM_TTY);
2232 packet_put_cstring(term != NULL ? term : ""); 2270 if ((r = sshpkt_put_cstring(ssh, term != NULL ? term : ""))
2233 packet_put_int((u_int)ws.ws_col); 2271 != 0 ||
2234 packet_put_int((u_int)ws.ws_row); 2272 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_col)) != 0 ||
2235 packet_put_int((u_int)ws.ws_xpixel); 2273 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_row)) != 0 ||
2236 packet_put_int((u_int)ws.ws_ypixel); 2274 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_xpixel)) != 0 ||
2275 (r = sshpkt_put_u32(ssh, (u_int)ws.ws_ypixel)) != 0)
2276 fatal("%s: build packet: %s", __func__, ssh_err(r));
2237 if (tiop == NULL) 2277 if (tiop == NULL)
2238 tiop = get_saved_tio(); 2278 tiop = get_saved_tio();
2239 ssh_tty_make_modes(ssh, -1, tiop); 2279 ssh_tty_make_modes(ssh, -1, tiop);
2240 packet_send(); 2280 if ((r = sshpkt_send(ssh)) != 0)
2281 fatal("%s: send packet: %s", __func__, ssh_err(r));
2241 /* XXX wait for reply */ 2282 /* XXX wait for reply */
2242 c->client_tty = 1; 2283 c->client_tty = 1;
2243 } 2284 }
@@ -2269,9 +2310,12 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2269 2310
2270 debug("Sending env %s = %s", name, val); 2311 debug("Sending env %s = %s", name, val);
2271 channel_request_start(ssh, id, "env", 0); 2312 channel_request_start(ssh, id, "env", 0);
2272 packet_put_cstring(name); 2313 if ((r = sshpkt_put_cstring(ssh, name)) != 0 ||
2273 packet_put_cstring(val); 2314 (r = sshpkt_put_cstring(ssh, val)) != 0 ||
2274 packet_send(); 2315 (r = sshpkt_send(ssh)) != 0) {
2316 fatal("%s: send packet: %s",
2317 __func__, ssh_err(r));
2318 }
2275 free(name); 2319 free(name);
2276 } 2320 }
2277 } 2321 }
@@ -2286,9 +2330,10 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2286 2330
2287 debug("Setting env %s = %s", name, val); 2331 debug("Setting env %s = %s", name, val);
2288 channel_request_start(ssh, id, "env", 0); 2332 channel_request_start(ssh, id, "env", 0);
2289 packet_put_cstring(name); 2333 if ((r = sshpkt_put_cstring(ssh, name)) != 0 ||
2290 packet_put_cstring(val); 2334 (r = sshpkt_put_cstring(ssh, val)) != 0 ||
2291 packet_send(); 2335 (r = sshpkt_send(ssh)) != 0)
2336 fatal("%s: send packet: %s", __func__, ssh_err(r));
2292 free(name); 2337 free(name);
2293 } 2338 }
2294 2339
@@ -2308,39 +2353,43 @@ client_session2_setup(struct ssh *ssh, int id, int want_tty, int want_subsystem,
2308 channel_request_start(ssh, id, "exec", 1); 2353 channel_request_start(ssh, id, "exec", 1);
2309 client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE); 2354 client_expect_confirm(ssh, id, "exec", CONFIRM_CLOSE);
2310 } 2355 }
2311 packet_put_string(sshbuf_ptr(cmd), sshbuf_len(cmd)); 2356 if ((r = sshpkt_put_stringb(ssh, cmd)) != 0 ||
2312 packet_send(); 2357 (r = sshpkt_send(ssh)) != 0)
2358 fatal("%s: send command: %s", __func__, ssh_err(r));
2313 } else { 2359 } else {
2314 channel_request_start(ssh, id, "shell", 1); 2360 channel_request_start(ssh, id, "shell", 1);
2315 client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE); 2361 client_expect_confirm(ssh, id, "shell", CONFIRM_CLOSE);
2316 packet_send(); 2362 if ((r = sshpkt_send(ssh)) != 0) {
2363 fatal("%s: send shell request: %s",
2364 __func__, ssh_err(r));
2365 }
2317 } 2366 }
2318} 2367}
2319 2368
2320static void 2369static void
2321client_init_dispatch(void) 2370client_init_dispatch(struct ssh *ssh)
2322{ 2371{
2323 dispatch_init(&dispatch_protocol_error); 2372 ssh_dispatch_init(ssh, &dispatch_protocol_error);
2324 2373
2325 dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); 2374 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
2326 dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); 2375 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data);
2327 dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); 2376 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
2328 dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); 2377 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
2329 dispatch_set(SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open); 2378 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &client_input_channel_open);
2330 dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 2379 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
2331 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 2380 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
2332 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req); 2381 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
2333 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 2382 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
2334 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); 2383 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm);
2335 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); 2384 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm);
2336 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request); 2385 ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
2337 2386
2338 /* rekeying */ 2387 /* rekeying */
2339 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 2388 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
2340 2389
2341 /* global request reply messages */ 2390 /* global request reply messages */
2342 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply); 2391 ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
2343 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply); 2392 ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
2344} 2393}
2345 2394
2346void 2395void