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-03-29 01:38:38 +0100
commitd51c7ac3328464dec21514fb398ab5c140a0664f (patch)
tree4f1a2aa08e99303f62c71cba0b38899f050d1b3d /sshd.c
parent6fabaf6fd9b07cc8bc6a17c9c4a5b76849cfc874 (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 010a2c38a..20a7a5f33 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
@@ -1719,10 +1723,13 @@ main(int ac, char **av)
1719 key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); 1723 key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp);
1720 free(fp); 1724 free(fp);
1721 } 1725 }
1726#ifndef GSSAPI
1727 /* The GSSAPI key exchange can run without a host key */
1722 if (!sensitive_data.have_ssh2_key) { 1728 if (!sensitive_data.have_ssh2_key) {
1723 logit("sshd: no hostkeys available -- exiting."); 1729 logit("sshd: no hostkeys available -- exiting.");
1724 exit(1); 1730 exit(1);
1725 } 1731 }
1732#endif
1726 1733
1727 /* 1734 /*
1728 * Load certificates. They are stored in an array at identical 1735 * Load certificates. They are stored in an array at identical
@@ -1992,6 +1999,60 @@ main(int ac, char **av)
1992 remote_ip, remote_port, laddr, ssh_local_port(ssh)); 1999 remote_ip, remote_port, laddr, ssh_local_port(ssh));
1993 free(laddr); 2000 free(laddr);
1994 2001
2002#ifdef USE_SECURITY_SESSION_API
2003 /*
2004 * Create a new security session for use by the new user login if
2005 * the current session is the root session or we are not launched
2006 * by inetd (eg: debugging mode or server mode). We do not
2007 * necessarily need to create a session if we are launched from
2008 * inetd because Panther xinetd will create a session for us.
2009 *
2010 * The only case where this logic will fail is if there is an
2011 * inetd running in a non-root session which is not creating
2012 * new sessions for us. Then all the users will end up in the
2013 * same session (bad).
2014 *
2015 * When the client exits, the session will be destroyed for us
2016 * automatically.
2017 *
2018 * We must create the session before any credentials are stored
2019 * (including AFS pags, which happens a few lines below).
2020 */
2021 {
2022 OSStatus err = 0;
2023 SecuritySessionId sid = 0;
2024 SessionAttributeBits sattrs = 0;
2025
2026 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2027 if (err)
2028 error("SessionGetInfo() failed with error %.8X",
2029 (unsigned) err);
2030 else
2031 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2032 (unsigned) sid, (unsigned) sattrs);
2033
2034 if (inetd_flag && !(sattrs & sessionIsRoot))
2035 debug("Running in inetd mode in a non-root session... "
2036 "assuming inetd created the session for us.");
2037 else {
2038 debug("Creating new security session...");
2039 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2040 if (err)
2041 error("SessionCreate() failed with error %.8X",
2042 (unsigned) err);
2043
2044 err = SessionGetInfo(callerSecuritySession, &sid,
2045 &sattrs);
2046 if (err)
2047 error("SessionGetInfo() failed with error %.8X",
2048 (unsigned) err);
2049 else
2050 debug("New Session ID is %.8X / Session Attributes are %.8X",
2051 (unsigned) sid, (unsigned) sattrs);
2052 }
2053 }
2054#endif
2055
1995 /* 2056 /*
1996 * We don't want to listen forever unless the other side 2057 * We don't want to listen forever unless the other side
1997 * successfully authenticates itself. So we set up an alarm which is 2058 * successfully authenticates itself. So we set up an alarm which is
@@ -2173,6 +2234,48 @@ do_ssh2_kex(void)
2173 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2234 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2174 list_hostkey_types()); 2235 list_hostkey_types());
2175 2236
2237#ifdef GSSAPI
2238 {
2239 char *orig;
2240 char *gss = NULL;
2241 char *newstr = NULL;
2242 orig = myproposal[PROPOSAL_KEX_ALGS];
2243
2244 /*
2245 * If we don't have a host key, then there's no point advertising
2246 * the other key exchange algorithms
2247 */
2248
2249 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2250 orig = NULL;
2251
2252 if (options.gss_keyex)
2253 gss = ssh_gssapi_server_mechanisms();
2254 else
2255 gss = NULL;
2256
2257 if (gss && orig)
2258 xasprintf(&newstr, "%s,%s", gss, orig);
2259 else if (gss)
2260 newstr = gss;
2261 else if (orig)
2262 newstr = orig;
2263
2264 /*
2265 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2266 * key alg, but we can't tell people about it unless its the only
2267 * host key algorithm we support
2268 */
2269 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2270 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2271
2272 if (newstr)
2273 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2274 else
2275 fatal("No supported key exchange algorithms");
2276 }
2277#endif
2278
2176 /* start key exchange */ 2279 /* start key exchange */
2177 if ((r = kex_setup(active_state, myproposal)) != 0) 2280 if ((r = kex_setup(active_state, myproposal)) != 0)
2178 fatal("kex_setup: %s", ssh_err(r)); 2281 fatal("kex_setup: %s", ssh_err(r));
@@ -2190,6 +2293,13 @@ do_ssh2_kex(void)
2190# endif 2293# endif
2191#endif 2294#endif
2192 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2295 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2296#ifdef GSSAPI
2297 if (options.gss_keyex) {
2298 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2299 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2300 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2301 }
2302#endif
2193 kex->server = 1; 2303 kex->server = 1;
2194 kex->client_version_string=client_version_string; 2304 kex->client_version_string=client_version_string;
2195 kex->server_version_string=server_version_string; 2305 kex->server_version_string=server_version_string;