summaryrefslogtreecommitdiff
path: root/serverloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'serverloop.c')
-rw-r--r--serverloop.c105
1 files changed, 52 insertions, 53 deletions
diff --git a/serverloop.c b/serverloop.c
index bc56709b1..567159410 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: serverloop.c,v 1.196 2017/08/30 03:59:08 djm Exp $ */ 1/* $OpenBSD: serverloop.c,v 1.197 2017/09/12 06:32:07 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{
@@ -207,7 +209,7 @@ wait_until_can_do_something(int connection_in, int connection_out,
207 static time_t last_client_time; 209 static time_t last_client_time;
208 210
209 /* Allocate and update select() masks for channel descriptors. */ 211 /* Allocate and update select() masks for channel descriptors. */
210 channel_prepare_select(active_state, readsetp, writesetp, maxfdp, 212 channel_prepare_select(ssh, readsetp, writesetp, maxfdp,
211 nallocp, &minwait_secs); 213 nallocp, &minwait_secs);
212 214
213 /* XXX need proper deadline system for rekey/client alive */ 215 /* XXX need proper deadline system for rekey/client alive */
@@ -273,12 +275,12 @@ wait_until_can_do_something(int connection_in, int connection_out,
273 time_t now = monotime(); 275 time_t now = monotime();
274 276
275 if (ret == 0) { /* timeout */ 277 if (ret == 0) { /* timeout */
276 client_alive_check(); 278 client_alive_check(ssh);
277 } else if (FD_ISSET(connection_in, *readsetp)) { 279 } else if (FD_ISSET(connection_in, *readsetp)) {
278 last_client_time = now; 280 last_client_time = now;
279 } else if (last_client_time != 0 && last_client_time + 281 } else if (last_client_time != 0 && last_client_time +
280 options.client_alive_interval <= now) { 282 options.client_alive_interval <= now) {
281 client_alive_check(); 283 client_alive_check(ssh);
282 last_client_time = now; 284 last_client_time = now;
283 } 285 }
284 } 286 }
@@ -291,9 +293,8 @@ wait_until_can_do_something(int connection_in, int connection_out,
291 * in buffers and processed later. 293 * in buffers and processed later.
292 */ 294 */
293static int 295static int
294process_input(fd_set *readset, int connection_in) 296process_input(struct ssh *ssh, fd_set *readset, int connection_in)
295{ 297{
296 struct ssh *ssh = active_state; /* XXX */
297 int len; 298 int len;
298 char buf[16384]; 299 char buf[16384];
299 300
@@ -333,13 +334,13 @@ process_output(fd_set *writeset, int connection_out)
333} 334}
334 335
335static void 336static void
336process_buffered_input_packets(void) 337process_buffered_input_packets(struct ssh *ssh)
337{ 338{
338 ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, NULL); 339 ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, NULL);
339} 340}
340 341
341static void 342static void
342collect_children(void) 343collect_children(struct ssh *ssh)
343{ 344{
344 pid_t pid; 345 pid_t pid;
345 sigset_t oset, nset; 346 sigset_t oset, nset;
@@ -354,14 +355,14 @@ collect_children(void)
354 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || 355 while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
355 (pid < 0 && errno == EINTR)) 356 (pid < 0 && errno == EINTR))
356 if (pid > 0) 357 if (pid > 0)
357 session_close_by_pid(pid, status); 358 session_close_by_pid(ssh, pid, status);
358 child_terminated = 0; 359 child_terminated = 0;
359 } 360 }
360 sigprocmask(SIG_SETMASK, &oset, NULL); 361 sigprocmask(SIG_SETMASK, &oset, NULL);
361} 362}
362 363
363void 364void
364server_loop2(Authctxt *authctxt) 365server_loop2(struct ssh *ssh, Authctxt *authctxt)
365{ 366{
366 fd_set *readset = NULL, *writeset = NULL; 367 fd_set *readset = NULL, *writeset = NULL;
367 int max_fd; 368 int max_fd;
@@ -389,18 +390,17 @@ server_loop2(Authctxt *authctxt)
389 server_init_dispatch(); 390 server_init_dispatch();
390 391
391 for (;;) { 392 for (;;) {
392 process_buffered_input_packets(); 393 process_buffered_input_packets(ssh);
393 394
394 if (!ssh_packet_is_rekeying(active_state) && 395 if (!ssh_packet_is_rekeying(ssh) &&
395 packet_not_very_much_data_to_write()) 396 packet_not_very_much_data_to_write())
396 channel_output_poll(); 397 channel_output_poll(ssh);
397 if (options.rekey_interval > 0 && 398 if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh))
398 !ssh_packet_is_rekeying(active_state))
399 rekey_timeout_ms = packet_get_rekey_timeout() * 1000; 399 rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
400 else 400 else
401 rekey_timeout_ms = 0; 401 rekey_timeout_ms = 0;
402 402
403 wait_until_can_do_something(connection_in, connection_out, 403 wait_until_can_do_something(ssh, connection_in, connection_out,
404 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); 404 &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms);
405 405
406 if (received_sigterm) { 406 if (received_sigterm) {
@@ -409,23 +409,23 @@ server_loop2(Authctxt *authctxt)
409 cleanup_exit(255); 409 cleanup_exit(255);
410 } 410 }
411 411
412 collect_children(); 412 collect_children(ssh);
413 if (!ssh_packet_is_rekeying(active_state)) 413 if (!ssh_packet_is_rekeying(ssh))
414 channel_after_select(active_state, readset, writeset); 414 channel_after_select(ssh, readset, writeset);
415 if (process_input(readset, connection_in) < 0) 415 if (process_input(ssh, readset, connection_in) < 0)
416 break; 416 break;
417 process_output(writeset, connection_out); 417 process_output(writeset, connection_out);
418 } 418 }
419 collect_children(); 419 collect_children(ssh);
420 420
421 free(readset); 421 free(readset);
422 free(writeset); 422 free(writeset);
423 423
424 /* free all channels, no more reads and writes */ 424 /* free all channels, no more reads and writes */
425 channel_free_all(); 425 channel_free_all(ssh);
426 426
427 /* free remaining sessions, e.g. remove wtmp entries */ 427 /* free remaining sessions, e.g. remove wtmp entries */
428 session_destroy_all(NULL); 428 session_destroy_all(ssh, NULL);
429} 429}
430 430
431static int 431static int
@@ -442,7 +442,7 @@ server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh)
442} 442}
443 443
444static Channel * 444static Channel *
445server_request_direct_tcpip(int *reason, const char **errmsg) 445server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg)
446{ 446{
447 Channel *c = NULL; 447 Channel *c = NULL;
448 char *target, *originator; 448 char *target, *originator;
@@ -460,7 +460,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
460 /* XXX fine grained permissions */ 460 /* XXX fine grained permissions */
461 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && 461 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 &&
462 !no_port_forwarding_flag && !options.disable_forwarding) { 462 !no_port_forwarding_flag && !options.disable_forwarding) {
463 c = channel_connect_to_port(target, target_port, 463 c = channel_connect_to_port(ssh, target, target_port,
464 "direct-tcpip", "direct-tcpip", reason, errmsg); 464 "direct-tcpip", "direct-tcpip", reason, errmsg);
465 } else { 465 } else {
466 logit("refused local port forward: " 466 logit("refused local port forward: "
@@ -477,7 +477,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg)
477} 477}
478 478
479static Channel * 479static Channel *
480server_request_direct_streamlocal(void) 480server_request_direct_streamlocal(struct ssh *ssh)
481{ 481{
482 Channel *c = NULL; 482 Channel *c = NULL;
483 char *target, *originator; 483 char *target, *originator;
@@ -499,7 +499,7 @@ server_request_direct_streamlocal(void)
499 if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && 499 if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 &&
500 !no_port_forwarding_flag && !options.disable_forwarding && 500 !no_port_forwarding_flag && !options.disable_forwarding &&
501 (pw->pw_uid == 0 || use_privsep)) { 501 (pw->pw_uid == 0 || use_privsep)) {
502 c = channel_connect_to_path(target, 502 c = channel_connect_to_path(ssh, target,
503 "direct-streamlocal@openssh.com", "direct-streamlocal"); 503 "direct-streamlocal@openssh.com", "direct-streamlocal");
504 } else { 504 } else {
505 logit("refused streamlocal port forward: " 505 logit("refused streamlocal port forward: "
@@ -514,7 +514,7 @@ server_request_direct_streamlocal(void)
514} 514}
515 515
516static Channel * 516static Channel *
517server_request_tun(void) 517server_request_tun(struct ssh *ssh)
518{ 518{
519 Channel *c = NULL; 519 Channel *c = NULL;
520 int mode, tun; 520 int mode, tun;
@@ -544,7 +544,7 @@ server_request_tun(void)
544 sock = tun_open(tun, mode); 544 sock = tun_open(tun, mode);
545 if (sock < 0) 545 if (sock < 0)
546 goto done; 546 goto done;
547 c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, 547 c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1,
548 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); 548 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
549 c->datagram = 1; 549 c->datagram = 1;
550#if defined(SSH_TUN_FILTER) 550#if defined(SSH_TUN_FILTER)
@@ -560,7 +560,7 @@ server_request_tun(void)
560} 560}
561 561
562static Channel * 562static Channel *
563server_request_session(void) 563server_request_session(struct ssh *ssh)
564{ 564{
565 Channel *c; 565 Channel *c;
566 566
@@ -578,15 +578,15 @@ server_request_session(void)
578 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all 578 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
579 * CHANNEL_REQUEST messages is registered. 579 * CHANNEL_REQUEST messages is registered.
580 */ 580 */
581 c = channel_new("session", SSH_CHANNEL_LARVAL, 581 c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL,
582 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 582 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
583 0, "server-session", 1); 583 0, "server-session", 1);
584 if (session_open(the_authctxt, c->self) != 1) { 584 if (session_open(the_authctxt, c->self) != 1) {
585 debug("session open failed, free channel %d", c->self); 585 debug("session open failed, free channel %d", c->self);
586 channel_free(c); 586 channel_free(ssh, c);
587 return NULL; 587 return NULL;
588 } 588 }
589 channel_register_cleanup(c->self, session_close_by_channel, 0); 589 channel_register_cleanup(ssh, c->self, session_close_by_channel, 0);
590 return c; 590 return c;
591} 591}
592 592
@@ -608,13 +608,13 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
608 ctype, rchan, rwindow, rmaxpack); 608 ctype, rchan, rwindow, rmaxpack);
609 609
610 if (strcmp(ctype, "session") == 0) { 610 if (strcmp(ctype, "session") == 0) {
611 c = server_request_session(); 611 c = server_request_session(ssh);
612 } else if (strcmp(ctype, "direct-tcpip") == 0) { 612 } else if (strcmp(ctype, "direct-tcpip") == 0) {
613 c = server_request_direct_tcpip(&reason, &errmsg); 613 c = server_request_direct_tcpip(ssh, &reason, &errmsg);
614 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) { 614 } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) {
615 c = server_request_direct_streamlocal(); 615 c = server_request_direct_streamlocal(ssh);
616 } else if (strcmp(ctype, "tun@openssh.com") == 0) { 616 } else if (strcmp(ctype, "tun@openssh.com") == 0) {
617 c = server_request_tun(); 617 c = server_request_tun(ssh);
618 } 618 }
619 if (c != NULL) { 619 if (c != NULL) {
620 debug("server_input_channel_open: confirm %s", ctype); 620 debug("server_input_channel_open: confirm %s", ctype);
@@ -645,9 +645,8 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh)
645} 645}
646 646
647static int 647static int
648server_input_hostkeys_prove(struct sshbuf **respp) 648server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp)
649{ 649{
650 struct ssh *ssh = active_state; /* XXX */
651 struct sshbuf *resp = NULL; 650 struct sshbuf *resp = NULL;
652 struct sshbuf *sigbuf = NULL; 651 struct sshbuf *sigbuf = NULL;
653 struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; 652 struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL;
@@ -750,7 +749,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
750 packet_send_debug("Server has disabled port forwarding."); 749 packet_send_debug("Server has disabled port forwarding.");
751 } else { 750 } else {
752 /* Start listening on the port */ 751 /* Start listening on the port */
753 success = channel_setup_remote_fwd_listener(&fwd, 752 success = channel_setup_remote_fwd_listener(ssh, &fwd,
754 &allocated_listen_port, &options.fwd_opts); 753 &allocated_listen_port, &options.fwd_opts);
755 } 754 }
756 free(fwd.listen_host); 755 free(fwd.listen_host);
@@ -768,7 +767,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
768 debug("%s: cancel-tcpip-forward addr %s port %d", __func__, 767 debug("%s: cancel-tcpip-forward addr %s port %d", __func__,
769 fwd.listen_host, fwd.listen_port); 768 fwd.listen_host, fwd.listen_port);
770 769
771 success = channel_cancel_rport_listener(&fwd); 770 success = channel_cancel_rport_listener(ssh, &fwd);
772 free(fwd.listen_host); 771 free(fwd.listen_host);
773 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { 772 } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) {
774 struct Forward fwd; 773 struct Forward fwd;
@@ -787,7 +786,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
787 "streamlocal forwarding."); 786 "streamlocal forwarding.");
788 } else { 787 } else {
789 /* Start listening on the socket */ 788 /* Start listening on the socket */
790 success = channel_setup_remote_fwd_listener( 789 success = channel_setup_remote_fwd_listener(ssh,
791 &fwd, NULL, &options.fwd_opts); 790 &fwd, NULL, &options.fwd_opts);
792 } 791 }
793 free(fwd.listen_path); 792 free(fwd.listen_path);
@@ -799,19 +798,19 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh)
799 debug("%s: cancel-streamlocal-forward path %s", __func__, 798 debug("%s: cancel-streamlocal-forward path %s", __func__,
800 fwd.listen_path); 799 fwd.listen_path);
801 800
802 success = channel_cancel_rport_listener(&fwd); 801 success = channel_cancel_rport_listener(ssh, &fwd);
803 free(fwd.listen_path); 802 free(fwd.listen_path);
804 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { 803 } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) {
805 no_more_sessions = 1; 804 no_more_sessions = 1;
806 success = 1; 805 success = 1;
807 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { 806 } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) {
808 success = server_input_hostkeys_prove(&resp); 807 success = server_input_hostkeys_prove(ssh, &resp);
809 } 808 }
810 if (want_reply) { 809 if (want_reply) {
811 packet_start(success ? 810 packet_start(success ?
812 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); 811 SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
813 if (success && resp != NULL) 812 if (success && resp != NULL)
814 ssh_packet_put_raw(active_state, sshbuf_ptr(resp), 813 ssh_packet_put_raw(ssh, sshbuf_ptr(resp),
815 sshbuf_len(resp)); 814 sshbuf_len(resp));
816 packet_send(); 815 packet_send();
817 packet_write_wait(); 816 packet_write_wait();
@@ -835,15 +834,15 @@ server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh)
835 debug("server_input_channel_req: channel %d request %s reply %d", 834 debug("server_input_channel_req: channel %d request %s reply %d",
836 id, rtype, reply); 835 id, rtype, reply);
837 836
838 if ((c = channel_lookup(id)) == NULL) 837 if ((c = channel_lookup(ssh, id)) == NULL)
839 packet_disconnect("server_input_channel_req: " 838 packet_disconnect("server_input_channel_req: "
840 "unknown channel %d", id); 839 "unknown channel %d", id);
841 if (!strcmp(rtype, "eow@openssh.com")) { 840 if (!strcmp(rtype, "eow@openssh.com")) {
842 packet_check_eom(); 841 packet_check_eom();
843 chan_rcvd_eow(c); 842 chan_rcvd_eow(ssh, c);
844 } else if ((c->type == SSH_CHANNEL_LARVAL || 843 } else if ((c->type == SSH_CHANNEL_LARVAL ||
845 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) 844 c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0)
846 success = session_input_channel_req(c, rtype); 845 success = session_input_channel_req(ssh, c, rtype);
847 if (reply && !(c->flags & CHAN_CLOSE_SENT)) { 846 if (reply && !(c->flags & CHAN_CLOSE_SENT)) {
848 packet_start(success ? 847 packet_start(success ?
849 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); 848 SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);