jonathancammack / rpms / openssh

Forked from rpms/openssh 8 months ago
Clone

Blame SOURCES/openssh-6.6p1-gssKexAlgorithms.patch

674526
diff -up openssh-6.6p1/gss-genr.c.gsskexalg openssh-6.6p1/gss-genr.c
674526
--- openssh-6.6p1/gss-genr.c.gsskexalg	2015-08-14 16:07:33.271343064 +0200
674526
+++ openssh-6.6p1/gss-genr.c	2015-08-14 16:07:33.338342936 +0200
674526
@@ -76,7 +76,8 @@ ssh_gssapi_oid_table_ok() {
674526
  */
674526
 
674526
 char *
674526
-ssh_gssapi_client_mechanisms(const char *host, const char *client) {
674526
+ssh_gssapi_client_mechanisms(const char *host, const char *client,
674526
+    const char *kex) {
674526
 	gss_OID_set gss_supported;
674526
 	OM_uint32 min_status;
674526
 
674526
@@ -84,12 +85,12 @@ ssh_gssapi_client_mechanisms(const char
674526
 		return NULL;
674526
 
674526
 	return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
674526
-	    host, client));
674526
+	    host, client, kex));
674526
 }
674526
 
674526
 char *
674526
 ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
674526
-    const char *host, const char *client) {
674526
+    const char *host, const char *client, const char *kex) {
674526
 	Buffer buf;
674526
 	size_t i;
674526
 	int oidpos, enclen;
674526
@@ -98,6 +99,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
674526
 	char deroid[2];
674526
 	const EVP_MD *evp_md = EVP_md5();
674526
 	EVP_MD_CTX md;
674526
+	char *s, *cp, *p;
674526
 
674526
 	if (gss_enc2oid != NULL) {
674526
 		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
674526
@@ -111,6 +113,7 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
674526
 	buffer_init(&buf;;
674526
 
674526
 	oidpos = 0;
674526
+	s = cp = xstrdup(kex);
674526
 	for (i = 0; i < gss_supported->count; i++) {
674526
 		if (gss_supported->elements[i].length < 128 &&
674526
 		    (*check)(NULL, &(gss_supported->elements[i]), host, client)) {
674526
@@ -129,26 +132,22 @@ ssh_gssapi_kex_mechs(gss_OID_set gss_sup
674526
 			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
674526
 			    encoded, EVP_MD_size(evp_md) * 2);
674526
 
674526
-			if (oidpos != 0)
674526
-				buffer_put_char(&buf, ',');
674526
-
674526
-			buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
674526
-			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
674526
-			buffer_append(&buf, encoded, enclen);
674526
-			buffer_put_char(&buf, ',');
674526
-			buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 
674526
-			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
674526
-			buffer_append(&buf, encoded, enclen);
674526
-			buffer_put_char(&buf, ',');
674526
-			buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
674526
-			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
674526
-			buffer_append(&buf, encoded, enclen);
674526
+			cp = strncpy(s, kex, strlen(kex));
674526
+			for ((p = strsep(&cp, ",")); p && *p != '\0';
674526
+				(p = strsep(&cp, ","))) {
674526
+				if (buffer_len(&buf) != 0)
674526
+					buffer_put_char(&buf, ',');
674526
+				buffer_append(&buf, p,
674526
+				    strlen(p));
674526
+				buffer_append(&buf, encoded, enclen);
674526
+			}
674526
 
674526
 			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
674526
 			gss_enc2oid[oidpos].encoded = encoded;
674526
 			oidpos++;
674526
 		}
674526
 	}
674526
+	free(s);
674526
 	gss_enc2oid[oidpos].oid = NULL;
674526
 	gss_enc2oid[oidpos].encoded = NULL;
674526
 
674526
diff -up openssh-6.6p1/gss-serv.c.gsskexalg openssh-6.6p1/gss-serv.c
674526
--- openssh-6.6p1/gss-serv.c.gsskexalg	2015-08-14 16:07:33.296343016 +0200
674526
+++ openssh-6.6p1/gss-serv.c	2015-08-14 16:07:33.338342936 +0200
674526
@@ -151,7 +151,7 @@ ssh_gssapi_server_mechanisms() {
674526
 
674526
 	ssh_gssapi_supported_oids(&supported);
674526
 	return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech,
674526
-	    NULL, NULL));
674526
+	    NULL, NULL, options.gss_kex_algorithms));
674526
 }
674526
 
674526
 /* Unprivileged */
674526
diff -up openssh-6.6p1/kex.c.gsskexalg openssh-6.6p1/kex.c
674526
--- openssh-6.6p1/kex.c.gsskexalg	2015-08-14 16:07:33.271343064 +0200
674526
+++ openssh-6.6p1/kex.c	2015-08-14 16:07:33.339342935 +0200
674526
@@ -160,6 +160,29 @@ kex_names_valid(const char *names)
674526
 	return 1;
674526
 }
674526
 
674526
+/* Validate GSS KEX method name list */
674526
+int
674526
+gss_kex_names_valid(const char *names)
674526
+{
674526
+	char *s, *cp, *p;
674526
+
674526
+	if (names == NULL || *names == '\0')
674526
+		return 0;
674526
+	s = cp = xstrdup(names);
674526
+	for ((p = strsep(&cp, ",")); p && *p != '\0';
674526
+	    (p = strsep(&cp, ","))) {
674526
+		if (strncmp(p, "gss-", 4) != 0
674526
+		  || kex_alg_by_name(p) == NULL) {
674526
+			error("Unsupported KEX algorithm \"%.100s\"", p);
674526
+			free(s);
674526
+			return 0;
674526
+		}
674526
+	}
674526
+	debug3("gss kex names ok: [%s]", names);
674526
+	free(s);
674526
+	return 1;
674526
+}
674526
+
674526
 /* put algorithm proposal into buffer */
674526
 static void
674526
 kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
674526
diff -up openssh-6.6p1/readconf.c.gsskexalg openssh-6.6p1/readconf.c
674526
--- openssh-6.6p1/readconf.c.gsskexalg	2015-08-14 16:07:33.274343058 +0200
674526
+++ openssh-6.6p1/readconf.c	2015-08-14 16:14:17.600574919 +0200
674526
@@ -55,6 +55,7 @@
674526
 #include "kex.h"
674526
 #include "mac.h"
674526
 #include "uidswap.h"
674526
+#include "ssh-gss.h"
674526
 
674526
 /* Format of the configuration file:
674526
 
674526
@@ -142,7 +143,7 @@ typedef enum {
674526
 	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
674526
 	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
674526
 	oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
674526
-	oGssServerIdentity, 
674526
+	oGssServerIdentity, oGssKexAlgorithms,
674526
 	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
674526
 	oSendEnv, oControlPath, oControlMaster, oControlPersist,
674526
 	oHashKnownHosts,
674526
@@ -191,6 +192,7 @@ static struct {
674526
 	{ "gssapiclientidentity", oGssClientIdentity },
674526
 	{ "gssapiserveridentity", oGssServerIdentity },
674526
 	{ "gssapirenewalforcesrekey", oGssRenewalRekey },
674526
+	{ "gssapikexalgorithms", oGssKexAlgorithms },
674526
 #else
674526
 	{ "gssapiauthentication", oUnsupported },
674526
 	{ "gssapikeyexchange", oUnsupported },
674526
@@ -198,6 +200,7 @@ static struct {
674526
 	{ "gssapitrustdns", oUnsupported },
674526
 	{ "gssapiclientidentity", oUnsupported },
674526
 	{ "gssapirenewalforcesrekey", oUnsupported },
674526
+	{ "gssapikexalgorithms", oUnsupported },
674526
 #endif
674526
 	{ "fallbacktorsh", oDeprecated },
674526
 	{ "usersh", oDeprecated },
674526
@@ -876,6 +879,18 @@ parse_time:
674526
 		intptr = &options->gss_renewal_rekey;
674526
 		goto parse_flag;
674526
 
674526
+	case oGssKexAlgorithms:
674526
+		arg = strdelim(&s);
674526
+		if (!arg || *arg == '\0')
674526
+			fatal("%.200s line %d: Missing argument.",
674526
+			    filename, linenum);
674526
+		if (!gss_kex_names_valid(arg))
674526
+			fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
674526
+			    filename, linenum, arg ? arg : "<NONE>");
674526
+		if (*activep && options->gss_kex_algorithms == NULL)
674526
+			options->gss_kex_algorithms = xstrdup(arg);
674526
+		break;
674526
+
674526
 	case oBatchMode:
674526
 		intptr = &options->batch_mode;
674526
 		goto parse_flag;
674526
@@ -1534,6 +1549,7 @@ initialize_options(Options * options)
674526
 	options->gss_renewal_rekey = -1;
674526
 	options->gss_client_identity = NULL;
674526
 	options->gss_server_identity = NULL;
674526
+	options->gss_kex_algorithms = NULL;
674526
 	options->password_authentication = -1;
674526
 	options->kbd_interactive_authentication = -1;
674526
 	options->kbd_interactive_devices = NULL;
674526
@@ -1660,6 +1676,8 @@ fill_default_options(Options * options)
674526
 		options->gss_trust_dns = 0;
674526
 	if (options->gss_renewal_rekey == -1)
674526
 		options->gss_renewal_rekey = 0;
674526
+	if (options->gss_kex_algorithms == NULL)
674526
+		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
674526
 	if (options->password_authentication == -1)
674526
 		options->password_authentication = 1;
674526
 	if (options->kbd_interactive_authentication == -1)
674526
diff -up openssh-6.6p1/readconf.h.gsskexalg openssh-6.6p1/readconf.h
674526
--- openssh-6.6p1/readconf.h.gsskexalg	2015-08-14 16:07:33.274343058 +0200
674526
+++ openssh-6.6p1/readconf.h	2015-08-14 16:07:33.339342935 +0200
674526
@@ -60,6 +60,7 @@ typedef struct {
674526
 	int	gss_renewal_rekey;	/* Credential renewal forces rekey */
674526
 	char    *gss_client_identity;   /* Principal to initiate GSSAPI with */
674526
 	char    *gss_server_identity;   /* GSSAPI target principal */
674526
+	char   *gss_kex_algorithms;	/* GSSAPI kex methods to be offered by client. */
674526
 	int     password_authentication;	/* Try password
674526
 						 * authentication. */
674526
 	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
674526
diff -up openssh-6.6p1/servconf.c.gsskexalg openssh-6.6p1/servconf.c
674526
--- openssh-6.6p1/servconf.c.gsskexalg	2015-08-14 16:07:45.704319443 +0200
674526
+++ openssh-6.6p1/servconf.c	2015-08-14 16:14:15.306579277 +0200
674526
@@ -54,6 +54,7 @@
674526
 #include "packet.h"
674526
 #include "hostfile.h"
674526
 #include "auth.h"
674526
+#include "ssh-gss.h"
674526
 
674526
 static void add_listen_addr(ServerOptions *, char *, int);
674526
 static void add_one_listen_addr(ServerOptions *, char *, int);
674526
@@ -112,6 +113,7 @@ initialize_server_options(ServerOptions
674526
 	options->gss_cleanup_creds = -1;
674526
 	options->gss_strict_acceptor = -1;
674526
 	options->gss_store_rekey = -1;
674526
+	options->gss_kex_algorithms = NULL;
674526
 	options->password_authentication = -1;
674526
 	options->kbd_interactive_authentication = -1;
674526
 	options->challenge_response_authentication = -1;
674526
@@ -258,6 +260,8 @@ fill_default_server_options(ServerOption
674526
 		options->gss_strict_acceptor = 1;
674526
 	if (options->gss_store_rekey == -1)
674526
 		options->gss_store_rekey = 0;
674526
+	if (options->gss_kex_algorithms == NULL)
674526
+		options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
674526
 	if (options->password_authentication == -1)
674526
 		options->password_authentication = 1;
674526
 	if (options->kbd_interactive_authentication == -1)
674526
@@ -360,7 +364,7 @@ typedef enum {
674526
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
674526
 	sClientAliveCountMax, sAuthorizedKeysFile,
674526
 	sGssAuthentication, sGssCleanupCreds, sGssEnablek5users, sGssStrictAcceptor,
674526
-	sGssKeyEx, sGssStoreRekey, sAcceptEnv, sPermitTunnel,
674526
+	sGssKeyEx, sGssStoreRekey, sGssKexAlgorithms, sAcceptEnv, sPermitTunnel,
674526
 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
674526
 	sUsePrivilegeSeparation, sAllowAgentForwarding,
674526
 	sHostCertificate,
674526
@@ -434,6 +438,7 @@ static struct {
674526
 	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
674526
 	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
674526
 	{ "gssapienablek5users", sGssEnablek5users, SSHCFG_ALL },
674526
+	{ "gssapikexalgorithms", sGssKexAlgorithms, SSHCFG_GLOBAL },
674526
 #else
674526
 	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
674526
 	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
674526
@@ -442,6 +447,7 @@ static struct {
674526
 	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
674526
 	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
674526
 	{ "gssapienablek5users", sUnsupported, SSHCFG_ALL },
674526
+	{ "gssapikexalgorithms", sUnsupported, SSHCFG_GLOBAL },
674526
 #endif
674526
 	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
674526
 	{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
674526
@@ -1137,6 +1143,18 @@ process_server_config_line(ServerOptions
674526
 		intptr = &options->gss_store_rekey;
674526
 		goto parse_flag;
674526
 
674526
+	case sGssKexAlgorithms:
674526
+		arg = strdelim(&cp;;
674526
+		if (!arg || *arg == '\0')
674526
+			fatal("%.200s line %d: Missing argument.",
674526
+			    filename, linenum);
674526
+		if (!gss_kex_names_valid(arg))
674526
+			fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
674526
+			    filename, linenum, arg ? arg : "<NONE>");
674526
+		if (*activep && options->gss_kex_algorithms == NULL)
674526
+			options->gss_kex_algorithms = xstrdup(arg);
674526
+		break;
674526
+
674526
 	case sPasswordAuthentication:
674526
 		intptr = &options->password_authentication;
674526
 		goto parse_flag;
674526
@@ -2068,6 +2086,7 @@ dump_config(ServerOptions *o)
674526
 	dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
674526
 	dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
674526
 	dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
674526
+	dump_cfg_string(sGssKexAlgorithms, o->gss_kex_algorithms);
674526
 #endif
674526
 	dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
674526
 	dump_cfg_fmtint(sKbdInteractiveAuthentication,
674526
diff -up openssh-6.6p1/servconf.h.gsskexalg openssh-6.6p1/servconf.h
674526
--- openssh-6.6p1/servconf.h.gsskexalg	2015-08-14 16:07:48.160314777 +0200
674526
+++ openssh-6.6p1/servconf.h	2015-08-14 16:09:34.447112854 +0200
674526
@@ -116,6 +116,7 @@ typedef struct {
674526
 	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
674526
 	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
674526
 	int 	gss_store_rekey;
674526
+	char   *gss_kex_algorithms;	/* GSSAPI kex methods to be offered by client. */
674526
 	int     password_authentication;	/* If true, permit password
674526
 						 * authentication. */
674526
 	int     kbd_interactive_authentication;	/* If true, permit */
674526
diff -up openssh-6.6p1/sshconnect2.c.gsskexalg openssh-6.6p1/sshconnect2.c
674526
--- openssh-6.6p1/sshconnect2.c.gsskexalg	2015-08-14 16:07:33.304343001 +0200
674526
+++ openssh-6.6p1/sshconnect2.c	2015-08-14 16:07:33.339342935 +0200
674526
@@ -179,7 +179,8 @@ ssh_kex2(char *host, struct sockaddr *ho
674526
 		else
674526
 			gss_host = host;
674526
 
674526
-		gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
674526
+		gss = ssh_gssapi_client_mechanisms(gss_host,
674526
+		    options.gss_client_identity, options.gss_kex_algorithms);
674526
 		if (gss) {
674526
 			debug("Offering GSSAPI proposal: %s", gss);
674526
 			xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
674526
diff -up openssh-6.6p1/ssh-gss.h.gsskexalg openssh-6.6p1/ssh-gss.h
674526
--- openssh-6.6p1/ssh-gss.h.gsskexalg	2015-08-14 16:07:33.278343050 +0200
674526
+++ openssh-6.6p1/ssh-gss.h	2015-08-14 16:07:33.340342932 +0200
674526
@@ -76,6 +76,11 @@ extern char **k5users_allowed_cmds;
674526
 #define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-"
674526
 #define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
674526
 
674526
+#define        GSS_KEX_DEFAULT_KEX \
674526
+	KEX_GSS_GEX_SHA1_ID "," \
674526
+	KEX_GSS_GRP1_SHA1_ID "," \
674526
+	KEX_GSS_GRP14_SHA1_ID
674526
+
674526
 typedef struct {
674526
 	char *filename;
674526
 	char *envvar;
674526
@@ -147,9 +152,9 @@ int ssh_gssapi_credentials_updated(Gssct
674526
 /* In the server */
674526
 typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, 
674526
     const char *);
674526
-char *ssh_gssapi_client_mechanisms(const char *, const char *);
674526
+char *ssh_gssapi_client_mechanisms(const char *, const char *, const char *);
674526
 char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
674526
-    const char *);
674526
+    const char *, const char *);
674526
 gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
674526
 int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, 
674526
     const char *);
674526
diff --git a/ssh.1 b/ssh.1
674526
index 4a7d1cd..c795c40 100644
674526
--- a/ssh.1
674526
+++ b/ssh.1
674526
@@ -449,6 +449,7 @@ For full details of the options listed below, and their possible values, see
674526
 .It GSSAPIDelegateCredentials
674526
 .It GSSAPIRenewalForcesRekey
674526
 .It GSSAPITrustDns
674526
+.It GSSAPIKexAlgorithms
674526
 .It HashKnownHosts
674526
 .It Host
674526
 .It HostbasedAuthentication
674526
diff --git a/ssh_config.5 b/ssh_config.5
674526
index c95fda6..a2af9c4 100644
674526
--- a/ssh_config.5
674526
+++ b/ssh_config.5
674526
@@ -719,6 +719,18 @@ command line will be passed untouched to the GSSAPI library.
674526
 The default is
674526
 .Dq no .
674526
 This option only applies to protocol version 2 connections using GSSAPI.
674526
+.It Cm GSSAPIKexAlgorithms
674526
+The list of key exchange algorithms that are offered for GSSAPI
674526
+key exchange. Possible values are
674526
+.Bd -literal -offset 3n
674526
+gss-gex-sha1-,
674526
+gss-group1-sha1-,
674526
+gss-group14-sha1-
674526
+.Ed
674526
+.Pp
674526
+The default is
674526
+.Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- .
674526
+This option only applies to protocol version 2 connections using GSSAPI.
674526
 .It Cm HashKnownHosts
674526
 Indicates that
674526
 .Xr ssh 1
674526
diff --git a/sshd_config.5 b/sshd_config.5
674526
index 5e8c6c6..4c670aa 100644
674526
--- a/sshd_config.5
674526
+++ b/sshd_config.5
674526
@@ -545,6 +545,18 @@ Controls whether the user's GSSAPI credentials should be updated following a
674526
 successful connection rekeying. This option can be used to accepted renewed 
674526
 or updated credentials from a compatible client. The default is
674526
 .Dq no .
674526
+.It Cm GSSAPIKexAlgorithms
674526
+The list of key exchange algorithms that are accepted by GSSAPI
674526
+key exchange. Possible values are
674526
+.Bd -literal -offset 3n
674526
+gss-gex-sha1-,
674526
+gss-group1-sha1-,
674526
+gss-group14-sha1-
674526
+.Ed
674526
+.Pp
674526
+The default is
674526
+.Dq gss-gex-sha1-,gss-group1-sha1-,gss-group14-sha1- .
674526
+This option only applies to protocol version 2 connections using GSSAPI.
674526
 .It Cm HostbasedAuthentication
674526
 Specifies whether rhosts or /etc/hosts.equiv authentication together
674526
 with successful public key client host authentication is allowed
f8987c
diff --git a/kex.h b/kex.h
f8987c
index db3dde4..17ae43b 100644
f8987c
--- a/kex.h
f8987c
+++ b/kex.h
f8987c
@@ -158,6 +158,7 @@ struct Kex {
f8987c
 
f8987c
 int	 kex_names_valid(const char *);
f8987c
 char	*kex_alg_list(char);
f8987c
+int	 gss_kex_names_valid(const char *);
f8987c
 
f8987c
 Kex	*kex_setup(char *[PROPOSAL_MAX]);
f8987c
 void	 kex_finish(Kex *);