summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorSimon Wilkinson <simon@sxw.org.uk>2014-02-09 16:09:48 +0000
committerColin Watson <cjwatson@debian.org>2018-04-03 08:20:56 +0100
commitcb427e23bf78d65407c78d868c4ef525dbfaa68f (patch)
tree595fd02db7d37d885ce1d309f50c6b9698ed4243 /sshd.c
parented6ae9c1a014a08ff5db3d768f01f2e427eeb476 (diff)
GSSAPI key exchange support
This patch has been rejected upstream: "None of the OpenSSH developers are in favour of adding this, and this situation has not changed for several years. This is not a slight on Simon's patch, which is of fine quality, but just that a) we don't trust GSSAPI implementations that much and b) we don't like adding new KEX since they are pre-auth attack surface. This one is particularly scary, since it requires hooks out to typically root-owned system resources." However, quite a lot of people rely on this in Debian, and it's better to have it merged into the main openssh package rather than having separate -krb5 packages (as we used to have). It seems to have a generally good security history. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2017-10-04 Patch-Name: gssapi.patch
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c112
1 files changed, 111 insertions, 1 deletions
diff --git a/sshd.c b/sshd.c
index fd95b681b..e88185efa 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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;