diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 112 |
1 files changed, 111 insertions, 1 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) |
@@ -531,7 +535,7 @@ privsep_preauth_child(void) | |||
531 | 535 | ||
532 | #ifdef GSSAPI | 536 | #ifdef GSSAPI |
533 | /* Cache supported mechanism OIDs for later use */ | 537 | /* Cache supported mechanism OIDs for later use */ |
534 | if (options.gss_authentication) | 538 | if (options.gss_authentication || options.gss_keyex) |
535 | ssh_gssapi_prepare_supported_oids(); | 539 | ssh_gssapi_prepare_supported_oids(); |
536 | #endif | 540 | #endif |
537 | 541 | ||
@@ -1753,10 +1757,13 @@ main(int ac, char **av) | |||
1753 | key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); | 1757 | key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); |
1754 | free(fp); | 1758 | free(fp); |
1755 | } | 1759 | } |
1760 | #ifndef GSSAPI | ||
1761 | /* The GSSAPI key exchange can run without a host key */ | ||
1756 | if (!sensitive_data.have_ssh2_key) { | 1762 | if (!sensitive_data.have_ssh2_key) { |
1757 | logit("sshd: no hostkeys available -- exiting."); | 1763 | logit("sshd: no hostkeys available -- exiting."); |
1758 | exit(1); | 1764 | exit(1); |
1759 | } | 1765 | } |
1766 | #endif | ||
1760 | 1767 | ||
1761 | /* | 1768 | /* |
1762 | * Load certificates. They are stored in an array at identical | 1769 | * Load certificates. They are stored in an array at identical |
@@ -2047,6 +2054,60 @@ main(int ac, char **av) | |||
2047 | rdomain == NULL ? "" : "\""); | 2054 | rdomain == NULL ? "" : "\""); |
2048 | free(laddr); | 2055 | free(laddr); |
2049 | 2056 | ||
2057 | #ifdef USE_SECURITY_SESSION_API | ||
2058 | /* | ||
2059 | * Create a new security session for use by the new user login if | ||
2060 | * the current session is the root session or we are not launched | ||
2061 | * by inetd (eg: debugging mode or server mode). We do not | ||
2062 | * necessarily need to create a session if we are launched from | ||
2063 | * inetd because Panther xinetd will create a session for us. | ||
2064 | * | ||
2065 | * The only case where this logic will fail is if there is an | ||
2066 | * inetd running in a non-root session which is not creating | ||
2067 | * new sessions for us. Then all the users will end up in the | ||
2068 | * same session (bad). | ||
2069 | * | ||
2070 | * When the client exits, the session will be destroyed for us | ||
2071 | * automatically. | ||
2072 | * | ||
2073 | * We must create the session before any credentials are stored | ||
2074 | * (including AFS pags, which happens a few lines below). | ||
2075 | */ | ||
2076 | { | ||
2077 | OSStatus err = 0; | ||
2078 | SecuritySessionId sid = 0; | ||
2079 | SessionAttributeBits sattrs = 0; | ||
2080 | |||
2081 | err = SessionGetInfo(callerSecuritySession, &sid, &sattrs); | ||
2082 | if (err) | ||
2083 | error("SessionGetInfo() failed with error %.8X", | ||
2084 | (unsigned) err); | ||
2085 | else | ||
2086 | debug("Current Session ID is %.8X / Session Attributes are %.8X", | ||
2087 | (unsigned) sid, (unsigned) sattrs); | ||
2088 | |||
2089 | if (inetd_flag && !(sattrs & sessionIsRoot)) | ||
2090 | debug("Running in inetd mode in a non-root session... " | ||
2091 | "assuming inetd created the session for us."); | ||
2092 | else { | ||
2093 | debug("Creating new security session..."); | ||
2094 | err = SessionCreate(0, sessionHasTTY | sessionIsRemote); | ||
2095 | if (err) | ||
2096 | error("SessionCreate() failed with error %.8X", | ||
2097 | (unsigned) err); | ||
2098 | |||
2099 | err = SessionGetInfo(callerSecuritySession, &sid, | ||
2100 | &sattrs); | ||
2101 | if (err) | ||
2102 | error("SessionGetInfo() failed with error %.8X", | ||
2103 | (unsigned) err); | ||
2104 | else | ||
2105 | debug("New Session ID is %.8X / Session Attributes are %.8X", | ||
2106 | (unsigned) sid, (unsigned) sattrs); | ||
2107 | } | ||
2108 | } | ||
2109 | #endif | ||
2110 | |||
2050 | /* | 2111 | /* |
2051 | * We don't want to listen forever unless the other side | 2112 | * We don't want to listen forever unless the other side |
2052 | * successfully authenticates itself. So we set up an alarm which is | 2113 | * successfully authenticates itself. So we set up an alarm which is |
@@ -2234,6 +2295,48 @@ do_ssh2_kex(void) | |||
2234 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( | 2295 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( |
2235 | list_hostkey_types()); | 2296 | list_hostkey_types()); |
2236 | 2297 | ||
2298 | #ifdef GSSAPI | ||
2299 | { | ||
2300 | char *orig; | ||
2301 | char *gss = NULL; | ||
2302 | char *newstr = NULL; | ||
2303 | orig = myproposal[PROPOSAL_KEX_ALGS]; | ||
2304 | |||
2305 | /* | ||
2306 | * If we don't have a host key, then there's no point advertising | ||
2307 | * the other key exchange algorithms | ||
2308 | */ | ||
2309 | |||
2310 | if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) | ||
2311 | orig = NULL; | ||
2312 | |||
2313 | if (options.gss_keyex) | ||
2314 | gss = ssh_gssapi_server_mechanisms(); | ||
2315 | else | ||
2316 | gss = NULL; | ||
2317 | |||
2318 | if (gss && orig) | ||
2319 | xasprintf(&newstr, "%s,%s", gss, orig); | ||
2320 | else if (gss) | ||
2321 | newstr = gss; | ||
2322 | else if (orig) | ||
2323 | newstr = orig; | ||
2324 | |||
2325 | /* | ||
2326 | * If we've got GSSAPI mechanisms, then we've got the 'null' host | ||
2327 | * key alg, but we can't tell people about it unless its the only | ||
2328 | * host key algorithm we support | ||
2329 | */ | ||
2330 | if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) | ||
2331 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; | ||
2332 | |||
2333 | if (newstr) | ||
2334 | myproposal[PROPOSAL_KEX_ALGS] = newstr; | ||
2335 | else | ||
2336 | fatal("No supported key exchange algorithms"); | ||
2337 | } | ||
2338 | #endif | ||
2339 | |||
2237 | /* start key exchange */ | 2340 | /* start key exchange */ |
2238 | if ((r = kex_setup(active_state, myproposal)) != 0) | 2341 | if ((r = kex_setup(active_state, myproposal)) != 0) |
2239 | fatal("kex_setup: %s", ssh_err(r)); | 2342 | fatal("kex_setup: %s", ssh_err(r)); |
@@ -2251,6 +2354,13 @@ do_ssh2_kex(void) | |||
2251 | # endif | 2354 | # endif |
2252 | #endif | 2355 | #endif |
2253 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; | 2356 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; |
2357 | #ifdef GSSAPI | ||
2358 | if (options.gss_keyex) { | ||
2359 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | ||
2360 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | ||
2361 | kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; | ||
2362 | } | ||
2363 | #endif | ||
2254 | kex->server = 1; | 2364 | kex->server = 1; |
2255 | kex->client_version_string=client_version_string; | 2365 | kex->client_version_string=client_version_string; |
2256 | kex->server_version_string=server_version_string; | 2366 | kex->server_version_string=server_version_string; |