mirror of
https://github.com/clearml/dropbear
synced 2025-06-26 18:17:32 +00:00
- Don't try to handle changed usernames
- Avoid logging repeated failed username messages
This commit is contained in:
parent
2e836bb553
commit
7435369615
6
auth.h
6
auth.h
@ -105,12 +105,14 @@ struct AuthState {
|
|||||||
unsigned char authtypes; /* Flags indicating which auth types are still
|
unsigned char authtypes; /* Flags indicating which auth types are still
|
||||||
valid */
|
valid */
|
||||||
unsigned int failcount; /* Number of (failed) authentication attempts.*/
|
unsigned int failcount; /* Number of (failed) authentication attempts.*/
|
||||||
unsigned authdone : 1; /* 0 if we haven't authed, 1 if we have. Applies for
|
unsigned int authdone; /* 0 if we haven't authed, 1 if we have. Applies for
|
||||||
client and server (though has differing
|
client and server (though has differing
|
||||||
meanings). */
|
meanings). */
|
||||||
unsigned perm_warn : 1; /* Server only, set if bad permissions on
|
unsigned int perm_warn; /* Server only, set if bad permissions on
|
||||||
~/.ssh/authorized_keys have already been
|
~/.ssh/authorized_keys have already been
|
||||||
logged. */
|
logged. */
|
||||||
|
unsigned int checkusername_failed; /* Server only, set if checkusername
|
||||||
|
has already failed */
|
||||||
|
|
||||||
/* These are only used for the server */
|
/* These are only used for the server */
|
||||||
uid_t pw_uid;
|
uid_t pw_uid;
|
||||||
|
60
svr-auth.c
60
svr-auth.c
@ -37,26 +37,10 @@
|
|||||||
#include "runopts.h"
|
#include "runopts.h"
|
||||||
#include "dbrandom.h"
|
#include "dbrandom.h"
|
||||||
|
|
||||||
static void authclear(void);
|
|
||||||
static int checkusername(const char *username, unsigned int userlen);
|
static int checkusername(const char *username, unsigned int userlen);
|
||||||
|
|
||||||
/* initialise the first time for a session, resetting all parameters */
|
/* initialise the first time for a session, resetting all parameters */
|
||||||
void svr_authinitialise() {
|
void svr_authinitialise() {
|
||||||
|
|
||||||
ses.authstate.failcount = 0;
|
|
||||||
ses.authstate.pw_name = NULL;
|
|
||||||
ses.authstate.pw_dir = NULL;
|
|
||||||
ses.authstate.pw_shell = NULL;
|
|
||||||
ses.authstate.pw_passwd = NULL;
|
|
||||||
authclear();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset the auth state, but don't reset the failcount. This is for if the
|
|
||||||
* user decides to try with a different username etc, and is also invoked
|
|
||||||
* on initialisation */
|
|
||||||
static void authclear() {
|
|
||||||
|
|
||||||
memset(&ses.authstate, 0, sizeof(ses.authstate));
|
memset(&ses.authstate, 0, sizeof(ses.authstate));
|
||||||
#if DROPBEAR_SVR_PUBKEY_AUTH
|
#if DROPBEAR_SVR_PUBKEY_AUTH
|
||||||
ses.authstate.authtypes |= AUTH_TYPE_PUBKEY;
|
ses.authstate.authtypes |= AUTH_TYPE_PUBKEY;
|
||||||
@ -66,19 +50,6 @@ static void authclear() {
|
|||||||
ses.authstate.authtypes |= AUTH_TYPE_PASSWORD;
|
ses.authstate.authtypes |= AUTH_TYPE_PASSWORD;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (ses.authstate.pw_name) {
|
|
||||||
m_free(ses.authstate.pw_name);
|
|
||||||
}
|
|
||||||
if (ses.authstate.pw_shell) {
|
|
||||||
m_free(ses.authstate.pw_shell);
|
|
||||||
}
|
|
||||||
if (ses.authstate.pw_dir) {
|
|
||||||
m_free(ses.authstate.pw_dir);
|
|
||||||
}
|
|
||||||
if (ses.authstate.pw_passwd) {
|
|
||||||
m_free(ses.authstate.pw_passwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send a banner message if specified to the client. The client might
|
/* Send a banner message if specified to the client. The client might
|
||||||
@ -274,18 +245,28 @@ static int checkusername(const char *username, unsigned int userlen) {
|
|||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* new user or username has changed */
|
if (strlen(username) != userlen) {
|
||||||
if (ses.authstate.username == NULL ||
|
dropbear_exit("Attempted username with a null byte from %s",
|
||||||
strcmp(username, ses.authstate.username) != 0) {
|
|
||||||
/* the username needs resetting */
|
|
||||||
if (ses.authstate.username != NULL) {
|
|
||||||
dropbear_log(LOG_WARNING, "Client trying multiple usernames from %s",
|
|
||||||
svr_ses.addrstring);
|
svr_ses.addrstring);
|
||||||
m_free(ses.authstate.username);
|
|
||||||
}
|
}
|
||||||
authclear();
|
|
||||||
|
if (ses.authstate.username == NULL) {
|
||||||
|
/* first request */
|
||||||
fill_passwd(username);
|
fill_passwd(username);
|
||||||
ses.authstate.username = m_strdup(username);
|
ses.authstate.username = m_strdup(username);
|
||||||
|
} else {
|
||||||
|
/* check username hasn't changed */
|
||||||
|
if (strcmp(username, ses.authstate.username) != 0) {
|
||||||
|
dropbear_exit("Client trying multiple usernames from %s",
|
||||||
|
svr_ses.addrstring);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* avoids cluttering logs with repeated failure messages from
|
||||||
|
consecutive authentication requests in a sesssion */
|
||||||
|
if (ses.authstate.checkusername_failed) {
|
||||||
|
TRACE(("checkusername: returning cached failure"))
|
||||||
|
return DROPBEAR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check that user exists */
|
/* check that user exists */
|
||||||
@ -294,6 +275,7 @@ static int checkusername(const 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);
|
||||||
|
ses.authstate.checkusername_failed = 1;
|
||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,6 +287,7 @@ static int checkusername(const 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);
|
||||||
|
ses.authstate.checkusername_failed = 1;
|
||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,6 +295,7 @@ static int checkusername(const 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");
|
||||||
|
ses.authstate.checkusername_failed = 1;
|
||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,6 +306,7 @@ static int checkusername(const char *username, unsigned int userlen) {
|
|||||||
dropbear_log(LOG_WARNING,
|
dropbear_log(LOG_WARNING,
|
||||||
"Logins are restricted to the group %s but user '%s' is not a member",
|
"Logins are restricted to the group %s but user '%s' is not a member",
|
||||||
svr_opts.restrict_group, ses.authstate.pw_name);
|
svr_opts.restrict_group, ses.authstate.pw_name);
|
||||||
|
ses.authstate.checkusername_failed = 1;
|
||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -349,6 +334,7 @@ static int checkusername(const char *username, unsigned int userlen) {
|
|||||||
/* no matching shell */
|
/* no matching shell */
|
||||||
endusershell();
|
endusershell();
|
||||||
TRACE(("no matching shell"))
|
TRACE(("no matching shell"))
|
||||||
|
ses.authstate.checkusername_failed = 1;
|
||||||
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);
|
||||||
return DROPBEAR_FAILURE;
|
return DROPBEAR_FAILURE;
|
||||||
|
Loading…
Reference in New Issue
Block a user