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-10-20 22:54:00 +0100
commit72b1d308e6400194ef6e4e7dd45bfa48fa39b5e6 (patch)
tree2a3b57ae5446f4273804064ccc42659adfc2a3b2 /sshd.c
parent3d246f10429fc9a37b98eabef94fe8dc7c61002b (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: 2018-10-20 Patch-Name: gssapi.patch
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/sshd.c b/sshd.c
index ba26287ba..539a000fd 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)
@@ -1810,10 +1814,13 @@ main(int ac, char **av)
1810 free(fp); 1814 free(fp);
1811 } 1815 }
1812 accumulate_host_timing_secret(cfg, NULL); 1816 accumulate_host_timing_secret(cfg, NULL);
1817#ifndef GSSAPI
1818 /* The GSSAPI key exchange can run without a host key */
1813 if (!sensitive_data.have_ssh2_key) { 1819 if (!sensitive_data.have_ssh2_key) {
1814 logit("sshd: no hostkeys available -- exiting."); 1820 logit("sshd: no hostkeys available -- exiting.");
1815 exit(1); 1821 exit(1);
1816 } 1822 }
1823#endif
1817 1824
1818 /* 1825 /*
1819 * Load certificates. They are stored in an array at identical 1826 * Load certificates. They are stored in an array at identical
@@ -2104,6 +2111,60 @@ main(int ac, char **av)
2104 rdomain == NULL ? "" : "\""); 2111 rdomain == NULL ? "" : "\"");
2105 free(laddr); 2112 free(laddr);
2106 2113
2114#ifdef USE_SECURITY_SESSION_API
2115 /*
2116 * Create a new security session for use by the new user login if
2117 * the current session is the root session or we are not launched
2118 * by inetd (eg: debugging mode or server mode). We do not
2119 * necessarily need to create a session if we are launched from
2120 * inetd because Panther xinetd will create a session for us.
2121 *
2122 * The only case where this logic will fail is if there is an
2123 * inetd running in a non-root session which is not creating
2124 * new sessions for us. Then all the users will end up in the
2125 * same session (bad).
2126 *
2127 * When the client exits, the session will be destroyed for us
2128 * automatically.
2129 *
2130 * We must create the session before any credentials are stored
2131 * (including AFS pags, which happens a few lines below).
2132 */
2133 {
2134 OSStatus err = 0;
2135 SecuritySessionId sid = 0;
2136 SessionAttributeBits sattrs = 0;
2137
2138 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2139 if (err)
2140 error("SessionGetInfo() failed with error %.8X",
2141 (unsigned) err);
2142 else
2143 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2144 (unsigned) sid, (unsigned) sattrs);
2145
2146 if (inetd_flag && !(sattrs & sessionIsRoot))
2147 debug("Running in inetd mode in a non-root session... "
2148 "assuming inetd created the session for us.");
2149 else {
2150 debug("Creating new security session...");
2151 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2152 if (err)
2153 error("SessionCreate() failed with error %.8X",
2154 (unsigned) err);
2155
2156 err = SessionGetInfo(callerSecuritySession, &sid,
2157 &sattrs);
2158 if (err)
2159 error("SessionGetInfo() failed with error %.8X",
2160 (unsigned) err);
2161 else
2162 debug("New Session ID is %.8X / Session Attributes are %.8X",
2163 (unsigned) sid, (unsigned) sattrs);
2164 }
2165 }
2166#endif
2167
2107 /* 2168 /*
2108 * We don't want to listen forever unless the other side 2169 * We don't want to listen forever unless the other side
2109 * successfully authenticates itself. So we set up an alarm which is 2170 * successfully authenticates itself. So we set up an alarm which is
@@ -2287,6 +2348,48 @@ do_ssh2_kex(void)
2287 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2348 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2288 list_hostkey_types()); 2349 list_hostkey_types());
2289 2350
2351#ifdef GSSAPI
2352 {
2353 char *orig;
2354 char *gss = NULL;
2355 char *newstr = NULL;
2356 orig = myproposal[PROPOSAL_KEX_ALGS];
2357
2358 /*
2359 * If we don't have a host key, then there's no point advertising
2360 * the other key exchange algorithms
2361 */
2362
2363 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2364 orig = NULL;
2365
2366 if (options.gss_keyex)
2367 gss = ssh_gssapi_server_mechanisms();
2368 else
2369 gss = NULL;
2370
2371 if (gss && orig)
2372 xasprintf(&newstr, "%s,%s", gss, orig);
2373 else if (gss)
2374 newstr = gss;
2375 else if (orig)
2376 newstr = orig;
2377
2378 /*
2379 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2380 * key alg, but we can't tell people about it unless its the only
2381 * host key algorithm we support
2382 */
2383 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2384 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2385
2386 if (newstr)
2387 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2388 else
2389 fatal("No supported key exchange algorithms");
2390 }
2391#endif
2392
2290 /* start key exchange */ 2393 /* start key exchange */
2291 if ((r = kex_setup(active_state, myproposal)) != 0) 2394 if ((r = kex_setup(active_state, myproposal)) != 0)
2292 fatal("kex_setup: %s", ssh_err(r)); 2395 fatal("kex_setup: %s", ssh_err(r));
@@ -2304,6 +2407,13 @@ do_ssh2_kex(void)
2304# endif 2407# endif
2305#endif 2408#endif
2306 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2409 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2410#ifdef GSSAPI
2411 if (options.gss_keyex) {
2412 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2413 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2414 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2415 }
2416#endif
2307 kex->server = 1; 2417 kex->server = 1;
2308 kex->client_version_string=client_version_string; 2418 kex->client_version_string=client_version_string;
2309 kex->server_version_string=server_version_string; 2419 kex->server_version_string=server_version_string;