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>2014-02-09 16:16:58 +0000
commit950be7e1b1a01ee9b25e2a72726a6370b8acacb6 (patch)
tree64829a84f903d7e2d3270c43e3f80df7db2a6a10 /sshd.c
parentee196dab7c5f97f0b80c8099343a375bead92010 (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: 2013-11-09 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 174cc7a42..4eddeb8d8 100644
--- a/sshd.c
+++ b/sshd.c
@@ -122,6 +122,10 @@
122#include "ssh-sandbox.h" 122#include "ssh-sandbox.h"
123#include "version.h" 123#include "version.h"
124 124
125#ifdef USE_SECURITY_SESSION_API
126#include <Security/AuthSession.h>
127#endif
128
125#ifdef LIBWRAP 129#ifdef LIBWRAP
126#include <tcpd.h> 130#include <tcpd.h>
127#include <syslog.h> 131#include <syslog.h>
@@ -1703,10 +1707,13 @@ main(int ac, char **av)
1703 logit("Disabling protocol version 1. Could not load host key"); 1707 logit("Disabling protocol version 1. Could not load host key");
1704 options.protocol &= ~SSH_PROTO_1; 1708 options.protocol &= ~SSH_PROTO_1;
1705 } 1709 }
1710#ifndef GSSAPI
1711 /* The GSSAPI key exchange can run without a host key */
1706 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1712 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
1707 logit("Disabling protocol version 2. Could not load host key"); 1713 logit("Disabling protocol version 2. Could not load host key");
1708 options.protocol &= ~SSH_PROTO_2; 1714 options.protocol &= ~SSH_PROTO_2;
1709 } 1715 }
1716#endif
1710 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1717 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
1711 logit("sshd: no hostkeys available -- exiting."); 1718 logit("sshd: no hostkeys available -- exiting.");
1712 exit(1); 1719 exit(1);
@@ -2035,6 +2042,60 @@ main(int ac, char **av)
2035 /* Log the connection. */ 2042 /* Log the connection. */
2036 verbose("Connection from %.500s port %d", remote_ip, remote_port); 2043 verbose("Connection from %.500s port %d", remote_ip, remote_port);
2037 2044
2045#ifdef USE_SECURITY_SESSION_API
2046 /*
2047 * Create a new security session for use by the new user login if
2048 * the current session is the root session or we are not launched
2049 * by inetd (eg: debugging mode or server mode). We do not
2050 * necessarily need to create a session if we are launched from
2051 * inetd because Panther xinetd will create a session for us.
2052 *
2053 * The only case where this logic will fail is if there is an
2054 * inetd running in a non-root session which is not creating
2055 * new sessions for us. Then all the users will end up in the
2056 * same session (bad).
2057 *
2058 * When the client exits, the session will be destroyed for us
2059 * automatically.
2060 *
2061 * We must create the session before any credentials are stored
2062 * (including AFS pags, which happens a few lines below).
2063 */
2064 {
2065 OSStatus err = 0;
2066 SecuritySessionId sid = 0;
2067 SessionAttributeBits sattrs = 0;
2068
2069 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2070 if (err)
2071 error("SessionGetInfo() failed with error %.8X",
2072 (unsigned) err);
2073 else
2074 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2075 (unsigned) sid, (unsigned) sattrs);
2076
2077 if (inetd_flag && !(sattrs & sessionIsRoot))
2078 debug("Running in inetd mode in a non-root session... "
2079 "assuming inetd created the session for us.");
2080 else {
2081 debug("Creating new security session...");
2082 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2083 if (err)
2084 error("SessionCreate() failed with error %.8X",
2085 (unsigned) err);
2086
2087 err = SessionGetInfo(callerSecuritySession, &sid,
2088 &sattrs);
2089 if (err)
2090 error("SessionGetInfo() failed with error %.8X",
2091 (unsigned) err);
2092 else
2093 debug("New Session ID is %.8X / Session Attributes are %.8X",
2094 (unsigned) sid, (unsigned) sattrs);
2095 }
2096 }
2097#endif
2098
2038 /* 2099 /*
2039 * We don't want to listen forever unless the other side 2100 * We don't want to listen forever unless the other side
2040 * successfully authenticates itself. So we set up an alarm which is 2101 * successfully authenticates itself. So we set up an alarm which is
@@ -2439,6 +2500,48 @@ do_ssh2_kex(void)
2439 2500
2440 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); 2501 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
2441 2502
2503#ifdef GSSAPI
2504 {
2505 char *orig;
2506 char *gss = NULL;
2507 char *newstr = NULL;
2508 orig = myproposal[PROPOSAL_KEX_ALGS];
2509
2510 /*
2511 * If we don't have a host key, then there's no point advertising
2512 * the other key exchange algorithms
2513 */
2514
2515 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2516 orig = NULL;
2517
2518 if (options.gss_keyex)
2519 gss = ssh_gssapi_server_mechanisms();
2520 else
2521 gss = NULL;
2522
2523 if (gss && orig)
2524 xasprintf(&newstr, "%s,%s", gss, orig);
2525 else if (gss)
2526 newstr = gss;
2527 else if (orig)
2528 newstr = orig;
2529
2530 /*
2531 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2532 * key alg, but we can't tell people about it unless its the only
2533 * host key algorithm we support
2534 */
2535 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2536 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2537
2538 if (newstr)
2539 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2540 else
2541 fatal("No supported key exchange algorithms");
2542 }
2543#endif
2544
2442 /* start key exchange */ 2545 /* start key exchange */
2443 kex = kex_setup(myproposal); 2546 kex = kex_setup(myproposal);
2444 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 2547 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
@@ -2446,6 +2549,13 @@ do_ssh2_kex(void)
2446 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; 2549 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
2447 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 2550 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
2448 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 2551 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
2552#ifdef GSSAPI
2553 if (options.gss_keyex) {
2554 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2555 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2556 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2557 }
2558#endif
2449 kex->server = 1; 2559 kex->server = 1;
2450 kex->client_version_string=client_version_string; 2560 kex->client_version_string=client_version_string;
2451 kex->server_version_string=server_version_string; 2561 kex->server_version_string=server_version_string;