CVE-2026-42218: Ensure auth fails take a fixed time
Implement a constant time for password-based authentication failure.
This commit is contained in:
@@ -41,6 +41,17 @@
|
|||||||
#include "sesexec.h"
|
#include "sesexec.h"
|
||||||
#include "string_calls.h"
|
#include "string_calls.h"
|
||||||
|
|
||||||
|
// Sys login fails all take a fixed time before returning. This
|
||||||
|
// prevents an attacker using timing differences to determine
|
||||||
|
// information about the users on the system (CVE-2026-42218)
|
||||||
|
//
|
||||||
|
// Note that some systems may provide an upper time bound for
|
||||||
|
// a login failure that is higher than this. For example, the Linux
|
||||||
|
// PAM stack default sys login fail time is around 2000 milli-seconds.
|
||||||
|
// Consequently, it is important the auth stack is always called, even
|
||||||
|
// if it has been determined that this is unnecessary.
|
||||||
|
#define FAILED_LOGIN_CONSTANT_TIME 600 // milli-seconds
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/**
|
/**
|
||||||
* Logs an authentication failure message
|
* Logs an authentication failure message
|
||||||
@@ -72,7 +83,6 @@ log_authfail_message(const char *username, const char *ip_addr)
|
|||||||
* @return Status for the operation
|
* @return Status for the operation
|
||||||
*
|
*
|
||||||
* @post If E_SCP_LOGIN_OK is returned, g_login_info is filled in
|
* @post If E_SCP_LOGIN_OK is returned, g_login_info is filled in
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static enum scp_login_status
|
static enum scp_login_status
|
||||||
authenticate_and_authorize_connection(const char *supplied_username,
|
authenticate_and_authorize_connection(const char *supplied_username,
|
||||||
@@ -84,6 +94,7 @@ authenticate_and_authorize_connection(const char *supplied_username,
|
|||||||
char *username; // From reverse-looking up the UID
|
char *username; // From reverse-looking up the UID
|
||||||
enum scp_login_status status;
|
enum scp_login_status status;
|
||||||
struct auth_info *auth_info;
|
struct auth_info *auth_info;
|
||||||
|
unsigned int start_time = g_get_elapsed_ms();
|
||||||
|
|
||||||
if (g_getuser_info_by_name(supplied_username,
|
if (g_getuser_info_by_name(supplied_username,
|
||||||
&uid, NULL, NULL, NULL, NULL) != 0)
|
&uid, NULL, NULL, NULL, NULL) != 0)
|
||||||
@@ -93,6 +104,11 @@ authenticate_and_authorize_connection(const char *supplied_username,
|
|||||||
supplied_username);
|
supplied_username);
|
||||||
log_authfail_message(supplied_username, ip_addr);
|
log_authfail_message(supplied_username, ip_addr);
|
||||||
status = E_SCP_LOGIN_NOT_AUTHENTICATED;
|
status = E_SCP_LOGIN_NOT_AUTHENTICATED;
|
||||||
|
|
||||||
|
/* Call the auth stack anyway. On some systems (e.g. linux-pam),
|
||||||
|
* a fixed delay is built in to the stack for an unsuccessful
|
||||||
|
* login, and this delay may exceed FAILED_LOGIN_CONSTANT_TIME */
|
||||||
|
auth_end(auth_userpass(username, password, ip_addr, NULL));
|
||||||
}
|
}
|
||||||
else if (g_getuser_info_by_uid(uid,
|
else if (g_getuser_info_by_uid(uid,
|
||||||
&username,
|
&username,
|
||||||
@@ -100,6 +116,7 @@ authenticate_and_authorize_connection(const char *supplied_username,
|
|||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_ERROR, "Can't reverse lookup UID %d", uid);
|
LOG(LOG_LEVEL_ERROR, "Can't reverse lookup UID %d", uid);
|
||||||
status = E_SCP_LOGIN_NOT_AUTHENTICATED;
|
status = E_SCP_LOGIN_NOT_AUTHENTICATED;
|
||||||
|
auth_end(auth_userpass(username, password, ip_addr, NULL));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -179,6 +196,15 @@ authenticate_and_authorize_connection(const char *supplied_username,
|
|||||||
|
|
||||||
g_free(username);
|
g_free(username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (status != E_SCP_LOGIN_OK)
|
||||||
|
{
|
||||||
|
unsigned int elapsed_ms = g_get_elapsed_ms() - start_time;
|
||||||
|
if (elapsed_ms < FAILED_LOGIN_CONSTANT_TIME)
|
||||||
|
{
|
||||||
|
g_sleep(FAILED_LOGIN_CONSTANT_TIME - elapsed_ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user