diff options
Diffstat (limited to 'serverloop.c')
-rw-r--r-- | serverloop.c | 133 |
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 | ||
167 | static void | 167 | static void |
168 | client_alive_check(void) | 168 | client_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 | */ |
198 | static void | 199 | static void |
199 | wait_until_can_do_something(int connection_in, int connection_out, | 200 | wait_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 | */ |
281 | static int | 295 | static int |
282 | process_input(fd_set *readset, int connection_in) | 296 | process_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 | ||
323 | static void | 336 | static void |
324 | process_buffered_input_packets(void) | 337 | process_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 | ||
329 | static void | 342 | static void |
330 | collect_children(void) | 343 | collect_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 | ||
351 | void | 364 | void |
352 | server_loop2(Authctxt *authctxt) | 365 | server_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 | ||
419 | static int | 431 | static int |
420 | server_input_keep_alive(int type, u_int32_t seq, void *ctxt) | 432 | server_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 | ||
432 | static Channel * | 444 | static Channel * |
433 | server_request_direct_tcpip(int *reason, const char **errmsg) | 445 | server_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 | ||
467 | static Channel * | 479 | static Channel * |
468 | server_request_direct_streamlocal(void) | 480 | server_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 | ||
504 | static Channel * | 516 | static Channel * |
505 | server_request_tun(void) | 517 | server_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 | ||
550 | static Channel * | 562 | static Channel * |
551 | server_request_session(void) | 563 | server_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 | ||
581 | static int | 593 | static int |
582 | server_input_channel_open(int type, u_int32_t seq, void *ctxt) | 594 | server_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 | ||
635 | static int | 648 | static int |
636 | server_input_hostkeys_prove(struct sshbuf **respp) | 649 | server_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 | ||
705 | static int | 717 | static int |
706 | server_input_global_request(int type, u_int32_t seq, void *ctxt) | 718 | server_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 | ||
812 | static int | 824 | static int |
813 | server_input_channel_req(int type, u_int32_t seq, void *ctxt) | 825 | server_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); |