diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 120 |
1 files changed, 116 insertions, 4 deletions
@@ -123,6 +123,10 @@ | |||
123 | #include "version.h" | 123 | #include "version.h" |
124 | #include "ssherr.h" | 124 | #include "ssherr.h" |
125 | 125 | ||
126 | #ifdef USE_SECURITY_SESSION_API | ||
127 | #include <Security/AuthSession.h> | ||
128 | #endif | ||
129 | |||
126 | /* Re-exec fds */ | 130 | /* Re-exec fds */ |
127 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | 131 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) |
128 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) | 132 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) |
@@ -796,8 +800,8 @@ notify_hostkeys(struct ssh *ssh) | |||
796 | } | 800 | } |
797 | debug3("%s: sent %u hostkeys", __func__, nkeys); | 801 | debug3("%s: sent %u hostkeys", __func__, nkeys); |
798 | if (nkeys == 0) | 802 | if (nkeys == 0) |
799 | fatal("%s: no hostkeys", __func__); | 803 | debug3("%s: no hostkeys", __func__); |
800 | if ((r = sshpkt_send(ssh)) != 0) | 804 | else if ((r = sshpkt_send(ssh)) != 0) |
801 | sshpkt_fatal(ssh, r, "%s: send", __func__); | 805 | sshpkt_fatal(ssh, r, "%s: send", __func__); |
802 | sshbuf_free(buf); | 806 | sshbuf_free(buf); |
803 | } | 807 | } |
@@ -1769,7 +1773,8 @@ main(int ac, char **av) | |||
1769 | free(fp); | 1773 | free(fp); |
1770 | } | 1774 | } |
1771 | accumulate_host_timing_secret(cfg, NULL); | 1775 | accumulate_host_timing_secret(cfg, NULL); |
1772 | if (!sensitive_data.have_ssh2_key) { | 1776 | /* The GSSAPI key exchange can run without a host key */ |
1777 | if (!sensitive_data.have_ssh2_key && !options.gss_keyex) { | ||
1773 | logit("sshd: no hostkeys available -- exiting."); | 1778 | logit("sshd: no hostkeys available -- exiting."); |
1774 | exit(1); | 1779 | exit(1); |
1775 | } | 1780 | } |
@@ -2064,6 +2069,60 @@ main(int ac, char **av) | |||
2064 | rdomain == NULL ? "" : "\""); | 2069 | rdomain == NULL ? "" : "\""); |
2065 | free(laddr); | 2070 | free(laddr); |
2066 | 2071 | ||
2072 | #ifdef USE_SECURITY_SESSION_API | ||
2073 | /* | ||
2074 | * Create a new security session for use by the new user login if | ||
2075 | * the current session is the root session or we are not launched | ||
2076 | * by inetd (eg: debugging mode or server mode). We do not | ||
2077 | * necessarily need to create a session if we are launched from | ||
2078 | * inetd because Panther xinetd will create a session for us. | ||
2079 | * | ||
2080 | * The only case where this logic will fail is if there is an | ||
2081 | * inetd running in a non-root session which is not creating | ||
2082 | * new sessions for us. Then all the users will end up in the | ||
2083 | * same session (bad). | ||
2084 | * | ||
2085 | * When the client exits, the session will be destroyed for us | ||
2086 | * automatically. | ||
2087 | * | ||
2088 | * We must create the session before any credentials are stored | ||
2089 | * (including AFS pags, which happens a few lines below). | ||
2090 | */ | ||
2091 | { | ||
2092 | OSStatus err = 0; | ||
2093 | SecuritySessionId sid = 0; | ||
2094 | SessionAttributeBits sattrs = 0; | ||
2095 | |||
2096 | err = SessionGetInfo(callerSecuritySession, &sid, &sattrs); | ||
2097 | if (err) | ||
2098 | error("SessionGetInfo() failed with error %.8X", | ||
2099 | (unsigned) err); | ||
2100 | else | ||
2101 | debug("Current Session ID is %.8X / Session Attributes are %.8X", | ||
2102 | (unsigned) sid, (unsigned) sattrs); | ||
2103 | |||
2104 | if (inetd_flag && !(sattrs & sessionIsRoot)) | ||
2105 | debug("Running in inetd mode in a non-root session... " | ||
2106 | "assuming inetd created the session for us."); | ||
2107 | else { | ||
2108 | debug("Creating new security session..."); | ||
2109 | err = SessionCreate(0, sessionHasTTY | sessionIsRemote); | ||
2110 | if (err) | ||
2111 | error("SessionCreate() failed with error %.8X", | ||
2112 | (unsigned) err); | ||
2113 | |||
2114 | err = SessionGetInfo(callerSecuritySession, &sid, | ||
2115 | &sattrs); | ||
2116 | if (err) | ||
2117 | error("SessionGetInfo() failed with error %.8X", | ||
2118 | (unsigned) err); | ||
2119 | else | ||
2120 | debug("New Session ID is %.8X / Session Attributes are %.8X", | ||
2121 | (unsigned) sid, (unsigned) sattrs); | ||
2122 | } | ||
2123 | } | ||
2124 | #endif | ||
2125 | |||
2067 | /* | 2126 | /* |
2068 | * We don't want to listen forever unless the other side | 2127 | * We don't want to listen forever unless the other side |
2069 | * successfully authenticates itself. So we set up an alarm which is | 2128 | * successfully authenticates itself. So we set up an alarm which is |
@@ -2260,6 +2319,48 @@ do_ssh2_kex(struct ssh *ssh) | |||
2260 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( | 2319 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( |
2261 | list_hostkey_types()); | 2320 | list_hostkey_types()); |
2262 | 2321 | ||
2322 | #if defined(GSSAPI) && defined(WITH_OPENSSL) | ||
2323 | { | ||
2324 | char *orig; | ||
2325 | char *gss = NULL; | ||
2326 | char *newstr = NULL; | ||
2327 | orig = myproposal[PROPOSAL_KEX_ALGS]; | ||
2328 | |||
2329 | /* | ||
2330 | * If we don't have a host key, then there's no point advertising | ||
2331 | * the other key exchange algorithms | ||
2332 | */ | ||
2333 | |||
2334 | if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) | ||
2335 | orig = NULL; | ||
2336 | |||
2337 | if (options.gss_keyex) | ||
2338 | gss = ssh_gssapi_server_mechanisms(); | ||
2339 | else | ||
2340 | gss = NULL; | ||
2341 | |||
2342 | if (gss && orig) | ||
2343 | xasprintf(&newstr, "%s,%s", gss, orig); | ||
2344 | else if (gss) | ||
2345 | newstr = gss; | ||
2346 | else if (orig) | ||
2347 | newstr = orig; | ||
2348 | |||
2349 | /* | ||
2350 | * If we've got GSSAPI mechanisms, then we've got the 'null' host | ||
2351 | * key alg, but we can't tell people about it unless its the only | ||
2352 | * host key algorithm we support | ||
2353 | */ | ||
2354 | if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) | ||
2355 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; | ||
2356 | |||
2357 | if (newstr) | ||
2358 | myproposal[PROPOSAL_KEX_ALGS] = newstr; | ||
2359 | else | ||
2360 | fatal("No supported key exchange algorithms"); | ||
2361 | } | ||
2362 | #endif | ||
2363 | |||
2263 | /* start key exchange */ | 2364 | /* start key exchange */ |
2264 | if ((r = kex_setup(ssh, myproposal)) != 0) | 2365 | if ((r = kex_setup(ssh, myproposal)) != 0) |
2265 | fatal("kex_setup: %s", ssh_err(r)); | 2366 | fatal("kex_setup: %s", ssh_err(r)); |
@@ -2275,7 +2376,18 @@ do_ssh2_kex(struct ssh *ssh) | |||
2275 | # ifdef OPENSSL_HAS_ECC | 2376 | # ifdef OPENSSL_HAS_ECC |
2276 | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; | 2377 | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; |
2277 | # endif | 2378 | # endif |
2278 | #endif | 2379 | # ifdef GSSAPI |
2380 | if (options.gss_keyex) { | ||
2381 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | ||
2382 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | ||
2383 | kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; | ||
2384 | kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; | ||
2385 | kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; | ||
2386 | kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; | ||
2387 | kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; | ||
2388 | } | ||
2389 | # endif | ||
2390 | #endif /* WITH_OPENSSL */ | ||
2279 | kex->kex[KEX_C25519_SHA256] = kex_gen_server; | 2391 | kex->kex[KEX_C25519_SHA256] = kex_gen_server; |
2280 | kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; | 2392 | kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; |
2281 | kex->load_host_public_key=&get_hostkey_public_by_type; | 2393 | kex->load_host_public_key=&get_hostkey_public_by_type; |