ksmbd: throttle session setup failures to avoid dictionary attacks
To avoid dictionary attacks (repeated session setups rapidly sent) to connect to server, ksmbd make a delay of a 5 seconds on session setup failure to make it harder to send enough random connection requests to break into a server if a user insert the wrong password 10 times in a row. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
34061d6b76
commit
621be84a9d
|
@ -211,6 +211,7 @@ struct ksmbd_tree_disconnect_request {
|
|||
*/
|
||||
struct ksmbd_logout_request {
|
||||
__s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */
|
||||
__u32 account_flags;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -317,6 +318,7 @@ enum KSMBD_TREE_CONN_STATUS {
|
|||
#define KSMBD_USER_FLAG_BAD_UID BIT(2)
|
||||
#define KSMBD_USER_FLAG_BAD_USER BIT(3)
|
||||
#define KSMBD_USER_FLAG_GUEST_ACCOUNT BIT(4)
|
||||
#define KSMBD_USER_FLAG_DELAY_SESSION BIT(5)
|
||||
|
||||
/*
|
||||
* Share config flags.
|
||||
|
|
|
@ -55,7 +55,7 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp)
|
|||
|
||||
void ksmbd_free_user(struct ksmbd_user *user)
|
||||
{
|
||||
ksmbd_ipc_logout_request(user->name);
|
||||
ksmbd_ipc_logout_request(user->name, user->flags);
|
||||
kfree(user->name);
|
||||
kfree(user->passkey);
|
||||
kfree(user);
|
||||
|
|
|
@ -18,6 +18,7 @@ struct ksmbd_user {
|
|||
|
||||
size_t passkey_sz;
|
||||
char *passkey;
|
||||
unsigned int failed_login_count;
|
||||
};
|
||||
|
||||
static inline bool user_guest(struct ksmbd_user *user)
|
||||
|
|
|
@ -1779,9 +1779,30 @@ int smb2_sess_setup(struct ksmbd_work *work)
|
|||
conn->mechToken = NULL;
|
||||
}
|
||||
|
||||
if (rc < 0 && sess) {
|
||||
ksmbd_session_destroy(sess);
|
||||
work->sess = NULL;
|
||||
if (rc < 0) {
|
||||
/*
|
||||
* SecurityBufferOffset should be set to zero
|
||||
* in session setup error response.
|
||||
*/
|
||||
rsp->SecurityBufferOffset = 0;
|
||||
|
||||
if (sess) {
|
||||
bool try_delay = false;
|
||||
|
||||
/*
|
||||
* To avoid dictionary attacks (repeated session setups rapidly sent) to
|
||||
* connect to server, ksmbd make a delay of a 5 seconds on session setup
|
||||
* failure to make it harder to send enough random connection requests
|
||||
* to break into a server.
|
||||
*/
|
||||
if (sess->user && sess->user->flags & KSMBD_USER_FLAG_DELAY_SESSION)
|
||||
try_delay = true;
|
||||
|
||||
ksmbd_session_destroy(sess);
|
||||
work->sess = NULL;
|
||||
if (try_delay)
|
||||
ssleep(5);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -601,7 +601,7 @@ int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ksmbd_ipc_logout_request(const char *account)
|
||||
int ksmbd_ipc_logout_request(const char *account, int flags)
|
||||
{
|
||||
struct ksmbd_ipc_msg *msg;
|
||||
struct ksmbd_logout_request *req;
|
||||
|
@ -616,6 +616,7 @@ int ksmbd_ipc_logout_request(const char *account)
|
|||
|
||||
msg->type = KSMBD_EVENT_LOGOUT_REQUEST;
|
||||
req = (struct ksmbd_logout_request *)msg->payload;
|
||||
req->account_flags = flags;
|
||||
strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);
|
||||
|
||||
ret = ipc_msg_send(msg);
|
||||
|
|
|
@ -25,7 +25,7 @@ ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess,
|
|||
struct sockaddr *peer_addr);
|
||||
int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id,
|
||||
unsigned long long connect_id);
|
||||
int ksmbd_ipc_logout_request(const char *account);
|
||||
int ksmbd_ipc_logout_request(const char *account, int flags);
|
||||
struct ksmbd_share_config_response *
|
||||
ksmbd_ipc_share_config_request(const char *name);
|
||||
struct ksmbd_spnego_authen_response *
|
||||
|
|
Loading…
Reference in New Issue