| --- 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 |