Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
ae7e164f
Commit
ae7e164f
authored
Oct 22, 2002
by
peter@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/pz/mysql/mysql-4.1-root
into mysql.com:/home/pz/mysql/mysql-4.1
parents
31d702dd
bdee968a
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
207 additions
and
221 deletions
+207
-221
client/insert_test.c
client/insert_test.c
+1
-0
client/mysqladmin.c
client/mysqladmin.c
+1
-1
client/select_test.c
client/select_test.c
+1
-0
include/mysql_com.h
include/mysql_com.h
+4
-1
libmysql/Makefile.shared
libmysql/Makefile.shared
+1
-1
libmysql/password.c
libmysql/password.c
+0
-191
mysql-test/r/func_crypt.result
mysql-test/r/func_crypt.result
+3
-3
mysql-test/t/func_crypt.test
mysql-test/t/func_crypt.test
+1
-1
sql/item_create.cc
sql/item_create.cc
+7
-0
sql/item_create.h
sql/item_create.h
+1
-0
sql/item_strfunc.cc
sql/item_strfunc.cc
+15
-1
sql/item_strfunc.h
sql/item_strfunc.h
+18
-2
sql/lex.h
sql/lex.h
+1
-0
sql/mysql_priv.h
sql/mysql_priv.h
+2
-1
sql/mysqld.cc
sql/mysqld.cc
+6
-2
sql/password.c
sql/password.c
+85
-8
sql/sql_acl.cc
sql/sql_acl.cc
+58
-7
sql/sql_yacc.yy
sql/sql_yacc.yy
+2
-2
No files found.
client/insert_test.c
View file @
ae7e164f
...
...
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "my_global.h"
#include "mysql.h"
#define INSERT_QUERY "insert into test (name,num) values ('item %d', %d)"
...
...
client/mysqladmin.c
View file @
ae7e164f
...
...
@@ -731,7 +731,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
return
1
;
}
if
(
argv
[
1
][
0
])
make_scrambled_password
(
crypted_pw
,
argv
[
1
]
);
make_scrambled_password
(
crypted_pw
,
argv
[
1
]
,
0
);
/* New passwords only */
else
crypted_pw
[
0
]
=
0
;
/* No password */
sprintf
(
buff
,
"set password='%s',sql_log_off=0"
,
crypted_pw
);
...
...
client/select_test.c
View file @
ae7e164f
...
...
@@ -19,6 +19,7 @@
#endif
#include <stdio.h>
#include <stdlib.h>
#include "my_global.h"
#include "mysql.h"
#define SELECT_QUERY "select name from test where num = %d"
...
...
include/mysql_com.h
View file @
ae7e164f
...
...
@@ -97,6 +97,7 @@ enum enum_server_command
#define CLIENT_IGNORE_SIGPIPE 4096
/* IGNORE sigpipes */
#define CLIENT_TRANSACTIONS 8192
/* Client knows about transactions */
#define CLIENT_PROTOCOL_41 16384
/* New 4.1 protocol */
#define CLIENT_SECURE_CONNECTION 32768
/* New 4.1 authentication */
#define SERVER_STATUS_IN_TRANS 1
/* Transaction has started */
#define SERVER_STATUS_AUTOCOMMIT 2
/* Server in auto_commit mode */
...
...
@@ -279,7 +280,9 @@ extern unsigned long net_buffer_length;
void
randominit
(
struct
rand_struct
*
,
unsigned
long
seed1
,
unsigned
long
seed2
);
double
rnd
(
struct
rand_struct
*
);
void
make_scrambled_password
(
char
*
to
,
const
char
*
password
);
void
make_scrambled_password
(
char
*
to
,
const
char
*
password
,
my_bool
force_old_scramble
);
uint
get_password_length
(
my_bool
force_old_scramble
);
uint8
get_password_version
(
const
char
*
password
);
void
get_salt_from_password
(
unsigned
long
*
res
,
const
char
*
password
);
void
make_password_from_salt
(
char
*
to
,
unsigned
long
*
hash_res
);
char
*
scramble
(
char
*
to
,
const
char
*
message
,
const
char
*
password
,
...
...
libmysql/Makefile.shared
View file @
ae7e164f
...
...
@@ -60,7 +60,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_compress.lo array.lo my_once.lo list.lo my_net.lo
\
charset.lo hash.lo mf_iocache.lo
\
mf_iocache2.lo my_seek.lo
\
my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo
\
my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo
sha1.lo
\
my_getopt.lo my_gethostbyname.lo my_port.lo
sqlobjects
=
net.lo
...
...
libmysql/password.c
100644 → 100755
View file @
ae7e164f
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* password checking routines */
/*****************************************************************************
The main idea is that no password are sent between client & server on
connection and that no password are saved in mysql in a decodable form.
On connection a random string is generated and sent to the client.
The client generates a new string with a random generator inited with
the hash values from the password and the sent string.
This 'check' string is sent to the server where it is compared with
a string generated from the stored hash_value of the password and the
random string.
The password is saved (in user.password) by using the PASSWORD() function in
mysql.
Example:
update user set password=PASSWORD("hello") where user="test"
This saves a hashed number as a string in the password field.
*****************************************************************************/
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include "mysql.h"
void
randominit
(
struct
rand_struct
*
rand_st
,
ulong
seed1
,
ulong
seed2
)
{
/* For mysql 3.21.# */
#ifdef HAVE_purify
bzero
((
char
*
)
rand_st
,
sizeof
(
*
rand_st
));
/* Avoid UMC varnings */
#endif
rand_st
->
max_value
=
0x3FFFFFFFL
;
rand_st
->
max_value_dbl
=
(
double
)
rand_st
->
max_value
;
rand_st
->
seed1
=
seed1
%
rand_st
->
max_value
;
rand_st
->
seed2
=
seed2
%
rand_st
->
max_value
;
}
static
void
old_randominit
(
struct
rand_struct
*
rand_st
,
ulong
seed1
)
{
/* For mysql 3.20.# */
rand_st
->
max_value
=
0x01FFFFFFL
;
rand_st
->
max_value_dbl
=
(
double
)
rand_st
->
max_value
;
seed1
%=
rand_st
->
max_value
;
rand_st
->
seed1
=
seed1
;
rand_st
->
seed2
=
seed1
/
2
;
}
double
rnd
(
struct
rand_struct
*
rand_st
)
{
rand_st
->
seed1
=
(
rand_st
->
seed1
*
3
+
rand_st
->
seed2
)
%
rand_st
->
max_value
;
rand_st
->
seed2
=
(
rand_st
->
seed1
+
rand_st
->
seed2
+
33
)
%
rand_st
->
max_value
;
return
(((
double
)
rand_st
->
seed1
)
/
rand_st
->
max_value_dbl
);
}
void
hash_password
(
ulong
*
result
,
const
char
*
password
)
{
register
ulong
nr
=
1345345333L
,
add
=
7
,
nr2
=
0x12345671L
;
ulong
tmp
;
for
(;
*
password
;
password
++
)
{
if
(
*
password
==
' '
||
*
password
==
'\t'
)
continue
;
/* skipp space in password */
tmp
=
(
ulong
)
(
uchar
)
*
password
;
nr
^=
(((
nr
&
63
)
+
add
)
*
tmp
)
+
(
nr
<<
8
);
nr2
+=
(
nr2
<<
8
)
^
nr
;
add
+=
tmp
;
}
result
[
0
]
=
nr
&
(((
ulong
)
1L
<<
31
)
-
1L
);
/* Don't use sign bit (str2int) */
;
result
[
1
]
=
nr2
&
(((
ulong
)
1L
<<
31
)
-
1L
);
return
;
}
void
make_scrambled_password
(
char
*
to
,
const
char
*
password
)
{
ulong
hash_res
[
2
];
hash_password
(
hash_res
,
password
);
sprintf
(
to
,
"%08lx%08lx"
,
hash_res
[
0
],
hash_res
[
1
]);
}
static
inline
uint
char_val
(
char
X
)
{
return
(
uint
)
(
X
>=
'0'
&&
X
<=
'9'
?
X
-
'0'
:
X
>=
'A'
&&
X
<=
'Z'
?
X
-
'A'
+
10
:
X
-
'a'
+
10
);
}
/*
** This code assumes that len(password) is divideable with 8 and that
** res is big enough (2 in mysql)
*/
void
get_salt_from_password
(
ulong
*
res
,
const
char
*
password
)
{
res
[
0
]
=
res
[
1
]
=
0
;
if
(
password
)
{
while
(
*
password
)
{
ulong
val
=
0
;
uint
i
;
for
(
i
=
0
;
i
<
8
;
i
++
)
val
=
(
val
<<
4
)
+
char_val
(
*
password
++
);
*
res
++=
val
;
}
}
return
;
}
void
make_password_from_salt
(
char
*
to
,
ulong
*
hash_res
)
{
sprintf
(
to
,
"%08lx%08lx"
,
hash_res
[
0
],
hash_res
[
1
]);
}
/*
* Genererate a new message based on message and password
* The same thing is done in client and server and the results are checked.
*/
char
*
scramble
(
char
*
to
,
const
char
*
message
,
const
char
*
password
,
my_bool
old_ver
)
{
struct
rand_struct
rand_st
;
ulong
hash_pass
[
2
],
hash_message
[
2
];
if
(
password
&&
password
[
0
])
{
char
*
to_start
=
to
;
hash_password
(
hash_pass
,
password
);
hash_password
(
hash_message
,
message
);
if
(
old_ver
)
old_randominit
(
&
rand_st
,
hash_pass
[
0
]
^
hash_message
[
0
]);
else
randominit
(
&
rand_st
,
hash_pass
[
0
]
^
hash_message
[
0
],
hash_pass
[
1
]
^
hash_message
[
1
]);
while
(
*
message
++
)
*
to
++=
(
char
)
(
floor
(
rnd
(
&
rand_st
)
*
31
)
+
64
);
if
(
!
old_ver
)
{
/* Make it harder to break */
char
extra
=
(
char
)
(
floor
(
rnd
(
&
rand_st
)
*
31
));
while
(
to_start
!=
to
)
*
(
to_start
++
)
^=
extra
;
}
}
*
to
=
0
;
return
to
;
}
my_bool
check_scramble
(
const
char
*
scrambled
,
const
char
*
message
,
ulong
*
hash_pass
,
my_bool
old_ver
)
{
struct
rand_struct
rand_st
;
ulong
hash_message
[
2
];
char
buff
[
16
],
*
to
,
extra
;
/* Big enough for check */
const
char
*
pos
;
hash_password
(
hash_message
,
message
);
if
(
old_ver
)
old_randominit
(
&
rand_st
,
hash_pass
[
0
]
^
hash_message
[
0
]);
else
randominit
(
&
rand_st
,
hash_pass
[
0
]
^
hash_message
[
0
],
hash_pass
[
1
]
^
hash_message
[
1
]);
to
=
buff
;
for
(
pos
=
scrambled
;
*
pos
;
pos
++
)
*
to
++=
(
char
)
(
floor
(
rnd
(
&
rand_st
)
*
31
)
+
64
);
if
(
old_ver
)
extra
=
0
;
else
extra
=
(
char
)
(
floor
(
rnd
(
&
rand_st
)
*
31
));
to
=
buff
;
while
(
*
scrambled
)
{
if
(
*
scrambled
++
!=
(
char
)
(
*
to
++
^
extra
))
return
1
;
/* Wrong password */
}
return
0
;
}
mysql-test/r/func_crypt.result
View file @
ae7e164f
select length(encrypt('foo', 'ff')) <> 0;
length(encrypt('foo', 'ff')) <> 0
1
select
password('test'
),length(encrypt('test')),encrypt('test','aa');
password('test'
) length(encrypt('test')) encrypt('test','aa')
378b243e220ca493 13 aaqPiZY5xR5l.
select
old_password('test'),length(password("1")
),length(encrypt('test')),encrypt('test','aa');
old_password('test') length(password("1")
) length(encrypt('test')) encrypt('test','aa')
378b243e220ca493
45
13 aaqPiZY5xR5l.
mysql-test/t/func_crypt.test
View file @
ae7e164f
select
length
(
encrypt
(
'foo'
,
'ff'
))
<>
0
;
--
replace_result
$
1
$aa
$
4
OSUA5cjdx0RUQ08opV27
/
aaqPiZY5xR5l
.
select
password
(
'test'
),
length
(
encrypt
(
'test'
)),
encrypt
(
'test'
,
'aa'
);
select
old_password
(
'test'
),
length
(
password
(
"1"
)
),
length
(
encrypt
(
'test'
)),
encrypt
(
'test'
,
'aa'
);
sql/item_create.cc
View file @
ae7e164f
...
...
@@ -52,6 +52,13 @@ Item *create_func_ord(Item* a)
return
new
Item_func_ord
(
a
);
}
Item
*
create_func_old_password
(
Item
*
a
)
{
return
new
Item_func_old_password
(
a
);
}
Item
*
create_func_asin
(
Item
*
a
)
{
return
new
Item_func_asin
(
a
);
...
...
sql/item_create.h
View file @
ae7e164f
...
...
@@ -66,6 +66,7 @@ Item *create_func_monthname(Item* a);
Item
*
create_func_nullif
(
Item
*
a
,
Item
*
b
);
Item
*
create_func_oct
(
Item
*
);
Item
*
create_func_ord
(
Item
*
a
);
Item
*
create_func_old_password
(
Item
*
a
);
Item
*
create_func_period_add
(
Item
*
a
,
Item
*
b
);
Item
*
create_func_period_diff
(
Item
*
a
,
Item
*
b
);
Item
*
create_func_pi
(
void
);
...
...
sql/item_strfunc.cc
View file @
ae7e164f
...
...
@@ -1273,11 +1273,25 @@ String *Item_func_password::val_str(String *str)
return
0
;
if
(
res
->
length
()
==
0
)
return
&
empty_string
;
make_scrambled_password
(
tmp_value
,
res
->
c_ptr
());
make_scrambled_password
(
tmp_value
,
res
->
c_ptr
(),
opt_old_passwords
);
str
->
set
(
tmp_value
,
get_password_length
(
opt_old_passwords
),
res
->
charset
());
return
str
;
}
String
*
Item_func_old_password
::
val_str
(
String
*
str
)
{
String
*
res
=
args
[
0
]
->
val_str
(
str
);
if
((
null_value
=
args
[
0
]
->
null_value
))
return
0
;
if
(
res
->
length
()
==
0
)
return
&
empty_string
;
make_scrambled_password
(
tmp_value
,
res
->
c_ptr
(),
1
);
str
->
set
(
tmp_value
,
16
,
res
->
charset
());
return
str
;
}
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
String
*
Item_func_encrypt
::
val_str
(
String
*
str
)
...
...
sql/item_strfunc.h
View file @
ae7e164f
...
...
@@ -21,6 +21,9 @@
#pragma interface
/* gcc class implementation */
#endif
extern
my_bool
opt_old_passwords
;
/* Need this variable for some functions */
class
Item_str_func
:
public
Item_func
{
public:
...
...
@@ -243,14 +246,27 @@ class Item_func_trim :public Item_str_func
class
Item_func_password
:
public
Item_str_func
{
char
tmp_value
[
17
];
char
tmp_value
[
64
];
/* This should be enough for new password format */
public:
Item_func_password
(
Item
*
a
)
:
Item_str_func
(
a
)
{}
String
*
val_str
(
String
*
);
void
fix_length_and_dec
()
{
max_length
=
16
;
}
void
fix_length_and_dec
()
{
max_length
=
get_password_length
(
opt_old_passwords
)
;
}
const
char
*
func_name
()
const
{
return
"password"
;
}
};
class
Item_func_old_password
:
public
Item_str_func
{
char
tmp_value
[
16
];
/* old password length */
public:
Item_func_old_password
(
Item
*
a
)
:
Item_str_func
(
a
)
{}
String
*
val_str
(
String
*
);
void
fix_length_and_dec
()
{
max_length
=
get_password_length
(
1
);
}
const
char
*
func_name
()
const
{
return
"old_password"
;
}
};
class
Item_func_des_encrypt
:
public
Item_str_func
{
String
tmp_value
;
...
...
sql/lex.h
View file @
ae7e164f
...
...
@@ -513,6 +513,7 @@ static SYMBOL sql_functions[] = {
{
"NUMPOINTS"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_numpoints
)},
{
"OCTET_LENGTH"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_length
)},
{
"OCT"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_oct
)},
{
"OLD_PASSWORD"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_old_password
)},
{
"ORD"
,
SYM
(
FUNC_ARG1
),
0
,
CREATE_FUNC
(
create_func_ord
)},
{
"OVERLAPS"
,
SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC
(
create_func_overlaps
)},
{
"PERIOD_ADD"
,
SYM
(
FUNC_ARG2
),
0
,
CREATE_FUNC
(
create_func_period_add
)},
...
...
sql/mysql_priv.h
View file @
ae7e164f
...
...
@@ -66,7 +66,8 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
****************************************************************************/
#define ACL_CACHE_SIZE 256
#define HASH_PASSWORD_LENGTH 16
/* Password lengh for 4.1 version previous versions had 16 bytes password hash */
#define HASH_PASSWORD_LENGTH 45
#define HOST_CACHE_SIZE 128
#define MAX_ACCEPT_RETRY 10 // Test accept this many times
#define MAX_FIELDS_BEFORE_HASH 32
...
...
sql/mysqld.cc
View file @
ae7e164f
...
...
@@ -278,7 +278,7 @@ static my_bool opt_noacl=0, opt_bootstrap=0, opt_myisam_log=0;
my_bool
opt_safe_user_create
=
0
,
opt_no_mix_types
=
0
;
my_bool
opt_safe_show_db
=
0
,
lower_case_table_names
,
opt_old_rpl_compat
;
my_bool
opt_show_slave_auth_info
,
opt_sql_bin_update
=
0
;
my_bool
opt_log_slave_updates
=
0
;
my_bool
opt_log_slave_updates
=
0
,
opt_old_passwords
=
0
;
volatile
bool
mqh_used
=
0
;
FILE
*
bootstrap_file
=
0
;
...
...
@@ -317,6 +317,7 @@ uint volatile thread_count=0, thread_running=0, kill_cached_threads=0,
ulong
thd_startup_options
=
(
OPTION_UPDATE_LOG
|
OPTION_AUTO_IS_NULL
|
OPTION_BIN_LOG
|
OPTION_QUOTE_SHOW_CREATE
);
uint
protocol_version
=
PROTOCOL_VERSION
;
uint
connection_auth_flag
=
0
;
/* Supported authentication mode */
struct
system_variables
global_system_variables
;
struct
system_variables
max_system_variables
;
ulong
keybuff_size
,
table_cache_size
,
...
...
@@ -2894,7 +2895,8 @@ enum options {
OPT_INNODB_FORCE_RECOVERY
,
OPT_BDB_CACHE_SIZE
,
OPT_BDB_LOG_BUFFER_SIZE
,
OPT_BDB_MAX_LOCK
OPT_BDB_MAX_LOCK
,
OPT_OLD_PASSWORDS
};
...
...
@@ -3225,6 +3227,8 @@ struct my_option my_long_options[] =
GET_STR
,
REQUIRED_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"safe-mode"
,
OPT_SAFE
,
"Skip some optimize stages (for testing)."
,
0
,
0
,
0
,
GET_NO_ARG
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
{
"old-passwords"
,
OPT_OLD_PASSWORDS
,
"Use old password encryption method (needed for old clients)"
,
(
gptr
*
)
&
opt_old_passwords
,
(
gptr
*
)
&
opt_old_passwords
,
0
,
GET_BOOL
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
#ifndef TO_BE_DELETED
{
"safe-show-database"
,
OPT_SAFE_SHOW_DB
,
"Deprecated option; One should use GRANT SHOW DATABASES instead..."
,
...
...
sql/password.c
View file @
ae7e164f
...
...
@@ -37,9 +37,18 @@
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <sha1.h>
#include "mysql.h"
/* Character to use as version identifier for version 4.1 */
#define PVERSION41_CHAR '*'
void
randominit
(
struct
rand_struct
*
rand_st
,
ulong
seed1
,
ulong
seed2
)
{
/* For mysql 3.21.# */
#ifdef HAVE_purify
...
...
@@ -84,13 +93,68 @@ void hash_password(ulong *result, const char *password)
return
;
}
void
make_scrambled_password
(
char
*
to
,
const
char
*
password
)
void
make_scrambled_password
(
char
*
to
,
const
char
*
password
,
my_bool
force_old_scramble
)
{
ulong
hash_res
[
2
];
ulong
hash_res
[
2
];
/* Used for pre 4.1 password hashing */
static
uint
salt
=
0
;
/* Salt for 4.1 version password */
unsigned
char
*
slt
=
(
unsigned
char
*
)
&
salt
;
SHA1_CONTEXT
context
;
uint8
digest
[
SHA1_HASH_SIZE
];
if
(
force_old_scramble
)
/* Pre 4.1 password encryption */
{
hash_password
(
hash_res
,
password
);
sprintf
(
to
,
"%08lx%08lx"
,
hash_res
[
0
],
hash_res
[
1
]);
}
else
/* New password 4.1 password scrambling */
{
to
[
0
]
=
PVERSION41_CHAR
;
/* New passwords have version prefix */
/* We do not need too strong salt generation so this should be enough */
salt
+=
getpid
()
+
time
(
NULL
)
+
0x01010101
;
/* Use only 2 first bytes from it */
sprintf
(
&
(
to
[
1
]),
"%02x%02x"
,
slt
[
0
],
slt
[
1
]);
sha1_reset
(
&
context
);
/* Use Salt for Hash */
sha1_input
(
&
context
,(
uint8
*
)
&
salt
,
2
);
for
(;
*
password
;
password
++
)
{
if
(
*
password
==
' '
||
*
password
==
'\t'
)
continue
;
/* skip space in password */
sha1_input
(
&
context
,(
int8
*
)
&
password
[
0
],
1
);
}
sha1_result
(
&
context
,
digest
);
/* Hash one more time */
sha1_reset
(
&
context
);
sha1_input
(
&
context
,
digest
,
SHA1_HASH_SIZE
);
sha1_result
(
&
context
,
digest
);
/* Print resulting hash into the password*/
sprintf
(
&
(
to
[
5
]),
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
,
digest
[
0
],
digest
[
1
],
digest
[
2
],
digest
[
3
],
digest
[
4
],
digest
[
5
],
digest
[
6
],
digest
[
7
],
digest
[
8
],
digest
[
9
],
digest
[
10
],
digest
[
11
],
digest
[
12
],
digest
[
13
],
digest
[
14
],
digest
[
15
],
digest
[
16
],
digest
[
17
],
digest
[
18
],
digest
[
19
]);
}
}
uint
get_password_length
(
my_bool
force_old_scramble
)
{
if
(
force_old_scramble
)
return
16
;
else
return
SHA1_HASH_SIZE
*
2
+
4
+
1
;
}
uint8
get_password_version
(
const
char
*
password
)
{
if
(
password
==
NULL
)
return
0
;
if
(
password
[
0
]
==
PVERSION41_CHAR
)
return
PVERSION41_CHAR
;
return
0
;
}
inline
uint
char_val
(
char
X
)
{
return
(
uint
)
(
X
>=
'0'
&&
X
<=
'9'
?
X
-
'0'
:
...
...
@@ -99,15 +163,27 @@ inline uint char_val(char X)
}
/*
** This code assumes that len(password) is divideable with 8 and that
** res is big enough (2 in mysql)
** This code detects new version password by leading char.
** Old password has to be divisible by 8 length
** do not forget to increase array length if you need longer passwords
*/
void
get_salt_from_password
(
ulong
*
res
,
const
char
*
password
)
{
res
[
0
]
=
res
[
1
]
=
0
;
bzero
(
res
,
5
*
sizeof
(
res
[
0
]))
;
if
(
password
)
{
if
(
password
[
0
]
==
PVERSION41_CHAR
)
// if new password
{
uint
val
=
0
;
uint
i
;
password
++
;
// skip version identifier.
//get hashing salt from password and store in in the start of array
for
(
i
=
0
;
i
<
4
;
i
++
)
val
=
(
val
<<
4
)
+
char_val
(
*
password
++
);
*
res
++=
val
;
}
while
(
*
password
)
{
ulong
val
=
0
;
...
...
@@ -122,6 +198,7 @@ void get_salt_from_password(ulong *res,const char *password)
void
make_password_from_salt
(
char
*
to
,
ulong
*
hash_res
)
{
// warning this does not work for new passwords yet
sprintf
(
to
,
"%08lx%08lx"
,
hash_res
[
0
],
hash_res
[
1
]);
}
...
...
sql/sql_acl.cc
View file @
ae7e164f
...
...
@@ -32,6 +32,8 @@
#include <assert.h>
#include <stdarg.h>
extern
uint
connection_auth_flag
;
struct
acl_host_and_ip
{
char
*
hostname
;
...
...
@@ -63,7 +65,8 @@ class ACL_USER :public ACL_ACCESS
uint
hostname_length
;
USER_RESOURCES
user_resource
;
char
*
user
,
*
password
;
ulong
salt
[
2
];
ulong
salt
[
6
];
// New password has longer length
uint8
pversion
;
// password version
enum
SSL_type
ssl_type
;
const
char
*
ssl_cipher
,
*
x509_issuer
,
*
x509_subject
;
};
...
...
@@ -142,7 +145,11 @@ my_bool acl_init(bool dont_read_acl_tables)
(
hash_get_key
)
acl_entry_get_key
,
(
void
(
*
)(
void
*
))
free
);
if
(
dont_read_acl_tables
)
{
/* If we do not read tables use old handshake to make it quick for all clients */
connection_auth_flag
=
CLIENT_LONG_PASSWORD
;
DBUG_RETURN
(
0
);
/* purecov: tested */
}
/*
To be able to run this from boot, we allocate a temporary THD
...
...
@@ -217,6 +224,7 @@ my_bool acl_init(bool dont_read_acl_tables)
DBUG_PRINT
(
"info"
,(
"user table fields: %d"
,
table
->
fields
));
allow_all_hosts
=
0
;
connection_auth_flag
=
0
;
/* Reset flag as we're rereading the table */
while
(
!
(
read_record_info
.
read_record
(
&
read_record_info
)))
{
ACL_USER
user
;
...
...
@@ -231,7 +239,7 @@ my_bool acl_init(bool dont_read_acl_tables)
"Found old style password for user '%s'. Ignoring user. (You may want to restart mysqld using --old-protocol)"
,
user
.
user
?
user
.
user
:
""
);
/* purecov: tested */
}
else
if
(
length
%
8
)
// This holds true for passwords
else
if
(
length
%
8
&&
length
!=
45
)
// This holds true for passwords
{
sql_print_error
(
"Found invalid password for user: '%s@%s'; Ignoring user"
,
...
...
@@ -240,6 +248,19 @@ my_bool acl_init(bool dont_read_acl_tables)
continue
;
/* purecov: tested */
}
get_salt_from_password
(
user
.
salt
,
user
.
password
);
user
.
pversion
=
get_password_version
(
user
.
password
);
/*
We check the version of passwords in database. If no old passwords found we can force new handshake
if there are only old password we will force new handshake. In case of both types of passwords
found we will perform 2 stage authentication.
*/
if
(
user
.
password
&&
user
.
password
[
0
]
!=
0
)
/* empty passwords are not counted */
{
if
(
user
.
pversion
)
connection_auth_flag
|=
CLIENT_SECURE_CONNECTION
;
else
connection_auth_flag
|=
CLIENT_LONG_PASSWORD
;
}
user
.
access
=
get_access
(
table
,
3
)
&
GLOBAL_ACLS
;
user
.
sort
=
get_sort
(
2
,
user
.
host
.
hostname
,
user
.
user
);
user
.
hostname_length
=
(
user
.
host
.
hostname
?
...
...
@@ -298,6 +319,17 @@ my_bool acl_init(bool dont_read_acl_tables)
end_read_record
(
&
read_record_info
);
freeze_size
(
&
acl_users
);
/*
If database is empty or has no passwords use new connection protocol
unless we're running with --old-passwords option
*/
if
(
!
connection_auth_flag
)
{
if
(
!
opt_old_passwords
)
connection_auth_flag
=
CLIENT_SECURE_CONNECTION
;
else
connection_auth_flag
=
CLIENT_LONG_PASSWORD
;
}
printf
(
"Set flag after read: %d
\n
"
,
connection_auth_flag
);
init_read_record
(
&
read_record_info
,
thd
,
table
=
tables
[
2
].
table
,
NULL
,
1
,
0
);
VOID
(
my_init_dynamic_array
(
&
acl_dbs
,
sizeof
(
ACL_DB
),
50
,
100
));
while
(
!
(
read_record_info
.
read_record
(
&
read_record_info
)))
...
...
@@ -671,6 +703,13 @@ static void acl_update_user(const char *user, const char *host,
{
acl_user
->
password
=
(
char
*
)
""
;
// Just point at something
get_salt_from_password
(
acl_user
->
salt
,
password
);
acl_user
->
pversion
=
get_password_version
(
acl_user
->
password
);
// We should allow connection with authentication method matching password
if
(
acl_user
->
pversion
)
connection_auth_flag
|=
CLIENT_SECURE_CONNECTION
;
else
connection_auth_flag
|=
CLIENT_LONG_PASSWORD
;
printf
(
"Debug: flag set to %d
\n
"
,
connection_auth_flag
);
}
}
break
;
...
...
@@ -706,6 +745,7 @@ static void acl_insert_user(const char *user, const char *host,
{
acl_user
.
password
=
(
char
*
)
""
;
// Just point at something
get_salt_from_password
(
acl_user
.
salt
,
password
);
acl_user
.
pversion
=
get_password_version
(
acl_user
.
password
);
}
VOID
(
push_dynamic
(
&
acl_users
,(
gptr
)
&
acl_user
));
...
...
@@ -1052,8 +1092,10 @@ bool change_password(THD *thd, const char *host, const char *user,
if
(
check_change_password
(
thd
,
host
,
user
))
DBUG_RETURN
(
1
);
/* password should always be 0
or 16
chars; simple hack to avoid cracking */
/* password should always be 0
,16 or 45
chars; simple hack to avoid cracking */
length
=
(
uint
)
strlen
(
new_password
);
if
(
length
!=
45
)
new_password
[
length
&
16
]
=
0
;
VOID
(
pthread_mutex_lock
(
&
acl_cache
->
lock
));
...
...
@@ -1074,14 +1116,23 @@ bool change_password(THD *thd, const char *host, const char *user,
DBUG_RETURN
(
1
);
/* purecov: deadcode */
}
get_salt_from_password
(
acl_user
->
salt
,
new_password
);
acl_user
->
pversion
=
get_password_version
(
new_password
);
if
(
!
new_password
[
0
])
acl_user
->
password
=
0
;
else
{
acl_user
->
password
=
(
char
*
)
""
;
// Point at something
/* Adjust global connection options depending of client password*/
if
(
acl_user
->
pversion
)
connection_auth_flag
|=
CLIENT_SECURE_CONNECTION
;
else
connection_auth_flag
|=
CLIENT_LONG_PASSWORD
;
}
acl_cache
->
clear
(
1
);
// Clear locked hostname cache
VOID
(
pthread_mutex_unlock
(
&
acl_cache
->
lock
));
char
buff
[
460
];
char
buff
[
512
];
/* Extend with extended password length*/
ulong
query_length
=
my_sprintf
(
buff
,
(
buff
,
"SET PASSWORD FOR
\"
%-.120s
\"
@
\"
%-.120s
\"
=
\"
%-.120s
\"
"
,
...
...
sql/sql_yacc.yy
View file @
ae7e164f
...
...
@@ -3650,7 +3650,7 @@ text_or_password:
else
{
char *buff=(char*) sql_alloc(HASH_PASSWORD_LENGTH+1);
make_scrambled_password(buff,$3.str);
make_scrambled_password(buff,$3.str
,opt_old_passwords
);
$$=buff;
}
}
...
...
@@ -3941,7 +3941,7 @@ grant_user:
char *buff=(char*) sql_alloc(HASH_PASSWORD_LENGTH+1);
if (buff)
{
make_scrambled_password(buff,$4.str);
make_scrambled_password(buff,$4.str
,opt_old_passwords
);
$1->password.str=buff;
$1->password.length=HASH_PASSWORD_LENGTH;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment