--- a/src/svr-authpasswd.c +++ b/src/svr-authpasswd.c @@ -33,6 +33,77 @@ #if DROPBEAR_SVR_PASSWORD_AUTH +#if DROPBEAR_NUTTX_PASSWD + +/* Process a password auth request, sending success or failure messages as + * appropriate */ +void svr_auth_password(int valid_user) { + + char * password = NULL; + unsigned int passwordlen; + unsigned int changepw; + int auth_ok = 0; + + /* check if client wants to change password */ + changepw = buf_getbool(ses.payload); + if (changepw) { + /* not implemented by this server */ + send_msg_userauth_failure(0, 1); + return; + } + + password = buf_getstring(ses.payload, &passwordlen); + if (valid_user && passwordlen <= DROPBEAR_MAX_PASSWORD_LEN && + strlen(password) == passwordlen) { + auth_ok = dropbear_verify_password(ses.authstate.pw_name, password); + } + m_burn(password, passwordlen); + m_free(password); + + /* After we have got the payload contents we can exit if the username + is invalid. Invalid users have already been logged. */ + if (!valid_user) { + send_msg_userauth_failure(0, 1); + return; + } + + if (passwordlen > DROPBEAR_MAX_PASSWORD_LEN) { + dropbear_log(LOG_WARNING, + "Too-long password attempt for '%s' from %s", + ses.authstate.pw_name, + svr_ses.addrstring); + send_msg_userauth_failure(0, 1); + return; + } + + if (auth_ok == DROPBEAR_SUCCESS) { + if (svr_opts.multiauthmethod && (ses.authstate.authtypes & ~AUTH_TYPE_PASSWORD)) { + /* successful password authentication, but extra auth required */ + dropbear_log(LOG_NOTICE, + "Password auth succeeded for '%s' from %s, extra auth required", + ses.authstate.pw_name, + svr_ses.addrstring); + ses.authstate.authtypes &= ~AUTH_TYPE_PASSWORD; /* password auth ok, delete the method flag */ + send_msg_userauth_failure(1, 0); /* Send partial success */ + } else { + /* successful authentication */ + dropbear_log(LOG_NOTICE, + "Password auth succeeded for '%s' from %s", + ses.authstate.pw_name, + svr_ses.addrstring); + send_msg_userauth_success(); + } + } else { + dropbear_log(LOG_WARNING, + "Bad password attempt for '%s' from %s", + ses.authstate.pw_name, + svr_ses.addrstring); + send_msg_userauth_failure(0, 1); + } +} + +#else + /* not constant time when strings are differing lengths. string content isn't leaked, and crypt hashes are predictable length. */ static int constant_time_strcmp(const char* a, const char* b) { @@ -131,4 +202,6 @@ } } +#endif /* DROPBEAR_NUTTX_PASSWD */ + #endif