MySQL 9.1.0
Source Code Documentation
validate_password_imp.cc File Reference
#include "validate_password_imp.h"
#include <assert.h>
#include <string.h>
#include <algorithm>
#include <atomic>
#include <fstream>
#include <iomanip>
#include <set>
#include <sstream>
#include <unordered_set>
#include "mysql/components/library_mysys/my_memory.h"
#include "mysql/components/services/mysql_rwlock.h"
#include "mysql/components/services/psi_memory.h"
#include "mysql/components/services/registry.h"
#include "mysqld_error.h"
#include "option_usage.h"
#include "scope_guard.h"

Macros

#define PSI_NOT_INSTRUMENTED   0
 
#define array_elements(A)   ((size_t)(sizeof(A) / sizeof(A[0])))
 

Typedefs

typedef std::string string_type
 
typedef std::set< string_typeset_type
 

Enumerations

enum  password_policy_enum {
  PASSWORD_POLICY_LOW , PASSWORD_POLICY_MEDIUM , PASSWORD_POLICY_STRONG , PASSWORD_POLICY_LOW ,
  PASSWORD_POLICY_MEDIUM , PASSWORD_POLICY_STRONG
}
 

Functions

static void init_validate_password_psi_keys ()
 
std::atomic< bool > is_initialized (false)
 
static void dictionary_activate (set_type *dict_words)
 Activate the new dictionary. More...
 
static void read_dictionary_file ()
 
static void free_dictionary_file ()
 
static int validate_dictionary_check (my_h_string password)
 
static bool my_memcmp_reverse (const char *a, size_t a_len, const char *b, size_t b_len)
 Compare a sequence of bytes in "a" with the reverse sequence of bytes of "b". More...
 
static bool is_valid_user (Security_context_handle ctx, const char *buffer, int length, const char *field_name)
 Validate a user name from the security context. More...
 
static bool is_valid_password_by_user_name (void *thd, my_h_string password)
 Check if the password is not the user name. More...
 
static void readjust_validate_password_length ()
 Check and readjust effective value of validate_password_length. More...
 
static void dictionary_update (MYSQL_THD, SYS_VAR *, void *var_ptr, const void *save)
 
static void length_update (MYSQL_THD, SYS_VAR *, void *var_ptr, const void *save)
 
static int validate_password_policy_strength (void *thd, my_h_string password, int policy)
 
int register_status_variables ()
 
int register_system_variables ()
 
int unregister_status_variables ()
 
int unregister_system_variables ()
 
bool log_service_init ()
 logger services initialization method for Component used when loading the Component. More...
 
bool log_service_deinit ()
 logger services de-initialization method for Component used when unloading the Component. More...
 
static mysql_service_status_t validate_password_init ()
 Initialization entry method for Component used when loading the Component. More...
 
static mysql_service_status_t validate_password_deinit ()
 De-initialization method for Component used when unloading the Component. More...
 
 PROVIDES_SERVICE (validate_password, validate_password)
 
 PROVIDES_SERVICE (validate_password, validate_password_changed_characters)
 
 END_COMPONENT_PROVIDES ()
 
 REQUIRES_SERVICE_PLACEHOLDER (log_builtins)
 
 REQUIRES_SERVICE_PLACEHOLDER (log_builtins_string)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_string_character_access)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_string_factory)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_string_case)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_string_converter)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_string_iterator)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_string_ctype)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_string_value)
 
 REQUIRES_SERVICE_PLACEHOLDER (component_sys_variable_register)
 
 REQUIRES_SERVICE_PLACEHOLDER (component_sys_variable_unregister)
 
 REQUIRES_SERVICE_PLACEHOLDER (status_variable_registration)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_thd_security_context)
 
 REQUIRES_SERVICE_PLACEHOLDER (mysql_security_context_options)
 
 REQUIRES_SERVICE_PLACEHOLDER (registry_registration)
 
 REQUIRES_SERVICE_PLACEHOLDER_AS (registry, mysql_service_registry_no_lock)
 
 REQUIRES_SERVICE_PLACEHOLDER_AS (registry_registration, mysql_service_registration_no_lock)
 
 REQUIRES_SERVICE (log_builtins)
 
 REQUIRES_SERVICE (log_builtins_string)
 
 REQUIRES_SERVICE (mysql_string_character_access)
 
 REQUIRES_SERVICE (mysql_string_factory)
 
 REQUIRES_SERVICE (mysql_string_case)
 
 REQUIRES_SERVICE (mysql_string_converter)
 
 REQUIRES_SERVICE (mysql_string_iterator)
 
 REQUIRES_SERVICE (mysql_string_ctype)
 
 REQUIRES_SERVICE (mysql_string_value)
 
 REQUIRES_SERVICE (component_sys_variable_register)
 
 REQUIRES_SERVICE (component_sys_variable_unregister)
 
 REQUIRES_SERVICE (status_variable_registration)
 
 REQUIRES_SERVICE (mysql_thd_security_context)
 
 REQUIRES_SERVICE (mysql_security_context_options)
 
 REQUIRES_SERVICE (registry_registration)
 
 REQUIRES_SERVICE_IMPLEMENTATION_AS (registry_registration, mysql_minimal_chassis_no_lock, mysql_service_registration_no_lock)
 
 REQUIRES_SERVICE_IMPLEMENTATION_AS (registry, mysql_minimal_chassis_no_lock, mysql_service_registry_no_lock)
 
 END_COMPONENT_REQUIRES ()
 
 METADATA ("mysql.author", "Oracle Corporation")
 
 METADATA ("mysql.license", "GPL")
 
 METADATA ("validate_password_service", "1")
 
 END_COMPONENT_METADATA ()
 

Variables

const int MAX_DICTIONARY_FILE_LENGTH = (1024 * 1024)
 
const int PASSWORD_SCORE = 25
 
const int MIN_DICTIONARY_WORD_LENGTH = 4
 
const int MAX_PASSWORD_LENGTH = 100
 
mysql_rwlock_t LOCK_dict_file
 
PSI_rwlock_key key_validate_password_LOCK_dict_file
 
static PSI_rwlock_info all_validate_password_rwlocks []
 
static const char * policy_names [] = {"LOW", "MEDIUM", "STRONG", nullptr}
 
static TYPE_LIB password_policy_typelib_t
 
static set_typedictionary_words {nullptr}
 
static int validate_password_length
 
static int validate_password_number_count
 
static int validate_password_mixed_case_count
 
static int validate_password_special_char_count
 
static ulong validate_password_policy
 
static char * validate_password_dictionary_file
 
static char * validate_password_dictionary_file_last_parsed = nullptr
 
static long long validate_password_dictionary_file_words_count = 0
 
static bool check_user_name
 
static int validate_password_changed_characters_percentage = 0
 
static SHOW_VAR validate_password_status_variables []
 
const mysql_service_log_builtins_tlog_bi
 accessor built-ins More...
 
const mysql_service_log_builtins_string_tlog_bs
 string built-ins More...
 
const mysql_service_validate_password_t imp_validate_password_validate_password
 
const mysql_service_validate_password_changed_characters_t imp_validate_password_validate_password_changed_characters
 
 REQUIRES_PSI_MEMORY_SERVICE_PLACEHOLDER
 
 REQUIRES_MYSQL_RWLOCK_SERVICE_PLACEHOLDER
 
 REQUIRES_PSI_MEMORY_SERVICE
 
 REQUIRES_MYSQL_RWLOCK_SERVICE
 
mysql_component_t mysql_component_validate_password
 

Macro Definition Documentation

◆ array_elements

#define array_elements (   A)    ((size_t)(sizeof(A) / sizeof(A[0])))

◆ PSI_NOT_INSTRUMENTED

#define PSI_NOT_INSTRUMENTED   0

Typedef Documentation

◆ set_type

typedef std::set<string_type> set_type

◆ string_type

typedef std::string string_type

Enumeration Type Documentation

◆ password_policy_enum

Enumerator
PASSWORD_POLICY_LOW 
PASSWORD_POLICY_MEDIUM 
PASSWORD_POLICY_STRONG 
PASSWORD_POLICY_LOW 
PASSWORD_POLICY_MEDIUM 
PASSWORD_POLICY_STRONG 

Function Documentation

◆ dictionary_activate()

static void dictionary_activate ( set_type dict_words)
static

Activate the new dictionary.

Assigns a local list to the global variable, taking the correct locks in the process. Also updates the status variables.

Parameters
dict_wordsnew dictionary words set

◆ dictionary_update()

static void dictionary_update ( MYSQL_THD  ,
SYS_VAR ,
void *  var_ptr,
const void *  save 
)
static

◆ END_COMPONENT_METADATA()

END_COMPONENT_METADATA ( )

◆ END_COMPONENT_PROVIDES()

END_COMPONENT_PROVIDES ( )

◆ END_COMPONENT_REQUIRES()

END_COMPONENT_REQUIRES ( )

◆ free_dictionary_file()

static void free_dictionary_file ( )
static

◆ init_validate_password_psi_keys()

static void init_validate_password_psi_keys ( )
static

◆ is_initialized()

std::atomic< bool > is_initialized ( false  )

◆ is_valid_password_by_user_name()

static bool is_valid_password_by_user_name ( void *  thd,
my_h_string  password 
)
static

Check if the password is not the user name.

Helper function. Checks if the password supplied is valid to use by comparing it the effected and the login user names to it and to the reverse of it. logs an error to the error log if it can't pick up the names.

Parameters
thdMySQL THD object
passwordthe password handle
Return values
trueThe password can be used
falsethe password is invalid

◆ is_valid_user()

static bool is_valid_user ( Security_context_handle  ctx,
const char *  buffer,
int  length,
const char *  field_name 
)
static

Validate a user name from the security context.

A helper function. Validates one user name (as specified by field_name) against the data in buffer/length by comparing the byte sequences in forward and reverse.

Logs an error to the error log if it can't pick up the user names.

Parameters
ctxthe current security context
bufferthe password data
lengththe length of buffer
field_namethe id of the security context field to use
Return values
truename can be used
falsename is invalid

◆ length_update()

static void length_update ( MYSQL_THD  ,
SYS_VAR ,
void *  var_ptr,
const void *  save 
)
static

◆ log_service_deinit()

bool log_service_deinit ( )

logger services de-initialization method for Component used when unloading the Component.

Returns
Status of performed operation
Return values
falsesuccess
truefailure

◆ log_service_init()

bool log_service_init ( )

logger services initialization method for Component used when loading the Component.

Returns
Status of performed operation
Return values
falsesuccess
truefailure

◆ METADATA() [1/3]

METADATA ( "mysql.author"  ,
"Oracle Corporation"   
)

◆ METADATA() [2/3]

METADATA ( "mysql.license"  ,
"GPL"   
)

◆ METADATA() [3/3]

METADATA ( "validate_password_service"  ,
"1"   
)

◆ my_memcmp_reverse()

static bool my_memcmp_reverse ( const char *  a,
size_t  a_len,
const char *  b,
size_t  b_len 
)
static

Compare a sequence of bytes in "a" with the reverse sequence of bytes of "b".

Parameters
athe first sequence
a_lenthe length of a
bthe second sequence
b_lenthe length of b
Return values
truesequences match
falsesequences don't match

◆ PROVIDES_SERVICE() [1/2]

PROVIDES_SERVICE ( validate_password  ,
validate_password   
)

◆ PROVIDES_SERVICE() [2/2]

PROVIDES_SERVICE ( validate_password  ,
validate_password_changed_characters   
)

◆ read_dictionary_file()

static void read_dictionary_file ( )
static

◆ readjust_validate_password_length()

static void readjust_validate_password_length ( )
static

Check and readjust effective value of validate_password_length.

Readjust validate_password_length according to the values of validate_password_number_count,validate_password_mixed_case_count and validate_password_special_char_count. This is required at the time plugin installation and as a part of setting new values for any of above mentioned variables.

◆ register_status_variables()

int register_status_variables ( )

◆ register_system_variables()

int register_system_variables ( )

◆ REQUIRES_SERVICE() [1/15]

REQUIRES_SERVICE ( component_sys_variable_register  )

◆ REQUIRES_SERVICE() [2/15]

REQUIRES_SERVICE ( component_sys_variable_unregister  )

◆ REQUIRES_SERVICE() [3/15]

REQUIRES_SERVICE ( log_builtins  )

◆ REQUIRES_SERVICE() [4/15]

REQUIRES_SERVICE ( log_builtins_string  )

◆ REQUIRES_SERVICE() [5/15]

REQUIRES_SERVICE ( mysql_security_context_options  )

◆ REQUIRES_SERVICE() [6/15]

REQUIRES_SERVICE ( mysql_string_case  )

◆ REQUIRES_SERVICE() [7/15]

REQUIRES_SERVICE ( mysql_string_character_access  )

◆ REQUIRES_SERVICE() [8/15]

REQUIRES_SERVICE ( mysql_string_converter  )

◆ REQUIRES_SERVICE() [9/15]

REQUIRES_SERVICE ( mysql_string_ctype  )

◆ REQUIRES_SERVICE() [10/15]

REQUIRES_SERVICE ( mysql_string_factory  )

◆ REQUIRES_SERVICE() [11/15]

REQUIRES_SERVICE ( mysql_string_iterator  )

◆ REQUIRES_SERVICE() [12/15]

REQUIRES_SERVICE ( mysql_string_value  )

◆ REQUIRES_SERVICE() [13/15]

REQUIRES_SERVICE ( mysql_thd_security_context  )

◆ REQUIRES_SERVICE() [14/15]

REQUIRES_SERVICE ( registry_registration  )

◆ REQUIRES_SERVICE() [15/15]

REQUIRES_SERVICE ( status_variable_registration  )

◆ REQUIRES_SERVICE_IMPLEMENTATION_AS() [1/2]

REQUIRES_SERVICE_IMPLEMENTATION_AS ( registry  ,
mysql_minimal_chassis_no_lock  ,
mysql_service_registry_no_lock   
)

◆ REQUIRES_SERVICE_IMPLEMENTATION_AS() [2/2]

REQUIRES_SERVICE_IMPLEMENTATION_AS ( registry_registration  ,
mysql_minimal_chassis_no_lock  ,
mysql_service_registration_no_lock   
)

◆ REQUIRES_SERVICE_PLACEHOLDER() [1/15]

REQUIRES_SERVICE_PLACEHOLDER ( component_sys_variable_register  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [2/15]

REQUIRES_SERVICE_PLACEHOLDER ( component_sys_variable_unregister  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [3/15]

REQUIRES_SERVICE_PLACEHOLDER ( log_builtins  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [4/15]

REQUIRES_SERVICE_PLACEHOLDER ( log_builtins_string  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [5/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_security_context_options  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [6/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_string_case  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [7/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_string_character_access  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [8/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_string_converter  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [9/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_string_ctype  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [10/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_string_factory  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [11/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_string_iterator  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [12/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_string_value  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [13/15]

REQUIRES_SERVICE_PLACEHOLDER ( mysql_thd_security_context  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [14/15]

REQUIRES_SERVICE_PLACEHOLDER ( registry_registration  )

◆ REQUIRES_SERVICE_PLACEHOLDER() [15/15]

REQUIRES_SERVICE_PLACEHOLDER ( status_variable_registration  )

◆ REQUIRES_SERVICE_PLACEHOLDER_AS() [1/2]

REQUIRES_SERVICE_PLACEHOLDER_AS ( registry  ,
mysql_service_registry_no_lock   
)

◆ REQUIRES_SERVICE_PLACEHOLDER_AS() [2/2]

REQUIRES_SERVICE_PLACEHOLDER_AS ( registry_registration  ,
mysql_service_registration_no_lock   
)

◆ unregister_status_variables()

int unregister_status_variables ( )

◆ unregister_system_variables()

int unregister_system_variables ( )

◆ validate_dictionary_check()

static int validate_dictionary_check ( my_h_string  password)
static

◆ validate_password_deinit()

static mysql_service_status_t validate_password_deinit ( )
static

De-initialization method for Component used when unloading the Component.

Returns
Status of performed operation
Return values
falsesuccess
truefailure

◆ validate_password_init()

static mysql_service_status_t validate_password_init ( )
static

Initialization entry method for Component used when loading the Component.

Returns
Status of performed operation
Return values
falsesuccess
truefailure

◆ validate_password_policy_strength()

static int validate_password_policy_strength ( void *  thd,
my_h_string  password,
int  policy 
)
static

Variable Documentation

◆ all_validate_password_rwlocks

PSI_rwlock_info all_validate_password_rwlocks[]
static
Initial value:
= {
{&key_validate_password_LOCK_dict_file, "LOCK_dict_file", 0, 0, ""}}
PSI_rwlock_key key_validate_password_LOCK_dict_file
Definition: validate_password_imp.cc:55

◆ check_user_name

bool check_user_name
static

◆ dictionary_words

set_type* dictionary_words {nullptr}
static

◆ imp_validate_password_validate_password

const mysql_service_validate_password_t imp_validate_password_validate_password
Initial value:
= {
static mysql_service_status_t get_strength(void *thd, my_h_string password, unsigned int *strength) noexcept
Gets the password strength between (0-100)
Definition: validate_password_imp.cc:534
static mysql_service_status_t validate(void *thd, my_h_string password) noexcept
Validates the strength of given password.
Definition: validate_password_imp.cc:591

◆ imp_validate_password_validate_password_changed_characters

const mysql_service_validate_password_changed_characters_t imp_validate_password_validate_password_changed_characters
Initial value:
= {
static mysql_service_status_t validate(my_h_string current_password, my_h_string new_password, uint *minimum_required, uint *changed) noexcept
Validate if number of changed characters matches the pre-configured criteria.
Definition: validate_password_imp.cc:619

◆ key_validate_password_LOCK_dict_file

PSI_rwlock_key key_validate_password_LOCK_dict_file

◆ LOCK_dict_file

mysql_rwlock_t LOCK_dict_file

◆ log_bi

accessor built-ins

accessor built-ins

◆ log_bs

string built-ins

◆ MAX_DICTIONARY_FILE_LENGTH

const int MAX_DICTIONARY_FILE_LENGTH = (1024 * 1024)

◆ MAX_PASSWORD_LENGTH

const int MAX_PASSWORD_LENGTH = 100

◆ MIN_DICTIONARY_WORD_LENGTH

const int MIN_DICTIONARY_WORD_LENGTH = 4

◆ mysql_component_validate_password

mysql_component_t mysql_component_validate_password
Initial value:
= { "mysql:validate_password" , __validate_password_provides, __validate_password_requires, __validate_password_metadata,
static mysql_service_status_t validate_password_deinit()
De-initialization method for Component used when unloading the Component.
Definition: validate_password_imp.cc:1068
static mysql_service_status_t validate_password_init()
Initialization entry method for Component used when loading the Component.
Definition: validate_password_imp.cc:1020

◆ password_policy_typelib_t

TYPE_LIB password_policy_typelib_t
static
Initial value:
"password_policy_typelib_t",
policy_names, nullptr}
#define array_elements(A)
Definition: validate_password_imp.cc:50
static const char * policy_names[]
Definition: validate_password_imp.cc:79

◆ PASSWORD_SCORE

const int PASSWORD_SCORE = 25

◆ policy_names

const char* policy_names[] = {"LOW", "MEDIUM", "STRONG", nullptr}
static

◆ REQUIRES_MYSQL_RWLOCK_SERVICE

REQUIRES_MYSQL_RWLOCK_SERVICE

◆ REQUIRES_MYSQL_RWLOCK_SERVICE_PLACEHOLDER

REQUIRES_MYSQL_RWLOCK_SERVICE_PLACEHOLDER

◆ REQUIRES_PSI_MEMORY_SERVICE

REQUIRES_PSI_MEMORY_SERVICE

◆ REQUIRES_PSI_MEMORY_SERVICE_PLACEHOLDER

REQUIRES_PSI_MEMORY_SERVICE_PLACEHOLDER

◆ validate_password_changed_characters_percentage

int validate_password_changed_characters_percentage = 0
static

◆ validate_password_dictionary_file

char* validate_password_dictionary_file
static

◆ validate_password_dictionary_file_last_parsed

char* validate_password_dictionary_file_last_parsed = nullptr
static

◆ validate_password_dictionary_file_words_count

long long validate_password_dictionary_file_words_count = 0
static

◆ validate_password_length

int validate_password_length
static

◆ validate_password_mixed_case_count

int validate_password_mixed_case_count
static

◆ validate_password_number_count

int validate_password_number_count
static

◆ validate_password_policy

ulong validate_password_policy
static

◆ validate_password_special_char_count

int validate_password_special_char_count
static

◆ validate_password_status_variables

SHOW_VAR validate_password_status_variables[]
static
Initial value:
= {
{"validate_password.dictionary_file_last_parsed",
{"validate_password.dictionary_file_words_count",
{nullptr, nullptr, SHOW_LONG, SHOW_SCOPE_GLOBAL}}
@ SHOW_LONG
shown as unsigned long
Definition: status_var.h:34
@ SHOW_CHAR_PTR
Definition: status_var.h:37
@ SHOW_LONGLONG
shown as unsigned longlong
Definition: status_var.h:35
@ SHOW_SCOPE_GLOBAL
Definition: status_var.h:70
static long long validate_password_dictionary_file_words_count
Definition: validate_password_imp.cc:96
static char * validate_password_dictionary_file_last_parsed
Definition: validate_password_imp.cc:95