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>2017-01-16 15:02:41 +0000
commit48fbb156bdc676fb6ba6817770e4e971fbf85b1f (patch)
treef35c67c09472bddc3337b1c74b0cb6a1d9b58670 /sshd.c
parent971a7653746a6972b907dfe0ce139c06e4a6f482 (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-01-16 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 1dc4d182a..0970f2970 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
@@ -1705,10 +1709,13 @@ main(int ac, char **av)
1705 key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); 1709 key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp);
1706 free(fp); 1710 free(fp);
1707 } 1711 }
1712#ifndef GSSAPI
1713 /* The GSSAPI key exchange can run without a host key */
1708 if (!sensitive_data.have_ssh2_key) { 1714 if (!sensitive_data.have_ssh2_key) {
1709 logit("sshd: no hostkeys available -- exiting."); 1715 logit("sshd: no hostkeys available -- exiting.");
1710 exit(1); 1716 exit(1);
1711 } 1717 }
1718#endif
1712 1719
1713 /* 1720 /*
1714 * Load certificates. They are stored in an array at identical 1721 * Load certificates. They are stored in an array at identical
@@ -1978,6 +1985,60 @@ main(int ac, char **av)
1978 remote_ip, remote_port, laddr, ssh_local_port(ssh)); 1985 remote_ip, remote_port, laddr, ssh_local_port(ssh));
1979 free(laddr); 1986 free(laddr);
1980 1987
1988#ifdef USE_SECURITY_SESSION_API
1989 /*
1990 * Create a new security session for use by the new user login if
1991 * the current session is the root session or we are not launched
1992 * by inetd (eg: debugging mode or server mode). We do not
1993 * necessarily need to create a session if we are launched from
1994 * inetd because Panther xinetd will create a session for us.
1995 *
1996 * The only case where this logic will fail is if there is an
1997 * inetd running in a non-root session which is not creating
1998 * new sessions for us. Then all the users will end up in the
1999 * same session (bad).
2000 *
2001 * When the client exits, the session will be destroyed for us
2002 * automatically.
2003 *
2004 * We must create the session before any credentials are stored
2005 * (including AFS pags, which happens a few lines below).
2006 */
2007 {
2008 OSStatus err = 0;
2009 SecuritySessionId sid = 0;
2010 SessionAttributeBits sattrs = 0;
2011
2012 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2013 if (err)
2014 error("SessionGetInfo() failed with error %.8X",
2015 (unsigned) err);
2016 else
2017 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2018 (unsigned) sid, (unsigned) sattrs);
2019
2020 if (inetd_flag && !(sattrs & sessionIsRoot))
2021 debug("Running in inetd mode in a non-root session... "
2022 "assuming inetd created the session for us.");
2023 else {
2024 debug("Creating new security session...");
2025 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2026 if (err)
2027 error("SessionCreate() failed with error %.8X",
2028 (unsigned) err);
2029
2030 err = SessionGetInfo(callerSecuritySession, &sid,
2031 &sattrs);
2032 if (err)
2033 error("SessionGetInfo() failed with error %.8X",
2034 (unsigned) err);
2035 else
2036 debug("New Session ID is %.8X / Session Attributes are %.8X",
2037 (unsigned) sid, (unsigned) sattrs);
2038 }
2039 }
2040#endif
2041
1981 /* 2042 /*
1982 * We don't want to listen forever unless the other side 2043 * We don't want to listen forever unless the other side
1983 * successfully authenticates itself. So we set up an alarm which is 2044 * successfully authenticates itself. So we set up an alarm which is
@@ -2159,6 +2220,48 @@ do_ssh2_kex(void)
2159 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2220 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2160 list_hostkey_types()); 2221 list_hostkey_types());
2161 2222
2223#ifdef GSSAPI
2224 {
2225 char *orig;
2226 char *gss = NULL;
2227 char *newstr = NULL;
2228 orig = myproposal[PROPOSAL_KEX_ALGS];
2229
2230 /*
2231 * If we don't have a host key, then there's no point advertising
2232 * the other key exchange algorithms
2233 */
2234
2235 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2236 orig = NULL;
2237
2238 if (options.gss_keyex)
2239 gss = ssh_gssapi_server_mechanisms();
2240 else
2241 gss = NULL;
2242
2243 if (gss && orig)
2244 xasprintf(&newstr, "%s,%s", gss, orig);
2245 else if (gss)
2246 newstr = gss;
2247 else if (orig)
2248 newstr = orig;
2249
2250 /*
2251 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2252 * key alg, but we can't tell people about it unless its the only
2253 * host key algorithm we support
2254 */
2255 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2256 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2257
2258 if (newstr)
2259 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2260 else
2261 fatal("No supported key exchange algorithms");
2262 }
2263#endif
2264
2162 /* start key exchange */ 2265 /* start key exchange */
2163 if ((r = kex_setup(active_state, myproposal)) != 0) 2266 if ((r = kex_setup(active_state, myproposal)) != 0)
2164 fatal("kex_setup: %s", ssh_err(r)); 2267 fatal("kex_setup: %s", ssh_err(r));
@@ -2176,6 +2279,13 @@ do_ssh2_kex(void)
2176# endif 2279# endif
2177#endif 2280#endif
2178 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2281 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2282#ifdef GSSAPI
2283 if (options.gss_keyex) {
2284 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2285 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2286 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2287 }
2288#endif
2179 kex->server = 1; 2289 kex->server = 1;
2180 kex->client_version_string=client_version_string; 2290 kex->client_version_string=client_version_string;
2181 kex->server_version_string=server_version_string; 2291 kex->server_version_string=server_version_string;