You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-10 01:02:57 +03:00
Peer certificate validation: Since version 3.4 peer certificate verification is enabled by default. It can be disabled via `mysql_optionsv`, using option MYSQL_OPT_SSL_VERIFY_SERVER_CERT: my_bool verify= 0; mysql_options(mariadb, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &verify); Self signed certificates If the client obtained a self signed peer certificate from MariaDB server the verification will fail, with the following exceptions: * If the connection between client and server is considered to be secure:, e.g. * a unix_socket is used for client server communication * hostname is localhost (Windows operating system), 127.0.0.1 or ::1 * a specified fingerprint matches the fingerprint of the peer certificate (see below) * a client can verify the certificate using account password, it's possible if * account has a password * authentication plugin is "secure without TLS", that is, one of mysql_native_password, ed25519 or parsec. Fingerprint verification of the peer certificate A fingerprint is a cryptographic hash (SHA-256, SHA-384 or SHA-512) of the peer certificate's binary data. Even if the fingerprint matches, an expired or revoked certificate will not be accepted. For security reasons support for MD5 and SHA1 has been removed. Technical details: ================== - Peer certificate verification call was removed from ma_tls_connect, instead it will be called directly after the handshake succeeded (my_auth.c) - mysql->net.tls_self_signed_error was replaced by mysql->net.tls_verify_status which contains the result of the peer certfificate verification: The verification status can be obtained with mariadb_get_infov using new parameter MARIADB_TLS_VERIFY_STATUS. unsigned int tls_verify_status; mariadb_get_infov(mysql, MARIADB_TLS_VERIFY_STATUS, &tls_verify_status); The result is a combination of the following flags: MARIADB_TLS_VERIFY_OK 0 MARIADB_TLS_VERIFY_TRUST 1 MARIADB_TLS_VERIFY_HOST 2 MARIADB_TLS_VERIFY_PERIOD 4 MARIADB_TLS_VERIFY_FINGERPRINT 8 MARIADB_TLS_VERIFY_REVOKED 16 MARIADB_TLS_VERIFY_UNKNOWN 32 - GnuTLS peer certificate verification callback was removed and replaced by gnutls_verify_peers2() api function, so the peer certificate validation will happen after handshake. - OpenSSL implementation will no longer use SSL_verify_result to check the validity of the peer certificate. Instead a callback function will be called during the handshake, which collects all certificate validation errors. - If the peer certificate is not trusted, hostname verification will be skipped. - Testing Added new test tls, which implements a python based dummy server, which allows to set different certificates and TLS options. Please note. that tests are expected to fail, since the server doesn't support further steps like user authentication etc. after the handshake. Prerequisite for running the tls test is Python3.
434 lines
11 KiB
C
434 lines
11 KiB
C
/*
|
|
Copyright (c) 2018 MariaDB Corporation AB
|
|
|
|
The MySQL Connector/C is licensed under the terms of the GPLv2
|
|
<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
|
MySQL Connectors. There are special exceptions to the terms and
|
|
conditions of the GPLv2 as it is applied to this software, see the
|
|
FLOSS License Exception
|
|
<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
|
|
|
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 02110-1301 USA
|
|
*/
|
|
/**
|
|
Some basic tests of the client API.
|
|
*/
|
|
|
|
#include "my_test.h"
|
|
#include "mariadb_rpl.h"
|
|
|
|
static int test_rpl_async(MYSQL *my __attribute__((unused)))
|
|
{
|
|
MYSQL *mysql= mysql_init(NULL);
|
|
MYSQL_RES *result;
|
|
MYSQL_ROW row;
|
|
MARIADB_RPL_EVENT *event= NULL;
|
|
MARIADB_RPL *rpl;
|
|
int events= 0, rc;
|
|
|
|
SKIP_SKYSQL;
|
|
SKIP_MAXSCALE;
|
|
|
|
if (!is_mariadb)
|
|
return SKIP;
|
|
|
|
if (!my_test_connect(mysql, hostname, username,
|
|
password, schema, port, socketname, 0, 1))
|
|
{
|
|
diag("Error: %s", mysql_error(mysql));
|
|
mysql_close(mysql);
|
|
return FAIL;
|
|
}
|
|
|
|
rc= mysql_query(mysql, "SELECT @@log_bin");
|
|
check_mysql_rc(rc, mysql);
|
|
|
|
result= mysql_store_result(mysql);
|
|
row= mysql_fetch_row(result);
|
|
if (!atoi(row[0]))
|
|
rc= SKIP;
|
|
mysql_free_result(result);
|
|
|
|
if (rc == SKIP)
|
|
{
|
|
diag("binary log disabled -> skip");
|
|
mysql_close(mysql);
|
|
return SKIP;
|
|
}
|
|
|
|
rpl = mariadb_rpl_init(mysql);
|
|
|
|
mysql_query(mysql, "SET @mariadb_slave_capability=4");
|
|
mysql_query(mysql, "SET NAMES latin1");
|
|
mysql_query(mysql, "SET @slave_gtid_strict_mode=1");
|
|
mysql_query(mysql, "SET @master_heartbeat_period=10");
|
|
mysql_query(mysql, "SET @slave_gtid_ignore_duplicates=1");
|
|
mysql_query(mysql, "SET NAMES utf8");
|
|
mysql_query(mysql, "SET @master_binlog_checksum= @@global.binlog_checksum");
|
|
rpl->server_id= 12;
|
|
rpl->start_position= 4;
|
|
rpl->flags= MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS;
|
|
|
|
if (mariadb_rpl_open(rpl))
|
|
return FAIL;
|
|
|
|
/* We run rpl_api as very last test, too make sure
|
|
binary log contains > 10000 events.
|
|
*/
|
|
while((event= mariadb_rpl_fetch(rpl, event)) && event->event_type != HEARTBEAT_LOG_EVENT)
|
|
{
|
|
events++;
|
|
}
|
|
mariadb_free_rpl_event(event);
|
|
mariadb_rpl_close(rpl);
|
|
mysql_close(mysql);
|
|
return OK;
|
|
}
|
|
|
|
static int test_rpl_semisync(MYSQL *my __attribute__((unused)))
|
|
{
|
|
MYSQL *mysql= mysql_init(NULL);
|
|
MYSQL_RES *result;
|
|
MYSQL_ROW row;
|
|
MARIADB_RPL_EVENT *event= NULL;
|
|
MARIADB_RPL *rpl;
|
|
int events= 0, rc;
|
|
|
|
SKIP_SKYSQL;
|
|
SKIP_MAXSCALE;
|
|
|
|
if (!is_mariadb)
|
|
return SKIP;
|
|
|
|
if (!my_test_connect(mysql, hostname, username,
|
|
password, schema, port, socketname, 0, 1))
|
|
{
|
|
diag("Error: %s", mysql_error(mysql));
|
|
mysql_close(mysql);
|
|
return FAIL;
|
|
}
|
|
|
|
rc= mysql_query(mysql, "SELECT @@log_bin");
|
|
check_mysql_rc(rc, mysql);
|
|
|
|
result= mysql_store_result(mysql);
|
|
row= mysql_fetch_row(result);
|
|
if (!atoi(row[0]))
|
|
rc= SKIP;
|
|
mysql_free_result(result);
|
|
|
|
if (rc == SKIP)
|
|
{
|
|
diag("binary log disabled -> skip");
|
|
mysql_close(mysql);
|
|
return SKIP;
|
|
}
|
|
|
|
rpl = mariadb_rpl_init(mysql);
|
|
|
|
mariadb_rpl_optionsv(rpl, MARIADB_RPL_HOST, "foo");
|
|
|
|
mysql_query(mysql, "SET @mariadb_slave_capability=4");
|
|
mysql_query(mysql, "SET NAMES latin1");
|
|
mysql_query(mysql, "SET @slave_gtid_strict_mode=1");
|
|
mysql_query(mysql, "SET @slave_gtid_ignore_duplicates=1");
|
|
mysql_query(mysql, "SET @master_heartbeat_period=10");
|
|
mysql_query(mysql, "SET NAMES utf8");
|
|
mysql_query(mysql, "SET @master_binlog_checksum= @@global.binlog_checksum");
|
|
rpl->server_id= 12;
|
|
rpl->start_position= 4;
|
|
rpl->flags= MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS;
|
|
|
|
mysql_query(mysql, "SET @mariadb_slave_capability=4");
|
|
mysql_query(mysql, "SET NAMES latin1");
|
|
mysql_query(mysql, "SET @slave_gtid_strict_mode=1");
|
|
mysql_query(mysql, "SET @slave_gtid_ignore_duplicates=1");
|
|
mysql_query(mysql, "SET NAMES utf8");
|
|
mysql_query(mysql, "SET @master_binlog_checksum= @@global.binlog_checksum");
|
|
rpl->server_id= 12;
|
|
rpl->start_position= 4;
|
|
rpl->flags= MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS;
|
|
|
|
if (mariadb_rpl_open(rpl))
|
|
return FAIL;
|
|
|
|
while((event= mariadb_rpl_fetch(rpl, event)) && event->event_type != HEARTBEAT_LOG_EVENT)
|
|
{
|
|
events++;
|
|
}
|
|
mariadb_free_rpl_event(event);
|
|
mariadb_rpl_close(rpl);
|
|
mysql_close(mysql);
|
|
return OK;
|
|
}
|
|
|
|
static int test_conc467(MYSQL *my __attribute__((unused)))
|
|
{
|
|
MYSQL *mysql= mysql_init(NULL);
|
|
MYSQL_RES *result;
|
|
MYSQL_ROW row;
|
|
MARIADB_RPL_EVENT *event= NULL;
|
|
MARIADB_RPL *rpl;
|
|
int rc;
|
|
|
|
SKIP_SKYSQL;
|
|
SKIP_MAXSCALE;
|
|
|
|
if (!is_mariadb)
|
|
return SKIP;
|
|
|
|
if (!my_test_connect(mysql, hostname, username,
|
|
password, schema, port, socketname, 0, 1))
|
|
{
|
|
diag("Error: %s", mysql_error(mysql));
|
|
mysql_close(mysql);
|
|
return FAIL;
|
|
}
|
|
|
|
rc= mysql_query(mysql, "SELECT @@log_bin");
|
|
check_mysql_rc(rc, mysql);
|
|
|
|
result= mysql_store_result(mysql);
|
|
row= mysql_fetch_row(result);
|
|
if (!atoi(row[0]))
|
|
rc= SKIP;
|
|
mysql_free_result(result);
|
|
|
|
if (rc == SKIP)
|
|
{
|
|
diag("binary log disabled -> skip");
|
|
mysql_close(mysql);
|
|
return SKIP;
|
|
}
|
|
|
|
/* Force to create a log rotate event */
|
|
rc= mysql_query(mysql, "FLUSH logs");
|
|
check_mysql_rc(rc, mysql);
|
|
|
|
rpl = mariadb_rpl_init(mysql);
|
|
|
|
mysql_query(mysql, "SET @mariadb_slave_capability=4");
|
|
mysql_query(mysql, "SET NAMES latin1");
|
|
mysql_query(mysql, "SET @slave_gtid_strict_mode=1");
|
|
mysql_query(mysql, "SET @slave_gtid_ignore_duplicates=1");
|
|
mysql_query(mysql, "SET NAMES utf8");
|
|
mysql_query(mysql, "SET @master_binlog_checksum= @@global.binlog_checksum");
|
|
rpl->server_id= 12;
|
|
rpl->start_position= 4;
|
|
rpl->flags= MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS;
|
|
|
|
if (mariadb_rpl_open(rpl))
|
|
return FAIL;
|
|
|
|
if (!(event= mariadb_rpl_fetch(rpl, event)))
|
|
rc= FAIL;
|
|
else
|
|
{
|
|
if (!rpl->filename)
|
|
{
|
|
diag("error: filename not set");
|
|
rc= FAIL;
|
|
}
|
|
else
|
|
diag("filename: %.*s", (int)rpl->filename_length, rpl->filename);
|
|
}
|
|
|
|
mariadb_free_rpl_event(event);
|
|
mariadb_rpl_close(rpl);
|
|
mysql_close(mysql);
|
|
return rc;
|
|
}
|
|
|
|
static int test_conc592(MYSQL *my __attribute__((unused)))
|
|
{
|
|
MARIADB_RPL *rpl;
|
|
MYSQL *mysql= mysql_init(NULL);
|
|
MYSQL *mysql_check= mysql_init(NULL);
|
|
const char *host= "myhost";
|
|
MYSQL_RES *result;
|
|
MYSQL_ROW row;
|
|
int rc;
|
|
int found= 0;
|
|
|
|
|
|
mysql_optionsv(mysql, MARIADB_OPT_RPL_REGISTER_REPLICA, host, 123);
|
|
|
|
SKIP_SKYSQL;
|
|
SKIP_MAXSCALE;
|
|
|
|
if (!is_mariadb)
|
|
return SKIP;
|
|
|
|
if (!my_test_connect(mysql, hostname, username,
|
|
password, schema, port, socketname, 0, 1))
|
|
{
|
|
diag("Error: %s", mysql_error(mysql));
|
|
mysql_close(mysql);
|
|
return FAIL;
|
|
}
|
|
|
|
if (!my_test_connect(mysql_check, hostname, username,
|
|
password, schema, port, socketname, 0, 1))
|
|
{
|
|
diag("Error: %s", mysql_error(mysql));
|
|
mysql_close(mysql);
|
|
return FAIL;
|
|
}
|
|
|
|
rc= mysql_query(mysql, "SELECT @@log_bin");
|
|
check_mysql_rc(rc, mysql);
|
|
|
|
result= mysql_store_result(mysql);
|
|
row= mysql_fetch_row(result);
|
|
if (!atoi(row[0]))
|
|
rc= SKIP;
|
|
mysql_free_result(result);
|
|
|
|
if (rc == SKIP)
|
|
{
|
|
diag("binary log disabled -> skip");
|
|
mysql_close(mysql);
|
|
return SKIP;
|
|
}
|
|
|
|
rpl = mariadb_rpl_init(mysql);
|
|
|
|
mysql_query(mysql, "SET @mariadb_slave_capability=4");
|
|
mysql_query(mysql, "SET NAMES latin1");
|
|
mysql_query(mysql, "SET @slave_gtid_strict_mode=1");
|
|
mysql_query(mysql, "SET @slave_gtid_ignore_duplicates=1");
|
|
mysql_query(mysql, "SET NAMES utf8");
|
|
mysql_query(mysql, "SET @master_binlog_checksum= @@global.binlog_checksum");
|
|
mysql_query(mysql, "SET @rpl_semi_sync_slave=1");
|
|
rpl->server_id= 12;
|
|
rpl->start_position= 4;
|
|
rpl->flags= MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS;
|
|
|
|
if (mariadb_rpl_open(rpl))
|
|
return FAIL;
|
|
|
|
rc= mysql_query(mysql_check, "SHOW SLAVE HOSTS");
|
|
check_mysql_rc(rc, mysql_check);
|
|
|
|
result= mysql_store_result(mysql_check);
|
|
|
|
while ((row= mysql_fetch_row(result)))
|
|
if (!strcmp(row[1], host))
|
|
found= 1;
|
|
|
|
mysql_free_result(result);
|
|
mysql_close(mysql);
|
|
mysql_close(mysql_check);
|
|
|
|
if (!found)
|
|
{
|
|
diag("Host '%s' not found in replica list", host);
|
|
return FAIL;
|
|
}
|
|
|
|
return OK;
|
|
}
|
|
|
|
static int test_conc689(MYSQL *my __attribute__((unused)))
|
|
{
|
|
MYSQL *mysql= mysql_init(NULL);
|
|
MYSQL_RES *result;
|
|
MYSQL_ROW row;
|
|
MARIADB_RPL_EVENT *event= NULL;
|
|
MARIADB_RPL *rpl;
|
|
int events= 0, rc;
|
|
|
|
SKIP_SKYSQL;
|
|
SKIP_MAXSCALE;
|
|
|
|
if (!is_mariadb)
|
|
return SKIP;
|
|
|
|
if (!my_test_connect(mysql, hostname, username,
|
|
password, schema, port, socketname, 0, 1))
|
|
{
|
|
diag("Error: %s", mysql_error(mysql));
|
|
mysql_close(mysql);
|
|
return FAIL;
|
|
}
|
|
|
|
rc= mysql_query(mysql, "SELECT @@log_bin");
|
|
check_mysql_rc(rc, mysql);
|
|
|
|
result= mysql_store_result(mysql);
|
|
row= mysql_fetch_row(result);
|
|
if (!atoi(row[0]))
|
|
rc= SKIP;
|
|
mysql_free_result(result);
|
|
|
|
if (rc == SKIP)
|
|
{
|
|
diag("binary log disabled -> skip");
|
|
mysql_close(mysql);
|
|
return SKIP;
|
|
}
|
|
|
|
rpl = mariadb_rpl_init(mysql);
|
|
|
|
mysql_query(mysql, "SET @mariadb_slave_capability=4");
|
|
mysql_query(mysql, "SET NAMES latin1");
|
|
mysql_query(mysql, "SET @slave_gtid_strict_mode=1");
|
|
mysql_query(mysql, "SET @master_heartbeat_period=10");
|
|
mysql_query(mysql, "SET @slave_gtid_ignore_duplicates=1");
|
|
mysql_query(mysql, "SET NAMES utf8");
|
|
mysql_query(mysql, "SET @master_binlog_checksum= @@global.binlog_checksum");
|
|
rpl->server_id= 12;
|
|
rpl->start_position= 4;
|
|
rpl->flags= MARIADB_RPL_BINLOG_SEND_ANNOTATE_ROWS;
|
|
|
|
if (mariadb_rpl_open(rpl))
|
|
return FAIL;
|
|
|
|
/* We run rpl_api as very last test, too make sure
|
|
binary log contains > 10000 events.
|
|
*/
|
|
while((event= mariadb_rpl_fetch(rpl, event)) && event->event_type != HEARTBEAT_LOG_EVENT)
|
|
{
|
|
events++;
|
|
}
|
|
FAIL_IF(event->event.heartbeat.filename.length == 0, "Invalid filename");
|
|
mariadb_free_rpl_event(event);
|
|
mariadb_rpl_close(rpl);
|
|
mysql_close(mysql);
|
|
return OK;
|
|
}
|
|
|
|
|
|
struct my_tests_st my_tests[] = {
|
|
{"test_conc689", test_conc689, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
|
{"test_conc592", test_conc592, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
|
{"test_rpl_async", test_rpl_async, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
|
{"test_rpl_semisync", test_rpl_semisync, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
|
{"test_conc467", test_conc467, TEST_CONNECTION_NEW, 0, NULL, NULL},
|
|
{NULL, NULL, 0, 0, NULL, NULL}
|
|
};
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
if (argc > 1)
|
|
get_options(argc, argv);
|
|
|
|
get_envvars();
|
|
|
|
run_tests(my_tests);
|
|
|
|
return(exit_status());
|
|
}
|