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-10 02:40:08 +0000
commitcd404114ded78fc51d5d9cbd458d55c9b2f67daa (patch)
treedf7a424d9301b69af906b50d550bfce6e6e2c5f3 /sshd.c
parent9a975a9faed7c4f334e8c8490db3e77e102f2b21 (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: 2014-02-10 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 25380c911..fe65132e8 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>
@@ -1721,10 +1725,13 @@ main(int ac, char **av)
1721 logit("Disabling protocol version 1. Could not load host key"); 1725 logit("Disabling protocol version 1. Could not load host key");
1722 options.protocol &= ~SSH_PROTO_1; 1726 options.protocol &= ~SSH_PROTO_1;
1723 } 1727 }
1728#ifndef GSSAPI
1729 /* The GSSAPI key exchange can run without a host key */
1724 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1730 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
1725 logit("Disabling protocol version 2. Could not load host key"); 1731 logit("Disabling protocol version 2. Could not load host key");
1726 options.protocol &= ~SSH_PROTO_2; 1732 options.protocol &= ~SSH_PROTO_2;
1727 } 1733 }
1734#endif
1728 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1735 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
1729 logit("sshd: no hostkeys available -- exiting."); 1736 logit("sshd: no hostkeys available -- exiting.");
1730 exit(1); 1737 exit(1);
@@ -2051,6 +2058,60 @@ main(int ac, char **av)
2051 remote_ip, remote_port, 2058 remote_ip, remote_port,
2052 get_local_ipaddr(sock_in), get_local_port()); 2059 get_local_ipaddr(sock_in), get_local_port());
2053 2060
2061#ifdef USE_SECURITY_SESSION_API
2062 /*
2063 * Create a new security session for use by the new user login if
2064 * the current session is the root session or we are not launched
2065 * by inetd (eg: debugging mode or server mode). We do not
2066 * necessarily need to create a session if we are launched from
2067 * inetd because Panther xinetd will create a session for us.
2068 *
2069 * The only case where this logic will fail is if there is an
2070 * inetd running in a non-root session which is not creating
2071 * new sessions for us. Then all the users will end up in the
2072 * same session (bad).
2073 *
2074 * When the client exits, the session will be destroyed for us
2075 * automatically.
2076 *
2077 * We must create the session before any credentials are stored
2078 * (including AFS pags, which happens a few lines below).
2079 */
2080 {
2081 OSStatus err = 0;
2082 SecuritySessionId sid = 0;
2083 SessionAttributeBits sattrs = 0;
2084
2085 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2086 if (err)
2087 error("SessionGetInfo() failed with error %.8X",
2088 (unsigned) err);
2089 else
2090 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2091 (unsigned) sid, (unsigned) sattrs);
2092
2093 if (inetd_flag && !(sattrs & sessionIsRoot))
2094 debug("Running in inetd mode in a non-root session... "
2095 "assuming inetd created the session for us.");
2096 else {
2097 debug("Creating new security session...");
2098 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2099 if (err)
2100 error("SessionCreate() failed with error %.8X",
2101 (unsigned) err);
2102
2103 err = SessionGetInfo(callerSecuritySession, &sid,
2104 &sattrs);
2105 if (err)
2106 error("SessionGetInfo() failed with error %.8X",
2107 (unsigned) err);
2108 else
2109 debug("New Session ID is %.8X / Session Attributes are %.8X",
2110 (unsigned) sid, (unsigned) sattrs);
2111 }
2112 }
2113#endif
2114
2054 /* 2115 /*
2055 * We don't want to listen forever unless the other side 2116 * We don't want to listen forever unless the other side
2056 * successfully authenticates itself. So we set up an alarm which is 2117 * successfully authenticates itself. So we set up an alarm which is
@@ -2456,6 +2517,48 @@ do_ssh2_kex(void)
2456 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2517 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2457 list_hostkey_types()); 2518 list_hostkey_types());
2458 2519
2520#ifdef GSSAPI
2521 {
2522 char *orig;
2523 char *gss = NULL;
2524 char *newstr = NULL;
2525 orig = myproposal[PROPOSAL_KEX_ALGS];
2526
2527 /*
2528 * If we don't have a host key, then there's no point advertising
2529 * the other key exchange algorithms
2530 */
2531
2532 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2533 orig = NULL;
2534
2535 if (options.gss_keyex)
2536 gss = ssh_gssapi_server_mechanisms();
2537 else
2538 gss = NULL;
2539
2540 if (gss && orig)
2541 xasprintf(&newstr, "%s,%s", gss, orig);
2542 else if (gss)
2543 newstr = gss;
2544 else if (orig)
2545 newstr = orig;
2546
2547 /*
2548 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2549 * key alg, but we can't tell people about it unless its the only
2550 * host key algorithm we support
2551 */
2552 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2553 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2554
2555 if (newstr)
2556 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2557 else
2558 fatal("No supported key exchange algorithms");
2559 }
2560#endif
2561
2459 /* start key exchange */ 2562 /* start key exchange */
2460 kex = kex_setup(myproposal); 2563 kex = kex_setup(myproposal);
2461 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 2564 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
@@ -2464,6 +2567,13 @@ do_ssh2_kex(void)
2464 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 2567 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
2465 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 2568 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
2466 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2569 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2570#ifdef GSSAPI
2571 if (options.gss_keyex) {
2572 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2573 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2574 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2575 }
2576#endif
2467 kex->server = 1; 2577 kex->server = 1;
2468 kex->client_version_string=client_version_string; 2578 kex->client_version_string=client_version_string;
2469 kex->server_version_string=server_version_string; 2579 kex->server_version_string=server_version_string;