- djm@cvs.openbsd.org 2013/05/16 04:27:50
     [ssh_config.5 readconf.h readconf.c]
     add the ability to ignore specific unrecognised ssh_config options;
     bz#866; ok markus@
diff --git a/readconf.c b/readconf.c
index d8898a0..51b23a3 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.198 2013/05/16 02:00:34 dtucker Exp $ */
+/* $OpenBSD: readconf.c,v 1.199 2013/05/16 04:27:50 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -134,8 +134,8 @@
 	oHashKnownHosts,
 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
 	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
-	oKexAlgorithms, oIPQoS, oRequestTTY,
-	oDeprecated, oUnsupported
+	oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown,
+	oIgnoredUnknownOption, oDeprecated, oUnsupported
 } OpCodes;
 
 /* Textual representations of the tokens. */
@@ -246,6 +246,7 @@
 	{ "kexalgorithms", oKexAlgorithms },
 	{ "ipqos", oIPQoS },
 	{ "requesttty", oRequestTTY },
+	{ "ignoreunknown", oIgnoreUnknown },
 
 	{ NULL, oBadOption }
 };
@@ -351,14 +352,17 @@
  */
 
 static OpCodes
-parse_token(const char *cp, const char *filename, int linenum)
+parse_token(const char *cp, const char *filename, int linenum,
+    const char *ignored_unknown)
 {
-	u_int i;
+	int i;
 
 	for (i = 0; keywords[i].name; i++)
-		if (strcasecmp(cp, keywords[i].name) == 0)
+		if (strcmp(cp, keywords[i].name) == 0)
 			return keywords[i].opcode;
-
+	if (ignored_unknown != NULL && match_pattern_list(cp, ignored_unknown,
+	    strlen(ignored_unknown), 1) == 1)
+		return oIgnoredUnknownOption;
 	error("%s: line %d: Bad configuration option: %s",
 	    filename, linenum, cp);
 	return oBadOption;
@@ -377,7 +381,7 @@
 {
 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
 	char **cpptr, fwdarg[256];
-	u_int *uintptr, max_entries = 0;
+	u_int i, *uintptr, max_entries = 0;
 	int negated, opcode, *intptr, value, value2, scale;
 	LogLevel *log_level_ptr;
 	long long orig, val64;
@@ -400,14 +404,22 @@
 		keyword = strdelim(&s);
 	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
 		return 0;
+	/* Match lowercase keyword */
+	for (i = 0; i < strlen(keyword); i++)
+		keyword[i] = tolower(keyword[i]);
 
-	opcode = parse_token(keyword, filename, linenum);
+	opcode = parse_token(keyword, filename, linenum,
+	    options->ignored_unknown);
 
 	switch (opcode) {
 	case oBadOption:
 		/* don't panic, but count bad options */
 		return -1;
 		/* NOTREACHED */
+	case oIgnoredUnknownOption:
+		debug("%s line %d: Ignored unknown option \"%s\"",
+		    filename, linenum, keyword);
+		return 0;
 	case oConnectTimeout:
 		intptr = &options->connection_timeout;
 parse_time:
@@ -1077,6 +1089,10 @@
 			*intptr = value;
 		break;
 
+	case oIgnoreUnknown:
+		charptr = &options->ignored_unknown;
+		goto parse_string;
+
 	case oDeprecated:
 		debug("%s line %d: Deprecated option \"%s\"",
 		    filename, linenum, keyword);
@@ -1238,6 +1254,7 @@
 	options->ip_qos_interactive = -1;
 	options->ip_qos_bulk = -1;
 	options->request_tty = -1;
+	options->ignored_unknown = NULL;
 }
 
 /*