diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 62 |
1 files changed, 50 insertions, 12 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.420 2014/02/26 21:53:37 markus Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.428 2014/07/15 15:54:14 millert 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 |
@@ -72,10 +72,12 @@ | |||
72 | #include <string.h> | 72 | #include <string.h> |
73 | #include <unistd.h> | 73 | #include <unistd.h> |
74 | 74 | ||
75 | #ifdef WITH_OPENSSL | ||
75 | #include <openssl/dh.h> | 76 | #include <openssl/dh.h> |
76 | #include <openssl/bn.h> | 77 | #include <openssl/bn.h> |
77 | #include <openssl/rand.h> | 78 | #include <openssl/rand.h> |
78 | #include "openbsd-compat/openssl-compat.h" | 79 | #include "openbsd-compat/openssl-compat.h" |
80 | #endif | ||
79 | 81 | ||
80 | #ifdef HAVE_SECUREWARE | 82 | #ifdef HAVE_SECUREWARE |
81 | #include <sys/security.h> | 83 | #include <sys/security.h> |
@@ -91,6 +93,7 @@ | |||
91 | #include "packet.h" | 93 | #include "packet.h" |
92 | #include "log.h" | 94 | #include "log.h" |
93 | #include "buffer.h" | 95 | #include "buffer.h" |
96 | #include "misc.h" | ||
94 | #include "servconf.h" | 97 | #include "servconf.h" |
95 | #include "uidswap.h" | 98 | #include "uidswap.h" |
96 | #include "compat.h" | 99 | #include "compat.h" |
@@ -98,7 +101,6 @@ | |||
98 | #include "digest.h" | 101 | #include "digest.h" |
99 | #include "key.h" | 102 | #include "key.h" |
100 | #include "kex.h" | 103 | #include "kex.h" |
101 | #include "dh.h" | ||
102 | #include "myproposal.h" | 104 | #include "myproposal.h" |
103 | #include "authfile.h" | 105 | #include "authfile.h" |
104 | #include "pathnames.h" | 106 | #include "pathnames.h" |
@@ -107,7 +109,6 @@ | |||
107 | #include "hostfile.h" | 109 | #include "hostfile.h" |
108 | #include "auth.h" | 110 | #include "auth.h" |
109 | #include "authfd.h" | 111 | #include "authfd.h" |
110 | #include "misc.h" | ||
111 | #include "msg.h" | 112 | #include "msg.h" |
112 | #include "dispatch.h" | 113 | #include "dispatch.h" |
113 | #include "channels.h" | 114 | #include "channels.h" |
@@ -267,7 +268,9 @@ struct passwd *privsep_pw = NULL; | |||
267 | void destroy_sensitive_data(void); | 268 | void destroy_sensitive_data(void); |
268 | void demote_sensitive_data(void); | 269 | void demote_sensitive_data(void); |
269 | 270 | ||
271 | #ifdef WITH_SSH1 | ||
270 | static void do_ssh1_kex(void); | 272 | static void do_ssh1_kex(void); |
273 | #endif | ||
271 | static void do_ssh2_kex(void); | 274 | static void do_ssh2_kex(void); |
272 | 275 | ||
273 | /* | 276 | /* |
@@ -943,7 +946,13 @@ static void | |||
943 | usage(void) | 946 | usage(void) |
944 | { | 947 | { |
945 | fprintf(stderr, "%s, %s\n", | 948 | fprintf(stderr, "%s, %s\n", |
946 | SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); | 949 | SSH_RELEASE, |
950 | #ifdef WITH_OPENSSL | ||
951 | SSLeay_version(SSLEAY_VERSION) | ||
952 | #else | ||
953 | "without OpenSSL" | ||
954 | #endif | ||
955 | ); | ||
947 | fprintf(stderr, | 956 | fprintf(stderr, |
948 | "usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" | 957 | "usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" |
949 | " [-E log_file] [-f config_file] [-g login_grace_time]\n" | 958 | " [-E log_file] [-f config_file] [-g login_grace_time]\n" |
@@ -976,6 +985,7 @@ send_rexec_state(int fd, Buffer *conf) | |||
976 | buffer_init(&m); | 985 | buffer_init(&m); |
977 | buffer_put_cstring(&m, buffer_ptr(conf)); | 986 | buffer_put_cstring(&m, buffer_ptr(conf)); |
978 | 987 | ||
988 | #ifdef WITH_SSH1 | ||
979 | if (sensitive_data.server_key != NULL && | 989 | if (sensitive_data.server_key != NULL && |
980 | sensitive_data.server_key->type == KEY_RSA1) { | 990 | sensitive_data.server_key->type == KEY_RSA1) { |
981 | buffer_put_int(&m, 1); | 991 | buffer_put_int(&m, 1); |
@@ -986,6 +996,7 @@ send_rexec_state(int fd, Buffer *conf) | |||
986 | buffer_put_bignum(&m, sensitive_data.server_key->rsa->p); | 996 | buffer_put_bignum(&m, sensitive_data.server_key->rsa->p); |
987 | buffer_put_bignum(&m, sensitive_data.server_key->rsa->q); | 997 | buffer_put_bignum(&m, sensitive_data.server_key->rsa->q); |
988 | } else | 998 | } else |
999 | #endif | ||
989 | buffer_put_int(&m, 0); | 1000 | buffer_put_int(&m, 0); |
990 | 1001 | ||
991 | #ifndef OPENSSL_PRNG_ONLY | 1002 | #ifndef OPENSSL_PRNG_ONLY |
@@ -1022,6 +1033,7 @@ recv_rexec_state(int fd, Buffer *conf) | |||
1022 | free(cp); | 1033 | free(cp); |
1023 | 1034 | ||
1024 | if (buffer_get_int(&m)) { | 1035 | if (buffer_get_int(&m)) { |
1036 | #ifdef WITH_SSH1 | ||
1025 | if (sensitive_data.server_key != NULL) | 1037 | if (sensitive_data.server_key != NULL) |
1026 | key_free(sensitive_data.server_key); | 1038 | key_free(sensitive_data.server_key); |
1027 | sensitive_data.server_key = key_new_private(KEY_RSA1); | 1039 | sensitive_data.server_key = key_new_private(KEY_RSA1); |
@@ -1031,8 +1043,13 @@ recv_rexec_state(int fd, Buffer *conf) | |||
1031 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); | 1043 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp); |
1032 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); | 1044 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->p); |
1033 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); | 1045 | buffer_get_bignum(&m, sensitive_data.server_key->rsa->q); |
1034 | rsa_generate_additional_parameters( | 1046 | if (rsa_generate_additional_parameters( |
1035 | sensitive_data.server_key->rsa); | 1047 | sensitive_data.server_key->rsa) != 0) |
1048 | fatal("%s: rsa_generate_additional_parameters " | ||
1049 | "error", __func__); | ||
1050 | #else | ||
1051 | fatal("ssh1 not supported"); | ||
1052 | #endif | ||
1036 | } | 1053 | } |
1037 | 1054 | ||
1038 | #ifndef OPENSSL_PRNG_ONLY | 1055 | #ifndef OPENSSL_PRNG_ONLY |
@@ -1555,7 +1572,9 @@ main(int ac, char **av) | |||
1555 | else | 1572 | else |
1556 | closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); | 1573 | closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); |
1557 | 1574 | ||
1575 | #ifdef WITH_OPENSSL | ||
1558 | OpenSSL_add_all_algorithms(); | 1576 | OpenSSL_add_all_algorithms(); |
1577 | #endif | ||
1559 | 1578 | ||
1560 | /* If requested, redirect the logs to the specified logfile. */ | 1579 | /* If requested, redirect the logs to the specified logfile. */ |
1561 | if (logfile != NULL) { | 1580 | if (logfile != NULL) { |
@@ -1660,7 +1679,12 @@ main(int ac, char **av) | |||
1660 | } | 1679 | } |
1661 | 1680 | ||
1662 | debug("sshd version %s, %s", SSH_VERSION, | 1681 | debug("sshd version %s, %s", SSH_VERSION, |
1663 | SSLeay_version(SSLEAY_VERSION)); | 1682 | #ifdef WITH_OPENSSL |
1683 | SSLeay_version(SSLEAY_VERSION) | ||
1684 | #else | ||
1685 | "without OpenSSL" | ||
1686 | #endif | ||
1687 | ); | ||
1664 | 1688 | ||
1665 | /* Store privilege separation user for later use if required. */ | 1689 | /* Store privilege separation user for later use if required. */ |
1666 | if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { | 1690 | if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { |
@@ -1785,6 +1809,8 @@ main(int ac, char **av) | |||
1785 | debug("host certificate: #%d type %d %s", j, key->type, | 1809 | debug("host certificate: #%d type %d %s", j, key->type, |
1786 | key_type(key)); | 1810 | key_type(key)); |
1787 | } | 1811 | } |
1812 | |||
1813 | #ifdef WITH_SSH1 | ||
1788 | /* Check certain values for sanity. */ | 1814 | /* Check certain values for sanity. */ |
1789 | if (options.protocol & SSH_PROTO_1) { | 1815 | if (options.protocol & SSH_PROTO_1) { |
1790 | if (options.server_key_bits < 512 || | 1816 | if (options.server_key_bits < 512 || |
@@ -1809,6 +1835,7 @@ main(int ac, char **av) | |||
1809 | options.server_key_bits); | 1835 | options.server_key_bits); |
1810 | } | 1836 | } |
1811 | } | 1837 | } |
1838 | #endif | ||
1812 | 1839 | ||
1813 | if (use_privsep) { | 1840 | if (use_privsep) { |
1814 | struct stat st; | 1841 | struct stat st; |
@@ -2174,8 +2201,12 @@ main(int ac, char **av) | |||
2174 | do_ssh2_kex(); | 2201 | do_ssh2_kex(); |
2175 | do_authentication2(authctxt); | 2202 | do_authentication2(authctxt); |
2176 | } else { | 2203 | } else { |
2204 | #ifdef WITH_SSH1 | ||
2177 | do_ssh1_kex(); | 2205 | do_ssh1_kex(); |
2178 | do_authentication(authctxt); | 2206 | do_authentication(authctxt); |
2207 | #else | ||
2208 | fatal("ssh1 not supported"); | ||
2209 | #endif | ||
2179 | } | 2210 | } |
2180 | /* | 2211 | /* |
2181 | * If we use privilege separation, the unprivileged child transfers | 2212 | * If we use privilege separation, the unprivileged child transfers |
@@ -2259,6 +2290,7 @@ main(int ac, char **av) | |||
2259 | exit(0); | 2290 | exit(0); |
2260 | } | 2291 | } |
2261 | 2292 | ||
2293 | #ifdef WITH_SSH1 | ||
2262 | /* | 2294 | /* |
2263 | * Decrypt session_key_int using our private server key and private host key | 2295 | * Decrypt session_key_int using our private server key and private host key |
2264 | * (key with larger modulus first). | 2296 | * (key with larger modulus first). |
@@ -2282,10 +2314,10 @@ ssh1_session_key(BIGNUM *session_key_int) | |||
2282 | SSH_KEY_BITS_RESERVED); | 2314 | SSH_KEY_BITS_RESERVED); |
2283 | } | 2315 | } |
2284 | if (rsa_private_decrypt(session_key_int, session_key_int, | 2316 | if (rsa_private_decrypt(session_key_int, session_key_int, |
2285 | sensitive_data.server_key->rsa) <= 0) | 2317 | sensitive_data.server_key->rsa) != 0) |
2286 | rsafail++; | 2318 | rsafail++; |
2287 | if (rsa_private_decrypt(session_key_int, session_key_int, | 2319 | if (rsa_private_decrypt(session_key_int, session_key_int, |
2288 | sensitive_data.ssh1_host_key->rsa) <= 0) | 2320 | sensitive_data.ssh1_host_key->rsa) != 0) |
2289 | rsafail++; | 2321 | rsafail++; |
2290 | } else { | 2322 | } else { |
2291 | /* Host key has bigger modulus (or they are equal). */ | 2323 | /* Host key has bigger modulus (or they are equal). */ |
@@ -2300,14 +2332,15 @@ ssh1_session_key(BIGNUM *session_key_int) | |||
2300 | SSH_KEY_BITS_RESERVED); | 2332 | SSH_KEY_BITS_RESERVED); |
2301 | } | 2333 | } |
2302 | if (rsa_private_decrypt(session_key_int, session_key_int, | 2334 | if (rsa_private_decrypt(session_key_int, session_key_int, |
2303 | sensitive_data.ssh1_host_key->rsa) < 0) | 2335 | sensitive_data.ssh1_host_key->rsa) != 0) |
2304 | rsafail++; | 2336 | rsafail++; |
2305 | if (rsa_private_decrypt(session_key_int, session_key_int, | 2337 | if (rsa_private_decrypt(session_key_int, session_key_int, |
2306 | sensitive_data.server_key->rsa) < 0) | 2338 | sensitive_data.server_key->rsa) != 0) |
2307 | rsafail++; | 2339 | rsafail++; |
2308 | } | 2340 | } |
2309 | return (rsafail); | 2341 | return (rsafail); |
2310 | } | 2342 | } |
2343 | |||
2311 | /* | 2344 | /* |
2312 | * SSH1 key exchange | 2345 | * SSH1 key exchange |
2313 | */ | 2346 | */ |
@@ -2485,6 +2518,7 @@ do_ssh1_kex(void) | |||
2485 | packet_send(); | 2518 | packet_send(); |
2486 | packet_write_wait(); | 2519 | packet_write_wait(); |
2487 | } | 2520 | } |
2521 | #endif | ||
2488 | 2522 | ||
2489 | void | 2523 | void |
2490 | sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen, | 2524 | sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen, |
@@ -2509,6 +2543,7 @@ sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen, | |||
2509 | static void | 2543 | static void |
2510 | do_ssh2_kex(void) | 2544 | do_ssh2_kex(void) |
2511 | { | 2545 | { |
2546 | char *myproposal[PROPOSAL_MAX] = { KEX_SERVER }; | ||
2512 | Kex *kex; | 2547 | Kex *kex; |
2513 | 2548 | ||
2514 | if (options.ciphers != NULL) { | 2549 | if (options.ciphers != NULL) { |
@@ -2588,11 +2623,13 @@ do_ssh2_kex(void) | |||
2588 | 2623 | ||
2589 | /* start key exchange */ | 2624 | /* start key exchange */ |
2590 | kex = kex_setup(myproposal); | 2625 | kex = kex_setup(myproposal); |
2626 | #ifdef WITH_OPENSSL | ||
2591 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; | 2627 | kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; |
2592 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; | 2628 | kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server; |
2593 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; | 2629 | kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; |
2594 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; | 2630 | kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; |
2595 | kex->kex[KEX_ECDH_SHA2] = kexecdh_server; | 2631 | kex->kex[KEX_ECDH_SHA2] = kexecdh_server; |
2632 | #endif | ||
2596 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; | 2633 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; |
2597 | #ifdef GSSAPI | 2634 | #ifdef GSSAPI |
2598 | if (options.gss_keyex) { | 2635 | if (options.gss_keyex) { |
@@ -2632,7 +2669,8 @@ cleanup_exit(int i) | |||
2632 | { | 2669 | { |
2633 | if (the_authctxt) { | 2670 | if (the_authctxt) { |
2634 | do_cleanup(the_authctxt); | 2671 | do_cleanup(the_authctxt); |
2635 | if (use_privsep && privsep_is_preauth && pmonitor->m_pid > 1) { | 2672 | if (use_privsep && privsep_is_preauth && |
2673 | pmonitor != NULL && pmonitor->m_pid > 1) { | ||
2636 | debug("Killing privsep child %d", pmonitor->m_pid); | 2674 | debug("Killing privsep child %d", pmonitor->m_pid); |
2637 | if (kill(pmonitor->m_pid, SIGKILL) != 0 && | 2675 | if (kill(pmonitor->m_pid, SIGKILL) != 0 && |
2638 | errno != ESRCH) | 2676 | errno != ESRCH) |