upstream commit

support =- for removing methods from algorithms lists,
e.g. Ciphers=-*cbc; suggested by Cristian Ionescu-Idbohrn in bz#2671 "I like
it" markus@

Upstream-ID: c78c38f9f81a963b33d0eade559f6048add24a6d
diff --git a/compat.c b/compat.c
index 69a104f..1e80cfa 100644
--- a/compat.c
+++ b/compat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.c,v 1.99 2016/05/24 02:31:57 dtucker Exp $ */
+/* $OpenBSD: compat.c,v 1.100 2017/02/03 23:01:19 djm Exp $ */
 /*
  * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  *
@@ -37,6 +37,7 @@
 #include "compat.h"
 #include "log.h"
 #include "match.h"
+#include "kex.h"
 
 int compat13 = 0;
 int compat20 = 0;
@@ -250,42 +251,14 @@
 	return ret;
 }
 
-/*
- * Filters a proposal string, excluding any algorithm matching the 'filter'
- * pattern list.
- */
-static char *
-filter_proposal(char *proposal, const char *filter)
-{
-	Buffer b;
-	char *orig_prop, *fix_prop;
-	char *cp, *tmp;
-
-	buffer_init(&b);
-	tmp = orig_prop = xstrdup(proposal);
-	while ((cp = strsep(&tmp, ",")) != NULL) {
-		if (match_pattern_list(cp, filter, 0) != 1) {
-			if (buffer_len(&b) > 0)
-				buffer_append(&b, ",", 1);
-			buffer_append(&b, cp, strlen(cp));
-		} else
-			debug2("Compat: skipping algorithm \"%s\"", cp);
-	}
-	buffer_append(&b, "\0", 1);
-	fix_prop = xstrdup((char *)buffer_ptr(&b));
-	buffer_free(&b);
-	free(orig_prop);
-
-	return fix_prop;
-}
-
 char *
 compat_cipher_proposal(char *cipher_prop)
 {
 	if (!(datafellows & SSH_BUG_BIGENDIANAES))
 		return cipher_prop;
 	debug2("%s: original cipher proposal: %s", __func__, cipher_prop);
-	cipher_prop = filter_proposal(cipher_prop, "aes*");
+	if ((cipher_prop = match_filter_list(cipher_prop, "aes*")) == NULL)
+		fatal("match_filter_list failed");
 	debug2("%s: compat cipher proposal: %s", __func__, cipher_prop);
 	if (*cipher_prop == '\0')
 		fatal("No supported ciphers found");
@@ -298,7 +271,8 @@
 	if (!(datafellows & SSH_BUG_RSASIGMD5))
 		return pkalg_prop;
 	debug2("%s: original public key proposal: %s", __func__, pkalg_prop);
-	pkalg_prop = filter_proposal(pkalg_prop, "ssh-rsa");
+	if ((pkalg_prop = match_filter_list(pkalg_prop, "ssh-rsa")) == NULL)
+		fatal("match_filter_list failed");
 	debug2("%s: compat public key proposal: %s", __func__, pkalg_prop);
 	if (*pkalg_prop == '\0')
 		fatal("No supported PK algorithms found");
@@ -312,10 +286,14 @@
 		return p;
 	debug2("%s: original KEX proposal: %s", __func__, p);
 	if ((datafellows & SSH_BUG_CURVE25519PAD) != 0)
-		p = filter_proposal(p, "curve25519-sha256@libssh.org");
+		if ((p = match_filter_list(p,
+		    "curve25519-sha256@libssh.org")) == NULL)
+			fatal("match_filter_list failed");
 	if ((datafellows & SSH_OLD_DHGEX) != 0) {
-		p = filter_proposal(p, "diffie-hellman-group-exchange-sha256");
-		p = filter_proposal(p, "diffie-hellman-group-exchange-sha1");
+		if ((p = match_filter_list(p,
+		    "diffie-hellman-group-exchange-sha256,"
+		    "diffie-hellman-group-exchange-sha1")) == NULL)
+			fatal("match_filter_list failed");
 	}
 	debug2("%s: compat KEX proposal: %s", __func__, p);
 	if (*p == '\0')