From 45feebb99dda104a0f12abfba53ba90eabc87ff7 Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 13 Jul 2023 09:30:33 +0200 Subject: [PATCH 1/3] Remove server certification verification Since the server certification option is used by client only, there is no need to have this flag in server and or client capabilities. The server itself validates client certificate depending on the user definition. --- include/ma_common.h | 1 + include/mariadb_com.h | 1 + libmariadb/ma_pvio.c | 2 +- libmariadb/mariadb_lib.c | 7 ++----- libmariadb/secure/gnutls.c | 4 ++-- libmariadb/secure/openssl.c | 5 ++--- libmariadb/secure/schannel.c | 4 ++-- plugins/auth/my_auth.c | 4 ++-- 8 files changed, 13 insertions(+), 15 deletions(-) diff --git a/include/ma_common.h b/include/ma_common.h index a05ecf2b..f25ff358 100644 --- a/include/ma_common.h +++ b/include/ma_common.h @@ -79,6 +79,7 @@ struct st_mysql_options_extension { char *proxy_header; size_t proxy_header_len; int (*io_wait)(my_socket handle, my_bool is_read, int timeout); + my_bool tls_verify_server_cert; }; typedef struct st_connection_handler diff --git a/include/mariadb_com.h b/include/mariadb_com.h index a1b99a8d..340568d6 100644 --- a/include/mariadb_com.h +++ b/include/mariadb_com.h @@ -164,6 +164,7 @@ enum enum_server_command #define CLIENT_PROGRESS (1UL << 29) /* client supports progress indicator */ #define CLIENT_PROGRESS_OBSOLETE CLIENT_PROGRESS #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) +#define CLIENT_SSL_VERIFY_SERVER_CERT_OBSOLETE CLIENT_SSL_VERIFY_SERVER_CERT #define CLIENT_REMEMBER_OPTIONS (1UL << 31) /* MariaDB specific capabilities */ diff --git a/libmariadb/ma_pvio.c b/libmariadb/ma_pvio.c index 12569b03..6ee25d0c 100644 --- a/libmariadb/ma_pvio.c +++ b/libmariadb/ma_pvio.c @@ -540,7 +540,7 @@ my_bool ma_pvio_start_ssl(MARIADB_PVIO *pvio) 2. verify CN (requires option ssl_verify_check) 3. verrify finger print */ - if ((pvio->mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) && + if (pvio->mysql->options.extension->tls_verify_server_cert && ma_pvio_tls_verify_server_cert(pvio->ctls)) return 1; diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 8abcad90..2c566275 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -3041,10 +3041,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...) mysql->options.use_ssl= (*(my_bool *)arg1); break; case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: - if (*(my_bool *)arg1) - mysql->options.client_flag |= CLIENT_SSL_VERIFY_SERVER_CERT; - else - mysql->options.client_flag &= ~CLIENT_SSL_VERIFY_SERVER_CERT; + mysql->options.extension->tls_verify_server_cert = *(my_bool*)arg1; break; case MYSQL_OPT_SSL_KEY: OPT_SET_VALUE_STR(&mysql->options, ssl_key, (char *)arg1); @@ -3380,7 +3377,7 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...) *((my_bool *)arg)= mysql->options.use_ssl; break; case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: - *((my_bool *)arg)= test(mysql->options.client_flag & CLIENT_SSL_VERIFY_SERVER_CERT); + *((my_bool*)arg) = mysql->options.extension->tls_verify_server_cert; break; case MYSQL_OPT_SSL_KEY: *((char **)arg)= mysql->options.ssl_key; diff --git a/libmariadb/secure/gnutls.c b/libmariadb/secure/gnutls.c index 6e32366c..46650918 100644 --- a/libmariadb/secure/gnutls.c +++ b/libmariadb/secure/gnutls.c @@ -1349,7 +1349,7 @@ static int my_verify_callback(gnutls_session_t ssl) CLEAR_CLIENT_ERROR(mysql); - if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT)) + if ((mysql->options.extension->tls_verify_server_cert)) { const char *hostname= mysql->host; @@ -1364,7 +1364,7 @@ static int my_verify_callback(gnutls_session_t ssl) gnutls_datum_t out; int type; /* accept self signed certificates if we don't have to verify server cert */ - if (!(mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) && + if (!(mysql->options.extension->tls_verify_server_cert) && (status & GNUTLS_CERT_SIGNER_NOT_FOUND)) return 0; diff --git a/libmariadb/secure/openssl.c b/libmariadb/secure/openssl.c index 6b23fd8a..a21d692e 100644 --- a/libmariadb/secure/openssl.c +++ b/libmariadb/secure/openssl.c @@ -501,9 +501,8 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls) /* In case handshake failed or if a root certificate (ca) was specified, we need to check the result code of X509 verification. A detailed check of the peer certificate (hostname checking will follow later) */ - if (rc != 1 || - (mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) || - (mysql->options.ssl_ca || mysql->options.ssl_capath)) + if (rc != 1 || mysql->options.extension->tls_verify_server_cert || + mysql->options.ssl_ca || mysql->options.ssl_capath) { long x509_err= SSL_get_verify_result(ssl); if (x509_err != X509_V_OK) diff --git a/libmariadb/secure/schannel.c b/libmariadb/secure/schannel.c index 4b168129..8069af53 100644 --- a/libmariadb/secure/schannel.c +++ b/libmariadb/secure/schannel.c @@ -448,11 +448,11 @@ my_bool ma_tls_connect(MARIADB_TLS *ctls) goto end; verify_certs = mysql->options.ssl_ca || mysql->options.ssl_capath || - (mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT); + (mysql->options.extension->tls_verify_server_cert); if (verify_certs) { - if (!ma_schannel_verify_certs(ctls, (mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT))) + if (!ma_schannel_verify_certs(ctls, mysql->options.extension->tls_verify_server_cert)) goto end; } diff --git a/plugins/auth/my_auth.c b/plugins/auth/my_auth.c index e5567e6c..7f28833d 100644 --- a/plugins/auth/my_auth.c +++ b/plugins/auth/my_auth.c @@ -223,7 +223,7 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, if (mysql->options.ssl_key || mysql->options.ssl_cert || mysql->options.ssl_ca || mysql->options.ssl_capath || mysql->options.ssl_cipher || mysql->options.use_ssl || - (mysql->options.client_flag & CLIENT_SSL_VERIFY_SERVER_CERT)) + mysql->options.extension->tls_verify_server_cert) mysql->options.use_ssl= 1; if (mysql->options.use_ssl) mysql->client_flag|= CLIENT_SSL; @@ -249,7 +249,7 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, was set to mandatory, we need to return an error */ if (mysql->options.use_ssl && !(mysql->server_capabilities & CLIENT_SSL)) { - if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) || + if (mysql->options.extension->tls_verify_server_cert || (mysql->options.extension && (mysql->options.extension->tls_fp || mysql->options.extension->tls_fp_list))) { From 8ab517cbc1bd7c37a551cfa4aa1e74cc17618cbc Mon Sep 17 00:00:00 2001 From: Georg Richter Date: Thu, 13 Jul 2023 10:58:15 +0200 Subject: [PATCH 2/3] Use OPT_SET_EXT_VALUE macro instead of assigning value directly. --- libmariadb/mariadb_lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index 2c566275..6b912d6f 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -3041,7 +3041,7 @@ mysql_optionsv(MYSQL *mysql,enum mysql_option option, ...) mysql->options.use_ssl= (*(my_bool *)arg1); break; case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: - mysql->options.extension->tls_verify_server_cert = *(my_bool*)arg1; + OPT_SET_EXTENDED_VALUE(&mysql->options, tls_verify_server_cert, *(my_bool *)arg1); break; case MYSQL_OPT_SSL_KEY: OPT_SET_VALUE_STR(&mysql->options, ssl_key, (char *)arg1); @@ -3377,7 +3377,7 @@ mysql_get_optionv(MYSQL *mysql, enum mysql_option option, void *arg, ...) *((my_bool *)arg)= mysql->options.use_ssl; break; case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: - *((my_bool*)arg) = mysql->options.extension->tls_verify_server_cert; + *((my_bool*)arg) = mysql->options.extension ? mysql->options.extension->tls_verify_server_cert : 0; break; case MYSQL_OPT_SSL_KEY: *((char **)arg)= mysql->options.ssl_key; From 3393fe35d378744e12636766931cf5109cc6c2e5 Mon Sep 17 00:00:00 2001 From: Lawrin Novitsky Date: Sun, 23 Jul 2023 15:27:30 +0200 Subject: [PATCH 3/3] Fixes for debug exceptions with runtime checks eanbled with VS /RTCc option This could be the cases of casting to smaler types with loss of data. The fix adds bitwise add with correspondent number of 0xff bytes. --- include/ma_global.h | 6 +++--- libmariadb/ma_stmt_codec.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/ma_global.h b/include/ma_global.h index 3a6003ea..d5e3da9b 100644 --- a/include/ma_global.h +++ b/include/ma_global.h @@ -788,9 +788,9 @@ typedef char bool; /* Ordinary boolean values 0 1 */ #define uint8korr(A) (*((ulonglong *) (A))) #define sint8korr(A) (*((longlong *) (A))) #define int2store(T,A) *((uint16*) (T))= (uint16) (A) -#define int3store(T,A) do { *(T)= (uchar) ((A));\ - *(T+1)=(uchar) (((uint) (A) >> 8));\ - *(T+2)=(uchar) (((A) >> 16)); } while (0) +#define int3store(T,A) do { *(T)= (uchar) ((A) & 0xff);\ + *(T+1)=(uchar) (((uint) (A) >> 8) & 0xff);\ + *(T+2)=(uchar) (((A) >> 16) & 0xff); } while (0) #define int4store(T,A) *((long *) (T))= (long) (A) #define int5store(T,A) do { *(T)= (uchar)((A));\ *((T)+1)=(uchar) (((A) >> 8));\ diff --git a/libmariadb/ma_stmt_codec.c b/libmariadb/ma_stmt_codec.c index 3dde3c40..afb46b25 100644 --- a/libmariadb/ma_stmt_codec.c +++ b/libmariadb/ma_stmt_codec.c @@ -606,18 +606,18 @@ static void convert_from_long(MYSQL_BIND *r_param, const MYSQL_FIELD *field, lon { switch (r_param->buffer_type) { case MYSQL_TYPE_TINY: - *(uchar *)r_param->buffer= (uchar)val; + *(uchar *)r_param->buffer= (uchar)(val & 0xff); *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX8) : NUMERIC_TRUNCATION(val, INT_MIN8, INT_MAX8); r_param->buffer_length= 1; break; case MYSQL_TYPE_SHORT: case MYSQL_TYPE_YEAR: - shortstore(r_param->buffer, (short)val); + shortstore(r_param->buffer, (short)(val & 0xffff)); *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX16) : NUMERIC_TRUNCATION(val, INT_MIN16, INT_MAX16); r_param->buffer_length= 2; break; case MYSQL_TYPE_LONG: - longstore(r_param->buffer, (int32)val); + longstore(r_param->buffer, (int32)(val & 0xffffffff)); *r_param->error= r_param->is_unsigned ? NUMERIC_TRUNCATION(val, 0, UINT_MAX32) : NUMERIC_TRUNCATION(val, INT_MIN32, INT_MAX32); r_param->buffer_length= 4; break;