upstream commit

add sshd_config HostbasedAcceptedKeyTypes and
 PubkeyAcceptedKeyTypes options to allow sshd to control what public key types
 will be accepted. Currently defaults to all. Feedback & ok markus@
diff --git a/sshkey.c b/sshkey.c
index a680929..30f209a 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.10 2015/01/12 20:13:27 markus Exp $ */
+/* $OpenBSD: sshkey.c,v 1.11 2015/01/13 07:39:19 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -54,6 +54,7 @@
 #include "digest.h"
 #define SSHKEY_INTERNAL
 #include "sshkey.h"
+#include "match.h"
 
 /* openssh private key file format */
 #define MARK_BEGIN		"-----BEGIN OPENSSH PRIVATE KEY-----\n"
@@ -219,9 +220,11 @@
 }
 
 int
-sshkey_names_valid2(const char *names)
+sshkey_names_valid2(const char *names, int allow_wildcard)
 {
 	char *s, *cp, *p;
+	const struct keytype *kt;
+	int type;
 
 	if (names == NULL || strcmp(names, "") == 0)
 		return 0;
@@ -229,9 +232,28 @@
 		return 0;
 	for ((p = strsep(&cp, ",")); p && *p != '\0';
 	    (p = strsep(&cp, ","))) {
-		switch (sshkey_type_from_name(p)) {
-		case KEY_RSA1:
-		case KEY_UNSPEC:
+		type = sshkey_type_from_name(p);
+		if (type == KEY_RSA1) {
+			free(s);
+			return 0;
+		}
+		if (type == KEY_UNSPEC) {
+			if (allow_wildcard) {
+				/*
+				 * Try matching key types against the string.
+				 * If any has a positive or negative match then
+				 * the component is accepted.
+				 */
+				for (kt = keytypes; kt->type != -1; kt++) {
+					if (kt->type == KEY_RSA1)
+						continue;
+					if (match_pattern_list(kt->name,
+					    p, strlen(p), 0) != 0)
+						break;
+				}
+				if (kt->type != -1)
+					continue;
+			}
 			free(s);
 			return 0;
 		}