Timing attacks and owl-always-auth

Darren Tucker dtucker at zip.com.au
Sat Aug 9 15:12:45 EST 2003


Hi All.
	Attached is a patch against OpenBSD, based in part on the owl-always-auth
patch.

	The idea is that the only way out of auth_passwd for the failure case is
the "return 0" at the bottom.

	I don't know if this is a good way to do it or not, it's presented for
discussion.

	Also, I don't think 3.6.1p2 is quite right WRT these timing issues (eg,
you get a fast failure if you get the root password right and
PermitRootLogin=no, and there's the infamous delay due to the "none"
authentication).

-- 
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4  37C9 C982 80C7 8FF4 FA69
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
-------------- next part --------------
Index: auth-passwd.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/auth-passwd.c,v
retrieving revision 1.28
diff -u -p -r1.28 auth-passwd.c
--- auth-passwd.c	2003/07/22 13:35:22	1.28
+++ auth-passwd.c	2003/08/09 04:45:13
@@ -43,9 +43,17 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.28 20
 #include "servconf.h"
 #include "auth.h"
 
-
 extern ServerOptions options;
+int auth_ok;
 
+int
+auth_result(int result)
+{
+	if (result == 0)
+		auth_ok = 0;
+	return auth_ok;
+}
+
 /*
  * Tries to authenticate the user using password.  Returns true if
  * authentication succeeds.
@@ -54,42 +62,52 @@ int
 auth_password(Authctxt *authctxt, const char *password)
 {
 	struct passwd * pw = authctxt->pw;
+	char *user = authctxt->user;
+	int success;
+
+	auth_ok = authctxt->valid;
 
 	/* deny if no user. */
 	if (pw == NULL)
-		return 0;
+		auth_result(0);
 	if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
-		return 0;
+		auth_result(0);
 	if (*password == '\0' && options.permit_empty_passwd == 0)
-		return 0;
+		auth_result(0);
 #ifdef KRB5
 	if (options.kerberos_authentication == 1) {
-		int ret = auth_krb5_password(authctxt, password);
-		if (ret == 1 || ret == 0)
-			return ret;
+		success = auth_krb5_password(authctxt, password);
+		if (success == 1 || success == 0)
+			if (auth_result(success) == 1)
+				return 1;
 		/* Fall back to ordinary passwd authentication. */
 	}
 #endif
 #ifdef BSD_AUTH
-	if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh",
-	    (char *)password) == 0)
-		return 0;
-	else
+	success = (auth_userokay(user, authctxt->style, "auth-ssh",
+	    (char *)password) == 0);
+	if (auth_result(success) == 1)
 		return 1;
 #else
 	/* Check for users with no password. */
-	if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
+	success = (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
+	if (auth_result(success) == 1)
 		return 1;
 	else {
 		/* Encrypt the candidate password using the proper salt. */
 		char *encrypted_password = crypt(password,
-		    (pw->pw_passwd[0] && pw->pw_passwd[1]) ?
+		    (pw && pw->pw_passwd[0] && pw->pw_passwd[1]) ?
 		    pw->pw_passwd : "xx");
 		/*
 		 * Authentication is accepted if the encrypted passwords
 		 * are identical.
 		 */
-		return (strcmp(encrypted_password, pw->pw_passwd) == 0);
+		if (pw) {
+			success = (strcmp(encrypted_password, pw->pw_passwd) == 0);
+			if (auth_result(success) == 1)
+				return 1;
+		}
 	}
+	return 0;
 #endif
 }
Index: auth2-none.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/auth2-none.c,v
retrieving revision 1.5
diff -u -p -r1.5 auth2-none.c
--- auth2-none.c	2003/07/31 09:21:02	1.5
+++ auth2-none.c	2003/08/09 04:45:13
@@ -96,7 +96,7 @@ userauth_none(Authctxt *authctxt)
 	none_enabled = 0;
 	packet_check_eom();
 	userauth_banner();
-	if (options.password_authentication && authctxt->valid)
+	if (options.password_authentication && options.permit_empty_passwd)
 		return (PRIVSEP(auth_password(authctxt, "")));
 	return (0);
 }


More information about the openssh-unix-dev mailing list