diff options
Diffstat (limited to 'usr.bin/ssh/serverloop.c')
-rw-r--r-- | usr.bin/ssh/serverloop.c | 105 |
1 files changed, 52 insertions, 53 deletions
diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c index ced2d52bdad..1cc74c2f7dc 100644 --- a/usr.bin/ssh/serverloop.c +++ b/usr.bin/ssh/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.196 2017/08/30 03:59:08 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.197 2017/09/12 06:32:07 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -159,7 +159,7 @@ sigterm_handler(int sig) } static void -client_alive_check(void) +client_alive_check(struct ssh *ssh) { int channel_id; @@ -173,12 +173,13 @@ client_alive_check(void) * send a bogus global/channel request with "wantreply", * we should get back a failure */ - if ((channel_id = channel_find_open()) == -1) { + if ((channel_id = channel_find_open(ssh)) == -1) { packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("keepalive@openssh.com"); packet_put_char(1); /* boolean: want reply */ } else { - channel_request_start(channel_id, "keepalive@openssh.com", 1); + channel_request_start(ssh, channel_id, + "keepalive@openssh.com", 1); } packet_send(); } @@ -190,7 +191,8 @@ client_alive_check(void) * for the duration of the wait (0 = infinite). */ static void -wait_until_can_do_something(int connection_in, int connection_out, +wait_until_can_do_something(struct ssh *ssh, + int connection_in, int connection_out, fd_set **readsetp, fd_set **writesetp, int *maxfdp, u_int *nallocp, u_int64_t max_time_ms) { @@ -201,7 +203,7 @@ wait_until_can_do_something(int connection_in, int connection_out, static time_t last_client_time; /* Allocate and update select() masks for channel descriptors. */ - channel_prepare_select(active_state, readsetp, writesetp, maxfdp, + channel_prepare_select(ssh, readsetp, writesetp, maxfdp, nallocp, &minwait_secs); /* XXX need proper deadline system for rekey/client alive */ @@ -267,12 +269,12 @@ wait_until_can_do_something(int connection_in, int connection_out, time_t now = monotime(); if (ret == 0) { /* timeout */ - client_alive_check(); + client_alive_check(ssh); } else if (FD_ISSET(connection_in, *readsetp)) { last_client_time = now; } else if (last_client_time != 0 && last_client_time + options.client_alive_interval <= now) { - client_alive_check(); + client_alive_check(ssh); last_client_time = now; } } @@ -285,9 +287,8 @@ wait_until_can_do_something(int connection_in, int connection_out, * in buffers and processed later. */ static int -process_input(fd_set *readset, int connection_in) +process_input(struct ssh *ssh, fd_set *readset, int connection_in) { - struct ssh *ssh = active_state; /* XXX */ int len; char buf[16384]; @@ -326,13 +327,13 @@ process_output(fd_set *writeset, int connection_out) } static void -process_buffered_input_packets(void) +process_buffered_input_packets(struct ssh *ssh) { - ssh_dispatch_run_fatal(active_state, DISPATCH_NONBLOCK, NULL); + ssh_dispatch_run_fatal(ssh, DISPATCH_NONBLOCK, NULL); } static void -collect_children(void) +collect_children(struct ssh *ssh) { pid_t pid; sigset_t oset, nset; @@ -347,14 +348,14 @@ collect_children(void) while ((pid = waitpid(-1, &status, WNOHANG)) > 0 || (pid < 0 && errno == EINTR)) if (pid > 0) - session_close_by_pid(pid, status); + session_close_by_pid(ssh, pid, status); child_terminated = 0; } sigprocmask(SIG_SETMASK, &oset, NULL); } void -server_loop2(Authctxt *authctxt) +server_loop2(struct ssh *ssh, Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; int max_fd; @@ -382,18 +383,17 @@ server_loop2(Authctxt *authctxt) server_init_dispatch(); for (;;) { - process_buffered_input_packets(); + process_buffered_input_packets(ssh); - if (!ssh_packet_is_rekeying(active_state) && + if (!ssh_packet_is_rekeying(ssh) && packet_not_very_much_data_to_write()) - channel_output_poll(); - if (options.rekey_interval > 0 && - !ssh_packet_is_rekeying(active_state)) + channel_output_poll(ssh); + if (options.rekey_interval > 0 && !ssh_packet_is_rekeying(ssh)) rekey_timeout_ms = packet_get_rekey_timeout() * 1000; else rekey_timeout_ms = 0; - wait_until_can_do_something(connection_in, connection_out, + wait_until_can_do_something(ssh, connection_in, connection_out, &readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); if (received_sigterm) { @@ -402,23 +402,23 @@ server_loop2(Authctxt *authctxt) cleanup_exit(255); } - collect_children(); - if (!ssh_packet_is_rekeying(active_state)) - channel_after_select(active_state, readset, writeset); - if (process_input(readset, connection_in) < 0) + collect_children(ssh); + if (!ssh_packet_is_rekeying(ssh)) + channel_after_select(ssh, readset, writeset); + if (process_input(ssh, readset, connection_in) < 0) break; process_output(writeset, connection_out); } - collect_children(); + collect_children(ssh); free(readset); free(writeset); /* free all channels, no more reads and writes */ - channel_free_all(); + channel_free_all(ssh); /* free remaining sessions, e.g. remove wtmp entries */ - session_destroy_all(NULL); + session_destroy_all(ssh, NULL); } static int @@ -435,7 +435,7 @@ server_input_keep_alive(int type, u_int32_t seq, struct ssh *ssh) } static Channel * -server_request_direct_tcpip(int *reason, const char **errmsg) +server_request_direct_tcpip(struct ssh *ssh, int *reason, const char **errmsg) { Channel *c = NULL; char *target, *originator; @@ -453,7 +453,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg) /* XXX fine grained permissions */ if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0 && !no_port_forwarding_flag && !options.disable_forwarding) { - c = channel_connect_to_port(target, target_port, + c = channel_connect_to_port(ssh, target, target_port, "direct-tcpip", "direct-tcpip", reason, errmsg); } else { logit("refused local port forward: " @@ -470,7 +470,7 @@ server_request_direct_tcpip(int *reason, const char **errmsg) } static Channel * -server_request_direct_streamlocal(void) +server_request_direct_streamlocal(struct ssh *ssh) { Channel *c = NULL; char *target, *originator; @@ -492,7 +492,7 @@ server_request_direct_streamlocal(void) if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && !no_port_forwarding_flag && !options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) { - c = channel_connect_to_path(target, + c = channel_connect_to_path(ssh, target, "direct-streamlocal@openssh.com", "direct-streamlocal"); } else { logit("refused streamlocal port forward: " @@ -507,7 +507,7 @@ server_request_direct_streamlocal(void) } static Channel * -server_request_tun(void) +server_request_tun(struct ssh *ssh) { Channel *c = NULL; int mode, tun; @@ -537,7 +537,7 @@ server_request_tun(void) sock = tun_open(tun, mode); if (sock < 0) goto done; - c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1, + c = channel_new(ssh, "tun", SSH_CHANNEL_OPEN, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1); c->datagram = 1; @@ -548,7 +548,7 @@ server_request_tun(void) } static Channel * -server_request_session(void) +server_request_session(struct ssh *ssh) { Channel *c; @@ -566,15 +566,15 @@ server_request_session(void) * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all * CHANNEL_REQUEST messages is registered. */ - c = channel_new("session", SSH_CHANNEL_LARVAL, + c = channel_new(ssh, "session", SSH_CHANNEL_LARVAL, -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT, 0, "server-session", 1); if (session_open(the_authctxt, c->self) != 1) { debug("session open failed, free channel %d", c->self); - channel_free(c); + channel_free(ssh, c); return NULL; } - channel_register_cleanup(c->self, session_close_by_channel, 0); + channel_register_cleanup(ssh, c->self, session_close_by_channel, 0); return c; } @@ -596,13 +596,13 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) ctype, rchan, rwindow, rmaxpack); if (strcmp(ctype, "session") == 0) { - c = server_request_session(); + c = server_request_session(ssh); } else if (strcmp(ctype, "direct-tcpip") == 0) { - c = server_request_direct_tcpip(&reason, &errmsg); + c = server_request_direct_tcpip(ssh, &reason, &errmsg); } else if (strcmp(ctype, "direct-streamlocal@openssh.com") == 0) { - c = server_request_direct_streamlocal(); + c = server_request_direct_streamlocal(ssh); } else if (strcmp(ctype, "tun@openssh.com") == 0) { - c = server_request_tun(); + c = server_request_tun(ssh); } if (c != NULL) { debug("server_input_channel_open: confirm %s", ctype); @@ -633,9 +633,8 @@ server_input_channel_open(int type, u_int32_t seq, struct ssh *ssh) } static int -server_input_hostkeys_prove(struct sshbuf **respp) +server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) { - struct ssh *ssh = active_state; /* XXX */ struct sshbuf *resp = NULL; struct sshbuf *sigbuf = NULL; struct sshkey *key = NULL, *key_pub = NULL, *key_prv = NULL; @@ -738,7 +737,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) packet_send_debug("Server has disabled port forwarding."); } else { /* Start listening on the port */ - success = channel_setup_remote_fwd_listener(&fwd, + success = channel_setup_remote_fwd_listener(ssh, &fwd, &allocated_listen_port, &options.fwd_opts); } free(fwd.listen_host); @@ -756,7 +755,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) debug("%s: cancel-tcpip-forward addr %s port %d", __func__, fwd.listen_host, fwd.listen_port); - success = channel_cancel_rport_listener(&fwd); + success = channel_cancel_rport_listener(ssh, &fwd); free(fwd.listen_host); } else if (strcmp(rtype, "streamlocal-forward@openssh.com") == 0) { struct Forward fwd; @@ -775,7 +774,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) "streamlocal forwarding."); } else { /* Start listening on the socket */ - success = channel_setup_remote_fwd_listener( + success = channel_setup_remote_fwd_listener(ssh, &fwd, NULL, &options.fwd_opts); } free(fwd.listen_path); @@ -787,19 +786,19 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) debug("%s: cancel-streamlocal-forward path %s", __func__, fwd.listen_path); - success = channel_cancel_rport_listener(&fwd); + success = channel_cancel_rport_listener(ssh, &fwd); free(fwd.listen_path); } else if (strcmp(rtype, "no-more-sessions@openssh.com") == 0) { no_more_sessions = 1; success = 1; } else if (strcmp(rtype, "hostkeys-prove-00@openssh.com") == 0) { - success = server_input_hostkeys_prove(&resp); + success = server_input_hostkeys_prove(ssh, &resp); } if (want_reply) { packet_start(success ? SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); if (success && resp != NULL) - ssh_packet_put_raw(active_state, sshbuf_ptr(resp), + ssh_packet_put_raw(ssh, sshbuf_ptr(resp), sshbuf_len(resp)); packet_send(); packet_write_wait(); @@ -823,15 +822,15 @@ server_input_channel_req(int type, u_int32_t seq, struct ssh *ssh) debug("server_input_channel_req: channel %d request %s reply %d", id, rtype, reply); - if ((c = channel_lookup(id)) == NULL) + if ((c = channel_lookup(ssh, id)) == NULL) packet_disconnect("server_input_channel_req: " "unknown channel %d", id); if (!strcmp(rtype, "eow@openssh.com")) { packet_check_eom(); - chan_rcvd_eow(c); + chan_rcvd_eow(ssh, c); } else if ((c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) && strcmp(c->ctype, "session") == 0) - success = session_input_channel_req(c, rtype); + success = session_input_channel_req(ssh, c, rtype); if (reply && !(c->flags & CHAN_CLOSE_SENT)) { packet_start(success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); |