1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-10 01:02:57 +03:00
Commit Graph

253 Commits

Author SHA1 Message Date
Georg Richter
3590fe6e8b Merge branch '3.3' into 3.4 2024-11-27 16:17:12 +01:00
Georg Richter
bdc66d6b8f Fix for CONC-703:
If connect failed and no error was set (apparently this happens
sometimes on Mac) we now set error to CR_SERVER_LOST.
2024-11-27 07:48:27 +01:00
Georg Richter
000ed6281f Fix for CONC-740:
Moved the initialization of server verification callback from
mysql_init to mysql_real_connect to avoid memory leak in case
of a reconnect.
2024-11-05 12:51:51 +01:00
Georg Richter
53243b8a7a Follow up of d4a8ca9209
Last commit was incomplete
2024-10-23 13:08:42 +02:00
Georg Richter
a66f3fc302 Merge branch '3.3' into 3.4 2024-10-22 13:50:24 +02:00
Georg Richter
6635e4bdd6 Fix for CONC-735
If a reconnect occurs, we need to check if mysql->options.host was
already set and pass NULL instead of the previous host name.
2024-10-22 13:26:50 +02:00
Georg Richter
e7b6adfbf9 Simplify tls_verification_callback 2024-09-10 07:19:12 +02:00
Georg Richter
b481c0a494 CONC-724: Added TLS verification callback support
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);
2024-09-09 10:36:45 +02:00
Georg Richter
57f38cf87f Save the result of peer certificate verification
Since the MARIADB_TLS_VERIFY_TRUST flag might be cleared in my_auth,
we store the original result of peer certificate verification in
mysql->extension->tls_validation.
This value can be obtained via mariadb_get_infov API function
using option MARIADB_TLS_VERIFY_STATUS.
2024-08-31 07:53:46 +02:00
Georg Richter
1287c901dc TLS/SSL changes (major rework)
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.
2024-07-16 13:12:26 +02:00
Georg Richter
5386f1a3f2 Merge remote-tracking branch 'origin/3.3' into 3.4-tls 2024-06-25 11:57:27 +02:00
Georg Richter
71fa44cff0 CONC-698: certificate info is read on every connect
Part 1: Fix for OpenSSL and Schannel
2024-06-20 08:34:19 +02:00
Georg Richter
486ce75d64 CONPY-704: parse_connection_string ignores empty string in last parameter
1) Fix check if end was reached (<= instead of <), so last parameter will
not be ignored in case it is an empty string.

2) Empty strings will be passed as NULL`in _mariadb_set_conf_option.
2024-06-11 16:00:22 +02:00
Georg Richter
4623d104e8 Merge branch '3.3' into 3.4 2024-05-14 09:54:50 +02:00
Georg Richter
e69af190c3 Merge branch '3.1' into 3.3 2024-05-14 09:48:52 +02:00
Georg Richter
6bd5b6746f Follow up fix for CONC-696
According to next_thread_id() in mysqld.cc the
thread id is limited to 4 bytes. Thanks to Vlad
for pointing out
2024-05-14 09:45:51 +02:00
Georg Richter
f578e359e5 Merge branch '3.1' into 3.3 2024-05-13 16:09:47 +02:00
Georg Richter
d5394838fd CONC-696: Replace COM_PROCESS_KILL by KILL command
Since COM_PROCESS_KILL isn't supported by newer MySQL
versions.
2024-05-13 15:57:39 +02:00
Georg Richter
55fe56fa42 Fix for CONC-505:
Don't allow to specify unsupported client flags (like
CLIENT_DEPRECATE_EOF) as client flag in mysql_real_connect
api function.
2024-05-08 14:22:13 +02:00
Georg Richter
923a0092e3 Added missing support for restricted_auth in conf files 2024-05-08 11:45:14 +02:00
Georg Richter
3f47c15241 Added missing support for restricted_auth in conf files 2024-05-06 14:31:49 +02:00
Georg Richter
19dffea4dc CONC-692: Provide X509 peer certificate information
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);
2024-04-24 11:21:28 +02:00
rusher
abce07da2a [MDEV-30366] Bulk unitary result flag client implementation part.
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.
2024-03-06 16:03:55 +01:00
Georg Richter
ebe1949540 Fix for CONC-505:
Don't allow to specify unsupported client flags (like
CLIENT_DEPRECATE_EOF) as client flag in mysql_real_connect
api function.
2024-02-22 09:03:51 +01:00
Sergei Golubchik
f6e99af056 Revert "self-signed certificate verification", it's 3.4 feature
This reverts 395641549ac7..536d9e2b9e5b, in particular:

8dffd56936 MDEV-31857 enable MYSQL_OPT_SSL_VERIFY_SERVER_CERT by default
a99570c118 MDEV-31855 SSL cert validation protocol extension
9aa15e72a7 TLS fingerprint

and related commits
2024-02-19 11:16:26 +01:00
Sergei Golubchik
82983a30f4 make DEFAULT_SSL_VERIFY_SERVER_CERT a cmake option 2024-02-14 15:01:29 +01:00
Sergei Golubchik
8dffd56936 MDEV-31857 enable MYSQL_OPT_SSL_VERIFY_SERVER_CERT by default
because the default value of every option is 0
(option and option.extension are bzero-ed to reset),
tls_verify_server_cert was renamed to tls_allow_invalid_server_cert
with the default value of 0, "do not allow".

API didn't change, it's still MYSQL_OPT_SSL_VERIFY_SERVER_CERT
2024-02-04 22:17:25 +01:00
Sergei Golubchik
a99570c118 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
2024-02-04 22:17:25 +01:00
Sergei Golubchik
830d137387 don't use the output printf buffer as a %s parameter
followup for ebcb9eca29
2024-02-04 22:17:24 +01:00
Sergei Golubchik
77a2e6ac5d don't warn about the authenticity of client-side errors
they cannot be sent by the server (ma_net_safe_read() guarantees that)
so they all should be safe and not forged

also, use existing macros to check for error ranges, they are
sufficiently parenthesized to avoid compiler warnings (errors with -Werror)
about "you might want to add parentheses here"
2023-12-21 19:00:35 +01:00
Daniel Lenski
bd87353512 Remove unreachable code section
Based on Sergei Golubchik's question about this code section in
https://github.com/mariadb-corporation/mariadb-connector-c/pull/223#issuecomment-1773728383,
eventually culminating in the conclusion that it's literally impossible to
reach this code section based on the types and signedess of the variables
involved:
https://github.com/mariadb-corporation/mariadb-connector-c/pull/223#issuecomment-1854720364

All new code of the whole pull request, including one or several files
that are either new files or modified ones, are contributed under the
BSD-new license. I am contributing on behalf of my employer Amazon Web
Services, Inc.
2023-12-21 18:38:12 +01:00
Daniel Lenski
ebcb9eca29 [CONC-648] Do not trust error packets received prior to TLS handshake completion
MariaDB Connector/C does not distinguish [application-layer error
packets](https://mariadb.com/kb/en/err_packet) that it receives prior to TLS
handshake completion from those that it receives immediately after.

(A trivially modified server built from
https://github.com/dlenski/mariadb-server/commit/demonstration_of_CONC-648_vulnerability
can easily be used to demonstrate this.)

Pre-TLS error packet received from this trivially modified server. This packet
should NOT be trusted to actually originate from the server:

    $ mariadb --ssl --ssl-verify-server-cert -uUsername -pVerySecretPassword -h CONC-648.vuln.demo.server.com
    ERROR 1815 (HY000): Internal error: Client will accept this error as genuine even if running with --ssl --ssl-verify-server-cert, and even though this error is sent in plaintext PRIOR TO TLS HANDSHAKE.

Post-(TLS handshake) error packet received from a normal MariaDB server upon
an attempt to connect with incorrect credentials.  This error packet CAN be
trusted to actually originate from the server, assuming transitive trust in
the TLS protocol implementation and PKI-based certificate validation:

    $ mariadb --ssl --ssl-verify-server-cert -uUsername -pWrongPassword -h $NORMAL_MARIADB10.6.14_SERVER
    ERROR 1045 (28000): Access denied for user 'Username'@'A.B.C.D' (using password: YES)

This client behavior opens up MariaDB Connector/C clients to an extremely
straightforward [downgrade attack](https://en.wikipedia.org/wiki/Downgrade_attack).

An on-path or pervasive attacker can inject errors into MariaDB
client→server connections that are intended to be protected by TLS, and the
client has no clear mechanism to distinguish such errors from errors that
actually come from the server.

An attacker could easily use this to DOS a client, or even influence its
behavior.  For example, consider a client application which is configured…

1. To use TLS with server certificate validation
   (`--ssl --ssl-verify-server-cert`), and
2. To wait for a back-off period and then *retry* connection attempts if the server
   responds with `ER_CON_COUNT_ERROR` ("Too many connections") from the
   server, and
3. To give up and shut down if its connection attempts fail with
   `ER_ACCESS_DENIED_ERROR` ("Access denied for user"), on the assumption
   that this is due to an incorrect or expired password, and cannot be
   resolved without human intervention.

An attacker could completely disable the retry mechanism of this application
by intercepting connection attempts and replying with
`ER_ACCESS_DENIED_ERROR` packets.

This patch modifies MariaDB Connector/C so that if the client is configured
to use TLS, error packets received prior to the completion of the TLS
handshake are untrusted, and are changed to a generic `CR_CONNECTION_ERROR`.

    $ mariadb --ssl --ssl-verify-server-cert -uUsername -pVerySecretPassword -h CONC-648.vuln.demo.server.com
    ERROR 2002 (HY000): Received error packet before completion of TLS handshake. The authenticity of the following error cannot be verified:
    1815 - Internal error: Client will accept this error as genuine even if running with --ssl --ssl-verify-server-cert, and even though this error is sent in plaintext PRIOR TO TLS HANDSHAKE.

All new code of the whole pull request, including one or several files
that are either new files or modified ones, are contributed under the
BSD-new license. I am contributing on behalf of my employer Amazon Web
Services, Inc.
2023-12-21 18:38:12 +01:00
Daniel Lenski
4419abe71a Client should reject CLIENT-only error codes sent by the server
Per @vuvova in
https://github.com/mariadb-corporation/mariadb-connector-c/pull/223#issuecomment-1854720364:

> I don't think the client should accept client-side errors from the server
> at all.

If the server sends an error packet with error codes in the ranges
`CR_{MIN,MAX}_ERROR` (codes [2000, 2999]) or `CER_{MIN,MAX}_ERROR` (codes
[5000, 5999]), we will replace these with `CR_MALFORMED_PACKET`, rather than
propagating them to the client user.
2023-12-21 18:38:12 +01:00
Vladislav Vaintroub
463a50e973 Merge remote-tracking branch 'origin/3.1' into 3.3
# Conflicts:
#	include/ma_crypt.h
#	libmariadb/mariadb_lib.c
2023-09-21 23:45:35 +02:00
Georg Richter
9f37c27bc8 Fix for CONC-668:
Fix build error on 32-bit systems.
2023-09-18 16:05:00 +02:00
Georg Richter
3a255ee3ea Merge branch '3.1' into 3.3 2023-07-24 11:07:05 +02:00
Georg Richter
8ab517cbc1 Use OPT_SET_EXT_VALUE macro instead of assigning value
directly.
2023-07-13 10:58:15 +02:00
Georg Richter
45feebb99d 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.
2023-07-13 09:30:33 +02:00
Marko Mäkelä
5af90f00ff Merge 3.1 into 3.3 2023-06-26 16:28:51 +03:00
Marko Mäkelä
d543bed61b Fix GCC 13 -Wmaybe-uninitialized 2023-06-26 10:59:14 +03:00
Georg Richter
85b7bde184 Merge branch '3.1' into 3.3 2023-05-02 18:01:34 +02:00
Georg Richter
a3bba4639f CONC-619: NULL pointer dereference in unpack_fields
Fixed NULL pointer dereference, thanks to Yury Chaikou which
reported this issue.
2023-05-02 17:59:18 +02:00
Georg Richter
dd8962a4b5 Merge branch '3.1' into 3.3 2023-04-25 15:08:28 +02:00
Georg Richter
0e452f66ac MariaDB Server detection fix
Use mariadb_connection() instead of checking 5.5.5 rpl hack
to detect if we are connected to a MariaDB Server.
2023-04-21 07:11:29 +02:00
Georg Richter
2000b06183 Replace SET_CLIENT_STMT_ERROR by stmt_set_error(). 2023-04-11 18:31:19 +02:00
Georg Richter
e82ec9b027 Merge branch '3.1' into 3.3 2023-03-30 13:36:29 +02:00
Georg Richter
17d4f38403 Fix for CONC-642: Set CR_OUT_OF_MEMORY error
Set CR_OUT_OF_MEMORY error in mysql_use_result() api function
if allocation of memory failed.
2023-03-30 13:30:53 +02:00
Georg Richter
e4417e725e Merge branch '3.1' into 3.3 2023-02-09 08:57:48 +01:00
Georg Richter
75439c0f39 CONC-632
When resetting the connection with mysql reset_connection(), the
server_status must be checked and any other resultsets that mayi
exist must be removed.
2023-02-08 11:46:39 +01:00
Georg Richter
d204e83104 Return correct client library version number instead of
server number in mysql_get_client_versio
2023-01-16 14:14:59 +01:00