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/session.c b/session.c
index 71466ff..9a15384 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.258 2010/11/25 04:10:09 djm Exp $ */
+/* $OpenBSD: session.c,v 1.277 2015/01/16 06:40:12 deraadt Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -49,6 +49,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <grp.h>
+#include <netdb.h>
 #ifdef HAVE_PATHS_H
 #include <paths.h>
 #endif
@@ -59,6 +60,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <limits.h>
 
 #include "openbsd-compat/sys-queue.h"
 #include "xmalloc.h"
@@ -80,13 +82,14 @@
 #include "hostfile.h"
 #include "auth.h"
 #include "auth-options.h"
+#include "authfd.h"
 #include "pathnames.h"
 #include "log.h"
+#include "misc.h"
 #include "servconf.h"
 #include "sshlogin.h"
 #include "serverloop.h"
 #include "canohost.h"
-#include "misc.h"
 #include "session.h"
 #include "kex.h"
 #include "monitor_wrap.h"
@@ -181,7 +184,6 @@
 {
 	Channel *nc;
 	int sock = -1;
-	struct sockaddr_un sunaddr;
 
 	if (auth_sock_name != NULL) {
 		error("authentication forwarding requested twice.");
@@ -199,7 +201,7 @@
 		packet_send_debug("Agent forwarding disabled: "
 		    "mkdtemp() failed: %.100s", strerror(errno));
 		restore_uid();
-		xfree(auth_sock_dir);
+		free(auth_sock_dir);
 		auth_sock_dir = NULL;
 		goto authsock_err;
 	}
@@ -207,33 +209,15 @@
 	xasprintf(&auth_sock_name, "%s/agent.%ld",
 	    auth_sock_dir, (long) getpid());
 
-	/* Create the socket. */
-	sock = socket(AF_UNIX, SOCK_STREAM, 0);
-	if (sock < 0) {
-		error("socket: %.100s", strerror(errno));
-		restore_uid();
-		goto authsock_err;
-	}
-
-	/* Bind it to the name. */
-	memset(&sunaddr, 0, sizeof(sunaddr));
-	sunaddr.sun_family = AF_UNIX;
-	strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
-
-	if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
-		error("bind: %.100s", strerror(errno));
-		restore_uid();
-		goto authsock_err;
-	}
+	/* Start a Unix listener on auth_sock_name. */
+	sock = unix_listener(auth_sock_name, SSH_LISTEN_BACKLOG, 0);
 
 	/* Restore the privileged uid. */
 	restore_uid();
 
-	/* Start listening on the socket. */
-	if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
-		error("listen: %.100s", strerror(errno));
+	/* Check for socket/bind/listen failure. */
+	if (sock < 0)
 		goto authsock_err;
-	}
 
 	/* Allocate a channel for the authentication agent socket. */
 	nc = channel_new("auth socket",
@@ -244,11 +228,10 @@
 	return 1;
 
  authsock_err:
-	if (auth_sock_name != NULL)
-		xfree(auth_sock_name);
+	free(auth_sock_name);
 	if (auth_sock_dir != NULL) {
 		rmdir(auth_sock_dir);
-		xfree(auth_sock_dir);
+		free(auth_sock_dir);
 	}
 	if (sock != -1)
 		close(sock);
@@ -273,7 +256,11 @@
 	setproctitle("%s", authctxt->pw->pw_name);
 
 	/* setup the channel layer */
-	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
+	/* XXX - streamlocal? */
+	if (no_port_forwarding_flag ||
+	    (options.allow_tcp_forwarding & FORWARD_LOCAL) == 0)
+		channel_disable_adm_local_opens();
+	else
 		channel_permit_all_opens();
 
 	auth_debug_send();
@@ -361,8 +348,8 @@
 			packet_check_eom();
 			success = session_setup_x11fwd(s);
 			if (!success) {
-				xfree(s->auth_proto);
-				xfree(s->auth_data);
+				free(s->auth_proto);
+				free(s->auth_data);
 				s->auth_proto = NULL;
 				s->auth_data = NULL;
 			}
@@ -383,13 +370,13 @@
 				debug("Port forwarding not permitted for this authentication.");
 				break;
 			}
-			if (!options.allow_tcp_forwarding) {
+			if (!(options.allow_tcp_forwarding & FORWARD_REMOTE)) {
 				debug("Port forwarding not permitted.");
 				break;
 			}
 			debug("Received TCP/IP port forwarding request.");
 			if (channel_input_port_forward_request(s->pw->pw_uid == 0,
-			    options.gateway_ports) < 0) {
+			    &options.fwd_opts) < 0) {
 				debug("Port forwarding failed.");
 				break;
 			}
@@ -409,7 +396,7 @@
 				if (do_exec(s, command) != 0)
 					packet_disconnect(
 					    "command execution failed");
-				xfree(command);
+				free(command);
 			} else {
 				if (do_exec(s, NULL) != 0)
 					packet_disconnect(
@@ -438,7 +425,7 @@
 	}
 }
 
-#define USE_PIPES
+#define USE_PIPES 1
 /*
  * This is called to fork and execute a command when we have no tty.  This
  * will call do_child from the child, and server_loop from the parent after
@@ -791,27 +778,50 @@
 do_exec(Session *s, const char *command)
 {
 	int ret;
+	const char *forced = NULL;
+	char session_type[1024], *tty = NULL;
 
 	if (options.adm_forced_command) {
 		original_command = command;
 		command = options.adm_forced_command;
-		if (IS_INTERNAL_SFTP(command)) {
-			s->is_subsystem = s->is_subsystem ?
-			    SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
-		} else if (s->is_subsystem)
-			s->is_subsystem = SUBSYSTEM_EXT;
-		debug("Forced command (config) '%.900s'", command);
+		forced = "(config)";
 	} else if (forced_command) {
 		original_command = command;
 		command = forced_command;
+		forced = "(key-option)";
+	}
+	if (forced != NULL) {
 		if (IS_INTERNAL_SFTP(command)) {
 			s->is_subsystem = s->is_subsystem ?
 			    SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR;
 		} else if (s->is_subsystem)
 			s->is_subsystem = SUBSYSTEM_EXT;
-		debug("Forced command (key option) '%.900s'", command);
+		snprintf(session_type, sizeof(session_type),
+		    "forced-command %s '%.900s'", forced, command);
+	} else if (s->is_subsystem) {
+		snprintf(session_type, sizeof(session_type),
+		    "subsystem '%.900s'", s->subsys);
+	} else if (command == NULL) {
+		snprintf(session_type, sizeof(session_type), "shell");
+	} else {
+		/* NB. we don't log unforced commands to preserve privacy */
+		snprintf(session_type, sizeof(session_type), "command");
 	}
 
+	if (s->ttyfd != -1) {
+		tty = s->tty;
+		if (strncmp(tty, "/dev/", 5) == 0)
+			tty += 5;
+	}
+
+	verbose("Starting session: %s%s%s for %s from %.200s port %d",
+	    session_type,
+	    tty == NULL ? "" : " on ",
+	    tty == NULL ? "" : tty,
+	    s->pw->pw_name,
+	    get_remote_ipaddr(),
+	    get_remote_port());
+
 #ifdef SSH_AUDIT_EVENTS
 	if (command != NULL)
 		PRIVSEP(audit_run_command(command));
@@ -952,6 +962,11 @@
 	u_int envsize;
 	u_int i, namelen;
 
+	if (strchr(name, '=') != NULL) {
+		error("Invalid environment variable \"%.100s\"", name);
+		return;
+	}
+
 	/*
 	 * If we're passed an uninitialized list, allocate a single null
 	 * entry before continuing.
@@ -974,7 +989,7 @@
 			break;
 	if (env[i]) {
 		/* Reuse the slot. */
-		xfree(env[i]);
+		free(env[i]);
 	} else {
 		/* New variable.  Expand if necessary. */
 		envsize = *envsizep;
@@ -1090,8 +1105,8 @@
 			umask((mode_t)mask);
 
 	for (i = 0; tmpenv[i] != NULL; i++)
-		xfree(tmpenv[i]);
-	xfree(tmpenv);
+		free(tmpenv[i]);
+	free(tmpenv);
 }
 #endif /* HAVE_ETC_DEFAULT_LOGIN */
 
@@ -1107,7 +1122,7 @@
 	for(i = 0; source[i] != NULL; i++) {
 		var_name = xstrdup(source[i]);
 		if ((var_val = strstr(var_name, "=")) == NULL) {
-			xfree(var_name);
+			free(var_name);
 			continue;
 		}
 		*var_val++ = '\0';
@@ -1115,7 +1130,7 @@
 		debug3("Copy environment: %s=%s", var_name, var_val);
 		child_set_env(env, envsize, var_name, var_val);
 
-		xfree(var_name);
+		free(var_name);
 	}
 }
 
@@ -1218,8 +1233,8 @@
 				child_set_env(&env, &envsize, str, str + i + 1);
 			}
 			custom_environment = ce->next;
-			xfree(ce->s);
-			xfree(ce);
+			free(ce->s);
+			free(ce);
 		}
 	}
 
@@ -1231,7 +1246,7 @@
 	laddr = get_local_ipaddr(packet_get_connection_in());
 	snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
 	    get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());
-	xfree(laddr);
+	free(laddr);
 	child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
 
 	if (s->ttyfd != -1)
@@ -1329,7 +1344,8 @@
 
 	/* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */
 	if (!s->is_subsystem && options.adm_forced_command == NULL &&
-	    !no_user_rc && stat(_PATH_SSH_USER_RC, &st) >= 0) {
+	    !no_user_rc && options.permit_user_rc &&
+	    stat(_PATH_SSH_USER_RC, &st) >= 0) {
 		snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
 		    shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
 		if (debug_flag)
@@ -1392,7 +1408,7 @@
 	struct stat sb;
 
 #ifdef HAVE_LOGIN_CAP
-	if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
+	if (login_getcapbool(lc, "ignorenologin", 0) || pw->pw_uid == 0)
 		return;
 	nl = login_getcapstr(lc, "nologin", def_nl, def_nl);
 #else
@@ -1402,7 +1418,7 @@
 #endif
 	if (stat(nl, &sb) == -1) {
 		if (nl != def_nl)
-			xfree(nl);
+			free(nl);
 		return;
 	}
 
@@ -1424,7 +1440,7 @@
 safely_chroot(const char *path, uid_t uid)
 {
 	const char *cp;
-	char component[MAXPATHLEN];
+	char component[PATH_MAX];
 	struct stat st;
 
 	if (*path != '/')
@@ -1476,6 +1492,9 @@
 do_setusercontext(struct passwd *pw)
 {
 	char *chroot_path, *tmp;
+#ifdef USE_LIBIAF
+	int doing_chroot = 0;
+#endif
 
 	platform_setusercontext(pw);
 
@@ -1498,8 +1517,7 @@
 			perror("initgroups");
 			exit(1);
 		}
-#ifndef ANDROID
-		/* FIXME - Android doesn't have this */
+#if !defined(ANDROID)
 		endgrent();
 #endif
 #endif
@@ -1515,6 +1533,12 @@
 			safely_chroot(chroot_path, pw->pw_uid);
 			free(tmp);
 			free(chroot_path);
+			/* Make sure we don't attempt to chroot again */
+			free(options.chroot_directory);
+			options.chroot_directory = NULL;
+#ifdef USE_LIBIAF
+			doing_chroot = 1;
+#endif
 		}
 
 #ifdef HAVE_LOGIN_CAP
@@ -1522,10 +1546,30 @@
 			perror("unable to set user context (setuser)");
 			exit(1);
 		}
+		/* 
+		 * FreeBSD's setusercontext() will not apply the user's
+		 * own umask setting unless running with the user's UID.
+		 */
+		(void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUMASK);
 #else
+# ifdef USE_LIBIAF
+/* In a chroot environment, the set_id() will always fail; typically 
+ * because of the lack of necessary authentication services and runtime
+ * such as ./usr/lib/libiaf.so, ./usr/lib/libpam.so.1, and ./etc/passwd
+ * We skip it in the internal sftp chroot case.
+ * We'll lose auditing and ACLs but permanently_set_uid will
+ * take care of the rest.
+ */
+	if ((doing_chroot == 0) && set_id(pw->pw_name) != 0) {
+		fatal("set_id(%s) Failed", pw->pw_name);
+	}
+# endif /* USE_LIBIAF */
 		/* Permanently switch to the desired uid. */
 		permanently_set_uid(pw);
 #endif
+	} else if (options.chroot_directory != NULL &&
+	    strcasecmp(options.chroot_directory, "none") != 0) {
+		fatal("server lacks privileges to chroot to ChrootDirectory");
 	}
 
 	if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
@@ -1581,6 +1625,13 @@
 static void
 child_close_fds(void)
 {
+	extern int auth_sock;
+
+	if (auth_sock != -1) {
+		close(auth_sock);
+		auth_sock = -1;
+	}
+
 	if (packet_get_connection_in() == packet_get_connection_out())
 		close(packet_get_connection_in());
 	else {
@@ -1594,7 +1645,7 @@
 	/* XXX better use close-on-exec? -markus */
 	channel_close_all();
 
-#ifndef ANDROID
+#if !defined(ANDROID)
 	/*
 	 * Close any extra file descriptors.  Note that there may still be
 	 * descriptors left by system functions.  They will be closed later.
@@ -1847,7 +1898,7 @@
 		fatal("%s: insane session id %d (max %d nalloc %d)",
 		    __func__, id, options.max_sessions, sessions_nalloc);
 	}
-	bzero(&sessions[id], sizeof(*sessions));
+	memset(&sessions[id], 0, sizeof(*sessions));
 	sessions[id].self = id;
 	sessions[id].used = 0;
 	sessions[id].chanid = -1;
@@ -2025,7 +2076,7 @@
 	u_int len;
 	int n_bytes;
 
-	if (no_pty_flag) {
+	if (no_pty_flag || !options.permit_tty) {
 		debug("Allocating a pty not permitted for this authentication.");
 		return 0;
 	}
@@ -2047,7 +2098,7 @@
 	s->ypixel = packet_get_int();
 
 	if (strcmp(s->term, "") == 0) {
-		xfree(s->term);
+		free(s->term);
 		s->term = NULL;
 	}
 
@@ -2055,8 +2106,7 @@
 	debug("Allocating pty.");
 	if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
 	    sizeof(s->tty)))) {
-		if (s->term)
-			xfree(s->term);
+		free(s->term);
 		s->term = NULL;
 		s->ptyfd = -1;
 		s->ttyfd = -1;
@@ -2087,15 +2137,16 @@
 	struct stat st;
 	u_int len;
 	int success = 0;
-	char *prog, *cmd, *subsys = packet_get_string(&len);
+	char *prog, *cmd;
 	u_int i;
 
+	s->subsys = packet_get_string(&len);
 	packet_check_eom();
-	logit("subsystem request for %.100s by user %s", subsys,
+	debug2("subsystem request for %.100s by user %s", s->subsys,
 	    s->pw->pw_name);
 
 	for (i = 0; i < options.num_subsystems; i++) {
-		if (strcmp(subsys, options.subsystem_name[i]) == 0) {
+		if (strcmp(s->subsys, options.subsystem_name[i]) == 0) {
 			prog = options.subsystem_command[i];
 			cmd = options.subsystem_args[i];
 			if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) {
@@ -2114,10 +2165,9 @@
 	}
 
 	if (!success)
-		logit("subsystem request for %.100s failed, subsystem not found",
-		    subsys);
+		logit("subsystem request for %.100s by user %s failed, "
+		    "subsystem not found", s->subsys, s->pw->pw_name);
 
-	xfree(subsys);
 	return success;
 }
 
@@ -2139,8 +2189,8 @@
 
 	success = session_setup_x11fwd(s);
 	if (!success) {
-		xfree(s->auth_proto);
-		xfree(s->auth_data);
+		free(s->auth_proto);
+		free(s->auth_data);
 		s->auth_proto = NULL;
 		s->auth_data = NULL;
 	}
@@ -2162,7 +2212,7 @@
 	char *command = packet_get_string(&len);
 	packet_check_eom();
 	success = do_exec(s, command) == 0;
-	xfree(command);
+	free(command);
 	return success;
 }
 
@@ -2173,7 +2223,7 @@
 	packet_get_int();	/* ignored */
 	packet_check_eom();
 
-	if (s->ttyfd == -1 || tcsendbreak(s->ttyfd, 0) < 0)
+	if (s->ptymaster == -1 || tcsendbreak(s->ptymaster, 0) < 0)
 		return 0;
 	return 1;
 }
@@ -2184,8 +2234,8 @@
 	char *name, *val;
 	u_int name_len, val_len, i;
 
-	name = packet_get_string(&name_len);
-	val = packet_get_string(&val_len);
+	name = packet_get_cstring(&name_len);
+	val = packet_get_cstring(&val_len);
 	packet_check_eom();
 
 	/* Don't set too many environment variables */
@@ -2208,8 +2258,8 @@
 	debug2("Ignoring env request %s: disallowed name", name);
 
  fail:
-	xfree(name);
-	xfree(val);
+	free(name);
+	free(val);
 	return (0);
 }
 
@@ -2391,24 +2441,16 @@
 		if (s->x11_chanids[i] != id)
 			session_close_x11(s->x11_chanids[i]);
 	}
-	xfree(s->x11_chanids);
+	free(s->x11_chanids);
 	s->x11_chanids = NULL;
-	if (s->display) {
-		xfree(s->display);
-		s->display = NULL;
-	}
-	if (s->auth_proto) {
-		xfree(s->auth_proto);
-		s->auth_proto = NULL;
-	}
-	if (s->auth_data) {
-		xfree(s->auth_data);
-		s->auth_data = NULL;
-	}
-	if (s->auth_display) {
-		xfree(s->auth_display);
-		s->auth_display = NULL;
-	}
+	free(s->display);
+	s->display = NULL;
+	free(s->auth_proto);
+	s->auth_proto = NULL;
+	free(s->auth_data);
+	s->auth_data = NULL;
+	free(s->auth_display);
+	s->auth_display = NULL;
 }
 
 static void
@@ -2470,24 +2512,19 @@
 	debug("session_close: session %d pid %ld", s->self, (long)s->pid);
 	if (s->ttyfd != -1)
 		session_pty_cleanup(s);
-	if (s->term)
-		xfree(s->term);
-	if (s->display)
-		xfree(s->display);
-	if (s->x11_chanids)
-		xfree(s->x11_chanids);
-	if (s->auth_display)
-		xfree(s->auth_display);
-	if (s->auth_data)
-		xfree(s->auth_data);
-	if (s->auth_proto)
-		xfree(s->auth_proto);
+	free(s->term);
+	free(s->display);
+	free(s->x11_chanids);
+	free(s->auth_display);
+	free(s->auth_data);
+	free(s->auth_proto);
+	free(s->subsys);
 	if (s->env != NULL) {
 		for (i = 0; i < s->num_env; i++) {
-			xfree(s->env[i].name);
-			xfree(s->env[i].val);
+			free(s->env[i].name);
+			free(s->env[i].val);
 		}
-		xfree(s->env);
+		free(s->env);
 	}
 	session_proctitle(s);
 	session_unused(s->self);
@@ -2607,7 +2644,7 @@
 {
 	struct stat st;
 	char display[512], auth_display[512];
-	char hostname[MAXHOSTNAMELEN];
+	char hostname[NI_MAXHOST];
 	u_int i;
 
 	if (no_x11_forwarding_flag) {
@@ -2618,7 +2655,7 @@
 		debug("X11 forwarding disabled in server configuration file.");
 		return 0;
 	}
-	if (!options.xauth_location ||
+	if (options.xauth_location == NULL ||
 	    (stat(options.xauth_location, &st) == -1)) {
 		packet_send_debug("No xauth program; cannot forward with spoofing.");
 		return 0;