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>2019-06-05 07:06:44 +0100
commit7ce79be85036c4b36937f1b1ba85f6094068412c (patch)
treec964917d8395ef5605cff9513aad4458b222beae /sshd.c
parent102062f825fb26a74295a1c089c00c4c4c76b68a (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. Origin: other, https://github.com/openssh-gsskex/openssh-gsskex/commits/debian/master Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 Last-Updated: 2019-06-05 Patch-Name: gssapi.patch
Diffstat (limited to 'sshd.c')
-rw-r--r--sshd.c120
1 files changed, 116 insertions, 4 deletions
diff --git a/sshd.c b/sshd.c
index cbd3bce91..98680721b 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)
@@ -796,8 +800,8 @@ notify_hostkeys(struct ssh *ssh)
796 } 800 }
797 debug3("%s: sent %u hostkeys", __func__, nkeys); 801 debug3("%s: sent %u hostkeys", __func__, nkeys);
798 if (nkeys == 0) 802 if (nkeys == 0)
799 fatal("%s: no hostkeys", __func__); 803 debug3("%s: no hostkeys", __func__);
800 if ((r = sshpkt_send(ssh)) != 0) 804 else if ((r = sshpkt_send(ssh)) != 0)
801 sshpkt_fatal(ssh, r, "%s: send", __func__); 805 sshpkt_fatal(ssh, r, "%s: send", __func__);
802 sshbuf_free(buf); 806 sshbuf_free(buf);
803} 807}
@@ -1769,7 +1773,8 @@ main(int ac, char **av)
1769 free(fp); 1773 free(fp);
1770 } 1774 }
1771 accumulate_host_timing_secret(cfg, NULL); 1775 accumulate_host_timing_secret(cfg, NULL);
1772 if (!sensitive_data.have_ssh2_key) { 1776 /* The GSSAPI key exchange can run without a host key */
1777 if (!sensitive_data.have_ssh2_key && !options.gss_keyex) {
1773 logit("sshd: no hostkeys available -- exiting."); 1778 logit("sshd: no hostkeys available -- exiting.");
1774 exit(1); 1779 exit(1);
1775 } 1780 }
@@ -2064,6 +2069,60 @@ main(int ac, char **av)
2064 rdomain == NULL ? "" : "\""); 2069 rdomain == NULL ? "" : "\"");
2065 free(laddr); 2070 free(laddr);
2066 2071
2072#ifdef USE_SECURITY_SESSION_API
2073 /*
2074 * Create a new security session for use by the new user login if
2075 * the current session is the root session or we are not launched
2076 * by inetd (eg: debugging mode or server mode). We do not
2077 * necessarily need to create a session if we are launched from
2078 * inetd because Panther xinetd will create a session for us.
2079 *
2080 * The only case where this logic will fail is if there is an
2081 * inetd running in a non-root session which is not creating
2082 * new sessions for us. Then all the users will end up in the
2083 * same session (bad).
2084 *
2085 * When the client exits, the session will be destroyed for us
2086 * automatically.
2087 *
2088 * We must create the session before any credentials are stored
2089 * (including AFS pags, which happens a few lines below).
2090 */
2091 {
2092 OSStatus err = 0;
2093 SecuritySessionId sid = 0;
2094 SessionAttributeBits sattrs = 0;
2095
2096 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2097 if (err)
2098 error("SessionGetInfo() failed with error %.8X",
2099 (unsigned) err);
2100 else
2101 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2102 (unsigned) sid, (unsigned) sattrs);
2103
2104 if (inetd_flag && !(sattrs & sessionIsRoot))
2105 debug("Running in inetd mode in a non-root session... "
2106 "assuming inetd created the session for us.");
2107 else {
2108 debug("Creating new security session...");
2109 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2110 if (err)
2111 error("SessionCreate() failed with error %.8X",
2112 (unsigned) err);
2113
2114 err = SessionGetInfo(callerSecuritySession, &sid,
2115 &sattrs);
2116 if (err)
2117 error("SessionGetInfo() failed with error %.8X",
2118 (unsigned) err);
2119 else
2120 debug("New Session ID is %.8X / Session Attributes are %.8X",
2121 (unsigned) sid, (unsigned) sattrs);
2122 }
2123 }
2124#endif
2125
2067 /* 2126 /*
2068 * We don't want to listen forever unless the other side 2127 * We don't want to listen forever unless the other side
2069 * successfully authenticates itself. So we set up an alarm which is 2128 * successfully authenticates itself. So we set up an alarm which is
@@ -2260,6 +2319,48 @@ do_ssh2_kex(struct ssh *ssh)
2260 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2319 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2261 list_hostkey_types()); 2320 list_hostkey_types());
2262 2321
2322#if defined(GSSAPI) && defined(WITH_OPENSSL)
2323 {
2324 char *orig;
2325 char *gss = NULL;
2326 char *newstr = NULL;
2327 orig = myproposal[PROPOSAL_KEX_ALGS];
2328
2329 /*
2330 * If we don't have a host key, then there's no point advertising
2331 * the other key exchange algorithms
2332 */
2333
2334 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2335 orig = NULL;
2336
2337 if (options.gss_keyex)
2338 gss = ssh_gssapi_server_mechanisms();
2339 else
2340 gss = NULL;
2341
2342 if (gss && orig)
2343 xasprintf(&newstr, "%s,%s", gss, orig);
2344 else if (gss)
2345 newstr = gss;
2346 else if (orig)
2347 newstr = orig;
2348
2349 /*
2350 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2351 * key alg, but we can't tell people about it unless its the only
2352 * host key algorithm we support
2353 */
2354 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2355 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2356
2357 if (newstr)
2358 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2359 else
2360 fatal("No supported key exchange algorithms");
2361 }
2362#endif
2363
2263 /* start key exchange */ 2364 /* start key exchange */
2264 if ((r = kex_setup(ssh, myproposal)) != 0) 2365 if ((r = kex_setup(ssh, myproposal)) != 0)
2265 fatal("kex_setup: %s", ssh_err(r)); 2366 fatal("kex_setup: %s", ssh_err(r));
@@ -2275,7 +2376,18 @@ do_ssh2_kex(struct ssh *ssh)
2275# ifdef OPENSSL_HAS_ECC 2376# ifdef OPENSSL_HAS_ECC
2276 kex->kex[KEX_ECDH_SHA2] = kex_gen_server; 2377 kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
2277# endif 2378# endif
2278#endif 2379# ifdef GSSAPI
2380 if (options.gss_keyex) {
2381 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2382 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2383 kex->kex[KEX_GSS_GRP14_SHA256] = kexgss_server;
2384 kex->kex[KEX_GSS_GRP16_SHA512] = kexgss_server;
2385 kex->kex[KEX_GSS_GEX_SHA1] = kexgssgex_server;
2386 kex->kex[KEX_GSS_NISTP256_SHA256] = kexgss_server;
2387 kex->kex[KEX_GSS_C25519_SHA256] = kexgss_server;
2388 }
2389# endif
2390#endif /* WITH_OPENSSL */
2279 kex->kex[KEX_C25519_SHA256] = kex_gen_server; 2391 kex->kex[KEX_C25519_SHA256] = kex_gen_server;
2280 kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server; 2392 kex->kex[KEX_KEM_SNTRUP4591761X25519_SHA512] = kex_gen_server;
2281 kex->load_host_public_key=&get_hostkey_public_by_type; 2393 kex->load_host_public_key=&get_hostkey_public_by_type;