From 96d0bf7425ca8150a1697abb8a7c4cef88b7b580 Mon Sep 17 00:00:00 2001 From: djm Date: Tue, 2 Sep 2003 21:32:45 +0000 Subject: [PATCH] - 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 --- ChangeLog | 8 ++++++++ auth-passwd.c | 44 ++++++++++++++++++++++---------------------- auth.c | 23 ++++++++++++++++++++++- auth.h | 4 +++- auth1.c | 4 +++- auth2-none.c | 4 ++-- auth2-passwd.c | 4 ++-- auth2.c | 3 ++- monitor.c | 2 +- 9 files changed, 65 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 76647dd3..644bbddf 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 diff --git a/auth-passwd.c b/auth-passwd.c index a5d23b6b..57a2d362 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 @@ auth_password(Authctxt *authctxt, const char *password) /* 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 @@ auth_password(Authctxt *authctxt, const char *password) 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 @@ auth_password(Authctxt *authctxt, const char *password) 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 @@ auth_password(Authctxt *authctxt, const char *password) (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 @@ auth_password(Authctxt *authctxt, const char *password) * 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 f645cc11..46e495ad 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 @@ -589,3 +589,24 @@ auth_debug_reset(void) 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 358f26b7..130a27da 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_add(const char *fmt,...) __attribute__((format(printf, 1, 2))); 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 5b1922a1..dfe944dd 100644 --- a/auth1.c +++ b/auth1.c @@ -299,8 +299,10 @@ do_authentication(void) /* 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 3332f4f8..c342adde 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 @@ userauth_none(Authctxt *authctxt) 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 8eb18f2e..67fb4c92 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 @@ userauth_passwd(Authctxt *authctxt) 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 efff03a5..41e77efd 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 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) #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 9ea7b93b..e5656470 100644 --- a/monitor.c +++ b/monitor.c @@ -649,7 +649,7 @@ mm_answer_authpassword(int socket, Buffer *m) 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); -- 2.45.1