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-10-07 14:26:43 +0100
commit1c1b6fa17982eb622e2c4e8f4a279f2113f57413 (patch)
treea67e7472f48242904e6a45732508822af63fd331 /sshd.c
parent487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (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-10-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 481d00155..e6706a886 100644
--- a/sshd.c
+++ b/sshd.c
@@ -123,6 +123,10 @@
123#include "ssh-sandbox.h" 123#include "ssh-sandbox.h"
124#include "version.h" 124#include "version.h"
125 125
126#ifdef USE_SECURITY_SESSION_API
127#include <Security/AuthSession.h>
128#endif
129
126#ifndef O_NOCTTY 130#ifndef O_NOCTTY
127#define O_NOCTTY 0 131#define O_NOCTTY 0
128#endif 132#endif
@@ -1745,10 +1749,13 @@ main(int ac, char **av)
1745 logit("Disabling protocol version 1. Could not load host key"); 1749 logit("Disabling protocol version 1. Could not load host key");
1746 options.protocol &= ~SSH_PROTO_1; 1750 options.protocol &= ~SSH_PROTO_1;
1747 } 1751 }
1752#ifndef GSSAPI
1753 /* The GSSAPI key exchange can run without a host key */
1748 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1754 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
1749 logit("Disabling protocol version 2. Could not load host key"); 1755 logit("Disabling protocol version 2. Could not load host key");
1750 options.protocol &= ~SSH_PROTO_2; 1756 options.protocol &= ~SSH_PROTO_2;
1751 } 1757 }
1758#endif
1752 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1759 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
1753 logit("sshd: no hostkeys available -- exiting."); 1760 logit("sshd: no hostkeys available -- exiting.");
1754 exit(1); 1761 exit(1);
@@ -2060,6 +2067,60 @@ main(int ac, char **av)
2060 remote_ip, remote_port, 2067 remote_ip, remote_port,
2061 get_local_ipaddr(sock_in), get_local_port()); 2068 get_local_ipaddr(sock_in), get_local_port());
2062 2069
2070#ifdef USE_SECURITY_SESSION_API
2071 /*
2072 * Create a new security session for use by the new user login if
2073 * the current session is the root session or we are not launched
2074 * by inetd (eg: debugging mode or server mode). We do not
2075 * necessarily need to create a session if we are launched from
2076 * inetd because Panther xinetd will create a session for us.
2077 *
2078 * The only case where this logic will fail is if there is an
2079 * inetd running in a non-root session which is not creating
2080 * new sessions for us. Then all the users will end up in the
2081 * same session (bad).
2082 *
2083 * When the client exits, the session will be destroyed for us
2084 * automatically.
2085 *
2086 * We must create the session before any credentials are stored
2087 * (including AFS pags, which happens a few lines below).
2088 */
2089 {
2090 OSStatus err = 0;
2091 SecuritySessionId sid = 0;
2092 SessionAttributeBits sattrs = 0;
2093
2094 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2095 if (err)
2096 error("SessionGetInfo() failed with error %.8X",
2097 (unsigned) err);
2098 else
2099 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2100 (unsigned) sid, (unsigned) sattrs);
2101
2102 if (inetd_flag && !(sattrs & sessionIsRoot))
2103 debug("Running in inetd mode in a non-root session... "
2104 "assuming inetd created the session for us.");
2105 else {
2106 debug("Creating new security session...");
2107 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2108 if (err)
2109 error("SessionCreate() failed with error %.8X",
2110 (unsigned) err);
2111
2112 err = SessionGetInfo(callerSecuritySession, &sid,
2113 &sattrs);
2114 if (err)
2115 error("SessionGetInfo() failed with error %.8X",
2116 (unsigned) err);
2117 else
2118 debug("New Session ID is %.8X / Session Attributes are %.8X",
2119 (unsigned) sid, (unsigned) sattrs);
2120 }
2121 }
2122#endif
2123
2063 /* 2124 /*
2064 * We don't want to listen forever unless the other side 2125 * We don't want to listen forever unless the other side
2065 * successfully authenticates itself. So we set up an alarm which is 2126 * successfully authenticates itself. So we set up an alarm which is
@@ -2482,6 +2543,48 @@ do_ssh2_kex(void)
2482 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2543 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2483 list_hostkey_types()); 2544 list_hostkey_types());
2484 2545
2546#ifdef GSSAPI
2547 {
2548 char *orig;
2549 char *gss = NULL;
2550 char *newstr = NULL;
2551 orig = myproposal[PROPOSAL_KEX_ALGS];
2552
2553 /*
2554 * If we don't have a host key, then there's no point advertising
2555 * the other key exchange algorithms
2556 */
2557
2558 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2559 orig = NULL;
2560
2561 if (options.gss_keyex)
2562 gss = ssh_gssapi_server_mechanisms();
2563 else
2564 gss = NULL;
2565
2566 if (gss && orig)
2567 xasprintf(&newstr, "%s,%s", gss, orig);
2568 else if (gss)
2569 newstr = gss;
2570 else if (orig)
2571 newstr = orig;
2572
2573 /*
2574 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2575 * key alg, but we can't tell people about it unless its the only
2576 * host key algorithm we support
2577 */
2578 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2579 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2580
2581 if (newstr)
2582 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2583 else
2584 fatal("No supported key exchange algorithms");
2585 }
2586#endif
2587
2485 /* start key exchange */ 2588 /* start key exchange */
2486 kex = kex_setup(myproposal); 2589 kex = kex_setup(myproposal);
2487#ifdef WITH_OPENSSL 2590#ifdef WITH_OPENSSL
@@ -2492,6 +2595,13 @@ do_ssh2_kex(void)
2492 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 2595 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
2493#endif 2596#endif
2494 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2597 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2598#ifdef GSSAPI
2599 if (options.gss_keyex) {
2600 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2601 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2602 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2603 }
2604#endif
2495 kex->server = 1; 2605 kex->server = 1;
2496 kex->client_version_string=client_version_string; 2606 kex->client_version_string=client_version_string;
2497 kex->server_version_string=server_version_string; 2607 kex->server_version_string=server_version_string;