From: Ashish Agarwal Date: April 17 2012 7:13am Subject: bzr push into mysql-trunk branch (ashish.y.agarwal:3871 to 3872) WL#2739 List-Archive: http://lists.mysql.com/commits/143574 Message-Id: <201204170713.q3H7DeRX017933@acsmt358.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3872 Ashish Agarwal 2012-04-17 WL#2739: Failing test case in WL branch. modified: include/mysql/plugin.h mysql-test/r/validate_password_plugin.result mysql-test/t/validate_password_plugin.test plugin/password_validation/validate_password.cc sql/item_create.cc sql/item_strfunc.cc 3871 Ashish Agarwal 2012-04-16 WL#2739: Auditing Password Security added: include/mysql/plugin_validate_password.h mysql-test/include/have_validate_password_plugin.inc mysql-test/r/validate_password_plugin.result mysql-test/t/validate_password_plugin-master.opt mysql-test/t/validate_password_plugin.test plugin/password_validation/ plugin/password_validation/CMakeLists.txt plugin/password_validation/dictionary.txt plugin/password_validation/validate_password.cc modified: include/CMakeLists.txt include/mysql/plugin.h mysql-test/include/plugin.defs sql/item_create.cc sql/item_func.cc sql/item_func.h sql/item_strfunc.cc sql/share/errmsg-utf8.txt sql/sql_acl.cc sql/sql_acl.h sql/sql_plugin.cc sql/sql_yacc.yy === modified file 'include/mysql/plugin.h' --- a/include/mysql/plugin.h 2012-04-16 12:25:21 +0000 +++ b/include/mysql/plugin.h 2012-04-17 07:12:21 +0000 @@ -86,7 +86,7 @@ typedef struct st_mysql_xid MYSQL_XID; #define MYSQL_AUDIT_PLUGIN 5 /* The Audit plugin type */ #define MYSQL_REPLICATION_PLUGIN 6 /* The replication plugin type */ #define MYSQL_AUTHENTICATION_PLUGIN 7 /* The authentication plugin type */ -#define MYSQL_VALIDATE_PASSWORD_PLUGIN 8 /* validate password plugin type */ +#define MYSQL_VALIDATE_PASSWORD_PLUGIN 8 /* validate password plugin type */ #define MYSQL_MAX_PLUGIN_TYPE_NUM 9 /* The number of plugin types */ /* We use the following strings to define licenses for plugins */ === modified file 'mysql-test/r/validate_password_plugin.result' --- a/mysql-test/r/validate_password_plugin.result 2012-04-16 12:25:21 +0000 +++ b/mysql-test/r/validate_password_plugin.result 2012-04-17 07:12:21 +0000 @@ -1,74 +1,50 @@ +CREATE USER 'base_user'@'localhost' IDENTIFIED BY ''; INSTALL PLUGIN validate_password SONAME 'validate_password.so'; INSTALL PLUGIN validate_password SONAME 'validate_password.so'; ERROR HY000: Function 'validate_password' already exists -CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'password1A#'; -password policy low -SET @@global.validate_password_policy_number=1; +policy: low= 1, medium= 2, strong= 3 +password policy low (which only check for password length) +default case: password length should be minimum 8 +SET @@global.validate_password_policy_number= 1; CREATE USER 'user'@'localhost' IDENTIFIED BY ''; ERROR HY000: not a valid password '' -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('pass'); -ERROR HY000: not a valid password 'pass' -UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='base_user'; -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password123'; -password policy medium -SET @@global.validate_password_policy_number=2; -CREATE USER 'user'@'localhost' IDENTIFIED BY 'pass'; -ERROR HY000: not a valid password 'pass' -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1'); -ERROR HY000: not a valid password 'password1' -UPDATE mysql.user SET PASSWORD= PASSWORD('password1A') WHERE user='base_user'; -ERROR HY000: not a valid password 'password1A' -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#'; -password policy strong -SET @@global.validate_password_policy_number=3; -CREATE USER 'user'@'localhost' IDENTIFIED BY 'password1'; -ERROR HY000: not a valid password 'password1' -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A'); -ERROR HY000: not a valid password 'password1A' -UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; -ERROR HY000: not a valid password 'password1A#' -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A##'; -SET @@global.validate_password_policy_number= 1; +SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password'); SET @@global.validate_password_length= 12; -SET PASSWORD FOR 'base_user'@'localhost'= password('password'); +UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='base_user'; ERROR HY000: not a valid password 'password' -UPDATE mysql.user SET PASSWORD= password('password1A#') WHERE user='base_user'; -ERROR HY000: not a valid password 'password1A#' GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234'; SET @@global.validate_password_length= 8; +password policy medium (check for mixed_case, digits, special_chars) +default case : atleast 1 mixed_case, 1 digit, 1 special_char SET @@global.validate_password_policy_number= 2; -SET @@global.validate_password_numbers= 3; -CREATE USER 'user'@'localhost' IDENTIFIED BY 'password1A#'; +CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; +ERROR HY000: not a valid password 'password' +SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); +SET @@global.validate_password_numbers= 2; +UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; ERROR HY000: not a valid password 'password1A#' -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password123A#'); -SET @@global.validate_password_numbers= 4; -UPDATE mysql.user SET PASSWORD= PASSWORD('password123A#') WHERE user='base_user'; -ERROR HY000: not a valid password 'password123A#' -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234A#'; +UPDATE mysql.user SET PASSWORD= PASSWORD('password12A#') WHERE user='base_user'; SET @@global.validate_password_numbers= 1; -CREATE USER 'user'@'localhost' IDENTIFIED BY 'password1A'; -ERROR HY000: not a valid password 'password1A' -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); -SET @@global.validate_password_special_chars= 3; -UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#$') WHERE user='base_user'; -ERROR HY000: not a valid password 'password1A#$' -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$!'; -SET @@global.validate_password_special_chars= 1; -CREATE USER 'user'@'localhost' IDENTIFIED BY 'password1'; -ERROR HY000: not a valid password 'password1' -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); SET @@global.validate_password_mixed_case= 2; UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; ERROR HY000: not a valid password 'password1A#' -UPDATE mysql.user SET PASSWORD= PASSWORD('1234567AB#') WHERE user='base_user'; -ERROR HY000: not a valid password '1234567AB#' -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1AB#'; +UPDATE mysql.user SET PASSWORD= PASSWORD('password1AB#') WHERE user='base_user'; SET @@global.validate_password_mixed_case= 1; -SET @@global.validate_password_policy_number= 3; +SET @@global.validate_password_special_chars= 2; +GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#'; +ERROR HY000: not a valid password 'password1A#' +GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$'; +SET @@global.validate_password_special_chars= 1; +# password policy strong +# default_file : dictionary.txt +SET @@global.validate_password_policy_number=3; +CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; +ERROR HY000: not a valid password 'password' SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A$'); UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; ERROR HY000: not a valid password 'password1A#' -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1AB#'; +GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A##'; +# test for password_validate_strength function SELECT VALIDATE_PASSWORD_STRENGTH('password', 0); ERROR 42000: Incorrect parameter count in the call to native function 'VALIDATE_PASSWORD_STRENGTH' SELECT VALIDATE_PASSWORD_STRENGTH(); === modified file 'mysql-test/t/validate_password_plugin.test' --- a/mysql-test/t/validate_password_plugin.test 2012-04-16 12:25:21 +0000 +++ b/mysql-test/t/validate_password_plugin.test 2012-04-17 07:12:21 +0000 @@ -1,100 +1,65 @@ +--source include/not_embedded.inc --source include/have_validate_password_plugin.inc +CREATE USER 'base_user'@'localhost' IDENTIFIED BY ''; + INSTALL PLUGIN validate_password SONAME 'validate_password.so'; --error ER_UDF_EXISTS INSTALL PLUGIN validate_password SONAME 'validate_password.so'; -CREATE USER 'base_user'@'localhost' IDENTIFIED BY 'password1A#'; - # test for all the three password policy +--echo policy: low= 1, medium= 2, strong= 3 ---echo password policy low +--echo password policy low (which only check for password length) +--echo default case: password length should be minimum 8 -SET @@global.validate_password_policy_number=1; +SET @@global.validate_password_policy_number= 1; --error ER_NOT_VALID_PASSWORD CREATE USER 'user'@'localhost' IDENTIFIED BY ''; ---error ER_NOT_VALID_PASSWORD -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('pass'); -UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='base_user'; -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password123'; - ---echo password policy medium - -SET @@global.validate_password_policy_number=2; ---error ER_NOT_VALID_PASSWORD -CREATE USER 'user'@'localhost' IDENTIFIED BY 'pass'; ---error ER_NOT_VALID_PASSWORD -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1'); ---error ER_NOT_VALID_PASSWORD -UPDATE mysql.user SET PASSWORD= PASSWORD('password1A') WHERE user='base_user'; -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#'; - ---echo password policy strong - -SET @@global.validate_password_policy_number=3; ---error ER_NOT_VALID_PASSWORD -CREATE USER 'user'@'localhost' IDENTIFIED BY 'password1'; ---error ER_NOT_VALID_PASSWORD -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A'); ---error ER_NOT_VALID_PASSWORD -UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A##'; - -# test for password length option - -SET @@global.validate_password_policy_number= 1; +SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password'); SET @@global.validate_password_length= 12; --error ER_NOT_VALID_PASSWORD -SET PASSWORD FOR 'base_user'@'localhost'= password('password'); ---error ER_NOT_VALID_PASSWORD -UPDATE mysql.user SET PASSWORD= password('password1A#') WHERE user='base_user'; +UPDATE mysql.user SET PASSWORD= PASSWORD('password') WHERE user='base_user'; GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234'; SET @@global.validate_password_length= 8; -# test for number of digits in a password +--echo password policy medium (check for mixed_case, digits, special_chars) +--echo default case : atleast 1 mixed_case, 1 digit, 1 special_char SET @@global.validate_password_policy_number= 2; -SET @@global.validate_password_numbers= 3; ---error ER_NOT_VALID_PASSWORD -CREATE USER 'user'@'localhost' IDENTIFIED BY 'password1A#'; -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password123A#'); -SET @@global.validate_password_numbers= 4; --error ER_NOT_VALID_PASSWORD -UPDATE mysql.user SET PASSWORD= PASSWORD('password123A#') WHERE user='base_user'; -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1234A#'; -SET @@global.validate_password_numbers= 1; - -# test for number of special characters in password - ---error ER_NOT_VALID_PASSWORD -CREATE USER 'user'@'localhost' IDENTIFIED BY 'password1A'; +CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); -SET @@global.validate_password_special_chars= 3; ---error ER_NOT_VALID_PASSWORD -UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#$') WHERE user='base_user'; -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$!'; -SET @@global.validate_password_special_chars= 1; - -# test for number of uppercase and lowercase - +SET @@global.validate_password_numbers= 2; --error ER_NOT_VALID_PASSWORD -CREATE USER 'user'@'localhost' IDENTIFIED BY 'password1'; -SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A#'); +UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; +UPDATE mysql.user SET PASSWORD= PASSWORD('password12A#') WHERE user='base_user'; +SET @@global.validate_password_numbers= 1; SET @@global.validate_password_mixed_case= 2; --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; ---error ER_NOT_VALID_PASSWORD -UPDATE mysql.user SET PASSWORD= PASSWORD('1234567AB#') WHERE user='base_user'; -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1AB#'; +UPDATE mysql.user SET PASSWORD= PASSWORD('password1AB#') WHERE user='base_user'; SET @@global.validate_password_mixed_case= 1; +SET @@global.validate_password_special_chars= 2; +--error ER_NOT_VALID_PASSWORD +GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#'; +GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A#$'; +SET @@global.validate_password_special_chars= 1; -# test for dictionary file +--echo # password policy strong +--echo # default_file : dictionary.txt +# 'password1A#' is present in default dictionary.txt file +# file should contain 1 word per line -SET @@global.validate_password_policy_number= 3; +SET @@global.validate_password_policy_number=3; +--error ER_NOT_VALID_PASSWORD +CREATE USER 'user'@'localhost' IDENTIFIED BY 'password'; SET PASSWORD FOR 'base_user'@'localhost'= PASSWORD('password1A$'); --error ER_NOT_VALID_PASSWORD UPDATE mysql.user SET PASSWORD= PASSWORD('password1A#') WHERE user='base_user'; -GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1AB#'; +GRANT USAGE ON *.* TO 'base_user'@'localhost' IDENTIFIED BY 'password1A##'; + +--echo # test for password_validate_strength function --error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT SELECT VALIDATE_PASSWORD_STRENGTH('password', 0); === modified file 'plugin/password_validation/validate_password.cc' --- a/plugin/password_validation/validate_password.cc 2012-04-16 12:25:21 +0000 +++ b/plugin/password_validation/validate_password.cc 2012-04-17 07:12:21 +0000 @@ -38,8 +38,8 @@ static char *validate_password_dictionar static int validate_password_policy(const char *password, uint policy) { uint has_numbers= 0; - uint has_special_chars=0; - uint has_lower=0; + uint has_special_chars= 0; + uint has_lower= 0; uint has_upper= 0; uint password_length= strlen(password); const char *c= password; @@ -98,7 +98,7 @@ static int validate_password_strength(co return PASSWORD_STRENGTH_REJECTED; } -/* +/* Plugin type-specific descriptor */ @@ -112,7 +112,7 @@ static struct st_mysql_validate_password static int validate_password_init(void *arg __attribute__((unused))) { MYSQL_FILE *fp; - char buff[128]; /*maximum length of word stored in dictionary file */ + char buff[128]; /* maximum length of word stored in dictionary file */ uint count= 0; char *dictionary_file; char default_dictionary_file[FN_REFLEN]; === modified file 'sql/item_create.cc' --- a/sql/item_create.cc 2012-04-16 12:25:21 +0000 +++ b/sql/item_create.cc 2012-04-17 07:12:21 +0000 @@ -5193,7 +5193,7 @@ Create_func_uuid_short::create(THD *thd) } -Create_func_validate_password_strength +Create_func_validate_password_strength Create_func_validate_password_strength::s_singleton; Item* === modified file 'sql/item_strfunc.cc' --- a/sql/item_strfunc.cc 2012-04-16 12:25:21 +0000 +++ b/sql/item_strfunc.cc 2012-04-17 07:12:21 +0000 @@ -1923,11 +1923,11 @@ String *Item_func_password::val_str_asci { DBUG_ASSERT(fixed == 1); String *res= args[0]->val_str(str); + check_password_validation(res->ptr()); if ((null_value=args[0]->null_value)) return 0; if (res->length() == 0) return make_empty_result(); - check_password_validation(res->ptr()); my_make_scrambled_password(tmp_value, res->ptr(), res->length()); str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1); return str; No bundle (reason: useless for push emails).