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>2015-08-19 17:09:55 +0100
commit5d3dc7ea4c96cab9483d5389a3b04163771fdee2 (patch)
treed20c6ac4435c138f3eefbc73caa649bcdfbcfb80 /sshd.c
parent544df7a04ae5b5c1fc30be7c445ad685d7a02dc9 (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: 2015-08-19 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 6f8c6f2b1..6b85e6c45 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
@@ -1823,10 +1827,13 @@ main(int ac, char **av)
1823 logit("Disabling protocol version 1. Could not load host key"); 1827 logit("Disabling protocol version 1. Could not load host key");
1824 options.protocol &= ~SSH_PROTO_1; 1828 options.protocol &= ~SSH_PROTO_1;
1825 } 1829 }
1830#ifndef GSSAPI
1831 /* The GSSAPI key exchange can run without a host key */
1826 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1832 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
1827 logit("Disabling protocol version 2. Could not load host key"); 1833 logit("Disabling protocol version 2. Could not load host key");
1828 options.protocol &= ~SSH_PROTO_2; 1834 options.protocol &= ~SSH_PROTO_2;
1829 } 1835 }
1836#endif
1830 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1837 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
1831 logit("sshd: no hostkeys available -- exiting."); 1838 logit("sshd: no hostkeys available -- exiting.");
1832 exit(1); 1839 exit(1);
@@ -2141,6 +2148,60 @@ main(int ac, char **av)
2141 remote_ip, remote_port, laddr, get_local_port()); 2148 remote_ip, remote_port, laddr, get_local_port());
2142 free(laddr); 2149 free(laddr);
2143 2150
2151#ifdef USE_SECURITY_SESSION_API
2152 /*
2153 * Create a new security session for use by the new user login if
2154 * the current session is the root session or we are not launched
2155 * by inetd (eg: debugging mode or server mode). We do not
2156 * necessarily need to create a session if we are launched from
2157 * inetd because Panther xinetd will create a session for us.
2158 *
2159 * The only case where this logic will fail is if there is an
2160 * inetd running in a non-root session which is not creating
2161 * new sessions for us. Then all the users will end up in the
2162 * same session (bad).
2163 *
2164 * When the client exits, the session will be destroyed for us
2165 * automatically.
2166 *
2167 * We must create the session before any credentials are stored
2168 * (including AFS pags, which happens a few lines below).
2169 */
2170 {
2171 OSStatus err = 0;
2172 SecuritySessionId sid = 0;
2173 SessionAttributeBits sattrs = 0;
2174
2175 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2176 if (err)
2177 error("SessionGetInfo() failed with error %.8X",
2178 (unsigned) err);
2179 else
2180 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2181 (unsigned) sid, (unsigned) sattrs);
2182
2183 if (inetd_flag && !(sattrs & sessionIsRoot))
2184 debug("Running in inetd mode in a non-root session... "
2185 "assuming inetd created the session for us.");
2186 else {
2187 debug("Creating new security session...");
2188 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2189 if (err)
2190 error("SessionCreate() failed with error %.8X",
2191 (unsigned) err);
2192
2193 err = SessionGetInfo(callerSecuritySession, &sid,
2194 &sattrs);
2195 if (err)
2196 error("SessionGetInfo() failed with error %.8X",
2197 (unsigned) err);
2198 else
2199 debug("New Session ID is %.8X / Session Attributes are %.8X",
2200 (unsigned) sid, (unsigned) sattrs);
2201 }
2202 }
2203#endif
2204
2144 /* 2205 /*
2145 * We don't want to listen forever unless the other side 2206 * We don't want to listen forever unless the other side
2146 * successfully authenticates itself. So we set up an alarm which is 2207 * successfully authenticates itself. So we set up an alarm which is
@@ -2570,6 +2631,48 @@ do_ssh2_kex(void)
2570 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2631 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2571 list_hostkey_types()); 2632 list_hostkey_types());
2572 2633
2634#ifdef GSSAPI
2635 {
2636 char *orig;
2637 char *gss = NULL;
2638 char *newstr = NULL;
2639 orig = myproposal[PROPOSAL_KEX_ALGS];
2640
2641 /*
2642 * If we don't have a host key, then there's no point advertising
2643 * the other key exchange algorithms
2644 */
2645
2646 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2647 orig = NULL;
2648
2649 if (options.gss_keyex)
2650 gss = ssh_gssapi_server_mechanisms();
2651 else
2652 gss = NULL;
2653
2654 if (gss && orig)
2655 xasprintf(&newstr, "%s,%s", gss, orig);
2656 else if (gss)
2657 newstr = gss;
2658 else if (orig)
2659 newstr = orig;
2660
2661 /*
2662 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2663 * key alg, but we can't tell people about it unless its the only
2664 * host key algorithm we support
2665 */
2666 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2667 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2668
2669 if (newstr)
2670 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2671 else
2672 fatal("No supported key exchange algorithms");
2673 }
2674#endif
2675
2573 /* start key exchange */ 2676 /* start key exchange */
2574 if ((r = kex_setup(active_state, myproposal)) != 0) 2677 if ((r = kex_setup(active_state, myproposal)) != 0)
2575 fatal("kex_setup: %s", ssh_err(r)); 2678 fatal("kex_setup: %s", ssh_err(r));
@@ -2584,6 +2687,13 @@ do_ssh2_kex(void)
2584# endif 2687# endif
2585#endif 2688#endif
2586 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2689 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2690#ifdef GSSAPI
2691 if (options.gss_keyex) {
2692 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2693 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2694 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2695 }
2696#endif
2587 kex->server = 1; 2697 kex->server = 1;
2588 kex->client_version_string=client_version_string; 2698 kex->client_version_string=client_version_string;
2589 kex->server_version_string=server_version_string; 2699 kex->server_version_string=server_version_string;