mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-31855 validate ssl certificates using client password
if the client enabled --ssl-verify-server-cert, then the server certificate is verified as follows: * if --ssl-ca or --ssl-capath were specified, the cert must have a proper signature by the specified CA (or CA in the path) and the cert's hostname must match the server's hostname. If the cert isn't signed or a hostname is wrong - the connection is aborted. * if MARIADB_OPT_TLS_PEER_FP was used and the fingerprint matches, the connection is allowed, if it doesn't match - aborted. * If the connection uses unix socket or named pipes - it's allowed. (consistent with server's --require-secure-transport behavior) otherwise the cert is still in doubt, we don't know if we can trust it or there's an active MitM in progress. * If the user has provided no password or the server requested an authentication plugin that sends the password in cleartext - the connection is aborted. * Perform the authentication. If the server accepts the password, it'll send SHA2(scramble || password hash || cert fingerprint) with the OK packet. * Verify the SHA2 digest, if it matches - the connection is allowed, otherwise it's aborted.
This commit is contained in:
@ -201,15 +201,11 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class ACL_USER :public ACL_USER_BASE,
|
||||
public ACL_USER_PARAM
|
||||
class ACL_USER :public ACL_USER_BASE, public ACL_USER_PARAM
|
||||
{
|
||||
public:
|
||||
|
||||
ACL_USER() = default;
|
||||
ACL_USER(THD *thd, const LEX_USER &combo,
|
||||
const Account_options &options,
|
||||
const privilege_t privileges);
|
||||
ACL_USER(THD *, const LEX_USER &, const Account_options &, const privilege_t);
|
||||
|
||||
ACL_USER *copy(MEM_ROOT *root)
|
||||
{
|
||||
@ -14390,6 +14386,29 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void make_ssl_info(THD *thd, LEX_CSTRING salt, char *info)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
uchar digest[256/8];
|
||||
if (!salt.length)
|
||||
return;
|
||||
|
||||
/*
|
||||
mark that it's after-auth mysql->info version 1.
|
||||
meaning, it contains sha2(salt, scramble, sha2_cert_fingerprint)
|
||||
encoded in 64 lowercase letters 'a'..'p', one letter per 4 bits (0..15)
|
||||
*/
|
||||
*info++= 1; // Version 1
|
||||
|
||||
DBUG_ASSERT(thd->scramble[SCRAMBLE_LENGTH] == 0);
|
||||
|
||||
LEX_CUSTRING fp= ssl_acceptor_fingerprint();
|
||||
my_sha256_multi(digest, salt.str, salt.length, thd->scramble,
|
||||
(size_t)SCRAMBLE_LENGTH, fp.str, fp.length, NULL);
|
||||
octet2hex(info, digest, sizeof(digest));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static int do_auth_once(THD *thd, const LEX_CSTRING *auth_plugin_name,
|
||||
MPVIO_EXT *mpvio)
|
||||
@ -14507,6 +14526,7 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
|
||||
{
|
||||
int res= CR_OK;
|
||||
MPVIO_EXT mpvio;
|
||||
char ssl_info[256/4 + 2]= {0}; // '\1', SHA256 (1 char per 4 bits), '\0'
|
||||
enum enum_server_command command= com_change_user_pkt_len ? COM_CHANGE_USER
|
||||
: COM_CONNECT;
|
||||
DBUG_ENTER("acl_authenticate");
|
||||
@ -14844,7 +14864,10 @@ bool acl_authenticate(THD *thd, uint com_change_user_pkt_len)
|
||||
sctx->external_user= my_strdup(key_memory_MPVIO_EXT_auth_info,
|
||||
mpvio.auth_info.external_user, MYF(0));
|
||||
|
||||
my_ok(thd);
|
||||
if (initialized && !com_change_user_pkt_len)
|
||||
make_ssl_info(thd, acl_user->auth[mpvio.curr_auth-1].salt, ssl_info);
|
||||
|
||||
my_ok(thd, 0, 0, ssl_info[0] == '\1' ? ssl_info : NULL);
|
||||
|
||||
PSI_CALL_set_thread_account
|
||||
(thd->main_security_ctx.user, static_cast<uint>(strlen(thd->main_security_ctx.user)),
|
||||
|
Reference in New Issue
Block a user