[Midnightbsd-cvs] src: crypto/openssh: Fix some of the merge conflicts.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Apr 6 00:50:42 EDT 2008


Log Message:
-----------
Fix some of the merge conflicts.

Modified Files:
--------------
    src/crypto/openssh:
        ChangeLog (r1.3 -> r1.4)
        Makefile.in (r1.3 -> r1.4)
        README (r1.3 -> r1.4)
        README.platform (r1.3 -> r1.4)
        auth-options.c (r1.3 -> r1.4)
        auth-options.h (r1.3 -> r1.4)
        auth-pam.c (r1.4 -> r1.5)
        auth-passwd.c (r1.4 -> r1.5)
        auth.c (r1.4 -> r1.5)
        auth.h (r1.4 -> r1.5)
        auth1.c (r1.4 -> r1.5)
        auth2-chall.c (r1.4 -> r1.5)
        auth2-gss.c (r1.3 -> r1.4)
        auth2.c (r1.4 -> r1.5)
        buildpkg.sh.in (r1.4 -> r1.5)
        canohost.c (r1.3 -> r1.4)
        channels.c (r1.4 -> r1.5)
        channels.h (r1.3 -> r1.4)
        cipher-ctr.c (r1.3 -> r1.4)
        clientloop.c (r1.4 -> r1.5)
        configure.ac (r1.4 -> r1.5)
        defines.h (r1.3 -> r1.4)
        entropy.c (r1.4 -> r1.5)
        gss-genr.c (r1.3 -> r1.4)
        gss-serv.c (r1.3 -> r1.4)
        includes.h (r1.4 -> r1.5)
        kex.c (r1.4 -> r1.5)
        kex.h (r1.3 -> r1.4)
        loginrec.c (r1.4 -> r1.5)
        misc.c (r1.4 -> r1.5)
        misc.h (r1.3 -> r1.4)
        monitor.c (r1.4 -> r1.5)
        monitor_wrap.c (r1.4 -> r1.5)
        myproposal.h (r1.4 -> r1.5)
        packet.c (r1.4 -> r1.5)
        readconf.c (r1.4 -> r1.5)
        readconf.h (r1.3 -> r1.4)
        scp.1 (r1.3 -> r1.4)
        scp.c (r1.4 -> r1.5)
        servconf.c (r1.4 -> r1.5)
        servconf.h (r1.4 -> r1.5)
        serverloop.c (r1.4 -> r1.5)
        session.c (r1.4 -> r1.5)
        sftp-client.c (r1.4 -> r1.5)
        sftp-server.c (r1.4 -> r1.5)
        sftp.1 (r1.2 -> r1.3)
        sftp.c (r1.4 -> r1.5)
        ssh-add.c (r1.3 -> r1.4)
        ssh-agent.1 (r1.3 -> r1.4)
        ssh-agent.c (r1.4 -> r1.5)
        ssh-keygen.1 (r1.3 -> r1.4)
        ssh-keygen.c (r1.4 -> r1.5)
        ssh-keyscan.1 (r1.3 -> r1.4)
        ssh-keyscan.c (r1.4 -> r1.5)
        ssh.1 (r1.3 -> r1.4)
        ssh.c (r1.4 -> r1.5)
        ssh_config (r1.5 -> r1.6)
        ssh_config.5 (r1.3 -> r1.4)
        sshconnect.c (r1.4 -> r1.5)
        sshconnect.h (r1.3 -> r1.4)
        sshconnect2.c (r1.3 -> r1.4)
        sshd.8 (r1.3 -> r1.4)
        sshd.c (r1.6 -> r1.7)
        sshd_config (r1.6 -> r1.7)
        sshd_config.5 (r1.3 -> r1.4)
    src/crypto/openssh/openbsd-compat:
        Makefile.in (r1.3 -> r1.4)
        base64.c (r1.2 -> r1.3)
        bindresvport.c (r1.3 -> r1.4)
        bsd-asprintf.c (r1.2 -> r1.3)
        bsd-misc.c (r1.3 -> r1.4)
        fake-rfc2553.h (r1.4 -> r1.5)
        getrrsetbyname.c (r1.4 -> r1.5)
        glob.c (r1.3 -> r1.4)
        glob.h (r1.3 -> r1.4)
        openbsd-compat.h (r1.3 -> r1.4)
        openssl-compat.h (r1.3 -> r1.4)
        port-uw.c (r1.3 -> r1.4)
        sys-queue.h (r1.2 -> r1.3)
        sys-tree.h (r1.2 -> r1.3)
    src/crypto/openssh/regress:
        agent-getpeereid.sh (r1.3 -> r1.4)
        test-exec.sh (r1.2 -> r1.3)
        try-ciphers.sh (r1.2 -> r1.3)

-------------- next part --------------
Index: sshconnect2.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sshconnect2.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/sshconnect2.c -L crypto/openssh/sshconnect2.c -u -r1.3 -r1.4
--- crypto/openssh/sshconnect2.c
+++ crypto/openssh/sshconnect2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect2.c,v 1.162 2006/08/30 00:06:51 dtucker Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.165 2008/01/19 23:09:49 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -31,6 +31,7 @@
 #include <sys/stat.h>
 
 #include <errno.h>
+#include <netdb.h>
 #include <pwd.h>
 #include <signal.h>
 #include <stdarg.h>
@@ -129,7 +130,7 @@
 		    options.hostkeyalgorithms;
 
 	if (options.rekey_limit)
-		packet_set_rekey_limit(options.rekey_limit);
+		packet_set_rekey_limit((u_int32_t)options.rekey_limit);
 
 	/* start key exchange */
 	kex = kex_setup(myproposal);
@@ -1307,7 +1308,7 @@
 	Sensitive *sensitive = authctxt->sensitive;
 	Buffer b;
 	u_char *signature, *blob;
-	char *chost, *pkalg, *p;
+	char *chost, *pkalg, *p, myname[NI_MAXHOST];
 	const char *service;
 	u_int blen, slen;
 	int ok, i, len, found = 0;
@@ -1331,7 +1332,16 @@
 		return 0;
 	}
 	/* figure out a name for the client host */
-	p = get_local_name(packet_get_connection_in());
+	p = NULL;
+	if (packet_connection_is_on_socket())
+		p = get_local_name(packet_get_connection_in());
+	if (p == NULL) {
+		if (gethostname(myname, sizeof(myname)) == -1) {
+			verbose("userauth_hostbased: gethostname: %s", 
+			    strerror(errno));
+		} else
+			p = xstrdup(myname);
+	}
 	if (p == NULL) {
 		error("userauth_hostbased: cannot get local ipaddr/name");
 		key_free(private);
Index: ssh.1
===================================================================
RCS file: /home/cvs/src/crypto/openssh/ssh.1,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/ssh.1 -L crypto/openssh/ssh.1 -u -r1.3 -r1.4
--- crypto/openssh/ssh.1
+++ crypto/openssh/ssh.1
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh.1,v 1.266 2006/12/11 21:25:46 markus Exp $
-.Dd September 25, 1999
+.\" $OpenBSD: ssh.1,v 1.273 2008/02/11 07:58:28 jmc Exp $
+.Dd $Mdocdate: March 26 2008 $
 .Dt SSH 1
 .Os
 .Sh NAME
@@ -43,7 +43,7 @@
 .Nd OpenSSH SSH client (remote login program)
 .Sh SYNOPSIS
 .Nm ssh
-.Op Fl 1246AaCfgkMNnqsTtVvXxY
+.Op Fl 1246AaCfgKkMNnqsTtVvXxY
 .Op Fl b Ar bind_address
 .Op Fl c Ar cipher_spec
 .Oo Fl D\ \&
@@ -315,6 +315,9 @@
 .Fl i
 options (and multiple identities specified in
 configuration files).
+.It Fl K
+Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI
+credentials to the server.
 .It Fl k
 Disables forwarding (delegation) of GSSAPI credentials to the server.
 .It Fl L Xo
@@ -503,7 +506,7 @@
 per-host basis in the configuration file.
 .It Fl q
 Quiet mode.
-Causes all warning and diagnostic messages to be suppressed.
+Causes most warning and diagnostic messages to be suppressed.
 .It Fl R Xo
 .Sm off
 .Oo Ar bind_address : Oc
@@ -674,7 +677,7 @@
 but protocol 2 is preferred since
 it provides additional mechanisms for confidentiality
 (the traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour)
-and integrity (hmac-md5, hmac-sha1, hmac-ripemd160).
+and integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160).
 Protocol 1 lacks a strong mechanism for ensuring the
 integrity of the connection.
 .Pp
@@ -1242,6 +1245,13 @@
 but allows host-based authentication without permitting login with
 rlogin/rsh.
 .Pp
+.It ~/.ssh/
+This directory is the default location for all user-specific configuration
+and authentication information.
+There is no general requirement to keep the entire contents of this directory
+secret, but the recommended permissions are read/write/execute for the user,
+and not accessible by others.
+.Pp
 .It ~/.ssh/authorized_keys
 Lists the public keys (RSA/DSA) that can be used for logging in as this user.
 The format of this file is described in the
Index: sshd.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sshd.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -L crypto/openssh/sshd.c -L crypto/openssh/sshd.c -u -r1.6 -r1.7
--- crypto/openssh/sshd.c
+++ crypto/openssh/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.349 2007/02/21 11:00:05 dtucker Exp $ */
+/* $OpenBSD: sshd.c,v 1.355 2008/02/14 13:10:31 mbalmer Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -75,6 +75,8 @@
 #include <openssl/bn.h>
 #include <openssl/md5.h>
 #include <openssl/rand.h>
+#include "openbsd-compat/openssl-compat.h"
+
 #ifdef HAVE_SECUREWARE
 #include <sys/security.h>
 #include <prot.h>
@@ -120,8 +122,8 @@
 #ifdef LIBWRAP
 #include <tcpd.h>
 #include <syslog.h>
-int allow_severity = LOG_INFO;
-int deny_severity = LOG_WARNING;
+int allow_severity;
+int deny_severity;
 #endif /* LIBWRAP */
 
 #ifndef O_NOCTTY
@@ -583,11 +585,12 @@
 {
 	u_int32_t rnd[256];
 	gid_t gidset[1];
-	int i;
+	u_int i;
 
 	/* Enable challenge-response authentication for privilege separation */
 	privsep_challenge_enable();
 
+	arc4random_stir();
 	for (i = 0; i < 256; i++)
 		rnd[i] = arc4random();
 	RAND_seed(rnd, sizeof(rnd));
@@ -662,6 +665,9 @@
 static void
 privsep_postauth(Authctxt *authctxt)
 {
+	u_int32_t rnd[256];
+	u_int i;
+
 #ifdef DISABLE_FD_PASSING
 	if (1) {
 #else
@@ -693,6 +699,11 @@
 	/* Demote the private keys to public keys. */
 	demote_sensitive_data();
 
+	arc4random_stir();
+	for (i = 0; i < 256; i++)
+		rnd[i] = arc4random();
+	RAND_seed(rnd, sizeof(rnd));
+
 	/* Drop privileges */
 	do_setusercontext(authctxt->pw);
 
@@ -953,8 +964,7 @@
 		    ntop, sizeof(ntop), strport, sizeof(strport),
 		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
 			error("getnameinfo failed: %.100s",
-			    (ret != EAI_SYSTEM) ? gai_strerror(ret) :
-			    strerror(errno));
+			    ssh_gai_strerror(ret));
 			continue;
 		}
 		/* Create socket for listening. */
@@ -977,6 +987,16 @@
 		    &on, sizeof(on)) == -1)
 			error("setsockopt SO_REUSEADDR: %s", strerror(errno));
 
+#ifdef IPV6_V6ONLY
+		/* Only communicate in IPv6 over AF_INET6 sockets. */
+		if (ai->ai_family == AF_INET6) {
+			if (setsockopt(listen_sock, IPPROTO_IPV6, IPV6_V6ONLY,
+			    &on, sizeof(on)) == -1)
+				error("setsockopt IPV6_V6ONLY: %s",
+				    strerror(errno));
+		}
+#endif
+
 		debug("Bind to port %s on %s.", strport, ntop);
 
 		/* Bind the socket to the desired port. */
@@ -1367,7 +1387,7 @@
 	}
 	if (rexeced_flag || inetd_flag)
 		rexec_flag = 0;
-	if (rexec_flag && (av[0] == NULL || *av[0] != '/'))
+	if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
 		fatal("sshd re-exec requires execution with an absolute path");
 	if (rexeced_flag)
 		closefrom(REEXEC_MIN_FREE_FD);
@@ -1421,6 +1441,10 @@
 	/* Fill in default values for those options not explicitly set. */
 	fill_default_server_options(&options);
 
+	/* challenge-response is implemented via keyboard interactive */
+	if (options.challenge_response_authentication)
+		options.kbd_interactive_authentication = 1;
+
 	/* set default channel AF */
 	channel_set_af(options.address_family);
 
@@ -1596,10 +1620,6 @@
 	/* Get a connection, either from inetd or a listening TCP socket */
 	if (inetd_flag) {
 		server_accept_inetd(&sock_in, &sock_out);
-
-		if ((options.protocol & SSH_PROTO_1) &&
-		    sensitive_data.server_key == NULL)
-			generate_ephemeral_server_key();
 	} else {
 		server_listen();
 
@@ -1736,6 +1756,8 @@
 	audit_connection_from(remote_ip, remote_port);
 #endif
 #ifdef LIBWRAP
+	allow_severity = options.log_facility|LOG_INFO;
+	deny_severity = options.log_facility|LOG_WARNING;
 	/* Check whether logins are denied from this host. */
 	if (packet_connection_is_on_socket()) {
 		struct request_info req;
@@ -1769,6 +1791,10 @@
 
 	sshd_exchange_identification(sock_in, sock_out);
 
+	/* In inetd mode, generate ephemeral key only for proto 1 connections */
+	if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
+		generate_ephemeral_server_key();
+
 	packet_set_nonblocking();
 
 	/* allocate authentication context */
@@ -1821,6 +1847,20 @@
 	audit_event(SSH_AUTH_SUCCESS);
 #endif
 
+#ifdef GSSAPI
+	if (options.gss_authentication) {
+		temporarily_use_uid(authctxt->pw);
+		ssh_gssapi_storecreds();
+		restore_uid();
+	}
+#endif
+#ifdef USE_PAM
+	if (options.use_pam) {
+		do_pam_setcred(1);
+		do_pam_session();
+	}
+#endif
+
 	/*
 	 * In privilege separation, we fork another child and prepare
 	 * file descriptor passing.
Index: auth1.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/auth1.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/auth1.c -L crypto/openssh/auth1.c -u -r1.4 -r1.5
--- crypto/openssh/auth1.c
+++ crypto/openssh/auth1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth1.c,v 1.70 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: auth1.c,v 1.71 2007/09/21 08:15:29 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
Index: auth.h
===================================================================
RCS file: /home/cvs/src/crypto/openssh/auth.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/auth.h -L crypto/openssh/auth.h -u -r1.4 -r1.5
--- crypto/openssh/auth.h
+++ crypto/openssh/auth.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.58 2006/08/18 09:15:20 markus Exp $ */
+/* $OpenBSD: auth.h,v 1.60 2007/09/21 08:15:29 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
Index: ssh-keyscan.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/ssh-keyscan.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/ssh-keyscan.c -L crypto/openssh/ssh-keyscan.c -u -r1.4 -r1.5
--- crypto/openssh/ssh-keyscan.c
+++ crypto/openssh/ssh-keyscan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-keyscan.c,v 1.74 2006/10/06 02:29:19 djm Exp $ */
+/* $OpenBSD: ssh-keyscan.c,v 1.75 2007/12/27 14:22:08 dtucker Exp $ */
 /*
  * Copyright 1995, 1996 by David Mazieres <dm at lcs.mit.edu>.
  *
@@ -410,7 +410,7 @@
 	hints.ai_family = IPv4or6;
 	hints.ai_socktype = SOCK_STREAM;
 	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
-		fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr));
+		fatal("getaddrinfo %s: %s", host, ssh_gai_strerror(gaierr));
 	for (ai = aitop; ai; ai = ai->ai_next) {
 		s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 		if (s < 0) {
Index: ssh.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/ssh.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/ssh.c -L crypto/openssh/ssh.c -u -r1.4 -r1.5
--- crypto/openssh/ssh.c
+++ crypto/openssh/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.295 2007/01/03 03:01:40 stevesk Exp $ */
+/* $OpenBSD: ssh.c,v 1.309 2008/01/19 20:51:26 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -72,6 +72,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/err.h>
+#include "openbsd-compat/openssl-compat.h"
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -185,7 +186,7 @@
 usage(void)
 {
 	fprintf(stderr,
-"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
+"usage: ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
 "           [-D [bind_address:]port] [-e escape_char] [-F configfile]\n"
 "           [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
 "           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
@@ -210,7 +211,7 @@
 	char *p, *cp, *line, buf[256];
 	struct stat st;
 	struct passwd *pw;
-	int dummy;
+	int dummy, timeout_ms;
 	extern int optind, optreset;
 	extern char *optarg;
 	struct servent *sp;
@@ -272,7 +273,7 @@
 
  again:
 	while ((opt = getopt(ac, av,
-	    "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
+	    "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) {
 		switch (opt) {
 		case '1':
 			options.protocol = SSH_PROTO_1;
@@ -326,6 +327,10 @@
 		case 'k':
 			options.gss_deleg_creds = 0;
 			break;
+		case 'K':
+			options.gss_authentication = 1;
+			options.gss_deleg_creds = 1;
+			break;
 		case 'i':
 			if (stat(optarg, &st) < 0) {
 				fprintf(stderr, "Warning: Identity file %s "
@@ -654,11 +659,15 @@
 	}
 
 	if (options.proxy_command != NULL &&
-	    strcmp(options.proxy_command, "none") == 0)
+	    strcmp(options.proxy_command, "none") == 0) {
+		xfree(options.proxy_command);
 		options.proxy_command = NULL;
+	}
 	if (options.control_path != NULL &&
-	    strcmp(options.control_path, "none") == 0)
+	    strcmp(options.control_path, "none") == 0) {
+		xfree(options.control_path);
 		options.control_path = NULL;
+	}
 
 	if (options.control_path != NULL) {
 		char thishost[NI_MAXHOST];
@@ -668,6 +677,7 @@
 		snprintf(buf, sizeof(buf), "%d", options.port);
 		cp = tilde_expand_filename(options.control_path,
 		    original_real_uid);
+		xfree(options.control_path);
 		options.control_path = percent_expand(cp, "p", buf, "h", host,
 		    "r", options.user, "l", thishost, (char *)NULL);
 		xfree(cp);
@@ -677,9 +687,12 @@
 	if (options.control_path != NULL)
 		control_client(options.control_path);
 
+	timeout_ms = options.connection_timeout * 1000;
+
 	/* Open a connection to the remote host. */
 	if (ssh_connect(host, &hostaddr, options.port,
-	    options.address_family, options.connection_attempts,
+	    options.address_family, options.connection_attempts, &timeout_ms,
+	    options.tcp_keep_alive, 
 #ifdef HAVE_CYGWIN
 	    options.use_privileged_port,
 #else
@@ -688,6 +701,9 @@
 	    options.proxy_command) != 0)
 		exit(255);
 
+	if (timeout_ms > 0)
+		debug3("timeout: %d ms remain after connect", timeout_ms);
+
 	/*
 	 * If we successfully made the connection, load the host private key
 	 * in case we will need it later for combined rsa-rhosts
@@ -763,7 +779,8 @@
 	signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE early */
 
 	/* Log into the remote system.  This never returns if the login fails. */
-	ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr, pw);
+	ssh_login(&sensitive_data, host, (struct sockaddr *)&hostaddr,
+	    pw, timeout_ms);
 
 	/* We no longer need the private host keys.  Clear them now. */
 	if (sensitive_data.nkeys != 0) {
@@ -853,6 +870,17 @@
 				    "forwarding.");
 		}
 	}
+
+	/* Initiate tunnel forwarding. */
+	if (options.tun_open != SSH_TUNMODE_NO) {
+		if (client_request_tun_fwd(options.tun_open,
+		    options.tun_local, options.tun_remote) == -1) {
+			if (options.exit_on_forward_failure)
+				fatal("Could not request tunnel forwarding.");
+			else
+				error("Could not request tunnel forwarding.");
+		}
+	}			
 }
 
 static void
@@ -975,6 +1003,11 @@
 	/* Initiate port forwardings. */
 	ssh_init_forwarding();
 
+	/* Execute a local command */
+	if (options.local_command != NULL &&
+	    options.permit_local_command)
+		ssh_local_cmd(options.local_command);
+
 	/* If requested, let ssh continue in the background. */
 	if (fork_after_authentication_flag)
 		if (daemon(1, 1) < 0)
@@ -1115,33 +1148,6 @@
 		packet_send();
 	}
 
-	if (options.tun_open != SSH_TUNMODE_NO) {
-		Channel *c;
-		int fd;
-
-		debug("Requesting tun.");
-		if ((fd = tun_open(options.tun_local,
-		    options.tun_open)) >= 0) {
-			c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
-			    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
-			    0, "tun", 1);
-			c->datagram = 1;
-#if defined(SSH_TUN_FILTER)
-			if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
-				channel_register_filter(c->self, sys_tun_infilter,
-				    sys_tun_outfilter);
-#endif
-			packet_start(SSH2_MSG_CHANNEL_OPEN);
-			packet_put_cstring("tun at openssh.com");
-			packet_put_int(c->self);
-			packet_put_int(c->local_window_max);
-			packet_put_int(c->local_maxpacket);
-			packet_put_int(options.tun_open);
-			packet_put_int(options.tun_remote);
-			packet_send();
-		}
-	}
-
 	client_session2_setup(id, tty_flag, subsystem_flag, getenv("TERM"),
 	    NULL, fileno(stdin), &command, environ, &ssh_subsystem_reply);
 
@@ -1201,7 +1207,6 @@
 
 	/* XXX should be pre-session */
 	ssh_init_forwarding();
-	ssh_control_listener();
 
 	if (!no_shell_flag || (datafellows & SSH_BUG_DUMMYCHAN))
 		id = ssh_session2_open();
@@ -1211,6 +1216,9 @@
 	    options.permit_local_command)
 		ssh_local_cmd(options.local_command);
 
+	/* Start listening for multiplex clients */
+	ssh_control_listener();
+
 	/* If requested, let ssh continue in the background. */
 	if (fork_after_authentication_flag)
 		if (daemon(1, 1) < 0)
@@ -1224,6 +1232,7 @@
 load_public_identity_files(void)
 {
 	char *filename, *cp, thishost[NI_MAXHOST];
+	char *pwdir = NULL, *pwname = NULL;
 	int i = 0;
 	Key *public;
 	struct passwd *pw;
@@ -1252,14 +1261,16 @@
 #endif /* SMARTCARD */
 	if ((pw = getpwuid(original_real_uid)) == NULL)
 		fatal("load_public_identity_files: getpwuid failed");
+	pwname = xstrdup(pw->pw_name);
+	pwdir = xstrdup(pw->pw_dir);
 	if (gethostname(thishost, sizeof(thishost)) == -1)
 		fatal("load_public_identity_files: gethostname: %s",
 		    strerror(errno));
 	for (; i < options.num_identity_files; i++) {
 		cp = tilde_expand_filename(options.identity_files[i],
 		    original_real_uid);
-		filename = percent_expand(cp, "d", pw->pw_dir,
-		    "u", pw->pw_name, "l", thishost, "h", host,
+		filename = percent_expand(cp, "d", pwdir,
+		    "u", pwname, "l", thishost, "h", host,
 		    "r", options.user, (char *)NULL);
 		xfree(cp);
 		public = key_load_public(filename, NULL);
@@ -1269,6 +1280,10 @@
 		options.identity_files[i] = filename;
 		options.identity_keys[i] = public;
 	}
+	bzero(pwname, strlen(pwname));
+	xfree(pwname);
+	bzero(pwdir, strlen(pwdir));
+	xfree(pwdir);
 }
 
 static void
@@ -1280,8 +1295,12 @@
 static void
 control_client_sigrelay(int signo)
 {
+	int save_errno = errno;
+
 	if (control_server_pid > 1)
 		kill(control_server_pid, signo);
+
+	errno = save_errno;
 }
 
 static int
@@ -1307,7 +1326,7 @@
 control_client(const char *path)
 {
 	struct sockaddr_un addr;
-	int i, r, fd, sock, exitval, num_env, addr_len;
+	int i, r, fd, sock, exitval[2], num_env, addr_len;
 	Buffer m;
 	char *term;
 	extern char **environ;
@@ -1375,6 +1394,8 @@
 	if (options.forward_agent)
 		flags |= SSHMUX_FLAG_AGENT_FWD;
 
+	signal(SIGPIPE, SIG_IGN);
+
 	buffer_init(&m);
 
 	/* Send our command to server */
@@ -1436,9 +1457,10 @@
 	if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
 		fatal("%s: msg_send", __func__);
 
-	mm_send_fd(sock, STDIN_FILENO);
-	mm_send_fd(sock, STDOUT_FILENO);
-	mm_send_fd(sock, STDERR_FILENO);
+	if (mm_send_fd(sock, STDIN_FILENO) == -1 ||
+	    mm_send_fd(sock, STDOUT_FILENO) == -1 ||
+	    mm_send_fd(sock, STDERR_FILENO) == -1)
+		fatal("%s: send fds failed", __func__);
 
 	/* Wait for reply, so master has a chance to gather ttymodes */
 	buffer_clear(&m);
@@ -1456,29 +1478,44 @@
 	if (tty_flag)
 		enter_raw_mode();
 
-	/* Stick around until the controlee closes the client_fd */
-	exitval = 0;
-	for (;!control_client_terminate;) {
-		r = read(sock, &exitval, sizeof(exitval));
+	/*
+	 * Stick around until the controlee closes the client_fd.
+	 * Before it does, it is expected to write this process' exit
+	 * value (one int). This process must read the value and wait for
+	 * the closure of the client_fd; if this one closes early, the 
+	 * multiplex master will terminate early too (possibly losing data).
+	 */
+	exitval[0] = 0;
+	for (i = 0; !control_client_terminate && i < (int)sizeof(exitval);) {
+		r = read(sock, (char *)exitval + i, sizeof(exitval) - i);
 		if (r == 0) {
 			debug2("Received EOF from master");
 			break;
 		}
-		if (r > 0)
-			debug2("Received exit status from master %d", exitval);
-		if (r == -1 && errno != EINTR)
+		if (r == -1) {
+			if (errno == EINTR)
+				continue;
 			fatal("%s: read %s", __func__, strerror(errno));
+		}
+		i += r;
 	}
 
-	if (control_client_terminate)
-		debug2("Exiting on signal %d", control_client_terminate);
-
 	close(sock);
-
 	leave_raw_mode();
+	if (i > (int)sizeof(int))
+		fatal("%s: master returned too much data (%d > %lu)",
+		    __func__, i, sizeof(int));
+	if (control_client_terminate) {
+		debug2("Exiting on signal %d", control_client_terminate);
+		exitval[0] = 255;
+	} else if (i < (int)sizeof(int)) {
+		debug2("Control master terminated unexpectedly");
+		exitval[0] = 255;
+	} else
+		debug2("Received exit status from master %d", exitval[0]);
 
 	if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
-		fprintf(stderr, "Connection to master closed.\r\n");
+		fprintf(stderr, "Shared connection to %s closed.\r\n", host);
 
-	exit(exitval);
+	exit(exitval[0]);
 }
Index: readconf.h
===================================================================
RCS file: /home/cvs/src/crypto/openssh/readconf.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/readconf.h -L crypto/openssh/readconf.h -u -r1.3 -r1.4
--- crypto/openssh/readconf.h
+++ crypto/openssh/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.71 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: readconf.h,v 1.72 2008/01/19 23:09:49 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -100,7 +100,7 @@
 	int	clear_forwardings;
 
 	int	enable_ssh_keysign;
-	int	rekey_limit;
+	int64_t rekey_limit;
 	int	no_host_authentication_for_localhost;
 	int	identities_only;
 	int	server_alive_interval;
Index: ssh-keygen.1
===================================================================
RCS file: /home/cvs/src/crypto/openssh/ssh-keygen.1,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/ssh-keygen.1 -L crypto/openssh/ssh-keygen.1 -u -r1.3 -r1.4
--- crypto/openssh/ssh-keygen.1
+++ crypto/openssh/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\"	$OpenBSD: ssh-keygen.1,v 1.74 2007/01/12 20:20:41 jmc Exp $
+.\"	$OpenBSD: ssh-keygen.1,v 1.75 2007/05/31 19:20:16 jmc Exp $
 .\"
 .\"  -*- nroff -*-
 .\"
@@ -37,7 +37,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd September 25, 1999
+.Dd $Mdocdate: June 5 2007 $
 .Dt SSH-KEYGEN 1
 .Os
 .Sh NAME
Index: auth.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/auth.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/auth.c -L crypto/openssh/auth.c -u -r1.4 -r1.5
--- crypto/openssh/auth.c
+++ crypto/openssh/auth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.75 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: auth.c,v 1.78 2007/09/21 08:15:29 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -115,11 +115,11 @@
 	/* grab passwd field for locked account check */
 #ifdef USE_SHADOW
 	if (spw != NULL)
-#if defined(HAVE_LIBIAF)  &&  !defined(BROKEN_LIBIAF)
+#ifdef USE_LIBIAF
 		passwd = get_iaf_password(pw);
 #else
 		passwd = spw->sp_pwdp;
-#endif /* HAVE_LIBIAF  && !BROKEN_LIBIAF */
+#endif /* USE_LIBIAF */
 #else
 	passwd = pw->pw_passwd;
 #endif
@@ -141,9 +141,9 @@
 		if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
 			locked = 1;
 #endif
-#if defined(HAVE_LIBIAF)  &&  !defined(BROKEN_LIBIAF)
+#ifdef USE_LIBIAF
 		free(passwd);
-#endif /* HAVE_LIBIAF  && !BROKEN_LIBIAF */
+#endif /* USE_LIBIAF */
 		if (locked) {
 			logit("User %.100s not allowed because account is locked",
 			    pw->pw_name);
Index: ssh-agent.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/ssh-agent.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/ssh-agent.c -L crypto/openssh/ssh-agent.c -u -r1.4 -r1.5
--- crypto/openssh/ssh-agent.c
+++ crypto/openssh/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.154 2007/02/28 00:55:30 dtucker Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.157 2007/09/25 23:48:57 canacar Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -51,6 +51,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/md5.h>
+#include "openbsd-compat/openssl-compat.h"
 
 #include <errno.h>
 #include <fcntl.h>
@@ -120,6 +121,7 @@
 
 /* pid of shell == parent of agent */
 pid_t parent_pid = -1;
+u_int parent_alive_interval = 0;
 
 /* pathname and directory for AUTH_SOCKET */
 char socket_name[MAXPATHLEN];
@@ -421,10 +423,11 @@
 	buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
 }
 
-static void
+/* removes expired keys and returns number of seconds until the next expiry */
+static u_int
 reaper(void)
 {
-	u_int now = time(NULL);
+	u_int deadline = 0, now = time(NULL);
 	Identity *id, *nxt;
 	int version;
 	Idtab *tab;
@@ -433,20 +436,29 @@
 		tab = idtab_lookup(version);
 		for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) {
 			nxt = TAILQ_NEXT(id, next);
-			if (id->death != 0 && now >= id->death) {
+			if (id->death == 0)
+				continue;
+			if (now >= id->death) {
 				debug("expiring key '%s'", id->comment);
 				TAILQ_REMOVE(&tab->idlist, id, next);
 				free_identity(id);
 				tab->nentries--;
-			}
+			} else
+				deadline = (deadline == 0) ? id->death :
+				    MIN(deadline, id->death);
 		}
 	}
+	if (deadline == 0 || deadline <= now)
+		return 0;
+	else
+		return (deadline - now);
 }
 
 static void
 process_add_identity(SocketEntry *e, int version)
 {
 	Idtab *tab = idtab_lookup(version);
+	Identity *id;
 	int type, success = 0, death = 0, confirm = 0;
 	char *type_name, *comment;
 	Key *k = NULL;
@@ -529,19 +541,19 @@
 	}
 	if (lifetime && !death)
 		death = time(NULL) + lifetime;
-	if (lookup_identity(k, version) == NULL) {
-		Identity *id = xmalloc(sizeof(Identity));
+	if ((id = lookup_identity(k, version)) == NULL) {
+		id = xmalloc(sizeof(Identity));
 		id->key = k;
-		id->comment = comment;
-		id->death = death;
-		id->confirm = confirm;
 		TAILQ_INSERT_TAIL(&tab->idlist, id, next);
 		/* Increment the number of identities. */
 		tab->nentries++;
 	} else {
 		key_free(k);
-		xfree(comment);
+		xfree(id->comment);
 	}
+	id->comment = comment;
+	id->death = death;
+	id->confirm = confirm;
 send:
 	buffer_put_int(&e->output, 1);
 	buffer_put_char(&e->output,
@@ -826,10 +838,12 @@
 }
 
 static int
-prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp)
+prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
+    struct timeval **tvpp)
 {
-	u_int i, sz;
+	u_int i, sz, deadline;
 	int n = 0;
+	static struct timeval tv;
 
 	for (i = 0; i < sockets_alloc; i++) {
 		switch (sockets[i].type) {
@@ -873,6 +887,17 @@
 			break;
 		}
 	}
+	deadline = reaper();
+	if (parent_alive_interval != 0)
+		deadline = (deadline == 0) ? parent_alive_interval :
+		    MIN(deadline, parent_alive_interval);
+	if (deadline == 0) {
+		*tvpp = NULL;
+	} else {
+		tv.tv_sec = deadline;
+		tv.tv_usec = 0;
+		*tvpp = &tv;
+	}
 	return (1);
 }
 
@@ -980,25 +1005,20 @@
 	_exit(2);
 }
 
-/*ARGSUSED*/
 static void
-check_parent_exists(int sig)
+check_parent_exists(void)
 {
-	int save_errno = errno;
-
 	if (parent_pid != -1 && kill(parent_pid, 0) < 0) {
 		/* printf("Parent has died - Authentication agent exiting.\n"); */
-		cleanup_handler(sig); /* safe */
+		cleanup_socket();
+		_exit(2);
 	}
-	mysignal(SIGALRM, check_parent_exists);
-	alarm(10);
-	errno = save_errno;
 }
 
 static void
 usage(void)
 {
-	fprintf(stderr, "Usage: %s [options] [command [args ...]]\n",
+	fprintf(stderr, "usage: %s [options] [command [arg ...]]\n",
 	    __progname);
 	fprintf(stderr, "Options:\n");
 	fprintf(stderr, "  -c          Generate C-shell commands on stdout.\n");
@@ -1027,7 +1047,7 @@
 	extern char *optarg;
 	pid_t pid;
 	char pidstrbuf[1 + 3 * sizeof pid];
-	struct timeval tv;
+	struct timeval *tvp = NULL;
 
 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
 	sanitise_stdfd();
@@ -1228,10 +1248,8 @@
 
 skip:
 	new_socket(AUTH_SOCKET, sock);
-	if (ac > 0) {
-		mysignal(SIGALRM, check_parent_exists);
-		alarm(10);
-	}
+	if (ac > 0)
+		parent_alive_interval = 10;
 	idtab_init();
 	if (!d_flag)
 		signal(SIGINT, SIG_IGN);
@@ -1241,12 +1259,12 @@
 	nalloc = 0;
 
 	while (1) {
-		tv.tv_sec = 10;
-		tv.tv_usec = 0;
-		prepare_select(&readsetp, &writesetp, &max_fd, &nalloc);
-		result = select(max_fd + 1, readsetp, writesetp, NULL, &tv);
+		prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp);
+		result = select(max_fd + 1, readsetp, writesetp, NULL, tvp);
 		saved_errno = errno;
-		reaper();	/* remove expired keys */
+		if (parent_alive_interval != 0)
+			check_parent_exists();
+		(void) reaper();	/* remove expired keys */
 		if (result < 0) {
 			if (saved_errno == EINTR)
 				continue;
Index: servconf.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/servconf.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/servconf.c -L crypto/openssh/servconf.c -u -r1.4 -r1.5
--- crypto/openssh/servconf.c
+++ crypto/openssh/servconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.170 2007/03/01 10:28:02 dtucker Exp $ */
+/* $OpenBSD: servconf.c,v 1.177 2008/02/10 10:54:28 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -122,6 +122,7 @@
 	options->permit_tun = -1;
 	options->num_permitted_opens = -1;
 	options->adm_forced_command = NULL;
+	options->chroot_directory = NULL;
 }
 
 void
@@ -291,7 +292,7 @@
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
-	sMatch, sPermitOpen, sForceCommand,
+	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
 	sUsePrivilegeSeparation,
 	sDeprecated, sUnsupported
 } ServerOpCodes;
@@ -321,7 +322,7 @@
 	{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
 	{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
 	{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
-	{ "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
+	{ "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
 	{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
 	{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
 	{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
@@ -403,6 +404,7 @@
  	{ "match", sMatch, SSHCFG_ALL },
 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
+	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
 	{ NULL, sBadOption, 0 }
 };
 
@@ -458,7 +460,7 @@
 	if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
 		fatal("bad addr or host: %s (%s)",
 		    addr ? addr : "<NULL>",
-		    gai_strerror(gaierr));
+		    ssh_gai_strerror(gaierr));
 	for (ai = aitop; ai->ai_next; ai = ai->ai_next)
 		;
 	ai->ai_next = options->listen_addrs;
@@ -592,7 +594,6 @@
 				debug("connection from %.100s matched 'Host "
 				    "%.100s' at line %d", host, arg, line);
 		} else if (strcasecmp(attrib, "address") == 0) {
-			debug("address '%s' arg '%s'", address, arg);
 			if (!address) {
 				result = 0;
 				continue;
@@ -622,6 +623,8 @@
 {
 	char *cp, **charptr, *arg, *p;
 	int cmdline = 0, *intptr, value, n;
+	SyslogFacility *log_facility_ptr;
+	LogLevel *log_level_ptr;
 	ServerOpCodes opcode;
 	u_short port;
 	u_int i, flags = 0;
@@ -805,7 +808,7 @@
 			fatal("%s line %d: Bad yes/"
 			    "without-password/forced-commands-only/no "
 			    "argument: %s", filename, linenum, arg);
-		if (*intptr == -1)
+		if (*activep && *intptr == -1)
 			*intptr = value;
 		break;
 
@@ -977,25 +980,25 @@
 		goto parse_flag;
 
 	case sLogFacility:
-		intptr = (int *) &options->log_facility;
+		log_facility_ptr = &options->log_facility;
 		arg = strdelim(&cp);
 		value = log_facility_number(arg);
 		if (value == SYSLOG_FACILITY_NOT_SET)
 			fatal("%.200s line %d: unsupported log facility '%s'",
 			    filename, linenum, arg ? arg : "<NONE>");
-		if (*intptr == -1)
-			*intptr = (SyslogFacility) value;
+		if (*log_facility_ptr == -1)
+			*log_facility_ptr = (SyslogFacility) value;
 		break;
 
 	case sLogLevel:
-		intptr = (int *) &options->log_level;
+		log_level_ptr = &options->log_level;
 		arg = strdelim(&cp);
 		value = log_level_number(arg);
 		if (value == SYSLOG_LEVEL_NOT_SET)
 			fatal("%.200s line %d: unsupported log level '%s'",
 			    filename, linenum, arg ? arg : "<NONE>");
-		if (*intptr == -1)
-			*intptr = (LogLevel) value;
+		if (*log_level_ptr == -1)
+			*log_level_ptr = (LogLevel) value;
 		break;
 
 	case sAllowTcpForwarding:
@@ -1146,6 +1149,7 @@
 	case sBanner:
 		charptr = &options->banner;
 		goto parse_filename;
+
 	/*
 	 * These options can contain %X options expanded at
 	 * connect time, so that you can specify paths like:
@@ -1254,6 +1258,17 @@
 			options->adm_forced_command = xstrdup(cp + len);
 		return 0;
 
+	case sChrootDirectory:
+		charptr = &options->chroot_directory;
+
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: missing file name.",
+			    filename, linenum);
+		if (*activep && *charptr == NULL)
+			*charptr = xstrdup(arg);
+		break;
+
 	case sDeprecated:
 		logit("%s line %d: Deprecated option %s",
 		    filename, linenum, arg);
@@ -1350,6 +1365,7 @@
 	M_CP_INTOPT(kerberos_authentication);
 	M_CP_INTOPT(hostbased_authentication);
 	M_CP_INTOPT(kbd_interactive_authentication);
+	M_CP_INTOPT(permit_root_login);
 
 	M_CP_INTOPT(allow_tcp_forwarding);
 	M_CP_INTOPT(gateway_ports);
@@ -1361,6 +1377,7 @@
 	if (preauth)
 		return;
 	M_CP_STROPT(adm_forced_command);
+	M_CP_STROPT(chroot_directory);
 }
 
 #undef M_CP_INTOPT
@@ -1387,8 +1404,4 @@
 	if (bad_options > 0)
 		fatal("%s: terminating, %d bad configuration options",
 		    filename, bad_options);
-
-	/* challenge-response is implemented via keyboard interactive */
-	if (options->challenge_response_authentication == 1)
-		options->kbd_interactive_authentication = 1;
 }
Index: myproposal.h
===================================================================
RCS file: /home/cvs/src/crypto/openssh/myproposal.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/myproposal.h -L crypto/openssh/myproposal.h -u -r1.4 -r1.5
--- crypto/openssh/myproposal.h
+++ crypto/openssh/myproposal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.21 2006/03/25 22:22:43 djm Exp $ */
+/* $OpenBSD: myproposal.h,v 1.22 2007/06/07 19:37:34 pvalchev Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -47,7 +47,7 @@
 	"aes192-cbc,aes256-cbc,rijndael-cbc at lysator.liu.se," \
 	"aes128-ctr,aes192-ctr,aes256-ctr"
 #define	KEX_DEFAULT_MAC \
-	"hmac-md5,hmac-sha1,hmac-ripemd160," \
+	"hmac-md5,hmac-sha1,umac-64 at openssh.com,hmac-ripemd160," \
 	"hmac-ripemd160 at openssh.com," \
 	"hmac-sha1-96,hmac-md5-96"
 #define	KEX_DEFAULT_COMP	"none,zlib at openssh.com,zlib"
Index: README.platform
===================================================================
RCS file: /home/cvs/src/crypto/openssh/README.platform,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/README.platform -L crypto/openssh/README.platform -u -r1.3 -r1.4
--- crypto/openssh/README.platform
+++ crypto/openssh/README.platform
@@ -23,6 +23,20 @@
 IPv6 known to work: 5.1ML7 5.2ML2 5.2ML5
 IPv6 known broken: 4.3.3ML11 5.1ML4
 
+If you wish to use dynamic libraries that aren't in the normal system
+locations (eg IBM's OpenSSL and zlib packages) then you will need to
+define the environment variable blibpath before running configure, eg
+
+blibpath=/lib:/usr/lib:/opt/freeware/lib ./configure \
+  --with-ssl-dir=/opt/freeware --with-zlib=/opt/freeware
+
+If sshd is built with the WITH_AIXAUTHENTICATE option (which is enabled
+by default) then sshd checks that users are permitted via the
+loginrestrictions() function, in particular that the user has the
+"rlogin" attribute set.  This check is not done for the root account,
+instead the PermitRootLogin setting in sshd_config is used.
+
+
 Cygwin
 ------
 To build on Cygwin, OpenSSH requires the following packages:
@@ -67,4 +81,4 @@
 return the output from pam_nologin to the client.
 
 
-$Id: README.platform,v 1.7 2006/06/23 11:05:13 dtucker Exp $
+$Id: README.platform,v 1.9 2007/08/09 04:31:53 dtucker Exp $
Index: sftp.1
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sftp.1,v
retrieving revision 1.2
retrieving revision 1.3
diff -L crypto/openssh/sftp.1 -L crypto/openssh/sftp.1 -u -r1.2 -r1.3
--- crypto/openssh/sftp.1
+++ crypto/openssh/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.63 2006/01/20 00:14:55 dtucker Exp $
+.\" $OpenBSD: sftp.1,v 1.64 2007/05/31 19:20:16 jmc Exp $
 .\"
 .\" Copyright (c) 2001 Damien Miller.  All rights reserved.
 .\"
@@ -22,7 +22,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 4, 2001
+.Dd $Mdocdate: June 5 2007 $
 .Dt SFTP 1
 .Os
 .Sh NAME
Index: entropy.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/entropy.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/entropy.c -L crypto/openssh/entropy.c -u -r1.4 -r1.5
--- crypto/openssh/entropy.c
+++ crypto/openssh/entropy.c
@@ -35,8 +35,9 @@
 # include <fcntl.h>
 #endif
 #include <stdarg.h>
-#include <unistd.h>
+#include <string.h>
 #include <signal.h>
+#include <unistd.h>
 
 #include <openssl/rand.h>
 #include <openssl/crypto.h>
Index: loginrec.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/loginrec.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/loginrec.c -L crypto/openssh/loginrec.c -u -r1.4 -r1.5
--- crypto/openssh/loginrec.c
+++ crypto/openssh/loginrec.c
@@ -161,6 +161,7 @@
 #include <pwd.h>
 #include <stdarg.h>
 #include <string.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "xmalloc.h"
Index: misc.h
===================================================================
RCS file: /home/cvs/src/crypto/openssh/misc.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/misc.h -L crypto/openssh/misc.h -u -r1.3 -r1.4
--- crypto/openssh/misc.h
+++ crypto/openssh/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.36 2006/08/18 10:27:16 djm Exp $ */
+/* $OpenBSD: misc.h,v 1.37 2007/12/27 14:22:08 dtucker Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -35,6 +35,7 @@
 void	 sanitise_stdfd(void);
 
 struct passwd *pwcopy(struct passwd *);
+const char *ssh_gai_strerror(int);
 
 typedef struct arglist arglist;
 struct arglist {
Index: channels.h
===================================================================
RCS file: /home/cvs/src/crypto/openssh/channels.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/channels.h -L crypto/openssh/channels.h -u -r1.3 -r1.4
--- crypto/openssh/channels.h
+++ crypto/openssh/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.88 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: channels.h,v 1.89 2007/06/11 09:14:00 markus Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -122,9 +122,9 @@
 
 /* default window/packet sizes for tcp/x11-fwd-channel */
 #define CHAN_SES_PACKET_DEFAULT	(32*1024)
-#define CHAN_SES_WINDOW_DEFAULT	(4*CHAN_SES_PACKET_DEFAULT)
+#define CHAN_SES_WINDOW_DEFAULT	(64*CHAN_SES_PACKET_DEFAULT)
 #define CHAN_TCP_PACKET_DEFAULT	(32*1024)
-#define CHAN_TCP_WINDOW_DEFAULT	(4*CHAN_TCP_PACKET_DEFAULT)
+#define CHAN_TCP_WINDOW_DEFAULT	(64*CHAN_TCP_PACKET_DEFAULT)
 #define CHAN_X11_PACKET_DEFAULT	(16*1024)
 #define CHAN_X11_WINDOW_DEFAULT	(4*CHAN_X11_PACKET_DEFAULT)
 
Index: sshd_config.5
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sshd_config.5,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/sshd_config.5 -L crypto/openssh/sshd_config.5 -u -r1.3 -r1.4
--- crypto/openssh/sshd_config.5
+++ crypto/openssh/sshd_config.5
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd_config.5,v 1.74 2007/03/01 16:19:33 jmc Exp $
-.Dd September 25, 1999
+.\" $OpenBSD: sshd_config.5,v 1.84 2008/03/25 11:58:02 djm Exp $
+.Dd $Mdocdate: March 27 2008 $
 .Dt SSHD_CONFIG 5
 .Os
 .Sh NAME
@@ -159,10 +159,11 @@
 The default is
 .Dq .ssh/authorized_keys .
 .It Cm Banner
-In some jurisdictions, sending a warning message before authentication
-may be relevant for getting legal protection.
 The contents of the specified file are sent to the remote user before
 authentication is allowed.
+If the argument is
+.Dq none
+then no banner is displayed.
 This option is only available for protocol version 2.
 By default, no banner is displayed.
 .It Cm ChallengeResponseAuthentication
@@ -172,6 +173,45 @@
 are supported.
 The default is
 .Dq yes .
+.It Cm ChrootDirectory
+Specifies a path to
+.Xr chroot 2
+to after authentication.
+This path, and all its components, must be root-owned directories that are
+not writable by any other user or group.
+.Pp
+The path may contain the following tokens that are expanded at runtime once
+the connecting user has been authenticated: %% is replaced by a literal '%',
+%h is replaced by the home directory of the user being authenticated, and
+%u is replaced by the username of that user.
+.Pp
+The
+.Cm ChrootDirectory
+must contain the necessary files and directories to support the
+users' session.
+For an interactive session this requires at least a shell, typically
+.Xr sh 1 ,
+and basic
+.Pa /dev
+nodes such as
+.Xr null 4 ,
+.Xr zero 4 ,
+.Xr stdin 4 ,
+.Xr stdout 4 ,
+.Xr stderr 4 ,
+.Xr arandom 4
+and
+.Xr tty 4
+devices.
+For file transfer sessions using
+.Dq sftp ,
+no additional configuration of the environment is necessary if the
+in-process sftp server is used (see
+.Cm Subsystem
+for details).
+.Pp
+The default is not to
+.Xr chroot 2 .
 .It Cm Ciphers
 Specifies the ciphers allowed for protocol version 2.
 Multiple ciphers must be comma-separated.
@@ -284,7 +324,9 @@
 .It Cm ForceCommand
 Forces the execution of the command specified by
 .Cm ForceCommand ,
-ignoring any command supplied by the client.
+ignoring any command supplied by the client and
+.Pa ~/.ssh/rc
+if present.
 The command is invoked by using the user's login shell with the -c option.
 This applies to shell, command, or subsystem execution.
 It is most useful inside a
@@ -293,6 +335,11 @@
 The command originally supplied by the client is available in the
 .Ev SSH_ORIGINAL_COMMAND
 environment variable.
+Specifying a command of
+.Dq internal-sftp
+will force the use of an in-process sftp server that requires no support
+files when used with
+.Cm ChrootDirectory .
 .It Cm GatewayPorts
 Specifies whether remote hosts are allowed to connect to ports
 forwarded for the client.
@@ -489,7 +536,10 @@
 for data integrity protection.
 Multiple algorithms must be comma-separated.
 The default is:
-.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
+.Bd -literal -offset indent
+hmac-md5,hmac-sha1,umac-64 at openssh.com,
+hmac-ripemd160,hmac-sha1-96,hmac-md5-96
+.Ed
 .It Cm Match
 Introduces a conditional block.
 If all of the criteria on the
@@ -520,6 +570,7 @@
 .Cm KerberosAuthentication ,
 .Cm PasswordAuthentication ,
 .Cm PermitOpen ,
+.Cm PermitRootLogin ,
 .Cm RhostsRSAAuthentication ,
 .Cm RSAAuthentication ,
 .Cm X11DisplayOffset ,
@@ -735,11 +786,22 @@
 Configures an external subsystem (e.g. file transfer daemon).
 Arguments should be a subsystem name and a command (with optional arguments)
 to execute upon subsystem request.
+.Pp
 The command
 .Xr sftp-server 8
 implements the
 .Dq sftp
 file transfer subsystem.
+.Pp
+Alternately the name
+.Dq internal-sftp
+implements an in-process
+.Dq sftp
+server.
+This may simplify configurations using
+.Cm ChrootDirectory
+to force a different filesystem root on clients.
+.Pp
 By default no subsystems are defined.
 Note that this option applies to protocol version 2 only.
 .It Cm SyslogFacility
Index: cipher-ctr.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/cipher-ctr.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/cipher-ctr.c -L crypto/openssh/cipher-ctr.c -u -r1.3 -r1.4
--- crypto/openssh/cipher-ctr.c
+++ crypto/openssh/cipher-ctr.c
@@ -29,13 +29,7 @@
 /* compatibility with old or broken OpenSSL versions */
 #include "openbsd-compat/openssl-compat.h"
 
-#ifdef USE_BUILTIN_RIJNDAEL
-#include "rijndael.h"
-#define AES_KEY rijndael_ctx
-#define AES_BLOCK_SIZE 16
-#define AES_encrypt(a, b, c) rijndael_encrypt(c, a, b)
-#define AES_set_encrypt_key(a, b, c) rijndael_set_key(c, (char *)a, b, 1)
-#else
+#ifndef USE_BUILTIN_RIJNDAEL
 #include <openssl/aes.h>
 #endif
 
Index: serverloop.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/serverloop.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/serverloop.c -L crypto/openssh/serverloop.c -u -r1.4 -r1.5
--- crypto/openssh/serverloop.c
+++ crypto/openssh/serverloop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.c,v 1.145 2006/10/11 12:38:03 markus Exp $ */
+/* $OpenBSD: serverloop.c,v 1.148 2008/02/22 20:44:02 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -104,7 +104,6 @@
 static int connection_out;	/* Connection to client (output). */
 static int connection_closed = 0;	/* Connection to client closed. */
 static u_int buffer_high;	/* "Soft" max buffer size. */
-static int client_alive_timeouts = 0;
 
 /*
  * This SIGCHLD kludge is used to detect when the child exits.  The server
@@ -248,7 +247,7 @@
 	int channel_id;
 
 	/* timeout, check to see how many we have had */
-	if (++client_alive_timeouts > options.client_alive_count_max) {
+	if (++keep_alive_timeouts > options.client_alive_count_max) {
 		logit("Timeout, client not responding.");
 		cleanup_exit(255);
 	}
@@ -887,7 +886,7 @@
 	 * even if this was generated by something other than
 	 * the bogus CHANNEL_REQUEST we send for keepalives.
 	 */
-	client_alive_timeouts = 0;
+	keep_alive_timeouts = 0;
 }
 
 static void
Index: ssh_config.5
===================================================================
RCS file: /home/cvs/src/crypto/openssh/ssh_config.5,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/ssh_config.5 -L crypto/openssh/ssh_config.5 -u -r1.3 -r1.4
--- crypto/openssh/ssh_config.5
+++ crypto/openssh/ssh_config.5
@@ -34,8 +34,8 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: ssh_config.5,v 1.98 2007/01/10 13:23:22 jmc Exp $
-.Dd September 25, 1999
+.\" $OpenBSD: ssh_config.5,v 1.105 2007/10/29 07:48:19 jmc Exp $
+.Dd $Mdocdate: December 2 2007 $
 .Dt SSH_CONFIG 5
 .Os
 .Sh NAME
@@ -387,7 +387,7 @@
 Specifies whether
 .Xr ssh 1
 should terminate the connection if it cannot set up all requested
-dynamic, local, and remote port forwardings.
+dynamic, tunnel, local, and remote port forwardings.
 The argument must be
 .Dq yes
 or
@@ -576,6 +576,14 @@
 It is possible to have
 multiple identity files specified in configuration files; all these
 identities will be tried in sequence.
+.It Cm KbdInteractiveAuthentication
+Specifies whether to use keyboard-interactive authentication.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq yes .
 .It Cm KbdInteractiveDevices
 Specifies the list of methods to use in keyboard-interactive authentication.
 Multiple method names must be comma-separated.
@@ -591,7 +599,7 @@
 Specifies a command to execute on the local machine after successfully
 connecting to the server.
 The command string extends to the end of the line, and is executed with
-.Pa /bin/sh .
+the user's shell.
 This directive is ignored unless
 .Cm PermitLocalCommand
 has been enabled.
@@ -641,7 +649,10 @@
 for data integrity protection.
 Multiple algorithms must be comma-separated.
 The default is:
-.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
+.Bd -literal -offset indent
+hmac-md5,hmac-sha1,umac-64 at openssh.com,
+hmac-ripemd160,hmac-sha1-96,hmac-md5-96
+.Ed
 .It Cm NoHostAuthenticationForLocalhost
 This option can be used if the home directory is shared across machines.
 In this case localhost will refer to a different machine on each of
@@ -712,7 +723,7 @@
 Specifies the command to use to connect to the server.
 The command
 string extends to the end of the line, and is executed with
-.Pa /bin/sh .
+the user's shell.
 In the command string,
 .Ql %h
 will be substituted by the host name to
Index: ssh-agent.1
===================================================================
RCS file: /home/cvs/src/crypto/openssh/ssh-agent.1,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/ssh-agent.1 -L crypto/openssh/ssh-agent.1 -u -r1.3 -r1.4
--- crypto/openssh/ssh-agent.1
+++ crypto/openssh/ssh-agent.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.44 2006/07/18 08:03:09 jmc Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.46 2007/09/09 11:38:01 sobrado Exp $
 .\"
 .\" Author: Tatu Ylonen <ylo at cs.hut.fi>
 .\" Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd September 25, 1999
+.Dd $Mdocdate: September 17 2007 $
 .Dt SSH-AGENT 1
 .Os
 .Sh NAME
@@ -42,11 +42,11 @@
 .Nd authentication agent
 .Sh SYNOPSIS
 .Nm ssh-agent
-.Op Fl a Ar bind_address
 .Op Fl c Li | Fl s
-.Op Fl t Ar life
 .Op Fl d
-.Op Ar command Op Ar args ...
+.Op Fl a Ar bind_address
+.Op Fl t Ar life
+.Op Ar command Op Ar arg ...
 .Nm ssh-agent
 .Op Fl c Li | Fl s
 .Fl k
@@ -77,16 +77,21 @@
 This is the default if
 .Ev SHELL
 looks like it's a csh style of shell.
+.It Fl d
+Debug mode.
+When this option is specified
+.Nm
+will not fork.
+.It Fl k
+Kill the current agent (given by the
+.Ev SSH_AGENT_PID
+environment variable).
 .It Fl s
 Generate Bourne shell commands on
 .Dv stdout .
 This is the default if
 .Ev SHELL
 does not look like it's a csh style of shell.
-.It Fl k
-Kill the current agent (given by the
-.Ev SSH_AGENT_PID
-environment variable).
 .It Fl t Ar life
 Set a default value for the maximum lifetime of identities added to the agent.
 The lifetime may be specified in seconds or in a time format specified in
@@ -95,11 +100,6 @@
 .Xr ssh-add 1
 overrides this value.
 Without this option the default maximum lifetime is forever.
-.It Fl d
-Debug mode.
-When this option is specified
-.Nm
-will not fork.
 .El
 .Pp
 If a commandline is given, this is executed as a subprocess of the agent.
Index: auth-options.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/auth-options.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/auth-options.c -L crypto/openssh/auth-options.c -u -r1.3 -r1.4
--- crypto/openssh/auth-options.c
+++ crypto/openssh/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.40 2006/08/03 03:34:41 deraadt Exp $ */
+/* $OpenBSD: auth-options.c,v 1.41 2008/03/26 21:28:14 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -42,6 +42,7 @@
 int no_agent_forwarding_flag = 0;
 int no_x11_forwarding_flag = 0;
 int no_pty_flag = 0;
+int no_user_rc = 0;
 
 /* "command=" option. */
 char *forced_command = NULL;
@@ -61,6 +62,7 @@
 	no_port_forwarding_flag = 0;
 	no_pty_flag = 0;
 	no_x11_forwarding_flag = 0;
+	no_user_rc = 0;
 	while (custom_environment) {
 		struct envstring *ce = custom_environment;
 		custom_environment = ce->next;
@@ -121,6 +123,13 @@
 			opts += strlen(cp);
 			goto next_option;
 		}
+		cp = "no-user-rc";
+		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+			auth_debug_add("User rc file execution disabled.");
+			no_user_rc = 1;
+			opts += strlen(cp);
+			goto next_option;
+		}
 		cp = "command=\"";
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
 			opts += strlen(cp);
Index: channels.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/channels.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/channels.c -L crypto/openssh/channels.c -u -r1.4 -r1.5
--- crypto/openssh/channels.c
+++ crypto/openssh/channels.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.c,v 1.268 2007/01/03 03:01:40 stevesk Exp $ */
+/* $OpenBSD: channels.c,v 1.272 2008/01/19 23:02:40 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -1446,14 +1446,13 @@
 channel_handle_rfd(Channel *c, fd_set *readset, fd_set *writeset)
 {
 	char buf[CHAN_RBUF];
-	int len;
+	int len, force;
 
-	if (c->rfd != -1 &&
-	    (c->detach_close || FD_ISSET(c->rfd, readset))) {
+	force = c->isatty && c->detach_close && c->istate != CHAN_INPUT_CLOSED;
+	if (c->rfd != -1 && (force || FD_ISSET(c->rfd, readset))) {
 		errno = 0;
 		len = read(c->rfd, buf, sizeof(buf));
-		if (len < 0 && (errno == EINTR ||
-		    (errno == EAGAIN && !(c->isatty && c->detach_close))))
+		if (len < 0 && (errno == EINTR || (errno == EAGAIN && !force)))
 			return 1;
 #ifndef PTY_ZEROREAD
 		if (len <= 0) {
@@ -1658,7 +1657,9 @@
 {
 	if (c->type == SSH_CHANNEL_OPEN &&
 	    !(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
-	    c->local_window < c->local_window_max/2 &&
+	    ((c->local_window_max - c->local_window >
+	    c->local_maxpacket*3) ||
+	    c->local_window < c->local_window_max/2) &&
 	    c->local_consumed > 0) {
 		packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
 		packet_put_int(c->remote_id);
@@ -2384,7 +2385,7 @@
 			wildcard = 1;
 	} else if (gateway_ports || is_client) {
 		if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
-		    strcmp(listen_addr, "0.0.0.0") == 0) ||
+		    strcmp(listen_addr, "0.0.0.0") == 0 && is_client == 0) ||
 		    *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
 		    (!is_client && gateway_ports == 1))
 			wildcard = 1;
@@ -2408,10 +2409,11 @@
 		if (addr == NULL) {
 			/* This really shouldn't happen */
 			packet_disconnect("getaddrinfo: fatal error: %s",
-			    gai_strerror(r));
+			    ssh_gai_strerror(r));
 		} else {
 			error("channel_setup_fwd_listener: "
-			    "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
+			    "getaddrinfo(%.64s): %s", addr,
+			    ssh_gai_strerror(r));
 		}
 		return 0;
 	}
@@ -2731,7 +2733,7 @@
 	snprintf(strport, sizeof strport, "%d", port);
 	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0) {
 		error("connect_to %.100s: unknown host (%s)", host,
-		    gai_strerror(gaierr));
+		    ssh_gai_strerror(gaierr));
 		return -1;
 	}
 	for (ai = aitop; ai; ai = ai->ai_next) {
@@ -2873,7 +2875,7 @@
 		hints.ai_socktype = SOCK_STREAM;
 		snprintf(strport, sizeof strport, "%d", port);
 		if ((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0) {
-			error("getaddrinfo: %.100s", gai_strerror(gaierr));
+			error("getaddrinfo: %.100s", ssh_gai_strerror(gaierr));
 			return -1;
 		}
 		for (ai = aitop; ai; ai = ai->ai_next) {
@@ -3046,7 +3048,8 @@
 	hints.ai_socktype = SOCK_STREAM;
 	snprintf(strport, sizeof strport, "%u", 6000 + display_number);
 	if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
-		error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
+		error("%.100s: unknown host. (%s)", buf,
+		ssh_gai_strerror(gaierr));
 		return -1;
 	}
 	for (ai = aitop; ai; ai = ai->ai_next) {
Index: readconf.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/readconf.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/readconf.c -L crypto/openssh/readconf.c -u -r1.4 -r1.5
--- crypto/openssh/readconf.c
+++ crypto/openssh/readconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.c,v 1.161 2007/01/21 01:45:35 stevesk Exp $ */
+/* $OpenBSD: readconf.c,v 1.165 2008/01/19 23:09:49 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -326,6 +326,7 @@
 {
 	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
 	int opcode, *intptr, value, value2, scale;
+	LogLevel *log_level_ptr;
 	long long orig, val64;
 	size_t len;
 	Forward fwd;
@@ -498,7 +499,6 @@
 		goto parse_int;
 
 	case oRekeyLimit:
-		intptr = &options->rekey_limit;
 		arg = strdelim(&s);
 		if (!arg || *arg == '\0')
 			fatal("%.200s line %d: Missing argument.", filename, linenum);
@@ -526,14 +526,14 @@
 		}
 		val64 *= scale;
 		/* detect integer wrap and too-large limits */
-		if ((val64 / scale) != orig || val64 > INT_MAX)
+		if ((val64 / scale) != orig || val64 > UINT_MAX)
 			fatal("%.200s line %d: RekeyLimit too large",
 			    filename, linenum);
 		if (val64 < 16)
 			fatal("%.200s line %d: RekeyLimit too small",
 			    filename, linenum);
-		if (*activep && *intptr == -1)
-			*intptr = (int)val64;
+		if (*activep && options->rekey_limit == -1)
+			options->rekey_limit = (u_int32_t)val64;
 		break;
 
 	case oIdentityFile:
@@ -692,14 +692,14 @@
 		break;
 
 	case oLogLevel:
-		intptr = (int *) &options->log_level;
+		log_level_ptr = &options->log_level;
 		arg = strdelim(&s);
 		value = log_level_number(arg);
 		if (value == SYSLOG_LEVEL_NOT_SET)
 			fatal("%.200s line %d: unsupported log level '%s'",
 			    filename, linenum, arg ? arg : "<NONE>");
-		if (*activep && (LogLevel) *intptr == SYSLOG_LEVEL_NOT_SET)
-			*intptr = (LogLevel) value;
+		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
+			*log_level_ptr = (LogLevel) value;
 		break;
 
 	case oLocalForward:
@@ -1224,7 +1224,7 @@
 	cp = p = xstrdup(fwdspec);
 
 	/* skip leading spaces */
-	while (*cp && isspace(*cp))
+	while (isspace(*cp))
 		cp++;
 
 	for (i = 0; i < 4; ++i)
@@ -1255,7 +1255,7 @@
 
 	xfree(p);
 
-	if (fwd->listen_port == 0 && fwd->connect_port == 0)
+	if (fwd->listen_port == 0 || fwd->connect_port == 0)
 		goto fail_free;
 
 	if (fwd->connect_host != NULL &&
Index: defines.h
===================================================================
RCS file: /home/cvs/src/crypto/openssh/defines.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/defines.h -L crypto/openssh/defines.h -u -r1.3 -r1.4
--- crypto/openssh/defines.h
+++ crypto/openssh/defines.h
@@ -25,7 +25,7 @@
 #ifndef _DEFINES_H
 #define _DEFINES_H
 
-/* $Id: defines.h,v 1.138 2006/09/21 13:13:30 dtucker Exp $ */
+/* $Id: defines.h,v 1.146 2008/02/28 08:22:04 dtucker Exp $ */
 
 
 /* Constants */
@@ -68,7 +68,7 @@
 # endif
 #endif
 
-#ifndef MAXSYMLINKS
+#if defined(HAVE_DECL_MAXSYMLINKS) && HAVE_DECL_MAXSYMLINKS == 0
 # define MAXSYMLINKS 5
 #endif
 
@@ -321,12 +321,6 @@
 #ifndef _PATH_BSHELL
 # define _PATH_BSHELL "/bin/sh"
 #endif
-#ifndef _PATH_CSHELL
-# define _PATH_CSHELL "/bin/csh"
-#endif
-#ifndef _PATH_SHELLS
-# define _PATH_SHELLS "/etc/shells"
-#endif
 
 #ifdef USER_PATH
 # ifdef _PATH_STDPATH
@@ -449,6 +443,10 @@
 # define __bounded__(x, y, z)
 #endif
 
+#if !defined(HAVE_ATTRIBUTE__NONNULL__) && !defined(__nonnull__)
+# define __nonnull__(x)
+#endif
+
 /* *-*-nto-qnx doesn't define this macro in the system headers */
 #ifdef MISSING_HOWMANY
 # define howmany(x,y)	(((x)+((y)-1))/(y))
@@ -487,7 +485,7 @@
 	 (struct cmsghdr *)NULL)
 #endif /* CMSG_FIRSTHDR */
 
-#ifndef offsetof
+#if defined(HAVE_DECL_OFFSETOF) && HAVE_DECL_OFFSETOF == 0
 # define offsetof(type, member) ((size_t) &((type *)0)->member)
 #endif
 
@@ -542,6 +540,10 @@
 # undef HAVE_UPDWTMPX
 #endif
 
+#if defined(BROKEN_SHADOW_EXPIRE) && defined(HAS_SHADOW_EXPIRE)
+# undef HAS_SHADOW_EXPIRE
+#endif
+
 #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT) && \
     defined(SYSLOG_R_SAFE_IN_SIGHAND)
 # define DO_LOG_SAFE_IN_SIGHAND
@@ -565,11 +567,6 @@
 # define CUSTOM_SSH_AUDIT_EVENTS
 #endif
 
-/* OPENSSL_free() is Free() in versions before OpenSSL 0.9.6 */
-#if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x0090600f)
-# define OPENSSL_free(x) Free(x)
-#endif
-
 #if !defined(HAVE___func__) && defined(HAVE___FUNCTION__)
 #  define __func__ __FUNCTION__
 #elif !defined(HAVE___func__)
@@ -696,9 +693,12 @@
 # define CUSTOM_SYS_AUTH_PASSWD 1
 #endif
 
-#ifdef HAVE_LIBIAF
+#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID)
 # define CUSTOM_SYS_AUTH_PASSWD 1
 #endif
+#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF)
+# define USE_LIBIAF
+#endif
 
 /* HP-UX 11.11 */
 #ifdef BTMP_FILE
Index: README
===================================================================
RCS file: /home/cvs/src/crypto/openssh/README,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/README -L crypto/openssh/README -u -r1.3 -r1.4
--- crypto/openssh/README
+++ crypto/openssh/README
@@ -1,4 +1,4 @@
-See http://www.openssh.com/txt/release-4.6 for the release notes.
+See http://www.openssh.com/txt/release-4.9 for the release notes.
 
 - A Japanese translation of this document and of the OpenSSH FAQ is
 - available at http://www.unixuser.org/~haruyama/security/openssh/index.html
@@ -62,4 +62,4 @@
 [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9
 [7] http://www.openssh.com/faq.html
 
-$Id: README,v 1.64.4.1 2007/03/06 10:27:56 djm Exp $
+$Id: README,v 1.67 2008/03/27 06:43:34 djm Exp $
Index: monitor_wrap.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/monitor_wrap.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/monitor_wrap.c -L crypto/openssh/monitor_wrap.c -u -r1.4 -r1.5
--- crypto/openssh/monitor_wrap.c
+++ crypto/openssh/monitor_wrap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor_wrap.c,v 1.55 2007/02/19 10:45:58 dtucker Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.60 2007/10/29 04:08:08 dtucker Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos at citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus at openbsd.org>
@@ -222,8 +222,8 @@
 	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
 
 	if (buffer_get_char(&m) == 0) {
-		buffer_free(&m);
-		return (NULL);
+		pw = NULL;
+		goto out;
 	}
 	pw = buffer_get_string(&m, &len);
 	if (len != sizeof(struct passwd))
@@ -237,6 +237,7 @@
 	pw->pw_dir = buffer_get_string(&m, NULL);
 	pw->pw_shell = buffer_get_string(&m, NULL);
 
+out:
 	/* copy options block as a Match directive may have changed some */
 	newopts = buffer_get_string(&m, &len);
 	if (len != sizeof(*newopts))
@@ -476,8 +477,8 @@
 
 	/* Mac structure */
 	mac->name = buffer_get_string(&b, NULL);
-	if (mac->name == NULL || mac_init(mac, mac->name) == -1)
-		fatal("%s: can not init mac %s", __func__, mac->name);
+	if (mac->name == NULL || mac_setup(mac, mac->name) == -1)
+		fatal("%s: can not setup mac %s", __func__, mac->name);
 	mac->enabled = buffer_get_int(&b);
 	mac->key = buffer_get_string(&b, &len);
 	if (len > mac->key_len)
@@ -688,8 +689,9 @@
 	buffer_append(&loginmsg, msg, strlen(msg));
 	xfree(msg);
 
-	*ptyfd = mm_receive_fd(pmonitor->m_recvfd);
-	*ttyfd = mm_receive_fd(pmonitor->m_recvfd);
+	if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
+	    (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
+		fatal("%s: receive fds failed", __func__);
 
 	/* Success */
 	return (1);
Index: sftp.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sftp.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/sftp.c -L crypto/openssh/sftp.c -u -r1.4 -r1.5
--- crypto/openssh/sftp.c
+++ crypto/openssh/sftp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.c,v 1.96 2007/01/03 04:09:15 stevesk Exp $ */
+/* $OpenBSD: sftp.c,v 1.99 2008/01/20 00:38:30 djm Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm at openbsd.org>
  *
@@ -26,6 +26,7 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 
+#include <ctype.h>
 #include <errno.h>
 
 #ifdef HAVE_PATHS_H
@@ -346,144 +347,78 @@
 }
 
 static int
-parse_getput_flags(const char **cpp, int *pflag)
+parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag)
 {
-	const char *cp = *cpp;
+	extern int optind, optreset, opterr;
+	int ch;
 
-	/* Check for flags */
-	if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
-		switch (cp[1]) {
+	optind = optreset = 1;
+	opterr = 0;
+
+	*pflag = 0;
+	while ((ch = getopt(argc, argv, "Pp")) != -1) {
+		switch (ch) {
 		case 'p':
 		case 'P':
 			*pflag = 1;
 			break;
 		default:
-			error("Invalid flag -%c", cp[1]);
-			return(-1);
+			error("%s: Invalid flag -%c", cmd, ch);
+			return -1;
 		}
-		cp += 2;
-		*cpp = cp + strspn(cp, WHITESPACE);
 	}
 
-	return(0);
+	return optind;
 }
 
 static int
-parse_ls_flags(const char **cpp, int *lflag)
+parse_ls_flags(char **argv, int argc, int *lflag)
 {
-	const char *cp = *cpp;
+	extern int optind, optreset, opterr;
+	int ch;
 
-	/* Defaults */
-	*lflag = LS_NAME_SORT;
+	optind = optreset = 1;
+	opterr = 0;
 
-	/* Check for flags */
-	if (cp++[0] == '-') {
-		for (; strchr(WHITESPACE, *cp) == NULL; cp++) {
-			switch (*cp) {
-			case 'l':
-				*lflag &= ~VIEW_FLAGS;
-				*lflag |= LS_LONG_VIEW;
-				break;
-			case '1':
-				*lflag &= ~VIEW_FLAGS;
-				*lflag |= LS_SHORT_VIEW;
-				break;
-			case 'n':
-				*lflag &= ~VIEW_FLAGS;
-				*lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
-				break;
-			case 'S':
-				*lflag &= ~SORT_FLAGS;
-				*lflag |= LS_SIZE_SORT;
-				break;
-			case 't':
-				*lflag &= ~SORT_FLAGS;
-				*lflag |= LS_TIME_SORT;
-				break;
-			case 'r':
-				*lflag |= LS_REVERSE_SORT;
-				break;
-			case 'f':
-				*lflag &= ~SORT_FLAGS;
-				break;
-			case 'a':
-				*lflag |= LS_SHOW_ALL;
-				break;
-			default:
-				error("Invalid flag -%c", *cp);
-				return(-1);
-			}
-		}
-		*cpp = cp + strspn(cp, WHITESPACE);
-	}
-
-	return(0);
-}
-
-static int
-get_pathname(const char **cpp, char **path)
-{
-	const char *cp = *cpp, *end;
-	char quot;
-	u_int i, j;
-
-	cp += strspn(cp, WHITESPACE);
-	if (!*cp) {
-		*cpp = cp;
-		*path = NULL;
-		return (0);
-	}
-
-	*path = xmalloc(strlen(cp) + 1);
-
-	/* Check for quoted filenames */
-	if (*cp == '\"' || *cp == '\'') {
-		quot = *cp++;
-
-		/* Search for terminating quote, unescape some chars */
-		for (i = j = 0; i <= strlen(cp); i++) {
-			if (cp[i] == quot) {	/* Found quote */
-				i++;
-				(*path)[j] = '\0';
-				break;
-			}
-			if (cp[i] == '\0') {	/* End of string */
-				error("Unterminated quote");
-				goto fail;
-			}
-			if (cp[i] == '\\') {	/* Escaped characters */
-				i++;
-				if (cp[i] != '\'' && cp[i] != '\"' &&
-				    cp[i] != '\\') {
-					error("Bad escaped character '\\%c'",
-					    cp[i]);
-					goto fail;
-				}
-			}
-			(*path)[j++] = cp[i];
-		}
-
-		if (j == 0) {
-			error("Empty quotes");
-			goto fail;
+	*lflag = LS_NAME_SORT;
+	while ((ch = getopt(argc, argv, "1Saflnrt")) != -1) {
+		switch (ch) {
+		case '1':
+			*lflag &= ~VIEW_FLAGS;
+			*lflag |= LS_SHORT_VIEW;
+			break;
+		case 'S':
+			*lflag &= ~SORT_FLAGS;
+			*lflag |= LS_SIZE_SORT;
+			break;
+		case 'a':
+			*lflag |= LS_SHOW_ALL;
+			break;
+		case 'f':
+			*lflag &= ~SORT_FLAGS;
+			break;
+		case 'l':
+			*lflag &= ~VIEW_FLAGS;
+			*lflag |= LS_LONG_VIEW;
+			break;
+		case 'n':
+			*lflag &= ~VIEW_FLAGS;
+			*lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;
+			break;
+		case 'r':
+			*lflag |= LS_REVERSE_SORT;
+			break;
+		case 't':
+			*lflag &= ~SORT_FLAGS;
+			*lflag |= LS_TIME_SORT;
+			break;
+		default:
+			error("ls: Invalid flag -%c", ch);
+			return -1;
 		}
-		*cpp = cp + i + strspn(cp + i, WHITESPACE);
-	} else {
-		/* Read to end of filename */
-		end = strpbrk(cp, WHITESPACE);
-		if (end == NULL)
-			end = strchr(cp, '\0');
-		*cpp = end + strspn(end, WHITESPACE);
-
-		memcpy(*path, cp, end - cp);
-		(*path)[end - cp] = '\0';
 	}
-	return (0);
 
- fail:
-	xfree(*path);
-	*path = NULL;
-	return (-1);
+	return optind;
 }
 
 static int
@@ -499,17 +434,6 @@
 }
 
 static int
-is_reg(char *path)
-{
-	struct stat sb;
-
-	if (stat(path, &sb) == -1)
-		fatal("stat %s: %s", path, strerror(errno));
-
-	return(S_ISREG(sb.st_mode));
-}
-
-static int
 remote_is_dir(struct sftp_conn *conn, char *path)
 {
 	Attrib *a;
@@ -597,6 +521,7 @@
 	glob_t g;
 	int err = 0;
 	int i;
+	struct stat sb;
 
 	if (dst) {
 		tmp_dst = xstrdup(dst);
@@ -605,7 +530,7 @@
 
 	memset(&g, 0, sizeof(g));
 	debug3("Looking up %s", src);
-	if (glob(src, 0, NULL, &g)) {
+	if (glob(src, GLOB_NOCHECK, NULL, &g)) {
 		error("File \"%s\" not found.", src);
 		err = -1;
 		goto out;
@@ -620,7 +545,13 @@
 	}
 
 	for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
-		if (!is_reg(g.gl_pathv[i])) {
+		if (stat(g.gl_pathv[i], &sb) == -1) {
+			err = -1;
+			error("stat %s: %s", g.gl_pathv[i], strerror(errno));
+			continue;
+		}
+
+		if (!S_ISREG(sb.st_mode)) {
 			error("skipping non-regular file %s",
 			    g.gl_pathv[i]);
 			continue;
@@ -866,15 +797,189 @@
 	return (0);
 }
 
+/*
+ * Undo escaping of glob sequences in place. Used to undo extra escaping
+ * applied in makeargv() when the string is destined for a function that
+ * does not glob it.
+ */
+static void
+undo_glob_escape(char *s)
+{
+	size_t i, j;
+
+	for (i = j = 0;;) {
+		if (s[i] == '\0') {
+			s[j] = '\0';
+			return;
+		}
+		if (s[i] != '\\') {
+			s[j++] = s[i++];
+			continue;
+		}
+		/* s[i] == '\\' */
+		++i;
+		switch (s[i]) {
+		case '?':
+		case '[':
+		case '*':
+		case '\\':
+			s[j++] = s[i++];
+			break;
+		case '\0':
+			s[j++] = '\\';
+			s[j] = '\0';
+			return;
+		default:
+			s[j++] = '\\';
+			s[j++] = s[i++];
+			break;
+		}
+	}
+}
+
+/*
+ * Split a string into an argument vector using sh(1)-style quoting,
+ * comment and escaping rules, but with some tweaks to handle glob(3)
+ * wildcards.
+ * Returns NULL on error or a NULL-terminated array of arguments.
+ */
+#define MAXARGS 	128
+#define MAXARGLEN	8192
+static char **
+makeargv(const char *arg, int *argcp)
+{
+	int argc, quot;
+	size_t i, j;
+	static char argvs[MAXARGLEN];
+	static char *argv[MAXARGS + 1];
+	enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q;
+
+	*argcp = argc = 0;
+	if (strlen(arg) > sizeof(argvs) - 1) {
+ args_too_longs:
+		error("string too long");
+		return NULL;
+	}
+	state = MA_START;
+	i = j = 0;
+	for (;;) {
+		if (isspace(arg[i])) {
+			if (state == MA_UNQUOTED) {
+				/* Terminate current argument */
+				argvs[j++] = '\0';
+				argc++;
+				state = MA_START;
+			} else if (state != MA_START)
+				argvs[j++] = arg[i];
+		} else if (arg[i] == '"' || arg[i] == '\'') {
+			q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE;
+			if (state == MA_START) {
+				argv[argc] = argvs + j;
+				state = q;
+			} else if (state == MA_UNQUOTED) 
+				state = q;
+			else if (state == q)
+				state = MA_UNQUOTED;
+			else
+				argvs[j++] = arg[i];
+		} else if (arg[i] == '\\') {
+			if (state == MA_SQUOTE || state == MA_DQUOTE) {
+				quot = state == MA_SQUOTE ? '\'' : '"';
+				/* Unescape quote we are in */
+				/* XXX support \n and friends? */
+				if (arg[i + 1] == quot) {
+					i++;
+					argvs[j++] = arg[i];
+				} else if (arg[i + 1] == '?' ||
+				    arg[i + 1] == '[' || arg[i + 1] == '*') {
+					/*
+					 * Special case for sftp: append
+					 * double-escaped glob sequence -
+					 * glob will undo one level of
+					 * escaping. NB. string can grow here.
+					 */
+					if (j >= sizeof(argvs) - 5)
+						goto args_too_longs;
+					argvs[j++] = '\\';
+					argvs[j++] = arg[i++];
+					argvs[j++] = '\\';
+					argvs[j++] = arg[i];
+				} else {
+					argvs[j++] = arg[i++];
+					argvs[j++] = arg[i];
+				}
+			} else {
+				if (state == MA_START) {
+					argv[argc] = argvs + j;
+					state = MA_UNQUOTED;
+				}
+				if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
+				    arg[i + 1] == '*' || arg[i + 1] == '\\') {
+					/*
+					 * Special case for sftp: append
+					 * escaped glob sequence -
+					 * glob will undo one level of
+					 * escaping.
+					 */
+					argvs[j++] = arg[i++];
+					argvs[j++] = arg[i];
+				} else {
+					/* Unescape everything */
+					/* XXX support \n and friends? */
+					i++;
+					argvs[j++] = arg[i];
+				}
+			}
+		} else if (arg[i] == '#') {
+			if (state == MA_SQUOTE || state == MA_DQUOTE)
+				argvs[j++] = arg[i];
+			else
+				goto string_done;
+		} else if (arg[i] == '\0') {
+			if (state == MA_SQUOTE || state == MA_DQUOTE) {
+				error("Unterminated quoted argument");
+				return NULL;
+			}
+ string_done:
+			if (state == MA_UNQUOTED) {
+				argvs[j++] = '\0';
+				argc++;
+			}
+			break;
+		} else {
+			if (state == MA_START) {
+				argv[argc] = argvs + j;
+				state = MA_UNQUOTED;
+			}
+			if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
+			    (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
+				/*
+				 * Special case for sftp: escape quoted
+				 * glob(3) wildcards. NB. string can grow
+				 * here.
+				 */
+				if (j >= sizeof(argvs) - 3)
+					goto args_too_longs;
+				argvs[j++] = '\\';
+				argvs[j++] = arg[i];
+			} else
+				argvs[j++] = arg[i];
+		}
+		i++;
+	}
+	*argcp = argc;
+	return argv;
+}
+
 static int
 parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
     unsigned long *n_arg, char **path1, char **path2)
 {
 	const char *cmd, *cp = *cpp;
-	char *cp2;
+	char *cp2, **argv;
 	int base = 0;
 	long l;
-	int i, cmdnum;
+	int i, cmdnum, optidx, argc;
 
 	/* Skip leading whitespace */
 	cp = cp + strspn(cp, WHITESPACE);
@@ -890,17 +995,13 @@
 		cp++;
 	}
 
-	/* Figure out which command we have */
-	for (i = 0; cmds[i].c; i++) {
-		int cmdlen = strlen(cmds[i].c);
+	if ((argv = makeargv(cp, &argc)) == NULL)
+		return -1;
 
-		/* Check for command followed by whitespace */
-		if (!strncasecmp(cp, cmds[i].c, cmdlen) &&
-		    strchr(WHITESPACE, cp[cmdlen])) {
-			cp += cmdlen;
-			cp = cp + strspn(cp, WHITESPACE);
+	/* Figure out which command we have */
+	for (i = 0; cmds[i].c != NULL; i++) {
+		if (strcasecmp(cmds[i].c, argv[0]) == 0)
 			break;
-		}
 	}
 	cmdnum = cmds[i].n;
 	cmd = cmds[i].c;
@@ -911,40 +1012,44 @@
 		cmdnum = I_SHELL;
 	} else if (cmdnum == -1) {
 		error("Invalid command.");
-		return (-1);
+		return -1;
 	}
 
 	/* Get arguments and parse flags */
 	*lflag = *pflag = *n_arg = 0;
 	*path1 = *path2 = NULL;
+	optidx = 1;
 	switch (cmdnum) {
 	case I_GET:
 	case I_PUT:
-		if (parse_getput_flags(&cp, pflag))
-			return(-1);
+		if ((optidx = parse_getput_flags(cmd, argv, argc, pflag)) == -1)
+			return -1;
 		/* Get first pathname (mandatory) */
-		if (get_pathname(&cp, path1))
-			return(-1);
-		if (*path1 == NULL) {
+		if (argc - optidx < 1) {
 			error("You must specify at least one path after a "
 			    "%s command.", cmd);
-			return(-1);
+			return -1;
+		}
+		*path1 = xstrdup(argv[optidx]);
+		/* Get second pathname (optional) */
+		if (argc - optidx > 1) {
+			*path2 = xstrdup(argv[optidx + 1]);
+			/* Destination is not globbed */
+			undo_glob_escape(*path2);
 		}
-		/* Try to get second pathname (optional) */
-		if (get_pathname(&cp, path2))
-			return(-1);
 		break;
 	case I_RENAME:
 	case I_SYMLINK:
-		if (get_pathname(&cp, path1))
-			return(-1);
-		if (get_pathname(&cp, path2))
-			return(-1);
-		if (!*path1 || !*path2) {
+		if (argc - optidx < 2) {
 			error("You must specify two paths after a %s "
 			    "command.", cmd);
-			return(-1);
+			return -1;
 		}
+		*path1 = xstrdup(argv[optidx]);
+		*path2 = xstrdup(argv[optidx + 1]);
+		/* Paths are not globbed */
+		undo_glob_escape(*path1);
+		undo_glob_escape(*path2);
 		break;
 	case I_RM:
 	case I_MKDIR:
@@ -953,59 +1058,57 @@
 	case I_LCHDIR:
 	case I_LMKDIR:
 		/* Get pathname (mandatory) */
-		if (get_pathname(&cp, path1))
-			return(-1);
-		if (*path1 == NULL) {
+		if (argc - optidx < 1) {
 			error("You must specify a path after a %s command.",
 			    cmd);
-			return(-1);
+			return -1;
 		}
+		*path1 = xstrdup(argv[optidx]);
+		/* Only "rm" globs */
+		if (cmdnum != I_RM)
+			undo_glob_escape(*path1);
 		break;
 	case I_LS:
-		if (parse_ls_flags(&cp, lflag))
+		if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
 			return(-1);
 		/* Path is optional */
-		if (get_pathname(&cp, path1))
-			return(-1);
+		if (argc - optidx > 0)
+			*path1 = xstrdup(argv[optidx]);
 		break;
 	case I_LLS:
+		/* Skip ls command and following whitespace */
+		cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);
 	case I_SHELL:
 		/* Uses the rest of the line */
 		break;
 	case I_LUMASK:
-		base = 8;
 	case I_CHMOD:
 		base = 8;
 	case I_CHOWN:
 	case I_CHGRP:
 		/* Get numeric arg (mandatory) */
+		if (argc - optidx < 1)
+			goto need_num_arg;
 		errno = 0;
-		l = strtol(cp, &cp2, base);
-		if (cp2 == cp || ((l == LONG_MIN || l == LONG_MAX) &&
-		    errno == ERANGE) || l < 0) {
+		l = strtol(argv[optidx], &cp2, base);
+		if (cp2 == argv[optidx] || *cp2 != '\0' ||
+		    ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
+		    l < 0) {
+ need_num_arg:
 			error("You must supply a numeric argument "
 			    "to the %s command.", cmd);
-			return(-1);
+			return -1;
 		}
-		cp = cp2;
 		*n_arg = l;
-		if (cmdnum == I_LUMASK && strchr(WHITESPACE, *cp))
+		if (cmdnum == I_LUMASK)
 			break;
-		if (cmdnum == I_LUMASK || !strchr(WHITESPACE, *cp)) {
-			error("You must supply a numeric argument "
-			    "to the %s command.", cmd);
-			return(-1);
-		}
-		cp += strspn(cp, WHITESPACE);
-
 		/* Get pathname (mandatory) */
-		if (get_pathname(&cp, path1))
-			return(-1);
-		if (*path1 == NULL) {
+		if (argc - optidx < 2) {
 			error("You must specify a path after a %s command.",
 			    cmd);
-			return(-1);
+			return -1;
 		}
+		*path1 = xstrdup(argv[optidx + 1]);
 		break;
 	case I_QUIT:
 	case I_PWD:
Index: auth2-chall.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/auth2-chall.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/auth2-chall.c -L crypto/openssh/auth2-chall.c -u -r1.4 -r1.5
--- crypto/openssh/auth2-chall.c
+++ crypto/openssh/auth2-chall.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-chall.c,v 1.32 2007/01/03 03:01:40 stevesk Exp $ */
+/* $OpenBSD: auth2-chall.c,v 1.33 2007/09/21 08:15:29 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2001 Per Allansson.  All rights reserved.
Index: configure.ac
===================================================================
RCS file: /home/cvs/src/crypto/openssh/configure.ac,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/configure.ac -L crypto/openssh/configure.ac -u -r1.4 -r1.5
--- crypto/openssh/configure.ac
+++ crypto/openssh/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.372 2007/03/05 00:51:27 djm Exp $
+# $Id: configure.ac,v 1.397 2008/03/27 01:33:07 djm Exp $
 #
 # Copyright (c) 1999-2004 Damien Miller
 #
@@ -15,7 +15,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_INIT(OpenSSH, Portable, openssh-unix-dev at mindrot.org)
-AC_REVISION($Revision: 1.372 $)
+AC_REVISION($Revision: 1.397 $)
 AC_CONFIG_SRCDIR([ssh.c])
 
 AC_CONFIG_HEADER(config.h)
@@ -90,18 +90,66 @@
 
 AC_CHECK_DECL(LLONG_MAX, have_llong_max=1, , [#include <limits.h>])
 
+use_stack_protector=1
+AC_ARG_WITH(stackprotect,
+    [  --without-stackprotect  Don't use compiler's stack protection], [
+    if test "x$withval" = "xno"; then
+	use_stack_protector=0
+    fi ])
+
 if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
 	CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wuninitialized"
 	GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
 	case $GCC_VER in
-		1.*) ;;
-		2.8* | 2.9*) CFLAGS="$CFLAGS -Wsign-compare" ;;
-		2.*) ;;
+		1.*) no_attrib_nonnull=1 ;;
+		2.8* | 2.9*)
+		     CFLAGS="$CFLAGS -Wsign-compare"
+		     no_attrib_nonnull=1
+		     ;;
+		2.*) no_attrib_nonnull=1 ;;
 		3.*) CFLAGS="$CFLAGS -Wsign-compare" ;;
 		4.*) CFLAGS="$CFLAGS -Wsign-compare -Wno-pointer-sign" ;;
 		*) ;;
 	esac
 
+	# -fstack-protector-all doesn't always work for some GCC versions
+	# and/or platforms, so we test if we can.  If it's not supported
+	# on a give platform gcc will emit a warning so we use -Werror.
+	if test "x$use_stack_protector" = "x1"; then
+	    for t in -fstack-protector-all -fstack-protector; do
+		AC_MSG_CHECKING(if $CC supports $t)
+		saved_CFLAGS="$CFLAGS"
+		saved_LDFLAGS="$LDFLAGS"
+		CFLAGS="$CFLAGS $t -Werror"
+		LDFLAGS="$LDFLAGS $t -Werror"
+		AC_LINK_IFELSE(
+			[AC_LANG_SOURCE([
+#include <stdlib.h>
+int main(void){return 0;}
+			 ])],
+		    [ AC_MSG_RESULT(yes)
+		      CFLAGS="$saved_CFLAGS $t"
+		      LDFLAGS="$saved_LDFLAGS $t"
+		      AC_MSG_CHECKING(if $t works)
+		      AC_RUN_IFELSE(
+			[AC_LANG_SOURCE([
+#include <stdlib.h>
+int main(void){exit(0);}
+			])],
+			[ AC_MSG_RESULT(yes)
+			  break ],
+			[ AC_MSG_RESULT(no) ],
+			[ AC_MSG_WARN([cross compiling: cannot test])
+			  break ]
+		      )
+		    ],
+		    [ AC_MSG_RESULT(no) ]
+		)
+		CFLAGS="$saved_CFLAGS"
+		LDFLAGS="$saved_LDFLAGS"
+	    done
+	fi
+
 	if test -z "$have_llong_max"; then
 		# retry LLONG_MAX with -std=gnu99, needed on some Linuxes
 		unset ac_cv_have_decl_LLONG_MAX
@@ -115,6 +163,10 @@
 	fi
 fi
 
+if test "x$no_attrib_nonnull" != "x1" ; then
+	AC_DEFINE(HAVE_ATTRIBUTE__NONNULL__, 1, [Have attribute nonnull])
+fi
+
 AC_ARG_WITH(rpath,
 	[  --without-rpath         Disable auto-added -R linker paths],
 	[
@@ -198,6 +250,7 @@
 	netgroup.h \
 	pam/pam_appl.h \
 	paths.h \
+	poll.h \
 	pty.h \
 	readpassphrase.h \
 	rpc/types.h \
@@ -215,6 +268,7 @@
 	sys/dir.h \
 	sys/mman.h \
 	sys/ndir.h \
+	sys/poll.h \
 	sys/prctl.h \
 	sys/pstat.h \
 	sys/select.h \
@@ -229,6 +283,7 @@
 	time.h \
 	tmpdir.h \
 	ttyent.h \
+	ucred.h \
 	unistd.h \
 	usersec.h \
 	util.h \
@@ -334,7 +389,7 @@
 		[],
 		[#include <usersec.h>]
 	)
-	AC_CHECK_FUNCS(setauthdb)
+	AC_CHECK_FUNCS(getgrset setauthdb)
 	AC_CHECK_DECL(F_CLOSEM,
 	    AC_DEFINE(HAVE_FCNTL_CLOSEM, 1, [Use F_CLOSEM fcntl for closefrom]),
 	    [],
@@ -396,6 +451,7 @@
 	AC_DEFINE(SETEUID_BREAKS_SETUID)
 	AC_DEFINE(BROKEN_SETREUID)
 	AC_DEFINE(BROKEN_SETREGID)
+	AC_DEFINE(BROKEN_GLOB, 1, [OS X glob does not do what we expect])
 	AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1,
 		[Define if your resolver libs need this for getrrsetbyname])
 	AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
@@ -403,6 +459,11 @@
 	    [Use tunnel device compatibility to OpenBSD])
 	AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
 	    [Prepend the address family to IP tunnel traffic])
+	m4_pattern_allow(AU_IPv)
+	AC_CHECK_DECL(AU_IPv4, [], 
+	    AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records])
+	    [#include <bsm/audit.h>]
+	)
 	;;
 *-*-dragonfly*)
 	SSHDLIBS="$SSHDLIBS -lcrypt"
@@ -540,6 +601,7 @@
 	AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
 	AC_CHECK_HEADER([net/if_tap.h], ,
 	    AC_DEFINE(SSH_TUN_NO_L2, 1, [No layer 2 tunnel support]))
+	AC_DEFINE(BROKEN_GLOB, 1, [FreeBSD glob does not do what we need])
 	;;
 *-*-bsdi*)
 	AC_DEFINE(SETEUID_BREAKS_SETUID)
@@ -776,7 +838,13 @@
 	AC_DEFINE(MISSING_FD_MASK, 1, [Define on *nto-qnx systems])
 	AC_DEFINE(DISABLE_LASTLOG)
 	AC_DEFINE(SSHD_ACQUIRES_CTTY)
+	AC_DEFINE(BROKEN_SHADOW_EXPIRE, 1, [QNX shadow support is broken])
 	enable_etc_default_login=no	# has incompatible /etc/default/login
+	case "$host" in
+	*-*-nto-qnx6*)
+		AC_DEFINE(DISABLE_FD_PASSING)
+		;;
+	esac
 	;;
 
 *-*-ultrix*)
@@ -1109,8 +1177,7 @@
 					CPPFLAGS="-I${withval} ${CPPFLAGS}"
 				fi
 			fi
-			LIBWRAP="-lwrap"
-			LIBS="$LIBWRAP $LIBS"
+			LIBS="-lwrap $LIBS"
 			AC_MSG_CHECKING(for libwrap)
 			AC_TRY_LINK(
 				[
@@ -1126,7 +1193,7 @@
 					AC_DEFINE(LIBWRAP, 1,
 						[Define if you want
 						TCP Wrappers support])
-					AC_SUBST(LIBWRAP)
+					SSHDLIBS="$SSHDLIBS -lwrap"
 					TCPW_MSG="yes"
 				],
 				[
@@ -1201,7 +1268,7 @@
 		AC_CHECK_FUNCS(getaudit, [],
 		    [AC_MSG_ERROR(BSM enabled and required function not found)])
 		# These are optional
-		AC_CHECK_FUNCS(getaudit_addr)
+		AC_CHECK_FUNCS(getaudit_addr aug_get_machine)
 		AC_DEFINE(USE_BSM_AUDIT, 1, [Use BSM audit module])
 		;;
 	  debug)
@@ -1241,6 +1308,7 @@
 	getnameinfo \
 	getopt \
 	getpeereid \
+	getpeerucred \
 	_getpty \
 	getrlimit \
 	getttyent \
@@ -1259,6 +1327,7 @@
 	ogetaddrinfo \
 	openlog_r \
 	openpty \
+	poll \
 	prctl \
 	pstat \
 	readpassphrase \
@@ -1292,6 +1361,7 @@
 	strtonum \
 	strtoll \
 	strtoul \
+	swap32 \
 	sysconf \
 	tcgetpgrp \
 	truncate \
@@ -1364,6 +1434,14 @@
 #include <unistd.h>
 	])
 
+AC_CHECK_DECLS(MAXSYMLINKS, , , [
+#include <sys/param.h>
+	])
+
+AC_CHECK_DECLS(offsetof, , , [
+#include <stddef.h>
+	])
+
 AC_CHECK_FUNCS(setresuid, [
 	dnl Some platorms have setresuid that isn't implemented, test for this
 	AC_MSG_CHECKING(if setresuid seems to work)
@@ -1489,7 +1567,7 @@
 
 # Check for missing getpeereid (or equiv) support
 NO_PEERCHECK=""
-if test "x$ac_cv_func_getpeereid" != "xyes" ; then
+if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "xyes"; then
 	AC_MSG_CHECKING([whether system supports SO_PEERCRED getsockopt])
 	AC_TRY_COMPILE(
 		[#include <sys/types.h>
@@ -1977,7 +2055,15 @@
 # Search for SHA256 support in libc and/or OpenSSL
 AC_CHECK_FUNCS(SHA256_Update EVP_sha256)
 
-AC_CHECK_LIB(iaf, ia_openinfo)
+saved_LIBS="$LIBS"
+AC_CHECK_LIB(iaf, ia_openinfo, [
+	LIBS="$LIBS -liaf"
+	AC_CHECK_FUNCS(set_id, [SSHDLIBS="$SSHDLIBS -liaf"
+				AC_DEFINE(HAVE_LIBIAF, 1,
+        		[Define if system has libiaf that supports set_id])
+				])
+])
+LIBS="$saved_LIBS"
 
 ### Configure cryptographic random number support
 
@@ -2027,7 +2113,7 @@
 
 			PAM_MSG="yes"
 
-			LIBPAM="-lpam"
+			SSHDLIBS="$SSHDLIBS -lpam"
 			AC_DEFINE(USE_PAM, 1,
 				[Define if you want to enable PAM support])
 
@@ -2037,11 +2123,10 @@
 					# libdl already in LIBS
 					;;
 				*)
-					LIBPAM="$LIBPAM -ldl"
+					SSHDLIBS="$SSHDLIBS -ldl"
 					;;
 				esac
 			fi
-			AC_SUBST(LIBPAM)
 		fi
 	]
 )
@@ -3150,25 +3235,43 @@
 			[#include <arpa/nameser.h>])
 	])
 
+AC_MSG_CHECKING(if struct __res_state _res is an extern)
+AC_LINK_IFELSE([
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+extern struct __res_state _res;
+int main() { return 0; }
+		],
+		[AC_MSG_RESULT(yes)
+		 AC_DEFINE(HAVE__RES_EXTERN, 1,
+		    [Define if you have struct __res_state _res as an extern])
+		],
+		[ AC_MSG_RESULT(no) ]
+)
+
 # Check whether user wants SELinux support
 SELINUX_MSG="no"
 LIBSELINUX=""
 AC_ARG_WITH(selinux,
-	[  --with-selinux   Enable SELinux support],
+	[  --with-selinux          Enable SELinux support],
 	[ if test "x$withval" != "xno" ; then
+		save_LIBS="$LIBS"
 		AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.])
 		SELINUX_MSG="yes"
 		AC_CHECK_HEADER([selinux/selinux.h], ,
 		    AC_MSG_ERROR(SELinux support requires selinux.h header))
 		AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ],
 		    AC_MSG_ERROR(SELinux support requires libselinux library))
-		save_LIBS="$LIBS"
-		LIBS="$LIBS $LIBSELINUX"
+		SSHDLIBS="$SSHDLIBS $LIBSELINUX"
 		AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
 		LIBS="$save_LIBS"
 	fi ]
 )
-AC_SUBST(LIBSELINUX)
 
 # Check whether user wants Kerberos 5 support
 KRB5_MSG="no"
@@ -4004,7 +4107,10 @@
 echo "    Compiler flags: ${CFLAGS}"
 echo "Preprocessor flags: ${CPPFLAGS}"
 echo "      Linker flags: ${LDFLAGS}"
-echo "         Libraries: ${LIBWRAP} ${LIBPAM} ${LIBS}"
+echo "         Libraries: ${LIBS}"
+if test ! -z "${SSHDLIBS}"; then
+echo "         +for sshd: ${SSHDLIBS}"
+fi
 
 echo ""
 
@@ -4030,12 +4136,12 @@
 fi
 
 if test ! -z "$NO_PEERCHECK" ; then
-	echo "WARNING: the operating system that you are using does not "
-	echo "appear to support either the getpeereid() API nor the "
-	echo "SO_PEERCRED getsockopt() option. These facilities are used to "
-	echo "enforce security checks to prevent unauthorised connections to "
-	echo "ssh-agent. Their absence increases the risk that a malicious "
-	echo "user can connect to your agent. "
+	echo "WARNING: the operating system that you are using does not"
+	echo "appear to support getpeereid(), getpeerucred() or the"
+	echo "SO_PEERCRED getsockopt() option. These facilities are used to"
+	echo "enforce security checks to prevent unauthorised connections to"
+	echo "ssh-agent. Their absence increases the risk that a malicious"
+	echo "user can connect to your agent."
 	echo ""
 fi
 
Index: sftp-client.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sftp-client.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/sftp-client.c -L crypto/openssh/sftp-client.c -u -r1.4 -r1.5
--- crypto/openssh/sftp-client.c
+++ crypto/openssh/sftp-client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-client.c,v 1.76 2007/01/22 11:32:50 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.81 2008/03/23 12:54:01 djm Exp $ */
 /*
  * Copyright (c) 2001-2004 Damien Miller <djm at openbsd.org>
  *
@@ -65,6 +65,8 @@
 	u_int num_requests;
 	u_int version;
 	u_int msg_id;
+#define SFTP_EXT_POSIX_RENAME	1
+	u_int exts;
 };
 
 static void
@@ -239,7 +241,7 @@
 struct sftp_conn *
 do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
 {
-	u_int type;
+	u_int type, exts = 0;
 	int version;
 	Buffer msg;
 	struct sftp_conn *ret;
@@ -270,6 +272,8 @@
 		char *value = buffer_get_string(&msg, NULL);
 
 		debug2("Init extension: \"%s\"", name);
+		if (strcmp(name, "posix-rename at openssh.com") == 0)
+			exts |= SFTP_EXT_POSIX_RENAME;
 		xfree(name);
 		xfree(value);
 	}
@@ -283,6 +287,7 @@
 	ret->num_requests = num_requests;
 	ret->version = version;
 	ret->msg_id = 1;
+	ret->exts = exts;
 
 	/* Some filexfer v.0 servers don't support large packets */
 	if (version == 0)
@@ -534,6 +539,7 @@
 	return(get_decode_stat(conn->fd_in, id, quiet));
 }
 
+#ifdef notyet
 Attrib *
 do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet)
 {
@@ -545,6 +551,7 @@
 
 	return(get_decode_stat(conn->fd_in, id, quiet));
 }
+#endif
 
 int
 do_setstat(struct sftp_conn *conn, char *path, Attrib *a)
@@ -637,13 +644,20 @@
 
 	/* Send rename request */
 	id = conn->msg_id++;
-	buffer_put_char(&msg, SSH2_FXP_RENAME);
-	buffer_put_int(&msg, id);
+	if ((conn->exts & SFTP_EXT_POSIX_RENAME)) {
+		buffer_put_char(&msg, SSH2_FXP_EXTENDED);
+		buffer_put_int(&msg, id);
+		buffer_put_cstring(&msg, "posix-rename at openssh.com");
+	} else {
+		buffer_put_char(&msg, SSH2_FXP_RENAME);
+		buffer_put_int(&msg, id);
+	}
 	buffer_put_cstring(&msg, oldpath);
 	buffer_put_cstring(&msg, newpath);
 	send_msg(conn->fd_out, &msg);
-	debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath,
-	    newpath);
+	debug3("Sent message %s \"%s\" -> \"%s\"",
+	    (conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename at openssh.com" :
+	    "SSH2_FXP_RENAME", oldpath, newpath);
 	buffer_free(&msg);
 
 	status = get_status(conn->fd_in, id);
@@ -686,6 +700,7 @@
 	return(status);
 }
 
+#ifdef notyet
 char *
 do_readlink(struct sftp_conn *conn, char *path)
 {
@@ -732,6 +747,7 @@
 
 	return(filename);
 }
+#endif
 
 static void
 send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
@@ -819,6 +835,7 @@
 	if (local_fd == -1) {
 		error("Couldn't open local file \"%s\" for writing: %s",
 		    local_path, strerror(errno));
+		do_close(conn, handle, handle_len);
 		buffer_free(&msg);
 		xfree(handle);
 		return(-1);
@@ -992,9 +1009,10 @@
 do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
     int pflag)
 {
-	int local_fd, status;
+	int local_fd;
+	int status = SSH2_FX_OK;
 	u_int handle_len, id, type;
-	u_int64_t offset;
+	off_t offset;
 	char *handle, *data;
 	Buffer msg;
 	struct stat sb;
@@ -1004,7 +1022,7 @@
 	struct outstanding_ack {
 		u_int id;
 		u_int len;
-		u_int64_t offset;
+		off_t offset;
 		TAILQ_ENTRY(outstanding_ack) tq;
 	};
 	TAILQ_HEAD(ackhead, outstanding_ack) acks;
@@ -1054,7 +1072,7 @@
 	if (handle == NULL) {
 		close(local_fd);
 		buffer_free(&msg);
-		return(-1);
+		return -1;
 	}
 
 	startid = ackid = id + 1;
@@ -1074,7 +1092,7 @@
 		 * Simulate an EOF on interrupt, allowing ACKs from the
 		 * server to drain.
 		 */
-		if (interrupted)
+		if (interrupted || status != SSH2_FX_OK)
 			len = 0;
 		else do
 			len = read(local_fd, data, conn->transfer_buflen);
@@ -1130,46 +1148,40 @@
 			if (ack == NULL)
 				fatal("Can't find request for ID %u", r_id);
 			TAILQ_REMOVE(&acks, ack, tq);
-
-			if (status != SSH2_FX_OK) {
-				error("Couldn't write to remote file \"%s\": %s",
-				    remote_path, fx2txt(status));
-				if (showprogress)
-					stop_progress_meter();
-				do_close(conn, handle, handle_len);
-				close(local_fd);
-				xfree(data);
-				xfree(ack);
-				status = -1;
-				goto done;
-			}
-			debug3("In write loop, ack for %u %u bytes at %llu",
-			    ack->id, ack->len, (unsigned long long)ack->offset);
+			debug3("In write loop, ack for %u %u bytes at %lld",
+			    ack->id, ack->len, (long long)ack->offset);
 			++ackid;
 			xfree(ack);
 		}
 		offset += len;
+		if (offset < 0)
+			fatal("%s: offset < 0", __func__);
 	}
+	buffer_free(&msg);
+
 	if (showprogress)
 		stop_progress_meter();
 	xfree(data);
 
+	if (status != SSH2_FX_OK) {
+		error("Couldn't write to remote file \"%s\": %s",
+		    remote_path, fx2txt(status));
+		status = -1;
+	}
+
 	if (close(local_fd) == -1) {
 		error("Couldn't close local file \"%s\": %s", local_path,
 		    strerror(errno));
-		do_close(conn, handle, handle_len);
 		status = -1;
-		goto done;
 	}
 
 	/* Override umask and utimes if asked */
 	if (pflag)
 		do_fsetstat(conn, handle, handle_len, &a);
 
-	status = do_close(conn, handle, handle_len);
-
-done:
+	if (do_close(conn, handle, handle_len) != SSH2_FX_OK)
+		status = -1;
 	xfree(handle);
-	buffer_free(&msg);
-	return(status);
+
+	return status;
 }
Index: sshconnect.h
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sshconnect.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -L crypto/openssh/sshconnect.h -L crypto/openssh/sshconnect.h -u -r1.3 -r1.4
--- crypto/openssh/sshconnect.h
+++ crypto/openssh/sshconnect.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.h,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: sshconnect.h,v 1.24 2007/09/04 11:15:56 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -33,10 +33,10 @@
 
 int
 ssh_connect(const char *, struct sockaddr_storage *, u_short, int, int,
-    int, const char *);
+    int *, int, int, const char *);
 
 void
-ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *);
+ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int);
 
 int	 verify_host_key(char *, struct sockaddr *, Key *);
 
Index: servconf.h
===================================================================
RCS file: /home/cvs/src/crypto/openssh/servconf.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/servconf.h -L crypto/openssh/servconf.h -u -r1.4 -r1.5
--- crypto/openssh/servconf.h
+++ crypto/openssh/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.80 2007/02/19 10:45:58 dtucker Exp $ */
+/* $OpenBSD: servconf.h,v 1.82 2008/02/13 22:38:17 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
@@ -36,6 +36,9 @@
 
 #define DEFAULT_AUTH_FAIL_MAX	6	/* Default for MaxAuthTries */
 
+/* Magic name for internal sftp-server */
+#define INTERNAL_SFTP_NAME	"internal-sftp"
+
 typedef struct {
 	u_int num_ports;
 	u_int ports_from_cmdline;
@@ -141,6 +144,8 @@
 	int	permit_tun;
 
 	int	num_permitted_opens;
+
+	char   *chroot_directory;
 }       ServerOptions;
 
 void	 initialize_server_options(ServerOptions *);
Index: sshconnect.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sshconnect.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/sshconnect.c -L crypto/openssh/sshconnect.c -u -r1.4 -r1.5
--- crypto/openssh/sshconnect.c
+++ crypto/openssh/sshconnect.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshconnect.c,v 1.200 2006/10/10 10:12:45 markus Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.203 2007/12/27 14:22:08 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -77,6 +77,23 @@
 static int show_other_keys(const char *, Key *);
 static void warn_changed_key(Key *);
 
+static void
+ms_subtract_diff(struct timeval *start, int *ms)
+{
+	struct timeval diff, finish;
+
+	gettimeofday(&finish, NULL);
+	timersub(&finish, start, &diff);	
+	*ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
+}
+
+static void
+ms_to_timeval(struct timeval *tv, int ms)
+{
+	tv->tv_sec = ms / 1000;
+	tv->tv_usec = (ms % 1000) * 1000;
+}
+
 /*
  * Connect to the given ssh server using a proxy command.
  */
@@ -86,7 +103,10 @@
 	char *command_string, *tmp;
 	int pin[2], pout[2];
 	pid_t pid;
-	char strport[NI_MAXSERV];
+	char *shell, strport[NI_MAXSERV];
+
+	if ((shell = getenv("SHELL")) == NULL)
+		shell = _PATH_BSHELL;
 
 	/* Convert the port number into a string. */
 	snprintf(strport, sizeof strport, "%hu", port);
@@ -132,7 +152,7 @@
 
 		/* Stderr is left as it is so that error messages get
 		   printed on the user's terminal. */
-		argv[0] = _PATH_BSHELL;
+		argv[0] = shell;
 		argv[1] = "-c";
 		argv[2] = command_string;
 		argv[3] = NULL;
@@ -204,7 +224,7 @@
 	gaierr = getaddrinfo(options.bind_address, "0", &hints, &res);
 	if (gaierr) {
 		error("getaddrinfo: %s: %s", options.bind_address,
-		    gai_strerror(gaierr));
+		    ssh_gai_strerror(gaierr));
 		close(sock);
 		return -1;
 	}
@@ -220,30 +240,36 @@
 
 static int
 timeout_connect(int sockfd, const struct sockaddr *serv_addr,
-    socklen_t addrlen, int timeout)
+    socklen_t addrlen, int *timeoutp)
 {
 	fd_set *fdset;
-	struct timeval tv;
+	struct timeval tv, t_start;
 	socklen_t optlen;
 	int optval, rc, result = -1;
 
-	if (timeout <= 0)
-		return (connect(sockfd, serv_addr, addrlen));
+	gettimeofday(&t_start, NULL);
+
+	if (*timeoutp <= 0) {
+		result = connect(sockfd, serv_addr, addrlen);
+		goto done;
+	}
 
 	set_nonblock(sockfd);
 	rc = connect(sockfd, serv_addr, addrlen);
 	if (rc == 0) {
 		unset_nonblock(sockfd);
-		return (0);
+		result = 0;
+		goto done;
+	}
+	if (errno != EINPROGRESS) {
+		result = -1;
+		goto done;
 	}
-	if (errno != EINPROGRESS)
-		return (-1);
 
 	fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
 	    sizeof(fd_mask));
 	FD_SET(sockfd, fdset);
-	tv.tv_sec = timeout;
-	tv.tv_usec = 0;
+	ms_to_timeval(&tv, *timeoutp);
 
 	for (;;) {
 		rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
@@ -282,6 +308,16 @@
 	}
 
 	xfree(fdset);
+
+ done:
+ 	if (result == 0 && *timeoutp > 0) {
+		ms_subtract_diff(&t_start, timeoutp);
+		if (*timeoutp <= 0) {
+			errno = ETIMEDOUT;
+			result = -1;
+		}
+	}
+
 	return (result);
 }
 
@@ -298,8 +334,8 @@
  */
 int
 ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
-    u_short port, int family, int connection_attempts,
-    int needpriv, const char *proxy_command)
+    u_short port, int family, int connection_attempts, int *timeout_ms,
+    int want_keepalive, int needpriv, const char *proxy_command)
 {
 	int gaierr;
 	int on = 1;
@@ -320,8 +356,8 @@
 	hints.ai_socktype = SOCK_STREAM;
 	snprintf(strport, sizeof strport, "%u", port);
 	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
-		fatal("%s: %.100s: %s", __progname, host,
-		    gai_strerror(gaierr));
+		fatal("%s: Could not resolve hostname %.100s: %s", __progname,
+		    host, ssh_gai_strerror(gaierr));
 
 	for (attempt = 0; attempt < connection_attempts; attempt++) {
 		if (attempt > 0) {
@@ -352,7 +388,7 @@
 				continue;
 
 			if (timeout_connect(sock, ai->ai_addr, ai->ai_addrlen,
-			    options.connection_timeout) >= 0) {
+			    timeout_ms) >= 0) {
 				/* Successful connection. */
 				memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
 				break;
@@ -379,7 +415,7 @@
 	debug("Connection established.");
 
 	/* Set SO_KEEPALIVE if requested. */
-	if (options.tcp_keep_alive &&
+	if (want_keepalive &&
 	    setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
 	    sizeof(on)) < 0)
 		error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
@@ -395,7 +431,7 @@
  * identification string.
  */
 static void
-ssh_exchange_identification(void)
+ssh_exchange_identification(int timeout_ms)
 {
 	char buf[256], remote_version[256];	/* must be same size! */
 	int remote_major, remote_minor, mismatch;
@@ -403,16 +439,44 @@
 	int connection_out = packet_get_connection_out();
 	int minor1 = PROTOCOL_MINOR_1;
 	u_int i, n;
+	size_t len;
+	int fdsetsz, remaining, rc;
+	struct timeval t_start, t_remaining;
+	fd_set *fdset;
+
+	fdsetsz = howmany(connection_in + 1, NFDBITS) * sizeof(fd_mask);
+	fdset = xcalloc(1, fdsetsz);
 
 	/* Read other side's version identification. */
+	remaining = timeout_ms;
 	for (n = 0;;) {
 		for (i = 0; i < sizeof(buf) - 1; i++) {
-			size_t len = atomicio(read, connection_in, &buf[i], 1);
+			if (timeout_ms > 0) {
+				gettimeofday(&t_start, NULL);
+				ms_to_timeval(&t_remaining, remaining);
+				FD_SET(connection_in, fdset);
+				rc = select(connection_in + 1, fdset, NULL,
+				    fdset, &t_remaining);
+				ms_subtract_diff(&t_start, &remaining);
+				if (rc == 0 || remaining <= 0)
+					fatal("Connection timed out during "
+					    "banner exchange");
+				if (rc == -1) {
+					if (errno == EINTR)
+						continue;
+					fatal("ssh_exchange_identification: "
+					    "select: %s", strerror(errno));
+				}
+			}
+
+			len = atomicio(read, connection_in, &buf[i], 1);
 
 			if (len != 1 && errno == EPIPE)
-				fatal("ssh_exchange_identification: Connection closed by remote host");
+				fatal("ssh_exchange_identification: "
+				    "Connection closed by remote host");
 			else if (len != 1)
-				fatal("ssh_exchange_identification: read: %.100s", strerror(errno));
+				fatal("ssh_exchange_identification: "
+				    "read: %.100s", strerror(errno));
 			if (buf[i] == '\r') {
 				buf[i] = '\n';
 				buf[i + 1] = 0;
@@ -423,7 +487,8 @@
 				break;
 			}
 			if (++n > 65536)
-				fatal("ssh_exchange_identification: No banner received");
+				fatal("ssh_exchange_identification: "
+				    "No banner received");
 		}
 		buf[sizeof(buf) - 1] = 0;
 		if (strncmp(buf, "SSH-", 4) == 0)
@@ -431,6 +496,7 @@
 		debug("ssh_exchange_identification: %s", buf);
 	}
 	server_version_string = xstrdup(buf);
+	xfree(fdset);
 
 	/*
 	 * Check that the versions match.  In future this might accept
@@ -943,7 +1009,7 @@
  */
 void
 ssh_login(Sensitive *sensitive, const char *orighost,
-    struct sockaddr *hostaddr, struct passwd *pw)
+    struct sockaddr *hostaddr, struct passwd *pw, int timeout_ms)
 {
 	char *host, *cp;
 	char *server_user, *local_user;
@@ -958,7 +1024,7 @@
 			*cp = (char)tolower(*cp);
 
 	/* Exchange protocol version identification strings with the server. */
-	ssh_exchange_identification();
+	ssh_exchange_identification(timeout_ms);
 
 	/* Put the connection into non-blocking mode. */
 	packet_set_nonblocking();
Index: kex.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/kex.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/kex.c -L crypto/openssh/kex.c -u -r1.4 -r1.5
--- crypto/openssh/kex.c
+++ crypto/openssh/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.77 2007/01/21 01:41:54 stevesk Exp $ */
+/* $OpenBSD: kex.c,v 1.79 2007/06/05 06:52:37 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  *
@@ -87,7 +87,7 @@
 kex_buf2prop(Buffer *raw, int *first_kex_follows)
 {
 	Buffer b;
-	int i;
+	u_int i;
 	char **proposal;
 
 	proposal = xcalloc(PROPOSAL_MAX, sizeof(char *));
@@ -108,7 +108,7 @@
 		*first_kex_follows = i;
 	debug2("kex_parse_kexinit: first_kex_follows %d ", i);
 	i = buffer_get_int(&b);
-	debug2("kex_parse_kexinit: reserved %d ", i);
+	debug2("kex_parse_kexinit: reserved %u ", i);
 	buffer_free(&b);
 	return proposal;
 }
@@ -123,6 +123,7 @@
 	xfree(proposal);
 }
 
+/* ARGSUSED */
 static void
 kex_protocol_error(int type, u_int32_t seq, void *ctxt)
 {
@@ -194,6 +195,7 @@
 	kex->flags |= KEX_INIT_SENT;
 }
 
+/* ARGSUSED */
 void
 kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
 {
@@ -258,7 +260,8 @@
 {
 	char *name = match_list(client, server, NULL);
 	if (name == NULL)
-		fatal("no matching cipher found: client %s server %s", client, server);
+		fatal("no matching cipher found: client %s server %s",
+		    client, server);
 	if ((enc->cipher = cipher_by_name(name)) == NULL)
 		fatal("matching cipher is not supported: %s", name);
 	enc->name = name;
@@ -274,8 +277,9 @@
 {
 	char *name = match_list(client, server, NULL);
 	if (name == NULL)
-		fatal("no matching mac found: client %s server %s", client, server);
-	if (mac_init(mac, name) < 0)
+		fatal("no matching mac found: client %s server %s",
+		    client, server);
+	if (mac_setup(mac, name) < 0)
 		fatal("unsupported mac %s", name);
 	/* truncate the key */
 	if (datafellows & SSH_BUG_HMAC)
@@ -308,7 +312,7 @@
 {
 	k->name = match_list(client, server, NULL);
 	if (k->name == NULL)
-		fatal("no kex alg");
+		fatal("Unable to negotiate a key exchange method");
 	if (strcmp(k->name, KEX_DH1) == 0) {
 		k->kex_type = KEX_DH_GRP1_SHA1;
 		k->evp_md = EVP_sha1();
@@ -388,7 +392,8 @@
 	for (mode = 0; mode < MODE_MAX; mode++) {
 		newkeys = xcalloc(1, sizeof(*newkeys));
 		kex->newkeys[mode] = newkeys;
-		ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
+		ctos = (!kex->server && mode == MODE_OUT) ||
+		    (kex->server && mode == MODE_IN);
 		nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
 		nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
 		ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
Index: sshd_config
===================================================================
RCS file: /home/cvs/src/crypto/openssh/sshd_config,v
retrieving revision 1.6
retrieving revision 1.7
diff -L crypto/openssh/sshd_config -L crypto/openssh/sshd_config -u -r1.6 -r1.7
--- crypto/openssh/sshd_config
+++ crypto/openssh/sshd_config
@@ -1,5 +1,5 @@
-#	$OpenBSD: sshd_config,v 1.74 2006/07/19 13:07:10 dtucker Exp $
-# $MidnightBSD$
+# 	$MidnightBSD$
+#	$OpenBSD: sshd_config,v 1.77 2008/02/08 23:24:07 djm Exp $
 
 # This is the sshd server system-wide configuration file.  See
 # sshd_config(5) for more information.
@@ -12,11 +12,15 @@
 # default value.
 
 #Port 22
-#Protocol 2,1
 #AddressFamily any
 #ListenAddress 0.0.0.0
 #ListenAddress ::
 
+# Disable legacy (protocol version 1) support in the server for new
+# installations. In future the default will change to require explicit
+# activation of protocol 1
+Protocol 2
+
 # HostKey for protocol version 1
 #HostKey /etc/ssh/ssh_host_key
 # HostKeys for protocol version 2
@@ -99,9 +103,10 @@
 #PidFile /var/run/sshd.pid
 #MaxStartups 10
 #PermitTunnel no
+#ChrootDirectory none
 
 # no default banner path
-#Banner /some/path
+#Banner none
 
 # override default of no subsystems
 Subsystem	sftp	/usr/libexec/sftp-server
Index: session.c
===================================================================
RCS file: /home/cvs/src/crypto/openssh/session.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -L crypto/openssh/session.c -L crypto/openssh/session.c -u -r1.4 -r1.5
--- crypto/openssh/session.c
+++ crypto/openssh/session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.c,v 1.221 2007/01/21 01:41:54 stevesk Exp $ */
+/* $OpenBSD: session.c,v 1.233 2008/03/26 21:28:14 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -84,9 +84,11 @@
 #include "sshlogin.h"
 #include "serverloop.h"
 #include "canohost.h"
+#include "misc.h"
 #include "session.h"
 #include "kex.h"
 #include "monitor_wrap.h"
+#include "sftp.h"
 
 #if defined(KRB5) && defined(USE_AFS)
 #include <kafs.h>
@@ -129,9 +131,13 @@
 const char *original_command = NULL;
 
 /* data */
-#define MAX_SESSIONS 10
+#define MAX_SESSIONS 20
 Session	sessions[MAX_SESSIONS];
 
+#define SUBSYSTEM_NONE		0
+#define SUBSYSTEM_EXT		1
+#define SUBSYSTEM_INT_SFTP	2
+
 #ifdef HAVE_LOGIN_CAP
 login_cap_t *lc;
 #endif
@@ -422,11 +428,6 @@
 
 	session_proctitle(s);
 
-#if defined(USE_PAM)
-	if (options.use_pam && !use_privsep)
-		do_pam_setcred(1);
-#endif /* USE_PAM */
-
 	/* Fork the child. */
 	if ((pid = fork()) == 0) {
 		is_child = 1;
@@ -557,14 +558,6 @@
 	ptyfd = s->ptyfd;
 	ttyfd = s->ttyfd;
 
-#if defined(USE_PAM)
-	if (options.use_pam) {
-		do_pam_set_tty(s->tty);
-		if (!use_privsep)
-			do_pam_setcred(1);
-	}
-#endif
-
 	/* Fork the child. */
 	if ((pid = fork()) == 0) {
 		is_child = 1;
@@ -683,10 +676,18 @@
 	if (options.adm_forced_command) {
 		original_command = command;
 		command = options.adm_forced_command;
+		if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
+			s->is_subsystem = SUBSYSTEM_INT_SFTP;
+		else if (s->is_subsystem)
+			s->is_subsystem = SUBSYSTEM_EXT;
 		debug("Forced command (config) '%.900s'", command);
 	} else if (forced_command) {
 		original_command = command;
 		command = forced_command;
+		if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
+			s->is_subsystem = SUBSYSTEM_INT_SFTP;
+		else if (s->is_subsystem)
+			s->is_subsystem = SUBSYSTEM_EXT;
 		debug("Forced command (key option) '%.900s'", command);
 	}
 
@@ -701,7 +702,6 @@
 		PRIVSEP(audit_run_command(shell));
 	}
 #endif
-
 	if (s->ttyfd != -1)
 		do_exec_pty(s, command);
 	else
@@ -897,8 +897,9 @@
 			;
 		if (!*cp || *cp == '#' || *cp == '\n')
 			continue;
-		if (strchr(cp, '\n'))
-			*strchr(cp, '\n') = '\0';
+
+		cp[strcspn(cp, "\n")] = '\0';
+
 		value = strchr(cp, '=');
 		if (value == NULL) {
 			fprintf(stderr, "Bad line %u in %.100s\n", lineno,
@@ -1201,8 +1202,9 @@
 	do_xauth =
 	    s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
 
-	/* ignore _PATH_SSH_USER_RC for subsystems */
-	if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
+	/* 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)) {
 		snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
 		    shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
 		if (debug_flag)
@@ -1283,10 +1285,72 @@
 	}
 }
 
+/*
+ * Chroot into a directory after checking it for safety: all path components
+ * must be root-owned directories with strict permissions.
+ */
+static void
+safely_chroot(const char *path, uid_t uid)
+{
+	const char *cp;
+	char component[MAXPATHLEN];
+	struct stat st;
+
+	if (*path != '/')
+		fatal("chroot path does not begin at root");
+	if (strlen(path) >= sizeof(component))
+		fatal("chroot path too long");
+
+	/*
+	 * Descend the path, checking that each component is a
+	 * root-owned directory with strict permissions.
+	 */
+	for (cp = path; cp != NULL;) {
+		if ((cp = strchr(cp, '/')) == NULL)
+			strlcpy(component, path, sizeof(component));
+		else {
+			cp++;
+			memcpy(component, path, cp - path);
+			component[cp - path] = '\0';
+		}
+	
+		debug3("%s: checking '%s'", __func__, component);
+
+		if (stat(component, &st) != 0)
+			fatal("%s: stat(\"%s\"): %s", __func__,
+			    component, strerror(errno));
+		if (st.st_uid != 0 || (st.st_mode & 022) != 0)
+			fatal("bad ownership or modes for chroot "
+			    "directory %s\"%s\"", 
+			    cp == NULL ? "" : "component ", component);
+		if (!S_ISDIR(st.st_mode))
+			fatal("chroot path %s\"%s\" is not a directory",
+			    cp == NULL ? "" : "component ", component);
+
+	}
+
+	if (chdir(path) == -1)
+		fatal("Unable to chdir to chroot path \"%s\": "
+		    "%s", path, strerror(errno));
+	if (chroot(path) == -1)
+		fatal("chroot(\"%s\"): %s", path, strerror(errno));
+	if (chdir("/") == -1)
+		fatal("%s: chdir(/) after chroot: %s",
+		    __func__, strerror(errno));
+	verbose("Changed root directory to \"%s\"", path);
+}
+
 /* Set login name, uid, gid, and groups. */
 void
 do_setusercontext(struct passwd *pw)
 {
+	char *chroot_path, *tmp;
+
+#ifdef WITH_SELINUX
+	/* Cache selinux status for later use */
+	(void)ssh_selinux_enabled();
+#endif
+
 #ifndef HAVE_CYGWIN
 	if (getuid() == 0 || geteuid() == 0)
 #endif /* HAVE_CYGWIN */
@@ -1300,21 +1364,13 @@
 # ifdef __bsdi__
 		setpgid(0, 0);
 # endif
-#ifdef GSSAPI
-		if (options.gss_authentication) {
-			temporarily_use_uid(pw);
-			ssh_gssapi_storecreds();
-			restore_uid();
-		}
-#endif
 # ifdef USE_PAM
 		if (options.use_pam) {
-			do_pam_session();
-			do_pam_setcred(0);
+			do_pam_setcred(use_privsep);
 		}
 # endif /* USE_PAM */
 		if (setusercontext(lc, pw, pw->pw_uid,
-		    (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
+		    (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
 			perror("unable to set user context");
 			exit(1);
 		}
@@ -1337,13 +1393,6 @@
 			exit(1);
 		}
 		endgrent();
-#ifdef GSSAPI
-		if (options.gss_authentication) {
-			temporarily_use_uid(pw);
-			ssh_gssapi_storecreds();
-			restore_uid();
-		}
-#endif
 # ifdef USE_PAM
 		/*
 		 * PAM credentials may take the form of supplementary groups.
@@ -1351,21 +1400,39 @@
 		 * Reestablish them here.
 		 */
 		if (options.use_pam) {
-			do_pam_session();
-			do_pam_setcred(0);
+			do_pam_setcred(use_privsep);
 		}
 # endif /* USE_PAM */
 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
 		irix_setusercontext(pw);
-#  endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
+# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
 # ifdef _AIX
 		aix_usrinfo(pw);
 # endif /* _AIX */
-#if defined(HAVE_LIBIAF)  &&  !defined(BROKEN_LIBIAF)
+# ifdef USE_LIBIAF
 		if (set_id(pw->pw_name) != 0) {
 			exit(1);
 		}
-#endif /* HAVE_LIBIAF  && !BROKEN_LIBIAF */
+# endif /* USE_LIBIAF */
+#endif
+
+		if (options.chroot_directory != NULL &&
+		    strcasecmp(options.chroot_directory, "none") != 0) {
+                        tmp = tilde_expand_filename(options.chroot_directory,
+			    pw->pw_uid);
+			chroot_path = percent_expand(tmp, "h", pw->pw_dir,
+			    "u", pw->pw_name, (char *)NULL);
+			safely_chroot(chroot_path, pw->pw_uid);
+			free(tmp);
+			free(chroot_path);
+		}
+
+#ifdef HAVE_LOGIN_CAP
+		if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
+			perror("unable to set user context (setuser)");
+			exit(1);
+		}
+#else
 		/* Permanently switch to the desired uid. */
 		permanently_set_uid(pw);
 #endif
@@ -1464,12 +1531,13 @@
  * environment, closing extra file descriptors, setting the user and group
  * ids, and executing the command or shell.
  */
+#define ARGV_MAX 10
 void
 do_child(Session *s, const char *command)
 {
 	extern char **environ;
 	char **env;
-	char *argv[10];
+	char *argv[ARGV_MAX];
 	const char *shell, *shell0, *hostname = NULL;
 	struct passwd *pw = s->pw;
 
@@ -1595,12 +1663,30 @@
 #endif
 	}
 
+	closefrom(STDERR_FILENO + 1);
+
 	if (!options.use_login)
 		do_rc_files(s, shell);
 
 	/* restore SIGPIPE for child */
 	signal(SIGPIPE, SIG_DFL);
 
+	if (s->is_subsystem == SUBSYSTEM_INT_SFTP) {
+		extern int optind, optreset;
+		int i;
+		char *p, *args;
+
+		setproctitle("%