diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 69 |
1 files changed, 39 insertions, 30 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.524 2019/01/19 21:38:24 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.525 2019/01/19 21:42:30 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 |
@@ -123,7 +123,6 @@ | |||
123 | #include "version.h" | 123 | #include "version.h" |
124 | #include "ssherr.h" | 124 | #include "ssherr.h" |
125 | 125 | ||
126 | #include "opacket.h" /* XXX */ | ||
127 | extern struct ssh *active_state; /* XXX move decl to this file */ | 126 | extern struct ssh *active_state; /* XXX move decl to this file */ |
128 | 127 | ||
129 | /* Re-exec fds */ | 128 | /* Re-exec fds */ |
@@ -244,7 +243,7 @@ struct passwd *privsep_pw = NULL; | |||
244 | /* Prototypes for various functions defined later in this file. */ | 243 | /* Prototypes for various functions defined later in this file. */ |
245 | void destroy_sensitive_data(void); | 244 | void destroy_sensitive_data(void); |
246 | void demote_sensitive_data(void); | 245 | void demote_sensitive_data(void); |
247 | static void do_ssh2_kex(void); | 246 | static void do_ssh2_kex(struct ssh *); |
248 | 247 | ||
249 | /* | 248 | /* |
250 | * Close all listening sockets | 249 | * Close all listening sockets |
@@ -458,8 +457,9 @@ privsep_preauth_child(void) | |||
458 | } | 457 | } |
459 | 458 | ||
460 | static int | 459 | static int |
461 | privsep_preauth(Authctxt *authctxt) | 460 | privsep_preauth(struct ssh *ssh) |
462 | { | 461 | { |
462 | Authctxt *authctxt = (Authctxt *)ssh->authctxt; | ||
463 | int status, r; | 463 | int status, r; |
464 | pid_t pid; | 464 | pid_t pid; |
465 | struct ssh_sandbox *box = NULL; | 465 | struct ssh_sandbox *box = NULL; |
@@ -467,7 +467,7 @@ privsep_preauth(Authctxt *authctxt) | |||
467 | /* Set up unprivileged child process to deal with network data */ | 467 | /* Set up unprivileged child process to deal with network data */ |
468 | pmonitor = monitor_init(); | 468 | pmonitor = monitor_init(); |
469 | /* Store a pointer to the kex for later rekeying */ | 469 | /* Store a pointer to the kex for later rekeying */ |
470 | pmonitor->m_pkex = &active_state->kex; | 470 | pmonitor->m_pkex = &ssh->kex; |
471 | 471 | ||
472 | if (use_privsep == PRIVSEP_ON) | 472 | if (use_privsep == PRIVSEP_ON) |
473 | box = ssh_sandbox_init(pmonitor); | 473 | box = ssh_sandbox_init(pmonitor); |
@@ -527,7 +527,7 @@ privsep_preauth(Authctxt *authctxt) | |||
527 | } | 527 | } |
528 | 528 | ||
529 | static void | 529 | static void |
530 | privsep_postauth(Authctxt *authctxt) | 530 | privsep_postauth(struct ssh *ssh, Authctxt *authctxt) |
531 | { | 531 | { |
532 | #ifdef DISABLE_FD_PASSING | 532 | #ifdef DISABLE_FD_PASSING |
533 | if (1) { | 533 | if (1) { |
@@ -576,7 +576,7 @@ privsep_postauth(Authctxt *authctxt) | |||
576 | * Tell the packet layer that authentication was successful, since | 576 | * Tell the packet layer that authentication was successful, since |
577 | * this information is not part of the key state. | 577 | * this information is not part of the key state. |
578 | */ | 578 | */ |
579 | packet_set_authenticated(); | 579 | ssh_packet_set_authenticated(ssh); |
580 | } | 580 | } |
581 | 581 | ||
582 | static void | 582 | static void |
@@ -759,21 +759,29 @@ notify_hostkeys(struct ssh *ssh) | |||
759 | sshkey_ssh_name(key), fp); | 759 | sshkey_ssh_name(key), fp); |
760 | free(fp); | 760 | free(fp); |
761 | if (nkeys == 0) { | 761 | if (nkeys == 0) { |
762 | packet_start(SSH2_MSG_GLOBAL_REQUEST); | 762 | /* |
763 | packet_put_cstring("hostkeys-00@openssh.com"); | 763 | * Start building the request when we find the |
764 | packet_put_char(0); /* want-reply */ | 764 | * first usable key. |
765 | */ | ||
766 | if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || | ||
767 | (r = sshpkt_put_cstring(ssh, "hostkeys-00@openssh.com")) != 0 || | ||
768 | (r = sshpkt_put_u8(ssh, 0)) != 0) /* want reply */ | ||
769 | sshpkt_fatal(ssh, r, "%s: start request", __func__); | ||
765 | } | 770 | } |
771 | /* Append the key to the request */ | ||
766 | sshbuf_reset(buf); | 772 | sshbuf_reset(buf); |
767 | if ((r = sshkey_putb(key, buf)) != 0) | 773 | if ((r = sshkey_putb(key, buf)) != 0) |
768 | fatal("%s: couldn't put hostkey %d: %s", | 774 | fatal("%s: couldn't put hostkey %d: %s", |
769 | __func__, i, ssh_err(r)); | 775 | __func__, i, ssh_err(r)); |
770 | packet_put_string(sshbuf_ptr(buf), sshbuf_len(buf)); | 776 | if ((r = sshpkt_put_stringb(ssh, buf)) != 0) |
777 | sshpkt_fatal(ssh, r, "%s: append key", __func__); | ||
771 | nkeys++; | 778 | nkeys++; |
772 | } | 779 | } |
773 | debug3("%s: sent %u hostkeys", __func__, nkeys); | 780 | debug3("%s: sent %u hostkeys", __func__, nkeys); |
774 | if (nkeys == 0) | 781 | if (nkeys == 0) |
775 | fatal("%s: no hostkeys", __func__); | 782 | fatal("%s: no hostkeys", __func__); |
776 | packet_send(); | 783 | if ((r = sshpkt_send(ssh)) != 0) |
784 | sshpkt_fatal(ssh, r, "%s: send", __func__); | ||
777 | sshbuf_free(buf); | 785 | sshbuf_free(buf); |
778 | } | 786 | } |
779 | 787 | ||
@@ -1951,9 +1959,10 @@ main(int ac, char **av) | |||
1951 | * Register our connection. This turns encryption off because we do | 1959 | * Register our connection. This turns encryption off because we do |
1952 | * not have a key. | 1960 | * not have a key. |
1953 | */ | 1961 | */ |
1954 | packet_set_connection(sock_in, sock_out); | 1962 | if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL) |
1955 | packet_set_server(); | 1963 | fatal("Unable to create connection"); |
1956 | ssh = active_state; /* XXX */ | 1964 | ssh_packet_set_server(ssh); |
1965 | active_state = ssh; /* XXX needed elsewhere */ | ||
1957 | 1966 | ||
1958 | check_ip_options(ssh); | 1967 | check_ip_options(ssh); |
1959 | 1968 | ||
@@ -1963,7 +1972,7 @@ main(int ac, char **av) | |||
1963 | process_permitopen(ssh, &options); | 1972 | process_permitopen(ssh, &options); |
1964 | 1973 | ||
1965 | /* Set SO_KEEPALIVE if requested. */ | 1974 | /* Set SO_KEEPALIVE if requested. */ |
1966 | if (options.tcp_keep_alive && packet_connection_is_on_socket() && | 1975 | if (options.tcp_keep_alive && ssh_packet_connection_is_on_socket(ssh) && |
1967 | setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) | 1976 | setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) < 0) |
1968 | error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); | 1977 | error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); |
1969 | 1978 | ||
@@ -2012,10 +2021,11 @@ main(int ac, char **av) | |||
2012 | if (kex_exchange_identification(ssh, -1, options.version_addendum) != 0) | 2021 | if (kex_exchange_identification(ssh, -1, options.version_addendum) != 0) |
2013 | cleanup_exit(255); /* error already logged */ | 2022 | cleanup_exit(255); /* error already logged */ |
2014 | 2023 | ||
2015 | packet_set_nonblocking(); | 2024 | ssh_packet_set_nonblocking(ssh); |
2016 | 2025 | ||
2017 | /* allocate authentication context */ | 2026 | /* allocate authentication context */ |
2018 | authctxt = xcalloc(1, sizeof(*authctxt)); | 2027 | authctxt = xcalloc(1, sizeof(*authctxt)); |
2028 | ssh->authctxt = authctxt; | ||
2019 | 2029 | ||
2020 | authctxt->loginmsg = loginmsg; | 2030 | authctxt->loginmsg = loginmsg; |
2021 | 2031 | ||
@@ -2032,7 +2042,7 @@ main(int ac, char **av) | |||
2032 | auth_debug_reset(); | 2042 | auth_debug_reset(); |
2033 | 2043 | ||
2034 | if (use_privsep) { | 2044 | if (use_privsep) { |
2035 | if (privsep_preauth(authctxt) == 1) | 2045 | if (privsep_preauth(ssh) == 1) |
2036 | goto authenticated; | 2046 | goto authenticated; |
2037 | } else if (have_agent) { | 2047 | } else if (have_agent) { |
2038 | if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { | 2048 | if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { |
@@ -2043,8 +2053,7 @@ main(int ac, char **av) | |||
2043 | 2053 | ||
2044 | /* perform the key exchange */ | 2054 | /* perform the key exchange */ |
2045 | /* authenticate user and start session */ | 2055 | /* authenticate user and start session */ |
2046 | do_ssh2_kex(); | 2056 | do_ssh2_kex(ssh); |
2047 | ssh->authctxt = authctxt; | ||
2048 | do_authentication2(ssh); | 2057 | do_authentication2(ssh); |
2049 | 2058 | ||
2050 | /* | 2059 | /* |
@@ -2053,7 +2062,7 @@ main(int ac, char **av) | |||
2053 | */ | 2062 | */ |
2054 | if (use_privsep) { | 2063 | if (use_privsep) { |
2055 | mm_send_keystate(pmonitor); | 2064 | mm_send_keystate(pmonitor); |
2056 | packet_clear_keys(); | 2065 | ssh_packet_clear_keys(ssh); |
2057 | exit(0); | 2066 | exit(0); |
2058 | } | 2067 | } |
2059 | 2068 | ||
@@ -2093,11 +2102,11 @@ main(int ac, char **av) | |||
2093 | * file descriptor passing. | 2102 | * file descriptor passing. |
2094 | */ | 2103 | */ |
2095 | if (use_privsep) { | 2104 | if (use_privsep) { |
2096 | privsep_postauth(authctxt); | 2105 | privsep_postauth(ssh, authctxt); |
2097 | /* the monitor process [priv] will not return */ | 2106 | /* the monitor process [priv] will not return */ |
2098 | } | 2107 | } |
2099 | 2108 | ||
2100 | packet_set_timeout(options.client_alive_interval, | 2109 | ssh_packet_set_timeout(ssh, options.client_alive_interval, |
2101 | options.client_alive_count_max); | 2110 | options.client_alive_count_max); |
2102 | 2111 | ||
2103 | /* Try to send all our hostkeys to the client */ | 2112 | /* Try to send all our hostkeys to the client */ |
@@ -2107,7 +2116,7 @@ main(int ac, char **av) | |||
2107 | do_authenticated(ssh, authctxt); | 2116 | do_authenticated(ssh, authctxt); |
2108 | 2117 | ||
2109 | /* The connection has been terminated. */ | 2118 | /* The connection has been terminated. */ |
2110 | packet_get_bytes(&ibytes, &obytes); | 2119 | ssh_packet_get_bytes(ssh, &ibytes, &obytes); |
2111 | verbose("Transferred: sent %llu, received %llu bytes", | 2120 | verbose("Transferred: sent %llu, received %llu bytes", |
2112 | (unsigned long long)obytes, (unsigned long long)ibytes); | 2121 | (unsigned long long)obytes, (unsigned long long)ibytes); |
2113 | 2122 | ||
@@ -2122,7 +2131,7 @@ main(int ac, char **av) | |||
2122 | PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); | 2131 | PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); |
2123 | #endif | 2132 | #endif |
2124 | 2133 | ||
2125 | packet_close(); | 2134 | ssh_packet_close(ssh); |
2126 | 2135 | ||
2127 | if (use_privsep) | 2136 | if (use_privsep) |
2128 | mm_terminate(); | 2137 | mm_terminate(); |
@@ -2156,7 +2165,7 @@ sshd_hostkey_sign(struct sshkey *privkey, struct sshkey *pubkey, | |||
2156 | 2165 | ||
2157 | /* SSH2 key exchange */ | 2166 | /* SSH2 key exchange */ |
2158 | static void | 2167 | static void |
2159 | do_ssh2_kex(void) | 2168 | do_ssh2_kex(struct ssh *ssh) |
2160 | { | 2169 | { |
2161 | char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; | 2170 | char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; |
2162 | struct kex *kex; | 2171 | struct kex *kex; |
@@ -2177,16 +2186,16 @@ do_ssh2_kex(void) | |||
2177 | } | 2186 | } |
2178 | 2187 | ||
2179 | if (options.rekey_limit || options.rekey_interval) | 2188 | if (options.rekey_limit || options.rekey_interval) |
2180 | packet_set_rekey_limits(options.rekey_limit, | 2189 | ssh_packet_set_rekey_limits(ssh, options.rekey_limit, |
2181 | options.rekey_interval); | 2190 | options.rekey_interval); |
2182 | 2191 | ||
2183 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( | 2192 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( |
2184 | list_hostkey_types()); | 2193 | list_hostkey_types()); |
2185 | 2194 | ||
2186 | /* start key exchange */ | 2195 | /* start key exchange */ |
2187 | if ((r = kex_setup(active_state, myproposal)) != 0) | 2196 | if ((r = kex_setup(ssh, myproposal)) != 0) |
2188 | fatal("kex_setup: %s", ssh_err(r)); | 2197 | fatal("kex_setup: %s", ssh_err(r)); |
2189 | kex = active_state->kex; | 2198 | kex = ssh->kex; |
2190 | #ifdef WITH_OPENSSL | 2199 | #ifdef WITH_OPENSSL |
2191 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; | 2200 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; |
2192 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; | 2201 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; |
@@ -2205,7 +2214,7 @@ do_ssh2_kex(void) | |||
2205 | kex->host_key_index=&get_hostkey_index; | 2214 | kex->host_key_index=&get_hostkey_index; |
2206 | kex->sign = sshd_hostkey_sign; | 2215 | kex->sign = sshd_hostkey_sign; |
2207 | 2216 | ||
2208 | ssh_dispatch_run_fatal(active_state, DISPATCH_BLOCK, &kex->done); | 2217 | ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done); |
2209 | 2218 | ||
2210 | session_id2 = kex->session_id; | 2219 | session_id2 = kex->session_id; |
2211 | session_id2_len = kex->session_id_len; | 2220 | session_id2_len = kex->session_id_len; |