1 | /* Copyright (c) 2014, Sergei Golubchik and MariaDB |
2 | Copyright (c) 2012, 2013, Oracle and/or its affiliates. |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
16 | |
17 | #include <mysqld_error.h> |
18 | #include <my_attribute.h> |
19 | #include <mysql/plugin_password_validation.h> |
20 | #include <ctype.h> |
21 | #include <string.h> |
22 | |
23 | static unsigned min_length, min_digits, min_letters, min_others; |
24 | |
25 | static int validate(MYSQL_CONST_LEX_STRING *username, |
26 | MYSQL_CONST_LEX_STRING *password) |
27 | { |
28 | unsigned digits=0 , uppers=0 , lowers=0, others=0, length= (unsigned)password->length; |
29 | const char *ptr= password->str, *end= ptr + length; |
30 | |
31 | if (strncmp(password->str, username->str, length) == 0) |
32 | return 1; |
33 | |
34 | /* everything non-ascii is the "other" character and is good for the password */ |
35 | for(; ptr < end; ptr++) |
36 | { |
37 | if (isdigit(*ptr)) |
38 | digits++; |
39 | else if (isupper(*ptr)) |
40 | uppers++; |
41 | else if (islower(*ptr)) |
42 | lowers++; |
43 | else |
44 | others++; |
45 | } |
46 | /* remember TRUE means the password failed the validation */ |
47 | return length < min_length || |
48 | uppers < min_letters || |
49 | lowers < min_letters || |
50 | digits < min_digits || |
51 | others < min_others; |
52 | } |
53 | |
54 | static void fix_min_length(MYSQL_THD thd __attribute__((unused)), |
55 | struct st_mysql_sys_var *var |
56 | __attribute__((unused)), |
57 | void *var_ptr, const void *save) |
58 | { |
59 | unsigned int new_min_length; |
60 | *((unsigned int *)var_ptr)= *((unsigned int *)save); |
61 | new_min_length= min_digits + 2 * min_letters + min_others; |
62 | if (min_length < new_min_length) |
63 | { |
64 | my_printf_error(ER_TRUNCATED_WRONG_VALUE, |
65 | "Adjusted the value of simple_password_check_minimal_length " |
66 | "from %u to %u" , ME_WARNING, min_length, new_min_length); |
67 | min_length= new_min_length; |
68 | } |
69 | } |
70 | |
71 | |
72 | static MYSQL_SYSVAR_UINT(minimal_length, min_length, PLUGIN_VAR_RQCMDARG, |
73 | "Minimal required password length" , NULL, fix_min_length, 8, 0, 1000, 1); |
74 | |
75 | static MYSQL_SYSVAR_UINT(digits, min_digits, PLUGIN_VAR_RQCMDARG, |
76 | "Minimal required number of digits" , NULL, fix_min_length, 1, 0, 1000, 1); |
77 | |
78 | static MYSQL_SYSVAR_UINT(letters_same_case, min_letters, PLUGIN_VAR_RQCMDARG, |
79 | "Minimal required number of letters of the same letter case." |
80 | "This limit is applied separately to upper-case and lower-case letters" , |
81 | NULL, fix_min_length, 1, 0, 1000, 1); |
82 | |
83 | static MYSQL_SYSVAR_UINT(other_characters, min_others, PLUGIN_VAR_RQCMDARG, |
84 | "Minimal required number of other (not letters or digits) characters" , |
85 | NULL, fix_min_length, 1, 0, 1000, 1); |
86 | |
87 | static struct st_mysql_sys_var* sysvars[]= { |
88 | MYSQL_SYSVAR(minimal_length), |
89 | MYSQL_SYSVAR(digits), |
90 | MYSQL_SYSVAR(letters_same_case), |
91 | MYSQL_SYSVAR(other_characters), |
92 | NULL |
93 | }; |
94 | |
95 | static struct st_mariadb_password_validation info= |
96 | { |
97 | MariaDB_PASSWORD_VALIDATION_INTERFACE_VERSION, |
98 | validate |
99 | }; |
100 | |
101 | maria_declare_plugin(simple_password_check) |
102 | { |
103 | MariaDB_PASSWORD_VALIDATION_PLUGIN, |
104 | &info, |
105 | "simple_password_check" , |
106 | "Sergei Golubchik" , |
107 | "Simple password strength checks" , |
108 | PLUGIN_LICENSE_GPL, |
109 | NULL, |
110 | NULL, |
111 | 0x0100, |
112 | NULL, |
113 | sysvars, |
114 | "1.0" , |
115 | MariaDB_PLUGIN_MATURITY_STABLE |
116 | } |
117 | maria_declare_plugin_end; |
118 | |