diff --git a/mysql-test/suite/plugins/r/password_reuse_check.result b/mysql-test/suite/plugins/r/password_reuse_check.result index a9b79cf34fc..e4f4dc0fab8 100644 --- a/mysql-test/suite/plugins/r/password_reuse_check.result +++ b/mysql-test/suite/plugins/r/password_reuse_check.result @@ -30,7 +30,7 @@ Error 1819 Your password does not satisfy the current policy requirements Error 1396 Operation ALTER USER failed for 'user_name'@'localhost' select hex(hash) from mysql.password_reuse_check_history; hex(hash) -6276C87127F2B65FC6B24E94E324A02FF0D393D7FB7DEAF6F5F49F0A8AB006711D5C6EF67E36A251AB6337E7E20D312F9ED66D70EB699A6EC85B1E0BC7F376C0 +B9F970DE4DA0145F842526C1BC9DBBBDB3EF80FDD7BE98061DAE3D18F492AA37668C07322DD21650C66B48FC78F0EAF6CB08245CC895BFDC43BE6921B07E5240 # emulate old password update mysql.password_reuse_check_history set time= date_sub(now(), interval 11 day); @@ -71,4 +71,24 @@ Level Code Message Warning 1105 password_reuse_check:[1054] Unknown column 'time' in 'where clause' Error 1819 Your password does not satisfy the current policy requirements drop table mysql.password_reuse_check_history; +# +# MDEV-28838: password_reuse_check plugin mixes username and password +# +grant select on *.* to user_name@localhost identified by 'test_pwd'; +grant select on *.* to user_nam@localhost identified by 'etest_pwd'; +show warnings; +Level Code Message +drop user user_name@localhost; +drop user user_nam@localhost; +drop table mysql.password_reuse_check_history; +grant select on *.* to user_name@localhost identified by 'test_pwd'; +grant select on *.* to tuser_name@localhos identified by 'test_pwd'; +show warnings; +Level Code Message +drop user user_name@localhost; +drop user tuser_name@localhos; +# +# End of 10.7 tests +# +drop table mysql.password_reuse_check_history; uninstall plugin password_reuse_check; diff --git a/mysql-test/suite/plugins/t/password_reuse_check.test b/mysql-test/suite/plugins/t/password_reuse_check.test index 85811df4a2e..16ff21dc454 100644 --- a/mysql-test/suite/plugins/t/password_reuse_check.test +++ b/mysql-test/suite/plugins/t/password_reuse_check.test @@ -69,5 +69,32 @@ set global password_reuse_check_interval= 10; grant select on *.* to user_name@localhost identified by 'test_pwd'; show warnings; +drop table mysql.password_reuse_check_history; + +--echo # +--echo # MDEV-28838: password_reuse_check plugin mixes username and password +--echo # + +grant select on *.* to user_name@localhost identified by 'test_pwd'; + +grant select on *.* to user_nam@localhost identified by 'etest_pwd'; +show warnings; + +drop user user_name@localhost; +drop user user_nam@localhost; +drop table mysql.password_reuse_check_history; + +grant select on *.* to user_name@localhost identified by 'test_pwd'; + +grant select on *.* to tuser_name@localhos identified by 'test_pwd'; +show warnings; + +drop user user_name@localhost; +drop user tuser_name@localhos; + +--echo # +--echo # End of 10.7 tests +--echo # + drop table mysql.password_reuse_check_history; uninstall plugin password_reuse_check; diff --git a/plugin/password_reuse_check/password_reuse_check.c b/plugin/password_reuse_check/password_reuse_check.c index ff0364ce007..103eb4e4144 100644 --- a/plugin/password_reuse_check/password_reuse_check.c +++ b/plugin/password_reuse_check/password_reuse_check.c @@ -13,6 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ +#include // for int2store #include // for snprintf #include // for memset #include @@ -30,6 +31,22 @@ static unsigned interval= 0; // helping string for bin_to_hex512 static char digits[]= "0123456789ABCDEF"; +/** + Store string with length + + @param to buffer where to put the length and string + @param from the string to store + + @return reference on the byte after copied string +*/ + +static char *store_str(char *to, const MYSQL_CONST_LEX_STRING *from) +{ + int2store(to, from->length); + memcpy(to + 2, from->str, from->length); + return to + 2 + from->length; +} + /** Convert string of 512 bits (64 bytes) to hex representation @@ -149,7 +166,8 @@ static int validate(const MYSQL_CONST_LEX_STRING *username, const MYSQL_CONST_LEX_STRING *hostname) { MYSQL *mysql= NULL; - size_t key_len= username->length + password->length + hostname->length; + size_t key_len= username->length + password->length + hostname->length + + (3 * 2 /* space for storing length of the strings */); size_t buff_len= (key_len > SQL_BUFF_LEN ? key_len : SQL_BUFF_LEN); size_t len; char *buff= malloc(buff_len); @@ -165,13 +183,16 @@ static int validate(const MYSQL_CONST_LEX_STRING *username, return 1; } - memcpy(buff, hostname->str, hostname->length); - memcpy(buff + hostname->length, username->str, username->length); - memcpy(buff + hostname->length + username->length, password->str, - password->length); - buff[key_len]= 0; + /* + Store: username, hostname, password + (password first to make its rewriting password in memory simplier) + */ + store_str(store_str(store_str(buff, password), username), hostname); + buff[key_len]= 0; // safety memset(hash, 0, sizeof(hash)); my_sha512(hash, buff, key_len); + // safety: rewrite password with zerows + memset(buff, 0, password->length); if (mysql_real_connect_local(mysql) == NULL) goto sql_error; @@ -232,10 +253,10 @@ maria_declare_plugin(password_reuse_check) PLUGIN_LICENSE_GPL, NULL, NULL, - 0x0100, + 0x0200, NULL, sysvars, - "1.0", + "2.0", MariaDB_PLUGIN_MATURITY_GAMMA } maria_declare_plugin_end;