MySQL 8.0.39
Source Code Documentation
validate_password.cc File Reference
#include <mysql/components/my_service.h>
#include <mysql/components/services/log_builtins.h>
#include <mysql/plugin_validate_password.h>
#include <mysql/service_my_plugin_log.h>
#include <mysql/service_mysql_string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <algorithm>
#include <fstream>
#include <set>
#include <string>
#include "my_compiler.h"
#include "my_inttypes.h"
#include "my_psi_config.h"
#include "my_sys.h"
#include "my_systime.h"
#include "mysql/mysql_lex_string.h"
#include "mysql/plugin.h"
#include "mysql/psi/mysql_rwlock.h"
#include "mysql/psi/psi_rwlock.h"
#include "mysql/service_locking.h"
#include "mysql/service_mysql_alloc.h"
#include "mysql/service_security_context.h"
#include "mysqld_error.h"
#include "sql/sql_error.h"
#include "typelib.h"

Macros

#define MAX_DICTIONARY_FILE_LENGTH   1024 * 1024
 
#define PASSWORD_SCORE   25
 
#define MIN_DICTIONARY_WORD_LENGTH   4
 
#define MAX_PASSWORD_LENGTH   100
 

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

THDthd_get_current_thd ()
 Get current THD object from thread local data. More...
 
static void init_validate_password_psi_keys ()
 
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 (mysql_string_handle 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 (MYSQL_SECURITY_CONTEXT ctx, const char *buffer, int length, const char *field_name, const char *logical_name)
 Validate a user name from the security context. More...
 
static bool is_valid_password_by_user_name (mysql_string_handle password)
 Check if the password is not the user name. More...
 
static int validate_password_policy_strength (mysql_string_handle password, int policy)
 
static int validate_password (mysql_string_handle password)
 
static int get_password_strength (mysql_string_handle password)
 
static void readjust_validate_password_length ()
 Check and readjust effective value of validate_password_length. More...
 
static int validate_password_init (MYSQL_PLUGIN plugin_info)
 
static int validate_password_deinit (void *arg)
 
static void dictionary_update (MYSQL_THD thd, SYS_VAR *var, void *var_ptr, const void *save)
 
static void length_update (MYSQL_THD thd, SYS_VAR *var, void *var_ptr, const void *save)
 
static MYSQL_SYSVAR_INT (length, validate_password_length, PLUGIN_VAR_RQCMDARG, "Password validate length to check for minimum password_length", nullptr, length_update, 8, 0, 0, 0)
 
static MYSQL_SYSVAR_INT (number_count, validate_password_number_count, PLUGIN_VAR_RQCMDARG, "password validate digit to ensure minimum numeric character in password", nullptr, length_update, 1, 0, 0, 0)
 
static MYSQL_SYSVAR_INT (mixed_case_count, validate_password_mixed_case_count, PLUGIN_VAR_RQCMDARG, "Password validate mixed case to ensure minimum " "upper/lower case in password", nullptr, length_update, 1, 0, 0, 0)
 
static MYSQL_SYSVAR_INT (special_char_count, validate_password_special_char_count, PLUGIN_VAR_RQCMDARG, "password validate special to ensure minimum special character in password", nullptr, length_update, 1, 0, 0, 0)
 
static MYSQL_SYSVAR_ENUM (policy, validate_password_policy, PLUGIN_VAR_RQCMDARG, "password_validate_policy choosen policy to validate password" "possible values are LOW MEDIUM (default), STRONG", nullptr, nullptr, PASSWORD_POLICY_MEDIUM, &password_policy_typelib_t)
 
static MYSQL_SYSVAR_STR (dictionary_file, validate_password_dictionary_file, PLUGIN_VAR_RQCMDARG|PLUGIN_VAR_MEMALLOC, "password_validate_dictionary file to be loaded and check for password", nullptr, dictionary_update, nullptr)
 
static MYSQL_SYSVAR_BOOL (check_user_name, check_user_name, PLUGIN_VAR_NOCMDARG, "Check if the password matches the login or the effective user names " "or the reverse of them", nullptr, nullptr, true)
 
 mysql_declare_plugin (validate_password)
 

Variables

static const mysql_service_registry_treg_srv = nullptr
 
const mysql_service_log_builtins_tlog_bi = nullptr
 accessor built-ins More...
 
const mysql_service_log_builtins_string_tlog_bs = nullptr
 string built-ins More...
 
mysql_rwlock_t LOCK_dict_file
 
PSI_rwlock_key key_validate_password_LOCK_dict_file
 
static PSI_rwlock_info all_validate_password_rwlocks []
 
static MYSQL_PLUGIN plugin_info_ptr
 
static const char * policy_names [] = {"LOW", "MEDIUM", "STRONG", NullS}
 
static TYPELIB 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 struct st_mysql_validate_password validate_password_descriptor
 
static SYS_VARvalidate_password_system_variables []
 
static SHOW_VAR validate_password_status_variables []
 
 mysql_declare_plugin_end
 

Macro Definition Documentation

◆ MAX_DICTIONARY_FILE_LENGTH

#define MAX_DICTIONARY_FILE_LENGTH   1024 * 1024

◆ MAX_PASSWORD_LENGTH

#define MAX_PASSWORD_LENGTH   100

◆ MIN_DICTIONARY_WORD_LENGTH

#define MIN_DICTIONARY_WORD_LENGTH   4

◆ PASSWORD_SCORE

#define PASSWORD_SCORE   25

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  thd,
SYS_VAR var,
void *  var_ptr,
const void *  save 
)
static

◆ free_dictionary_file()

static void free_dictionary_file ( )
static

◆ get_password_strength()

static int get_password_strength ( mysql_string_handle  password)
static

◆ init_validate_password_psi_keys()

static void init_validate_password_psi_keys ( )
static

◆ is_valid_password_by_user_name()

static bool is_valid_password_by_user_name ( mysql_string_handle  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
passwordthe password handle
Return values
trueThe password can be used
falsethe password is invalid

◆ is_valid_user()

static bool is_valid_user ( MYSQL_SECURITY_CONTEXT  ctx,
const char *  buffer,
int  length,
const char *  field_name,
const char *  logical_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
logical_namethe name of the field to use in the error message
Return values
truename can be used
falsename is invalid

◆ length_update()

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

◆ 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

◆ mysql_declare_plugin()

mysql_declare_plugin ( validate_password  )

◆ MYSQL_SYSVAR_BOOL()

static MYSQL_SYSVAR_BOOL ( check_user_name  ,
check_user_name  ,
PLUGIN_VAR_NOCMDARG  ,
"Check if the password matches the login or the effective user names " "or the reverse of them"  ,
nullptr  ,
nullptr  ,
true   
)
static

◆ MYSQL_SYSVAR_ENUM()

static MYSQL_SYSVAR_ENUM ( policy  ,
validate_password_policy  ,
PLUGIN_VAR_RQCMDARG  ,
"password_validate_policy choosen policy to validate password" "possible values are LOW MEDIUM   default,
STRONG"  ,
nullptr  ,
nullptr  ,
PASSWORD_POLICY_MEDIUM  ,
password_policy_typelib_t 
)
static

◆ MYSQL_SYSVAR_INT() [1/4]

static MYSQL_SYSVAR_INT ( length  ,
validate_password_length  ,
PLUGIN_VAR_RQCMDARG  ,
"Password validate length to check for minimum password_length"  ,
nullptr  ,
length_update  ,
,
,
,
 
)
static

◆ MYSQL_SYSVAR_INT() [2/4]

static MYSQL_SYSVAR_INT ( mixed_case_count  ,
validate_password_mixed_case_count  ,
PLUGIN_VAR_RQCMDARG  ,
"Password validate mixed case to ensure minimum " "upper/lower case in password ,
nullptr  ,
length_update  ,
,
,
,
 
)
static

◆ MYSQL_SYSVAR_INT() [3/4]

static MYSQL_SYSVAR_INT ( number_count  ,
validate_password_number_count  ,
PLUGIN_VAR_RQCMDARG  ,
"password validate digit to ensure minimum numeric character in password ,
nullptr  ,
length_update  ,
,
,
,
 
)
static

◆ MYSQL_SYSVAR_INT() [4/4]

static MYSQL_SYSVAR_INT ( special_char_count  ,
validate_password_special_char_count  ,
PLUGIN_VAR_RQCMDARG  ,
"password validate special to ensure minimum special character in password ,
nullptr  ,
length_update  ,
,
,
,
 
)
static

◆ MYSQL_SYSVAR_STR()

static MYSQL_SYSVAR_STR ( dictionary_file  ,
validate_password_dictionary_file  ,
PLUGIN_VAR_RQCMDARG PLUGIN_VAR_MEMALLOC,
"password_validate_dictionary file to be loaded and check for password ,
nullptr  ,
dictionary_update  ,
nullptr   
)
static

◆ 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.

◆ thd_get_current_thd()

THD * thd_get_current_thd ( )

Get current THD object from thread local data.

Return values
TheTHD object for the thread, NULL if not connection thread

◆ validate_dictionary_check()

static int validate_dictionary_check ( mysql_string_handle  password)
static

◆ validate_password()

static int validate_password ( mysql_string_handle  password)
static

◆ validate_password_deinit()

static int validate_password_deinit ( void *  arg)
static

◆ validate_password_init()

static int validate_password_init ( MYSQL_PLUGIN  plugin_info)
static

◆ validate_password_policy_strength()

static int validate_password_policy_strength ( mysql_string_handle  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,
#define PSI_DOCUMENT_ME
Definition: component_common.h:29
PSI_rwlock_key key_validate_password_LOCK_dict_file
Definition: validate_password.cc:74

◆ check_user_name

bool check_user_name
static

◆ dictionary_words

set_type* dictionary_words {nullptr}
static

◆ 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

◆ mysql_declare_plugin_end

mysql_declare_plugin_end

◆ password_policy_typelib_t

TYPELIB password_policy_typelib_t
static
Initial value:
"password_policy_typelib_t",
policy_names, nullptr}
static const char * policy_names[]
Definition: validate_password.cc:106
#define array_elements(A)
Definition: validate_password_imp.cc:48

◆ plugin_info_ptr

MYSQL_PLUGIN plugin_info_ptr
static

◆ policy_names

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

◆ reg_srv

const mysql_service_registry_t* reg_srv = nullptr
static

◆ validate_password_descriptor

struct st_mysql_validate_password validate_password_descriptor
static
Initial value:
= {
}
#define MYSQL_VALIDATE_PASSWORD_INTERFACE_VERSION
Definition: plugin_validate_password.h:33
static int get_password_strength(mysql_string_handle password)
Definition: validate_password.cc:400
static int validate_password(mysql_string_handle password)
Definition: validate_password.cc:395

◆ 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",
#define NullS
Definition of the null string (a null pointer of type char *), used in some of our string handling co...
Definition: m_string.h:53
@ 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.cc:123
static char * validate_password_dictionary_file_last_parsed
Definition: validate_password.cc:122

◆ validate_password_system_variables

SYS_VAR* validate_password_system_variables[]
static
Initial value:
= {
MYSQL_SYSVAR(length), MYSQL_SYSVAR(number_count),
MYSQL_SYSVAR(mixed_case_count), MYSQL_SYSVAR(special_char_count),
MYSQL_SYSVAR(policy), MYSQL_SYSVAR(dictionary_file),
#define MYSQL_SYSVAR(name)
Definition: plugin.h:252
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
static bool check_user_name
Definition: validate_password.cc:124