diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 112 |
1 files changed, 111 insertions, 1 deletions
@@ -122,6 +122,10 @@ | |||
122 | #include "version.h" | 122 | #include "version.h" |
123 | #include "ssherr.h" | 123 | #include "ssherr.h" |
124 | 124 | ||
125 | #ifdef USE_SECURITY_SESSION_API | ||
126 | #include <Security/AuthSession.h> | ||
127 | #endif | ||
128 | |||
125 | /* Re-exec fds */ | 129 | /* Re-exec fds */ |
126 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | 130 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) |
127 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) | 131 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) |
@@ -529,7 +533,7 @@ privsep_preauth_child(void) | |||
529 | 533 | ||
530 | #ifdef GSSAPI | 534 | #ifdef GSSAPI |
531 | /* Cache supported mechanism OIDs for later use */ | 535 | /* Cache supported mechanism OIDs for later use */ |
532 | if (options.gss_authentication) | 536 | if (options.gss_authentication || options.gss_keyex) |
533 | ssh_gssapi_prepare_supported_oids(); | 537 | ssh_gssapi_prepare_supported_oids(); |
534 | #endif | 538 | #endif |
535 | 539 | ||
@@ -1708,10 +1712,13 @@ main(int ac, char **av) | |||
1708 | key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); | 1712 | key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); |
1709 | free(fp); | 1713 | free(fp); |
1710 | } | 1714 | } |
1715 | #ifndef GSSAPI | ||
1716 | /* The GSSAPI key exchange can run without a host key */ | ||
1711 | if (!sensitive_data.have_ssh2_key) { | 1717 | if (!sensitive_data.have_ssh2_key) { |
1712 | logit("sshd: no hostkeys available -- exiting."); | 1718 | logit("sshd: no hostkeys available -- exiting."); |
1713 | exit(1); | 1719 | exit(1); |
1714 | } | 1720 | } |
1721 | #endif | ||
1715 | 1722 | ||
1716 | /* | 1723 | /* |
1717 | * Load certificates. They are stored in an array at identical | 1724 | * Load certificates. They are stored in an array at identical |
@@ -1987,6 +1994,60 @@ main(int ac, char **av) | |||
1987 | remote_ip, remote_port, laddr, ssh_local_port(ssh)); | 1994 | remote_ip, remote_port, laddr, ssh_local_port(ssh)); |
1988 | free(laddr); | 1995 | free(laddr); |
1989 | 1996 | ||
1997 | #ifdef USE_SECURITY_SESSION_API | ||
1998 | /* | ||
1999 | * Create a new security session for use by the new user login if | ||
2000 | * the current session is the root session or we are not launched | ||
2001 | * by inetd (eg: debugging mode or server mode). We do not | ||
2002 | * necessarily need to create a session if we are launched from | ||
2003 | * inetd because Panther xinetd will create a session for us. | ||
2004 | * | ||
2005 | * The only case where this logic will fail is if there is an | ||
2006 | * inetd running in a non-root session which is not creating | ||
2007 | * new sessions for us. Then all the users will end up in the | ||
2008 | * same session (bad). | ||
2009 | * | ||
2010 | * When the client exits, the session will be destroyed for us | ||
2011 | * automatically. | ||
2012 | * | ||
2013 | * We must create the session before any credentials are stored | ||
2014 | * (including AFS pags, which happens a few lines below). | ||
2015 | */ | ||
2016 | { | ||
2017 | OSStatus err = 0; | ||
2018 | SecuritySessionId sid = 0; | ||
2019 | SessionAttributeBits sattrs = 0; | ||
2020 | |||
2021 | err = SessionGetInfo(callerSecuritySession, &sid, &sattrs); | ||
2022 | if (err) | ||
2023 | error("SessionGetInfo() failed with error %.8X", | ||
2024 | (unsigned) err); | ||
2025 | else | ||
2026 | debug("Current Session ID is %.8X / Session Attributes are %.8X", | ||
2027 | (unsigned) sid, (unsigned) sattrs); | ||
2028 | |||
2029 | if (inetd_flag && !(sattrs & sessionIsRoot)) | ||
2030 | debug("Running in inetd mode in a non-root session... " | ||
2031 | "assuming inetd created the session for us."); | ||
2032 | else { | ||
2033 | debug("Creating new security session..."); | ||
2034 | err = SessionCreate(0, sessionHasTTY | sessionIsRemote); | ||
2035 | if (err) | ||
2036 | error("SessionCreate() failed with error %.8X", | ||
2037 | (unsigned) err); | ||
2038 | |||
2039 | err = SessionGetInfo(callerSecuritySession, &sid, | ||
2040 | &sattrs); | ||
2041 | if (err) | ||
2042 | error("SessionGetInfo() failed with error %.8X", | ||
2043 | (unsigned) err); | ||
2044 | else | ||
2045 | debug("New Session ID is %.8X / Session Attributes are %.8X", | ||
2046 | (unsigned) sid, (unsigned) sattrs); | ||
2047 | } | ||
2048 | } | ||
2049 | #endif | ||
2050 | |||
1990 | /* | 2051 | /* |
1991 | * We don't want to listen forever unless the other side | 2052 | * We don't want to listen forever unless the other side |
1992 | * successfully authenticates itself. So we set up an alarm which is | 2053 | * successfully authenticates itself. So we set up an alarm which is |
@@ -2170,6 +2231,48 @@ do_ssh2_kex(void) | |||
2170 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( | 2231 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( |
2171 | list_hostkey_types()); | 2232 | list_hostkey_types()); |
2172 | 2233 | ||
2234 | #ifdef GSSAPI | ||
2235 | { | ||
2236 | char *orig; | ||
2237 | char *gss = NULL; | ||
2238 | char *newstr = NULL; | ||
2239 | orig = myproposal[PROPOSAL_KEX_ALGS]; | ||
2240 | |||
2241 | /* | ||
2242 | * If we don't have a host key, then there's no point advertising | ||
2243 | * the other key exchange algorithms | ||
2244 | */ | ||
2245 | |||
2246 | if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0) | ||
2247 | orig = NULL; | ||
2248 | |||
2249 | if (options.gss_keyex) | ||
2250 | gss = ssh_gssapi_server_mechanisms(); | ||
2251 | else | ||
2252 | gss = NULL; | ||
2253 | |||
2254 | if (gss && orig) | ||
2255 | xasprintf(&newstr, "%s,%s", gss, orig); | ||
2256 | else if (gss) | ||
2257 | newstr = gss; | ||
2258 | else if (orig) | ||
2259 | newstr = orig; | ||
2260 | |||
2261 | /* | ||
2262 | * If we've got GSSAPI mechanisms, then we've got the 'null' host | ||
2263 | * key alg, but we can't tell people about it unless its the only | ||
2264 | * host key algorithm we support | ||
2265 | */ | ||
2266 | if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0) | ||
2267 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null"; | ||
2268 | |||
2269 | if (newstr) | ||
2270 | myproposal[PROPOSAL_KEX_ALGS] = newstr; | ||
2271 | else | ||
2272 | fatal("No supported key exchange algorithms"); | ||
2273 | } | ||
2274 | #endif | ||
2275 | |||
2173 | /* start key exchange */ | 2276 | /* start key exchange */ |
2174 | if ((r = kex_setup(active_state, myproposal)) != 0) | 2277 | if ((r = kex_setup(active_state, myproposal)) != 0) |
2175 | fatal("kex_setup: %s", ssh_err(r)); | 2278 | fatal("kex_setup: %s", ssh_err(r)); |
@@ -2187,6 +2290,13 @@ do_ssh2_kex(void) | |||
2187 | # endif | 2290 | # endif |
2188 | #endif | 2291 | #endif |
2189 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; | 2292 | kex->kex[KEX_C25519_SHA256] = kexc25519_server; |
2293 | #ifdef GSSAPI | ||
2294 | if (options.gss_keyex) { | ||
2295 | kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server; | ||
2296 | kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server; | ||
2297 | kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server; | ||
2298 | } | ||
2299 | #endif | ||
2190 | kex->server = 1; | 2300 | kex->server = 1; |
2191 | kex->client_version_string=client_version_string; | 2301 | kex->client_version_string=client_version_string; |
2192 | kex->server_version_string=server_version_string; | 2302 | kex->server_version_string=server_version_string; |