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>2016-08-07 12:18:35 +0100
commiteecddf8b72fcad83ccca43b1badb03782704f6b7 (patch)
treefd0046825c8d42bd267afa7839d5603b130cf847 /sshd.c
parenta8ed8d256b2e2c05b0c15565a7938028c5192277 (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: 2016-08-07 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 799c7711f..ebb88c776 100644
--- a/sshd.c
+++ b/sshd.c
@@ -125,6 +125,10 @@
125#include "version.h" 125#include "version.h"
126#include "ssherr.h" 126#include "ssherr.h"
127 127
128#ifdef USE_SECURITY_SESSION_API
129#include <Security/AuthSession.h>
130#endif
131
128#ifndef O_NOCTTY 132#ifndef O_NOCTTY
129#define O_NOCTTY 0 133#define O_NOCTTY 0
130#endif 134#endif
@@ -1892,10 +1896,13 @@ main(int ac, char **av)
1892 logit("Disabling protocol version 1. Could not load host key"); 1896 logit("Disabling protocol version 1. Could not load host key");
1893 options.protocol &= ~SSH_PROTO_1; 1897 options.protocol &= ~SSH_PROTO_1;
1894 } 1898 }
1899#ifndef GSSAPI
1900 /* The GSSAPI key exchange can run without a host key */
1895 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1901 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
1896 logit("Disabling protocol version 2. Could not load host key"); 1902 logit("Disabling protocol version 2. Could not load host key");
1897 options.protocol &= ~SSH_PROTO_2; 1903 options.protocol &= ~SSH_PROTO_2;
1898 } 1904 }
1905#endif
1899 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1906 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
1900 logit("sshd: no hostkeys available -- exiting."); 1907 logit("sshd: no hostkeys available -- exiting.");
1901 exit(1); 1908 exit(1);
@@ -2207,6 +2214,60 @@ main(int ac, char **av)
2207 remote_ip, remote_port, laddr, ssh_local_port(ssh)); 2214 remote_ip, remote_port, laddr, ssh_local_port(ssh));
2208 free(laddr); 2215 free(laddr);
2209 2216
2217#ifdef USE_SECURITY_SESSION_API
2218 /*
2219 * Create a new security session for use by the new user login if
2220 * the current session is the root session or we are not launched
2221 * by inetd (eg: debugging mode or server mode). We do not
2222 * necessarily need to create a session if we are launched from
2223 * inetd because Panther xinetd will create a session for us.
2224 *
2225 * The only case where this logic will fail is if there is an
2226 * inetd running in a non-root session which is not creating
2227 * new sessions for us. Then all the users will end up in the
2228 * same session (bad).
2229 *
2230 * When the client exits, the session will be destroyed for us
2231 * automatically.
2232 *
2233 * We must create the session before any credentials are stored
2234 * (including AFS pags, which happens a few lines below).
2235 */
2236 {
2237 OSStatus err = 0;
2238 SecuritySessionId sid = 0;
2239 SessionAttributeBits sattrs = 0;
2240
2241 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2242 if (err)
2243 error("SessionGetInfo() failed with error %.8X",
2244 (unsigned) err);
2245 else
2246 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2247 (unsigned) sid, (unsigned) sattrs);
2248
2249 if (inetd_flag && !(sattrs & sessionIsRoot))
2250 debug("Running in inetd mode in a non-root session... "
2251 "assuming inetd created the session for us.");
2252 else {
2253 debug("Creating new security session...");
2254 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2255 if (err)
2256 error("SessionCreate() failed with error %.8X",
2257 (unsigned) err);
2258
2259 err = SessionGetInfo(callerSecuritySession, &sid,
2260 &sattrs);
2261 if (err)
2262 error("SessionGetInfo() failed with error %.8X",
2263 (unsigned) err);
2264 else
2265 debug("New Session ID is %.8X / Session Attributes are %.8X",
2266 (unsigned) sid, (unsigned) sattrs);
2267 }
2268 }
2269#endif
2270
2210 /* 2271 /*
2211 * We don't want to listen forever unless the other side 2272 * We don't want to listen forever unless the other side
2212 * successfully authenticates itself. So we set up an alarm which is 2273 * successfully authenticates itself. So we set up an alarm which is
@@ -2631,6 +2692,48 @@ do_ssh2_kex(void)
2631 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2692 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2632 list_hostkey_types()); 2693 list_hostkey_types());
2633 2694
2695#ifdef GSSAPI
2696 {
2697 char *orig;
2698 char *gss = NULL;
2699 char *newstr = NULL;
2700 orig = myproposal[PROPOSAL_KEX_ALGS];
2701
2702 /*
2703 * If we don't have a host key, then there's no point advertising
2704 * the other key exchange algorithms
2705 */
2706
2707 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2708 orig = NULL;
2709
2710 if (options.gss_keyex)
2711 gss = ssh_gssapi_server_mechanisms();
2712 else
2713 gss = NULL;
2714
2715 if (gss && orig)
2716 xasprintf(&newstr, "%s,%s", gss, orig);
2717 else if (gss)
2718 newstr = gss;
2719 else if (orig)
2720 newstr = orig;
2721
2722 /*
2723 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2724 * key alg, but we can't tell people about it unless its the only
2725 * host key algorithm we support
2726 */
2727 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2728 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2729
2730 if (newstr)
2731 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2732 else
2733 fatal("No supported key exchange algorithms");
2734 }
2735#endif
2736
2634 /* start key exchange */ 2737 /* start key exchange */
2635 if ((r = kex_setup(active_state, myproposal)) != 0) 2738 if ((r = kex_setup(active_state, myproposal)) != 0)
2636 fatal("kex_setup: %s", ssh_err(r)); 2739 fatal("kex_setup: %s", ssh_err(r));
@@ -2648,6 +2751,13 @@ do_ssh2_kex(void)
2648# endif 2751# endif
2649#endif 2752#endif
2650 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2753 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2754#ifdef GSSAPI
2755 if (options.gss_keyex) {
2756 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2757 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2758 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2759 }
2760#endif
2651 kex->server = 1; 2761 kex->server = 1;
2652 kex->client_version_string=client_version_string; 2762 kex->client_version_string=client_version_string;
2653 kex->server_version_string=server_version_string; 2763 kex->server_version_string=server_version_string;