- markus@cvs.openbsd.org 2003/08/26 09:58:43
     [auth-passwd.c auth.c auth.h auth1.c auth2-none.c auth2-passwd.c]
     [auth2.c monitor.c]
     fix passwd auth for 'username leaks via timing'; with djm@, original
     patches from solar
diff --git a/ChangeLog b/ChangeLog
index ea6aaed..f91e452 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+20030903
+ - (djm) OpenBSD CVS Sync
+   - markus@cvs.openbsd.org 2003/08/26 09:58:43
+     [auth-passwd.c auth.c auth.h auth1.c auth2-none.c auth2-passwd.c]
+     [auth2.c monitor.c]
+     fix passwd auth for 'username leaks via timing'; with djm@, original 
+     patches from solar
+
 20030902
  - (djm) OpenBSD CVS Sync
    - deraadt@cvs.openbsd.org 2003/08/24 17:36:51
@@ -968,4 +976,4 @@
  - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
    Report from murple@murple.net, diagnosis from dtucker@zip.com.au
 
-$Id: ChangeLog,v 1.2937 2003/09/02 13:33:42 djm Exp $
+$Id: ChangeLog,v 1.2938 2003/09/02 21:32:45 djm Exp $
diff --git a/auth-passwd.c b/auth-passwd.c
index a5d23b6..57a2d36 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -36,7 +36,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-passwd.c,v 1.28 2003/07/22 13:35:22 markus Exp $");
+RCSID("$OpenBSD: auth-passwd.c,v 1.29 2003/08/26 09:58:43 markus Exp $");
 
 #include "packet.h"
 #include "log.h"
@@ -62,25 +62,22 @@
 
 	/* deny if no user. */
 	if (pw == NULL)
-		ok = 0;
+		return 0;
 #ifndef HAVE_CYGWIN
 	if (pw && pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
 		ok = 0;
 #endif
 	if (*password == '\0' && options.permit_empty_passwd == 0)
-		ok = 0;
-
-	if (!ok)
 		return 0;
 
 #if defined(HAVE_OSF_SIA)
-	return auth_sia_password(authctxt, password);
+	return auth_sia_password(authctxt, password) && ok;
 #else
 # ifdef KRB5
 	if (options.kerberos_authentication == 1) {
 		int ret = auth_krb5_password(authctxt, password);
 		if (ret == 1 || ret == 0)
-			return ret;
+			return ret && ok;
 		/* Fall back to ordinary passwd authentication. */
 	}
 # endif
@@ -89,30 +86,32 @@
 		HANDLE hToken = cygwin_logon_user(pw, password);
 
 		if (hToken == INVALID_HANDLE_VALUE)
-			return (0);
+			return 0;
 		cygwin_set_impersonation_token(hToken);
-		return (1);
+		return ok;
 	}
 # endif
 # ifdef WITH_AIXAUTHENTICATE
 	{
-		char *authmsg;
+		char *authmsg = NULL;
 		int reenter = 1;
-		int authsuccess = (authenticate(pw->pw_name, password, 
-		    &reenter, &authmsg) == 0);
-		aix_remove_embedded_newlines(authmsg);	
+		int authsuccess = 0;
 
-		if (authsuccess) {
+		if (authenticate(pw->pw_name, password, &reenter,
+		    &authmsg) == 0 && ok) {
 			char *msg;
 			char *host = 
 			    (char *)get_canonical_hostname(options.use_dns);
 
+			authsuccess = 1;
+			aix_remove_embedded_newlines(authmsg);	
+
 			debug3("AIX/authenticate succeeded for user %s: %.100s",
 				pw->pw_name, authmsg);
 
 	        	/* No pty yet, so just label the line as "ssh" */
 	        	if (loginsuccess(authctxt->user, host, "ssh", 
-			    &msg) == 0){
+			    &msg) == 0) {
 				if (msg != NULL) {
 					debug("%s: msg %s", __func__, msg);
 					buffer_append(&loginmsg, msg, 
@@ -120,14 +119,15 @@
 					xfree(msg);
 				}
 			}
-		} else 
+		} else {
 			debug3("AIX/authenticate failed for user %s: %.100s",
 			    pw->pw_name, authmsg);
+		}
 
 		if (authmsg != NULL)
 			xfree(authmsg);
 
-		return (authsuccess);
+		return authsuccess;
 	}
 # endif
 # ifdef BSD_AUTH
@@ -135,15 +135,15 @@
 	    (char *)password) == 0)
 		return 0;
 	else
-		return 1;
+		return ok;
 # else
 	{
-	char *pw_password = shadow_pw(pw);
+	/* Just use the supplied fake password if authctxt is invalid */
+	char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
 
 	/* Check for users with no password. */
-	/* XXX Reverted back to OpenBSD, why was this changed again? */
 	if (strcmp(pw_password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
-		return 1;
+		return ok;
 	else {
 		/* Encrypt the candidate password using the proper salt. */
 		char *encrypted_password = xcrypt(password,
@@ -153,7 +153,7 @@
 		 * Authentication is accepted if the encrypted passwords
 		 * are identical.
 		 */
-		return (strcmp(encrypted_password, pw_password) == 0);
+		return (strcmp(encrypted_password, pw_password) == 0) && ok;
 	}
 
 	}
diff --git a/auth.c b/auth.c
index f645cc1..46e495a 100644
--- a/auth.c
+++ b/auth.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.48 2003/06/02 09:17:34 markus Exp $");
+RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $");
 
 #ifdef HAVE_LOGIN_H
 #include <login.h>
@@ -589,3 +589,24 @@
 		auth_debug_init = 1;
 	}
 }
+
+struct passwd *
+fakepw(void)
+{
+	static struct passwd fake;
+
+	memset(&fake, 0, sizeof(fake));
+	fake.pw_name = "NOUSER";
+	fake.pw_passwd =
+	    "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK";	
+	fake.pw_gecos = "NOUSER";
+	fake.pw_uid = -1;
+	fake.pw_gid = -1;
+#ifdef HAVE_PW_CLASS_IN_PASSWD
+	fake.pw_class = "";
+#endif
+	fake.pw_dir = "/nonexist";
+	fake.pw_shell = "/nonexist";
+
+	return (&fake);
+}
diff --git a/auth.h b/auth.h
index 358f26b..130a27d 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $	*/
+/*	$OpenBSD: auth.h,v 1.45 2003/08/26 09:58:43 markus Exp $	*/
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -173,6 +173,8 @@
 void	 auth_debug_send(void);
 void	 auth_debug_reset(void);
 
+struct passwd *fakepw(void);
+
 #define AUTH_FAIL_MAX 6
 #define AUTH_FAIL_LOG (AUTH_FAIL_MAX/2)
 #define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
diff --git a/auth1.c b/auth1.c
index 5b1922a..dfe944d 100644
--- a/auth1.c
+++ b/auth1.c
@@ -299,8 +299,10 @@
 	/* Verify that the user is a valid user. */
 	if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
 		authctxt->valid = 1;
-	else
+	else {
 		debug("do_authentication: illegal user %s", user);
+		authctxt->pw = fakepw();
+	}
 
 	setproctitle("%s%s", authctxt->pw ? user : "unknown",
 	    use_privsep ? " [net]" : "");
diff --git a/auth2-none.c b/auth2-none.c
index 3332f4f..c342add 100644
--- a/auth2-none.c
+++ b/auth2-none.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-none.c,v 1.5 2003/07/31 09:21:02 markus Exp $");
+RCSID("$OpenBSD: auth2-none.c,v 1.6 2003/08/26 09:58:43 markus Exp $");
 
 #include "auth.h"
 #include "xmalloc.h"
@@ -100,7 +100,7 @@
 	if (check_nt_auth(1, authctxt->pw) == 0)
 		return(0);
 #endif
-	if (options.password_authentication && authctxt->valid)
+	if (options.password_authentication)
 		return (PRIVSEP(auth_password(authctxt, "")));
 	return (0);
 }
diff --git a/auth2-passwd.c b/auth2-passwd.c
index 8eb18f2..67fb4c9 100644
--- a/auth2-passwd.c
+++ b/auth2-passwd.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2-passwd.c,v 1.3 2003/04/08 20:21:28 itojun Exp $");
+RCSID("$OpenBSD: auth2-passwd.c,v 1.4 2003/08/26 09:58:43 markus Exp $");
 
 #include "xmalloc.h"
 #include "packet.h"
@@ -47,7 +47,7 @@
 		logit("password change not supported");
 	password = packet_get_string(&len);
 	packet_check_eom();
-	if (PRIVSEP(auth_password(authctxt, password)) == 1 && authctxt->valid
+	if (PRIVSEP(auth_password(authctxt, password)) == 1
 #ifdef HAVE_CYGWIN
 	    && check_nt_auth(1, authctxt->pw)
 #endif
diff --git a/auth2.c b/auth2.c
index efff03a..41e77ef 100644
--- a/auth2.c
+++ b/auth2.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.101 2003/08/22 13:22:27 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $");
 
 #include "ssh2.h"
 #include "xmalloc.h"
@@ -168,6 +168,7 @@
 #endif
 		} else {
 			logit("input_userauth_request: illegal user %s", user);
+			authctxt->pw = fakepw();
 #ifdef USE_PAM
 			if (options.use_pam)
 				PRIVSEP(start_pam(user));
diff --git a/monitor.c b/monitor.c
index 9ea7b93..e565647 100644
--- a/monitor.c
+++ b/monitor.c
@@ -649,7 +649,7 @@
 	passwd = buffer_get_string(m, &plen);
 	/* Only authenticate if the context is valid */
 	authenticated = options.password_authentication &&
-	    auth_password(authctxt, passwd) && authctxt->valid;
+	    auth_password(authctxt, passwd);
 	memset(passwd, 0, strlen(passwd));
 	xfree(passwd);