summaryrefslogtreecommitdiff
path: root/serverloop.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 /serverloop.c
parent3d246f10429fc9a37b98eabef94fe8dc7c61002b (diff)
parentfd0fa130ecf06d7d092932adcd5d77f1549bfc8d (diff)
Import openssh_8.0p1.orig.tar.gz
Diffstat (limited to 'serverloop.c')
-rw-r--r--serverloop.c383
1 files changed, 222 insertions, 161 deletions
diff --git a/serverloop.c b/serverloop.c
index 7be83e2d3..d7b04b37c 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.209 2018/07/27 05:13:02 dtucker Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.215 2019/03/27 09:29:14 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>
@@ -98,7 +99,7 @@ static volatile sig_atomic_t child_terminated = 0; /* The child has terminated.
98static volatile sig_atomic_t received_sigterm = 0; 99static volatile sig_atomic_t received_sigterm = 0;
99 100
100/* prototypes */ 101/* prototypes */
101static void server_init_dispatch(void); 102static void server_init_dispatch(struct ssh *);
102 103
103/* requested tunnel forwarding interface(s), shared with session.c */ 104/* requested tunnel forwarding interface(s), shared with session.c */
104char *tun_fwd_ifnames = NULL; 105char *tun_fwd_ifnames = NULL;
@@ -179,11 +180,12 @@ sigterm_handler(int sig)
179static void 180static void
180client_alive_check(struct ssh *ssh) 181client_alive_check(struct ssh *ssh)
181{ 182{
182 int channel_id;
183 char remote_id[512]; 183 char remote_id[512];
184 int r, channel_id;
184 185
185 /* timeout, check to see how many we have had */ 186 /* timeout, check to see how many we have had */
186 if (packet_inc_alive_timeouts() > options.client_alive_count_max) { 187 if (ssh_packet_inc_alive_timeouts(ssh) >
188 options.client_alive_count_max) {
187 sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); 189 sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
188 logit("Timeout, client not responding from %s", remote_id); 190 logit("Timeout, client not responding from %s", remote_id);
189 cleanup_exit(255); 191 cleanup_exit(255);
@@ -194,14 +196,17 @@ client_alive_check(struct ssh *ssh)
194 * we should get back a failure 196 * we should get back a failure
195 */ 197 */
196 if ((channel_id = channel_find_open(ssh)) == -1) { 198 if ((channel_id = channel_find_open(ssh)) == -1) {
197 packet_start(SSH2_MSG_GLOBAL_REQUEST); 199 if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
198 packet_put_cstring("keepalive@openssh.com"); 200 (r = sshpkt_put_cstring(ssh, "keepalive@openssh.com"))
199 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));
200 } else { 204 } else {
201 channel_request_start(ssh, channel_id, 205 channel_request_start(ssh, channel_id,
202 "keepalive@openssh.com", 1); 206 "keepalive@openssh.com", 1);
203 } 207 }
204 packet_send(); 208 if ((r = sshpkt_send(ssh)) != 0)
209 fatal("%s: %s", __func__, ssh_err(r));
205} 210}
206 211
207/* 212/*
@@ -220,6 +225,7 @@ wait_until_can_do_something(struct ssh *ssh,
220 int ret; 225 int ret;
221 time_t minwait_secs = 0; 226 time_t minwait_secs = 0;
222 int client_alive_scheduled = 0; 227 int client_alive_scheduled = 0;
228 /* time we last heard from the client OR sent a keepalive */
223 static time_t last_client_time; 229 static time_t last_client_time;
224 230
225 /* Allocate and update select() masks for channel descriptors. */ 231 /* Allocate and update select() masks for channel descriptors. */
@@ -242,9 +248,10 @@ wait_until_can_do_something(struct ssh *ssh,
242 uint64_t keepalive_ms = 248 uint64_t keepalive_ms =
243 (uint64_t)options.client_alive_interval * 1000; 249 (uint64_t)options.client_alive_interval * 1000;
244 250
245 client_alive_scheduled = 1; 251 if (max_time_ms == 0 || max_time_ms > keepalive_ms) {
246 if (max_time_ms == 0 || max_time_ms > keepalive_ms)
247 max_time_ms = keepalive_ms; 252 max_time_ms = keepalive_ms;
253 client_alive_scheduled = 1;
254 }
248 } 255 }
249 256
250#if 0 257#if 0
@@ -258,14 +265,14 @@ wait_until_can_do_something(struct ssh *ssh,
258 * If we have buffered packet data going to the client, mark that 265 * If we have buffered packet data going to the client, mark that
259 * descriptor. 266 * descriptor.
260 */ 267 */
261 if (packet_have_data_to_write()) 268 if (ssh_packet_have_data_to_write(ssh))
262 FD_SET(connection_out, *writesetp); 269 FD_SET(connection_out, *writesetp);
263 270
264 /* 271 /*
265 * If child has terminated and there is enough buffer space to read 272 * If child has terminated and there is enough buffer space to read
266 * from it, then read as much as is available and exit. 273 * from it, then read as much as is available and exit.
267 */ 274 */
268 if (child_terminated && packet_not_very_much_data_to_write()) 275 if (child_terminated && ssh_packet_not_very_much_data_to_write(ssh))
269 if (max_time_ms == 0 || client_alive_scheduled) 276 if (max_time_ms == 0 || client_alive_scheduled)
270 max_time_ms = 100; 277 max_time_ms = 100;
271 278
@@ -288,13 +295,15 @@ wait_until_can_do_something(struct ssh *ssh,
288 } else if (client_alive_scheduled) { 295 } else if (client_alive_scheduled) {
289 time_t now = monotime(); 296 time_t now = monotime();
290 297
291 if (ret == 0) { /* timeout */ 298 /*
299 * If the select timed out, or returned for some other reason
300 * but we haven't heard from the client in time, send keepalive.
301 */
302 if (ret == 0 || (last_client_time != 0 && last_client_time +
303 options.client_alive_interval <= now)) {
292 client_alive_check(ssh); 304 client_alive_check(ssh);
293 } else if (FD_ISSET(connection_in, *readsetp)) {
294 last_client_time = now; 305 last_client_time = now;
295 } else if (last_client_time != 0 && last_client_time + 306 } else if (FD_ISSET(connection_in, *readsetp)) {
296 options.client_alive_interval <= now) {
297 client_alive_check(ssh);
298 last_client_time = now; 307 last_client_time = now;
299 } 308 }
300 } 309 }
@@ -309,7 +318,7 @@ wait_until_can_do_something(struct ssh *ssh,
309static int 318static int
310process_input(struct ssh *ssh, fd_set *readset, int connection_in) 319process_input(struct ssh *ssh, fd_set *readset, int connection_in)
311{ 320{
312 int len; 321 int r, len;
313 char buf[16384]; 322 char buf[16384];
314 323
315 /* Read and buffer any input data from the client. */ 324 /* Read and buffer any input data from the client. */
@@ -330,7 +339,10 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in)
330 } 339 }
331 } else { 340 } else {
332 /* Buffer any received data. */ 341 /* Buffer any received data. */
333 packet_process_incoming(buf, len); 342 if ((r = ssh_packet_process_incoming(ssh, buf, len))
343 != 0)
344 fatal("%s: ssh_packet_process_incoming: %s",
345 __func__, ssh_err(r));
334 } 346 }
335 } 347 }
336 return 0; 348 return 0;
@@ -340,11 +352,16 @@ process_input(struct ssh *ssh, fd_set *readset, int connection_in)
340 * Sends data from internal buffers to client program stdin. 352 * Sends data from internal buffers to client program stdin.
341 */ 353 */
342static void 354static void
343process_output(fd_set *writeset, int connection_out) 355process_output(struct ssh *ssh, fd_set *writeset, int connection_out)
344{ 356{
357 int r;
358
345 /* Send any buffered packet data to the client. */ 359 /* Send any buffered packet data to the client. */
346 if (FD_ISSET(connection_out, writeset)) 360 if (FD_ISSET(connection_out, writeset)) {
347 packet_write_poll(); 361 if ((r = ssh_packet_write_poll(ssh)) != 0)
362 fatal("%s: ssh_packet_write_poll: %s",
363 __func__, ssh_err(r));
364 }
348} 365}
349 366
350static void 367static void
@@ -387,8 +404,8 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
387 404
388 signal(SIGCHLD, sigchld_handler); 405 signal(SIGCHLD, sigchld_handler);
389 child_terminated = 0; 406 child_terminated = 0;
390 connection_in = packet_get_connection_in(); 407 connection_in = ssh_packet_get_connection_in(ssh);
391 connection_out = packet_get_connection_out(); 408 connection_out = ssh_packet_get_connection_out(ssh);
392 409
393 if (!use_privsep) { 410 if (!use_privsep) {
394 signal(SIGTERM, sigterm_handler); 411 signal(SIGTERM, sigterm_handler);
@@ -401,18 +418,21 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
401 max_fd = MAXIMUM(connection_in, connection_out); 418 max_fd = MAXIMUM(connection_in, connection_out);
402 max_fd = MAXIMUM(max_fd, notify_pipe[0]); 419 max_fd = MAXIMUM(max_fd, notify_pipe[0]);
403 420
404 server_init_dispatch(); 421 server_init_dispatch(ssh);
405 422
406 for (;;) { 423 for (;;) {
407 process_buffered_input_packets(ssh); 424 process_buffered_input_packets(ssh);
408 425
409 if (!ssh_packet_is_rekeying(ssh) && 426 if (!ssh_packet_is_rekeying(ssh) &&
410 packet_not_very_much_data_to_write()) 427 ssh_packet_not_very_much_data_to_write(ssh))
411 channel_output_poll(ssh); 428 channel_output_poll(ssh);
412 if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh)) 429 if (options.rekey_interval > 0 &&
413 rekey_timeout_ms = packet_get_rekey_timeout() * 1000; 430 !ssh_packet_is_rekeying(ssh)) {
414 else 431 rekey_timeout_ms = ssh_packet_get_rekey_timeout(ssh) *
432 1000;
433 } else {
415 rekey_timeout_ms = 0; 434 rekey_timeout_ms = 0;
435 }
416 436
417 wait_until_can_do_something(ssh, connection_in, connection_out, 437 wait_until_can_do_something(ssh, connection_in, connection_out,
418 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); 438 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
@@ -428,7 +448,7 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt)
428 channel_after_select(ssh, readset, writeset); 448 channel_after_select(ssh, readset, writeset);
429 if (process_input(ssh, readset, connection_in) < 0) 449 if (process_input(ssh, readset, connection_in) < 0)
430 break; 450 break;
431 process_output(writeset, connection_out); 451 process_output(ssh, writeset, connection_out);
432 } 452 }
433 collect_children(ssh); 453 collect_children(ssh);
434 454
@@ -451,7 +471,7 @@ server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
451 * even if this was generated by something other than 471 * even if this was generated by something other than
452 * the bogus CHANNEL_REQUEST we send for keepalives. 472 * the bogus CHANNEL_REQUEST we send for keepalives.
453 */ 473 */
454 packet_set_alive_timeouts(0); 474 ssh_packet_set_alive_timeouts(ssh, 0);
455 return 0; 475 return 0;
456} 476}
457 477
@@ -459,16 +479,28 @@ static Channel *
459server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg) 479server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
460{ 480{
461 Channel *c = NULL; 481 Channel *c = NULL;
462 char *target, *originator; 482 char *target = NULL, *originator = NULL;
463 u_short target_port, originator_port; 483 u_int target_port = 0, originator_port = 0;
464 484 int r;
465 target = packet_get_string(NULL); 485
466 target_port = packet_get_int(); 486 if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
467 originator = packet_get_string(NULL); 487 (r = sshpkt_get_u32(ssh, &target_port)) != 0 ||
468 originator_port = packet_get_int(); 488 (r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
469 packet_check_eom(); 489 (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
490 (r = sshpkt_get_end(ssh)) != 0)
491 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
492 if (target_port > 0xFFFF) {
493 error("%s: invalid target port", __func__);
494 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
495 goto out;
496 }
497 if (originator_port > 0xFFFF) {
498 error("%s: invalid originator port", __func__);
499 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
500 goto out;
501 }
470 502
471 debug("%s: originator %s port %d, target %s port %d", __func__, 503 debug("%s: originator %s port %u, target %s port %u", __func__,
472 originator, originator_port, target, target_port); 504 originator, originator_port, target, target_port);
473 505
474 /* XXX fine grained permissions */ 506 /* XXX fine grained permissions */
@@ -485,9 +517,9 @@ server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
485 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED; 517 *reason = SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED;
486 } 518 }
487 519
520 out:
488 free(originator); 521 free(originator);
489 free(target); 522 free(target);
490
491 return c; 523 return c;
492} 524}
493 525
@@ -495,17 +527,23 @@ static Channel *
495server_request_direct_streamlocal(struct ssh *ssh) 527server_request_direct_streamlocal(struct ssh *ssh)
496{ 528{
497 Channel *c = NULL; 529 Channel *c = NULL;
498 char *target, *originator; 530 char *target = NULL, *originator = NULL;
499 u_short originator_port; 531 u_int originator_port = 0;
500 struct passwd *pw = the_authctxt->pw; 532 struct passwd *pw = the_authctxt->pw;
533 int r;
501 534
502 if (pw == NULL || !the_authctxt->valid) 535 if (pw == NULL || !the_authctxt->valid)
503 fatal("%s: no/invalid user", __func__); 536 fatal("%s: no/invalid user", __func__);
504 537
505 target = packet_get_string(NULL); 538 if ((r = sshpkt_get_cstring(ssh, &target, NULL)) != 0 ||
506 originator = packet_get_string(NULL); 539 (r = sshpkt_get_cstring(ssh, &originator, NULL)) != 0 ||
507 originator_port = packet_get_int(); 540 (r = sshpkt_get_u32(ssh, &originator_port)) != 0 ||
508 packet_check_eom(); 541 (r = sshpkt_get_end(ssh)) != 0)
542 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
543 if (originator_port > 0xFFFF) {
544 error("%s: invalid originator port", __func__);
545 goto out;
546 }
509 547
510 debug("%s: originator %s port %d, target %s", __func__, 548 debug("%s: originator %s port %d, target %s", __func__,
511 originator, originator_port, target); 549 originator, originator_port, target);
@@ -522,9 +560,9 @@ server_request_direct_streamlocal(struct ssh *ssh)
522 originator, originator_port, target); 560 originator, originator_port, target);
523 } 561 }
524 562
563out:
525 free(originator); 564 free(originator);
526 free(target); 565 free(target);
527
528 return c; 566 return c;
529} 567}
530 568
@@ -532,27 +570,35 @@ static Channel *
532server_request_tun(struct ssh *ssh) 570server_request_tun(struct ssh *ssh)
533{ 571{
534 Channel *c = NULL; 572 Channel *c = NULL;
535 int mode, tun, sock; 573 u_int mode, tun;
574 int r, sock;
536 char *tmp, *ifname = NULL; 575 char *tmp, *ifname = NULL;
537 576
538 mode = packet_get_int(); 577 if ((r = sshpkt_get_u32(ssh, &mode)) != 0)
578 sshpkt_fatal(ssh, r, "%s: parse mode", __func__);
539 switch (mode) { 579 switch (mode) {
540 case SSH_TUNMODE_POINTOPOINT: 580 case SSH_TUNMODE_POINTOPOINT:
541 case SSH_TUNMODE_ETHERNET: 581 case SSH_TUNMODE_ETHERNET:
542 break; 582 break;
543 default: 583 default:
544 packet_send_debug("Unsupported tunnel device mode."); 584 ssh_packet_send_debug(ssh, "Unsupported tunnel device mode.");
545 return NULL; 585 return NULL;
546 } 586 }
547 if ((options.permit_tun & mode) == 0) { 587 if ((options.permit_tun & mode) == 0) {
548 packet_send_debug("Server has rejected tunnel device " 588 ssh_packet_send_debug(ssh, "Server has rejected tunnel device "
549 "forwarding"); 589 "forwarding");
550 return NULL; 590 return NULL;
551 } 591 }
552 592
553 tun = packet_get_int(); 593 if ((r = sshpkt_get_u32(ssh, &tun)) != 0)
594 sshpkt_fatal(ssh, r, "%s: parse device", __func__);
595 if (tun > INT_MAX) {
596 debug("%s: invalid tun", __func__);
597 goto done;
598 }
554 if (auth_opts->force_tun_device != -1) { 599 if (auth_opts->force_tun_device != -1) {
555 if (tun != SSH_TUNID_ANY && auth_opts->force_tun_device != tun) 600 if (tun != SSH_TUNID_ANY &&
601 auth_opts->force_tun_device != (int)tun)
556 goto done; 602 goto done;
557 tun = auth_opts->force_tun_device; 603 tun = auth_opts->force_tun_device;
558 } 604 }
@@ -585,7 +631,7 @@ server_request_tun(struct ssh *ssh)
585 631
586 done: 632 done:
587 if (c == NULL) 633 if (c == NULL)
588 packet_send_debug("Failed to open the tunnel device."); 634 ssh_packet_send_debug(ssh, "Failed to open the tunnel device.");
589 return c; 635 return c;
590} 636}
591 637
@@ -593,13 +639,15 @@ static Channel *
593server_request_session(struct ssh *ssh) 639server_request_session(struct ssh *ssh)
594{ 640{
595 Channel *c; 641 Channel *c;
642 int r;
596 643
597 debug("input_session_request"); 644 debug("input_session_request");
598 packet_check_eom(); 645 if ((r = sshpkt_get_end(ssh)) != 0)
646 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
599 647
600 if (no_more_sessions) { 648 if (no_more_sessions) {
601 packet_disconnect("Possible attack: attempt to open a session " 649 ssh_packet_disconnect(ssh, "Possible attack: attempt to open a "
602 "after additional sessions disabled"); 650 "session after additional sessions disabled");
603 } 651 }
604 652
605 /* 653 /*
@@ -624,20 +672,22 @@ static int
624server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) 672server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
625{ 673{
626 Channel *c = NULL; 674 Channel *c = NULL;
627 char *ctype; 675 char *ctype = NULL;
628 const char *errmsg = NULL; 676 const char *errmsg = NULL;
629 int rchan, reason = SSH2_OPEN_CONNECT_FAILED; 677 int r, reason = SSH2_OPEN_CONNECT_FAILED;
630 u_int rmaxpack, rwindow, len; 678 u_int rchan = 0, rmaxpack = 0, rwindow = 0;
631 679
632 ctype = packet_get_string(&len); 680 if ((r = sshpkt_get_cstring(ssh, &ctype, NULL)) != 0 ||
633 rchan = packet_get_int(); 681 (r = sshpkt_get_u32(ssh, &rchan)) != 0 ||
634 rwindow = packet_get_int(); 682 (r = sshpkt_get_u32(ssh, &rwindow)) != 0 ||
635 rmaxpack = packet_get_int(); 683 (r = sshpkt_get_u32(ssh, &rmaxpack)) != 0)
636 684 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
637 debug("%s: ctype %s rchan %d win %d max %d", __func__, 685 debug("%s: ctype %s rchan %u win %u max %u", __func__,
638 ctype, rchan, rwindow, rmaxpack); 686 ctype, rchan, rwindow, rmaxpack);
639 687
640 if (strcmp(ctype, "session") == 0) { 688 if (rchan > INT_MAX) {
689 error("%s: invalid remote channel ID", __func__);
690 } else if (strcmp(ctype, "session") == 0) {
641 c = server_request_session(ssh); 691 c = server_request_session(ssh);
642 } else if (strcmp(ctype, "direct-tcpip") == 0) { 692 } else if (strcmp(ctype, "direct-tcpip") == 0) {
643 c = server_request_direct_tcpip(ssh, &reason, &errmsg); 693 c = server_request_direct_tcpip(ssh, &reason, &errmsg);
@@ -648,26 +698,32 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
648 } 698 }
649 if (c != NULL) { 699 if (c != NULL) {
650 debug("%s: confirm %s", __func__, ctype); 700 debug("%s: confirm %s", __func__, ctype);
651 c->remote_id = rchan; 701 c->remote_id = (int)rchan;
652 c->have_remote_id = 1; 702 c->have_remote_id = 1;
653 c->remote_window = rwindow; 703 c->remote_window = rwindow;
654 c->remote_maxpacket = rmaxpack; 704 c->remote_maxpacket = rmaxpack;
655 if (c->type != SSH_CHANNEL_CONNECTING) { 705 if (c->type != SSH_CHANNEL_CONNECTING) {
656 packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION); 706 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION)) != 0 ||
657 packet_put_int(c->remote_id); 707 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
658 packet_put_int(c->self); 708 (r = sshpkt_put_u32(ssh, c->self)) != 0 ||
659 packet_put_int(c->local_window); 709 (r = sshpkt_put_u32(ssh, c->local_window)) != 0 ||
660 packet_put_int(c->local_maxpacket); 710 (r = sshpkt_put_u32(ssh, c->local_maxpacket)) != 0 ||
661 packet_send(); 711 (r = sshpkt_send(ssh)) != 0) {
712 sshpkt_fatal(ssh, r,
713 "%s: send open confirm", __func__);
714 }
662 } 715 }
663 } else { 716 } else {
664 debug("%s: failure %s", __func__, ctype); 717 debug("%s: failure %s", __func__, ctype);
665 packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE); 718 if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE)) != 0 ||
666 packet_put_int(rchan); 719 (r = sshpkt_put_u32(ssh, rchan)) != 0 ||
667 packet_put_int(reason); 720 (r = sshpkt_put_u32(ssh, reason)) != 0 ||
668 packet_put_cstring(errmsg ? errmsg : "open failed"); 721 (r = sshpkt_put_cstring(ssh, errmsg ? errmsg : "open failed")) != 0 ||
669 packet_put_cstring(""); 722 (r = sshpkt_put_cstring(ssh, "")) != 0 ||
670 packet_send(); 723 (r = sshpkt_send(ssh)) != 0) {
724 sshpkt_fatal(ssh, r,
725 "%s: send open failure", __func__);
726 }
671 } 727 }
672 free(ctype); 728 free(ctype);
673 return 0; 729 return 0;
@@ -730,9 +786,9 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
730 (r = sshbuf_put_string(sigbuf, 786 (r = sshbuf_put_string(sigbuf,
731 ssh->kex->session_id, ssh->kex->session_id_len)) != 0 || 787 ssh->kex->session_id, ssh->kex->session_id_len)) != 0 ||
732 (r = sshkey_puts(key, sigbuf)) != 0 || 788 (r = sshkey_puts(key, sigbuf)) != 0 ||
733 (r = ssh->kex->sign(key_prv, key_pub, &sig, &slen, 789 (r = ssh->kex->sign(ssh, key_prv, key_pub, &sig, &slen,
734 sshbuf_ptr(sigbuf), sshbuf_len(sigbuf), 790 sshbuf_ptr(sigbuf), sshbuf_len(sigbuf),
735 use_kexsigtype ? ssh->kex->hostkey_alg : NULL, 0)) != 0 || 791 use_kexsigtype ? ssh->kex->hostkey_alg : NULL)) != 0 ||
736 (r = sshbuf_put_string(resp, sig, slen)) != 0) { 792 (r = sshbuf_put_string(resp, sig, slen)) != 0) {
737 error("%s: couldn't prepare signature: %s", 793 error("%s: couldn't prepare signature: %s",
738 __func__, ssh_err(r)); 794 __func__, ssh_err(r));
@@ -754,65 +810,66 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
754static int 810static int
755server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) 811server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
756{ 812{
757 char *rtype; 813 char *rtype = NULL;
758 int want_reply; 814 u_char want_reply = 0;
759 int r, success = 0, allocated_listen_port = 0; 815 int r, success = 0, allocated_listen_port = 0;
816 u_int port = 0;
760 struct sshbuf *resp = NULL; 817 struct sshbuf *resp = NULL;
761 struct passwd *pw = the_authctxt->pw; 818 struct passwd *pw = the_authctxt->pw;
819 struct Forward fwd;
762 820
821 memset(&fwd, 0, sizeof(fwd));
763 if (pw == NULL || !the_authctxt->valid) 822 if (pw == NULL || !the_authctxt->valid)
764 fatal("%s: no/invalid user", __func__); 823 fatal("%s: no/invalid user", __func__);
765 824
766 rtype = packet_get_string(NULL); 825 if ((r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
767 want_reply = packet_get_char(); 826 (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
827 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
768 debug("%s: rtype %s want_reply %d", __func__, rtype, want_reply); 828 debug("%s: rtype %s want_reply %d", __func__, rtype, want_reply);
769 829
770 /* -R style forwarding */ 830 /* -R style forwarding */
771 if (strcmp(rtype, "tcpip-forward") == 0) { 831 if (strcmp(rtype, "tcpip-forward") == 0) {
772 struct Forward fwd; 832 if ((r = sshpkt_get_cstring(ssh, &fwd.listen_host, NULL)) != 0 ||
773 833 (r = sshpkt_get_u32(ssh, &port)) != 0)
774 memset(&fwd, 0, sizeof(fwd)); 834 sshpkt_fatal(ssh, r, "%s: parse tcpip-forward", __func__);
775 fwd.listen_host = packet_get_string(NULL); 835 debug("%s: tcpip-forward listen %s port %u", __func__,
776 fwd.listen_port = (u_short)packet_get_int(); 836 fwd.listen_host, port);
777 debug("%s: tcpip-forward listen %s port %d", __func__, 837 if (port <= INT_MAX)
778 fwd.listen_host, fwd.listen_port); 838 fwd.listen_port = (int)port;
779
780 /* check permissions */ 839 /* check permissions */
781 if ((options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || 840 if (port > INT_MAX ||
841 (options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 ||
782 !auth_opts->permit_port_forwarding_flag || 842 !auth_opts->permit_port_forwarding_flag ||
783 options.disable_forwarding || 843 options.disable_forwarding ||
784 (!want_reply && fwd.listen_port == 0) || 844 (!want_reply && fwd.listen_port == 0) ||
785 (fwd.listen_port != 0 && 845 (fwd.listen_port != 0 &&
786 !bind_permitted(fwd.listen_port, pw->pw_uid))) { 846 !bind_permitted(fwd.listen_port, pw->pw_uid))) {
787 success = 0; 847 success = 0;
788 packet_send_debug("Server has disabled port forwarding."); 848 ssh_packet_send_debug(ssh, "Server has disabled port forwarding.");
789 } else { 849 } else {
790 /* Start listening on the port */ 850 /* Start listening on the port */
791 success = channel_setup_remote_fwd_listener(ssh, &fwd, 851 success = channel_setup_remote_fwd_listener(ssh, &fwd,
792 &allocated_listen_port, &options.fwd_opts); 852 &allocated_listen_port, &options.fwd_opts);
793 } 853 }
794 free(fwd.listen_host);
795 if ((resp = sshbuf_new()) == NULL) 854 if ((resp = sshbuf_new()) == NULL)
796 fatal("%s: sshbuf_new", __func__); 855 fatal("%s: sshbuf_new", __func__);
797 if (allocated_listen_port != 0 && 856 if (allocated_listen_port != 0 &&
798 (r = sshbuf_put_u32(resp, allocated_listen_port)) != 0) 857 (r = sshbuf_put_u32(resp, allocated_listen_port)) != 0)
799 fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r)); 858 fatal("%s: sshbuf_put_u32: %s", __func__, ssh_err(r));
800 } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { 859 } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) {
801 struct Forward fwd; 860 if ((r = sshpkt_get_cstring(ssh, &fwd.listen_host, NULL)) != 0 ||
861 (r = sshpkt_get_u32(ssh, &port)) != 0)
862 sshpkt_fatal(ssh, r, "%s: parse cancel-tcpip-forward", __func__);
802 863
803 memset(&fwd, 0, sizeof(fwd));
804 fwd.listen_host = packet_get_string(NULL);
805 fwd.listen_port = (u_short)packet_get_int();
806 debug("%s: cancel-tcpip-forward addr %s port %d", __func__, 864 debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
807 fwd.listen_host, fwd.listen_port); 865 fwd.listen_host, port);
808 866 if (port <= INT_MAX) {
809 success = channel_cancel_rport_listener(ssh, &fwd); 867 fwd.listen_port = (int)port;
810 free(fwd.listen_host); 868 success = channel_cancel_rport_listener(ssh, &fwd);
869 }
811 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { 870 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
812 struct Forward fwd; 871 if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
813 872 sshpkt_fatal(ssh, r, "%s: parse streamlocal-forward@openssh.com", __func__);
814 memset(&fwd, 0, sizeof(fwd));
815 fwd.listen_path = packet_get_string(NULL);
816 debug("%s: streamlocal-forward listen path %s", __func__, 873 debug("%s: streamlocal-forward listen path %s", __func__,
817 fwd.listen_path); 874 fwd.listen_path);
818 875
@@ -822,39 +879,37 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
822 options.disable_forwarding || 879 options.disable_forwarding ||
823 (pw->pw_uid != 0 && !use_privsep)) { 880 (pw->pw_uid != 0 && !use_privsep)) {
824 success = 0; 881 success = 0;
825 packet_send_debug("Server has disabled " 882 ssh_packet_send_debug(ssh, "Server has disabled "
826 "streamlocal forwarding."); 883 "streamlocal forwarding.");
827 } else { 884 } else {
828 /* Start listening on the socket */ 885 /* Start listening on the socket */
829 success = channel_setup_remote_fwd_listener(ssh, 886 success = channel_setup_remote_fwd_listener(ssh,
830 &fwd, NULL, &options.fwd_opts); 887 &fwd, NULL, &options.fwd_opts);
831 } 888 }
832 free(fwd.listen_path);
833 } else if (strcmp(rtype, "cancel-streamlocal-forward@openssh.com") == 0) { 889 } else if (strcmp(rtype, "cancel-streamlocal-forward@openssh.com") == 0) {
834 struct Forward fwd; 890 if ((r = sshpkt_get_cstring(ssh, &fwd.listen_path, NULL)) != 0)
835 891 sshpkt_fatal(ssh, r, "%s: parse cancel-streamlocal-forward@openssh.com", __func__);
836 memset(&fwd, 0, sizeof(fwd));
837 fwd.listen_path = packet_get_string(NULL);
838 debug("%s: cancel-streamlocal-forward path %s", __func__, 892 debug("%s: cancel-streamlocal-forward path %s", __func__,
839 fwd.listen_path); 893 fwd.listen_path);
840 894
841 success = channel_cancel_rport_listener(ssh, &fwd); 895 success = channel_cancel_rport_listener(ssh, &fwd);
842 free(fwd.listen_path);
843 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { 896 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
844 no_more_sessions = 1; 897 no_more_sessions = 1;
845 success = 1; 898 success = 1;
846 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { 899 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
847 success = server_input_hostkeys_prove(ssh, &resp); 900 success = server_input_hostkeys_prove(ssh, &resp);
848 } 901 }
902 /* XXX sshpkt_get_end() */
849 if (want_reply) { 903 if (want_reply) {
850 packet_start(success ? 904 if ((r = sshpkt_start(ssh, success ?
851 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 905 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE)) != 0 ||
852 if (success && resp != NULL) 906 (success && resp != NULL && (r = sshpkt_putb(ssh, resp)) != 0) ||
853 ssh_packet_put_raw(ssh, sshbuf_ptr(resp), 907 (r = sshpkt_send(ssh)) != 0 ||
854 sshbuf_len(resp)); 908 (r = ssh_packet_write_wait(ssh)) != 0)
855 packet_send(); 909 sshpkt_fatal(ssh, r, "%s: send reply", __func__);
856 packet_write_wait();
857 } 910 }
911 free(fwd.listen_host);
912 free(fwd.listen_path);
858 free(rtype); 913 free(rtype);
859 sshbuf_free(resp); 914 sshbuf_free(resp);
860 return 0; 915 return 0;
@@ -864,58 +919,64 @@ static int
864server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) 919server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
865{ 920{
866 Channel *c; 921 Channel *c;
867 int id, reply, success = 0; 922 int r, success = 0;
868 char *rtype; 923 char *rtype = NULL;
869 924 u_char want_reply = 0;
870 id = packet_get_int(); 925 u_int id = 0;
871 rtype = packet_get_string(NULL); 926
872 reply = packet_get_char(); 927 if ((r = sshpkt_get_u32(ssh, &id)) != 0 ||
873 928 (r = sshpkt_get_cstring(ssh, &rtype, NULL)) != 0 ||
874 debug("server_input_channel_req: channel %d request %s reply %d", 929 (r = sshpkt_get_u8(ssh, &want_reply)) != 0)
875 id, rtype, reply); 930 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
876 931
877 if ((c = channel_lookup(ssh, id)) == NULL) 932 debug("server_input_channel_req: channel %u request %s reply %d",
878 packet_disconnect("server_input_channel_req: " 933 id, rtype, want_reply);
879 "unknown channel %d", id); 934
935 if (id >= INT_MAX || (c = channel_lookup(ssh, (int)id)) == NULL) {
936 ssh_packet_disconnect(ssh, "%s: unknown channel %d",
937 __func__, id);
938 }
880 if (!strcmp(rtype, "eow@openssh.com")) { 939 if (!strcmp(rtype, "eow@openssh.com")) {
881 packet_check_eom(); 940 if ((r = sshpkt_get_end(ssh)) != 0)
941 sshpkt_fatal(ssh, r, "%s: parse packet", __func__);
882 chan_rcvd_eow(ssh, c); 942 chan_rcvd_eow(ssh, c);
883 } else if ((c->type == SSH_CHANNEL_LARVAL || 943 } else if ((c->type == SSH_CHANNEL_LARVAL ||
884 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) 944 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
885 success = session_input_channel_req(ssh, c, rtype); 945 success = session_input_channel_req(ssh, c, rtype);
886 if (reply && !(c->flags & CHAN_CLOSE_SENT)) { 946 if (want_reply && !(c->flags & CHAN_CLOSE_SENT)) {
887 if (!c->have_remote_id) 947 if (!c->have_remote_id)
888 fatal("%s: channel %d: no remote_id", 948 fatal("%s: channel %d: no remote_id",
889 __func__, c->self); 949 __func__, c->self);
890 packet_start(success ? 950 if ((r = sshpkt_start(ssh, success ?
891 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 951 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE)) != 0 ||
892 packet_put_int(c->remote_id); 952 (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 ||
893 packet_send(); 953 (r = sshpkt_send(ssh)) != 0)
954 sshpkt_fatal(ssh, r, "%s: send reply", __func__);
894 } 955 }
895 free(rtype); 956 free(rtype);
896 return 0; 957 return 0;
897} 958}
898 959
899static void 960static void
900server_init_dispatch(void) 961server_init_dispatch(struct ssh *ssh)
901{ 962{
902 debug("server_init_dispatch"); 963 debug("server_init_dispatch");
903 dispatch_init(&dispatch_protocol_error); 964 ssh_dispatch_init(ssh, &dispatch_protocol_error);
904 dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose); 965 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
905 dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data); 966 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_DATA, &channel_input_data);
906 dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof); 967 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
907 dispatch_set(SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data); 968 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_EXTENDED_DATA, &channel_input_extended_data);
908 dispatch_set(SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open); 969 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN, &server_input_channel_open);
909 dispatch_set(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation); 970 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, &channel_input_open_confirmation);
910 dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure); 971 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
911 dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req); 972 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req);
912 dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); 973 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
913 dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request); 974 ssh_dispatch_set(ssh, SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
914 /* client_alive */ 975 /* client_alive */
915 dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive); 976 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive);
916 dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive); 977 ssh_dispatch_set(ssh, SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
917 dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive); 978 ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
918 dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive); 979 ssh_dispatch_set(ssh, SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
919 /* rekeying */ 980 /* rekeying */
920 dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit); 981 ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit);
921} 982}