summaryrefslogtreecommitdiff
path: root/serverloop.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2017-10-04 11:23:58 +0100
committerColin Watson <cjwatson@debian.org>2017-10-05 23:58:12 +0100
commit0556ea972b15607b7e13ff31bc05840881c91dd3 (patch)
treed6b8d48062d0278b5ae0eeff42d0e9afa9f26860 /serverloop.c
parentdb2122d97eb1ecdd8d99b7bf79b0dd2b5addfd92 (diff)
parent801a62eedaaf47b20dbf4b426dc3e084bf0c8d49 (diff)
New upstream release (7.6p1)
Diffstat (limited to 'serverloop.c')
-rw-r--r--serverloop.c133
1 files changed, 74 insertions, 59 deletions
diff --git a/serverloop.c b/serverloop.c
index 2976f5594..24bbae322 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.191 2017/02/01 02:59:09 dtucker Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.198 2017/09/12 06:35:32 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
@@ -165,7 +165,7 @@ sigterm_handler(int sig)
165} 165}
166 166
167static void 167static void
168client_alive_check(void) 168client_alive_check(struct ssh *ssh)
169{ 169{
170 int channel_id; 170 int channel_id;
171 171
@@ -179,12 +179,13 @@ client_alive_check(void)
179 * send a bogus global/channel request with "wantreply", 179 * send a bogus global/channel request with "wantreply",
180 * we should get back a failure 180 * we should get back a failure
181 */ 181 */
182 if ((channel_id = channel_find_open()) == -1) { 182 if ((channel_id = channel_find_open(ssh)) == -1) {
183 packet_start(SSH2_MSG_GLOBAL_REQUEST); 183 packet_start(SSH2_MSG_GLOBAL_REQUEST);
184 packet_put_cstring("keepalive@openssh.com"); 184 packet_put_cstring("keepalive@openssh.com");
185 packet_put_char(1); /* boolean: want reply */ 185 packet_put_char(1); /* boolean: want reply */
186 } else { 186 } else {
187 channel_request_start(channel_id, "keepalive@openssh.com", 1); 187 channel_request_start(ssh, channel_id,
188 "keepalive@openssh.com", 1);
188 } 189 }
189 packet_send(); 190 packet_send();
190} 191}
@@ -196,7 +197,8 @@ client_alive_check(void)
196 * for the duration of the wait (0 = infinite). 197 * for the duration of the wait (0 = infinite).
197 */ 198 */
198static void 199static void
199wait_until_can_do_something(int connection_in, int connection_out, 200wait_until_can_do_something(struct ssh *ssh,
201 int connection_in, int connection_out,
200 fd_set **readsetp, fd_set **writesetp, int *maxfdp, 202 fd_set **readsetp, fd_set **writesetp, int *maxfdp,
201 u_int *nallocp, u_int64_t max_time_ms) 203 u_int *nallocp, u_int64_t max_time_ms)
202{ 204{
@@ -204,10 +206,11 @@ wait_until_can_do_something(int connection_in, int connection_out,
204 int ret; 206 int ret;
205 time_t minwait_secs = 0; 207 time_t minwait_secs = 0;
206 int client_alive_scheduled = 0; 208 int client_alive_scheduled = 0;
209 static time_t last_client_time;
207 210
208 /* Allocate and update select() masks for channel descriptors. */ 211 /* Allocate and update select() masks for channel descriptors. */
209 channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 212 channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
210 &minwait_secs, 0); 213 nallocp, &minwait_secs);
211 214
212 /* XXX need proper deadline system for rekey/client alive */ 215 /* XXX need proper deadline system for rekey/client alive */
213 if (minwait_secs != 0) 216 if (minwait_secs != 0)
@@ -268,8 +271,19 @@ wait_until_can_do_something(int connection_in, int connection_out,
268 memset(*writesetp, 0, *nallocp); 271 memset(*writesetp, 0, *nallocp);
269 if (errno != EINTR) 272 if (errno != EINTR)
270 error("select: %.100s", strerror(errno)); 273 error("select: %.100s", strerror(errno));
271 } else if (ret == 0 && client_alive_scheduled) 274 } else if (client_alive_scheduled) {
272 client_alive_check(); 275 time_t now = monotime();
276
277 if (ret == 0) { /* timeout */
278 client_alive_check(ssh);
279 } else if (FD_ISSET(connection_in, *readsetp)) {
280 last_client_time = now;
281 } else if (last_client_time != 0 && last_client_time +
282 options.client_alive_interval <= now) {
283 client_alive_check(ssh);
284 last_client_time = now;
285 }
286 }
273 287
274 notify_done(*readsetp); 288 notify_done(*readsetp);
275} 289}
@@ -279,9 +293,8 @@ wait_until_can_do_something(int connection_in, int connection_out,
279 * in buffers and processed later. 293 * in buffers and processed later.
280 */ 294 */
281static int 295static int
282process_input(fd_set *readset, int connection_in) 296process_input(struct ssh *ssh, fd_set *readset, int connection_in)
283{ 297{
284 struct ssh *ssh = active_state; /* XXX */
285 int len; 298 int len;
286 char buf[16384]; 299 char buf[16384];
287 300
@@ -321,13 +334,13 @@ process_output(fd_set *writeset, int connection_out)
321} 334}
322 335
323static void 336static void
324process_buffered_input_packets(void) 337process_buffered_input_packets(struct ssh *ssh)
325{ 338{
326 dispatch_run(DISPATCH_NONBLOCK, NULL, active_state); 339 ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, NULL);
327} 340}
328 341
329static void 342static void
330collect_children(void) 343collect_children(struct ssh *ssh)
331{ 344{
332 pid_t pid; 345 pid_t pid;
333 sigset_t oset, nset; 346 sigset_t oset, nset;
@@ -342,14 +355,14 @@ collect_children(void)
342 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || 355 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
343 (pid < 0 && errno == EINTR)) 356 (pid < 0 && errno == EINTR))
344 if (pid > 0) 357 if (pid > 0)
345 session_close_by_pid(pid, status); 358 session_close_by_pid(ssh, pid, status);
346 child_terminated = 0; 359 child_terminated = 0;
347 } 360 }
348 sigprocmask(SIG_SETMASK, &oset, NULL); 361 sigprocmask(SIG_SETMASK, &oset, NULL);
349} 362}
350 363
351void 364void
352server_loop2(Authctxt *authctxt) 365server_loop2(struct ssh *ssh, Authctxt *authctxt)
353{ 366{
354 fd_set *readset = NULL, *writeset = NULL; 367 fd_set *readset = NULL, *writeset = NULL;
355 int max_fd; 368 int max_fd;
@@ -377,18 +390,17 @@ server_loop2(Authctxt *authctxt)
377 server_init_dispatch(); 390 server_init_dispatch();
378 391
379 for (;;) { 392 for (;;) {
380 process_buffered_input_packets(); 393 process_buffered_input_packets(ssh);
381 394
382 if (!ssh_packet_is_rekeying(active_state) && 395 if (!ssh_packet_is_rekeying(ssh) &&
383 packet_not_very_much_data_to_write()) 396 packet_not_very_much_data_to_write())
384 channel_output_poll(); 397 channel_output_poll(ssh);
385 if (options.rekey_interval > 0 && 398 if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh))
386 !ssh_packet_is_rekeying(active_state))
387 rekey_timeout_ms = packet_get_rekey_timeout() * 1000; 399 rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
388 else 400 else
389 rekey_timeout_ms = 0; 401 rekey_timeout_ms = 0;
390 402
391 wait_until_can_do_something(connection_in, connection_out, 403 wait_until_can_do_something(ssh, connection_in, connection_out,
392 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); 404 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
393 405
394 if (received_sigterm) { 406 if (received_sigterm) {
@@ -397,27 +409,27 @@ server_loop2(Authctxt *authctxt)
397 cleanup_exit(255); 409 cleanup_exit(255);
398 } 410 }
399 411
400 collect_children(); 412 collect_children(ssh);
401 if (!ssh_packet_is_rekeying(active_state)) 413 if (!ssh_packet_is_rekeying(ssh))
402 channel_after_select(readset, writeset); 414 channel_after_select(ssh, readset, writeset);
403 if (process_input(readset, connection_in) < 0) 415 if (process_input(ssh, readset, connection_in) < 0)
404 break; 416 break;
405 process_output(writeset, connection_out); 417 process_output(writeset, connection_out);
406 } 418 }
407 collect_children(); 419 collect_children(ssh);
408 420
409 free(readset); 421 free(readset);
410 free(writeset); 422 free(writeset);
411 423
412 /* free all channels, no more reads and writes */ 424 /* free all channels, no more reads and writes */
413 channel_free_all(); 425 channel_free_all(ssh);
414 426
415 /* free remaining sessions, e.g. remove wtmp entries */ 427 /* free remaining sessions, e.g. remove wtmp entries */
416 session_destroy_all(NULL); 428 session_destroy_all(ssh, NULL);
417} 429}
418 430
419static int 431static int
420server_input_keep_alive(int type, u_int32_t seq, void *ctxt) 432server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
421{ 433{
422 debug("Got %d/%u for keepalive", type, seq); 434 debug("Got %d/%u for keepalive", type, seq);
423 /* 435 /*
@@ -430,7 +442,7 @@ server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
430} 442}
431 443
432static Channel * 444static Channel *
433server_request_direct_tcpip(int *reason, const char **errmsg) 445server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
434{ 446{
435 Channel *c = NULL; 447 Channel *c = NULL;
436 char *target, *originator; 448 char *target, *originator;
@@ -448,7 +460,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
448 /* XXX fine grained permissions */ 460 /* XXX fine grained permissions */
449 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && 461 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
450 !no_port_forwarding_flag && !options.disable_forwarding) { 462 !no_port_forwarding_flag && !options.disable_forwarding) {
451 c = channel_connect_to_port(target, target_port, 463 c = channel_connect_to_port(ssh, target, target_port,
452 "direct-tcpip", "direct-tcpip", reason, errmsg); 464 "direct-tcpip", "direct-tcpip", reason, errmsg);
453 } else { 465 } else {
454 logit("refused local port forward: " 466 logit("refused local port forward: "
@@ -465,7 +477,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
465} 477}
466 478
467static Channel * 479static Channel *
468server_request_direct_streamlocal(void) 480server_request_direct_streamlocal(struct ssh *ssh)
469{ 481{
470 Channel *c = NULL; 482 Channel *c = NULL;
471 char *target, *originator; 483 char *target, *originator;
@@ -487,7 +499,7 @@ server_request_direct_streamlocal(void)
487 if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && 499 if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
488 !no_port_forwarding_flag && !options.disable_forwarding && 500 !no_port_forwarding_flag && !options.disable_forwarding &&
489 (pw->pw_uid == 0 || use_privsep)) { 501 (pw->pw_uid == 0 || use_privsep)) {
490 c = channel_connect_to_path(target, 502 c = channel_connect_to_path(ssh, target,
491 "direct-streamlocal@openssh.com", "direct-streamlocal"); 503 "direct-streamlocal@openssh.com", "direct-streamlocal");
492 } else { 504 } else {
493 logit("refused streamlocal port forward: " 505 logit("refused streamlocal port forward: "
@@ -502,7 +514,7 @@ server_request_direct_streamlocal(void)
502} 514}
503 515
504static Channel * 516static Channel *
505server_request_tun(void) 517server_request_tun(struct ssh *ssh)
506{ 518{
507 Channel *c = NULL; 519 Channel *c = NULL;
508 int mode, tun; 520 int mode, tun;
@@ -532,12 +544,12 @@ server_request_tun(void)
532 sock = tun_open(tun, mode); 544 sock = tun_open(tun, mode);
533 if (sock < 0) 545 if (sock < 0)
534 goto done; 546 goto done;
535 c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, 547 c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
536 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); 548 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
537 c->datagram = 1; 549 c->datagram = 1;
538#if defined(SSH_TUN_FILTER) 550#if defined(SSH_TUN_FILTER)
539 if (mode == SSH_TUNMODE_POINTOPOINT) 551 if (mode == SSH_TUNMODE_POINTOPOINT)
540 channel_register_filter(c->self, sys_tun_infilter, 552 channel_register_filter(ssh, c->self, sys_tun_infilter,
541 sys_tun_outfilter, NULL, NULL); 553 sys_tun_outfilter, NULL, NULL);
542#endif 554#endif
543 555
@@ -548,7 +560,7 @@ server_request_tun(void)
548} 560}
549 561
550static Channel * 562static Channel *
551server_request_session(void) 563server_request_session(struct ssh *ssh)
552{ 564{
553 Channel *c; 565 Channel *c;
554 566
@@ -566,20 +578,20 @@ server_request_session(void)
566 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all 578 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
567 * CHANNEL_REQUEST messages is registered. 579 * CHANNEL_REQUEST messages is registered.
568 */ 580 */
569 c = channel_new("session", SSH_CHANNEL_LARVAL, 581 c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL,
570 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 582 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
571 0, "server-session", 1); 583 0, "server-session", 1);
572 if (session_open(the_authctxt, c->self) != 1) { 584 if (session_open(the_authctxt, c->self) != 1) {
573 debug("session open failed, free channel %d", c->self); 585 debug("session open failed, free channel %d", c->self);
574 channel_free(c); 586 channel_free(ssh, c);
575 return NULL; 587 return NULL;
576 } 588 }
577 channel_register_cleanup(c->self, session_close_by_channel, 0); 589 channel_register_cleanup(ssh, c->self, session_close_by_channel, 0);
578 return c; 590 return c;
579} 591}
580 592
581static int 593static int
582server_input_channel_open(int type, u_int32_t seq, void *ctxt) 594server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
583{ 595{
584 Channel *c = NULL; 596 Channel *c = NULL;
585 char *ctype; 597 char *ctype;
@@ -596,17 +608,18 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
596 ctype, rchan, rwindow, rmaxpack); 608 ctype, rchan, rwindow, rmaxpack);
597 609
598 if (strcmp(ctype, "session") == 0) { 610 if (strcmp(ctype, "session") == 0) {
599 c = server_request_session(); 611 c = server_request_session(ssh);
600 } else if (strcmp(ctype, "direct-tcpip") == 0) { 612 } else if (strcmp(ctype, "direct-tcpip") == 0) {
601 c = server_request_direct_tcpip(&reason, &errmsg); 613 c = server_request_direct_tcpip(ssh, &reason, &errmsg);
602 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) { 614 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) {
603 c = server_request_direct_streamlocal(); 615 c = server_request_direct_streamlocal(ssh);
604 } else if (strcmp(ctype, "tun@openssh.com") == 0) { 616 } else if (strcmp(ctype, "tun@openssh.com") == 0) {
605 c = server_request_tun(); 617 c = server_request_tun(ssh);
606 } 618 }
607 if (c != NULL) { 619 if (c != NULL) {
608 debug("server_input_channel_open: confirm %s", ctype); 620 debug("server_input_channel_open: confirm %s", ctype);
609 c->remote_id = rchan; 621 c->remote_id = rchan;
622 c->have_remote_id = 1;
610 c->remote_window = rwindow; 623 c->remote_window = rwindow;
611 c->remote_maxpacket = rmaxpack; 624 c->remote_maxpacket = rmaxpack;
612 if (c->type != SSH_CHANNEL_CONNECTING) { 625 if (c->type != SSH_CHANNEL_CONNECTING) {
@@ -633,9 +646,8 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
633} 646}
634 647
635static int 648static int
636server_input_hostkeys_prove(struct sshbuf **respp) 649server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
637{ 650{
638 struct ssh *ssh = active_state; /* XXX */
639 struct sshbuf *resp = NULL; 651 struct sshbuf *resp = NULL;
640 struct sshbuf *sigbuf = NULL; 652 struct sshbuf *sigbuf = NULL;
641 struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; 653 struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
@@ -703,7 +715,7 @@ server_input_hostkeys_prove(struct sshbuf **respp)
703} 715}
704 716
705static int 717static int
706server_input_global_request(int type, u_int32_t seq, void *ctxt) 718server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
707{ 719{
708 char *rtype; 720 char *rtype;
709 int want_reply; 721 int want_reply;
@@ -738,7 +750,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
738 packet_send_debug("Server has disabled port forwarding."); 750 packet_send_debug("Server has disabled port forwarding.");
739 } else { 751 } else {
740 /* Start listening on the port */ 752 /* Start listening on the port */
741 success = channel_setup_remote_fwd_listener(&fwd, 753 success = channel_setup_remote_fwd_listener(ssh, &fwd,
742 &allocated_listen_port, &options.fwd_opts); 754 &allocated_listen_port, &options.fwd_opts);
743 } 755 }
744 free(fwd.listen_host); 756 free(fwd.listen_host);
@@ -756,7 +768,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
756 debug("%s: cancel-tcpip-forward addr %s port %d", __func__, 768 debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
757 fwd.listen_host, fwd.listen_port); 769 fwd.listen_host, fwd.listen_port);
758 770
759 success = channel_cancel_rport_listener(&fwd); 771 success = channel_cancel_rport_listener(ssh, &fwd);
760 free(fwd.listen_host); 772 free(fwd.listen_host);
761 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { 773 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
762 struct Forward fwd; 774 struct Forward fwd;
@@ -775,7 +787,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
775 "streamlocal forwarding."); 787 "streamlocal forwarding.");
776 } else { 788 } else {
777 /* Start listening on the socket */ 789 /* Start listening on the socket */
778 success = channel_setup_remote_fwd_listener( 790 success = channel_setup_remote_fwd_listener(ssh,
779 &fwd, NULL, &options.fwd_opts); 791 &fwd, NULL, &options.fwd_opts);
780 } 792 }
781 free(fwd.listen_path); 793 free(fwd.listen_path);
@@ -787,19 +799,19 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
787 debug("%s: cancel-streamlocal-forward path %s", __func__, 799 debug("%s: cancel-streamlocal-forward path %s", __func__,
788 fwd.listen_path); 800 fwd.listen_path);
789 801
790 success = channel_cancel_rport_listener(&fwd); 802 success = channel_cancel_rport_listener(ssh, &fwd);
791 free(fwd.listen_path); 803 free(fwd.listen_path);
792 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { 804 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
793 no_more_sessions = 1; 805 no_more_sessions = 1;
794 success = 1; 806 success = 1;
795 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { 807 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
796 success = server_input_hostkeys_prove(&resp); 808 success = server_input_hostkeys_prove(ssh, &resp);
797 } 809 }
798 if (want_reply) { 810 if (want_reply) {
799 packet_start(success ? 811 packet_start(success ?
800 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 812 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
801 if (success && resp != NULL) 813 if (success && resp != NULL)
802 ssh_packet_put_raw(active_state, sshbuf_ptr(resp), 814 ssh_packet_put_raw(ssh, sshbuf_ptr(resp),
803 sshbuf_len(resp)); 815 sshbuf_len(resp));
804 packet_send(); 816 packet_send();
805 packet_write_wait(); 817 packet_write_wait();
@@ -810,7 +822,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
810} 822}
811 823
812static int 824static int
813server_input_channel_req(int type, u_int32_t seq, void *ctxt) 825server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
814{ 826{
815 Channel *c; 827 Channel *c;
816 int id, reply, success = 0; 828 int id, reply, success = 0;
@@ -823,16 +835,19 @@ server_input_channel_req(int type, u_int32_t seq, void *ctxt)
823 debug("server_input_channel_req: channel %d request %s reply %d", 835 debug("server_input_channel_req: channel %d request %s reply %d",
824 id, rtype, reply); 836 id, rtype, reply);
825 837
826 if ((c = channel_lookup(id)) == NULL) 838 if ((c = channel_lookup(ssh, id)) == NULL)
827 packet_disconnect("server_input_channel_req: " 839 packet_disconnect("server_input_channel_req: "
828 "unknown channel %d", id); 840 "unknown channel %d", id);
829 if (!strcmp(rtype, "eow@openssh.com")) { 841 if (!strcmp(rtype, "eow@openssh.com")) {
830 packet_check_eom(); 842 packet_check_eom();
831 chan_rcvd_eow(c); 843 chan_rcvd_eow(ssh, c);
832 } else if ((c->type == SSH_CHANNEL_LARVAL || 844 } else if ((c->type == SSH_CHANNEL_LARVAL ||
833 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) 845 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
834 success = session_input_channel_req(c, rtype); 846 success = session_input_channel_req(ssh, c, rtype);
835 if (reply && !(c->flags & CHAN_CLOSE_SENT)) { 847 if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
848 if (!c->have_remote_id)
849 fatal("%s: channel %d: no remote_id",
850 __func__, c->self);
836 packet_start(success ? 851 packet_start(success ?
837 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 852 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
838 packet_put_int(c->remote_id); 853 packet_put_int(c->remote_id);