For testing purposes (the python3 dummy server can't handle
further communication after TLS handshake succeeded) support
for verification callback was added.
my_bool callback(MYSQL *mysql, unsigned int *flags, my_bool verified)
Parameter:
- mysql connection handle for current connection
- flags verification flags
- verified true if callback was called after verification,
otherwise false
Return value:
- False (0) to continue
- True (1) to abort tls connection
The callback function can be registered via
mysql_optionsv(mysql, MARIADB_OPT_TLS_VERIFICATION_CALLBACK, callback);
* fix comments
* reorder errors to put hard errors on top
* report errors from openssl
* don't overwrite errors in C/C
* pass correct flags to gnutls_x509_crt_check_hostname2()
* use the same define name everywhere consistently
* don't recalculate fingerprint in openssl unnecessary
* misc
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.
Added a new structure MARIADB_X509_INFO, which
contains information about servers certificate.
The information can be obtained via mysql_get_infov API
function:
MARIADB_X509_INFO *info;
mariadb_get_infov(mysql, MARIADB_TLS_PEER_CERT_INFO, &info);
With MDEV-30366, server now permit to send a result-set containing generated id and Affected rows for each bulk operation. This feature can be enabled with option MARIADB_OPT_BULK_UNIT_RESULTS when server supports it.
- All (MariaDB and MySQL) events are now supported
- Added new api functions:
- mariadb_rpl_error: returns error message
- mariadb_rpl_errno: returns error number
- mariadb_rpl_extract_rows: extract values of
ROW_EVENTS
- Added decryption support
- Added uncompression
-
This feature allows client applications to register a callback function,
which is called as soon as the server status changes or session_track
information was sent by the server.
Registration is handled via mysql_optionsv() API function:
mysql_optionsv(mysql, MARIADB_OPT_STATUS_CALLBACK, function, data)
The callback function must be defined as follws:
void status_callback(void *data, enum enum_mariadb_status_info type, ..)
Parameters:
- data Pointer passed with registration of callback function
(usually a connection handle)
- type Information type STATUS_TYPE or SESSION_TRACK_TYPE
Variadic Parameters:
if (type == STATUS_TYPE):
- server status (unsigned int)
if (type == SESSION_TRACK_TYPE)
- enum enum_session_state_type track_type - session track type
if (track_type == SESSION_TRACK_SYSTEM_VARIABLES)
- MARIADB_CONST_STRING *key
- MARIADB_CONST_STRING *value
else
- MARIADB_CONST_STRING *value
An example can be found in connection.c (test_status_callback)
Added new option MARIADB_OPT_RPL_REGISTER_REPLICA which expects
two parameters, host and port. When this option was set, rpl_open
will send a COM_REGISTER_SLAVE command with server_id, host and
port to the connected server. This information can be retrieved
by "SHOW SLAVE STATUS" command.
Example:
rc= mysql_optionsv(mysql, MARIADB_OPT_RPL_REGISTER_REPLICA,
"myhost", 123);
Added new options MARIADB_CONNECTION_BYTES_READ and
MARIADB_CONNECTION_BYTES_SENT which can be passed to
mariadb_get_infov() api funcion to obtain the bytes sent
or read to/from database server.
A connection string contains key/value pairs, separated by a semicolon
as used in ODBC. Supported keys are all configuration options which can
be used in MariaDB configuration files. For a complete list check
https://github.com/mariadb-corporation/mariadb-connector-c/wiki/config_files#configuration-options.
The connection string must contain at least one semicolon, otherwise
it wil be interpreted as hostname. Unknown or invalid keys will be ignored.
To connect via connection string, the following methods might be used:
- by specifing connection option in configuration file:
connection=host=localhost;ssl_enforce=1;
- by using mariadb_connect() macro
mariadb_connect(mysql, "host=localhost;ssl_enforce=1")
- by passing connection string in host parameter to mysql_real_connect
mysql_real_connect(mysql, "host=localhost;ssl_enforce=1", NULL, NULL, NULL, 0, NULL, 0)
Added new option MARIADB_OPT_RESTRICTED_AUTH (and corresponding
"restricted-auth" option for configuration files) which specifies
on or more comma spearated authentication plugins which are allowed
for authenication.
If the server asks for an authentication plugin not listed in this
option the connect attempt will fail with error CR_PLUGIN_NOT_ALLOWED.
- removed unused methods from MYSQL_STMT handle,
(left over from PHP's mysqlnd)
- Added execute_generate_request method: This will allow
Connector/Python to prefill the execute buffer without
numerous GIL acquire/release calls.
Added a new option MARIADB_OPT_SKIP_READ_RESPONSE which skips automatic
reading of server response after sending a command to the server.
Server packets have to be retrieved by calling the corresponding methods,
e.g:
Send command Read method
mysql_real_query/mysql_send_query db_read_query_result
mysql_stmt_prepare db_read_prepare_response
mysql_stmt_execute,
mariadb_stmt_execute_direct db_read_execute_response
Projects compiled with -Wstrict-prototypes will emit a warning. C
requires that functions with arguments be prototyped as foo(void), not
foo(). This commit fixes the warning.
At irregular intervals older windows versions (prior Windows 10) fail to establish a secure (TLS)
connection and return errors SEC_E_INVALID_TOKEN, SEC_E_BUFFER_TOO_SMALL or SEC_E_MESSAGE_ALTERED.
This is a bug in windows schannel library and was only fixed in recent versions, also OpenSSL provided
a workaround (see https://github.com/openssl/openssl/pull/1350).
Since we are unable to fix this, we introduced a workaround for this problem. In case of an error
during TLS handshake we check the errorcode and try to reconnect up to three times if the error code
was SEC_E_INVALID_TOKEN, SEC_E_BUFFER_TOO_SMALL or SEC_E_MESSAGE_ALTERED.
- STDCALL is ignored for variable argument functions.
- __attribute__ does work for Clang (also if that pretends to be MSVC)
- remove unused function
- simplify ma_getopt, fixes some strange compile error in clang (about
SSE intrinsics)
- fix some clang warnings
Client part of MDEV-14101: Add support for tls-version, via
mysql_options(mysql, MARIADB_OPT_TLS_VERSION, value)
Accepted values are "TLSv1.1", "TLSv1.2" and "TLSv1.3".
Fixed testcase openssl_1 for schannel