This commit is contained in:
Matt Johnston 2013-07-08 22:43:56 +08:00
commit e05b7f0b76

View File

@ -110,6 +110,7 @@ void recv_msg_userauth_request() {
unsigned char *username = NULL, *servicename = NULL, *methodname = NULL; unsigned char *username = NULL, *servicename = NULL, *methodname = NULL;
unsigned int userlen, servicelen, methodlen; unsigned int userlen, servicelen, methodlen;
int valid_user = 0;
TRACE(("enter recv_msg_userauth_request")) TRACE(("enter recv_msg_userauth_request"))
@ -124,7 +125,6 @@ void recv_msg_userauth_request() {
send_msg_userauth_banner(); send_msg_userauth_banner();
} }
username = buf_getstring(ses.payload, &userlen); username = buf_getstring(ses.payload, &userlen);
servicename = buf_getstring(ses.payload, &servicelen); servicename = buf_getstring(ses.payload, &servicelen);
methodname = buf_getstring(ses.payload, &methodlen); methodname = buf_getstring(ses.payload, &methodlen);
@ -141,12 +141,12 @@ void recv_msg_userauth_request() {
dropbear_exit("unknown service in auth"); dropbear_exit("unknown service in auth");
} }
/* check username is good before continuing */ /* check username is good before continuing.
if (checkusername(username, userlen) == DROPBEAR_FAILURE) { * the 'incrfail' varies depending on the auth method to
/* username is invalid/no shell/etc - send failure */ * avoid giving away which users exist on the system through
TRACE(("sending checkusername failure")) * the time delay. */
send_msg_userauth_failure(0, 1); if (checkusername(username, userlen) == DROPBEAR_SUCCESS) {
goto out; valid_user = 1;
} }
/* user wants to know what methods are supported */ /* user wants to know what methods are supported */
@ -154,7 +154,8 @@ void recv_msg_userauth_request() {
strncmp(methodname, AUTH_METHOD_NONE, strncmp(methodname, AUTH_METHOD_NONE,
AUTH_METHOD_NONE_LEN) == 0) { AUTH_METHOD_NONE_LEN) == 0) {
TRACE(("recv_msg_userauth_request: 'none' request")) TRACE(("recv_msg_userauth_request: 'none' request"))
if (svr_opts.allowblankpass if (valid_user
&& svr_opts.allowblankpass
&& !svr_opts.noauthpass && !svr_opts.noauthpass
&& !(svr_opts.norootpass && ses.authstate.pw_uid == 0) && !(svr_opts.norootpass && ses.authstate.pw_uid == 0)
&& ses.authstate.pw_passwd[0] == '\0') && ses.authstate.pw_passwd[0] == '\0')
@ -168,6 +169,7 @@ void recv_msg_userauth_request() {
} }
else else
{ {
/* 'none' has no failure delay */
send_msg_userauth_failure(0, 0); send_msg_userauth_failure(0, 0);
goto out; goto out;
} }
@ -180,10 +182,12 @@ void recv_msg_userauth_request() {
if (methodlen == AUTH_METHOD_PASSWORD_LEN && if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
strncmp(methodname, AUTH_METHOD_PASSWORD, strncmp(methodname, AUTH_METHOD_PASSWORD,
AUTH_METHOD_PASSWORD_LEN) == 0) { AUTH_METHOD_PASSWORD_LEN) == 0) {
if (valid_user) {
svr_auth_password(); svr_auth_password();
goto out; goto out;
} }
} }
}
#endif #endif
#ifdef ENABLE_SVR_PAM_AUTH #ifdef ENABLE_SVR_PAM_AUTH
@ -193,10 +197,12 @@ void recv_msg_userauth_request() {
if (methodlen == AUTH_METHOD_PASSWORD_LEN && if (methodlen == AUTH_METHOD_PASSWORD_LEN &&
strncmp(methodname, AUTH_METHOD_PASSWORD, strncmp(methodname, AUTH_METHOD_PASSWORD,
AUTH_METHOD_PASSWORD_LEN) == 0) { AUTH_METHOD_PASSWORD_LEN) == 0) {
if (valid_user) {
svr_auth_pam(); svr_auth_pam();
goto out; goto out;
} }
} }
}
#endif #endif
#ifdef ENABLE_SVR_PUBKEY_AUTH #ifdef ENABLE_SVR_PUBKEY_AUTH
@ -204,12 +210,17 @@ void recv_msg_userauth_request() {
if (methodlen == AUTH_METHOD_PUBKEY_LEN && if (methodlen == AUTH_METHOD_PUBKEY_LEN &&
strncmp(methodname, AUTH_METHOD_PUBKEY, strncmp(methodname, AUTH_METHOD_PUBKEY,
AUTH_METHOD_PUBKEY_LEN) == 0) { AUTH_METHOD_PUBKEY_LEN) == 0) {
if (valid_user) {
svr_auth_pubkey(); svr_auth_pubkey();
} else {
/* pubkey has no failure delay */
send_msg_userauth_failure(0, 0);
}
goto out; goto out;
} }
#endif #endif
/* nothing matched, we just fail */ /* nothing matched, we just fail with a delay */
send_msg_userauth_failure(0, 1); send_msg_userauth_failure(0, 1);
out: out:
@ -252,7 +263,6 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
dropbear_log(LOG_WARNING, dropbear_log(LOG_WARNING,
"Login attempt for nonexistent user from %s", "Login attempt for nonexistent user from %s",
svr_ses.addrstring); svr_ses.addrstring);
send_msg_userauth_failure(0, 1);
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;
} }
@ -264,7 +274,6 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
"Login attempt with wrong user %s from %s", "Login attempt with wrong user %s from %s",
ses.authstate.pw_name, ses.authstate.pw_name,
svr_ses.addrstring); svr_ses.addrstring);
send_msg_userauth_failure(0, 1);
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;
} }
@ -272,7 +281,6 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
if (svr_opts.norootlogin && ses.authstate.pw_uid == 0) { if (svr_opts.norootlogin && ses.authstate.pw_uid == 0) {
TRACE(("leave checkusername: root login disabled")) TRACE(("leave checkusername: root login disabled"))
dropbear_log(LOG_WARNING, "root login rejected"); dropbear_log(LOG_WARNING, "root login rejected");
send_msg_userauth_failure(0, 1);
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;
} }
@ -301,7 +309,6 @@ static int checkusername(unsigned char *username, unsigned int userlen) {
TRACE(("no matching shell")) TRACE(("no matching shell"))
dropbear_log(LOG_WARNING, "User '%s' has invalid shell, rejected", dropbear_log(LOG_WARNING, "User '%s' has invalid shell, rejected",
ses.authstate.pw_name); ses.authstate.pw_name);
send_msg_userauth_failure(0, 1);
return DROPBEAR_FAILURE; return DROPBEAR_FAILURE;
goodshell: goodshell:
@ -311,7 +318,6 @@ goodshell:
TRACE(("uid = %d", ses.authstate.pw_uid)) TRACE(("uid = %d", ses.authstate.pw_uid))
TRACE(("leave checkusername")) TRACE(("leave checkusername"))
return DROPBEAR_SUCCESS; return DROPBEAR_SUCCESS;
} }
/* Send a failure message to the client, in responds to a userauth_request. /* Send a failure message to the client, in responds to a userauth_request.
@ -358,8 +364,8 @@ void send_msg_userauth_failure(int partial, int incrfail) {
if (incrfail) { if (incrfail) {
unsigned int delay; unsigned int delay;
genrandom((unsigned char*)&delay, sizeof(delay)); genrandom((unsigned char*)&delay, sizeof(delay));
/* We delay for 300ms +- 50ms, 0.1ms granularity */ /* We delay for 300ms +- 50ms */
delay = 250000 + (delay % 1000)*100; delay = 250000 + (delay % 100000);
usleep(delay); usleep(delay);
ses.authstate.failcount++; ses.authstate.failcount++;
} }