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]);