1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-28838 password_reuse_check plugin mixes username and password

To prevent the problem of mixing user name and password and
host name and user name we add length of the hostname and user name
to the hash.
This commit is contained in:
Oleksandr Byelkin
2022-06-29 14:56:10 +02:00
parent c12192b1c6
commit a5f78505d7
3 changed files with 77 additions and 9 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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 <my_global.h> // for int2store
#include <stdio.h> // for snprintf
#include <string.h> // for memset
#include <mysql/plugin_password_validation.h>
@ -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;