Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37402913
en ru br
Репозитории ALT
S:9.4p1-alt1
5.1: 5.3p1-alt1
4.1: 5.0p1-alt3
4.0: 5.0p1-alt3
+updates:4.7p1-alt1
3.0: 3.6.1p2-alt6
www.altlinux.org/Changes

Группа :: Сети/Удалённый доступ
Пакет: openssh

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: openssh-5.0p1-alt3.patch
Скачать


 Makefile.in                     |    6 +-
 auth-options.c                  |   11 ++-
 auth-options.h                  |    2 +-
 auth-pam.c                      |   41 +++---
 auth-rh-rsa.c                   |    4 +
 auth-rsa.c                      |   22 +++-
 auth.c                          |   20 +++-
 auth.h                          |    2 +
 auth1.c                         |   12 +-
 auth2-hostbased.c               |    4 +
 auth2-pubkey.c                  |   62 +++++++++-
 auth2.c                         |    8 +-
 blacklist.c                     |  267 +++++++++++++++++++++++++++++++++++++++
 blacklist.h                     |   37 ++++++
 channels.c                      |    6 +
 clientloop.c                    |   16 ++-
 entropy.c                       |    8 +-
 log.c                           |   35 +++++-
 log.h                           |    1 +
 mac.c                           |    4 +-
 monitor.c                       |    2 +-
 monitor_mm.c                    |    1 +
 myproposal.h                    |    9 +-
 openbsd-compat/Makefile.in      |    2 +-
 openbsd-compat/getpeerproc.c    |   74 +++++++++++
 openbsd-compat/openbsd-compat.h |    2 +
 openbsd-compat/xmmap.c          |    8 +-
 pathnames.h                     |    4 +
 progressmeter.c                 |    2 +-
 readconf.c                      |    8 +-
 scard-opensc.c                  |    2 +-
 scp.c                           |    4 +-
 servconf.c                      |   76 ++++++++++--
 servconf.h                      |    3 +
 sftp-server.0                   |    4 +-
 sftp-server.8                   |    4 +-
 sftp-server.c                   |    4 +
 sftp.c                          |    4 +-
 ssh-agent.1                     |   11 ++-
 ssh-agent.c                     |  146 +++++++++++++++------
 ssh-keygen.1                    |    2 +-
 ssh-keygen.c                    |    4 +-
 ssh-keyscan.c                   |    4 +-
 ssh.0                           |   31 +++---
 ssh.1                           |   18 ++--
 ssh.c                           |    4 +-
 ssh_config                      |   10 +-
 ssh_config.0                    |   15 ++-
 ssh_config.5                    |   17 ++--
 sshconnect.c                    |    5 +-
 sshconnect1.c                   |    2 +-
 sshd.0                          |    4 +-
 sshd.8                          |    1 -
 sshd.c                          |   25 ++++-
 sshd_config                     |   29 +++--
 sshd_config.0                   |   32 +++---
 sshd_config.5                   |   81 ++++++++++---
 57 files changed, 980 insertions(+), 242 deletions(-)
diff --git a/Makefile.in b/Makefile.in
index 6b488fe..6c3c595 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -62,7 +62,7 @@ INSTALL_SSH_RAND_HELPER=@INSTALL_SSH_RAND_HELPER@
 
 TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-agent$(EXEEXT) scp$(EXEEXT) ssh-rand-helper${EXEEXT} sftp-server$(EXEEXT) sftp$(EXEEXT)
 
-LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
+LIBSSH_OBJS=acss.o authfd.o authfile.o blacklist.o bufaux.o bufbn.o buffer.o \
 	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
 	cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
 	compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
@@ -280,9 +280,9 @@ install-files: scard-install
 	$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8
 	$(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8
 	-rm -f $(DESTDIR)$(bindir)/slogin
-	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
+	ln -s ssh$(git-EXEEXT) $(DESTDIR)$(bindir)/slogin
 	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
-	ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
+	ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
 
 install-sysconf:
 	if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
diff --git a/auth-options.c b/auth-options.c
index 6e22569..934414b 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -83,7 +83,7 @@ auth_clear_options(void)
  * side effect: sets key option flags
  */
 int
-auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
+auth_parse_options(struct passwd *pw, char *opts, const char *file, u_long linenum)
 {
 	const char *cp;
 	int i;
@@ -97,6 +97,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 	while (*opts && *opts != ' ' && *opts != '\t') {
 		cp = "no-port-forwarding";
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+			debug("Port forwarding disabled.");
 			auth_debug_add("Port forwarding disabled.");
 			no_port_forwarding_flag = 1;
 			opts += strlen(cp);
@@ -104,6 +105,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 		}
 		cp = "no-agent-forwarding";
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+			debug("Agent forwarding disabled.");
 			auth_debug_add("Agent forwarding disabled.");
 			no_agent_forwarding_flag = 1;
 			opts += strlen(cp);
@@ -111,6 +113,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 		}
 		cp = "no-X11-forwarding";
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+			debug("X11 forwarding disabled.");
 			auth_debug_add("X11 forwarding disabled.");
 			no_x11_forwarding_flag = 1;
 			opts += strlen(cp);
@@ -118,6 +121,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 		}
 		cp = "no-pty";
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+			debug("Pty allocation disabled.");
 			auth_debug_add("Pty allocation disabled.");
 			no_pty_flag = 1;
 			opts += strlen(cp);
@@ -125,6 +129,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 		}
 		cp = "no-user-rc";
 		if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+			debug("User rc file execution disabled.");
 			auth_debug_add("User rc file execution disabled.");
 			no_user_rc = 1;
 			opts += strlen(cp);
@@ -155,6 +160,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 				goto bad_option;
 			}
 			forced_command[i] = '\0';
+			debug("Forced command: %.900s", forced_command);
 			auth_debug_add("Forced command: %.900s", forced_command);
 			opts++;
 			goto next_option;
@@ -187,8 +193,8 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 				goto bad_option;
 			}
 			s[i] = '\0';
-			auth_debug_add("Adding to environment: %.900s", s);
 			debug("Adding to environment: %.900s", s);
+			auth_debug_add("Adding to environment: %.900s", s);
 			opts++;
 			new_envstring = xmalloc(sizeof(struct envstring));
 			new_envstring->s = s;
@@ -327,6 +333,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
 				forced_tun_device = -1;
 				goto bad_option;
 			}
+			debug("Forced tun device: %d", forced_tun_device);
 			auth_debug_add("Forced tun device: %d", forced_tun_device);
 			opts++;
 			goto next_option;
diff --git a/auth-options.h b/auth-options.h
index 14488f7..f7495af 100644
--- a/auth-options.h
+++ b/auth-options.h
@@ -31,7 +31,7 @@ extern char *forced_command;
 extern struct envstring *custom_environment;
 extern int forced_tun_device;
 
-int	auth_parse_options(struct passwd *, char *, char *, u_long);
+int	auth_parse_options(struct passwd *, char *, const char *, u_long);
 void	auth_clear_options(void);
 
 #endif
diff --git a/auth-pam.c b/auth-pam.c
index ccdb993..dac8d2c 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -65,6 +65,8 @@
 #include <pam/pam_appl.h>
 #endif
 
+#include <security/pam_userpass.h>
+
 /* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */
 #ifdef PAM_SUN_CODEBASE
 # define sshpam_const		/* Solaris, HP-UX, AIX */
@@ -230,7 +232,7 @@ static int sshpam_cred_established = 0;
 static int sshpam_account_status = -1;
 static char **sshpam_env = NULL;
 static Authctxt *sshpam_authctxt = NULL;
-static const char *sshpam_password = NULL;
+static pam_userpass_t sshpam_userpass;
 static char badpw[] = "\b\n\r\177INCORRECT";
 
 /* Some PAM implementations don't implement this */
@@ -607,11 +609,11 @@ sshpam_cleanup(void)
 		pam_setcred(sshpam_handle, PAM_DELETE_CRED);
 		sshpam_cred_established = 0;
 	}
-	if (sshpam_session_open) {
+	if (getpid() == sshpam_session_open) {
 		debug("PAM: closing session");
 		pam_close_session(sshpam_handle, PAM_SILENT);
-		sshpam_session_open = 0;
 	}
+	sshpam_session_open = 0;
 	sshpam_authenticated = 0;
 	pam_end(sshpam_handle, sshpam_err);
 	sshpam_handle = NULL;
@@ -794,8 +796,9 @@ sshpam_query(void *ctx, char **name, char **info,
 				return (0);
 			}
 			error("PAM: %s for %s%.100s from %.100s", msg,
-			    sshpam_authctxt->valid ? "" : "illegal user ",
-			    sshpam_authctxt->user,
+			    !sshpam_authctxt->valid ? "UNKNOWN USER" :
+				(sshpam_authctxt->pw->pw_uid == 0 ? "ROOT USER " : ""),
+			    sshpam_authctxt->valid ? sshpam_authctxt->user : "",
 			    get_remote_name_or_ip(utmp_len, options.use_dns));
 			/* FALLTHROUGH */
 		default:
@@ -1047,7 +1050,7 @@ do_pam_session(void)
 		    pam_strerror(sshpam_handle, sshpam_err));
 	sshpam_err = pam_open_session(sshpam_handle, 0);
 	if (sshpam_err == PAM_SUCCESS)
-		sshpam_session_open = 1;
+		sshpam_session_open = getpid();
 	else {
 		sshpam_session_open = 0;
 		disable_forwarding();
@@ -1132,18 +1135,15 @@ sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
 	if (n <= 0 || n > PAM_MAX_NUM_MSG)
 		return (PAM_CONV_ERR);
 
+	i = pam_userpass_conv(n, msg, resp, data);
+	if (i != PAM_CONV_ERR)
+		return i;
+
 	if ((reply = calloc(n, sizeof(*reply))) == NULL)
 		return (PAM_CONV_ERR);
 
 	for (i = 0; i < n; ++i) {
 		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
-		case PAM_PROMPT_ECHO_OFF:
-			if (sshpam_password == NULL)
-				goto fail;
-			if ((reply[i].resp = strdup(sshpam_password)) == NULL)
-				goto fail;
-			reply[i].resp_retcode = PAM_SUCCESS;
-			break;
 		case PAM_ERROR_MSG:
 		case PAM_TEXT_INFO:
 			len = strlen(PAM_MSG_MEMBER(msg, i, msg));
@@ -1172,7 +1172,7 @@ sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
 	return (PAM_CONV_ERR);
 }
 
-static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL };
+static struct pam_conv passwd_conv = { sshpam_passwd_conv, &sshpam_userpass };
 
 /*
  * Attempt password authentication via PAM
@@ -1187,9 +1187,6 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
 		fatal("PAM: %s called when PAM disabled or failed to "
 		    "initialise.", __func__);
 
-	sshpam_password = password;
-	sshpam_authctxt = authctxt;
-
 	/*
 	 * If the user logging in is invalid, or is root but is not permitted
 	 * by PermitRootLogin, use an invalid password to prevent leaking
@@ -1197,7 +1194,11 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
 	 */
 	if (!authctxt->valid || (authctxt->pw->pw_uid == 0 &&
 	    options.permit_root_login != PERMIT_YES))
-		sshpam_password = badpw;
+		password = badpw;
+
+	sshpam_userpass.user = authctxt->valid ? authctxt->user : "UNKNOWN USER";
+	sshpam_userpass.pass = password;
+	sshpam_authctxt = authctxt;
 
 	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
 	    (const void *)&passwd_conv);
@@ -1206,14 +1207,14 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
 		    pam_strerror(sshpam_handle, sshpam_err));
 
 	sshpam_err = pam_authenticate(sshpam_handle, flags);
-	sshpam_password = NULL;
+	sshpam_userpass.user = sshpam_userpass.pass = NULL;
 	if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
 		debug("PAM: password authentication accepted for %.100s",
 		    authctxt->user);
 		return 1;
 	} else {
 		debug("PAM: password authentication failed for %.100s: %s",
-		    authctxt->valid ? authctxt->user : "an illegal user",
+		    authctxt->valid ? authctxt->user : "UNKNOWN USER",
 		    pam_strerror(sshpam_handle, sshpam_err));
 		return 0;
 	}
diff --git a/auth-rh-rsa.c b/auth-rh-rsa.c
index eca7502..94e6f23 100644
--- a/auth-rh-rsa.c
+++ b/auth-rh-rsa.c
@@ -34,6 +34,7 @@
 #include "ssh-gss.h"
 #endif
 #include "monitor_wrap.h"
+#include "blacklist.h"
 
 /* import */
 extern ServerOptions options;
@@ -48,6 +49,9 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
 	if (!auth_rhosts(pw, cuser))
 		return 0;
 
+	if (blacklisted_key(client_host_key, 0))
+		return 0;
+
 	host_status = check_key_in_hostfiles(pw, client_host_key,
 	    chost, _PATH_SSH_SYSTEM_HOSTFILE,
 	    options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
diff --git a/auth-rsa.c b/auth-rsa.c
index 69f9a58..dd036b1 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -47,6 +47,7 @@
 #include "monitor_wrap.h"
 #include "ssh.h"
 #include "misc.h"
+#include "blacklist.h"
 
 /* import */
 extern ServerOptions options;
@@ -180,15 +181,21 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
 	temporarily_use_uid(pw);
 
 	/* The authorized keys. */
-	file = authorized_keys_file(pw);
-	debug("trying public RSA key file %s", file);
+	file = authorized_keys_system_file(pw);
+	debug("trying public RSA key system file %s", file);
 
-	/* Fail quietly if file does not exist */
 	if (stat(file, &st) < 0) {
-		/* Restore the privileged uid. */
-		restore_uid();
 		xfree(file);
-		return (0);
+		file = authorized_keys_file(pw);
+		debug("trying public RSA key user file %s", file);
+
+		/* Fail quietly if file does not exist */
+		if (stat(file, &st) < 0) {
+			/* Restore the privileged uid. */
+			restore_uid();
+			xfree(file);
+			return (0);
+		}
 	}
 	/* Open the file containing the authorized keys. */
 	f = fopen(file, "r");
@@ -265,6 +272,9 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
 			    "actual %d vs. announced %d.",
 			    file, linenum, BN_num_bits(key->rsa->n), bits);
 
+		if (blacklisted_key(key, 0))
+			continue;
+
 		/* We have found the desired key. */
 		/*
 		 * If our options do not allow this key to be used,
diff --git a/auth.c b/auth.c
index f94c7d1..358a1a2 100644
--- a/auth.c
+++ b/auth.c
@@ -267,8 +267,9 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
 	authlog("%s %s for %s%.100s from %.200s port %d%s",
 	    authmsg,
 	    method,
-	    authctxt->valid ? "" : "invalid user ",
-	    authctxt->user,
+	    !authctxt->valid ? "UNKNOWN USER" :
+		(authctxt->pw->pw_uid == 0 ? "ROOT USER " : ""),
+	    authctxt->valid ? authctxt->user : "",
 	    get_remote_ipaddr(),
 	    get_remote_port(),
 	    info);
@@ -359,6 +360,18 @@ authorized_keys_file2(struct passwd *pw)
 	return expand_authorized_keys(options.authorized_keys_file2, pw);
 }
 
+char *
+authorized_keys_system_file(struct passwd *pw)
+{
+	return expand_authorized_keys(options.authorized_keys_system_file, pw);
+}
+
+char *
+authorized_keys_system_file2(struct passwd *pw)
+{
+	return expand_authorized_keys(options.authorized_keys_system_file2, pw);
+}
+
 /* return ok if key exists in sysfile or userfile */
 HostStatus
 check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
@@ -486,8 +499,7 @@ getpwnamallow(const char *user)
 
 	pw = getpwnam(user);
 	if (pw == NULL) {
-		logit("Invalid user %.100s from %.100s",
-		    user, get_remote_ipaddr());
+		logit("UNKNOWN USER from %.100s", get_remote_ipaddr());
 #ifdef CUSTOM_FAILED_LOGIN
 		record_failed_login(user,
 		    get_canonical_hostname(options.use_dns), "ssh");
diff --git a/auth.h b/auth.h
index f752c12..d98c23a 100644
--- a/auth.h
+++ b/auth.h
@@ -165,6 +165,8 @@ void	abandon_challenge_response(Authctxt *);
 
 char	*authorized_keys_file(struct passwd *);
 char	*authorized_keys_file2(struct passwd *);
+char	*authorized_keys_system_file(struct passwd *);
+char	*authorized_keys_system_file2(struct passwd *);
 
 int
 secure_filename(FILE *, const char *, struct passwd *, char *, size_t);
diff --git a/auth1.c b/auth1.c
index c17cc91..b1ab54c 100644
--- a/auth1.c
+++ b/auth1.c
@@ -240,7 +240,9 @@ do_authloop(Authctxt *authctxt)
 	const struct AuthMethod1 *meth;
 
 	debug("Attempting authentication for %s%.100s.",
-	    authctxt->valid ? "" : "invalid user ", authctxt->user);
+	    !authctxt->valid ? "UNKNOWN USER" :
+		(authctxt->pw->pw_uid == 0 ? "ROOT USER " : ""),
+	    authctxt->valid ? authctxt->user : "");
 
 	/* If the user has no password, accept authentication immediately. */
 	if (options.password_authentication &&
@@ -305,8 +307,7 @@ do_authloop(Authctxt *authctxt)
 		}
 #endif
 		if (!authctxt->valid && authenticated)
-			fatal("INTERNAL ERROR: authenticated invalid user %s",
-			    authctxt->user);
+			fatal("INTERNAL ERROR: authenticated UNKNOWN USER");
 
 #ifdef _UNICOS
 		if (authenticated && cray_access_denied(authctxt->user)) {
@@ -407,11 +408,12 @@ do_authentication(Authctxt *authctxt)
 	if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
 		authctxt->valid = 1;
 	else {
-		debug("do_authentication: invalid user %s", user);
+		debug("do_authentication: UNKNOWN USER");
 		authctxt->pw = fakepw();
+		authctxt->valid = 0;
 	}
 
-	setproctitle("%s%s", authctxt->valid ? user : "unknown",
+	setproctitle("%s%s", authctxt->valid ? user : "UNKNOWN USER",
 	    use_privsep ? " [net]" : "");
 
 #ifdef USE_PAM
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
index 663dec5..d2ee98a 100644
--- a/auth2-hostbased.c
+++ b/auth2-hostbased.c
@@ -47,6 +47,7 @@
 #endif
 #include "monitor_wrap.h"
 #include "pathnames.h"
+#include "blacklist.h"
 
 /* import */
 extern ServerOptions options;
@@ -145,6 +146,9 @@ hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
 	HostStatus host_status;
 	int len;
 
+	if (blacklisted_key(key, 0))
+		return 0;
+
 	resolvedname = get_canonical_hostname(options.use_dns);
 	ipaddr = get_remote_ipaddr();
 
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 9863cd9..37dbaf7 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -52,6 +52,7 @@
 #endif
 #include "monitor_wrap.h"
 #include "misc.h"
+#include "blacklist.h"
 
 /* import */
 extern ServerOptions options;
@@ -266,8 +267,8 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
 }
 
 /* check whether given key is in .ssh/authorized_keys* */
-int
-user_key_allowed(struct passwd *pw, Key *key)
+static int
+check_user_key_allowed(struct passwd *pw, Key *key)
 {
 	int success;
 	char *file;
@@ -285,6 +286,63 @@ user_key_allowed(struct passwd *pw, Key *key)
 	return success;
 }
 
+/* check whether given key is in /etc/openssh/authorized_keys* */
+static int
+check_system_key_allowed(struct passwd *pw, Key *key, int *found)
+{
+	int success = 0;
+	char *file;
+	struct stat st;
+
+	*found = 0;
+	file = authorized_keys_system_file(pw);
+	debug("checking public key system file %s", file);
+	if (stat(file, &st) == 0) {
+		*found = 1;
+		success = user_key_allowed2(pw, key, file);
+		xfree(file);
+		if (success)
+			return success;
+	} else
+		xfree(file);
+
+	/* try suffix "2" for backward compat, too */
+	file = authorized_keys_system_file2(pw);
+	debug("checking public key system file2 %s", file);
+	if (stat(file, &st) == 0) {
+		*found = 1;
+		success = user_key_allowed2(pw, key, file);
+		xfree(file);
+		return success;
+	}
+	xfree(file);
+
+	return success;
+}
+
+/*
+ * check whether given key is in /etc/openssh/authorized_keys*
+ * if not found, check whether given key is in .ssh/authorized_keys*
+ */
+int
+user_key_allowed(struct passwd *pw, Key *key)
+{
+	int found, success;
+
+	/* no user given */
+	if (!pw)
+		return 0;
+
+	if (blacklisted_key(key, 0))
+		return 0;
+
+	success = check_system_key_allowed(pw, key, &found);
+	if (!found)
+		success = check_user_key_allowed(pw, key);
+
+	return success;
+}
+
 Authmethod method_pubkey = {
 	"publickey",
 	userauth_pubkey,
diff --git a/auth2.c b/auth2.c
index 03d7f09..a21fd0a 100644
--- a/auth2.c
+++ b/auth2.c
@@ -163,8 +163,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
 			authctxt->valid = 1;
 			debug2("input_userauth_request: setting up authctxt for %s", user);
 		} else {
-			logit("input_userauth_request: invalid user %s", user);
+			logit("input_userauth_request: UNKNOWN USER");
 			authctxt->pw = fakepw();
+			authctxt->valid = 0;
 #ifdef SSH_AUDIT_EVENTS
 			PRIVSEP(audit_event(SSH_INVALID_USER));
 #endif
@@ -173,7 +174,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
 		if (options.use_pam)
 			PRIVSEP(start_pam(authctxt));
 #endif
-		setproctitle("%s%s", authctxt->valid ? user : "unknown",
+		setproctitle("%s%s", authctxt->valid ? user : "UNKNOWN USER",
 		    use_privsep ? " [net]" : "");
 		authctxt->service = xstrdup(service);
 		authctxt->style = style ? xstrdup(style) : NULL;
@@ -214,8 +215,7 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
 	char *methods;
 
 	if (!authctxt->valid && authenticated)
-		fatal("INTERNAL ERROR: authenticated invalid user %s",
-		    authctxt->user);
+		fatal("INTERNAL ERROR: authenticated UNKNOWN USER");
 
 	/* Special handling for root */
 	if (authenticated && authctxt->pw->pw_uid == 0 &&
diff --git a/blacklist.c b/blacklist.c
new file mode 100644
index 0000000..89eff83
--- /dev/null
+++ b/blacklist.c
@@ -0,0 +1,267 @@
+/*
+ * Support for RSA/DSA key blacklisting based on partial fingerprints,
+ * developed under Openwall Project for Owl - http://www.openwall.com/Owl/
+ *
+ * Copyright (c) 2008 Dmitry V. Levin <ldv at cvs.openwall.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * The blacklist encoding was designed by Solar Designer and Dmitry V. Levin.
+ * No intellectual property rights to the encoding scheme are claimed.
+ *
+ * This effort was supported by CivicActions - http://www.civicactions.com
+ *
+ * The file size to encode 294,903 of 48-bit fingerprints is just 1.3 MB,
+ * which corresponds to less than 4.5 bytes per fingerprint.
+ */
+
+#include "includes.h"
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "atomicio.h"
+#include "blacklist.h"
+#include "canohost.h"
+#include "log.h"
+#include "pathnames.h"
+#include "servconf.h"
+#include "xmalloc.h"
+
+extern ServerOptions options;
+
+typedef struct
+{
+	/* format version identifier */
+	char    version[8];
+	/* index size, in bits */
+	uint8_t index_size;
+	/* offset size, in bits */
+	uint8_t offset_size;
+	/* record size, in bits */
+	uint8_t record_bits;
+	/* number of records */
+	uint8_t records[3];
+	/* offset shift */
+	uint8_t shift[2];
+
+} __attribute__((packed)) blacklist_header;
+
+static unsigned
+c2u(uint8_t c)
+{
+	return (c >= 'a') ? (c - 'a' + 10) : (c - '0');
+}
+
+static blacklist_error_t
+validate_blacklist(const char *fname, int fd, unsigned *bytes,
+		   unsigned *records, unsigned *shift)
+{
+	unsigned expected;
+	struct stat st;
+	blacklist_header header;
+
+	if (fstat(fd, &st)) {
+		error("fstat for blacklist file %s failed: %m", fname);
+		return BLACKLIST_ERROR_ACCESS;
+	}
+
+	if (atomicio(read, fd, &header, sizeof(header)) != sizeof(header)) {
+		error("read blacklist file %s header failed: %m", fname);
+		return BLACKLIST_ERROR_ACCESS;
+	}
+
+	if (memcmp(header.version, "SSH-FP", 6)) {
+		error("blacklist file %s has unrecognized format", fname);
+		return BLACKLIST_ERROR_FORMAT;
+	}
+
+	if (header.index_size != 16 || header.offset_size != 16 ||
+	    memcmp(header.version, "SSH-FP00", 8)) {
+		error("blacklist file %s has unsupported format", fname);
+		return BLACKLIST_ERROR_VERSION;
+	}
+
+	*bytes = (header.record_bits >> 3) - 2;
+	*records =
+		(((header.records[0] << 8) +
+		  header.records[1]) << 8) + header.records[2];
+	*shift = (header.shift[0] << 8) + header.shift[1];
+
+	expected = sizeof(header) + 0x20000 + (*records) * (*bytes);
+	if (st.st_size != expected) {
+		error("blacklist file %s size mismatch: "
+		      "expected size %u, found size %lu",
+		      fname, expected, (unsigned long) st.st_size);
+		return BLACKLIST_ERROR_ACCESS;
+	}
+
+	return BLACKLIST_ERROR_NONE;
+}
+
+static int
+expected_offset(uint16_t index, uint16_t shift, unsigned records)
+{
+	return ((index * (long long) records) >> 16) - shift;
+}
+
+static int
+xlseek(const char *fname, int fd, unsigned seek)
+{
+	if (lseek(fd, seek, SEEK_SET) != seek) {
+		error("lseek for blacklist file %s failed: %m", fname);
+		return BLACKLIST_ERROR_ACCESS;
+	}
+	return BLACKLIST_ERROR_NONE;
+}
+
+static blacklist_error_t
+check(const char *fname, int fd, const char *s)
+{
+	unsigned bytes, records, shift;
+	unsigned num, i, j;
+	int     off_start, off_end;
+	blacklist_error_t rc;
+	uint16_t index;
+	/* max number of bytes stored in record_bits, minus two bytes used for index */
+	uint8_t buf[(0xff >> 3) - 2];
+
+	if ((rc = validate_blacklist(fname, fd, &bytes, &records, &shift)))
+		return rc;
+
+	index = (((((c2u(s[0]) << 4) | c2u(s[1])) << 4) |
+		  c2u(s[2])) << 4) | c2u(s[3]);
+	if (xlseek(fname, fd, sizeof(blacklist_header) + index * 2))
+		return BLACKLIST_ERROR_ACCESS;
+
+	if (atomicio(read, fd, buf, 4) != 4) {
+		error("read blacklist file %s offsets failed: %m", fname);
+		return BLACKLIST_ERROR_ACCESS;
+	}
+
+	off_start = (buf[0] << 8) + buf[1] +
+		expected_offset(index, shift, records);
+	if (off_start < 0 || (unsigned) off_start > records) {
+		error("blacklist file %s off_start overflow [%d] for index %#x",
+		      fname, off_start, index);
+		return BLACKLIST_ERROR_ACCESS;
+	}
+	if (index < 0xffff) {
+		off_end = (buf[2] << 8) + buf[3] +
+			expected_offset(index + 1, shift, records);
+		if (off_end < off_start || (unsigned) off_end > records) {
+			error("blacklist file %s off_end overflow [%d] for index %#x",
+			      fname, off_end, index);
+			return BLACKLIST_ERROR_ACCESS;
+		}
+	} else
+		off_end = records;
+
+	if (xlseek(fname, fd,
+		   sizeof(blacklist_header) + 0x20000 + off_start * bytes))
+		return BLACKLIST_ERROR_ACCESS;
+
+	num = off_end - off_start;
+	for (i = 0; i < num; ++i) {
+		if (atomicio(read, fd, buf, bytes) != bytes) {
+			error("read blacklist file %s fingerprints failed: %m",
+			      fname);
+			return BLACKLIST_ERROR_ACCESS;
+		}
+
+		for (j = 0; j < bytes; ++j)
+			if (((c2u(s[4 + j * 2]) << 4) | c2u(s[5 + j * 2])) !=
+			    buf[j])
+				break;
+		if (j >= bytes) {
+			debug("blacklisted fingerprint: %s offset=%u, number=%u",
+			      s, off_start, i);
+			return BLACKLIST_ERROR_ALL;
+		}
+	}
+
+	debug("non-blacklisted fingerprint: %s offset=%u, number=%u",
+	      s, off_start, num);
+	return BLACKLIST_ERROR_NONE;
+}
+
+static blacklist_error_t
+blacklisted_fingerprint(const char *hex)
+{
+	int     fd = -1;
+	blacklist_error_t rc = BLACKLIST_ERROR_ACCESS;
+	const char *fname = _PATH_BLACKLIST;
+	char   *s, *p;
+
+	debug("Checking fingerprint %s using blacklist file %s", hex, fname);
+
+	s = xstrdup(hex);
+	for (p = s; *hex; ++hex)
+		if (*hex != ':')
+			*p++ = *hex;
+	*p = '\0';
+
+	if (strlen(s) != 32 || strlen(s) != strspn(s, "0123456789abcdef")) {
+		error("%s: invalid fingerprint", s);
+		goto out;
+	}
+
+	if ((fd = open(fname, O_RDONLY)) < 0) {
+		if (ENOENT == errno) {
+			rc = BLACKLIST_ERROR_MISSING;
+			verbose("open blacklist file %s failed: %m", fname);
+		} else
+			logit("open blacklist file %s failed: %m", fname);
+		goto out;
+	}
+
+	rc = check(fname, fd, s);
+
+out:
+	close(fd);
+	xfree(s);
+	return rc;
+}
+
+int
+blacklisted_key(Key *key, int hostkey)
+{
+	int     rc;
+	const char *text;
+	char   *fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
+
+	switch ((rc = blacklisted_fingerprint(fp))) {
+		case BLACKLIST_ERROR_NONE:
+			break;
+		case BLACKLIST_ERROR_ALL:
+			text = (options.ignore_blacklist_errors == rc) ?
+			       "Permitted" : "Rejected";
+			if (hostkey)
+				logit("%s blacklisted host key %s", text, fp);
+			else
+				logit("%s blacklisted public key %s from %.100s",
+				      text, fp, get_remote_ipaddr());
+			break;
+		default:
+			if (hostkey)
+				logit("Unable to check blacklist for host key %s",
+				      fp);
+			else
+				logit("Unable to check blacklist for public key %s from %.100s",
+				      fp, get_remote_ipaddr());
+	}
+
+	xfree(fp);
+	return (rc > options.ignore_blacklist_errors);
+}
diff --git a/blacklist.h b/blacklist.h
new file mode 100644
index 0000000..853ede1
--- /dev/null
+++ b/blacklist.h
@@ -0,0 +1,37 @@
+/*
+ * Support for RSA/DSA key blacklisting based on partial fingerprints,
+ * developed under Openwall Project for Owl - http://www.openwall.com/Owl/
+ *
+ * Copyright (c) 2008 Dmitry V. Levin <ldv at cvs.openwall.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef BLACKLIST_H_
+#define BLACKLIST_H_
+
+#include "key.h"
+
+int blacklisted_key(Key *, int);
+
+typedef enum
+{
+	BLACKLIST_ERROR_NONE = 0,
+	BLACKLIST_ERROR_MISSING,
+	BLACKLIST_ERROR_VERSION,
+	BLACKLIST_ERROR_FORMAT,
+	BLACKLIST_ERROR_ACCESS,
+	BLACKLIST_ERROR_ALL
+} blacklist_error_t;
+
+#endif /* BLACKLIST_H_ */
diff --git a/channels.c b/channels.c
index b6bd901..5fb88c3 100644
--- a/channels.c
+++ b/channels.c
@@ -2552,6 +2552,8 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
 		packet_write_wait();
 		/* Assume that server accepts the request */
 		success = 1;
+		debug("Forward request from remote address %s:%u to local address %s:%u succeded.",
+		      address_to_bind, listen_port, host_to_connect, port_to_connect);
 	} else {
 		packet_start(SSH_CMSG_PORT_FORWARD_REQUEST);
 		packet_put_int(listen_port);
@@ -2565,8 +2567,12 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
 		switch (type) {
 		case SSH_SMSG_SUCCESS:
 			success = 1;
+			debug("Forward request from remote port %u to local address %s:%u succeded.",
+			      listen_port, host_to_connect, port_to_connect);
 			break;
 		case SSH_SMSG_FAILURE:
+			debug("Forward request from remote port %u to local address %s:%u failed.",
+			      listen_port, host_to_connect, port_to_connect);
 			break;
 		default:
 			/* Unknown packet */
diff --git a/clientloop.c b/clientloop.c
index 8a40bc7..bd1a637 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -777,16 +777,24 @@ client_process_control(fd_set *readset)
 	switch (command) {
 	case SSHMUX_COMMAND_OPEN:
 		if (options.control_master == SSHCTL_MASTER_ASK ||
-		    options.control_master == SSHCTL_MASTER_AUTO_ASK)
+		    options.control_master == SSHCTL_MASTER_AUTO_ASK) {
+			char *proc = getpeerproc(client_fd);
 			allowed = ask_permission("Allow shared connection "
-			    "to %s? ", host);
+			    "to %s?\nRequest from \"%.80s\".",
+			    host, (proc ? proc : "<unknown>"));
+			free(proc);
+		}
 		/* continue below */
 		break;
 	case SSHMUX_COMMAND_TERMINATE:
 		if (options.control_master == SSHCTL_MASTER_ASK ||
-		    options.control_master == SSHCTL_MASTER_AUTO_ASK)
+		    options.control_master == SSHCTL_MASTER_AUTO_ASK) {
+			char *proc = getpeerproc(client_fd);
 			allowed = ask_permission("Terminate shared connection "
-			    "to %s? ", host);
+			    "to %s?\nRequest from \"%.80s\".",
+			    host, (proc ? proc : "<unknown>"));
+			free(proc);
+		}
 		if (allowed)
 			quit_pending = 1;
 		/* FALLTHROUGH */
diff --git a/entropy.c b/entropy.c
index 8b70539..24e5208 100644
--- a/entropy.c
+++ b/entropy.c
@@ -153,11 +153,11 @@ init_rng(void)
 {
 	/*
 	 * OpenSSL version numbers: MNNFFPPS: major minor fix patch status
-	 * We match major, minor, fix and status (not patch)
+	 * We match major, minor and fix (but not patch and status)
 	 */
-	if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xff0L)
-		fatal("OpenSSL version mismatch. Built against %lx, you "
-		    "have %lx", OPENSSL_VERSION_NUMBER, SSLeay());
+	if ((SSLeay() ^ OPENSSL_VERSION_NUMBER) & ~0xfffL)
+		fatal("OpenSSL version mismatch. Built against %lx, you have %lx",
+		      (unsigned long) OPENSSL_VERSION_NUMBER, SSLeay());
 
 #ifndef OPENSSL_PRNG_ONLY
 	original_uid = getuid();
diff --git a/log.c b/log.c
index fae5b04..c959253 100644
--- a/log.c
+++ b/log.c
@@ -54,8 +54,13 @@
 
 static LogLevel log_level = SYSLOG_LEVEL_INFO;
 static int log_on_stderr = 1;
+#ifdef LOG_AUTHPRIV
+static int log_facility = LOG_AUTHPRIV;
+#else
 static int log_facility = LOG_AUTH;
+#endif
 static char *argv0;
+static int log_keep = 0;
 
 extern char *__progname;
 
@@ -302,6 +307,16 @@ log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr)
 #endif
 }
 
+void
+log_init_chroot(void)
+{
+	if (log_on_stderr)
+		return;
+	closelog();
+	openlog(argv0 ?: __progname, LOG_PID|LOG_NDELAY, log_facility);
+	log_keep = 1;
+}
+
 #define MSGBUFSIZ 1024
 
 void
@@ -323,11 +338,15 @@ do_log(LogLevel level, const char *fmt, va_list args)
 	case SYSLOG_LEVEL_FATAL:
 		if (!log_on_stderr)
 			txt = "fatal";
+		else
+			txt = __progname;
 		pri = LOG_CRIT;
 		break;
 	case SYSLOG_LEVEL_ERROR:
 		if (!log_on_stderr)
 			txt = "error";
+		else
+			txt = __progname;
 		pri = LOG_ERR;
 		break;
 	case SYSLOG_LEVEL_INFO:
@@ -365,15 +384,19 @@ do_log(LogLevel level, const char *fmt, va_list args)
 		snprintf(msgbuf, sizeof msgbuf, "%s\r\n", fmtbuf);
 		write(STDERR_FILENO, msgbuf, strlen(msgbuf));
 	} else {
+		if (log_keep) {
+			syslog(pri, "%.500s", fmtbuf);
+		} else {
 #if defined(HAVE_OPENLOG_R) && defined(SYSLOG_DATA_INIT)
-		openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
-		syslog_r(pri, &sdata, "%.500s", fmtbuf);
-		closelog_r(&sdata);
+			openlog_r(argv0 ? argv0 : __progname, LOG_PID, log_facility, &sdata);
+			syslog_r(pri, &sdata, "%.500s", fmtbuf);
+			closelog_r(&sdata);
 #else
-		openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
-		syslog(pri, "%.500s", fmtbuf);
-		closelog();
+			openlog(argv0 ? argv0 : __progname, LOG_PID, log_facility);
+			syslog(pri, "%.500s", fmtbuf);
+			closelog();
 #endif
+		}
 	}
 	errno = saved_errno;
 }
diff --git a/log.h b/log.h
index 7a8c570..1f5e504 100644
--- a/log.h
+++ b/log.h
@@ -47,6 +47,7 @@ typedef enum {
 }       LogLevel;
 
 void     log_init(char *, LogLevel, SyslogFacility, int);
+void     log_init_chroot(void);
 
 SyslogFacility	log_facility_number(char *);
 LogLevel log_level_number(char *);
diff --git a/mac.c b/mac.c
index 3446465..2bb1f54 100644
--- a/mac.c
+++ b/mac.c
@@ -127,8 +127,8 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen)
 	u_char b[4], nonce[8];
 
 	if (mac->mac_len > sizeof(m))
-		fatal("mac_compute: mac too long %u %lu",
-		    mac->mac_len, sizeof(m));
+		fatal("mac_compute: mac too long %u %u",
+		    mac->mac_len, (unsigned)sizeof(m));
 
 	switch (mac->type) {
 	case SSH_EVP:
diff --git a/monitor.c b/monitor.c
index cc0e0fc..7dfe314 100644
--- a/monitor.c
+++ b/monitor.c
@@ -618,7 +618,7 @@ mm_answer_pwnamallow(int sock, Buffer *m)
 	pwent = getpwnamallow(username);
 
 	authctxt->user = xstrdup(username);
-	setproctitle("%s [priv]", pwent ? username : "unknown");
+	setproctitle("%s [priv]", pwent ? username : "UNKNOWN USER");
 	xfree(username);
 
 	buffer_clear(m);
diff --git a/monitor_mm.c b/monitor_mm.c
index dab7475..627938f 100644
--- a/monitor_mm.c
+++ b/monitor_mm.c
@@ -139,6 +139,7 @@ mm_destroy(struct mm_master *mm)
 	mm_freelist(mm->mmalloc, &mm->rb_allocated);
 
 #ifdef HAVE_MMAP
+	memset(mm->address, 0xd0, mm->size);
 	if (munmap(mm->address, mm->size) == -1)
 		fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size,
 		    strerror(errno));
diff --git a/myproposal.h b/myproposal.h
index 87a9e58..9099462 100644
--- a/myproposal.h
+++ b/myproposal.h
@@ -42,10 +42,11 @@
 
 #define	KEX_DEFAULT_PK_ALG	"ssh-rsa,ssh-dss"
 #define	KEX_DEFAULT_ENCRYPT \
-	"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
-	"arcfour128,arcfour256,arcfour," \
-	"aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \
-	"aes128-ctr,aes192-ctr,aes256-ctr"
+	"aes256-ctr,aes192-ctr,aes128-ctr," \
+	"blowfish-cbc,aes256-cbc,aes192-cbc," \
+	"aes128-cbc,3des-cbc,cast128-cbc," \
+	"arcfour256,arcfour128,arcfour," \
+	"rijndael-cbc@lysator.liu.se"
 #define	KEX_DEFAULT_MAC \
 	"hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \
 	"hmac-ripemd160@openssh.com," \
diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in
index b44a785..6d28018 100644
--- a/openbsd-compat/Makefile.in
+++ b/openbsd-compat/Makefile.in
@@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@
 
 OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sha2.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o strtonum.o strtoll.o strtoul.o vis.o
 
-COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
+COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o getpeerproc.o openssl-compat.o xmmap.o xcrypt.o
 
 PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
 
diff --git a/openbsd-compat/getpeerproc.c b/openbsd-compat/getpeerproc.c
new file mode 100644
index 0000000..8b268b9
--- /dev/null
+++ b/openbsd-compat/getpeerproc.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2002,2004 Damien Miller <djm@mindrot.org>
+ * Copyright (c) 2007 Dmitry V. Levin <ldv@altlinux.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include "xmalloc.h"
+
+static pid_t
+getpeerpid(int s)
+{
+#if defined(SO_PEERCRED)
+	struct ucred cred;
+	socklen_t len = sizeof(cred);
+
+	if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0)
+		return -1;
+
+	return cred.pid;
+#else
+	return 0;
+#endif /* defined(SO_PEERCRED) */
+}
+
+char *
+getpeerproc(int s)
+{
+	pid_t pid;
+	int len, fd, i;
+	char path[PATH_MAX];
+	char line[1024];
+
+	if (!(pid = getpeerpid(s)))
+		return NULL;
+
+	len = snprintf(path, sizeof(path), "/proc/%u/cmdline", (unsigned)pid);
+	if (len < 0 || (size_t)len > sizeof(path) ||
+	    (fd = open(path, O_RDONLY)) < 0)
+		return NULL;
+
+	if ((len = read(fd, line, sizeof(line) - 1)) > 0)
+	{
+		for (i = 0; i < len; ++i)
+			if (isspace(line[i]) || !isprint(line[i]))
+				line[i] = ' ';
+		if (line[len - 1] == ' ')
+			line[len - 1] = '\0';
+		else
+			line[len] = '\0';
+	}
+
+	close(fd);
+
+	return (len > 0) ? xstrdup(line) : NULL;
+}
diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h
index 6406af1..4cab3f6 100644
--- a/openbsd-compat/openbsd-compat.h
+++ b/openbsd-compat/openbsd-compat.h
@@ -186,6 +186,8 @@ int vasprintf(char **, const char *, va_list);
 int vsnprintf(char *, size_t, const char *, va_list);
 #endif
 
+char *getpeerproc(int);
+
 void *xmmap(size_t size);
 char *xcrypt(const char *password, const char *salt);
 char *shadow_pw(struct passwd *pw);
diff --git a/openbsd-compat/xmmap.c b/openbsd-compat/xmmap.c
index 23efe38..a5ddff8 100644
--- a/openbsd-compat/xmmap.c
+++ b/openbsd-compat/xmmap.c
@@ -70,8 +70,12 @@ xmmap(size_t size)
 		if (tmpfd == -1)
 			fatal("mkstemp(\"%s\"): %s",
 			    MM_SWAP_TEMPLATE, strerror(errno));
-		unlink(tmpname);
-		ftruncate(tmpfd, size);
+		if (unlink(tmpname))
+			fatal("unlink(\"%s\"): %s",
+			    tmpname, strerror(errno));
+		if (ftruncate(tmpfd, size))
+			fatal("truncate(\"%s\", %lu): %s",
+			    tmpname, (unsigned long) size, strerror(errno));
 		address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED,
 		    tmpfd, (off_t)0);
 		close(tmpfd);
diff --git a/pathnames.h b/pathnames.h
index f2571e2..dfca169 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -43,6 +43,8 @@
 /* Backwards compatibility */
 #define _PATH_DH_PRIMES			SSHDIR "/primes"
 
+#define _PATH_BLACKLIST			SSHDIR "/blacklist"
+
 #ifndef _PATH_SSH_PROGRAM
 #define _PATH_SSH_PROGRAM		"/usr/bin/ssh"
 #endif
@@ -92,9 +94,11 @@
  * may need to be world-readable.  (This file is read by the daemon which is
  * running as root.)
  */
+#define _PATH_SSH_SYSTEM_PERMITTED_KEYS	SSHDIR "/authorized_keys/%u"
 #define _PATH_SSH_USER_PERMITTED_KEYS	".ssh/authorized_keys"
 
 /* backward compat for protocol v2 */
+#define _PATH_SSH_SYSTEM_PERMITTED_KEYS2	SSHDIR "/authorized_keys2/%u"
 #define _PATH_SSH_USER_PERMITTED_KEYS2	".ssh/authorized_keys2"
 
 /*
diff --git a/progressmeter.c b/progressmeter.c
index 0f95222..fe0b521 100644
--- a/progressmeter.c
+++ b/progressmeter.c
@@ -44,7 +44,7 @@
 #define MAX_WINSIZE 512
 #define PADDING 1		/* padding between the progress indicators */
 #define UPDATE_INTERVAL 1	/* update the progress meter every second */
-#define STALL_TIME 5		/* we're stalled after this many seconds */
+#define STALL_TIME 60		/* we're stalled after this many seconds */
 
 /* determines whether we can output to the terminal */
 static int can_output(void);
diff --git a/readconf.c b/readconf.c
index 3ddb4d3..8de7d03 100644
--- a/readconf.c
+++ b/readconf.c
@@ -97,8 +97,8 @@
      ForwardX11 no
      PasswordAuthentication yes
      RSAAuthentication yes
-     RhostsRSAAuthentication yes
-     StrictHostKeyChecking yes
+     RhostsRSAAuthentication no
+     StrictHostKeyChecking ask
      TcpKeepAlive no
      IdentityFile ~/.ssh/identity
      Port 22
@@ -1096,7 +1096,7 @@ fill_default_options(Options * options)
 	if (options->pubkey_authentication == -1)
 		options->pubkey_authentication = 1;
 	if (options->challenge_response_authentication == -1)
-		options->challenge_response_authentication = 1;
+		options->challenge_response_authentication = 0;
 	if (options->gss_authentication == -1)
 		options->gss_authentication = 0;
 	if (options->gss_deleg_creds == -1)
@@ -1136,7 +1136,7 @@ fill_default_options(Options * options)
 	/* options->macs, default set in myproposals.h */
 	/* options->hostkeyalgorithms, default set in myproposals.h */
 	if (options->protocol == SSH_PROTO_UNKNOWN)
-		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
+		options->protocol = SSH_PROTO_2;
 	if (options->num_identity_files == 0) {
 		if (options->protocol & SSH_PROTO_1) {
 			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
diff --git a/scard-opensc.c b/scard-opensc.c
index 36dae05..e8f6d6b 100644
--- a/scard-opensc.c
+++ b/scard-opensc.c
@@ -96,7 +96,7 @@ sc_init(void)
 		goto err;
 	if (sc_reader_id >= ctx->reader_count) {
 		r = SC_ERROR_NO_READERS_FOUND;
-		error("Illegal reader number %d (max %d)", sc_reader_id,
+		error("Invalid reader number %d (max %d)", sc_reader_id,
 		    ctx->reader_count -1);
 		goto err;
 	}
diff --git a/scp.c b/scp.c
index c047864..db4a2e5 100644
--- a/scp.c
+++ b/scp.c
@@ -712,7 +712,7 @@ next:			if (fd != -1) {
 			if (i + amt > stb.st_size)
 				amt = stb.st_size - i;
 			if (!haderr) {
-				if (atomicio(read, fd, bp->buf, amt) != amt)
+				if (atomicio(read, fd, bp->buf, amt) != (size_t) amt)
 					haderr = errno;
 			}
 			/* Keep writing after error to retain sync */
@@ -721,7 +721,7 @@ next:			if (fd != -1) {
 				continue;
 			}
 			if (scpio(vwrite, remout, bp->buf, amt,
-			    &statbytes) != amt)
+			    &statbytes) != (size_t) amt)
 				haderr = errno;
 		}
 		unset_nonblock(remout);
diff --git a/servconf.c b/servconf.c
index 9add96c..577e2e5 100644
--- a/servconf.c
+++ b/servconf.c
@@ -39,6 +39,7 @@
 #include "match.h"
 #include "channels.h"
 #include "groupaccess.h"
+#include "blacklist.h"
 
 static void add_listen_addr(ServerOptions *, char *, u_short);
 static void add_one_listen_addr(ServerOptions *, char *, u_short);
@@ -94,6 +95,7 @@ initialize_server_options(ServerOptions *options)
 	options->password_authentication = -1;
 	options->kbd_interactive_authentication = -1;
 	options->challenge_response_authentication = -1;
+	options->ignore_blacklist_errors = -1;
 	options->permit_empty_passwd = -1;
 	options->permit_user_env = -1;
 	options->use_login = -1;
@@ -118,6 +120,8 @@ initialize_server_options(ServerOptions *options)
 	options->client_alive_count_max = -1;
 	options->authorized_keys_file = NULL;
 	options->authorized_keys_file2 = NULL;
+	options->authorized_keys_system_file = NULL;
+	options->authorized_keys_system_file2 = NULL;
 	options->num_accept_env = 0;
 	options->permit_tun = -1;
 	options->num_permitted_opens = -1;
@@ -130,11 +134,11 @@ fill_default_server_options(ServerOptions *options)
 {
 	/* Portable-specific options */
 	if (options->use_pam == -1)
-		options->use_pam = 0;
+		options->use_pam = 1;
 
 	/* Standard Options */
 	if (options->protocol == SSH_PROTO_UNKNOWN)
-		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
+		options->protocol = SSH_PROTO_2;
 	if (options->num_host_key_files == 0) {
 		/* fill default hostkeys for protocols */
 		if (options->protocol & SSH_PROTO_1)
@@ -160,7 +164,7 @@ fill_default_server_options(ServerOptions *options)
 	if (options->key_regeneration_time == -1)
 		options->key_regeneration_time = 3600;
 	if (options->permit_root_login == PERMIT_NOT_SET)
-		options->permit_root_login = PERMIT_YES;
+		options->permit_root_login = PERMIT_NO_PASSWD;
 	if (options->ignore_rhosts == -1)
 		options->ignore_rhosts = 1;
 	if (options->ignore_user_known_hosts == -1)
@@ -170,7 +174,7 @@ fill_default_server_options(ServerOptions *options)
 	if (options->print_lastlog == -1)
 		options->print_lastlog = 1;
 	if (options->x11_forwarding == -1)
-		options->x11_forwarding = 0;
+		options->x11_forwarding = 1;
 	if (options->x11_display_offset == -1)
 		options->x11_display_offset = 10;
 	if (options->x11_use_localhost == -1)
@@ -212,7 +216,9 @@ fill_default_server_options(ServerOptions *options)
 	if (options->kbd_interactive_authentication == -1)
 		options->kbd_interactive_authentication = 0;
 	if (options->challenge_response_authentication == -1)
-		options->challenge_response_authentication = 1;
+		options->challenge_response_authentication = 0;
+	if (options->ignore_blacklist_errors == -1)
+		options->ignore_blacklist_errors = BLACKLIST_ERROR_VERSION;
 	if (options->permit_empty_passwd == -1)
 		options->permit_empty_passwd = 0;
 	if (options->permit_user_env == -1)
@@ -226,11 +232,13 @@ fill_default_server_options(ServerOptions *options)
 	if (options->gateway_ports == -1)
 		options->gateway_ports = 0;
 	if (options->max_startups == -1)
-		options->max_startups = 10;
+		options->max_startups = 20;
 	if (options->max_startups_rate == -1)
-		options->max_startups_rate = 100;		/* 100% */
+		options->max_startups_rate = 30;		/* 30% */
 	if (options->max_startups_begin == -1)
-		options->max_startups_begin = options->max_startups;
+		options->max_startups_begin =
+			(options->max_startups_rate >= 100) ?
+				options->max_startups : options->max_startups/2;
 	if (options->max_authtries == -1)
 		options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
 	if (options->use_dns == -1)
@@ -248,6 +256,15 @@ fill_default_server_options(ServerOptions *options)
 	}
 	if (options->authorized_keys_file == NULL)
 		options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS;
+	if (options->authorized_keys_system_file2 == NULL) {
+		/* authorized_keys_system_file2 falls back to authorized_keys_system_file */
+		if (options->authorized_keys_system_file != NULL)
+			options->authorized_keys_system_file2 = options->authorized_keys_system_file;
+		else
+			options->authorized_keys_system_file2 = _PATH_SSH_SYSTEM_PERMITTED_KEYS2;
+	}
+	if (options->authorized_keys_system_file == NULL)
+		options->authorized_keys_system_file = _PATH_SSH_SYSTEM_PERMITTED_KEYS;
 	if (options->permit_tun == -1)
 		options->permit_tun = SSH_TUNMODE_NO;
 
@@ -282,7 +299,7 @@ typedef enum {
 	sListenAddress, sAddressFamily,
 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
-	sStrictModes, sEmptyPasswd, sTCPKeepAlive,
+	sStrictModes, sIgnoreBlacklistErrors, sEmptyPasswd, sTCPKeepAlive,
 	sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
 	sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
 	sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
@@ -291,6 +308,7 @@ typedef enum {
 	sBanner, sUseDNS, sHostbasedAuthentication,
 	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
 	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
+	sAuthorizedKeysSystemFile, sAuthorizedKeysSystemFile2,
 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
 	sUsePrivilegeSeparation,
@@ -372,6 +390,7 @@ static struct {
 	{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
 	{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
 	{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
+	{ "ignoreblacklisterrors", sIgnoreBlacklistErrors, SSHCFG_GLOBAL },
 	{ "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
 	{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
 	{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
@@ -398,6 +417,8 @@ static struct {
 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
 	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
+	{ "authorizedkeyssystemfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
+	{ "authorizedkeyssystemfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
 	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
@@ -923,6 +944,32 @@ parse_flag:
 		intptr = &options->tcp_keep_alive;
 		goto parse_flag;
 
+	case sIgnoreBlacklistErrors:
+		intptr = &options->ignore_blacklist_errors;
+		arg = strdelim(&cp);
+		if (!arg || *arg == '\0')
+			fatal("%s line %d: missing none/missing/version/format/access/all argument.",
+			    filename, linenum);
+		value = 0;	/* silence compiler */
+		if (strcmp(arg, "none") == 0)
+			value = BLACKLIST_ERROR_NONE;
+		else if (strcmp(arg, "missing") == 0)
+			value = BLACKLIST_ERROR_MISSING;
+		else if (strcmp(arg, "version") == 0)
+			value = BLACKLIST_ERROR_VERSION;
+		else if (strcmp(arg, "format") == 0)
+			value = BLACKLIST_ERROR_FORMAT;
+		else if (strcmp(arg, "access") == 0)
+			value = BLACKLIST_ERROR_ACCESS;
+		else if (strcmp(arg, "all") == 0)
+			value = BLACKLIST_ERROR_ALL;
+		else
+			fatal("%s line %d: Bad none/missing/version/format/access/all argument: %s",
+				filename, linenum, arg);
+		if (*activep && *intptr == -1)
+			*intptr = value;
+		break;
+
 	case sEmptyPasswd:
 		intptr = &options->permit_empty_passwd;
 		goto parse_flag;
@@ -1133,10 +1180,10 @@ parse_flag:
 			    options->max_startups ||
 			    options->max_startups_rate > 100 ||
 			    options->max_startups_rate < 1)
-				fatal("%s line %d: Illegal MaxStartups spec.",
+				fatal("%s line %d: Invalid MaxStartups spec.",
 				    filename, linenum);
 		} else if (n != 1)
-			fatal("%s line %d: Illegal MaxStartups spec.",
+			fatal("%s line %d: Invalid MaxStartups spec.",
 			    filename, linenum);
 		else
 			options->max_startups = options->max_startups_begin;
@@ -1156,6 +1203,13 @@ parse_flag:
 	 *
 	 * AuthorizedKeysFile	/etc/ssh_keys/%u
 	 */
+	case sAuthorizedKeysSystemFile:
+	case sAuthorizedKeysSystemFile2:
+		charptr = (opcode == sAuthorizedKeysSystemFile ) ?
+		    &options->authorized_keys_system_file :
+		    &options->authorized_keys_system_file2;
+		goto parse_filename;
+
 	case sAuthorizedKeysFile:
 	case sAuthorizedKeysFile2:
 		charptr = (opcode == sAuthorizedKeysFile) ?
diff --git a/servconf.h b/servconf.h
index 5b88067..0e846ff 100644
--- a/servconf.h
+++ b/servconf.h
@@ -95,6 +95,7 @@ typedef struct {
 						 * authentication. */
 	int     kbd_interactive_authentication;	/* If true, permit */
 	int     challenge_response_authentication;
+	int     ignore_blacklist_errors;	/* none/missing/version/format/access/all */
 	int     permit_empty_passwd;	/* If false, do not permit empty
 					 * passwords. */
 	int     permit_user_env;	/* If true, read ~/.ssh/environment */
@@ -134,6 +135,8 @@ typedef struct {
 					 * disconnect the session
 					 */
 
+	char   *authorized_keys_system_file;	/* File containing system public keys */
+	char   *authorized_keys_system_file2;
 	char   *authorized_keys_file;	/* File containing public keys */
 	char   *authorized_keys_file2;
 
diff --git a/sftp-server.0 b/sftp-server.0
index 614ae03..3928026 100644
--- a/sftp-server.0
+++ b/sftp-server.0
@@ -20,8 +20,8 @@ DESCRIPTION
      -f log_facility
              Specifies the facility code that is used when logging messages
              from sftp-server.  The possible values are: DAEMON, USER, AUTH,
-             LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
-             The default is AUTH.
+             AUTHPRIV, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6,
+             LOCAL7.  The default is AUTHPRIV.
 
      -l log_level
              Specifies which messages will be logged by sftp-server.  The pos-
diff --git a/sftp-server.8 b/sftp-server.8
index 7452eca..387aeae 100644
--- a/sftp-server.8
+++ b/sftp-server.8
@@ -57,9 +57,9 @@ Valid options are:
 .It Fl f Ar log_facility
 Specifies the facility code that is used when logging messages from
 .Nm .
-The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2,
 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
-The default is AUTH.
+The default is AUTHPRIV.
 .It Fl l Ar log_level
 Specifies which messages will be logged by
 .Nm .
diff --git a/sftp-server.c b/sftp-server.c
index d9549f5..2a33bf2 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1247,7 +1247,11 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw)
 	fd_set *rset, *wset;
 	int in, out, max, ch, skipargs = 0, log_stderr = 0;
 	ssize_t len, olen, set_size;
+#ifdef LOG_AUTHPRIV
+	SyslogFacility log_facility = SYSLOG_FACILITY_AUTHPRIV;
+#else
 	SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
+#endif
 	char *cp, buf[4*4096];
 
 	extern char *optarg;
diff --git a/sftp.c b/sftp.c
index 861c3db..3543de9 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1130,8 +1130,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
     int err_abort)
 {
 	char *path1, *path2, *tmp;
-	int pflag, lflag, iflag, cmdnum, i;
-	unsigned long n_arg;
+	int pflag = 0, lflag = 0, iflag = 0, cmdnum = 0, i = 0;
+	unsigned long n_arg = 0;
 	Attrib a, *aa;
 	char path_buf[MAXPATHLEN];
 	int err = 0;
diff --git a/ssh-agent.1 b/ssh-agent.1
index 0081be5..3134853 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -43,6 +43,7 @@
 .Sh SYNOPSIS
 .Nm ssh-agent
 .Op Fl c Li | Fl s
+.Op Fl u
 .Op Fl d
 .Op Fl a Ar bind_address
 .Op Fl t Ar life
@@ -77,6 +78,8 @@ Generate C-shell commands on
 This is the default if
 .Ev SHELL
 looks like it's a csh style of shell.
+.It Fl u
+Run the agent in unique mode.
 .It Fl d
 Debug mode.
 When this option is specified
@@ -178,14 +181,18 @@ environment variable holds the agent's process ID.
 The agent exits automatically when the command given on the command
 line terminates.
 .Sh FILES
-.Bl -tag -width Ds
+.Bl -tag -width Ds -compact
 .It Pa ~/.ssh/identity
 Contains the protocol version 1 RSA authentication identity of the user.
+.Pp
 .It Pa ~/.ssh/id_dsa
 Contains the protocol version 2 DSA authentication identity of the user.
+.Pp
 .It Pa ~/.ssh/id_rsa
 Contains the protocol version 2 RSA authentication identity of the user.
-.It Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt
+.Pp
+.It Pa /tmp/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt ,
+.It Pa ~/.ssh/agent
 Unix-domain sockets used to contain the connection to the
 authentication agent.
 These sockets should only be readable by the owner.
diff --git a/ssh-agent.c b/ssh-agent.c
index 6f8727b..9fcff72 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -191,16 +191,18 @@ lookup_identity(Key *key, int version)
 
 /* Check confirmation of keysign request */
 static int
-confirm_key(Identity *id)
+confirm_key(Identity *id, char *proc)
 {
 	char *p;
 	int ret = -1;
 
 	p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
-	if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
-	    id->comment, p))
+	if (ask_permission("Allow use of key %s?\nKey fingerprint %s.\n"
+	    "Request from \"%.80s\".",
+	    id->comment, p, (proc ? proc : "<unknown>")))
 		ret = 0;
 	xfree(p);
+	free(proc);
 
 	return (ret);
 }
@@ -268,7 +270,7 @@ process_authentication_challenge1(SocketEntry *e)
 		goto failure;
 
 	id = lookup_identity(key, 1);
-	if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
+	if (id != NULL && (!id->confirm || confirm_key(id, getpeerproc(e->fd)) == 0)) {
 		Key *private = id->key;
 		/* Decrypt the challenge using the private key. */
 		if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0)
@@ -328,7 +330,7 @@ process_sign_request2(SocketEntry *e)
 	key = key_from_blob(blob, blen);
 	if (key != NULL) {
 		Identity *id = lookup_identity(key, 2);
-		if (id != NULL && (!id->confirm || confirm_key(id) == 0))
+		if (id != NULL && (!id->confirm || confirm_key(id, getpeerproc(e->fd)) == 0))
 			ok = key_sign(id->key, &signature, &slen, data, dlen);
 		key_free(key);
 	}
@@ -922,13 +924,12 @@ after_select(fd_set *readset, fd_set *writeset)
 				sock = accept(sockets[i].fd,
 				    (struct sockaddr *)&sunaddr, &slen);
 				if (sock < 0) {
-					error("accept from AUTH_SOCKET: %s",
-					    strerror(errno));
+					error("accept from AUTH_SOCKET: %m");
 					break;
 				}
 				if (getpeereid(sock, &euid, &egid) < 0) {
-					error("getpeereid %d failed: %s",
-					    sock, strerror(errno));
+					error("getpeereid %d failed: %m",
+					    sock);
 					close(sock);
 					break;
 				}
@@ -1015,6 +1016,26 @@ check_parent_exists(void)
 	}
 }
 
+static int
+check_auth_socket(const char *authsocket)
+{
+	int sock, rc;
+	struct sockaddr_un sunaddr;
+
+	sock = socket(AF_UNIX, SOCK_STREAM, 0);
+	if (sock < 0)
+		return sock;
+
+	memset(&sunaddr, 0, sizeof(sunaddr));
+	sunaddr.sun_family = AF_UNIX;
+	strlcpy(sunaddr.sun_path, authsocket, sizeof(sunaddr.sun_path));
+
+	rc = connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr));
+	close(sock);
+
+	return rc;
+}
+
 static void
 usage(void)
 {
@@ -1024,6 +1045,7 @@ usage(void)
 	fprintf(stderr, "  -c          Generate C-shell commands on stdout.\n");
 	fprintf(stderr, "  -s          Generate Bourne shell commands on stdout.\n");
 	fprintf(stderr, "  -k          Kill the current agent.\n");
+	fprintf(stderr, "  -u          Unique mode.\n");
 	fprintf(stderr, "  -d          Debug mode.\n");
 	fprintf(stderr, "  -a socket   Bind agent socket to given name.\n");
 	fprintf(stderr, "  -t life     Default identity lifetime (seconds).\n");
@@ -1034,6 +1056,7 @@ int
 main(int ac, char **av)
 {
 	int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
+	int u_flag = 0, already_running = 0;
 	int sock, fd, ch, result, saved_errno;
 	u_int nalloc;
 	char *shell, *format, *pidstr, *agentsocket = NULL;
@@ -1046,7 +1069,6 @@ main(int ac, char **av)
 	extern int optind;
 	extern char *optarg;
 	pid_t pid;
-	char pidstrbuf[1 + 3 * sizeof pid];
 	struct timeval *tvp = NULL;
 
 	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@@ -1067,7 +1089,7 @@ main(int ac, char **av)
 	init_rng();
 	seed_rng();
 
-	while ((ch = getopt(ac, av, "cdksa:t:")) != -1) {
+	while ((ch = getopt(ac, av, "cdksua:t:")) != -1) {
 		switch (ch) {
 		case 'c':
 			if (s_flag)
@@ -1082,6 +1104,9 @@ main(int ac, char **av)
 				usage();
 			s_flag++;
 			break;
+		case 'u':
+			u_flag++;
+			break;
 		case 'd':
 			if (d_flag)
 				usage();
@@ -1103,7 +1128,10 @@ main(int ac, char **av)
 	ac -= optind;
 	av += optind;
 
-	if (ac > 0 && (c_flag || k_flag || s_flag || d_flag))
+	if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || u_flag))
+		usage();
+
+	if (u_flag && (k_flag || agentsocket))
 		usage();
 
 	if (ac == 0 && !c_flag && !s_flag) {
@@ -1117,20 +1145,16 @@ main(int ac, char **av)
 
 		pidstr = getenv(SSH_AGENTPID_ENV_NAME);
 		if (pidstr == NULL) {
-			fprintf(stderr, "%s not set, cannot kill agent\n",
-			    SSH_AGENTPID_ENV_NAME);
-			exit(1);
+			fatal("%s not set, cannot kill agent",
+			      SSH_AGENTPID_ENV_NAME);
 		}
 		pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);
 		if (errstr) {
-			fprintf(stderr,
-			    "%s=\"%s\", which is not a good PID: %s\n",
-			    SSH_AGENTPID_ENV_NAME, pidstr, errstr);
-			exit(1);
+			fatal( "%s=\"%s\", which is not a good PID: %s",
+			      SSH_AGENTPID_ENV_NAME, pidstr, errstr);
 		}
 		if (kill(pid, SIGTERM) == -1) {
-			perror("kill");
-			exit(1);
+			fatal("kill: %m");
 		}
 		format = c_flag ? "unsetenv %s;\n" : "unset %s;\n";
 		printf(format, SSH_AUTHSOCKET_ENV_NAME);
@@ -1140,15 +1164,22 @@ main(int ac, char **av)
 	}
 	parent_pid = getpid();
 
-	if (agentsocket == NULL) {
+	if (u_flag) {
+		struct passwd *pw = getpwuid(geteuid());
+		if (!pw)
+			fatal("getpwuid: %m");
+		snprintf(socket_name, sizeof socket_name,
+			 "%s/.ssh/agent", pw->pw_dir);
+		endpwent();
+	}
+	else if (agentsocket == NULL) {
 		/* Create private directory for agent socket */
 		strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir);
 		if (mkdtemp(socket_dir) == NULL) {
-			perror("mkdtemp: private socket dir");
-			exit(1);
+			fatal("mkdtemp: private socket dir: %m");
 		}
-		snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir,
-		    (long)parent_pid);
+		snprintf(socket_name, sizeof socket_name,
+			 "%s/agent.%ld", socket_dir, (long)parent_pid);
 	} else {
 		/* Try to use specified agent socket */
 		socket_dir[0] = '\0';
@@ -1161,7 +1192,7 @@ main(int ac, char **av)
 	 */
 	sock = socket(AF_UNIX, SOCK_STREAM, 0);
 	if (sock < 0) {
-		perror("socket");
+		error("socket: %m");
 		*socket_name = '\0'; /* Don't unlink any existing file */
 		cleanup_exit(1);
 	}
@@ -1170,14 +1201,44 @@ main(int ac, char **av)
 	strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
 	prev_mask = umask(0177);
 	if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) {
-		perror("bind");
-		*socket_name = '\0'; /* Don't unlink any existing file */
-		umask(prev_mask);
-		cleanup_exit(1);
+		int rc = -1;
+
+		if (u_flag && (EADDRINUSE == errno)) {
+			if (check_auth_socket(socket_name) < 0) {
+				(void) unlink(socket_name);
+				rc = bind(sock, (struct sockaddr *) & sunaddr,
+					sizeof(sunaddr));
+			} else {
+				already_running = 1;
+				rc = 0;
+			}
+		}
+		if (rc < 0) {
+			error("bind: %s: %m", socket_name);
+			*socket_name = '\0'; /* Don't unlink any existing file */
+			umask(prev_mask);
+			cleanup_exit(1);
+		}
 	}
 	umask(prev_mask);
+
+	if (already_running) {
+		close(sock);
+		if (ac == 0) {
+			format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n";
+			printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name,
+			    SSH_AUTHSOCKET_ENV_NAME);
+			exit(0);
+		}
+		if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) < 0) {
+			fatal("setenv: %m");
+		}
+		execvp(av[0], av);
+		fatal("execvp: %s: %m", av[0]);
+	}
+
 	if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
-		perror("listen");
+		error("listen: %m");
 		cleanup_exit(1);
 	}
 
@@ -1195,10 +1256,12 @@ main(int ac, char **av)
 	}
 	pid = fork();
 	if (pid == -1) {
-		perror("fork");
+		error("fork: %m");
 		cleanup_exit(1);
 	}
 	if (pid != 0) {		/* Parent - execute the given command. */
+		char pidstrbuf[1 + 3 * sizeof pid];
+
 		close(sock);
 		snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid);
 		if (ac == 0) {
@@ -1212,22 +1275,23 @@ main(int ac, char **av)
 		}
 		if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 ||
 		    setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) {
-			perror("setenv");
-			exit(1);
+			fatal("setenv: %m");
 		}
 		execvp(av[0], av);
-		perror(av[0]);
-		exit(1);
+		fatal("execvp: %s: %m", av[0]);
 	}
 	/* child */
 	log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0);
 
 	if (setsid() == -1) {
-		error("setsid: %s", strerror(errno));
+		error("setsid: %m");
 		cleanup_exit(1);
 	}
 
-	(void)chdir("/");
+	if (chdir("/") == -1) {
+		error("chdir: %m");
+		cleanup_exit(1);
+	}
 	if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
 		/* XXX might close listen socket */
 		(void)dup2(fd, STDIN_FILENO);
@@ -1241,14 +1305,14 @@ main(int ac, char **av)
 	/* deny core dumps, since memory contains unencrypted private keys */
 	rlim.rlim_cur = rlim.rlim_max = 0;
 	if (setrlimit(RLIMIT_CORE, &rlim) < 0) {
-		error("setrlimit RLIMIT_CORE: %s", strerror(errno));
+		error("setrlimit RLIMIT_CORE: %m");
 		cleanup_exit(1);
 	}
 #endif
 
 skip:
 	new_socket(AUTH_SOCKET, sock);
-	if (ac > 0)
+	if (!u_flag && ac > 0)
 		parent_alive_interval = 10;
 	idtab_init();
 	if (!d_flag)
diff --git a/ssh-keygen.1 b/ssh-keygen.1
index 4e629de..e4b05d1 100644
--- a/ssh-keygen.1
+++ b/ssh-keygen.1
@@ -192,7 +192,7 @@ Show the bubblebabble digest of specified private or public key file.
 Specifies the number of bits in the key to create.
 For RSA keys, the minimum size is 768 bits and the default is 2048 bits.
 Generally, 2048 bits is considered sufficient.
-DSA keys must be exactly 1024 bits as specified by FIPS 186-2.
+DSA keys must be at least 1024 bits.
 .It Fl C Ar comment
 Provides a new comment.
 .It Fl c
diff --git a/ssh-keygen.c b/ssh-keygen.c
index 69b16e6..40eaef6 100644
--- a/ssh-keygen.c
+++ b/ssh-keygen.c
@@ -1329,8 +1329,8 @@ main(int argc, char **argv)
 	}
 	if (bits == 0)
 		bits = (type == KEY_DSA) ? DEFAULT_BITS_DSA : DEFAULT_BITS;
-	if (type == KEY_DSA && bits != 1024)
-		fatal("DSA keys must be 1024 bits");
+	if (type == KEY_DSA && bits < 1024)
+		fatal("DSA keys must be at least 1024 bits");
 	if (!quiet)
 		printf("Generating public/private %s key pair.\n", key_type_name);
 	private = key_generate(type, bits);
diff --git a/ssh-keyscan.c b/ssh-keyscan.c
index 43ebfee..fade527 100644
--- a/ssh-keyscan.c
+++ b/ssh-keyscan.c
@@ -813,11 +813,11 @@ main(int argc, char **argv)
 
 	maxfd = fdlim_get(1);
 	if (maxfd < 0)
-		fatal("%s: fdlim_get: bad value", __progname);
+		fatal("fdlim_get: bad value");
 	if (maxfd > MAXMAXFD)
 		maxfd = MAXMAXFD;
 	if (MAXCON <= 0)
-		fatal("%s: not enough file descriptors", __progname);
+		fatal("not enough file descriptors");
 	if (maxfd > fdlim_get(0))
 		fdlim_set(maxfd);
 	fdcon = xcalloc(maxfd, sizeof(con));
diff --git a/ssh.0 b/ssh.0
index aedd6c7..86d1673 100644
--- a/ssh.0
+++ b/ssh.0
@@ -75,7 +75,7 @@ DESCRIPTION
              3des.  des is only supported in the ssh client for interoperabil-
              ity with legacy protocol 1 implementations that do not support
              the 3des cipher.  Its use is strongly discouraged due to crypto-
-             graphic weaknesses.  The default is ``3des''.
+             graphic weaknesses.  The default is ``blowfish''.
 
              For protocol version 2, cipher_spec is a comma-separated list of
              ciphers listed in order of preference.  The supported ciphers
@@ -83,9 +83,10 @@ DESCRIPTION
              aes192-ctr, aes256-ctr, arcfour128, arcfour256, arcfour, blow-
              fish-cbc, and cast128-cbc.  The default is:
 
-                   aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-                   arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-                   aes192-ctr,aes256-ctr
+		   aes256-ctr,aes192-ctr,aes128-ctr,
+		   blowfish-cbc,aes256-cbc,aes192-cbc,
+		   aes128-cbc,3des-cbc,cast128-cbc,
+		   arcfour256,arcfour128,arcfour
 
      -D [bind_address:]port
              Specifies a local ``dynamic'' application-level port forwarding.
@@ -367,15 +368,16 @@ DESCRIPTION
      error occurred.
 
 AUTHENTICATION
-     The OpenSSH SSH client supports SSH protocols 1 and 2.  Protocol 2 is the
-     default, with ssh falling back to protocol 1 if it detects protocol 2 is
-     unsupported.  These settings may be altered using the Protocol option in
-     ssh_config(5), or enforced using the -1 and -2 options (see above).  Both
-     protocols support similar authentication methods, but protocol 2 is pre-
-     ferred since it provides additional mechanisms for confidentiality (the
-     traffic is encrypted using AES, 3DES, Blowfish, CAST128, or Arcfour) and
-     integrity (hmac-md5, hmac-sha1, umac-64, hmac-ripemd160).  Protocol 1
-     lacks a strong mechanism for ensuring the integrity of the connection.
+     The OpenSSH SSH client supports SSH protocols 1 and 2.  Protocol 2 is
+     the default.  ssh can be configured to fall back to protocol 1 if it
+     detects protocol 2 is unsupported.  These settings may be altered using
+     the Protocol option in ssh_config(5), or enforced using the -1 and -2
+     options (see above).  Both protocols support similar authentication
+     methods, but protocol 2 is pre- ferred since it provides additional
+     mechanisms for confidentiality (the traffic is encrypted using AES,
+     3DES, Blowfish, CAST128, or Arcfour) and integrity (hmac-md5, hmac-sha1,
+     umac-64, hmac-ripemd160).  Protocol 1 lacks a strong mechanism for
+     ensuring the integrity of the connection.
 
      The methods available for authentication are: GSSAPI-based authentica-
      tion, host-based authentication, public key authentication, challenge-re-
@@ -432,8 +434,7 @@ AUTHENTICATION
      arbitrary "challenge" text, and prompts for a response.  Protocol 2 al-
      lows multiple challenges and responses; protocol 1 is restricted to just
      one challenge/response.  Examples of challenge-response authentication
-     include BSD Authentication (see login.conf(5)) and PAM (some non-OpenBSD
-     systems).
+     include BSD Authentication and PAM (some non-OpenBSD systems).
 
      Finally, if other authentication methods fail, ssh prompts the user for a
      password.  The password is sent to the remote host for checking; however,
diff --git a/ssh.1 b/ssh.1
index d62df90..e8e2b7f 100644
--- a/ssh.1
+++ b/ssh.1
@@ -185,7 +185,7 @@ that do not support the
 cipher.
 Its use is strongly discouraged due to cryptographic weaknesses.
 The default is
-.Dq 3des .
+.Dq blowfish .
 .Pp
 For protocol version 2,
 .Ar cipher_spec
@@ -207,9 +207,10 @@ and
 cast128-cbc.
 The default is:
 .Bd -literal -offset indent
-aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-aes192-ctr,aes256-ctr
+aes256-ctr,aes192-ctr,aes128-ctr,
+blowfish-cbc,aes256-cbc,aes192-cbc,
+aes128-cbc,3des-cbc,cast128-cbc,
+arcfour256,arcfour128,arcfour
 .Ed
 .It Fl D Xo
 .Sm off
@@ -661,9 +662,10 @@ exits with the exit status of the remote command or with 255
 if an error occurred.
 .Sh AUTHENTICATION
 The OpenSSH SSH client supports SSH protocols 1 and 2.
-Protocol 2 is the default, with
+Protocol 2 is the default.
 .Nm
-falling back to protocol 1 if it detects protocol 2 is unsupported.
+can be configured to fall back to protocol 1 if it detects
+protocol 2 is unsupported.
 These settings may be altered using the
 .Cm Protocol
 option in
@@ -796,9 +798,7 @@ text, and prompts for a response.
 Protocol 2 allows multiple challenges and responses;
 protocol 1 is restricted to just one challenge/response.
 Examples of challenge-response authentication include
-BSD Authentication (see
-.Xr login.conf 5 )
-and PAM (some non-OpenBSD systems).
+BSD Authentication and PAM (some non-OpenBSD systems).
 .Pp
 Finally, if other authentication methods fail,
 .Nm
diff --git a/ssh.c b/ssh.c
index 2ed76c9..9d1a4c2 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1503,8 +1503,8 @@ control_client(const char *path)
 	close(sock);
 	leave_raw_mode();
 	if (i > (int)sizeof(int))
-		fatal("%s: master returned too much data (%d > %lu)",
-		    __func__, i, sizeof(int));
+		fatal("%s: master returned too much data (%d > %u)",
+		    __func__, i, (unsigned)sizeof(int));
 	if (control_client_terminate) {
 		debug2("Exiting on signal %d", control_client_terminate);
 		exitval[0] = 255;
diff --git a/ssh_config b/ssh_config
index 8cb0698..24c56d1 100644
--- a/ssh_config
+++ b/ssh_config
@@ -17,7 +17,11 @@
 # list of available options, their meanings and defaults, please see the
 # ssh_config(5) man page.
 
-# Host *
+Host *
+    # Send locale environment variables
+    SendEnv LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE
+    SendEnv LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY
+    SendEnv LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME
 #   ForwardAgent no
 #   ForwardX11 no
 #   RhostsRSAAuthentication no
@@ -36,8 +40,8 @@
 #   IdentityFile ~/.ssh/id_dsa
 #   Port 22
 #   Protocol 2,1
-#   Cipher 3des
-#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
+#   Cipher blowfish
+#   Ciphers aes256-ctr,aes192-ctr,aes128-ctr,blowfish-cbc,aes256-cbc,aes192-cbc,aes128-cbc,3des-cbc,cast128-cbc,arcfour256,arcfour128,arcfour
 #   MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
 #   EscapeChar ~
 #   Tunnel no
diff --git a/ssh_config.0 b/ssh_config.0
index 005df34..354ad73 100644
--- a/ssh_config.0
+++ b/ssh_config.0
@@ -67,7 +67,7 @@ DESCRIPTION
      ChallengeResponseAuthentication
              Specifies whether to use challenge-response authentication.  The
              argument to this keyword must be ``yes'' or ``no''.  The default
-             is ``yes''.
+             is ``no''.
 
      CheckHostIP
              If this flag is set to ``yes'', ssh(1) will additionally check
@@ -81,7 +81,7 @@ DESCRIPTION
              are supported.  des is only supported in the ssh(1) client for
              interoperability with legacy protocol 1 implementations that do
              not support the 3des cipher.  Its use is strongly discouraged due
-             to cryptographic weaknesses.  The default is ``3des''.
+             to cryptographic weaknesses.  The default is ``blowfish''.
 
      Ciphers
              Specifies the ciphers allowed for protocol version 2 in order of
@@ -91,9 +91,10 @@ DESCRIPTION
              ``arcfour128'', ``arcfour256'', ``arcfour'', ``blowfish-cbc'',
              and ``cast128-cbc''.  The default is:
 
-                aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-                arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-                aes192-ctr,aes256-ctr
+		aes256-ctr,aes192-ctr,aes128-ctr,
+		blowfish-cbc,aes256-cbc,aes192-cbc,
+		aes128-cbc,3des-cbc,cast128-cbc,
+		arcfour256,arcfour128,arcfour
 
      ClearAllForwardings
              Specifies that all local, remote, and dynamic port forwardings
@@ -412,7 +413,7 @@ DESCRIPTION
      Protocol
              Specifies the protocol versions ssh(1) should support in order of
              preference.  The possible values are `1' and `2'.  Multiple ver-
-             sions must be comma-separated.  The default is ``2,1''.  This
+             sions must be comma-separated.  The default is ``2''.  Value ``2,1''
              means that ssh tries version 2 and falls back to version 1 if
              version 2 is not available.
 
@@ -603,7 +604,7 @@ DESCRIPTION
 
      XAuthLocation
              Specifies the full pathname of the xauth(1) program.  The default
-             is /usr/X11R6/bin/xauth.
+             is /usr/bin/xauth.
 
 PATTERNS
      A pattern consists of zero or more non-whitespace characters, `*' (a
diff --git a/ssh_config.5 b/ssh_config.5
index 17fc0ec..38ac507 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -150,7 +150,7 @@ The argument to this keyword must be
 or
 .Dq no .
 The default is
-.Dq yes .
+.Dq no .
 .It Cm CheckHostIP
 If this flag is set to
 .Dq yes ,
@@ -182,7 +182,7 @@ that do not support the
 cipher.
 Its use is strongly discouraged due to cryptographic weaknesses.
 The default is
-.Dq 3des .
+.Dq blowfish .
 .It Cm Ciphers
 Specifies the ciphers allowed for protocol version 2
 in order of preference.
@@ -203,9 +203,10 @@ and
 .Dq cast128-cbc .
 The default is:
 .Bd -literal -offset 3n
-aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-aes192-ctr,aes256-ctr
+aes256-ctr,aes192-ctr,aes128-ctr,
+blowfish-cbc,aes256-cbc,aes192-cbc,
+aes128-cbc,3des-cbc,cast128-cbc,
+arcfour256,arcfour128,arcfour
 .Ed
 .It Cm ClearAllForwardings
 Specifies that all local, remote, and dynamic port forwardings
@@ -715,8 +716,8 @@ and
 .Sq 2 .
 Multiple versions must be comma-separated.
 The default is
-.Dq 2,1 .
-This means that ssh
+.Dq 2 .
+Value "2,1" means that ssh
 tries version 2 and falls back to version 1
 if version 2 is not available.
 .It Cm ProxyCommand
@@ -1049,7 +1050,7 @@ Specifies the full pathname of the
 .Xr xauth 1
 program.
 The default is
-.Pa /usr/X11R6/bin/xauth .
+.Pa /usr/bin/xauth .
 .El
 .Sh PATTERNS
 A
diff --git a/sshconnect.c b/sshconnect.c
index a604c97..7f9c9e9 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -65,7 +65,6 @@ static int matching_host_key_dns = 0;
 
 /* import */
 extern Options options;
-extern char *__progname;
 extern uid_t original_real_uid;
 extern uid_t original_effective_uid;
 extern pid_t proxy_command_pid;
@@ -356,7 +355,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
 	hints.ai_socktype = SOCK_STREAM;
 	snprintf(strport, sizeof strport, "%u", port);
 	if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
-		fatal("%s: Could not resolve hostname %.100s: %s", __progname,
+		fatal("Could not resolve hostname %.100s: %s",
 		    host, ssh_gai_strerror(gaierr));
 
 	for (attempt = 0; attempt < connection_attempts; attempt++) {
@@ -407,7 +406,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
 
 	/* Return failure if we didn't get a successful connection. */
 	if (sock == -1) {
-		error("ssh: connect to host %s port %s: %s",
+		error("connect to host %s port %s: %s",
 		    host, strport, strerror(errno));
 		return (-1);
 	}
diff --git a/sshconnect1.c b/sshconnect1.c
index fd07bbf..dd82f8d 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -483,7 +483,7 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
 	BIGNUM *key;
 	Key *host_key, *server_key;
 	int bits, rbits;
-	int ssh_cipher_default = SSH_CIPHER_3DES;
+	int ssh_cipher_default = SSH_CIPHER_BLOWFISH;
 	u_char session_key[SSH_SESSION_KEY_LENGTH];
 	u_char cookie[8];
 	u_int supported_ciphers;
diff --git a/sshd.0 b/sshd.0
index 25c7c31..4940b4e 100644
--- a/sshd.0
+++ b/sshd.0
@@ -537,8 +537,8 @@ FILES
 
 SEE ALSO
      scp(1), sftp(1), ssh(1), ssh-add(1), ssh-agent(1), ssh-keygen(1),
-     ssh-keyscan(1), chroot(2), hosts_access(5), login.conf(5), moduli(5),
-     sshd_config(5), inetd(8), sftp-server(8)
+     ssh-keyscan(1), chroot(2), hosts_access(5), moduli(5), sshd_config(5),
+     inetd(8), sftp-server(8)
 
 AUTHORS
      OpenSSH is a derivative of the original and free ssh 1.2.12 release by
diff --git a/sshd.8 b/sshd.8
index c9476ad..6176658 100644
--- a/sshd.8
+++ b/sshd.8
@@ -843,7 +843,6 @@ The content of this file is not sensitive; it can be world-readable.
 .Xr ssh-keyscan 1 ,
 .Xr chroot 2 ,
 .Xr hosts_access 5 ,
-.Xr login.conf 5 ,
 .Xr moduli 5 ,
 .Xr sshd_config 5 ,
 .Xr inetd 8 ,
diff --git a/sshd.c b/sshd.c
index 5dfc2b1..7a7f3ca 100644
--- a/sshd.c
+++ b/sshd.c
@@ -118,6 +118,7 @@
 #include "monitor_wrap.h"
 #include "monitor_fdpass.h"
 #include "version.h"
+#include "blacklist.h"
 
 #ifdef LIBWRAP
 #include <tcpd.h>
@@ -598,6 +599,10 @@ privsep_preauth_child(void)
 	/* Demote the private keys to public keys. */
 	demote_sensitive_data();
 
+	/* Prepare chrooted syslogging. */
+	tzset();
+	log_init_chroot();
+
 	/* Change our root directory */
 	if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
 		fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
@@ -1110,15 +1115,18 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
 			}
 			if (unset_nonblock(*newsock) == -1) {
 				close(*newsock);
+				*newsock = -1;
 				continue;
 			}
 			if (drop_connection(startups) == 1) {
 				debug("drop connection #%d", startups);
 				close(*newsock);
+				*newsock = -1;
 				continue;
 			}
 			if (pipe(startup_p) == -1) {
 				close(*newsock);
+				*newsock = -1;
 				continue;
 			}
 
@@ -1127,6 +1135,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
 				error("reexec socketpair: %s",
 				    strerror(errno));
 				close(*newsock);
+				*newsock = -1;
 				close(startup_p[0]);
 				close(startup_p[1]);
 				continue;
@@ -1225,6 +1234,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
 			}
 
 			close(*newsock);
+			*newsock = -1;
 
 			/*
 			 * Ensure that our random state differs
@@ -1385,7 +1395,7 @@ main(int ac, char **av)
 			break;
 		}
 	}
-	if (rexeced_flag || inetd_flag)
+	if (rexeced_flag || inetd_flag || test_flag)
 		rexec_flag = 0;
 	if (!test_flag && (rexec_flag && (av[0] == NULL || *av[0] != '/')))
 		fatal("sshd re-exec requires execution with an absolute path");
@@ -1484,6 +1494,11 @@ main(int ac, char **av)
 			sensitive_data.host_keys[i] = NULL;
 			continue;
 		}
+		if (blacklisted_key(key, 1)) {
+			sensitive_data.host_keys[i] = NULL;
+			key_free(key);
+			continue;
+		}
 		switch (key->type) {
 		case KEY_RSA1:
 			sensitive_data.ssh1_host_key = key;
@@ -1612,7 +1627,8 @@ main(int ac, char **av)
 
 	/* Chdir to the root directory so that the current disk can be
 	   unmounted if desired. */
-	chdir("/");
+	if (chdir("/") == -1)
+		fatal("chdir(\"/\"): %s", strerror(errno));
 
 	/* ignore SIGPIPE */
 	signal(SIGPIPE, SIG_IGN);
@@ -1831,6 +1847,11 @@ main(int ac, char **av)
 	}
 
  authenticated:
+
+#ifdef HAVE_FCHOWN
+	fchown(newsock, authctxt->pw->pw_uid, authctxt->pw->pw_gid);
+#endif
+
 	/*
 	 * Cancel the alarm we set to limit the time taken for
 	 * authentication.
diff --git a/sshd_config b/sshd_config
index ddfbbe9..2dc94ff 100644
--- a/sshd_config
+++ b/sshd_config
@@ -11,15 +11,11 @@
 # default value.
 
 #Port 22
+#Protocol 2
 #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
@@ -32,13 +28,13 @@ Protocol 2
 
 # Logging
 # obsoletes QuietMode and FascistLogging
-#SyslogFacility AUTH
+#SyslogFacility AUTHPRIV
 #LogLevel INFO
 
 # Authentication:
 
 #LoginGraceTime 2m
-#PermitRootLogin yes
+#PermitRootLogin without-password
 #StrictModes yes
 #MaxAuthTries 6
 
@@ -60,8 +56,8 @@ Protocol 2
 #PasswordAuthentication yes
 #PermitEmptyPasswords no
 
-# Change to no to disable s/key passwords
-#ChallengeResponseAuthentication yes
+# Change to yes to enable s/key passwords
+#ChallengeResponseAuthentication no
 
 # Kerberos options
 #KerberosAuthentication no
@@ -82,11 +78,11 @@ Protocol 2
 # If you just want the PAM account and session checks to run without
 # PAM authentication, then enable this but set PasswordAuthentication
 # and ChallengeResponseAuthentication to 'no'.
-#UsePAM no
+#UsePAM yes
 
 #AllowTcpForwarding yes
 #GatewayPorts no
-#X11Forwarding no
+#X11Forwarding yes
 #X11DisplayOffset 10
 #X11UseLocalhost yes
 #PrintMotd yes
@@ -100,7 +96,7 @@ Protocol 2
 #ClientAliveCountMax 3
 #UseDNS yes
 #PidFile /var/run/sshd.pid
-#MaxStartups 10
+#MaxStartups 10:30:20
 #PermitTunnel no
 #ChrootDirectory none
 
@@ -108,10 +104,15 @@ Protocol 2
 #Banner none
 
 # override default of no subsystems
-Subsystem	sftp	/usr/libexec/sftp-server
+#Subsystem	sftp	/usr/libexec/sftp-server
+
+# Accept locale environment variables
+AcceptEnv LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE
+AcceptEnv LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY
+AcceptEnv LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME
 
 # Example of overriding settings on a per-user basis
 #Match User anoncvs
-#	X11Forwarding no
+#	X11Forwarding yes
 #	AllowTcpForwarding no
 #	ForceCommand cvs server
diff --git a/sshd_config.0 b/sshd_config.0
index cd6744b..d24aff5 100644
--- a/sshd_config.0
+++ b/sshd_config.0
@@ -83,8 +83,7 @@ DESCRIPTION
 
      ChallengeResponseAuthentication
              Specifies whether challenge-response authentication is allowed.
-             All authentication styles from login.conf(5) are supported.  The
-             default is ``yes''.
+             The default is ``no''.
 
      ChrootDirectory
              Specifies a path to chroot(2) to after authentication.  This
@@ -101,7 +100,7 @@ DESCRIPTION
              ries to support the users' session.  For an interactive session
              this requires at least a shell, typically sh(1), and basic /dev
              nodes such as null(4), zero(4), stdin(4), stdout(4), stderr(4),
-             arandom(4) and tty(4) devices.  For file transfer sessions using
+             urandom(4) and tty(4) devices.  For file transfer sessions using
              ``sftp'', no additional configuration of the environment is nec-
              essary if the in-process sftp server is used (see Subsystem for
              details).
@@ -116,9 +115,10 @@ DESCRIPTION
              ``arcfour256'', ``arcfour'', ``blowfish-cbc'', and
              ``cast128-cbc''.  The default is:
 
-                aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-                arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-                aes192-ctr,aes256-ctr
+		aes256-ctr,aes192-ctr,aes128-ctr,
+		blowfish-cbc,aes256-cbc,aes192-cbc,
+		aes128-cbc,3des-cbc,cast128-cbc,
+		arcfour256,arcfour128,arcfour
 
      ClientAliveCountMax
              Sets the number of client alive messages (see below) which may be
@@ -334,7 +334,7 @@ DESCRIPTION
              Specifies the maximum number of concurrent unauthenticated con-
              nections to the SSH daemon.  Additional connections will be
              dropped until authentication succeeds or the LoginGraceTime ex-
-             pires for a connection.  The default is 10.
+             pires for a connection.
 
              Alternatively, random early drop can be enabled by specifying the
              three colon separated values ``start:rate:full'' (e.g.
@@ -344,6 +344,8 @@ DESCRIPTION
              creases linearly and all connection attempts are refused if the
              number of unauthenticated connections reaches ``full'' (60).
 
+             The default is 10:30:20.
+
      PasswordAuthentication
              Specifies whether password authentication is allowed.  The de-
              fault is ``yes''.
@@ -370,7 +372,7 @@ DESCRIPTION
      PermitRootLogin
              Specifies whether root can log in using ssh(1).  The argument
              must be ``yes'', ``without-password'', ``forced-commands-only'',
-             or ``no''.  The default is ``yes''.
+             or ``no''.  The default is ``without-password''.
 
              If this option is set to ``without-password'', password authenti-
              cation is disabled for root.
@@ -417,7 +419,7 @@ DESCRIPTION
      Protocol
              Specifies the protocol versions sshd(8) supports.  The possible
              values are `1' and `2'.  Multiple versions must be comma-separat-
-             ed.  The default is ``2,1''.  Note that the order of the protocol
+             ed.  The default is ``2''.  Note that the order of the protocol
              list does not indicate preference, because the client selects
              among multiple protocol versions offered by the server.  Specify-
              ing ``2,1'' is identical to ``1,2''.
@@ -466,9 +468,9 @@ DESCRIPTION
 
      SyslogFacility
              Gives the facility code that is used when logging messages from
-             sshd(8).  The possible values are: DAEMON, USER, AUTH, LOCAL0,
-             LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.  The de-
-             fault is AUTH.
+             sshd(8).  The possible values are: DAEMON, USER, AUTH, AUTHPRIV,
+             LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
+             The default is AUTHPRIV.
 
      TCPKeepAlive
              Specifies whether the system should send TCP keepalive messages
@@ -510,7 +512,7 @@ DESCRIPTION
              either PasswordAuthentication or ChallengeResponseAuthentication.
 
              If UsePAM is enabled, you will not be able to run sshd(8) as a
-             non-root user.  The default is ``no''.
+             non-root user.  The default is ``yes''.
 
      UsePrivilegeSeparation
              Specifies whether sshd(8) separates privileges by creating an un-
@@ -528,7 +530,7 @@ DESCRIPTION
 
      X11Forwarding
              Specifies whether X11 forwarding is permitted.  The argument must
-             be ``yes'' or ``no''.  The default is ``no''.
+             be ``yes'' or ``no''.  The default is ``yes''.
 
              When X11 forwarding is enabled, there may be additional exposure
              to the server and to client displays if the sshd(8) proxy display
@@ -562,7 +564,7 @@ DESCRIPTION
 
      XAuthLocation
              Specifies the full pathname of the xauth(1) program.  The default
-             is /usr/X11R6/bin/xauth.
+             is /usr/bin/xauth.
 
 TIME FORMATS
      sshd(8) command-line arguments and configuration file options that speci-
diff --git a/sshd_config.5 b/sshd_config.5
index 510ff9c..548c382 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -158,6 +158,23 @@ is taken to be an absolute path or one relative to the user's home
 directory.
 The default is
 .Dq .ssh/authorized_keys .
+.It Cm AuthorizedKeysSystemFile
+Specifies the file that contains the public keys that can be used
+for user authentication.
+.Cm AuthorizedKeysSystemFile
+may contain tokens of the form %T which are substituted during connection
+set-up. The following tokens are defined: %% 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.
+After expansion,
+.Cm AuthorizedKeysSystemFile
+is taken to be an absolute path or one relative to the user's home
+directory.
+If that file exists, it will be tried before
+.Cm AuthorizedKeysFile
+file.
+The default is
+.Dq /etc/openssh/authorized_keys/%u .
 .It Cm Banner
 The contents of the specified file are sent to the remote user before
 authentication is allowed.
@@ -168,11 +185,8 @@ This option is only available for protocol version 2.
 By default, no banner is displayed.
 .It Cm ChallengeResponseAuthentication
 Specifies whether challenge-response authentication is allowed.
-All authentication styles from
-.Xr login.conf 5
-are supported.
 The default is
-.Dq yes .
+.Dq no .
 .It Cm ChrootDirectory
 Specifies a path to
 .Xr chroot 2
@@ -199,7 +213,7 @@ nodes such as
 .Xr stdin 4 ,
 .Xr stdout 4 ,
 .Xr stderr 4 ,
-.Xr arandom 4
+.Xr urandom 4
 and
 .Xr tty 4
 devices.
@@ -231,9 +245,10 @@ and
 .Dq cast128-cbc .
 The default is:
 .Bd -literal -offset 3n
-aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-aes192-ctr,aes256-ctr
+aes256-ctr,aes192-ctr,aes128-ctr,
+blowfish-cbc,aes256-cbc,aes192-cbc,
+aes128-cbc,3des-cbc,cast128-cbc,
+arcfour256,arcfour128,arcfour
 .Ed
 .It Cm ClientAliveCountMax
 Sets the number of client alive messages (see below) which may be
@@ -589,7 +604,6 @@ SSH daemon.
 Additional connections will be dropped until authentication succeeds or the
 .Cm LoginGraceTime
 expires for a connection.
-The default is 10.
 .Pp
 Alternatively, random early drop can be enabled by specifying
 the three colon separated values
@@ -607,10 +621,45 @@ The probability increases linearly and all connection attempts
 are refused if the number of unauthenticated connections reaches
 .Dq full
 (60).
+.Pp
+The default is 10:30:20.
 .It Cm PasswordAuthentication
 Specifies whether password authentication is allowed.
 The default is
 .Dq yes .
+.It Cm IgnoreBlacklistErrors
+Specifies whether
+.Xr sshd 8
+should allow keys recorded in its blacklist of known-compromised keys.
+If
+.Dq all ,
+then attempts to authenticate with compromised keys will be logged
+but accepted.
+If
+.Dq access ,
+then attempts to authenticate with compromised keys will be rejected,
+but blacklist file access errors will be ignored.
+If
+.Dq format ,
+then attempts to authenticate with compromised keys will be rejected, but
+blacklist file access errors due to missing blacklist file or blacklist
+file unrecognized format will be ignored.
+If
+.Dq version ,
+then attempts to authenticate with compromised keys will be rejected, but
+blacklist file access errors due to missing blacklist file or blacklist
+file format version mismatch will be ignored.
+If
+.Dq missing ,
+then attempts to authenticate with compromised keys will be rejected,
+but blacklist file access errors due to missing blacklist file will
+be ignored.
+If
+.Dq none ,
+then attempts to authenticate with compromised keys, or in case of
+any blacklist file access error, will be rejected.
+The default is
+.Dq version .
 .It Cm PermitEmptyPasswords
 When password authentication is allowed, it specifies whether the
 server allows login to accounts with empty password strings.
@@ -653,7 +702,7 @@ The argument must be
 or
 .Dq no .
 The default is
-.Dq yes .
+.Dq without-password .
 .Pp
 If this option is set to
 .Dq without-password ,
@@ -746,7 +795,7 @@ and
 .Sq 2 .
 Multiple versions must be comma-separated.
 The default is
-.Dq 2,1 .
+.Dq 2 .
 Note that the order of the protocol list does not indicate preference,
 because the client selects among multiple protocol versions offered
 by the server.
@@ -807,9 +856,9 @@ Note that this option applies to protocol version 2 only.
 .It Cm SyslogFacility
 Gives the facility code that is used when logging messages from
 .Xr sshd 8 .
-The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
+The possible values are: DAEMON, USER, AUTH, AUTHPRIV, LOCAL0, LOCAL1, LOCAL2,
 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
-The default is AUTH.
+The default is AUTHPRIV.
 .It Cm TCPKeepAlive
 Specifies whether the system should send TCP keepalive messages to the
 other side.
@@ -881,7 +930,7 @@ is enabled, you will not be able to run
 .Xr sshd 8
 as a non-root user.
 The default is
-.Dq no .
+.Dq yes .
 .It Cm UsePrivilegeSeparation
 Specifies whether
 .Xr sshd 8
@@ -906,7 +955,7 @@ The argument must be
 or
 .Dq no .
 The default is
-.Dq no .
+.Dq yes .
 .Pp
 When X11 forwarding is enabled, there may be additional exposure to
 the server and to client displays if the
@@ -963,7 +1012,7 @@ Specifies the full pathname of the
 .Xr xauth 1
 program.
 The default is
-.Pa /usr/X11R6/bin/xauth .
+.Pa /usr/bin/xauth .
 .El
 .Sh TIME FORMATS
 .Xr sshd 8
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin