external/openssh: update to 6.8p1.

In preparation for some updates to external/openssh to make it work with
BoringSSL, this change updates the code to a recent version. The current
version (5.9p1) is coming up on four years old now.

  * Confirmed that f5c67b478bef9992de9e9ec91ce10af4f6205e0d matches
    OpenSSH 5.9p1 exactly (save for the removal of the scard
    subdirectory).

  * Downloaded openssh-6.8p1.tar.gz (SHA256:
    3ff64ce73ee124480b5bf767b9830d7d3c03bbcb6abe716b78f0192c37ce160e)
    and verified with PGP signature. (I've verified Damien's key in
    person previously.)

  * Applied changes between f5c67b478bef9992de9e9ec91ce10af4f6205e0d and
    OpenSSH 5.9p1 to 6.8p1 and updated the build as best I can. The
    ugliest change is probably the duplication of umac.c to umac128.c
    because Android conditionally compiles that file twice. See the
    comment in those files.

Change-Id: I63cb07a8118afb5a377f116087a0882914cea486
diff --git a/auth-options.c b/auth-options.c
index eae45cf..4f0da9c 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.54 2010/12/24 21:41:48 djm Exp $ */
+/* $OpenBSD: auth-options.c,v 1.65 2015/01/14 10:30:34 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -21,22 +21,22 @@
 #include <stdarg.h>
 
 #include "openbsd-compat/sys-queue.h"
+
+#include "key.h"	/* XXX for typedef */
+#include "buffer.h"	/* XXX for typedef */
 #include "xmalloc.h"
 #include "match.h"
+#include "ssherr.h"
 #include "log.h"
 #include "canohost.h"
-#include "buffer.h"
+#include "sshbuf.h"
+#include "misc.h"
 #include "channels.h"
 #include "servconf.h"
-#include "misc.h"
-#include "key.h"
+#include "sshkey.h"
 #include "auth-options.h"
 #include "hostfile.h"
 #include "auth.h"
-#ifdef GSSAPI
-#include "ssh-gss.h"
-#endif
-#include "monitor_wrap.h"
 
 /* Flags set authorized_keys flags */
 int no_port_forwarding_flag = 0;
@@ -72,15 +72,15 @@
 	while (custom_environment) {
 		struct envstring *ce = custom_environment;
 		custom_environment = ce->next;
-		xfree(ce->s);
-		xfree(ce);
+		free(ce->s);
+		free(ce);
 	}
 	if (forced_command) {
-		xfree(forced_command);
+		free(forced_command);
 		forced_command = NULL;
 	}
 	if (authorized_principals) {
-		xfree(authorized_principals);
+		free(authorized_principals);
 		authorized_principals = NULL;
 	}
 	forced_tun_device = -1;
@@ -149,7 +149,7 @@
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
 			opts += strlen(cp);
 			if (forced_command != NULL)
-				xfree(forced_command);
+				free(forced_command);
 			forced_command = xmalloc(strlen(opts) + 1);
 			i = 0;
 			while (*opts) {
@@ -167,7 +167,7 @@
 				    file, linenum);
 				auth_debug_add("%.100s, line %lu: missing end quote",
 				    file, linenum);
-				xfree(forced_command);
+				free(forced_command);
 				forced_command = NULL;
 				goto bad_option;
 			}
@@ -180,7 +180,7 @@
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
 			opts += strlen(cp);
 			if (authorized_principals != NULL)
-				xfree(authorized_principals);
+				free(authorized_principals);
 			authorized_principals = xmalloc(strlen(opts) + 1);
 			i = 0;
 			while (*opts) {
@@ -198,7 +198,7 @@
 				    file, linenum);
 				auth_debug_add("%.100s, line %lu: missing end quote",
 				    file, linenum);
-				xfree(authorized_principals);
+				free(authorized_principals);
 				authorized_principals = NULL;
 				goto bad_option;
 			}
@@ -232,14 +232,14 @@
 				    file, linenum);
 				auth_debug_add("%.100s, line %lu: missing end quote",
 				    file, linenum);
-				xfree(s);
+				free(s);
 				goto bad_option;
 			}
 			s[i] = '\0';
 			auth_debug_add("Adding to environment: %.900s", s);
 			debug("Adding to environment: %.900s", s);
 			opts++;
-			new_envstring = xmalloc(sizeof(struct envstring));
+			new_envstring = xcalloc(1, sizeof(struct envstring));
 			new_envstring->s = s;
 			new_envstring->next = custom_environment;
 			custom_environment = new_envstring;
@@ -269,7 +269,7 @@
 				    file, linenum);
 				auth_debug_add("%.100s, line %lu: missing end quote",
 				    file, linenum);
-				xfree(patterns);
+				free(patterns);
 				goto bad_option;
 			}
 			patterns[i] = '\0';
@@ -277,7 +277,7 @@
 			switch (match_host_and_ip(remote_host, remote_ip,
 			    patterns)) {
 			case 1:
-				xfree(patterns);
+				free(patterns);
 				/* Host name matches. */
 				goto next_option;
 			case -1:
@@ -287,7 +287,7 @@
 				    "invalid criteria", file, linenum);
 				/* FALLTHROUGH */
 			case 0:
-				xfree(patterns);
+				free(patterns);
 				logit("Authentication tried for %.100s with "
 				    "correct key but not from a permitted "
 				    "host (host=%.200s, ip=%.200s).",
@@ -323,12 +323,13 @@
 				    file, linenum);
 				auth_debug_add("%.100s, line %lu: missing "
 				    "end quote", file, linenum);
-				xfree(patterns);
+				free(patterns);
 				goto bad_option;
 			}
 			patterns[i] = '\0';
 			opts++;
 			p = patterns;
+			/* XXX - add streamlocal support */
 			host = hpdelim(&p);
 			if (host == NULL || strlen(host) >= NI_MAXHOST) {
 				debug("%.100s, line %lu: Bad permitopen "
@@ -337,21 +338,21 @@
 				auth_debug_add("%.100s, line %lu: "
 				    "Bad permitopen specification", file,
 				    linenum);
-				xfree(patterns);
+				free(patterns);
 				goto bad_option;
 			}
 			host = cleanhostname(host);
-			if (p == NULL || (port = a2port(p)) <= 0) {
+			if (p == NULL || (port = permitopen_port(p)) < 0) {
 				debug("%.100s, line %lu: Bad permitopen port "
 				    "<%.100s>", file, linenum, p ? p : "");
 				auth_debug_add("%.100s, line %lu: "
 				    "Bad permitopen port", file, linenum);
-				xfree(patterns);
+				free(patterns);
 				goto bad_option;
 			}
-			if (options.allow_tcp_forwarding)
+			if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0)
 				channel_add_permitted_opens(host, port);
-			xfree(patterns);
+			free(patterns);
 			goto next_option;
 		}
 		cp = "tunnel=\"";
@@ -370,13 +371,13 @@
 				    file, linenum);
 				auth_debug_add("%.100s, line %lu: missing end quote",
 				    file, linenum);
-				xfree(tun);
+				free(tun);
 				forced_tun_device = -1;
 				goto bad_option;
 			}
 			tun[i] = '\0';
 			forced_tun_device = a2tun(tun, NULL);
-			xfree(tun);
+			free(tun);
 			if (forced_tun_device == SSH_TUNID_ERR) {
 				debug("%.100s, line %lu: invalid tun device",
 				    file, linenum);
@@ -420,7 +421,7 @@
 #define OPTIONS_CRITICAL	1
 #define OPTIONS_EXTENSIONS	2
 static int
-parse_option_list(u_char *optblob, size_t optblob_len, struct passwd *pw,
+parse_option_list(struct sshbuf *oblob, struct passwd *pw,
     u_int which, int crit,
     int *cert_no_port_forwarding_flag,
     int *cert_no_agent_forwarding_flag,
@@ -432,30 +433,26 @@
 {
 	char *command, *allowed;
 	const char *remote_ip;
-	u_char *name = NULL, *data_blob = NULL;
-	u_int nlen, dlen, clen;
-	Buffer c, data;
-	int ret = -1, found;
+	char *name = NULL;
+	struct sshbuf *c = NULL, *data = NULL;
+	int r, ret = -1, result, found;
 
-	buffer_init(&data);
+	if ((c = sshbuf_fromb(oblob)) == NULL) {
+		error("%s: sshbuf_fromb failed", __func__);
+		goto out;
+	}
 
-	/* Make copy to avoid altering original */
-	buffer_init(&c);
-	buffer_append(&c, optblob, optblob_len);
-
-	while (buffer_len(&c) > 0) {
-		if ((name = buffer_get_cstring_ret(&c, &nlen)) == NULL ||
-		    (data_blob = buffer_get_string_ret(&c, &dlen)) == NULL) {
-			error("Certificate options corrupt");
+	while (sshbuf_len(c) > 0) {
+		sshbuf_free(data);
+		data = NULL;
+		if ((r = sshbuf_get_cstring(c, &name, NULL)) != 0 ||
+		    (r = sshbuf_froms(c, &data)) != 0) {
+			error("Unable to parse certificate options: %s",
+			    ssh_err(r));
 			goto out;
 		}
-		buffer_append(&data, data_blob, dlen);
-		debug3("found certificate option \"%.100s\" len %u",
-		    name, dlen);
-		if (strlen(name) != nlen) {
-			error("Certificate constraint name contains \\0");
-			goto out;
-		}
+		debug3("found certificate option \"%.100s\" len %zu",
+		    name, sshbuf_len(data));
 		found = 0;
 		if ((which & OPTIONS_EXTENSIONS) != 0) {
 			if (strcmp(name, "permit-X11-forwarding") == 0) {
@@ -479,50 +476,41 @@
 		}
 		if (!found && (which & OPTIONS_CRITICAL) != 0) {
 			if (strcmp(name, "force-command") == 0) {
-				if ((command = buffer_get_cstring_ret(&data,
-				    &clen)) == NULL) {
-					error("Certificate constraint \"%s\" "
-					    "corrupt", name);
-					goto out;
-				}
-				if (strlen(command) != clen) {
-					error("force-command constraint "
-					    "contains \\0");
+				if ((r = sshbuf_get_cstring(data, &command,
+				    NULL)) != 0) {
+					error("Unable to parse \"%s\" "
+					    "section: %s", name, ssh_err(r));
 					goto out;
 				}
 				if (*cert_forced_command != NULL) {
 					error("Certificate has multiple "
 					    "force-command options");
-					xfree(command);
+					free(command);
 					goto out;
 				}
 				*cert_forced_command = command;
 				found = 1;
 			}
 			if (strcmp(name, "source-address") == 0) {
-				if ((allowed = buffer_get_cstring_ret(&data,
-				    &clen)) == NULL) {
-					error("Certificate constraint "
-					    "\"%s\" corrupt", name);
-					goto out;
-				}
-				if (strlen(allowed) != clen) {
-					error("source-address constraint "
-					    "contains \\0");
+				if ((r = sshbuf_get_cstring(data, &allowed,
+				    NULL)) != 0) {
+					error("Unable to parse \"%s\" "
+					    "section: %s", name, ssh_err(r));
 					goto out;
 				}
 				if ((*cert_source_address_done)++) {
 					error("Certificate has multiple "
 					    "source-address options");
-					xfree(allowed);
+					free(allowed);
 					goto out;
 				}
 				remote_ip = get_remote_ipaddr();
-				switch (addr_match_cidr_list(remote_ip,
-				    allowed)) {
+				result = addr_match_cidr_list(remote_ip,
+				    allowed);
+				free(allowed);
+				switch (result) {
 				case 1:
 					/* accepted */
-					xfree(allowed);
 					break;
 				case 0:
 					/* no match */
@@ -535,12 +523,11 @@
 					    "is not permitted to use this "
 					    "certificate for login.",
 					    remote_ip);
-					xfree(allowed);
 					goto out;
 				case -1:
+				default:
 					error("Certificate source-address "
 					    "contents invalid");
-					xfree(allowed);
 					goto out;
 				}
 				found = 1;
@@ -556,15 +543,13 @@
 				logit("Certificate extension \"%s\" "
 				    "is not supported", name);
 			}
-		} else if (buffer_len(&data) != 0) {
+		} else if (sshbuf_len(data) != 0) {
 			error("Certificate option \"%s\" corrupt "
 			    "(extra data)", name);
 			goto out;
 		}
-		buffer_clear(&data);
-		xfree(name);
-		xfree(data_blob);
-		name = data_blob = NULL;
+		free(name);
+		name = NULL;
 	}
 	/* successfully parsed all options */
 	ret = 0;
@@ -573,15 +558,13 @@
 	if (ret != 0 &&
 	    cert_forced_command != NULL &&
 	    *cert_forced_command != NULL) {
-		xfree(*cert_forced_command);
+		free(*cert_forced_command);
 		*cert_forced_command = NULL;
 	}
 	if (name != NULL)
-		xfree(name);
-	if (data_blob != NULL)
-		xfree(data_blob);
-	buffer_free(&data);
-	buffer_free(&c);
+		free(name);
+	sshbuf_free(data);
+	sshbuf_free(c);
 	return ret;
 }
 
@@ -590,7 +573,7 @@
  * options so this must be called after auth_parse_options().
  */
 int
-auth_cert_options(Key *k, struct passwd *pw)
+auth_cert_options(struct sshkey *k, struct passwd *pw)
 {
 	int cert_no_port_forwarding_flag = 1;
 	int cert_no_agent_forwarding_flag = 1;
@@ -600,10 +583,9 @@
 	char *cert_forced_command = NULL;
 	int cert_source_address_done = 0;
 
-	if (key_cert_is_legacy(k)) {
+	if (sshkey_cert_is_legacy(k)) {
 		/* All options are in the one field for v00 certs */
-		if (parse_option_list(buffer_ptr(&k->cert->critical),
-		    buffer_len(&k->cert->critical), pw,
+		if (parse_option_list(k->cert->critical, pw,
 		    OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1,
 		    &cert_no_port_forwarding_flag,
 		    &cert_no_agent_forwarding_flag,
@@ -615,14 +597,12 @@
 			return -1;
 	} else {
 		/* Separate options and extensions for v01 certs */
-		if (parse_option_list(buffer_ptr(&k->cert->critical),
-		    buffer_len(&k->cert->critical), pw,
+		if (parse_option_list(k->cert->critical, pw,
 		    OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL,
 		    &cert_forced_command,
 		    &cert_source_address_done) == -1)
 			return -1;
-		if (parse_option_list(buffer_ptr(&k->cert->extensions),
-		    buffer_len(&k->cert->extensions), pw,
+		if (parse_option_list(k->cert->extensions, pw,
 		    OPTIONS_EXTENSIONS, 1,
 		    &cert_no_port_forwarding_flag,
 		    &cert_no_agent_forwarding_flag,
@@ -641,7 +621,7 @@
 	/* CA-specified forced command supersedes key option */
 	if (cert_forced_command != NULL) {
 		if (forced_command != NULL)
-			xfree(forced_command);
+			free(forced_command);
 		forced_command = cert_forced_command;
 	}
 	return 0;