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-03-20 00:24:48 +0000
commit9dfcd1a0e691c1cad34b168e27b3ed31ab6986cd (patch)
tree3a19744ef1cf261141a522e13f75abbb3b7dba4b /sshd.c
parent796ba4fd011b5d0d9d78d592ba2f30fc9d5ed2e7 (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-03-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 7523de977..d787fea7b 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>
@@ -1728,10 +1732,13 @@ main(int ac, char **av)
1728 logit("Disabling protocol version 1. Could not load host key"); 1732 logit("Disabling protocol version 1. Could not load host key");
1729 options.protocol &= ~SSH_PROTO_1; 1733 options.protocol &= ~SSH_PROTO_1;
1730 } 1734 }
1735#ifndef GSSAPI
1736 /* The GSSAPI key exchange can run without a host key */
1731 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) { 1737 if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
1732 logit("Disabling protocol version 2. Could not load host key"); 1738 logit("Disabling protocol version 2. Could not load host key");
1733 options.protocol &= ~SSH_PROTO_2; 1739 options.protocol &= ~SSH_PROTO_2;
1734 } 1740 }
1741#endif
1735 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) { 1742 if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
1736 logit("sshd: no hostkeys available -- exiting."); 1743 logit("sshd: no hostkeys available -- exiting.");
1737 exit(1); 1744 exit(1);
@@ -2058,6 +2065,60 @@ main(int ac, char **av)
2058 remote_ip, remote_port, 2065 remote_ip, remote_port,
2059 get_local_ipaddr(sock_in), get_local_port()); 2066 get_local_ipaddr(sock_in), get_local_port());
2060 2067
2068#ifdef USE_SECURITY_SESSION_API
2069 /*
2070 * Create a new security session for use by the new user login if
2071 * the current session is the root session or we are not launched
2072 * by inetd (eg: debugging mode or server mode). We do not
2073 * necessarily need to create a session if we are launched from
2074 * inetd because Panther xinetd will create a session for us.
2075 *
2076 * The only case where this logic will fail is if there is an
2077 * inetd running in a non-root session which is not creating
2078 * new sessions for us. Then all the users will end up in the
2079 * same session (bad).
2080 *
2081 * When the client exits, the session will be destroyed for us
2082 * automatically.
2083 *
2084 * We must create the session before any credentials are stored
2085 * (including AFS pags, which happens a few lines below).
2086 */
2087 {
2088 OSStatus err = 0;
2089 SecuritySessionId sid = 0;
2090 SessionAttributeBits sattrs = 0;
2091
2092 err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
2093 if (err)
2094 error("SessionGetInfo() failed with error %.8X",
2095 (unsigned) err);
2096 else
2097 debug("Current Session ID is %.8X / Session Attributes are %.8X",
2098 (unsigned) sid, (unsigned) sattrs);
2099
2100 if (inetd_flag && !(sattrs & sessionIsRoot))
2101 debug("Running in inetd mode in a non-root session... "
2102 "assuming inetd created the session for us.");
2103 else {
2104 debug("Creating new security session...");
2105 err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
2106 if (err)
2107 error("SessionCreate() failed with error %.8X",
2108 (unsigned) err);
2109
2110 err = SessionGetInfo(callerSecuritySession, &sid,
2111 &sattrs);
2112 if (err)
2113 error("SessionGetInfo() failed with error %.8X",
2114 (unsigned) err);
2115 else
2116 debug("New Session ID is %.8X / Session Attributes are %.8X",
2117 (unsigned) sid, (unsigned) sattrs);
2118 }
2119 }
2120#endif
2121
2061 /* 2122 /*
2062 * We don't want to listen forever unless the other side 2123 * We don't want to listen forever unless the other side
2063 * successfully authenticates itself. So we set up an alarm which is 2124 * successfully authenticates itself. So we set up an alarm which is
@@ -2469,6 +2530,48 @@ do_ssh2_kex(void)
2469 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal( 2530 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
2470 list_hostkey_types()); 2531 list_hostkey_types());
2471 2532
2533#ifdef GSSAPI
2534 {
2535 char *orig;
2536 char *gss = NULL;
2537 char *newstr = NULL;
2538 orig = myproposal[PROPOSAL_KEX_ALGS];
2539
2540 /*
2541 * If we don't have a host key, then there's no point advertising
2542 * the other key exchange algorithms
2543 */
2544
2545 if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
2546 orig = NULL;
2547
2548 if (options.gss_keyex)
2549 gss = ssh_gssapi_server_mechanisms();
2550 else
2551 gss = NULL;
2552
2553 if (gss && orig)
2554 xasprintf(&newstr, "%s,%s", gss, orig);
2555 else if (gss)
2556 newstr = gss;
2557 else if (orig)
2558 newstr = orig;
2559
2560 /*
2561 * If we've got GSSAPI mechanisms, then we've got the 'null' host
2562 * key alg, but we can't tell people about it unless its the only
2563 * host key algorithm we support
2564 */
2565 if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
2566 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
2567
2568 if (newstr)
2569 myproposal[PROPOSAL_KEX_ALGS] = newstr;
2570 else
2571 fatal("No supported key exchange algorithms");
2572 }
2573#endif
2574
2472 /* start key exchange */ 2575 /* start key exchange */
2473 kex = kex_setup(myproposal); 2576 kex = kex_setup(myproposal);
2474 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; 2577 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
@@ -2477,6 +2580,13 @@ do_ssh2_kex(void)
2477 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; 2580 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
2478 kex->kex[KEX_ECDH_SHA2] = kexecdh_server; 2581 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
2479 kex->kex[KEX_C25519_SHA256] = kexc25519_server; 2582 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
2583#ifdef GSSAPI
2584 if (options.gss_keyex) {
2585 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
2586 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
2587 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
2588 }
2589#endif
2480 kex->server = 1; 2590 kex->server = 1;
2481 kex->client_version_string=client_version_string; 2591 kex->client_version_string=client_version_string;
2482 kex->server_version_string=server_version_string; 2592 kex->server_version_string=server_version_string;