--- a/svr-auth.c +++ b/svr-auth.c @@ -125,10 +125,11 @@ void recv_msg_userauth_request() { AUTH_METHOD_NONE_LEN) == 0) { TRACE(("recv_msg_userauth_request: 'none' request")) if (valid_user - && (svr_opts.allowblankpass || !strcmp(ses.authstate.pw_name, "root")) - && !svr_opts.noauthpass - && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) - && ses.authstate.pw_passwd[0] == '\0') + && ((svr_opts.failsafe_mode && !strcmp(ses.authstate.pw_name, "root")) + || ((svr_opts.allowblankpass || !strcmp(ses.authstate.pw_name, "root")) + && !svr_opts.noauthpass + && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) + && ses.authstate.pw_passwd[0] == '\0'))) { dropbear_log(LOG_NOTICE, "Auth succeeded with blank password for '%s' from %s", --- a/svr-runopts.c +++ b/svr-runopts.c @@ -77,6 +77,7 @@ static void printhelp(const char * progn "-s Disable password logins\n" "-g Disable password logins for root\n" "-B Allow blank password logins\n" + "-f Failsafe mode: always allow password-less root login\n" #endif "-T Maximum authentication tries (default %d)\n" #if DROPBEAR_SVR_LOCALTCPFWD @@ -144,6 +145,7 @@ void svr_getopts(int argc, char ** argv) svr_opts.noauthpass = 0; svr_opts.norootpass = 0; svr_opts.allowblankpass = 0; + svr_opts.failsafe_mode = 0; svr_opts.maxauthtries = MAX_AUTH_TRIES; svr_opts.inetdmode = 0; svr_opts.portcount = 0; @@ -266,6 +268,9 @@ void svr_getopts(int argc, char ** argv) case 'B': svr_opts.allowblankpass = 1; break; + case 'f': + svr_opts.failsafe_mode = 1; + break; #endif case 'h': printhelp(argv[0]); --- a/runopts.h +++ b/runopts.h @@ -106,6 +106,8 @@ typedef struct svr_runopts { int allowblankpass; unsigned int maxauthtries; + int failsafe_mode; + #if DROPBEAR_SVR_REMOTETCPFWD int noremotetcp; #endif