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 | } |
@@ -1773,7 +1777,8 @@ main(int ac, char **av) | |||
1773 | free(fp); | 1777 | free(fp); |
1774 | } | 1778 | } |
1775 | accumulate_host_timing_secret(cfg, NULL); | 1779 | accumulate_host_timing_secret(cfg, NULL); |
1776 | if (!sensitive_data.have_ssh2_key) { | 1780 | /* The GSSAPI key exchange can run without a host key */ |
1781 | if (!sensitive_data.have_ssh2_key && !options.gss_keyex) { | ||
1777 | logit("sshd: no hostkeys available -- exiting."); | 1782 | logit("sshd: no hostkeys available -- exiting."); |
1778 | exit(1); | 1783 | exit(1); |
1779 | } | 1784 | } |
@@ -2069,6 +2074,60 @@ main(int ac, char **av) | |||
2069 | rdomain == NULL ? "" : "\""); | 2074 | rdomain == NULL ? "" : "\""); |
2070 | free(laddr); | 2075 | free(laddr); |
2071 | 2076 | ||
2077 | #ifdef USE_SECURITY_SESSION_API | ||
2078 | /* | ||
2079 | * Create a new security session for use by the new user login if | ||
2080 | * the current session is the root session or we are not launched | ||
2081 | * by inetd (eg: debugging mode or server mode). We do not | ||
2082 | * necessarily need to create a session if we are launched from | ||
2083 | * inetd because Panther xinetd will create a session for us. | ||
2084 | * | ||
2085 | * The only case where this logic will fail is if there is an | ||
2086 | * inetd running in a non-root session which is not creating | ||
2087 | * new sessions for us. Then all the users will end up in the | ||
2088 | * same session (bad). | ||
2089 | * | ||
2090 | * When the client exits, the session will be destroyed for us | ||
2091 | * automatically. | ||
2092 | * | ||
2093 | * We must create the session before any credentials are stored | ||
2094 | * (including AFS pags, which happens a few lines below). | ||
2095 | */ | ||
2096 | { | ||
2097 | OSStatus err = 0; | ||
2098 | SecuritySessionId sid = 0; | ||
2099 | SessionAttributeBits sattrs = 0; | ||
2100 | |||
2101 | err = SessionGetInfo(callerSecuritySession, &sid, &sattrs); | ||
2102 | if (err) | ||
2103 | error("SessionGetInfo() failed with error %.8X", | ||
2104 | (unsigned) err); | ||
2105 | else | ||
2106 | debug("Current Session ID is %.8X / Session Attributes are %.8X", | ||
2107 | (unsigned) sid, (unsigned) sattrs); | ||
2108 | |||
2109 | if (inetd_flag && !(sattrs & sessionIsRoot)) | ||
2110 | debug("Running in inetd mode in a non-root session... " | ||
2111 | "assuming inetd created the session for us."); | ||
2112 | else { | ||
2113 | debug("Creating new security session..."); | ||
2114 | err = SessionCreate(0, sessionHasTTY | sessionIsRemote); | ||
2115 | if (err) | ||
2116 | error("SessionCreate() failed with error %.8X", | ||
2117 | (unsigned) err); | ||
2118 | |||
2119 | err = SessionGetInfo(callerSecuritySession, &sid, | ||
2120 | &sattrs); | ||
2121 | if (err) | ||
2122 | error("SessionGetInfo() failed with error %.8X", | ||
2123 | (unsigned) err); | ||
2124 | else | ||
2125 | debug("New Session ID is %.8X / Session Attributes are %.8X", | ||
2126 | (unsigned) sid, (unsigned) sattrs); | ||
2127 | } | ||
2128 | } | ||
2129 | #endif | ||
2130 | |||
2072 | /* | 2131 | /* |
2073 | * We don't want to listen forever unless the other side | 2132 | * We don't want to listen forever unless the other side |
2074 | * successfully authenticates itself. So we set up an alarm which is | 2133 | * successfully authenticates itself. So we set up an alarm which is |
@@ -2265,6 +2324,48 @@ do_ssh2_kex(struct ssh *ssh) | |||
2265 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( | 2324 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( |
2266 | list_hostkey_types()); | 2325 | list_hostkey_types()); |
2267 | 2326 | ||
2327 | #if defined(GSSAPI) && defined(WITH_OPENSSL) | ||
2328 | { | ||
2329 | char *orig; | ||
2330 | char *gss = NULL; | ||
2331 | char *newstr = NULL; | ||
2332 | orig = myproposal[PROPOSAL_KEX_ALGS]; | ||
2333 | |||
2334 | /* | ||
2335 | * If we don't have a host key, then there's no point advertising | ||
2336 | * the other key exchange algorithms | ||
2337 | */ | ||
2338 | |||
2339 | if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) | ||
2340 | orig = NULL; | ||
2341 | |||
2342 | if (options.gss_keyex) | ||
2343 | gss = ssh_gssapi_server_mechanisms(); | ||
2344 | else | ||
2345 | gss = NULL; | ||
2346 | |||
2347 | if (gss && orig) | ||
2348 | xasprintf(&newstr, "%s,%s", gss, orig); | ||
2349 | else if (gss) | ||
2350 | newstr = gss; | ||
2351 | else if (orig) | ||
2352 | newstr = orig; | ||
2353 | |||
2354 | /* | ||
2355 | * If we've got GSSAPI mechanisms, then we've got the 'null' host | ||
2356 | * key alg, but we can't tell people about it unless its the only | ||
2357 | * host key algorithm we support | ||
2358 | */ | ||
2359 | if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) | ||
2360 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; | ||
2361 | |||
2362 | if (newstr) | ||
2363 | myproposal[PROPOSAL_KEX_ALGS] = newstr; | ||
2364 | else | ||
2365 | fatal("No supported key exchange algorithms"); | ||
2366 | } | ||
2367 | #endif | ||
2368 | |||
2268 | /* start key exchange */ | 2369 | /* start key exchange */ |
2269 | if ((r = kex_setup(ssh, myproposal)) != 0) | 2370 | if ((r = kex_setup(ssh, myproposal)) != 0) |
2270 | fatal("kex_setup: %s", ssh_err(r)); | 2371 | fatal("kex_setup: %s", ssh_err(r)); |
@@ -2280,7 +2381,18 @@ do_ssh2_kex(struct ssh *ssh) | |||
2280 | # ifdef OPENSSL_HAS_ECC | 2381 | # ifdef OPENSSL_HAS_ECC |
2281 | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; | 2382 | kex->kex[KEX_ECDH_SHA2] = kex_gen_server; |
2282 | # endif | 2383 | # endif |
2283 | #endif | 2384 | # ifdef GSSAPI |
2385 | if (options.gss_keyex) { | ||
2386 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | ||
2387 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | ||
2388 | kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server; | ||
2389 | kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server; | ||
2390 | kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server; | ||
2391 | kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server; | ||
2392 | kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server; | ||
2393 | } | ||
2394 | # endif | ||
2395 | #endif /* WITH_OPENSSL */ | ||
2284 | kex->kex[KEX_C25519_SHA256] = kex_gen_server; | 2396 | kex->kex[KEX_C25519_SHA256] = kex_gen_server; |
2285 | kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; | 2397 | kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; |
2286 | kex->load_host_public_key=&get_hostkey_public_by_type; | 2398 | kex->load_host_public_key=&get_hostkey_public_by_type; |