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-10-04 13:54:43 +0100
commit4e70490950e5c5134df48848affaf73685bf0284 (patch)
tree59de097e770693fb1f81268e85f7802df32cb58e /sshd.c
parent62f54f20bf351468e0124f63cc2902ee40d9b0e9 (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 51a1aaf6e..45e50fac3 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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;