- (dtucker) [auth-pam.c] Use an invalid password for root if
   PermitRootLogin != yes or the login is invalid, to prevent leaking
   information.  Based on Openwall's owl-always-auth patch.  ok djm@
diff --git a/ChangeLog b/ChangeLog
index f3f2fc3..6782c0f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 20040530
- - (dtucker) [auth-pam.c auth-pam.h auth-passwd.c]: Bug #874: Re-add PAM 
+ - (dtucker) [auth-pam.c auth-pam.h auth-passwd.c] Bug #874: Re-add PAM 
    support for PasswordAuthentication=yes.  ok djm@
+ - (dtucker) [auth-pam.c] Use an invalid password for root if
+   PermitRootLogin != yes or the login is invalid, to prevent leaking
+   information.  Based on Openwall's owl-always-auth patch.  ok djm@
 
 20040527
  - (dtucker) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec
@@ -1167,4 +1170,4 @@
    - (djm) Trim deprecated options from INSTALL. Mention UsePAM
    - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
 
-$Id: ChangeLog,v 1.3369 2004/05/30 10:43:59 dtucker Exp $
+$Id: ChangeLog,v 1.3370 2004/05/30 12:04:56 dtucker Exp $
diff --git a/auth-pam.c b/auth-pam.c
index 8de90a3..b6fc49e 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -31,7 +31,7 @@
 
 /* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
 #include "includes.h"
-RCSID("$Id: auth-pam.c,v 1.103 2004/05/30 10:43:59 dtucker Exp $");
+RCSID("$Id: auth-pam.c,v 1.104 2004/05/30 12:04:56 dtucker Exp $");
 
 #ifdef USE_PAM
 #if defined(HAVE_SECURITY_PAM_APPL_H)
@@ -1021,6 +1021,7 @@
 {
 	int flags = (options.permit_empty_passwd == 0 ?
 	    PAM_DISALLOW_NULL_AUTHTOK : 0);
+	static char badpw[] = "\b\n\r\177INCORRECT";
 
 	if (!options.use_pam || sshpam_handle == NULL)
 		fatal("PAM: %s called when PAM disabled or failed to "
@@ -1029,6 +1030,15 @@
 	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
+	 * information via timing (eg if the PAM config has a delay on fail).
+	 */
+	if (!authctxt->valid || (authctxt->pw->pw_uid == 0 &&
+	     options.permit_root_login != PERMIT_YES))
+		sshpam_password = badpw;
+
 	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
 	    (const void *)&passwd_conv);
 	if (sshpam_err != PAM_SUCCESS)