You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-08 14:02:17 +03:00
MDEV-31855 SSL cert validation protocol extension
* extend the client auth plugin API with a new callback * relax the plugin version check to allow load a plugin with the same major version, even if the minor versions differ * implement the protocol extension: - don't abort at once if the certificate is self signed and no CA was explicitly specified - allow it if it passes fingerprint check - allow it if plugin has hash_password_bin callback, password was non-empty and the control hash matches server's
This commit is contained in:
@@ -305,7 +305,8 @@ IF(NOT WITH_SSL STREQUAL "OFF")
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
IF(OPENSSL_FOUND)
|
IF(OPENSSL_FOUND)
|
||||||
ADD_DEFINITIONS(-DHAVE_OPENSSL -DHAVE_TLS)
|
ADD_DEFINITIONS(-DHAVE_OPENSSL -DHAVE_TLS)
|
||||||
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/openssl.c")
|
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/openssl.c"
|
||||||
|
"${CC_SOURCE_DIR}/libmariadb/secure/openssl_crypt.c")
|
||||||
SET(SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
|
SET(SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
CHECK_INCLUDE_FILES (${OPENSSL_INCLUDE_DIR}/openssl/applink.c HAVE_OPENSSL_APPLINK_C)
|
CHECK_INCLUDE_FILES (${OPENSSL_INCLUDE_DIR}/openssl/applink.c HAVE_OPENSSL_APPLINK_C)
|
||||||
@@ -332,7 +333,8 @@ IF(NOT WITH_SSL STREQUAL "OFF")
|
|||||||
FIND_PACKAGE(GnuTLS "3.3.24" REQUIRED)
|
FIND_PACKAGE(GnuTLS "3.3.24" REQUIRED)
|
||||||
IF(GNUTLS_FOUND)
|
IF(GNUTLS_FOUND)
|
||||||
ADD_DEFINITIONS(-DHAVE_GNUTLS -DHAVE_TLS)
|
ADD_DEFINITIONS(-DHAVE_GNUTLS -DHAVE_TLS)
|
||||||
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/gnutls.c")
|
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/gnutls.c"
|
||||||
|
"${CC_SOURCE_DIR}/libmariadb/secure/gnutls_crypt.c")
|
||||||
SET(SSL_LIBRARIES ${GNUTLS_LIBRARY})
|
SET(SSL_LIBRARIES ${GNUTLS_LIBRARY})
|
||||||
SET(TLS_LIBRARY_VERSION "GnuTLS ${GNUTLS_VERSION_STRING}")
|
SET(TLS_LIBRARY_VERSION "GnuTLS ${GNUTLS_VERSION_STRING}")
|
||||||
INCLUDE_DIRECTORIES(${GNUTLS_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${GNUTLS_INCLUDE_DIR})
|
||||||
@@ -342,12 +344,13 @@ IF(NOT WITH_SSL STREQUAL "OFF")
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
IF(WITH_SSL STREQUAL "SCHANNEL")
|
IF(WITH_SSL STREQUAL "SCHANNEL")
|
||||||
ADD_DEFINITIONS(-DHAVE_SCHANNEL -DHAVE_TLS)
|
ADD_DEFINITIONS(-DHAVE_SCHANNEL -DHAVE_TLS -DHAVE_WINCRYPT)
|
||||||
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/schannel.c"
|
SET(SSL_SOURCES "${CC_SOURCE_DIR}/libmariadb/secure/schannel.c"
|
||||||
|
"${CC_SOURCE_DIR}/libmariadb/secure/win_crypt.c"
|
||||||
"${CC_SOURCE_DIR}/libmariadb/secure/ma_schannel.c"
|
"${CC_SOURCE_DIR}/libmariadb/secure/ma_schannel.c"
|
||||||
"${CC_SOURCE_DIR}/libmariadb/secure/schannel_certs.c")
|
"${CC_SOURCE_DIR}/libmariadb/secure/schannel_certs.c")
|
||||||
INCLUDE_DIRECTORIES("${CC_SOURCE_DIR}/plugins/pvio/")
|
INCLUDE_DIRECTORIES("${CC_SOURCE_DIR}/plugins/pvio/")
|
||||||
SET(SSL_LIBRARIES secur32)
|
SET(SSL_LIBRARIES secur32 crypt32 bcrypt)
|
||||||
SET(TLS_LIBRARY_VERSION "Schannel ${CMAKE_SYSTEM_VERSION}")
|
SET(TLS_LIBRARY_VERSION "Schannel ${CMAKE_SYSTEM_VERSION}")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
@@ -129,3 +129,16 @@ typedef struct st_mariadb_field_extension
|
|||||||
{
|
{
|
||||||
MARIADB_CONST_STRING metadata[MARIADB_FIELD_ATTR_LAST+1]; /* 10.5 */
|
MARIADB_CONST_STRING metadata[MARIADB_FIELD_ATTR_LAST+1]; /* 10.5 */
|
||||||
} MA_FIELD_EXTENSION;
|
} MA_FIELD_EXTENSION;
|
||||||
|
|
||||||
|
#if defined(HAVE_SCHANNEL) || defined(HAVE_GNUTLS)
|
||||||
|
#define reset_tls_self_signed_error(mysql) \
|
||||||
|
do { \
|
||||||
|
free((char*)mysql->net.tls_self_signed_error); \
|
||||||
|
mysql->net.tls_self_signed_error= 0; \
|
||||||
|
} while(0)
|
||||||
|
#else
|
||||||
|
#define reset_tls_self_signed_error(mysql) \
|
||||||
|
do { \
|
||||||
|
mysql->net.tls_self_signed_error= 0; \
|
||||||
|
} while(0)
|
||||||
|
#endif
|
||||||
|
@@ -288,7 +288,7 @@ typedef struct st_net {
|
|||||||
my_bool unused_2;
|
my_bool unused_2;
|
||||||
my_bool compress;
|
my_bool compress;
|
||||||
my_bool unused_3;
|
my_bool unused_3;
|
||||||
void *unused_4;
|
const char *tls_self_signed_error;
|
||||||
unsigned int last_errno;
|
unsigned int last_errno;
|
||||||
unsigned char error;
|
unsigned char error;
|
||||||
my_bool unused_5;
|
my_bool unused_5;
|
||||||
|
@@ -43,7 +43,7 @@
|
|||||||
#define MYSQL_CLIENT_PLUGIN_RESERVED2 1
|
#define MYSQL_CLIENT_PLUGIN_RESERVED2 1
|
||||||
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2 /* authentication */
|
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN 2 /* authentication */
|
||||||
|
|
||||||
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0100
|
#define MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION 0x0101
|
||||||
#define MYSQL_CLIENT_MAX_PLUGINS 3
|
#define MYSQL_CLIENT_MAX_PLUGINS 3
|
||||||
|
|
||||||
/* Connector/C specific plugin types */
|
/* Connector/C specific plugin types */
|
||||||
@@ -128,6 +128,7 @@ struct st_mysql_client_plugin_AUTHENTICATION
|
|||||||
{
|
{
|
||||||
MYSQL_CLIENT_PLUGIN_HEADER
|
MYSQL_CLIENT_PLUGIN_HEADER
|
||||||
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
|
int (*authenticate_user)(MYSQL_PLUGIN_VIO *vio, struct st_mysql *mysql);
|
||||||
|
int (*hash_password_bin)(struct st_mysql *mysql, unsigned char *hash, size_t *hash_length);
|
||||||
};
|
};
|
||||||
|
|
||||||
/******** trace plugin *******/
|
/******** trace plugin *******/
|
||||||
|
@@ -111,8 +111,7 @@ static int get_plugin_nr(uint type)
|
|||||||
|
|
||||||
static const char *check_plugin_version(struct st_mysql_client_plugin *plugin, unsigned int version)
|
static const char *check_plugin_version(struct st_mysql_client_plugin *plugin, unsigned int version)
|
||||||
{
|
{
|
||||||
if (plugin->interface_version < version ||
|
if (plugin->interface_version >> 8 != version >> 8)
|
||||||
(plugin->interface_version >> 8) > (version >> 8))
|
|
||||||
return "Incompatible client plugin interface";
|
return "Incompatible client plugin interface";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -545,6 +545,7 @@ my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
|
|||||||
3. verrify finger print
|
3. verrify finger print
|
||||||
*/
|
*/
|
||||||
if (pvio->mysql->options.extension->tls_verify_server_cert &&
|
if (pvio->mysql->options.extension->tls_verify_server_cert &&
|
||||||
|
!pvio->mysql->net.tls_self_signed_error &&
|
||||||
ma_pvio_tls_verify_server_cert(pvio->ctls))
|
ma_pvio_tls_verify_server_cert(pvio->ctls))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@@ -556,6 +557,7 @@ my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio)
|
|||||||
pvio->mysql->options.extension->tls_fp,
|
pvio->mysql->options.extension->tls_fp,
|
||||||
pvio->mysql->options.extension->tls_fp_list))
|
pvio->mysql->options.extension->tls_fp_list))
|
||||||
return 1;
|
return 1;
|
||||||
|
reset_tls_self_signed_error(pvio->mysql); // validated
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -1440,6 +1440,8 @@ mysql_real_connect(MYSQL *mysql, const char *host, const char *user,
|
|||||||
if (!mysql->options.extension || !mysql->options.extension->status_callback)
|
if (!mysql->options.extension || !mysql->options.extension->status_callback)
|
||||||
mysql_optionsv(mysql, MARIADB_OPT_STATUS_CALLBACK, NULL, NULL);
|
mysql_optionsv(mysql, MARIADB_OPT_STATUS_CALLBACK, NULL, NULL);
|
||||||
|
|
||||||
|
reset_tls_self_signed_error(mysql);
|
||||||
|
|
||||||
/* if host contains a semicolon, we need to parse connection string */
|
/* if host contains a semicolon, we need to parse connection string */
|
||||||
if (host && strchr(host, ';'))
|
if (host && strchr(host, ';'))
|
||||||
{
|
{
|
||||||
@@ -2444,6 +2446,7 @@ mysql_close(MYSQL *mysql)
|
|||||||
mysql_close_memory(mysql);
|
mysql_close_memory(mysql);
|
||||||
mysql_close_options(mysql);
|
mysql_close_options(mysql);
|
||||||
ma_clear_session_state(mysql);
|
ma_clear_session_state(mysql);
|
||||||
|
reset_tls_self_signed_error(mysql);
|
||||||
|
|
||||||
if (mysql->net.extension)
|
if (mysql->net.extension)
|
||||||
{
|
{
|
||||||
|
@@ -1371,11 +1371,23 @@ static int my_verify_callback(gnutls_session_t ssl)
|
|||||||
{
|
{
|
||||||
gnutls_datum_t out;
|
gnutls_datum_t out;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
|
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
|
||||||
|
{
|
||||||
/* accept self signed certificates if we don't have to verify server cert */
|
/* accept self signed certificates if we don't have to verify server cert */
|
||||||
if (!(mysql->options.extension->tls_verify_server_cert) &&
|
if (!mysql->options.extension->tls_verify_server_cert)
|
||||||
(status & GNUTLS_CERT_SIGNER_NOT_FOUND))
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* postpone the error for self signed certificates if CA isn't set */
|
||||||
|
if (!mysql->options.ssl_ca && !mysql->options.ssl_capath)
|
||||||
|
{
|
||||||
|
type= gnutls_certificate_type_get(ssl);
|
||||||
|
gnutls_certificate_verification_status_print(status, type, &out, 0);
|
||||||
|
mysql->net.tls_self_signed_error= (char*)out.data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* gnutls default error message "certificate validation failed" isn't very
|
/* gnutls default error message "certificate validation failed" isn't very
|
||||||
descriptive, so we provide more information about the error here */
|
descriptive, so we provide more information about the error here */
|
||||||
type= gnutls_certificate_type_get(ssl);
|
type= gnutls_certificate_type_get(ssl);
|
||||||
|
@@ -526,6 +526,13 @@ my_bool ma_schannel_verify_certs(MARIADB_TLS *ctls, BOOL verify_server_name)
|
|||||||
end:
|
end:
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
|
/* postpone the error for self signed certificates if CA isn't set */
|
||||||
|
if (status == CERT_E_UNTRUSTEDROOT && !ca_file && !ca_path)
|
||||||
|
{
|
||||||
|
mysql->net.tls_self_signed_error= strdup(errmsg);
|
||||||
|
ret= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, errmsg);
|
pvio->set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, 0, errmsg);
|
||||||
}
|
}
|
||||||
if (pServerCert)
|
if (pServerCert)
|
||||||
|
@@ -510,7 +510,11 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls)
|
|||||||
mysql->options.ssl_ca || mysql->options.ssl_capath)
|
mysql->options.ssl_ca || mysql->options.ssl_capath)
|
||||||
{
|
{
|
||||||
long x509_err= SSL_get_verify_result(ssl);
|
long x509_err= SSL_get_verify_result(ssl);
|
||||||
if (x509_err != X509_V_OK)
|
if ((x509_err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT ||
|
||||||
|
x509_err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) && rc == 1 &&
|
||||||
|
!mysql->options.ssl_ca && !mysql->options.ssl_capath)
|
||||||
|
mysql->net.tls_self_signed_error= X509_verify_cert_error_string(x509_err);
|
||||||
|
else if (x509_err != X509_V_OK)
|
||||||
{
|
{
|
||||||
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(x509_err));
|
ER(CR_SSL_CONNECTION_ERROR), X509_verify_cert_error_string(x509_err));
|
||||||
|
@@ -117,5 +117,6 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
gssapi_auth_client
|
gssapi_auth_client,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
@@ -145,7 +145,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
|
|||||||
auth_caching_sha2_init,
|
auth_caching_sha2_init,
|
||||||
auth_caching_sha2_deinit,
|
auth_caching_sha2_deinit,
|
||||||
NULL,
|
NULL,
|
||||||
auth_caching_sha2_client
|
auth_caching_sha2_client,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_WINCRYPT
|
#ifdef HAVE_WINCRYPT
|
||||||
|
@@ -58,7 +58,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
|
|||||||
auth_dialog_init,
|
auth_dialog_init,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
auth_dialog_open
|
auth_dialog_open,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -83,7 +83,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
|
|||||||
auth_ed25519_init,
|
auth_ed25519_init,
|
||||||
auth_ed25519_deinit,
|
auth_ed25519_deinit,
|
||||||
NULL,
|
NULL,
|
||||||
auth_ed25519_client
|
auth_ed25519_client,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -70,7 +70,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
clear_password_auth_client
|
clear_password_auth_client,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#include <errmsg.h>
|
#include <errmsg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ma_common.h>
|
#include <ma_common.h>
|
||||||
|
#include <ma_crypt.h>
|
||||||
#include <mysql/client_plugin.h>
|
#include <mysql/client_plugin.h>
|
||||||
|
|
||||||
typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
|
typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
|
||||||
@@ -14,6 +15,16 @@ extern char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer);
|
|||||||
extern int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length);
|
extern int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length);
|
||||||
extern unsigned char *mysql_net_store_length(unsigned char *packet, ulonglong length);
|
extern unsigned char *mysql_net_store_length(unsigned char *packet, ulonglong length);
|
||||||
|
|
||||||
|
#define hashing(p) (p->interface_version >= 0x0101 && p->hash_password_bin)
|
||||||
|
|
||||||
|
static int set_error_from_tls_self_signed_error(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN,
|
||||||
|
ER(CR_SSL_CONNECTION_ERROR), mysql->net.tls_self_signed_error);
|
||||||
|
reset_tls_self_signed_error(mysql);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int (*read_packet)(struct st_plugin_vio *vio, uchar **buf);
|
int (*read_packet)(struct st_plugin_vio *vio, uchar **buf);
|
||||||
int (*write_packet)(struct st_plugin_vio *vio, const uchar *pkt, size_t pkt_len);
|
int (*write_packet)(struct st_plugin_vio *vio, const uchar *pkt, size_t pkt_len);
|
||||||
@@ -50,7 +61,8 @@ auth_plugin_t mysql_native_password_client_plugin=
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
native_password_auth_client
|
native_password_auth_client,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -110,7 +122,8 @@ auth_plugin_t dummy_fallback_client_plugin=
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
dummy_fallback_auth_client
|
dummy_fallback_auth_client,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -350,6 +363,13 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
|
|||||||
}
|
}
|
||||||
if (ma_pvio_start_ssl(mysql->net.pvio))
|
if (ma_pvio_start_ssl(mysql->net.pvio))
|
||||||
goto error;
|
goto error;
|
||||||
|
if (mysql->net.tls_self_signed_error &&
|
||||||
|
(!mysql->passwd || !mysql->passwd[0] || !hashing(mpvio->plugin)))
|
||||||
|
{
|
||||||
|
/* cannot use auth to validate the cert */
|
||||||
|
set_error_from_tls_self_signed_error(mysql);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_TLS */
|
#endif /* HAVE_TLS */
|
||||||
|
|
||||||
@@ -727,15 +747,62 @@ retry:
|
|||||||
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
|
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
|
||||||
auth_plugin= &dummy_fallback_client_plugin;
|
auth_plugin= &dummy_fallback_client_plugin;
|
||||||
|
|
||||||
|
/* can we use this plugin with this tls server cert ? */
|
||||||
|
if (mysql->net.tls_self_signed_error && !hashing(auth_plugin))
|
||||||
|
return set_error_from_tls_self_signed_error(mysql);
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
net->read_pos[0] should always be 0 here if the server implements
|
net->read_pos[0] should always be 0 here if the server implements
|
||||||
the protocol correctly
|
the protocol correctly
|
||||||
*/
|
*/
|
||||||
if (mysql->net.read_pos[0] == 0)
|
if (mysql->net.read_pos[0] != 0)
|
||||||
return ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length);
|
|
||||||
return 1;
|
return 1;
|
||||||
|
if (ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!mysql->net.tls_self_signed_error)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
assert(mysql->options.use_ssl);
|
||||||
|
assert(mysql->options.extension->tls_verify_server_cert);
|
||||||
|
assert(!mysql->options.ssl_ca);
|
||||||
|
assert(!mysql->options.ssl_capath);
|
||||||
|
assert(!mysql->options.extension->tls_fp);
|
||||||
|
assert(!mysql->options.extension->tls_fp_list);
|
||||||
|
assert(hashing(auth_plugin));
|
||||||
|
assert(mysql->passwd[0]);
|
||||||
|
if (mysql->info && mysql->info[0] == '\1')
|
||||||
|
{
|
||||||
|
MA_HASH_CTX *ctx = NULL;
|
||||||
|
unsigned char buf[1024], digest[MA_SHA256_HASH_SIZE];
|
||||||
|
char fp[128], hexdigest[sizeof(digest)*2+1], *hexsig= mysql->info + 1;
|
||||||
|
size_t buflen= sizeof(buf) - 1, fplen;
|
||||||
|
|
||||||
|
mysql->info= NULL; /* no need to confuse the client with binary info */
|
||||||
|
|
||||||
|
if (!(fplen= ma_tls_get_finger_print(mysql->net.pvio->ctls, MA_HASH_SHA256,
|
||||||
|
fp, sizeof(fp))))
|
||||||
|
return 1; /* error is already set */
|
||||||
|
|
||||||
|
if (auth_plugin->hash_password_bin(mysql, buf, &buflen) ||
|
||||||
|
!(ctx= ma_hash_new(MA_HASH_SHA256)))
|
||||||
|
{
|
||||||
|
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ma_hash_input(ctx, (unsigned char*)buf, buflen);
|
||||||
|
ma_hash_input(ctx, (unsigned char*)mysql->scramble_buff, SCRAMBLE_LENGTH);
|
||||||
|
ma_hash_input(ctx, (unsigned char*)fp, fplen);
|
||||||
|
ma_hash_result(ctx, digest);
|
||||||
|
ma_hash_free(ctx);
|
||||||
|
|
||||||
|
mysql_hex_string(hexdigest, (char*)digest, sizeof(digest));
|
||||||
|
if (strcmp(hexdigest, hexsig) == 0)
|
||||||
|
return 0; /* phew. self-signed certificate is validated! */
|
||||||
|
}
|
||||||
|
|
||||||
|
return set_error_from_tls_self_signed_error(mysql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -63,7 +63,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
auth_old_password
|
auth_old_password,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -76,7 +76,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ =
|
|||||||
auth_sha256_init,
|
auth_sha256_init,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
auth_sha256_client
|
auth_sha256_client,
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_WINCRYPT
|
#ifdef HAVE_WINCRYPT
|
||||||
|
Reference in New Issue
Block a user