rutwa189 / rpms / openssh

Forked from rpms/openssh a year ago
Clone

Blame SOURCES/openssh-7.0p1-gssKexAlgorithms.patch

f5835d
diff -up openssh-7.0p1/gss-genr.c.gsskexalg openssh-7.0p1/gss-genr.c
f5835d
--- openssh-7.0p1/gss-genr.c.gsskexalg	2015-08-19 12:28:38.024518959 +0200
f5835d
+++ openssh-7.0p1/gss-genr.c	2015-08-19 12:28:38.078518839 +0200
f5835d
@@ -78,7 +78,8 @@ ssh_gssapi_oid_table_ok() {
f5835d
  */
f5835d
 
f5835d
 char *
f5835d
-ssh_gssapi_client_mechanisms(const char *host, const char *client) {
f5835d
+ssh_gssapi_client_mechanisms(const char *host, const char *client,
f5835d
+    const char *kex) {
f5835d
 	gss_OID_set gss_supported;
f5835d
 	OM_uint32 min_status;
f5835d
 
f5835d
@@ -86,12 +87,12 @@ ssh_gssapi_client_mechanisms(const char
f5835d
 		return NULL;
f5835d
 
f5835d
 	return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
f5835d
-	    host, client));
f5835d
+	    host, client, kex));
f5835d
 }
f5835d
 
f5835d
 char *
f5835d
 ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
f5835d
-    const char *host, const char *client) {
f5835d
+    const char *host, const char *client, const char *kex) {
f5835d
 	struct sshbuf *buf;
f5835d
 	size_t i;
f5835d
 	int oidpos, enclen, r;
f5835d
@@ -100,6 +101,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
f5835d
 	char deroid[2];
f5835d
 	const EVP_MD *evp_md = EVP_md5();
f5835d
 	EVP_MD_CTX md;
f5835d
+	char *s, *cp, *p;
f5835d
 
f5835d
 	if (gss_enc2oid != NULL) {
f5835d
 		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
f5835d
@@ -113,6 +115,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
f5835d
 		fatal("%s: sshbuf_new failed", __func__);
f5835d
 
f5835d
 	oidpos = 0;
f5835d
+	s = cp = xstrdup(kex);
f5835d
 	for (i = 0; i < gss_supported->count; i++) {
f5835d
 		if (gss_supported->elements[i].length < 128 &&
f5835d
 		    (*check)(NULL, &(gss_supported->elements[i]), host, client)) {
f5835d
@@ -131,28 +134,25 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
f5835d
 			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
f5835d
 			    encoded, EVP_MD_size(evp_md) * 2);
f5835d
 
f5835d
-			if (oidpos != 0)
f5835d
-				if ((r = sshbuf_put_u8(buf, ',')) != 0)
f5835d
-					fatal("%s: buffer error: %s", __func__, ssh_err(r));
f5835d
-
f5835d
-			if ((r = sshbuf_put(buf, KEX_GSS_GEX_SHA1_ID,
f5835d
-			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1)) != 0 ||
f5835d
-			    (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
f5835d
-			    (r = sshbuf_put_u8(buf, ',')) != 0 ||
f5835d
-			    (r = sshbuf_put(buf, KEX_GSS_GRP1_SHA1_ID, 
f5835d
-			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1)) != 0 ||
f5835d
-			    (r = sshbuf_put(buf, encoded, enclen)) != 0 ||
f5835d
-			    (r = sshbuf_put_u8(buf, ',')) != 0 ||
f5835d
-			    (r = sshbuf_put(buf, KEX_GSS_GRP14_SHA1_ID,
f5835d
-			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1)) != 0 ||
f5835d
-			    (r = sshbuf_put(buf, encoded, enclen)) != 0)
f5835d
-		 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
f5835d
+			cp = strncpy(s, kex, strlen(kex));
f5835d
+			for ((p = strsep(&cp, ",")); p && *p != '\0';
f5835d
+				(p = strsep(&cp, ","))) {
f5835d
+				if (sshbuf_len(buf) != 0)
f5835d
+					if ((r = sshbuf_put_u8(buf, ',')) != 0)
f5835d
+			 			fatal("%s: buffer error: %s",
f5835d
+						    __func__, ssh_err(r));
f5835d
+				if ((r = sshbuf_put(buf, p, strlen(p))) != 0 ||
f5835d
+				    (r = sshbuf_put(buf, encoded, enclen)) != 0)
f5835d
+			 		fatal("%s: buffer error: %s",
f5835d
+					    __func__, ssh_err(r));
f5835d
+			}
f5835d
 
f5835d
 			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
f5835d
 			gss_enc2oid[oidpos].encoded = encoded;
f5835d
 			oidpos++;
f5835d
 		}
f5835d
 	}
f5835d
+	free(s);
f5835d
 	gss_enc2oid[oidpos].oid = NULL;
f5835d
 	gss_enc2oid[oidpos].encoded = NULL;
f5835d
 
f5835d
diff -up openssh-7.0p1/gss-serv.c.gsskexalg openssh-7.0p1/gss-serv.c
f5835d
--- openssh-7.0p1/gss-serv.c.gsskexalg	2015-08-19 12:28:38.024518959 +0200
f5835d
+++ openssh-7.0p1/gss-serv.c	2015-08-19 12:28:38.078518839 +0200
f5835d
@@ -149,7 +149,8 @@ ssh_gssapi_server_mechanisms() {
f5835d
 	if (supported_oids == NULL)
f5835d
 		ssh_gssapi_prepare_supported_oids();
f5835d
 	return (ssh_gssapi_kex_mechs(supported_oids,
f5835d
-	    &ssh_gssapi_server_check_mech, NULL, NULL));
f5835d
+	    &ssh_gssapi_server_check_mech, NULL, NULL,
f5835d
+	    options.gss_kex_algorithms));
f5835d
 }
f5835d
 
f5835d
 /* Unprivileged */
f5835d
diff -up openssh-7.0p1/kex.c.gsskexalg openssh-7.0p1/kex.c
f5835d
--- openssh-7.0p1/kex.c.gsskexalg	2015-08-19 12:28:38.078518839 +0200
f5835d
+++ openssh-7.0p1/kex.c	2015-08-19 12:30:13.249306371 +0200
f5835d
@@ -50,6 +50,7 @@
f5835d
 #include "misc.h"
f5835d
 #include "dispatch.h"
f5835d
 #include "monitor.h"
f5835d
+#include "xmalloc.h"
f5835d
 
f5835d
 #include "ssherr.h"
f5835d
 #include "sshbuf.h"
f5835d
@@ -232,6 +232,29 @@ kex_assemble_names(const char *def, char
f5835d
 	return r;
f5835d
 }
f5835d
 
f5835d
+/* Validate GSS KEX method name list */
f5835d
+int
f5835d
+gss_kex_names_valid(const char *names)
f5835d
+{
f5835d
+	char *s, *cp, *p;
f5835d
+
f5835d
+	if (names == NULL || *names == '\0')
f5835d
+		return 0;
f5835d
+	s = cp = xstrdup(names);
f5835d
+	for ((p = strsep(&cp, ",")); p && *p != '\0';
f5835d
+	    (p = strsep(&cp, ","))) {
f5835d
+		if (strncmp(p, "gss-", 4) != 0
f5835d
+		  || kex_alg_by_name(p) == NULL) {
f5835d
+			error("Unsupported KEX algorithm \"%.100s\"", p);
f5835d
+			free(s);
f5835d
+			return 0;
f5835d
+		}
f5835d
+	}
f5835d
+	debug3("gss kex names ok: [%s]", names);
f5835d
+	free(s);
f5835d
+	return 1;
f5835d
+}
f5835d
+
f5835d
 /* put algorithm proposal into buffer */
f5835d
 int
f5835d
 kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX])
f5835d
diff -up openssh-7.0p1/kex.h.gsskexalg openssh-7.0p1/kex.h
f5835d
--- openssh-7.0p1/kex.h.gsskexalg	2015-08-19 12:28:38.078518839 +0200
f5835d
+++ openssh-7.0p1/kex.h	2015-08-19 12:30:52.404218958 +0200
f5835d
@@ -173,6 +173,7 @@ int	 kex_names_valid(const char *);
f5835d
 char	*kex_alg_list(char);
f5835d
 char	*kex_names_cat(const char *, const char *);
f5835d
 int	 kex_assemble_names(char **, const char *, const char *);
f5835d
+int	 gss_kex_names_valid(const char *);
f5835d
 
f5835d
 int	 kex_new(struct ssh *, char *[PROPOSAL_MAX], struct kex **);
f5835d
 int	 kex_setup(struct ssh *, char *[PROPOSAL_MAX]);
f5835d
diff -up openssh-7.0p1/readconf.c.gsskexalg openssh-7.0p1/readconf.c
f5835d
--- openssh-7.0p1/readconf.c.gsskexalg	2015-08-19 12:28:38.026518955 +0200
f5835d
+++ openssh-7.0p1/readconf.c	2015-08-19 12:31:28.333138747 +0200
f5835d
@@ -61,6 +61,7 @@
f5835d
 #include "uidswap.h"
f5835d
 #include "myproposal.h"
f5835d
 #include "digest.h"
f5835d
+#include "ssh-gss.h"
f5835d
 
f5835d
 /* Format of the configuration file:
f5835d
 
f5835d
@@ -148,7 +149,7 @@ typedef enum {
f5835d
 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
f5835d
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
f5835d
 	oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
f5835d
-	oGssServerIdentity, 
f5835d
+	oGssServerIdentity, oGssKexAlgorithms,
f5835d
 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
f5835d
 	oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
f5835d
 	oHashKnownHosts,
f5835d
@@ -200,6 +201,7 @@ static struct {
f5835d
 	{ "gssapiclientidentity", oGssClientIdentity },
f5835d
 	{ "gssapiserveridentity", oGssServerIdentity },
f5835d
 	{ "gssapirenewalforcesrekey", oGssRenewalRekey },
f5835d
+	{ "gssapikexalgorithms", oGssKexAlgorithms },
f5835d
 # else
f5835d
 	{ "gssapiauthentication", oUnsupported },
f5835d
 	{ "gssapikeyexchange", oUnsupported },
f5835d
@@ -207,6 +209,7 @@ static struct {
f5835d
 	{ "gssapitrustdns", oUnsupported },
f5835d
 	{ "gssapiclientidentity", oUnsupported },
f5835d
 	{ "gssapirenewalforcesrekey", oUnsupported },
f5835d
+	{ "gssapikexalgorithms", oUnsupported },
f5835d
 #endif
f5835d
 #ifdef ENABLE_PKCS11
f5835d
 	{ "smartcarddevice", oPKCS11Provider },
f5835d
@@ -929,6 +932,18 @@ parse_time:
f5835d
 		intptr = &options->gss_renewal_rekey;
f5835d
 		goto parse_flag;
f5835d
 
f5835d
+	case oGssKexAlgorithms:
f5835d
+		arg = strdelim(&s);
f5835d
+		if (!arg || *arg == '\0')
f5835d
+			fatal("%.200s line %d: Missing argument.",
f5835d
+			    filename, linenum);
f5835d
+		if (!gss_kex_names_valid(arg))
f5835d
+			fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
f5835d
+			    filename, linenum, arg ? arg : "<NONE>");
f5835d
+		if (*activep && options->gss_kex_algorithms == NULL)
f5835d
+			options->gss_kex_algorithms = xstrdup(arg);
f5835d
+		break;
f5835d
+
f5835d
 	case oBatchMode:
f5835d
 		intptr = &options->batch_mode;
f5835d
 		goto parse_flag;
f5835d
@@ -1638,6 +1653,7 @@ initialize_options(Options * options)
f5835d
 	options->gss_renewal_rekey = -1;
f5835d
 	options->gss_client_identity = NULL;
f5835d
 	options->gss_server_identity = NULL;
f5835d
+	options->gss_kex_algorithms = NULL;
f5835d
 	options->password_authentication = -1;
f5835d
 	options->kbd_interactive_authentication = -1;
f5835d
 	options->kbd_interactive_devices = NULL;
f5835d
@@ -1773,6 +1789,10 @@ fill_default_options(Options * options)
f5835d
 		options->gss_trust_dns = 0;
f5835d
 	if (options->gss_renewal_rekey == -1)
f5835d
 		options->gss_renewal_rekey = 0;
f5835d
+#ifdef GSSAPI
f5835d
+	if (options->gss_kex_algorithms == NULL)
f5835d
+		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
f5835d
+#endif
f5835d
 	if (options->password_authentication == -1)
f5835d
 		options->password_authentication = 1;
f5835d
 	if (options->kbd_interactive_authentication == -1)
f5835d
@@ -2651,6 +2671,8 @@ dump_client_config(Options *o, const cha
f5835d
 	dump_cfg_string(oGssClientIdentity, o->gss_client_identity);
f5835d
 	dump_cfg_string(oGssServerIdentity, o->gss_client_identity);
f5835d
 	dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey);
f5835d
+	dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ?
f5835d
+		o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX);
f5835d
 #endif /* GSSAPI */
f5835d
 	dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
f5835d
 	dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
f5835d
diff -up openssh-7.9p1/readconf.h.gsskexalg openssh-7.9p1/readconf.h
f5835d
--- openssh-7.9p1/readconf.h.gsskexalg	2018-11-14 09:20:06.616350574 +0100
f5835d
+++ openssh-7.9p1/readconf.h	2018-11-14 09:20:06.647350828 +0100
f5835d
@@ -46,6 +46,7 @@ typedef struct {
f5835d
 	int	gss_renewal_rekey;	/* Credential renewal forces rekey */
f5835d
 	char    *gss_client_identity;   /* Principal to initiate GSSAPI with */
f5835d
 	char    *gss_server_identity;   /* GSSAPI target principal */
f5835d
+	char   *gss_kex_algorithms;	/* GSSAPI kex methods to be offered by client. */
f5835d
 	int     password_authentication;	/* Try password
f5835d
 						 * authentication. */
f5835d
 	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
f5835d
diff -up openssh-7.0p1/servconf.c.gsskexalg openssh-7.0p1/servconf.c
f5835d
--- openssh-7.0p1/servconf.c.gsskexalg	2015-08-19 12:28:38.074518847 +0200
f5835d
+++ openssh-7.0p1/servconf.c	2015-08-19 12:33:13.599902732 +0200
f5835d
@@ -57,6 +57,7 @@
f5835d
 #include "auth.h"
f5835d
 #include "myproposal.h"
f5835d
 #include "digest.h"
f5835d
+#include "ssh-gss.h"
f5835d
 
f5835d
 static void add_listen_addr(ServerOptions *, const char *,
f5835d
     const char *, int);
f5835d
@@ -121,6 +122,7 @@ initialize_server_options(ServerOptions
f5835d
 	options->gss_cleanup_creds = -1;
f5835d
 	options->gss_strict_acceptor = -1;
f5835d
 	options->gss_store_rekey = -1;
f5835d
+	options->gss_kex_algorithms = NULL;
f5835d
 	options->use_kuserok = -1;
f5835d
 	options->enable_k5users = -1;
f5835d
 	options->password_authentication = -1;
f5835d
@@ -288,6 +290,10 @@ fill_default_server_options(ServerOption
f5835d
 		options->gss_strict_acceptor = 1;
f5835d
 	if (options->gss_store_rekey == -1)
f5835d
 		options->gss_store_rekey = 0;
f5835d
+#ifdef GSSAPI
f5835d
+	if (options->gss_kex_algorithms == NULL)
f5835d
+		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
f5835d
+#endif
f5835d
 	if (options->use_kuserok == -1)
f5835d
 		options->use_kuserok = 1;
f5835d
 	if (options->enable_k5users == -1)
f5835d
@@ -427,7 +431,7 @@ typedef enum {
f5835d
 	sHostKeyAlgorithms,
f5835d
 	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
f5835d
 	sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
f5835d
-	sGssKeyEx, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel,
f5835d
+	sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sSetEnv, sPermitTunnel,
f5835d
 	sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory,
f5835d
 	sUsePrivilegeSeparation, sAllowAgentForwarding,
f5835d
 	sHostCertificate,
f5835d
@@ -506,6 +510,7 @@ static struct {
f5835d
 	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
f5835d
 	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
f5835d
 	{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
f5835d
+	{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
f5835d
 #else
f5835d
 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
f5835d
 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
f5835d
@@ -513,6 +518,7 @@ static struct {
f5835d
 	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
f5835d
 	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
f5835d
 	{ "gssapienablek5users", sUnsupported, SSHCFG_ALL },
f5835d
+	{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
f5835d
 #endif
f5835d
 	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
f5835d
 	{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
f5835d
@@ -1273,6 +1279,18 @@ process_server_config_line(ServerOptions
f5835d
 		intptr = &options->gss_store_rekey;
f5835d
 		goto parse_flag;
f5835d
 
f5835d
+	case sGssKexAlgorithms:
f5835d
+		arg = strdelim(&cp;;
f5835d
+		if (!arg || *arg == '\0')
f5835d
+			fatal("%.200s line %d: Missing argument.",
f5835d
+			    filename, linenum);
f5835d
+		if (!gss_kex_names_valid(arg))
f5835d
+			fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
f5835d
+			    filename, linenum, arg ? arg : "<NONE>");
f5835d
+		if (*activep && options->gss_kex_algorithms == NULL)
f5835d
+			options->gss_kex_algorithms = xstrdup(arg);
f5835d
+		break;
f5835d
+
f5835d
 	case sPasswordAuthentication:
f5835d
 		intptr = &options->password_authentication;
f5835d
 		goto parse_flag;
f5835d
@@ -2304,6 +2322,7 @@ dump_config(ServerOptions *o)
f5835d
 	dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
f5835d
 	dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
f5835d
 	dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
f5835d
+	dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms);
f5835d
 #endif
f5835d
 	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
f5835d
 	dump_cfg_fmtint(sKbdInteractiveAuthentication,
f5835d
diff -up openssh-7.0p1/servconf.h.gsskexalg openssh-7.0p1/servconf.h
f5835d
--- openssh-7.0p1/servconf.h.gsskexalg	2015-08-19 12:28:38.080518834 +0200
f5835d
+++ openssh-7.0p1/servconf.h	2015-08-19 12:34:46.328693944 +0200
f5835d
@@ -122,6 +122,7 @@ typedef struct {
f5835d
 	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
f5835d
 	int     gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
f5835d
 	int 	gss_store_rekey;
f5835d
+	char   *gss_kex_algorithms;	/* GSSAPI kex methods to be offered by client. */
f5835d
 	int     password_authentication;	/* If true, permit password
f5835d
 						 * authentication. */
f5835d
 	int     kbd_interactive_authentication;	/* If true, permit */
f5835d
diff -up openssh-7.0p1/ssh.1.gsskexalg openssh-7.0p1/ssh.1
f5835d
--- openssh-7.0p1/ssh.1.gsskexalg	2015-08-19 12:28:38.081518832 +0200
f5835d
+++ openssh-7.0p1/ssh.1	2015-08-19 12:35:31.741591692 +0200
f5835d
@@ -496,6 +496,7 @@ For full details of the options listed b
f5835d
 .It GSSAPIDelegateCredentials
f5835d
 .It GSSAPIRenewalForcesRekey
f5835d
 .It GSSAPITrustDNS
f5835d
+.It GSSAPIKexAlgorithms
f5835d
 .It HashKnownHosts
f5835d
 .It Host
f5835d
 .It HostbasedAuthentication
f5835d
diff -up openssh-7.0p1/ssh_config.5.gsskexalg openssh-7.0p1/ssh_config.5
f5835d
--- openssh-7.0p1/ssh_config.5.gsskexalg	2015-08-19 12:28:38.028518950 +0200
f5835d
+++ openssh-7.0p1/ssh_config.5	2015-08-19 12:28:38.082518830 +0200
f5835d
@@ -786,6 +786,18 @@ command line will be passed untouched to
f5835d
 command line will be passed untouched to the GSSAPI library.
f5835d
 The default is
f5835d
 .Dq no .
f5835d
+.It Cm GSSAPIKexAlgorithms
f5835d
+The list of key exchange algorithms that are offered for GSSAPI
f5835d
+key exchange. Possible values are
f5835d
+.Bd -literal -offset 3n
f5835d
+gss-gex-sha1-,
f5835d
+gss-group1-sha1-,
f5835d
+gss-group14-sha1-
f5835d
+.Ed
f5835d
+.Pp
f5835d
+The default is
f5835d
+.Dq gss-gex-sha1-,gss-group14-sha1- .
f5835d
+This option only applies to protocol version 2 connections using GSSAPI.
f5835d
 .It Cm HashKnownHosts
f5835d
 Indicates that
f5835d
 .Xr ssh 1
f5835d
diff -up openssh-7.0p1/sshconnect2.c.gsskexalg openssh-7.0p1/sshconnect2.c
f5835d
--- openssh-7.0p1/sshconnect2.c.gsskexalg	2015-08-19 12:28:38.045518912 +0200
f5835d
+++ openssh-7.0p1/sshconnect2.c	2015-08-19 12:28:38.081518832 +0200
f5835d
@@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho
f5835d
 		else
f5835d
 			gss_host = host;
f5835d
 
f5835d
-		gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
f5835d
+		gss = ssh_gssapi_client_mechanisms(gss_host,
f5835d
+		    options.gss_client_identity, options.gss_kex_algorithms);
f5835d
 		if (gss) {
f5835d
 			debug("Offering GSSAPI proposal: %s", gss);
f5835d
 			xasprintf(&options.kex_algorithms,
f5835d
--- openssh-7.1p1/sshd_config.5.gsskexalg	2015-12-10 15:32:48.105418092 +0100
f5835d
+++ openssh-7.1p1/sshd_config.5	2015-12-10 15:33:47.771279548 +0100
f5835d
@@ -663,6 +663,18 @@ or updated credentials from a compatible
f5835d
 For this to work
f5835d
 .Cm GSSAPIKeyExchange
f5835d
 needs to be enabled in the server and also used by the client.
f5835d
+.It Cm GSSAPIKexAlgorithms
f5835d
+The list of key exchange algorithms that are accepted by GSSAPI
f5835d
+key exchange. Possible values are
f5835d
+.Bd -literal -offset 3n
f5835d
+gss-gex-sha1-,
f5835d
+gss-group1-sha1-,
f5835d
+gss-group14-sha1-
f5835d
+.Ed
f5835d
+.Pp
f5835d
+The default is
f5835d
+.Dq gss-gex-sha1-,gss-group14-sha1- .
f5835d
+This option only applies to protocol version 2 connections using GSSAPI.
f5835d
 .It Cm HostbasedAcceptedKeyTypes
f5835d
 Specifies the key types that will be accepted for hostbased authentication
f5835d
 as a list of comma-separated patterns.
f5835d
diff -up openssh-7.0p1/ssh-gss.h.gsskexalg openssh-7.0p1/ssh-gss.h
f5835d
--- openssh-7.0p1/ssh-gss.h.gsskexalg	2015-08-19 12:28:38.031518944 +0200
f5835d
+++ openssh-7.0p1/ssh-gss.h	2015-08-19 12:28:38.081518832 +0200
f5835d
@@ -76,6 +76,10 @@ extern char **k5users_allowed_cmds;
f5835d
 #define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-"
f5835d
 #define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
f5835d
 
f5835d
+#define        GSS_KEX_DEFAULT_KEX \
f5835d
+	KEX_GSS_GEX_SHA1_ID "," \
f5835d
+	KEX_GSS_GRP14_SHA1_ID
f5835d
+
f5835d
 typedef struct {
f5835d
 	char *envvar;
f5835d
 	char *envval;
f5835d
@@ -147,9 +151,9 @@ int ssh_gssapi_credentials_updated(Gssct
f5835d
 /* In the server */
f5835d
 typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, 
f5835d
     const char *);
f5835d
-char *ssh_gssapi_client_mechanisms(const char *, const char *);
f5835d
+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *);
f5835d
 char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
f5835d
-    const char *);
f5835d
+    const char *, const char *);
f5835d
 gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
f5835d
 int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, 
f5835d
     const char *);