summaryrefslogtreecommitdiff
path: root/serverloop.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2019-01-19 21:40:48 +0000
committerDamien Miller <djm@mindrot.org>2019-01-20 09:45:17 +1100
commit7ec5cb4d15ed2f2c5c9f5d00e6b361d136fc1e2d (patch)
treeaa9adf28c7a89c64d8441b4d7f134095a4391ef9 /serverloop.c
parent64c9598ac05332d1327cbf55334dee4172d216c4 (diff)
upstream: convert serverloop.c to new packet API
with & ok markus@ OpenBSD-Commit-ID: c92dd19b55457541478f95c0d6b318426d86d885
Diffstat (limited to 'serverloop.c')
-rw-r--r--serverloop.c356
1 files changed, 204 insertions, 152 deletions
diff --git a/serverloop.c b/serverloop.c
index e0c26bbbc..c60758e88 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.210 2019/01/19 21:31:32 djm Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.211 2019/01/19 21:40:48 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
@@ -49,6 +49,7 @@
49#include <errno.h> 49#include <errno.h>
50#include <fcntl.h> 50#include <fcntl.h>
51#include <pwd.h> 51#include <pwd.h>
52#include <limits.h>
52#include <signal.h> 53#include <signal.h>
53#include <string.h> 54#include <string.h>
54#include <termios.h> 55#include <termios.h>
@@ -78,9 +79,6 @@
78#include "serverloop.h" 79#include "serverloop.h"
79#include "ssherr.h" 80#include "ssherr.h"
80 81
81#include "opacket.h" /* XXX */
82extern struct ssh *active_state; /* XXX */
83
84extern ServerOptions options; 82extern ServerOptions options;
85 83
86/* XXX */ 84/* XXX */
@@ -101,7 +99,7 @@ static volatile sig_atomic_t child_terminated = 0; /* The child has terminated.
101static volatile sig_atomic_t received_sigterm = 0; 99static volatile sig_atomic_t received_sigterm = 0;
102 100
103/* prototypes */ 101/* prototypes */
104static void server_init_dispatch(void); 102static void server_init_dispatch(struct ssh *);
105 103
106/* requested tunnel forwarding interface(s), shared with session.c */ 104/* requested tunnel forwarding interface(s), shared with session.c */
107char *tun_fwd_ifnames = NULL; 105char *tun_fwd_ifnames = NULL;
@@ -182,11 +180,12 @@ sigterm_handler(int sig)
182static void 180static void
183client_alive_check(struct ssh *ssh) 181client_alive_check(struct ssh *ssh)
184{ 182{
185 int channel_id;
186 char remote_id[512]; 183 char remote_id[512];
184 int r, channel_id;
187 185
188 /* timeout, check to see how many we have had */ 186 /* timeout, check to see how many we have had */
189 if (packet_inc_alive_timeouts() > options.client_alive_count_max) { 187 if (ssh_packet_inc_alive_timeouts(ssh) >
188 options.client_alive_count_max) {
190 sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); 189 sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
191 logit("Timeout, client not responding from %s", remote_id); 190 logit("Timeout, client not responding from %s", remote_id);
192 cleanup_exit(255); 191 cleanup_exit(255);
@@ -197,14 +196,17 @@ client_alive_check(struct ssh *ssh)
197 * we should get back a failure 196 * we should get back a failure
198 */ 197 */
199 if ((channel_id = channel_find_open(ssh)) == -1) { 198 if ((channel_id = channel_find_open(ssh)) == -1) {
200 packet_start(SSH2_MSG_GLOBAL_REQUEST); 199 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
201 packet_put_cstring("keepalive@openssh.com"); 200 (r = sshpkt_put_cstring(ssh, "keepalive@openssh.com"))
202 packet_put_char(1); /* boolean: want reply */ 201 != 0 ||
202 (r = sshpkt_put_u8(ssh, 1)) != 0) /* boolean: want reply */
203 fatal("%s: %s", __func__, ssh_err(r));
203 } else { 204 } else {
204 channel_request_start(ssh, channel_id, 205 channel_request_start(ssh, channel_id,
205 "keepalive@openssh.com", 1); 206 "keepalive@openssh.com", 1);
206 } 207 }
207 packet_send(); 208 if ((r = sshpkt_send(ssh)) != 0)
209 fatal("%s: %s", __func__, ssh_err(r));
208} 210}
209 211
210/* 212/*
@@ -261,14 +263,14 @@ wait_until_can_do_something(struct ssh *ssh,
261 * If we have buffered packet data going to the client, mark that 263 * If we have buffered packet data going to the client, mark that
262 * descriptor. 264 * descriptor.
263 */ 265 */
264 if (packet_have_data_to_write()) 266 if (ssh_packet_have_data_to_write(ssh))
265 FD_SET(connection_out, *writesetp); 267 FD_SET(connection_out, *writesetp);
266 268
267 /* 269 /*
268 * If child has terminated and there is enough buffer space to read 270 * If child has terminated and there is enough buffer space to read
269 * from it, then read as much as is available and exit. 271 * from it, then read as much as is available and exit.
270 */ 272 */
271 if (child_terminated && packet_not_very_much_data_to_write()) 273 if (child_terminated && ssh_packet_not_very_much_data_to_write(ssh))
272 if (max_time_ms == 0 || client_alive_scheduled) 274 if (max_time_ms == 0 || client_alive_scheduled)
273 max_time_ms = 100; 275 max_time_ms = 100;
274 276
@@ -312,7 +314,7 @@ wait_until_can_do_something(struct ssh *ssh,
312static int 314static int
313process_input(struct ssh *ssh, fd_set *readset, int connection_in) 315process_input(struct ssh *ssh, fd_set *readset, int connection_in)
314{ 316{
315 int len; 317 int r, len;
316 char buf[16384]; 318 char buf[16384];
317 319
318 /* Read and buffer any input data from the client. */ 320 /* Read and buffer any input data from the client. */
@@ -333,7 +335,10 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in)
333 } 335 }
334 } else { 336 } else {
335 /* Buffer any received data. */ 337 /* Buffer any received data. */
336 packet_process_incoming(buf, len); 338 if ((r = ssh_packet_process_incoming(ssh, buf, len))
339 != 0)
340 fatal("%s: ssh_packet_process_incoming: %s",
341 __func__, ssh_err(r));
337 } 342 }
338 } 343 }
339 return 0; 344 return 0;
@@ -343,11 +348,16 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in)
343 * Sends data from internal buffers to client program stdin. 348 * Sends data from internal buffers to client program stdin.
344 */ 349 */
345static void 350static void
346process_output(fd_set *writeset, int connection_out) 351process_output(struct ssh *ssh, fd_set *writeset, int connection_out)
347{ 352{
353 int r;
354
348 /* Send any buffered packet data to the client. */ 355 /* Send any buffered packet data to the client. */
349 if (FD_ISSET(connection_out, writeset)) 356 if (FD_ISSET(connection_out, writeset)) {
350 packet_write_poll(); 357 if ((r = ssh_packet_write_poll(ssh)) != 0)
358 fatal("%s: ssh_packet_write_poll: %s",
359 __func__, ssh_err(r));
360 }
351} 361}
352 362
353static void 363static void
@@ -390,8 +400,8 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
390 400
391 signal(SIGCHLD, sigchld_handler); 401 signal(SIGCHLD, sigchld_handler);
392 child_terminated = 0; 402 child_terminated = 0;
393 connection_in = packet_get_connection_in(); 403 connection_in = ssh_packet_get_connection_in(ssh);
394 connection_out = packet_get_connection_out(); 404 connection_out = ssh_packet_get_connection_out(ssh);
395 405
396 if (!use_privsep) { 406 if (!use_privsep) {
397 signal(SIGTERM, sigterm_handler); 407 signal(SIGTERM, sigterm_handler);
@@ -404,18 +414,21 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
404 max_fd = MAXIMUM(connection_in, connection_out); 414 max_fd = MAXIMUM(connection_in, connection_out);
405 max_fd = MAXIMUM(max_fd, notify_pipe[0]); 415 max_fd = MAXIMUM(max_fd, notify_pipe[0]);
406 416
407 server_init_dispatch(); 417 server_init_dispatch(ssh);
408 418
409 for (;;) { 419 for (;;) {
410 process_buffered_input_packets(ssh); 420 process_buffered_input_packets(ssh);
411 421
412 if (!ssh_packet_is_rekeying(ssh) && 422 if (!ssh_packet_is_rekeying(ssh) &&
413 packet_not_very_much_data_to_write()) 423 ssh_packet_not_very_much_data_to_write(ssh))
414 channel_output_poll(ssh); 424 channel_output_poll(ssh);
415 if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh)) 425 if (options.rekey_interval > 0 &&
416 rekey_timeout_ms = packet_get_rekey_timeout() * 1000; 426 !ssh_packet_is_rekeying(ssh)) {
417 else 427 rekey_timeout_ms = ssh_packet_get_rekey_timeout(ssh) *
428 1000;
429 } else {
418 rekey_timeout_ms = 0; 430 rekey_timeout_ms = 0;
431 }
419 432
420 wait_until_can_do_something(ssh, connection_in, connection_out, 433 wait_until_can_do_something(ssh, connection_in, connection_out,
421 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); 434 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
@@ -431,7 +444,7 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
431 channel_after_select(ssh, readset, writeset); 444 channel_after_select(ssh, readset, writeset);
432 if (process_input(ssh, readset, connection_in) < 0) 445 if (process_input(ssh, readset, connection_in) < 0)
433 break; 446 break;
434 process_output(writeset, connection_out); 447 process_output(ssh, writeset, connection_out);
435 } 448 }
436 collect_children(ssh); 449 collect_children(ssh);
437 450
@@ -454,7 +467,7 @@ server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
454 * even if this was generated by something other than 467 * even if this was generated by something other than
455 * the bogus CHANNEL_REQUEST we send for keepalives. 468 * the bogus CHANNEL_REQUEST we send for keepalives.
456 */ 469 */
457 packet_set_alive_timeouts(0); 470 ssh_packet_set_alive_timeouts(ssh, 0);
458 return 0; 471 return 0;
459} 472}
460 473
@@ -462,16 +475,28 @@ static Channel *
462server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg) 475server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
463{ 476{
464 Channel *c = NULL; 477 Channel *c = NULL;
465 char *target, *originator; 478 char *target = NULL, *originator = NULL;
466 u_short target_port, originator_port; 479 u_int target_port = 0, originator_port = 0;
467 480 int r;
468 target = packet_get_string(NULL); 481
469 target_port = packet_get_int(); 482 if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
470 originator = packet_get_string(NULL); 483 (r = sshpkt_get_u32(ssh, &target_port)) != 0 ||
471 originator_port = packet_get_int(); 484 (r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
472 packet_check_eom(); 485 (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
486 (r = sshpkt_get_end(ssh)) != 0)
487 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
488 if (target_port > 0xFFFF) {
489 error("%s: invalid target port", __func__);
490 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
491 goto out;
492 }
493 if (originator_port > 0xFFFF) {
494 error("%s: invalid originator port", __func__);
495 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
496 goto out;
497 }
473 498
474 debug("%s: originator %s port %d, target %s port %d", __func__, 499 debug("%s: originator %s port %u, target %s port %u", __func__,
475 originator, originator_port, target, target_port); 500 originator, originator_port, target, target_port);
476 501
477 /* XXX fine grained permissions */ 502 /* XXX fine grained permissions */
@@ -488,9 +513,9 @@ server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
488 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED; 513 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
489 } 514 }
490 515
516 out:
491 free(originator); 517 free(originator);
492 free(target); 518 free(target);
493
494 return c; 519 return c;
495} 520}
496 521
@@ -498,17 +523,23 @@ static Channel *
498server_request_direct_streamlocal(struct ssh *ssh) 523server_request_direct_streamlocal(struct ssh *ssh)
499{ 524{
500 Channel *c = NULL; 525 Channel *c = NULL;
501 char *target, *originator; 526 char *target = NULL, *originator = NULL;
502 u_short originator_port; 527 u_int originator_port = 0;
503 struct passwd *pw = the_authctxt->pw; 528 struct passwd *pw = the_authctxt->pw;
529 int r;
504 530
505 if (pw == NULL || !the_authctxt->valid) 531 if (pw == NULL || !the_authctxt->valid)
506 fatal("%s: no/invalid user", __func__); 532 fatal("%s: no/invalid user", __func__);
507 533
508 target = packet_get_string(NULL); 534 if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
509 originator = packet_get_string(NULL); 535 (r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
510 originator_port = packet_get_int(); 536 (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
511 packet_check_eom(); 537 (r = sshpkt_get_end(ssh)) != 0)
538 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
539 if (originator_port > 0xFFFF) {
540 error("%s: invalid originator port", __func__);
541 goto out;
542 }
512 543
513 debug("%s: originator %s port %d, target %s", __func__, 544 debug("%s: originator %s port %d, target %s", __func__,
514 originator, originator_port, target); 545 originator, originator_port, target);
@@ -525,9 +556,9 @@ server_request_direct_streamlocal(struct ssh *ssh)
525 originator, originator_port, target); 556 originator, originator_port, target);
526 } 557 }
527 558
559out:
528 free(originator); 560 free(originator);
529 free(target); 561 free(target);
530
531 return c; 562 return c;
532} 563}
533 564
@@ -535,27 +566,35 @@ static Channel *
535server_request_tun(struct ssh *ssh) 566server_request_tun(struct ssh *ssh)
536{ 567{
537 Channel *c = NULL; 568 Channel *c = NULL;
538 int mode, tun, sock; 569 u_int mode, tun;
570 int r, sock;
539 char *tmp, *ifname = NULL; 571 char *tmp, *ifname = NULL;
540 572
541 mode = packet_get_int(); 573 if ((r = sshpkt_get_u32(ssh, &mode)) != 0)
574 sshpkt_fatal(ssh, r, "%s: parse mode", __func__);
542 switch (mode) { 575 switch (mode) {
543 case SSH_TUNMODE_POINTOPOINT: 576 case SSH_TUNMODE_POINTOPOINT:
544 case SSH_TUNMODE_ETHERNET: 577 case SSH_TUNMODE_ETHERNET:
545 break; 578 break;
546 default: 579 default:
547 packet_send_debug("Unsupported tunnel device mode."); 580 ssh_packet_send_debug(ssh, "Unsupported tunnel device mode.");
548 return NULL; 581 return NULL;
549 } 582 }
550 if ((options.permit_tun & mode) == 0) { 583 if ((options.permit_tun & mode) == 0) {
551 packet_send_debug("Server has rejected tunnel device " 584 ssh_packet_send_debug(ssh, "Server has rejected tunnel device "
552 "forwarding"); 585 "forwarding");
553 return NULL; 586 return NULL;
554 } 587 }
555 588
556 tun = packet_get_int(); 589 if ((r = sshpkt_get_u32(ssh, &tun)) != 0)
590 sshpkt_fatal(ssh, r, "%s: parse device", __func__);
591 if (tun > INT_MAX) {
592 debug("%s: invalid tun", __func__);
593 goto done;
594 }
557 if (auth_opts->force_tun_device != -1) { 595 if (auth_opts->force_tun_device != -1) {
558 if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun) 596 if (tun != SSH_TUNID_ANY &&
597 auth_opts->force_tun_device != (int)tun)
559 goto done; 598 goto done;
560 tun = auth_opts->force_tun_device; 599 tun = auth_opts->force_tun_device;
561 } 600 }
@@ -588,7 +627,7 @@ server_request_tun(struct ssh *ssh)
588 627
589 done: 628 done:
590 if (c == NULL) 629 if (c == NULL)
591 packet_send_debug("Failed to open the tunnel device."); 630 ssh_packet_send_debug(ssh, "Failed to open the tunnel device.");
592 return c; 631 return c;
593} 632}
594 633
@@ -596,13 +635,15 @@ static Channel *
596server_request_session(struct ssh *ssh) 635server_request_session(struct ssh *ssh)
597{ 636{
598 Channel *c; 637 Channel *c;
638 int r;
599 639
600 debug("input_session_request"); 640 debug("input_session_request");
601 packet_check_eom(); 641 if ((r = sshpkt_get_end(ssh)) != 0)
642 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
602 643
603 if (no_more_sessions) { 644 if (no_more_sessions) {
604 packet_disconnect("Possible attack: attempt to open a session " 645 sshpkt_disconnect(ssh, "Possible attack: attempt to open a "
605 "after additional sessions disabled"); 646 "session after additional sessions disabled");
606 } 647 }
607 648
608 /* 649 /*
@@ -627,20 +668,22 @@ static int
627server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) 668server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
628{ 669{
629 Channel *c = NULL; 670 Channel *c = NULL;
630 char *ctype; 671 char *ctype = NULL;
631 const char *errmsg = NULL; 672 const char *errmsg = NULL;
632 int rchan, reason = SSH2_OPEN_CONNECT_FAILED; 673 int r, reason = SSH2_OPEN_CONNECT_FAILED;
633 u_int rmaxpack, rwindow, len; 674 u_int rchan = 0, rmaxpack = 0, rwindow = 0;
634 675
635 ctype = packet_get_string(&len); 676 if ((r = sshpkt_get_cstring(ssh, &ctype, NULL)) != 0 ||
636 rchan = packet_get_int(); 677 (r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
637 rwindow = packet_get_int(); 678 (r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
638 rmaxpack = packet_get_int(); 679 (r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
639 680 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
640 debug("%s: ctype %s rchan %d win %d max %d", __func__, 681 debug("%s: ctype %s rchan %u win %u max %u", __func__,
641 ctype, rchan, rwindow, rmaxpack); 682 ctype, rchan, rwindow, rmaxpack);
642 683
643 if (strcmp(ctype, "session") == 0) { 684 if (rchan > INT_MAX) {
685 error("%s: invalid remote channel ID", __func__);
686 } else if (strcmp(ctype, "session") == 0) {
644 c = server_request_session(ssh); 687 c = server_request_session(ssh);
645 } else if (strcmp(ctype, "direct-tcpip") == 0) { 688 } else if (strcmp(ctype, "direct-tcpip") == 0) {
646 c = server_request_direct_tcpip(ssh, &reason, &errmsg); 689 c = server_request_direct_tcpip(ssh, &reason, &errmsg);
@@ -651,26 +694,32 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
651 } 694 }
652 if (c != NULL) { 695 if (c != NULL) {
653 debug("%s: confirm %s", __func__, ctype); 696 debug("%s: confirm %s", __func__, ctype);
654 c->remote_id = rchan; 697 c->remote_id = (int)rchan;
655 c->have_remote_id = 1; 698 c->have_remote_id = 1;
656 c->remote_window = rwindow; 699 c->remote_window = rwindow;
657 c->remote_maxpacket = rmaxpack; 700 c->remote_maxpacket = rmaxpack;
658 if (c->type != SSH_CHANNEL_CONNECTING) { 701 if (c->type != SSH_CHANNEL_CONNECTING) {
659 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 702 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
660 packet_put_int(c->remote_id); 703 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
661 packet_put_int(c->self); 704 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
662 packet_put_int(c->local_window); 705 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
663 packet_put_int(c->local_maxpacket); 706 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
664 packet_send(); 707 (r = sshpkt_send(ssh)) != 0) {
708 sshpkt_fatal(ssh, r,
709 "%s: send open confirm", __func__);
710 }
665 } 711 }
666 } else { 712 } else {
667 debug("%s: failure %s", __func__, ctype); 713 debug("%s: failure %s", __func__, ctype);
668 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 714 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
669 packet_put_int(rchan); 715 (r = sshpkt_put_u32(ssh, rchan)) != 0 ||
670 packet_put_int(reason); 716 (r = sshpkt_put_u32(ssh, reason)) != 0 ||
671 packet_put_cstring(errmsg ? errmsg : "open failed"); 717 (r = sshpkt_put_cstring(ssh, errmsg ? errmsg : "open failed")) != 0 ||
672 packet_put_cstring(""); 718 (r = sshpkt_put_cstring(ssh, "")) != 0 ||
673 packet_send(); 719 (r = sshpkt_send(ssh)) != 0) {
720 sshpkt_fatal(ssh, r,
721 "%s: send open failure", __func__);
722 }
674 } 723 }
675 free(ctype); 724 free(ctype);
676 return 0; 725 return 0;
@@ -757,65 +806,66 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
757static int 806static int
758server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) 807server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
759{ 808{
760 char *rtype; 809 char *rtype = NULL;
761 int want_reply; 810 u_char want_reply = 0;
762 int r, success = 0, allocated_listen_port = 0; 811 int r, success = 0, allocated_listen_port = 0;
812 u_int port = 0;
763 struct sshbuf *resp = NULL; 813 struct sshbuf *resp = NULL;
764 struct passwd *pw = the_authctxt->pw; 814 struct passwd *pw = the_authctxt->pw;
815 struct Forward fwd;
765 816
817 memset(&fwd, 0, sizeof(fwd));
766 if (pw == NULL || !the_authctxt->valid) 818 if (pw == NULL || !the_authctxt->valid)
767 fatal("%s: no/invalid user", __func__); 819 fatal("%s: no/invalid user", __func__);
768 820
769 rtype = packet_get_string(NULL); 821 if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
770 want_reply = packet_get_char(); 822 (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
823 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
771 debug("%s: rtype %s want_reply %d", __func__, rtype, want_reply); 824 debug("%s: rtype %s want_reply %d", __func__, rtype, want_reply);
772 825
773 /* -R style forwarding */ 826 /* -R style forwarding */
774 if (strcmp(rtype, "tcpip-forward") == 0) { 827 if (strcmp(rtype, "tcpip-forward") == 0) {
775 struct Forward fwd; 828 if ((r = sshpkt_get_cstring(ssh, &fwd.listen_host, NULL)) != 0 ||
776 829 (r = sshpkt_get_u32(ssh, &port)) != 0)
777 memset(&fwd, 0, sizeof(fwd)); 830 sshpkt_fatal(ssh, r, "%s: parse tcpip-forward", __func__);
778 fwd.listen_host = packet_get_string(NULL); 831 debug("%s: tcpip-forward listen %s port %u", __func__,
779 fwd.listen_port = (u_short)packet_get_int(); 832 fwd.listen_host, port);
780 debug("%s: tcpip-forward listen %s port %d", __func__, 833 if (port <= INT_MAX)
781 fwd.listen_host, fwd.listen_port); 834 fwd.listen_port = (int)port;
782
783 /* check permissions */ 835 /* check permissions */
784 if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || 836 if (port > INT_MAX ||
837 (options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
785 !auth_opts->permit_port_forwarding_flag || 838 !auth_opts->permit_port_forwarding_flag ||
786 options.disable_forwarding || 839 options.disable_forwarding ||
787 (!want_reply && fwd.listen_port == 0) || 840 (!want_reply && fwd.listen_port == 0) ||
788 (fwd.listen_port != 0 && 841 (fwd.listen_port != 0 &&
789 !bind_permitted(fwd.listen_port, pw->pw_uid))) { 842 !bind_permitted(fwd.listen_port, pw->pw_uid))) {
790 success = 0; 843 success = 0;
791 packet_send_debug("Server has disabled port forwarding."); 844 ssh_packet_send_debug(ssh, "Server has disabled port forwarding.");
792 } else { 845 } else {
793 /* Start listening on the port */ 846 /* Start listening on the port */
794 success = channel_setup_remote_fwd_listener(ssh, &fwd, 847 success = channel_setup_remote_fwd_listener(ssh, &fwd,
795 &allocated_listen_port, &options.fwd_opts); 848 &allocated_listen_port, &options.fwd_opts);
796 } 849 }
797 free(fwd.listen_host);
798 if ((resp = sshbuf_new()) == NULL) 850 if ((resp = sshbuf_new()) == NULL)
799 fatal("%s: sshbuf_new", __func__); 851 fatal("%s: sshbuf_new", __func__);
800 if (allocated_listen_port != 0 && 852 if (allocated_listen_port != 0 &&
801 (r = sshbuf_put_u32(resp, allocated_listen_port)) != 0) 853 (r = sshbuf_put_u32(resp, allocated_listen_port)) != 0)
802 fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r)); 854 fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r));
803 } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { 855 } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
804 struct Forward fwd; 856 if ((r = sshpkt_get_cstring(ssh, &fwd.listen_host, NULL)) != 0 ||
857 (r = sshpkt_get_u32(ssh, &port)) != 0)
858 sshpkt_fatal(ssh, r, "%s: parse cancel-tcpip-forward", __func__);
805 859
806 memset(&fwd, 0, sizeof(fwd));
807 fwd.listen_host = packet_get_string(NULL);
808 fwd.listen_port = (u_short)packet_get_int();
809 debug("%s: cancel-tcpip-forward addr %s port %d", __func__, 860 debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
810 fwd.listen_host, fwd.listen_port); 861 fwd.listen_host, port);
811 862 if (port <= INT_MAX) {
812 success = channel_cancel_rport_listener(ssh, &fwd); 863 fwd.listen_port = (int)port;
813 free(fwd.listen_host); 864 success = channel_cancel_rport_listener(ssh, &fwd);
865 }
814 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { 866 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
815 struct Forward fwd; 867 if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
816 868 sshpkt_fatal(ssh, r, "%s: parse streamlocal-forward@openssh.com", __func__);
817 memset(&fwd, 0, sizeof(fwd));
818 fwd.listen_path = packet_get_string(NULL);
819 debug("%s: streamlocal-forward listen path %s", __func__, 869 debug("%s: streamlocal-forward listen path %s", __func__,
820 fwd.listen_path); 870 fwd.listen_path);
821 871
@@ -825,39 +875,37 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
825 options.disable_forwarding || 875 options.disable_forwarding ||
826 (pw->pw_uid != 0 && !use_privsep)) { 876 (pw->pw_uid != 0 && !use_privsep)) {
827 success = 0; 877 success = 0;
828 packet_send_debug("Server has disabled " 878 ssh_packet_send_debug(ssh, "Server has disabled "
829 "streamlocal forwarding."); 879 "streamlocal forwarding.");
830 } else { 880 } else {
831 /* Start listening on the socket */ 881 /* Start listening on the socket */
832 success = channel_setup_remote_fwd_listener(ssh, 882 success = channel_setup_remote_fwd_listener(ssh,
833 &fwd, NULL, &options.fwd_opts); 883 &fwd, NULL, &options.fwd_opts);
834 } 884 }
835 free(fwd.listen_path);
836 } else if (strcmp(rtype, "cancel-streamlocal-forward@openssh.com") == 0) { 885 } else if (strcmp(rtype, "cancel-streamlocal-forward@openssh.com") == 0) {
837 struct Forward fwd; 886 if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
838 887 sshpkt_fatal(ssh, r, "%s: parse cancel-streamlocal-forward@openssh.com", __func__);
839 memset(&fwd, 0, sizeof(fwd));
840 fwd.listen_path = packet_get_string(NULL);
841 debug("%s: cancel-streamlocal-forward path %s", __func__, 888 debug("%s: cancel-streamlocal-forward path %s", __func__,
842 fwd.listen_path); 889 fwd.listen_path);
843 890
844 success = channel_cancel_rport_listener(ssh, &fwd); 891 success = channel_cancel_rport_listener(ssh, &fwd);
845 free(fwd.listen_path);
846 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { 892 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
847 no_more_sessions = 1; 893 no_more_sessions = 1;
848 success = 1; 894 success = 1;
849 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { 895 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
850 success = server_input_hostkeys_prove(ssh, &resp); 896 success = server_input_hostkeys_prove(ssh, &resp);
851 } 897 }
898 /* XXX sshpkt_get_end() */
852 if (want_reply) { 899 if (want_reply) {
853 packet_start(success ? 900 if ((r = sshpkt_start(ssh, success ?
854 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 901 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE)) != 0 ||
855 if (success && resp != NULL) 902 (success && resp != NULL && (r = sshpkt_putb(ssh, resp)) != 0) ||
856 ssh_packet_put_raw(ssh, sshbuf_ptr(resp), 903 (r = sshpkt_send(ssh)) != 0 ||
857 sshbuf_len(resp)); 904 (r = ssh_packet_write_wait(ssh)) != 0)
858 packet_send(); 905 sshpkt_fatal(ssh, r, "%s: send reply", __func__);
859 packet_write_wait();
860 } 906 }
907 free(fwd.listen_host);
908 free(fwd.listen_path);
861 free(rtype); 909 free(rtype);
862 sshbuf_free(resp); 910 sshbuf_free(resp);
863 return 0; 911 return 0;
@@ -867,58 +915,62 @@ static int
867server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) 915server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
868{ 916{
869 Channel *c; 917 Channel *c;
870 int id, reply, success = 0; 918 int r, success = 0;
871 char *rtype; 919 char *rtype = NULL;
920 u_char want_reply = 0;
921 u_int id = 0;
872 922
873 id = packet_get_int(); 923 if ((r = sshpkt_get_u32(ssh, &id)) != 0 ||
874 rtype = packet_get_string(NULL); 924 (r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
875 reply = packet_get_char(); 925 (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
926 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
876 927
877 debug("server_input_channel_req: channel %d request %s reply %d", 928 debug("server_input_channel_req: channel %u request %s reply %d",
878 id, rtype, reply); 929 id, rtype, want_reply);
879 930
880 if ((c = channel_lookup(ssh, id)) == NULL) 931 if (id >= INT_MAX || (c = channel_lookup(ssh, (int)id)) == NULL)
881 packet_disconnect("server_input_channel_req: " 932 sshpkt_disconnect(ssh, "%s: unknown channel %d", __func__, id);
882 "unknown channel %d", id);
883 if (!strcmp(rtype, "eow@openssh.com")) { 933 if (!strcmp(rtype, "eow@openssh.com")) {
884 packet_check_eom(); 934 if ((r = sshpkt_get_end(ssh)) != 0)
935 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
885 chan_rcvd_eow(ssh, c); 936 chan_rcvd_eow(ssh, c);
886 } else if ((c->type == SSH_CHANNEL_LARVAL || 937 } else if ((c->type == SSH_CHANNEL_LARVAL ||
887 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) 938 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
888 success = session_input_channel_req(ssh, c, rtype); 939 success = session_input_channel_req(ssh, c, rtype);
889 if (reply && !(c->flags & CHAN_CLOSE_SENT)) { 940 if (want_reply && !(c->flags & CHAN_CLOSE_SENT)) {
890 if (!c->have_remote_id) 941 if (!c->have_remote_id)
891 fatal("%s: channel %d: no remote_id", 942 fatal("%s: channel %d: no remote_id",
892 __func__, c->self); 943 __func__, c->self);
893 packet_start(success ? 944 if ((r = sshpkt_start(ssh, success ?
894 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 945 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
895 packet_put_int(c->remote_id); 946 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
896 packet_send(); 947 (r = sshpkt_send(ssh)) != 0)
948 sshpkt_fatal(ssh, r, "%s: send reply", __func__);
897 } 949 }
898 free(rtype); 950 free(rtype);
899 return 0; 951 return 0;
900} 952}
901 953
902static void 954static void
903server_init_dispatch(void) 955server_init_dispatch(struct ssh *ssh)
904{ 956{
905 debug("server_init_dispatch"); 957 debug("server_init_dispatch");
906 dispatch_init(&dispatch_protocol_error); 958 ssh_dispatch_init(ssh, &dispatch_protocol_error);
907 dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); 959 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
908 dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); 960 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data);
909 dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); 961 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
910 dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); 962 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
911 dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open); 963 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open);
912 dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 964 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
913 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 965 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
914 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req); 966 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
915 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 967 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
916 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request); 968 ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
917 /* client_alive */ 969 /* client_alive */
918 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive); 970 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive);
919 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive); 971 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
920 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive); 972 ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
921 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive); 973 ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
922 /* rekeying */ 974 /* rekeying */
923 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 975 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
924} 976}