summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2022-06-29 14:56:10 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2022-07-06 12:23:31 +0200
commita5f78505d798ff973daed8cfec1e8486c89a23ed (patch)
tree8d458cb6e0b9b0afd341fbf92ed8d230554fd76d
parentc12192b1c663a50d76245fc2f6f6617f6df5da66 (diff)
downloadmariadb-git-a5f78505d798ff973daed8cfec1e8486c89a23ed.tar.gz
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.
-rw-r--r--mysql-test/suite/plugins/r/password_reuse_check.result22
-rw-r--r--mysql-test/suite/plugins/t/password_reuse_check.test27
-rw-r--r--plugin/password_reuse_check/password_reuse_check.c37
3 files changed, 77 insertions, 9 deletions
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
@@ -70,4 +70,31 @@ 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 <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;