mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
Do the partial merge of WL#5602 correctly:
Remove unused code (that should not have been merged) Add protocol extension (that should have been merged) Fix bugs (see pack.c)
This commit is contained in:
@@ -1,32 +0,0 @@
|
|||||||
/* defines and prototypes for using crypt_genhash_impl.cc */
|
|
||||||
|
|
||||||
#ifndef CRYPT_HASHGEN_IMPL_H
|
|
||||||
#define CRYPT_HASHGEN_IMPL_H
|
|
||||||
#define ROUNDS_DEFAULT 5000
|
|
||||||
#define ROUNDS_MIN 1000
|
|
||||||
#define ROUNDS_MAX 999999999
|
|
||||||
#define MIXCHARS 32
|
|
||||||
#define CRYPT_SALT_LENGTH 20
|
|
||||||
#define CRYPT_MAGIC_LENGTH 3
|
|
||||||
#define CRYPT_PARAM_LENGTH 13
|
|
||||||
#define SHA256_HASH_LENGTH 43
|
|
||||||
#define CRYPT_MAX_PASSWORD_SIZE (CRYPT_SALT_LENGTH + \
|
|
||||||
SHA256_HASH_LENGTH + \
|
|
||||||
CRYPT_MAGIC_LENGTH + \
|
|
||||||
CRYPT_PARAM_LENGTH)
|
|
||||||
|
|
||||||
int extract_user_salt(char **salt_begin,
|
|
||||||
char **salt_end);
|
|
||||||
C_MODE_START
|
|
||||||
char *
|
|
||||||
my_crypt_genhash(char *ctbuffer,
|
|
||||||
size_t ctbufflen,
|
|
||||||
const char *plaintext,
|
|
||||||
int plaintext_len,
|
|
||||||
const char *switchsalt,
|
|
||||||
const char **params);
|
|
||||||
void generate_user_salt(char *buffer, int buffer_len);
|
|
||||||
void xor_string(char *to, int to_len, char *pattern, int pattern_len);
|
|
||||||
|
|
||||||
C_MODE_END
|
|
||||||
#endif
|
|
@@ -1,13 +0,0 @@
|
|||||||
#ifndef CLIENT_AUTHENTICATION_H
|
|
||||||
#define CLIENT_AUTHENTICATION_H
|
|
||||||
#include "mysql.h"
|
|
||||||
#include "mysql/client_plugin.h"
|
|
||||||
|
|
||||||
C_MODE_START
|
|
||||||
int sha256_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
|
|
||||||
int sha256_password_init(char *, size_t, int, va_list);
|
|
||||||
int sha256_password_deinit(void);
|
|
||||||
C_MODE_END
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@@ -265,11 +265,11 @@ enum enum_server_command
|
|||||||
CLIENT_REMEMBER_OPTIONS | \
|
CLIENT_REMEMBER_OPTIONS | \
|
||||||
CLIENT_PROGRESS | \
|
CLIENT_PROGRESS | \
|
||||||
CLIENT_PLUGIN_AUTH | \
|
CLIENT_PLUGIN_AUTH | \
|
||||||
|
CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | \
|
||||||
CLIENT_CONNECT_ATTRS)
|
CLIENT_CONNECT_ATTRS)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
To be added later:
|
To be added later:
|
||||||
CLIENT_CONNECT_ATTRS, CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA,
|
|
||||||
CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS
|
CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -641,7 +641,9 @@ void my_thread_end(void);
|
|||||||
#ifdef MY_GLOBAL_INCLUDED
|
#ifdef MY_GLOBAL_INCLUDED
|
||||||
ulong STDCALL net_field_length(uchar **packet);
|
ulong STDCALL net_field_length(uchar **packet);
|
||||||
my_ulonglong net_field_length_ll(uchar **packet);
|
my_ulonglong net_field_length_ll(uchar **packet);
|
||||||
|
my_ulonglong safe_net_field_length_ll(uchar **packet, size_t packet_len);
|
||||||
uchar *net_store_length(uchar *pkg, ulonglong length);
|
uchar *net_store_length(uchar *pkg, ulonglong length);
|
||||||
|
uchar *safe_net_store_length(uchar *pkg, size_t pkg_len, ulonglong length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -24,8 +24,6 @@ void my_make_scrambled_password_323(char *to, const char *password,
|
|||||||
size_t pass_len);
|
size_t pass_len);
|
||||||
void my_make_scrambled_password(char *to, const char *password,
|
void my_make_scrambled_password(char *to, const char *password,
|
||||||
size_t pass_len);
|
size_t pass_len);
|
||||||
void my_make_scrambled_password_sha1(char *to, const char *password,
|
|
||||||
size_t pass_len);
|
|
||||||
|
|
||||||
void hash_password(ulong *result, const char *password, uint password_len);
|
void hash_password(ulong *result, const char *password, uint password_len);
|
||||||
|
|
||||||
|
@@ -35,7 +35,6 @@ struct st_mysql_options_extention {
|
|||||||
char *default_auth;
|
char *default_auth;
|
||||||
char *ssl_crl; /* PEM CRL file */
|
char *ssl_crl; /* PEM CRL file */
|
||||||
char *ssl_crlpath; /* PEM directory of CRL-s? */
|
char *ssl_crlpath; /* PEM directory of CRL-s? */
|
||||||
char *server_public_key_path;
|
|
||||||
void (*report_progress)(const MYSQL *mysql,
|
void (*report_progress)(const MYSQL *mysql,
|
||||||
unsigned int stage,
|
unsigned int stage,
|
||||||
unsigned int max_stage,
|
unsigned int max_stage,
|
||||||
|
@@ -337,7 +337,6 @@ SET(CLIENT_SOURCES
|
|||||||
../sql-common/mysql_async.c
|
../sql-common/mysql_async.c
|
||||||
../sql-common/my_time.c
|
../sql-common/my_time.c
|
||||||
../sql-common/client_plugin.c
|
../sql-common/client_plugin.c
|
||||||
../sql-common/client_authentication.cc
|
|
||||||
../sql/net_serv.cc
|
../sql/net_serv.cc
|
||||||
../sql-common/pack.c
|
../sql-common/pack.c
|
||||||
../sql/password.c
|
../sql/password.c
|
||||||
|
@@ -35,6 +35,7 @@ extern char * mysql_unix_port;
|
|||||||
CLIENT_MULTI_RESULTS | \
|
CLIENT_MULTI_RESULTS | \
|
||||||
CLIENT_PS_MULTI_RESULTS | \
|
CLIENT_PS_MULTI_RESULTS | \
|
||||||
CLIENT_PLUGIN_AUTH | \
|
CLIENT_PLUGIN_AUTH | \
|
||||||
|
CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | \
|
||||||
CLIENT_CONNECT_ATTRS)
|
CLIENT_CONNECT_ATTRS)
|
||||||
|
|
||||||
sig_handler my_pipe_sig_handler(int sig);
|
sig_handler my_pipe_sig_handler(int sig);
|
||||||
|
@@ -26,7 +26,6 @@ ENDIF()
|
|||||||
# must be compiled with "-fvisibility=hidden"
|
# must be compiled with "-fvisibility=hidden"
|
||||||
IF(WITH_SSL STREQUAL "bundled" AND HAVE_VISIBILITY_HIDDEN)
|
IF(WITH_SSL STREQUAL "bundled" AND HAVE_VISIBILITY_HIDDEN)
|
||||||
SET_SOURCE_FILES_PROPERTIES(
|
SET_SOURCE_FILES_PROPERTIES(
|
||||||
crypt_genhash_impl.cc
|
|
||||||
my_aes.cc
|
my_aes.cc
|
||||||
my_md5.cc
|
my_md5.cc
|
||||||
my_sha1.cc
|
my_sha1.cc
|
||||||
@@ -35,7 +34,6 @@ IF(WITH_SSL STREQUAL "bundled" AND HAVE_VISIBILITY_HIDDEN)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
SET(MYSYS_SSL_SOURCES
|
SET(MYSYS_SSL_SOURCES
|
||||||
crypt_genhash_impl.cc
|
|
||||||
my_aes.cc
|
my_aes.cc
|
||||||
my_sha1.cc
|
my_sha1.cc
|
||||||
my_sha2.cc
|
my_sha2.cc
|
||||||
|
@@ -1,454 +0,0 @@
|
|||||||
/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
|
|
||||||
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; version 2 of the License.
|
|
||||||
|
|
||||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA */
|
|
||||||
|
|
||||||
/* We always should include my_global first */
|
|
||||||
|
|
||||||
#include <my_global.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL
|
|
||||||
|
|
||||||
#ifdef HAVE_YASSL
|
|
||||||
#include <sha.hpp>
|
|
||||||
#include <openssl/ssl.h>
|
|
||||||
#else
|
|
||||||
#include <openssl/sha.h>
|
|
||||||
#include <openssl/rand.h>
|
|
||||||
#endif
|
|
||||||
#include "crypt_genhash_impl.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifndef HAVE_YASSL
|
|
||||||
#define DIGEST_CTX SHA256_CTX
|
|
||||||
#define DIGESTInit SHA256_Init
|
|
||||||
#define DIGESTUpdate SHA256_Update
|
|
||||||
#define DIGESTFinal SHA256_Final
|
|
||||||
#define DIGEST_LEN SHA256_DIGEST_LENGTH
|
|
||||||
#else
|
|
||||||
#define DIGEST_CTX TaoCrypt::SHA256
|
|
||||||
#define DIGEST_LEN 32
|
|
||||||
void DIGESTInit(DIGEST_CTX *ctx)
|
|
||||||
{
|
|
||||||
ctx->Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DIGESTUpdate(DIGEST_CTX *ctx, const void *plaintext, int len)
|
|
||||||
{
|
|
||||||
ctx->Update((const TaoCrypt::byte *)plaintext, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DIGESTFinal(void *txt, DIGEST_CTX *ctx)
|
|
||||||
{
|
|
||||||
ctx->Final((TaoCrypt::byte *)txt);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAVE_YASSL
|
|
||||||
|
|
||||||
static const char crypt_alg_magic[] = "$5";
|
|
||||||
|
|
||||||
#ifndef MAX
|
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Size-bounded string copying and concatenation
|
|
||||||
This is a replacement for STRLCPY(3)
|
|
||||||
*/
|
|
||||||
|
|
||||||
size_t
|
|
||||||
strlcat(char *dst, const char *src, size_t siz)
|
|
||||||
{
|
|
||||||
char *d= dst;
|
|
||||||
const char *s= src;
|
|
||||||
size_t n= siz;
|
|
||||||
size_t dlen;
|
|
||||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
|
||||||
while (n-- != 0 && *d != '\0')
|
|
||||||
d++;
|
|
||||||
dlen= d - dst;
|
|
||||||
n= siz - dlen;
|
|
||||||
if (n == 0)
|
|
||||||
return(dlen + siz);
|
|
||||||
while (*s != '\0')
|
|
||||||
{
|
|
||||||
if (n != 1)
|
|
||||||
{
|
|
||||||
*d++= *s;
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
*d= '\0';
|
|
||||||
return(dlen + (s - src)); /* count does not include NUL */
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int crypt_alg_magic_len = sizeof (crypt_alg_magic) - 1;
|
|
||||||
|
|
||||||
static unsigned char b64t[] = /* 0 ... 63 => ascii - 64 */
|
|
||||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
||||||
|
|
||||||
#define b64_from_24bit(B2, B1, B0, N) \
|
|
||||||
{ \
|
|
||||||
uint32 w = ((B2) << 16) | ((B1) << 8) | (B0); \
|
|
||||||
int n = (N); \
|
|
||||||
while (--n >= 0 && ctbufflen > 0) { \
|
|
||||||
*p++ = b64t[w & 0x3f]; \
|
|
||||||
w >>= 6; \
|
|
||||||
ctbufflen--; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ROUNDS "rounds="
|
|
||||||
#define ROUNDSLEN (sizeof (ROUNDS) - 1)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the integer value after rounds= where ever it occurs in the string.
|
|
||||||
if the last char after the int is a , or $ that is fine anything else is an
|
|
||||||
error.
|
|
||||||
*/
|
|
||||||
static uint32 getrounds(const char *s)
|
|
||||||
{
|
|
||||||
const char *r;
|
|
||||||
const char *p;
|
|
||||||
char *e;
|
|
||||||
long val;
|
|
||||||
|
|
||||||
if (s == NULL)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
if ((r = strstr(s, ROUNDS)) == NULL)
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(r, ROUNDS, ROUNDSLEN) != 0)
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
p= r + ROUNDSLEN;
|
|
||||||
errno= 0;
|
|
||||||
val= strtol(p, &e, 10);
|
|
||||||
/*
|
|
||||||
An error occurred or there is non-numeric stuff at the end
|
|
||||||
which isn't one of the crypt(3c) special chars ',' or '$'
|
|
||||||
*/
|
|
||||||
if (errno != 0 || val < 0 || !(*e == '\0' || *e == ',' || *e == '$'))
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ((uint32) val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Finds the interval which envelopes the user salt in a crypt password
|
|
||||||
The crypt format is assumed to be $a$bbbb$cccccc\0 and the salt is found
|
|
||||||
by counting the delimiters and marking begin and end.
|
|
||||||
|
|
||||||
@param salt_being[in] Pointer to start of crypt passwd
|
|
||||||
@param salt_being[out] Pointer to first byte of the salt
|
|
||||||
@param salt_end[in] Pointer to the last byte in passwd
|
|
||||||
@param salt_end[out] Pointer to the byte immediatly following the salt ($)
|
|
||||||
|
|
||||||
@return The size of the salt identified
|
|
||||||
*/
|
|
||||||
|
|
||||||
int extract_user_salt(char **salt_begin,
|
|
||||||
char **salt_end)
|
|
||||||
{
|
|
||||||
char *it= *salt_begin;
|
|
||||||
int delimiter_count= 0;
|
|
||||||
while(it != *salt_end)
|
|
||||||
{
|
|
||||||
if (*it == '$')
|
|
||||||
{
|
|
||||||
++delimiter_count;
|
|
||||||
if (delimiter_count == 2)
|
|
||||||
{
|
|
||||||
*salt_begin= it + 1;
|
|
||||||
}
|
|
||||||
if (delimiter_count == 3)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
*salt_end= it;
|
|
||||||
return *salt_end - *salt_begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *sha256_find_digest(char *pass)
|
|
||||||
{
|
|
||||||
int sz= strlen(pass);
|
|
||||||
return pass + sz - SHA256_HASH_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Portions of the below code come from crypt_bsdmd5.so (bsdmd5.c) :
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
||||||
* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
|
|
||||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
|
||||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* $FreeBSD: crypt.c,v 1.5 1996/10/14 08:34:02 phk Exp $
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The below code implements the specification from:
|
|
||||||
*
|
|
||||||
* From http://people.redhat.com/drepper/SHA-crypt.txt
|
|
||||||
*
|
|
||||||
* Portions of the code taken from inspired by or verified against the
|
|
||||||
* source in the above document which is licensed as:
|
|
||||||
*
|
|
||||||
* "Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>."
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Due to a Solaris namespace bug DS is a reserved word. To work around this
|
|
||||||
DS is undefined.
|
|
||||||
*/
|
|
||||||
#undef DS
|
|
||||||
|
|
||||||
/* ARGSUSED4 */
|
|
||||||
extern "C"
|
|
||||||
char *
|
|
||||||
my_crypt_genhash(char *ctbuffer,
|
|
||||||
size_t ctbufflen,
|
|
||||||
const char *plaintext,
|
|
||||||
int plaintext_len,
|
|
||||||
const char *switchsalt,
|
|
||||||
const char **params)
|
|
||||||
{
|
|
||||||
int salt_len, i;
|
|
||||||
char *salt;
|
|
||||||
unsigned char A[DIGEST_LEN];
|
|
||||||
unsigned char B[DIGEST_LEN];
|
|
||||||
unsigned char DP[DIGEST_LEN];
|
|
||||||
unsigned char DS[DIGEST_LEN];
|
|
||||||
DIGEST_CTX ctxA, ctxB, ctxC, ctxDP, ctxDS;
|
|
||||||
int rounds = ROUNDS_DEFAULT;
|
|
||||||
int srounds = 0;
|
|
||||||
bool custom_rounds= false;
|
|
||||||
char *p;
|
|
||||||
char *P, *Pp;
|
|
||||||
char *S, *Sp;
|
|
||||||
|
|
||||||
/* Refine the salt */
|
|
||||||
salt = (char *)switchsalt;
|
|
||||||
|
|
||||||
/* skip our magic string */
|
|
||||||
if (strncmp((char *)salt, crypt_alg_magic, crypt_alg_magic_len) == 0)
|
|
||||||
{
|
|
||||||
salt += crypt_alg_magic_len + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
srounds = getrounds(salt);
|
|
||||||
if (srounds != 0) {
|
|
||||||
rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
|
|
||||||
custom_rounds= true;
|
|
||||||
p = strchr(salt, '$');
|
|
||||||
if (p != NULL)
|
|
||||||
salt = p + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
salt_len = MIN(strcspn(salt, "$"), CRYPT_SALT_LENGTH);
|
|
||||||
//plaintext_len = strlen(plaintext);
|
|
||||||
|
|
||||||
/* 1. */
|
|
||||||
DIGESTInit(&ctxA);
|
|
||||||
|
|
||||||
/* 2. The password first, since that is what is most unknown */
|
|
||||||
DIGESTUpdate(&ctxA, plaintext, plaintext_len);
|
|
||||||
|
|
||||||
/* 3. Then the raw salt */
|
|
||||||
DIGESTUpdate(&ctxA, salt, salt_len);
|
|
||||||
|
|
||||||
/* 4. - 8. */
|
|
||||||
DIGESTInit(&ctxB);
|
|
||||||
DIGESTUpdate(&ctxB, plaintext, plaintext_len);
|
|
||||||
DIGESTUpdate(&ctxB, salt, salt_len);
|
|
||||||
DIGESTUpdate(&ctxB, plaintext, plaintext_len);
|
|
||||||
DIGESTFinal(B, &ctxB);
|
|
||||||
|
|
||||||
/* 9. - 10. */
|
|
||||||
for (i= plaintext_len; i > MIXCHARS; i -= MIXCHARS)
|
|
||||||
DIGESTUpdate(&ctxA, B, MIXCHARS);
|
|
||||||
DIGESTUpdate(&ctxA, B, i);
|
|
||||||
|
|
||||||
/* 11. */
|
|
||||||
for (i= plaintext_len; i > 0; i >>= 1) {
|
|
||||||
if ((i & 1) != 0)
|
|
||||||
{
|
|
||||||
DIGESTUpdate(&ctxA, B, MIXCHARS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DIGESTUpdate(&ctxA, plaintext, plaintext_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 12. */
|
|
||||||
DIGESTFinal(A, &ctxA);
|
|
||||||
|
|
||||||
/* 13. - 15. */
|
|
||||||
DIGESTInit(&ctxDP);
|
|
||||||
for (i= 0; i < plaintext_len; i++)
|
|
||||||
DIGESTUpdate(&ctxDP, plaintext, plaintext_len);
|
|
||||||
DIGESTFinal(DP, &ctxDP);
|
|
||||||
|
|
||||||
/* 16. */
|
|
||||||
Pp= P= (char *)alloca(plaintext_len);
|
|
||||||
for (i= plaintext_len; i >= MIXCHARS; i -= MIXCHARS)
|
|
||||||
{
|
|
||||||
Pp= (char *)(memcpy(Pp, DP, MIXCHARS)) + MIXCHARS;
|
|
||||||
}
|
|
||||||
(void) memcpy(Pp, DP, i);
|
|
||||||
|
|
||||||
/* 17. - 19. */
|
|
||||||
DIGESTInit(&ctxDS);
|
|
||||||
for (i= 0; i < 16 + (uint8)A[0]; i++)
|
|
||||||
DIGESTUpdate(&ctxDS, salt, salt_len);
|
|
||||||
DIGESTFinal(DS, &ctxDS);
|
|
||||||
|
|
||||||
/* 20. */
|
|
||||||
Sp= S= (char *)alloca(salt_len);
|
|
||||||
for (i= salt_len; i >= MIXCHARS; i -= MIXCHARS)
|
|
||||||
{
|
|
||||||
Sp= (char *)(memcpy(Sp, DS, MIXCHARS)) + MIXCHARS;
|
|
||||||
}
|
|
||||||
(void) memcpy(Sp, DS, i);
|
|
||||||
|
|
||||||
/* 21. */
|
|
||||||
for (i= 0; i < rounds; i++)
|
|
||||||
{
|
|
||||||
DIGESTInit(&ctxC);
|
|
||||||
|
|
||||||
if ((i & 1) != 0)
|
|
||||||
{
|
|
||||||
DIGESTUpdate(&ctxC, P, plaintext_len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i == 0)
|
|
||||||
DIGESTUpdate(&ctxC, A, MIXCHARS);
|
|
||||||
else
|
|
||||||
DIGESTUpdate(&ctxC, DP, MIXCHARS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i % 3 != 0) {
|
|
||||||
DIGESTUpdate(&ctxC, S, salt_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i % 7 != 0) {
|
|
||||||
DIGESTUpdate(&ctxC, P, plaintext_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((i & 1) != 0)
|
|
||||||
{
|
|
||||||
if (i == 0)
|
|
||||||
DIGESTUpdate(&ctxC, A, MIXCHARS);
|
|
||||||
else
|
|
||||||
DIGESTUpdate(&ctxC, DP, MIXCHARS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DIGESTUpdate(&ctxC, P, plaintext_len);
|
|
||||||
}
|
|
||||||
DIGESTFinal(DP, &ctxC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 22. Now make the output string */
|
|
||||||
if (custom_rounds)
|
|
||||||
{
|
|
||||||
(void) snprintf(ctbuffer, ctbufflen,
|
|
||||||
"%s$rounds=%zu$", crypt_alg_magic, (size_t)rounds);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(void) snprintf(ctbuffer, ctbufflen,
|
|
||||||
"%s$", crypt_alg_magic);
|
|
||||||
}
|
|
||||||
(void) strncat(ctbuffer, (const char *)salt, salt_len);
|
|
||||||
(void) strlcat(ctbuffer, "$", ctbufflen);
|
|
||||||
|
|
||||||
p= ctbuffer + strlen(ctbuffer);
|
|
||||||
ctbufflen -= strlen(ctbuffer);
|
|
||||||
|
|
||||||
b64_from_24bit(DP[ 0], DP[10], DP[20], 4);
|
|
||||||
b64_from_24bit(DP[21], DP[ 1], DP[11], 4);
|
|
||||||
b64_from_24bit(DP[12], DP[22], DP[ 2], 4);
|
|
||||||
b64_from_24bit(DP[ 3], DP[13], DP[23], 4);
|
|
||||||
b64_from_24bit(DP[24], DP[ 4], DP[14], 4);
|
|
||||||
b64_from_24bit(DP[15], DP[25], DP[ 5], 4);
|
|
||||||
b64_from_24bit(DP[ 6], DP[16], DP[26], 4);
|
|
||||||
b64_from_24bit(DP[27], DP[ 7], DP[17], 4);
|
|
||||||
b64_from_24bit(DP[18], DP[28], DP[ 8], 4);
|
|
||||||
b64_from_24bit(DP[ 9], DP[19], DP[29], 4);
|
|
||||||
b64_from_24bit(0, DP[31], DP[30], 3);
|
|
||||||
*p= '\0';
|
|
||||||
|
|
||||||
(void) memset(A, 0, sizeof (A));
|
|
||||||
(void) memset(B, 0, sizeof (B));
|
|
||||||
(void) memset(DP, 0, sizeof (DP));
|
|
||||||
(void) memset(DS, 0, sizeof (DS));
|
|
||||||
|
|
||||||
return (ctbuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Generate a random string using ASCII characters but avoid seperator character.
|
|
||||||
Stdlib rand and srand are used to produce pseudo random numbers between
|
|
||||||
with about 7 bit worth of entropty between 1-127.
|
|
||||||
*/
|
|
||||||
extern "C"
|
|
||||||
void generate_user_salt(char *buffer, int buffer_len)
|
|
||||||
{
|
|
||||||
char *end= buffer + buffer_len - 1;
|
|
||||||
#ifdef HAVE_YASSL
|
|
||||||
yaSSL::RAND_bytes((unsigned char *) buffer, buffer_len);
|
|
||||||
#else
|
|
||||||
RAND_bytes((unsigned char *) buffer, buffer_len);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Sequence must be a legal UTF8 string */
|
|
||||||
for (; buffer < end; buffer++)
|
|
||||||
{
|
|
||||||
*buffer &= 0x7f;
|
|
||||||
if (*buffer == '\0' || *buffer == '$')
|
|
||||||
*buffer= *buffer + 1;
|
|
||||||
}
|
|
||||||
/* Make sure the buffer is terminated properly */
|
|
||||||
*end= '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void xor_string(char *to, int to_len, char *pattern, int pattern_len)
|
|
||||||
{
|
|
||||||
int loop= 0;
|
|
||||||
while(loop <= to_len)
|
|
||||||
{
|
|
||||||
*(to + loop) ^= *(pattern + loop % pattern_len);
|
|
||||||
++loop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAVE_OPENSSL
|
|
@@ -2477,6 +2477,29 @@ typedef struct {
|
|||||||
int last_read_packet_len; /**< the length of the last *read* packet */
|
int last_read_packet_len; /**< the length of the last *read* packet */
|
||||||
} MCPVIO_EXT;
|
} MCPVIO_EXT;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Write 1-8 bytes of string length header infromation to dest depending on
|
||||||
|
value of src_len, then copy src_len bytes from src to dest.
|
||||||
|
|
||||||
|
@param dest Destination buffer of size src_len+8
|
||||||
|
@param dest_end One byte past the end of the dest buffer
|
||||||
|
@param src Source buff of size src_len
|
||||||
|
@param src_end One byte past the end of the src buffer
|
||||||
|
|
||||||
|
@return pointer dest+src_len+header size or NULL if
|
||||||
|
*/
|
||||||
|
|
||||||
|
static uchar *write_length_encoded_string4(uchar *dst, size_t dst_len,
|
||||||
|
const uchar *src, size_t src_len)
|
||||||
|
{
|
||||||
|
uchar *to= safe_net_store_length(dst, dst_len, src_len);
|
||||||
|
if (to == NULL)
|
||||||
|
return NULL;
|
||||||
|
memcpy(to, src, src_len);
|
||||||
|
return to + src_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
sends a COM_CHANGE_USER command with a caller provided payload
|
sends a COM_CHANGE_USER command with a caller provided payload
|
||||||
|
|
||||||
@@ -2578,7 +2601,7 @@ error:
|
|||||||
1 charset number
|
1 charset number
|
||||||
23 reserved (always 0)
|
23 reserved (always 0)
|
||||||
n user name, \0-terminated
|
n user name, \0-terminated
|
||||||
n plugin auth data (e.g. scramble), length (1 byte) coded
|
n plugin auth data (e.g. scramble), length encoded
|
||||||
n database name, \0-terminated
|
n database name, \0-terminated
|
||||||
(if CLIENT_CONNECT_WITH_DB is set in the capabilities)
|
(if CLIENT_CONNECT_WITH_DB is set in the capabilities)
|
||||||
n client auth plugin name - \0-terminated string,
|
n client auth plugin name - \0-terminated string,
|
||||||
@@ -2736,9 +2759,19 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
|
|||||||
{
|
{
|
||||||
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
if (mysql->server_capabilities & CLIENT_SECURE_CONNECTION)
|
||||||
{
|
{
|
||||||
*end++= data_len;
|
if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA)
|
||||||
memcpy(end, data, data_len);
|
end= (char*)write_length_encoded_string4((uchar*)end,
|
||||||
end+= data_len;
|
buff_size, data, data_len);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (data_len > 255)
|
||||||
|
goto error;
|
||||||
|
*end++= data_len;
|
||||||
|
memcpy(end, data, data_len);
|
||||||
|
end+= data_len;
|
||||||
|
}
|
||||||
|
if (end == NULL)
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -1,253 +0,0 @@
|
|||||||
/* Copyright (c) 2012, Oracle and/or its affiliates.
|
|
||||||
Copyright (c) 2013, Monty Program 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; version 2 of the License.
|
|
||||||
|
|
||||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA */
|
|
||||||
|
|
||||||
#include <my_global.h>
|
|
||||||
|
|
||||||
#if defined(HAVE_OPENSSL)
|
|
||||||
#include "crypt_genhash_impl.h"
|
|
||||||
#include "mysql/client_authentication.h"
|
|
||||||
#include "m_ctype.h"
|
|
||||||
#include "sql_common.h"
|
|
||||||
#include "errmsg.h"
|
|
||||||
#include "m_string.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if !defined(HAVE_YASSL)
|
|
||||||
#include <openssl/rsa.h>
|
|
||||||
#include <openssl/pem.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#if defined(_WIN32) && !defined(_OPENSSL_Applink) && defined(HAVE_OPENSSL_APPLINK_C)
|
|
||||||
#include <openssl/applink.c>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#include "mysql/service_my_plugin_log.h"
|
|
||||||
|
|
||||||
#define MAX_CIPHER_LENGTH 1024
|
|
||||||
|
|
||||||
#if !defined(HAVE_YASSL)
|
|
||||||
mysql_mutex_t g_public_key_mutex;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int sha256_password_init(char *a, size_t b, int c, va_list d)
|
|
||||||
{
|
|
||||||
#if !defined(HAVE_YASSL)
|
|
||||||
mysql_mutex_init(0,&g_public_key_mutex, MY_MUTEX_INIT_SLOW);
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sha256_password_deinit(void)
|
|
||||||
{
|
|
||||||
#if !defined(HAVE_YASSL)
|
|
||||||
mysql_mutex_destroy(&g_public_key_mutex);
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(HAVE_YASSL)
|
|
||||||
/**
|
|
||||||
Reads and parse RSA public key data from a file.
|
|
||||||
|
|
||||||
@param mysql connection handle with file path data
|
|
||||||
|
|
||||||
@return Pointer to the RSA public key storage buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
RSA *rsa_init(MYSQL *mysql)
|
|
||||||
{
|
|
||||||
static RSA *g_public_key= NULL;
|
|
||||||
RSA *key= NULL;
|
|
||||||
|
|
||||||
mysql_mutex_lock(&g_public_key_mutex);
|
|
||||||
key= g_public_key;
|
|
||||||
mysql_mutex_unlock(&g_public_key_mutex);
|
|
||||||
|
|
||||||
if (key != NULL)
|
|
||||||
return key;
|
|
||||||
|
|
||||||
FILE *pub_key_file= NULL;
|
|
||||||
|
|
||||||
if (mysql->options.extension != NULL &&
|
|
||||||
mysql->options.extension->server_public_key_path != NULL &&
|
|
||||||
mysql->options.extension->server_public_key_path != '\0')
|
|
||||||
{
|
|
||||||
pub_key_file= fopen(mysql->options.extension->server_public_key_path,
|
|
||||||
"r");
|
|
||||||
}
|
|
||||||
/* No public key is used; return 0 without errors to indicate this. */
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (pub_key_file == NULL)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
If a key path was submitted but no key located then we print an error
|
|
||||||
message. Else we just report that there is no public key.
|
|
||||||
*/
|
|
||||||
fprintf(stderr,"Can't locate server public key '%s'\n",
|
|
||||||
mysql->options.extension->server_public_key_path);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mysql_mutex_lock(&g_public_key_mutex);
|
|
||||||
key= g_public_key= PEM_read_RSA_PUBKEY(pub_key_file, 0, 0, 0);
|
|
||||||
mysql_mutex_unlock(&g_public_key_mutex);
|
|
||||||
fclose(pub_key_file);
|
|
||||||
if (g_public_key == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Public key is not in PEM format: '%s'\n",
|
|
||||||
mysql->options.extension->server_public_key_path);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
#endif // !defined(HAVE_YASSL)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Authenticate the client using the RSA or TLS and a SHA256 salted password.
|
|
||||||
|
|
||||||
@param vio Provides plugin access to communication channel
|
|
||||||
@param mysql Client connection handler
|
|
||||||
|
|
||||||
@return Error status
|
|
||||||
@retval CR_ERROR An error occurred.
|
|
||||||
@retval CR_OK Authentication succeeded.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
int sha256_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
|
|
||||||
{
|
|
||||||
bool uses_password= mysql->passwd[0] != 0;
|
|
||||||
#if !defined(HAVE_YASSL)
|
|
||||||
unsigned char encrypted_password[MAX_CIPHER_LENGTH];
|
|
||||||
static char request_public_key= '\1';
|
|
||||||
RSA *public_key= NULL;
|
|
||||||
bool got_public_key_from_server= false;
|
|
||||||
#endif
|
|
||||||
bool connection_is_secure= false;
|
|
||||||
unsigned char scramble_pkt[20];
|
|
||||||
unsigned char *pkt;
|
|
||||||
|
|
||||||
|
|
||||||
DBUG_ENTER("sha256_password_auth_client");
|
|
||||||
|
|
||||||
/*
|
|
||||||
Get the scramble from the server because we need it when sending encrypted
|
|
||||||
password.
|
|
||||||
*/
|
|
||||||
if (vio->read_packet(vio, &pkt) != SCRAMBLE_LENGTH)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("info",("Scramble is not of correct length."));
|
|
||||||
DBUG_RETURN(CR_ERROR);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Copy the scramble to the stack or it will be lost on the next use of the
|
|
||||||
net buffer.
|
|
||||||
*/
|
|
||||||
memcpy(scramble_pkt, pkt, SCRAMBLE_LENGTH);
|
|
||||||
|
|
||||||
if (mysql_get_ssl_cipher(mysql) != NULL)
|
|
||||||
connection_is_secure= true;
|
|
||||||
|
|
||||||
/* If connection isn't secure attempt to get the RSA public key file */
|
|
||||||
if (!connection_is_secure)
|
|
||||||
{
|
|
||||||
#if !defined(HAVE_YASSL)
|
|
||||||
public_key= rsa_init(mysql);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!uses_password)
|
|
||||||
{
|
|
||||||
/* We're not using a password */
|
|
||||||
static const unsigned char zero_byte= '\0';
|
|
||||||
if (vio->write_packet(vio, (const unsigned char *) &zero_byte, 1))
|
|
||||||
DBUG_RETURN(CR_ERROR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Password is a 0-terminated byte array ('\0' character included) */
|
|
||||||
unsigned int passwd_len= strlen(mysql->passwd) + 1;
|
|
||||||
if (!connection_is_secure)
|
|
||||||
{
|
|
||||||
#if !defined(HAVE_YASSL)
|
|
||||||
/*
|
|
||||||
If no public key; request one from the server.
|
|
||||||
*/
|
|
||||||
if (public_key == NULL)
|
|
||||||
{
|
|
||||||
if (vio->write_packet(vio, (const unsigned char *) &request_public_key,
|
|
||||||
1))
|
|
||||||
DBUG_RETURN(CR_ERROR);
|
|
||||||
|
|
||||||
int pkt_len= 0;
|
|
||||||
unsigned char *pkt;
|
|
||||||
if ((pkt_len= vio->read_packet(vio, &pkt)) == -1)
|
|
||||||
DBUG_RETURN(CR_ERROR);
|
|
||||||
BIO* bio= BIO_new_mem_buf(pkt, pkt_len);
|
|
||||||
public_key= PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
|
|
||||||
BIO_free(bio);
|
|
||||||
if (public_key == 0)
|
|
||||||
DBUG_RETURN(CR_ERROR);
|
|
||||||
got_public_key_from_server= true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Obfuscate the plain text password with the session scramble */
|
|
||||||
xor_string(mysql->passwd, strlen(mysql->passwd), (char *) scramble_pkt,
|
|
||||||
SCRAMBLE_LENGTH);
|
|
||||||
/* Encrypt the password and send it to the server */
|
|
||||||
int cipher_length= RSA_size(public_key);
|
|
||||||
/*
|
|
||||||
When using RSA_PKCS1_OAEP_PADDING the password length must be less
|
|
||||||
than RSA_size(rsa) - 41.
|
|
||||||
*/
|
|
||||||
if (passwd_len + 41 >= (unsigned) cipher_length)
|
|
||||||
{
|
|
||||||
/* password message is to long */
|
|
||||||
DBUG_RETURN(CR_ERROR);
|
|
||||||
}
|
|
||||||
RSA_public_encrypt(passwd_len, (unsigned char *) mysql->passwd,
|
|
||||||
encrypted_password,
|
|
||||||
public_key, RSA_PKCS1_OAEP_PADDING);
|
|
||||||
if (got_public_key_from_server)
|
|
||||||
RSA_free(public_key);
|
|
||||||
|
|
||||||
if (vio->write_packet(vio, (uchar*) encrypted_password, cipher_length))
|
|
||||||
DBUG_RETURN(CR_ERROR);
|
|
||||||
#else
|
|
||||||
set_mysql_extended_error(mysql, CR_AUTH_PLUGIN_ERR, unknown_sqlstate,
|
|
||||||
ER(CR_AUTH_PLUGIN_ERR), "sha256_password",
|
|
||||||
"Authentication requires SSL encryption");
|
|
||||||
DBUG_RETURN(CR_ERROR); // If no openssl support
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The vio is encrypted already; just send the plain text passwd */
|
|
||||||
if (vio->write_packet(vio, (uchar*) mysql->passwd, passwd_len))
|
|
||||||
DBUG_RETURN(CR_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(mysql->passwd, 0, passwd_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(CR_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@@ -48,7 +48,7 @@ ulong STDCALL net_field_length(uchar **packet)
|
|||||||
/* The same as above but returns longlong */
|
/* The same as above but returns longlong */
|
||||||
my_ulonglong net_field_length_ll(uchar **packet)
|
my_ulonglong net_field_length_ll(uchar **packet)
|
||||||
{
|
{
|
||||||
reg1 uchar *pos= *packet;
|
uchar *pos= *packet;
|
||||||
if (*pos < 251)
|
if (*pos < 251)
|
||||||
{
|
{
|
||||||
(*packet)++;
|
(*packet)++;
|
||||||
@@ -69,12 +69,47 @@ my_ulonglong net_field_length_ll(uchar **packet)
|
|||||||
(*packet)+=4;
|
(*packet)+=4;
|
||||||
return (my_ulonglong) uint3korr(pos+1);
|
return (my_ulonglong) uint3korr(pos+1);
|
||||||
}
|
}
|
||||||
|
DBUG_ASSERT(*pos == 254);
|
||||||
(*packet)+=9; /* Must be 254 when here */
|
(*packet)+=9; /* Must be 254 when here */
|
||||||
#ifdef NO_CLIENT_LONGLONG
|
|
||||||
return (my_ulonglong) uint4korr(pos+1);
|
|
||||||
#else
|
|
||||||
return (my_ulonglong) uint8korr(pos+1);
|
return (my_ulonglong) uint8korr(pos+1);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
|
my_ulonglong safe_net_field_length_ll(uchar **packet, size_t packet_len)
|
||||||
|
{
|
||||||
|
uchar *pos= *packet;
|
||||||
|
if (packet_len < 1)
|
||||||
|
goto err;
|
||||||
|
if (*pos < 251)
|
||||||
|
{
|
||||||
|
(*packet)++;
|
||||||
|
return (my_ulonglong) *pos;
|
||||||
|
}
|
||||||
|
if (*pos == 251)
|
||||||
|
{
|
||||||
|
(*packet)++;
|
||||||
|
return (my_ulonglong) NULL_LENGTH;
|
||||||
|
}
|
||||||
|
if (*pos == 252)
|
||||||
|
{
|
||||||
|
if (packet_len < 3)
|
||||||
|
goto err;
|
||||||
|
(*packet)+=3;
|
||||||
|
return (my_ulonglong) uint2korr(pos+1);
|
||||||
|
}
|
||||||
|
if (*pos == 253)
|
||||||
|
{
|
||||||
|
if (packet_len < 4)
|
||||||
|
goto err;
|
||||||
|
(*packet)+=4;
|
||||||
|
return (my_ulonglong) uint3korr(pos+1);
|
||||||
|
}
|
||||||
|
if (packet_len < 9 || *pos != 254)
|
||||||
|
goto err;
|
||||||
|
(*packet)+=9;
|
||||||
|
return (my_ulonglong) uint8korr(pos+1);
|
||||||
|
err:
|
||||||
|
*packet = NULL;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -82,36 +117,34 @@ my_ulonglong net_field_length_ll(uchar **packet)
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
net_store_length()
|
net_store_length()
|
||||||
pkg Store the packed integer here
|
packet Store the packed integer here
|
||||||
length integers to store
|
length integers to store
|
||||||
|
|
||||||
NOTES
|
NOTES
|
||||||
This is mostly used to store lengths of strings.
|
This is mostly used to store lengths of strings.
|
||||||
We have to cast the result for the LL() becasue of a bug in Forte CC
|
|
||||||
compiler.
|
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
Position in 'pkg' after the packed length
|
Position in 'packet' after the packed length
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uchar *net_store_length(uchar *packet, ulonglong length)
|
uchar *net_store_length(uchar *packet, ulonglong length)
|
||||||
{
|
{
|
||||||
if (length < (ulonglong) 251LL)
|
if (length < 251)
|
||||||
{
|
{
|
||||||
*packet=(uchar) length;
|
*packet= (uchar) length;
|
||||||
return packet+1;
|
return packet+1;
|
||||||
}
|
}
|
||||||
/* 251 is reserved for NULL */
|
/* 251 is reserved for NULL */
|
||||||
if (length < (ulonglong) 65536LL)
|
if (length < 65536)
|
||||||
{
|
{
|
||||||
*packet++=252;
|
*packet++=252;
|
||||||
int2store(packet,(uint) length);
|
int2store(packet, (uint) length);
|
||||||
return packet+2;
|
return packet+2;
|
||||||
}
|
}
|
||||||
if (length < (ulonglong) 16777216LL)
|
if (length < 16777216)
|
||||||
{
|
{
|
||||||
*packet++=253;
|
*packet++=253;
|
||||||
int3store(packet,(ulong) length);
|
int3store(packet, (ulong) length);
|
||||||
return packet+3;
|
return packet+3;
|
||||||
}
|
}
|
||||||
*packet++=254;
|
*packet++=254;
|
||||||
@@ -119,3 +152,36 @@ uchar *net_store_length(uchar *packet, ulonglong length)
|
|||||||
return packet+8;
|
return packet+8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uchar *safe_net_store_length(uchar *packet, size_t packet_len, ulonglong length)
|
||||||
|
{
|
||||||
|
if (length < 251)
|
||||||
|
{
|
||||||
|
if (packet_len < 1)
|
||||||
|
return NULL;
|
||||||
|
*packet= (uchar) length;
|
||||||
|
return packet+1;
|
||||||
|
}
|
||||||
|
/* 251 is reserved for NULL */
|
||||||
|
if (length < 65536)
|
||||||
|
{
|
||||||
|
if (packet_len < 3)
|
||||||
|
return NULL;
|
||||||
|
*packet++=252;
|
||||||
|
int2store(packet, (uint) length);
|
||||||
|
return packet+2;
|
||||||
|
}
|
||||||
|
if (length < 16777216)
|
||||||
|
{
|
||||||
|
if (packet_len < 4)
|
||||||
|
return NULL;
|
||||||
|
*packet++=253;
|
||||||
|
int3store(packet, (ulong) length);
|
||||||
|
return packet+3;
|
||||||
|
}
|
||||||
|
if (packet_len < 9)
|
||||||
|
return NULL;
|
||||||
|
*packet++=254;
|
||||||
|
int8store(packet,length);
|
||||||
|
return packet+8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
CLIENT_PROTOCOL_41 | \
|
CLIENT_PROTOCOL_41 | \
|
||||||
CLIENT_SECURE_CONNECTION | \
|
CLIENT_SECURE_CONNECTION | \
|
||||||
CLIENT_PLUGIN_AUTH | \
|
CLIENT_PLUGIN_AUTH | \
|
||||||
|
CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA | \
|
||||||
CLIENT_CONNECT_ATTRS)
|
CLIENT_CONNECT_ATTRS)
|
||||||
|
|
||||||
#define read_user_name(A) {}
|
#define read_user_name(A) {}
|
||||||
|
@@ -2171,129 +2171,28 @@ void Item_func_trim::print(String *str, enum_query_type query_type)
|
|||||||
|
|
||||||
/* Item_func_password */
|
/* Item_func_password */
|
||||||
|
|
||||||
/**
|
|
||||||
Helper function for calculating a new password. Used in
|
|
||||||
Item_func_password::fix_length_and_dec() for const parameters and in
|
|
||||||
Item_func_password::val_str_ascii() for non-const parameters.
|
|
||||||
@param str The plain text password which should be digested
|
|
||||||
@param buffer a pointer to the buffer where the digest will be stored.
|
|
||||||
|
|
||||||
@note The buffer must be of at least CRYPT_MAX_PASSWORD_SIZE size.
|
|
||||||
|
|
||||||
@return Size of the password.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int calculate_password(String *str, char *buffer)
|
|
||||||
{
|
|
||||||
DBUG_ASSERT(str);
|
|
||||||
if (str->length() == 0) // PASSWORD('') returns ''
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int buffer_len= 0;
|
|
||||||
THD *thd= current_thd;
|
|
||||||
int old_passwords= 0;
|
|
||||||
if (thd)
|
|
||||||
old_passwords= thd->variables.old_passwords;
|
|
||||||
|
|
||||||
#if defined(HAVE_OPENSSL)
|
|
||||||
if (old_passwords == 2)
|
|
||||||
{
|
|
||||||
my_make_scrambled_password(buffer, str->ptr(),
|
|
||||||
str->length());
|
|
||||||
buffer_len= (int) strlen(buffer) + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (old_passwords == 0)
|
|
||||||
{
|
|
||||||
my_make_scrambled_password_sha1(buffer, str->ptr(),
|
|
||||||
str->length());
|
|
||||||
buffer_len= SCRAMBLED_PASSWORD_CHAR_LENGTH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (old_passwords == 1)
|
|
||||||
{
|
|
||||||
my_make_scrambled_password_323(buffer, str->ptr(),
|
|
||||||
str->length());
|
|
||||||
buffer_len= SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
|
|
||||||
}
|
|
||||||
return buffer_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Item_func_password */
|
|
||||||
void Item_func_password::fix_length_and_dec()
|
|
||||||
{
|
|
||||||
maybe_null= false; // PASSWORD() never returns NULL
|
|
||||||
|
|
||||||
if (args[0]->const_item())
|
|
||||||
{
|
|
||||||
String str;
|
|
||||||
String *res= args[0]->val_str(&str);
|
|
||||||
if (!args[0]->null_value)
|
|
||||||
{
|
|
||||||
m_hashed_password_buffer_len=
|
|
||||||
calculate_password(res, m_hashed_password_buffer);
|
|
||||||
fix_length_and_charset(m_hashed_password_buffer_len, default_charset());
|
|
||||||
m_recalculate_password= false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_recalculate_password= true;
|
|
||||||
fix_length_and_charset(CRYPT_MAX_PASSWORD_SIZE, default_charset());
|
|
||||||
}
|
|
||||||
|
|
||||||
String *Item_func_password::val_str_ascii(String *str)
|
String *Item_func_password::val_str_ascii(String *str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
|
||||||
String *res= args[0]->val_str(str);
|
String *res= args[0]->val_str(str);
|
||||||
|
|
||||||
if (args[0]->null_value)
|
|
||||||
res= make_empty_result();
|
|
||||||
|
|
||||||
/* we treat NULLs as equal to empty string when calling the plugin */
|
|
||||||
check_password_policy(res);
|
check_password_policy(res);
|
||||||
|
if (args[0]->null_value || res->length() == 0)
|
||||||
null_value= 0;
|
|
||||||
if (args[0]->null_value) // PASSWORD(NULL) returns ''
|
|
||||||
return res;
|
|
||||||
|
|
||||||
if (m_recalculate_password)
|
|
||||||
m_hashed_password_buffer_len= calculate_password(res,
|
|
||||||
m_hashed_password_buffer);
|
|
||||||
|
|
||||||
if (m_hashed_password_buffer_len == 0)
|
|
||||||
return make_empty_result();
|
return make_empty_result();
|
||||||
|
my_make_scrambled_password(tmp_value, res->ptr(), res->length());
|
||||||
str->set(m_hashed_password_buffer, m_hashed_password_buffer_len,
|
str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1);
|
||||||
default_charset());
|
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *Item_func_password::
|
char *Item_func_password::alloc(THD *thd, const char *password, size_t pass_len)
|
||||||
create_password_hash_buffer(THD *thd, const char *password, size_t pass_len)
|
|
||||||
{
|
{
|
||||||
String *password_str= new (thd->mem_root)String(password, thd->variables.
|
char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
|
||||||
|
if (buff)
|
||||||
|
{
|
||||||
|
String *password_str= new (thd->mem_root)String(password, thd->variables.
|
||||||
character_set_client);
|
character_set_client);
|
||||||
check_password_policy(password_str);
|
check_password_policy(password_str);
|
||||||
|
|
||||||
char *buff= NULL;
|
|
||||||
if (thd->variables.old_passwords == 0)
|
|
||||||
{
|
|
||||||
/* Allocate memory for the password scramble and one extra byte for \0 */
|
|
||||||
buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH + 1);
|
|
||||||
my_make_scrambled_password_sha1(buff, password, pass_len);
|
|
||||||
}
|
|
||||||
#if defined(HAVE_OPENSSL)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Allocate memory for the password scramble and one extra byte for \0 */
|
|
||||||
buff= (char *) thd->alloc(CRYPT_MAX_PASSWORD_SIZE + 1);
|
|
||||||
my_make_scrambled_password(buff, password, pass_len);
|
my_make_scrambled_password(buff, password, pass_len);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,8 +21,6 @@
|
|||||||
|
|
||||||
/* This file defines all string functions */
|
/* This file defines all string functions */
|
||||||
|
|
||||||
#include "crypt_genhash_impl.h"
|
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_INTERFACE
|
#ifdef USE_PRAGMA_INTERFACE
|
||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
@@ -394,21 +392,16 @@ public:
|
|||||||
|
|
||||||
class Item_func_password :public Item_str_ascii_func
|
class Item_func_password :public Item_str_ascii_func
|
||||||
{
|
{
|
||||||
char m_hashed_password_buffer[CRYPT_MAX_PASSWORD_SIZE + 1];
|
char tmp_value[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
|
||||||
unsigned int m_hashed_password_buffer_len;
|
|
||||||
bool m_recalculate_password;
|
|
||||||
public:
|
public:
|
||||||
Item_func_password(Item *a) :Item_str_ascii_func(a)
|
Item_func_password(Item *a) :Item_str_ascii_func(a) {}
|
||||||
{
|
|
||||||
m_hashed_password_buffer_len= 0;
|
|
||||||
m_recalculate_password= false;
|
|
||||||
}
|
|
||||||
String *val_str_ascii(String *str);
|
String *val_str_ascii(String *str);
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec()
|
||||||
|
{
|
||||||
|
fix_length_and_charset(SCRAMBLED_PASSWORD_CHAR_LENGTH, default_charset());
|
||||||
|
}
|
||||||
const char *func_name() const { return "password"; }
|
const char *func_name() const { return "password"; }
|
||||||
static char *alloc(THD *thd, const char *password, size_t pass_len);
|
static char *alloc(THD *thd, const char *password, size_t pass_len);
|
||||||
static char *create_password_hash_buffer(THD *thd, const char *password,
|
|
||||||
size_t pass_len);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -67,7 +67,6 @@
|
|||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
#include <my_rnd.h>
|
#include <my_rnd.h>
|
||||||
#include <sha1.h>
|
#include <sha1.h>
|
||||||
#include <crypt_genhash_impl.h>
|
|
||||||
|
|
||||||
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
|
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/
|
||||||
|
|
||||||
@@ -280,14 +279,13 @@ void make_password_from_salt_323(char *to, const ulong *salt)
|
|||||||
**************** MySQL 4.1.1 authentication routines *************
|
**************** MySQL 4.1.1 authentication routines *************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Generate string of printable random characters of requested length
|
Generate string of printable random characters of requested length.
|
||||||
SYNOPSIS
|
|
||||||
create_random_string()
|
@param to[out] Buffer for generation; must be at least length+1 bytes
|
||||||
to OUT buffer for generation; must be at least length+1 bytes
|
long; result string is always null-terminated
|
||||||
long; result string is always null-terminated
|
length[in] How many random characters to put in buffer
|
||||||
length IN how many random characters to put in buffer
|
rand_st Structure used for number generation
|
||||||
rand_st INOUT structure used for number generation
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void create_random_string(char *to, uint length,
|
void create_random_string(char *to, uint length,
|
||||||
@@ -374,23 +372,6 @@ my_crypt(char *to, const uchar *s1, const uchar *s2, uint len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_OPENSSL)
|
|
||||||
void my_make_scrambled_password(char *to, const char *password,
|
|
||||||
size_t pass_len)
|
|
||||||
{
|
|
||||||
|
|
||||||
char salt[CRYPT_SALT_LENGTH + 1];
|
|
||||||
|
|
||||||
generate_user_salt(salt, CRYPT_SALT_LENGTH + 1);
|
|
||||||
my_crypt_genhash(to,
|
|
||||||
CRYPT_MAX_PASSWORD_SIZE,
|
|
||||||
password,
|
|
||||||
pass_len,
|
|
||||||
salt,
|
|
||||||
0);
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
Compute two stage SHA1 hash of the password :
|
Compute two stage SHA1 hash of the password :
|
||||||
|
|
||||||
@@ -422,14 +403,14 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len,
|
|||||||
The result of this function is used as return value from PASSWORD() and
|
The result of this function is used as return value from PASSWORD() and
|
||||||
is stored in the database.
|
is stored in the database.
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
my_make_scrambled_password_sha1()
|
my_make_scrambled_password()
|
||||||
buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string
|
buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string
|
||||||
password IN password string
|
password IN password string
|
||||||
pass_len IN length of password string
|
pass_len IN length of password string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void my_make_scrambled_password_sha1(char *to, const char *password,
|
void my_make_scrambled_password(char *to, const char *password,
|
||||||
size_t pass_len)
|
size_t pass_len)
|
||||||
{
|
{
|
||||||
uint8 hash_stage2[SHA1_HASH_SIZE];
|
uint8 hash_stage2[SHA1_HASH_SIZE];
|
||||||
|
|
||||||
@@ -455,7 +436,7 @@ void my_make_scrambled_password_sha1(char *to, const char *password,
|
|||||||
|
|
||||||
void make_scrambled_password(char *to, const char *password)
|
void make_scrambled_password(char *to, const char *password)
|
||||||
{
|
{
|
||||||
my_make_scrambled_password_sha1(to, password, strlen(password));
|
my_make_scrambled_password(to, password, strlen(password));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -500,7 +481,7 @@ scramble(char *to, const char *message, const char *password)
|
|||||||
null-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZE
|
null-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZE
|
||||||
long (if not, something fishy is going on).
|
long (if not, something fishy is going on).
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
check_scramble_sha1()
|
check_scramble()
|
||||||
scramble clients' reply, presumably produced by scramble()
|
scramble clients' reply, presumably produced by scramble()
|
||||||
message original random string, previously sent to client
|
message original random string, previously sent to client
|
||||||
(presumably second argument of scramble()), must be
|
(presumably second argument of scramble()), must be
|
||||||
@@ -514,8 +495,8 @@ scramble(char *to, const char *message, const char *password)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool
|
my_bool
|
||||||
check_scramble_sha1(const uchar *scramble_arg, const char *message,
|
check_scramble(const uchar *scramble_arg, const char *message,
|
||||||
const uint8 *hash_stage2)
|
const uint8 *hash_stage2)
|
||||||
{
|
{
|
||||||
uint8 buf[SHA1_HASH_SIZE];
|
uint8 buf[SHA1_HASH_SIZE];
|
||||||
uint8 hash_stage2_reassured[SHA1_HASH_SIZE];
|
uint8 hash_stage2_reassured[SHA1_HASH_SIZE];
|
||||||
@@ -532,13 +513,6 @@ check_scramble_sha1(const uchar *scramble_arg, const char *message,
|
|||||||
return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
|
return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
my_bool
|
|
||||||
check_scramble(const uchar *scramble_arg, const char *message,
|
|
||||||
const uint8 *hash_stage2)
|
|
||||||
{
|
|
||||||
return check_scramble_sha1(scramble_arg, message, hash_stage2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Convert scrambled password from asciiz hex string to binary form.
|
Convert scrambled password from asciiz hex string to binary form.
|
||||||
|
|
||||||
@@ -567,3 +541,4 @@ void make_password_from_salt(char *to, const uint8 *hash_stage2)
|
|||||||
*to++= PVERSION41_CHAR;
|
*to++= PVERSION41_CHAR;
|
||||||
octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE);
|
octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11419,13 +11419,20 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
|
|||||||
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
|
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
|
||||||
*passwd > 127 and become 2**32-127+ after casting to uint.
|
*passwd > 127 and become 2**32-127+ after casting to uint.
|
||||||
*/
|
*/
|
||||||
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
|
uint passwd_len;
|
||||||
(uchar)(*passwd++) : strlen(passwd);
|
if (!(thd->client_capabilities & CLIENT_SECURE_CONNECTION))
|
||||||
|
passwd_len= strlen(passwd);
|
||||||
|
else if (!(thd->client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA))
|
||||||
|
passwd_len= (uchar)(*passwd++);
|
||||||
|
else
|
||||||
|
passwd_len= safe_net_field_length_ll((uchar**)&passwd,
|
||||||
|
net->read_pos + pkt_len - (uchar*)passwd);
|
||||||
|
|
||||||
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
|
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
|
||||||
db + passwd_len + 1 : 0;
|
db + passwd_len + 1 : 0;
|
||||||
|
|
||||||
if (passwd + passwd_len + test(db) > (char *)net->read_pos + pkt_len)
|
if (passwd == NULL ||
|
||||||
|
passwd + passwd_len + test(db) > (char *)net->read_pos + pkt_len)
|
||||||
return packet_error;
|
return packet_error;
|
||||||
|
|
||||||
/* strlen() can't be easily deleted without changing protocol */
|
/* strlen() can't be easily deleted without changing protocol */
|
||||||
|
@@ -9753,7 +9753,7 @@ function_call_conflict:
|
|||||||
| PASSWORD '(' expr ')'
|
| PASSWORD '(' expr ')'
|
||||||
{
|
{
|
||||||
Item* i1;
|
Item* i1;
|
||||||
if (thd->variables.old_passwords == 1)
|
if (thd->variables.old_passwords)
|
||||||
i1= new (thd->mem_root) Item_func_old_password($3);
|
i1= new (thd->mem_root) Item_func_old_password($3);
|
||||||
else
|
else
|
||||||
i1= new (thd->mem_root) Item_func_password($3);
|
i1= new (thd->mem_root) Item_func_password($3);
|
||||||
@@ -14789,18 +14789,10 @@ text_or_password:
|
|||||||
TEXT_STRING { $$=$1.str;}
|
TEXT_STRING { $$=$1.str;}
|
||||||
| PASSWORD '(' TEXT_STRING ')'
|
| PASSWORD '(' TEXT_STRING ')'
|
||||||
{
|
{
|
||||||
if ($3.length == 0)
|
$$= $3.length ? thd->variables.old_passwords ?
|
||||||
$$= $3.str;
|
Item_func_old_password::alloc(thd, $3.str, $3.length) :
|
||||||
else
|
Item_func_password::alloc(thd, $3.str, $3.length) :
|
||||||
switch (thd->variables.old_passwords) {
|
$3.str;
|
||||||
case 1: $$= Item_func_old_password::
|
|
||||||
alloc(thd, $3.str, $3.length);
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
case 2: $$= Item_func_password::
|
|
||||||
create_password_hash_buffer(thd, $3.str, $3.length);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ($$ == NULL)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
@@ -15400,7 +15392,7 @@ grant_user:
|
|||||||
(char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
|
(char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
|
||||||
if (buff == NULL)
|
if (buff == NULL)
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
my_make_scrambled_password_sha1(buff, $4.str, $4.length);
|
my_make_scrambled_password(buff, $4.str, $4.length);
|
||||||
$1->password.str= buff;
|
$1->password.str= buff;
|
||||||
$1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
|
$1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user