On Thu, 2009-04-02 at 21:54 +0800, Matt Johnston wrote:
> On Thu, Mar 26, 2009 at 02:05:02AM -0400, Paul Smith wrote:
> > In openssh I can do this by setting the SSH daemon parameter to not fail
> > on empty passwords.
> > 
> > Is there any interest in something like this?
> 
> I guess that would be useful - patches happily accepted :)

OK, attached.

This works for me, although the implementation is slightly different in
"tone" than the existing auth checkers (for example it returns
true/false).  That's because it seemed to me that the "none" method
couldn't be handled identically, especially if it continues to be
ifdef'd out with ENABLE_SVR_PASSWORD_AUTH, although if that
"requirement" is removed things could be much simpler.

Probably with enough noodling it could be made better.

> > The second thing is that a have a number of systems already deployed,
> > and they contain host keys generated by OpenSSH's keygen.  However, when
> > I try to invoke the dropbear server and point it at those
> > OpenSSH-generated keys, it just fails for me with an error about a line
> > that's too long.  Is it possible to get dropbear to use an
> > OpenSSH-generated host key?
> 
> The dropbearconvert program can convert to/from OpenSSH
> keys, as long as they are not encrypted.

That worked perfectly.  Thanks!
diff -ur a/auth.h b/auth.h
--- a/auth.h	2008-03-27 09:17:14.000000000 -0400
+++ b/auth.h	2009-04-02 15:11:28.000000000 -0400
@@ -34,6 +34,7 @@
 void recv_msg_userauth_request();
 void send_msg_userauth_failure(int partial, int incrfail);
 void send_msg_userauth_success();
+int svr_auth_none();
 void svr_auth_password();
 void svr_auth_pubkey();
 void svr_auth_pam();
diff -ur a/cli-runopts.c b/cli-runopts.c
--- a/cli-runopts.c	2008-03-27 09:17:14.000000000 -0400
+++ b/cli-runopts.c	2009-04-02 13:02:26.000000000 -0400
@@ -59,6 +59,7 @@
 #ifdef ENABLE_CLI_LOCALTCPFWD
 					"-L <listenport:remotehost:remoteport> Local port forwarding\n"
 					"-g    Allow remote hosts to connect to forwarded ports\n"
+					"-G    Allow empty passwords\n"
 #endif
 #ifdef ENABLE_CLI_REMOTETCPFWD
 					"-R <listenport:remotehost:remoteport> Remote port forwarding\n"
diff -ur a/dropbear.8 b/dropbear.8
--- a/dropbear.8	2008-03-27 09:17:14.000000000 -0400
+++ b/dropbear.8	2009-04-02 14:13:23.000000000 -0400
@@ -54,6 +54,9 @@
 .B \-g
 Disable password logins for root.
 .TP
+.B \-G
+Allow empty passwords.
+.TP
 .B \-j
 Disable local port forwarding.
 .TP
diff -ur a/runopts.h b/runopts.h
--- a/runopts.h	2008-03-27 09:17:15.000000000 -0400
+++ b/runopts.h	2009-04-02 12:54:39.000000000 -0400
@@ -77,6 +77,8 @@
 	int noauthpass;
 	int norootpass;
 
+	int needpasswd;
+
 #ifdef ENABLE_SVR_REMOTETCPFWD
 	int noremotetcp;
 #endif
diff -ur a/svr-auth.c b/svr-auth.c
--- a/svr-auth.c	2008-03-27 09:17:16.000000000 -0400
+++ b/svr-auth.c	2009-04-02 16:22:17.000000000 -0400
@@ -139,15 +139,6 @@
 		m_free(methodname);
 		dropbear_exit("unknown service in auth");
 	}
-
-	/* user wants to know what methods are supported */
-	if (methodlen == AUTH_METHOD_NONE_LEN &&
-			strncmp(methodname, AUTH_METHOD_NONE,
-				AUTH_METHOD_NONE_LEN) == 0) {
-		TRACE(("recv_msg_userauth_request: 'none' request"))
-		send_msg_userauth_failure(0, 0);
-		goto out;
-	}
 	
 	/* check username is good before continuing */
 	if (checkusername(username, userlen) == DROPBEAR_FAILURE) {
@@ -157,6 +148,17 @@
 		goto out;
 	}
 
+	/* allow 'none' if empty passwords are allowed */
+	if (methodlen == AUTH_METHOD_NONE_LEN &&
+			strncmp(methodname, AUTH_METHOD_NONE,
+				AUTH_METHOD_NONE_LEN) == 0) {
+		TRACE(("recv_msg_userauth_request: 'none' request"))
+		if (svr_opts.needpasswd || svr_auth_none() == 0) {
+			send_msg_userauth_failure(0, 0);
+		}
+		goto out;
+	}
+
 #ifdef ENABLE_SVR_PASSWORD_AUTH
 	if (!svr_opts.noauthpass &&
 			!(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) {
@@ -272,7 +274,7 @@
 	}
 
 	/* check for an empty password */
-	if (ses.authstate.pw_passwd[0] == '\0') {
+	if (svr_opts.needpasswd && ses.authstate.pw_passwd[0] == '\0') {
 		TRACE(("leave checkusername: empty pword"))
 		dropbear_log(LOG_WARNING, "user '%s' has blank password, rejected",
 				ses.authstate.pw_name);
diff -ur a/svr-authpasswd.c b/svr-authpasswd.c
--- a/svr-authpasswd.c	2008-03-27 09:17:16.000000000 -0400
+++ b/svr-authpasswd.c	2009-04-02 16:45:59.000000000 -0400
@@ -29,6 +29,46 @@
 #include "buffer.h"
 #include "dbutil.h"
 #include "auth.h"
+#include "runopts.h"
+
+/* Process a 'none' auth request, sending success if appropriate.
+ * Return true if we authenticated, false if not--if false we didn't respond */
+int svr_auth_none() {
+
+#ifdef ENABLE_SVR_PASSWORD_AUTH
+	
+#ifdef HAVE_SHADOW_H
+	struct spwd *spasswd = NULL;
+#endif
+	char * passwdcrypt = NULL; /* the crypt from /etc/passwd or /etc/shadow */
+
+	passwdcrypt = ses.authstate.pw_passwd;
+#ifdef HAVE_SHADOW_H
+	/* get the shadow password if possible */
+	spasswd = getspnam(ses.authstate.pw_name);
+	if (spasswd != NULL && spasswd->sp_pwdp != NULL) {
+		passwdcrypt = spasswd->sp_pwdp;
+	}
+#endif
+
+	/* empty passwords succeed
+	 * need to do this again here since the shadow password
+	 * may differ to that tested in auth.c */
+	if (passwdcrypt[0] == '\0') {
+		/* successful authentication */
+		dropbear_log(LOG_NOTICE, 
+			"none auth succeeded for '%s' from %s",
+			ses.authstate.pw_name,
+			svr_ses.addrstring);
+		send_msg_userauth_success();
+
+		return 1;
+	}
+
+#endif
+
+	return 0;
+}
 
 #ifdef ENABLE_SVR_PASSWORD_AUTH
 
@@ -63,7 +103,7 @@
 	/* check for empty password - need to do this again here
 	 * since the shadow password may differ to that tested
 	 * in auth.c */
-	if (passwdcrypt[0] == '\0') {
+	if (svr_opts.needpasswd && passwdcrypt[0] == '\0') {
 		dropbear_log(LOG_WARNING, "user '%s' has blank password, rejected",
 				ses.authstate.pw_name);
 		send_msg_userauth_failure(0, 1);
diff -ur a/svr-runopts.c b/svr-runopts.c
--- a/svr-runopts.c	2008-03-27 09:17:16.000000000 -0400
+++ b/svr-runopts.c	2009-04-02 12:54:11.000000000 -0400
@@ -113,6 +113,7 @@
 	svr_opts.norootlogin = 0;
 	svr_opts.noauthpass = 0;
 	svr_opts.norootpass = 0;
+	svr_opts.needpasswd = 1;
 	svr_opts.inetdmode = 0;
 	svr_opts.portcount = 0;
 	svr_opts.hostkey = NULL;
@@ -225,6 +226,9 @@
 				case 'g':
 					svr_opts.norootpass = 1;
 					break;
+				case 'G':
+					svr_opts.needpasswd = 0;
+					break;
 #endif
 				case 'h':
 					printhelp(argv[0]);

Reply via email to