Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ find_package(MySQL REQUIRED)
find_package(ZLIB REQUIRED)
find_package(AWSSDK 1.11.774 EXACT REQUIRED COMPONENTS s3-crt)

# minimysql_server needs OpenSSL::SSL for boost::asio::ssl (server-side TLS
# listener). OpenSSL::Crypto is used by several other targets as well and
# was previously picked up transitively via AWS SDK; make the dependency
# explicit now that we also need the SSL half of OpenSSL.
find_package(OpenSSL REQUIRED)

# various utility files
set(util_source_files
src/util/bnf_parser_helpers.hpp
Expand Down Expand Up @@ -179,6 +185,17 @@ set(opensslpp_source_files
src/opensslpp/crypto_rng.hpp
src/opensslpp/crypto_rng.cpp

src/opensslpp/digest_context_fwd.hpp
src/opensslpp/digest_context.hpp
src/opensslpp/digest_context.cpp

src/opensslpp/rsa_private_key_fwd.hpp
src/opensslpp/rsa_private_key.hpp
src/opensslpp/rsa_private_key.cpp

src/opensslpp/ssl_context_helpers.hpp
src/opensslpp/ssl_context_helpers.cpp

src/opensslpp/core_error_fwd.hpp
src/opensslpp/core_error.hpp
src/opensslpp/core_error.cpp
Expand All @@ -187,7 +204,7 @@ add_library(lib_opensslpp STATIC ${opensslpp_source_files})
target_link_libraries(lib_opensslpp
PRIVATE
binlog_server_compiler_flags
Boost::headers OpenSSL::Crypto
Boost::headers OpenSSL::SSL OpenSSL::Crypto
)
# it is not possible to propagate CXX_EXTENSIONS and CXX_STANDARD_REQUIRED
# via interface library (binlog_server_compiler_flags)
Expand Down Expand Up @@ -591,6 +608,10 @@ set(binsrv_source_files
src/binsrv/main_config.hpp
src/binsrv/main_config.cpp

src/binsrv/pbs_listener_config_fwd.hpp
src/binsrv/pbs_listener_config.hpp
src/binsrv/pbs_listener_config.cpp

src/binsrv/replication_config_fwd.hpp
src/binsrv/replication_config.hpp
src/binsrv/replication_config.cpp
Expand Down Expand Up @@ -675,9 +696,11 @@ set(minimysql_source_files
src/minimysql/connection_context.cpp
src/minimysql/network_io_operations_fwd.hpp
src/minimysql/network_io_operations.hpp
src/minimysql/network_io_operations.cpp
src/minimysql/network_service.hpp
src/minimysql/network_service.cpp
src/minimysql/ssl_acceptor_context_fwd.hpp
src/minimysql/ssl_acceptor_context.hpp
src/minimysql/ssl_acceptor_context.cpp
src/minimysql/sample_event_collection.hpp
src/minimysql/sample_event_collection.cpp
)
Expand All @@ -701,6 +724,7 @@ target_link_libraries(binlog_server
binsrv::lib_opensslpp
Boost::headers Boost::json Boost::url Boost::asio
aws-cpp-sdk-s3-crt
OpenSSL::SSL
OpenSSL::Crypto
)
# it is not possible to propagate CXX_EXTENSIONS and CXX_STANDARD_REQUIRED
Expand Down
43 changes: 43 additions & 0 deletions mtr/binlog_streaming/include/generate_binsrv_config.inc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# --let $binsrv_encryption_cipher = AES-256-CTR (optional)
# --let $binsrv_encryption_kek_id = alpha (optional)
# --let $binsrv_keyring_data_file_path = $MYSQL_TMP_DIR/keyring_data.json (optional)
# --let $binsrv_pbs_listener_rsa_public_key_path = /path/to/pub.pem (optional)
# --let $binsrv_pbs_listener_rsa_private_key_path = /path/to/priv.pem (optional)
# --let $binsrv_pbs_listener_ssl_cert = /path/to/server-cert.pem (optional)
# --let $binsrv_pbs_listener_ssl_key = /path/to/server-key.pem (optional)
# --source set_up_binsrv_environment.inc

--echo
Expand Down Expand Up @@ -170,6 +174,45 @@ if ($binsrv_encryption_enabled)
);
}

# Optional 'pbs_listener' block (see binsrv/pbs_listener_config.hpp).
# The block carries two independent field pairs (RSA key pair for
# caching_sha2_password full auth, and TLS cert/key pair for the SSL
# listener); the block is emitted whenever at least one of the pairs is
# fully set, but ALL FOUR fields are always written - the pair that the
# caller did not set gets emitted as empty strings so nv_tuple_from_json
# always sees every declared field and pbs_listener_config::validate()
# sees the empty pair as "not configured" (which is fine per each pair's
# own "both-set-or-both-empty" invariant). Tests that don't set either
# pair get a plain plaintext-only, RSA-less listener config with no
# 'pbs_listener' block at all.
--let $binsrv_pbs_listener_needs_block = 0
if ($binsrv_pbs_listener_rsa_public_key_path != "")
{
if ($binsrv_pbs_listener_rsa_private_key_path != "")
{
--let $binsrv_pbs_listener_needs_block = 1
}
}
if ($binsrv_pbs_listener_ssl_cert != "")
{
if ($binsrv_pbs_listener_ssl_key != "")
{
--let $binsrv_pbs_listener_needs_block = 1
}
}
if ($binsrv_pbs_listener_needs_block)
{
eval SET @binsrv_config_json = JSON_INSERT(
@binsrv_config_json, '$.pbs_listener',
JSON_OBJECT(
'rsa_public_key_path', '$binsrv_pbs_listener_rsa_public_key_path',
'rsa_private_key_path', '$binsrv_pbs_listener_rsa_private_key_path',
'ssl_cert_path', '$binsrv_pbs_listener_ssl_cert',
'ssl_key_path', '$binsrv_pbs_listener_ssl_key'
)
);
}

--let $binsrv_config_file_path = $MYSQL_TMP_DIR/binsrv_config.json
--let $write_var = `SELECT @binsrv_config_json`
--let $write_to_file = $binsrv_config_file_path
Expand Down
4 changes: 4 additions & 0 deletions mtr/binlog_streaming/include/set_up_binsrv_environment.inc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
# --let $binsrv_encryption_cipher = AES-256-CTR (optional)
# --let $binsrv_encryption_kek_id = alpha (optional)
# --let $binsrv_keyring_data_file_path = $MYSQL_TMP_DIR/keyring_data.json (optional)
# --let $binsrv_pbs_listener_rsa_public_key_path = /path/to/pub.pem (optional)
# --let $binsrv_pbs_listener_rsa_private_key_path = /path/to/priv.pem (optional)
# --let $binsrv_pbs_listener_ssl_cert = /path/to/server-cert.pem (optional)
# --let $binsrv_pbs_listener_ssl_key = /path/to/server-key.pem (optional)
# --source set_up_binsrv_environment.inc

--source ../include/generate_binsrv_config.inc
Expand Down
10 changes: 7 additions & 3 deletions mtr/binlog_streaming/r/auth_method_switch.result
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,20 @@ include/read_file_to_var.inc
*** Control: client picks the same plugin the server advertises
*** (caching_sha2_password). No AuthMethodSwitch is expected on the
*** wire; a zero exit code from mysql confirms the session got as
*** far as running the probe query.
*** far as running the probe query. --get-server-public-key is
*** required because PBS has no digest cache and drives every
*** login through the 0x04 full-authentication branch (see
*** caching_sha2_full_auth.test for the full-auth path itself).

*** Trigger: client forces mysql_native_password in its handshake so
*** the Binlog Server has to send an AuthMethodSwitch, and the client
*** must recompute its response against a fresh caching_sha2_password
*** scramble. If the switch encoding, the follow-up parse, or the
*** re-verified fast-auth path is broken, mysql returns non-zero and
*** post-switch authentication is broken, mysql returns non-zero and
*** MTR fails the --exec. The log grep that follows the shutdown
*** is what actually proves the switch happened - this line only
*** proves the session survived it.
*** proves the session survived it. --get-server-public-key covers
*** the 0x04 that follows the switch (always-full-auth in PBS).

*** Sending SIGTERM to the Binlog Server Utility and waiting for the
*** process to terminate (poll kill -0 until the pid is gone).
Expand Down
67 changes: 67 additions & 0 deletions mtr/binlog_streaming/r/caching_sha2_full_auth.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
*** Resetting replication at the very beginning of the test.

*** Generating a configuration file in JSON format for the Binlog
*** Server utility.

*** Determining binlog file directory from the server.

*** Creating a temporary directory <BINSRV_STORAGE_PATH> for storing
*** binlog files downloaded via the Binlog Server utility.

*** Starting Binlog Server Utility in background in pull mode.
*** Because PBS has no digest cache, every login this binsrv
*** sees will be driven through the 0x04 full-auth branch.
*** stdout/stderr goes to a dedicated log so we can grep for auth
*** markers AFTER binsrv has exited.
include/read_file_to_var.inc

*** Waiting for the Binlog Server listener to come up on
*** 127.0.0.1:3307. We probe with bash's /dev/tcp instead of the
*** mysql client because bash is not ASAN-instrumented and
*** /dev/tcp uses a plain connect(2), so each attempt is cheap and
*** measures exactly the "listening on the port" state we care
*** about.

*** Scenario 1: correct password + --get-server-public-key. Server
*** sends 0x04 (PBS default), client requests the PEM
*** with 0x02, server enqueues the RSA public key, client OAEP-
*** encrypts the password and sends the ciphertext, server
*** rsa_private_key::decrypt_oaep recovers it and matches. A zero
*** exit code from mysql means the whole PEM + RSA round-trip
*** succeeded.

*** Scenario 2: correct password + --server-public-key-path pointing
*** at the PEM we wrote above. Server sends 0x04, client skips the
*** 0x02 PEM-fetch step and OAEP-encrypts the password directly with
*** the local key, server decrypts and matches. Confirms
*** rsa_private_key::decrypt_oaep and the ciphertext-length check
*** in the wrapper agree with what mysql's client-side OAEP produces
*** for this key.

*** Scenario 3: WRONG password + --get-server-public-key. Same full-
*** auth handshake as scenario 1, but the RSA-decrypted plaintext no
*** longer matches the configured password so
*** verify_encrypted_password() returns failed and the server issues
*** an access_denied. mysql exits non-zero, which we assert on to
*** confirm the rejection path is graceful (no crash, no hang).

*** Sending SIGTERM to the Binlog Server Utility and waiting for the
*** process to terminate (poll kill -0 until the pid is gone).
*** Graceful exit flushes std::cout, so any log line binsrv wrote
*** during its lifetime is now safely on disk.

*** Confirming end-to-end results by grepping the Binlog Server
*** stdout log (now complete and flushed):
*** - "client authentication succeeded for rpl" proves at least one
*** full-auth session round-tripped correctly (scenarios 1 & 2)
*** - "client authentication failed for rpl" proves the rejection
*** path fired for the wrong-password session (scenario 3)
include/wait_for_pattern_in_file.inc [client authentication succeeded for rpl]
include/wait_for_pattern_in_file.inc [client authentication failed for rpl]

*** Removing the Binlog Server utility storage directory.

*** Removing the Binlog Server utility log file.

*** Removing the Binlog Server utility configuration file.
KILL CONNECTION <CONNECTION_ID>;
66 changes: 66 additions & 0 deletions mtr/binlog_streaming/r/ssl_listener.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
*** Resetting replication at the very beginning of the test.

*** Generating a configuration file in JSON format for the Binlog
*** Server utility.

*** Determining binlog file directory from the server.

*** Creating a temporary directory <BINSRV_STORAGE_PATH> for storing
*** binlog files downloaded via the Binlog Server utility.

*** Starting Binlog Server Utility in background in pull mode with
*** TLS enabled on its MySQL-protocol listener (server cert / key
*** taken from MYSQL_TEST_DIR/std_data).
*** stdout/stderr goes to a dedicated log so we can grep for TLS and
*** auth markers AFTER binsrv has exited (see auth_method_switch
*** .test for why we defer log inspection until after graceful
*** shutdown).
include/read_file_to_var.inc

*** Waiting for the Binlog Server listener to come up on
*** 127.0.0.1:3307. We probe with bash's /dev/tcp instead of the
*** mysql client because bash is not ASAN-instrumented and
*** /dev/tcp uses a plain connect(2), so each attempt is cheap and
*** measures exactly the "listening on the port" state we care
*** about.

*** Scenario 1: TLS client. --ssl-mode=REQUIRED forces mysql to send
*** Protocol::SSLRequest first; the Binlog Server responds with a
*** TLS handshake, marks the transport secure, and then the
*** caching_sha2_password full-auth (0x04) branch takes the
*** cleartext-over-secure-transport path (verify_cleartext_password)
*** - no --get-server-public-key needed. A zero exit code from
*** mysql means the whole handshake + auth + probe round-trip
*** succeeded.

*** Scenario 2: non-TLS client on the same TLS-enabled listener.
*** --ssl-mode=DISABLED tells mysql to skip the TLS upgrade; the
*** session stays on plain TCP and full-auth (0x04) therefore
*** requires the RSA / PEM handshake (--get-server-public-key). A
*** zero exit code confirms TLS is per-session opt-in and does not
*** break plain-TCP clients (matches Percona Server behaviour with
*** require_secure_transport=OFF).

*** Sending SIGTERM to the Binlog Server Utility and waiting for the
*** process to terminate (poll kill -0 until the pid is gone).
*** Graceful exit flushes std::cout, so any log line binsrv wrote
*** during its lifetime is now safely on disk.

*** Confirming end-to-end results by grepping the Binlog Server
*** stdout log (now complete and flushed):
*** - "TLS handshake completed with" proves scenario 1 negotiated
*** the TLS upgrade successfully
*** - "(over TLS)" proves scenario 1's auth ran on the encrypted
*** transport (cleartext-over-0x04 branch), not RSA
*** - "(over plain TCP)" proves scenario 2 kept using plain TCP
*** and completed via the RSA / PEM full-auth branch
include/wait_for_pattern_in_file.inc [TLS handshake completed with]
include/wait_for_pattern_in_file.inc [client authentication succeeded for rpl \(over TLS\)]
include/wait_for_pattern_in_file.inc [client authentication succeeded for rpl \(over plain TCP\)]

*** Removing the Binlog Server utility storage directory.

*** Removing the Binlog Server utility log file.

*** Removing the Binlog Server utility configuration file.
KILL CONNECTION <CONNECTION_ID>;
51 changes: 51 additions & 0 deletions mtr/binlog_streaming/std_data/caching_sha2_full_auth_privkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAvV2VNbsQPG0Bh0KC8F4zCGXvMNcSicCiLXxeLWrJsmKZl0gg
f2ydymYUUewq+dVxDdh85sdSvxEmtIWvKSRK+RRCAURztq2Succd+24SF5IZYjlI
JE/U0AYUxHzUcOsannfzui60IaTHpcBFHTJK6myxGx9MORZmhfv580mfvz4yvgLj
S5yGOIS6rlxD9YV1Y04Rx3SXQQBnC7rDBL91ktNWvbclsonfytY19N9p+Gprms30
yRT+BmPFB7TqpReeZa3ivg15g/z3BLNyvj3YKiQM3cd7ENJC2x2LRxL5pG684cFN
StSjT4FvA+oh45UnU45aOSEjrxNkBG8ci0e+VKX539rK+nDzTE/MHpnvfHp4DB+k
SYBPuKHY2Eaw31NwPpfLWwEJPiDrktJJmRZqENMHLXksdiqGhvYmI33wZaZAfjbD
ZFMfPF5yBMBGDZ3aeNz5Le7uqS6g6XMOoiz/d2S5RzRrCol1yqCBPtODjfFPC4K8
GGYVkWZgSCf/PRt/DgDnZOfZSSYIQNeyr21emqgqQ+yhXEGKVjcDTKcbSLiWAdA+
GkAzLAXXhafM8mrhpnGKdO4Or6ySz7G1vk2Jt2ZSdP740oVSJi59P9NEgXcbd3c4
FzjXSOOsxfhPQfobUk3ikt55lN3fBX3mBvUduxNhAcQ02ZD5zXrX6+loiV8CAwEA
AQKCAgAfFO45zIOEt4uprOQbGgscVMbm6FZVn/W+q4w1vjJvAjodl6wl3ikkII8z
RyViroMI98DAjHTrgaAtv0eZ5CgeLBINbTPlByZvMdyc+Vsk3UknUymhNC1FG8pq
2eZwxlYvLpcltya/4vEWJrHxceDUC5UiU4fKUv/u/AXxxeLfnBDuGUE/luh8/GQ7
3E8XTJmQ/C5045E0DSHczgHWlKpyuBejuh0I6hJ+k5x1nfoh2S3iUe3c14I+gD/F
3Q8qm+7W16zA7ytD29Cbx+yMh1Ak0pf+CxELGMf6eSX0O4wYTkjYcUcDglVv5lnX
daWsWj4DO/lZKTRXN0KSa75uqg72Q1FjK//UNEigO99HYMsOWHBtaRzAwkklY5Da
5WHn3sxmfotlFDiyT30R/T0dpAjvgH18A235KOpgLnM7Kaxc3kjMmorIJrkD25oG
OmRRTvdZ5rQ+IuBzaGUOD4ZwTwQ9HMieMjjLCcmkhhzzIZni1eNMva7MJyws4qcH
tjOPQvtb8m8ZXzT77nnkKirbJLVk+FqzL93/w1Kp/BRgVVChrXhdDFW2KSI8sx7Z
T7J8Dir4Oz2JFgpuBLKTz2Bnu6EDNEdGmomP79DO2IGoPNwhhBRDNM2oYR2nPTME
0f9moTJBghsi6rutgxkf1KDY6z2oysJKoJowegEYaUh0J0aHqQKCAQEA8hEL2y5C
iq2fzLRulXEVLG4di6ZZ0ZcyuV6rwQRWrhqv//+csagNmvguz6mFF9iNciv8FT2Z
crIgJUPefslKXuqqm/zEhhafDBXypMHsk4yReIdlxQDkmnamoGJZRd3CSsNFm68a
52hkl3gniMprMp8wWyr2UNeahD9cgtooyua/hyaXewh57L9pJGHlLayvqEn6Rs0V
0lpSzMTJWqFrDPuSc+ufsd3sk1MfvdnDw5oh7cHjZhlHJVtPSrjneCTbEnNpXIr/
yGL+qamZD+a8a318KMz72y3RwA0VMkhhkAYFYV+S5qYrlbFxjacVOS0Zi0LOklrl
jGMj6RzcD2W35QKCAQEAyEP27OgVTkaEr3bmNHYMBqYZ2snYMUgJF5GOitfLGSGM
55Io++BO6NMDbcNyCtWu2RYbHfdF1qjlTxPHjqsy6z4+tpxjpnPQEbO5eN1PG3iZ
+YO6z1yXLMwglkK4Acv1YWkMZ6l2V55MyntdiCWG/UYOlVw1kxqxlhgzmyq1ZMj5
4IOGqjsjPsMs2ZVANE54y/SriocnM/2Z08440SElOtheu5G/PfTF2j3ZZRBvuggu
MVnl2+5c0PpT1DGS74327WhRWDixmgEPEgLTd9hSpCWN/5nj67zskHKv6pmOLS+I
jd+rpzrnqDallDmTm/DqcLLDuaxsxEV/788pRllf8wKCAQEAoxcfENZTGNIv9yCd
3OvqoxuxplQ28cJX95K0T4BX0kfCyszySrP6Lq4GA/2n4VASxJij57+v8hnXFKRs
dKm0BM1Ak4Yy9lCpaeAjsiPB/AtaO4Wl6JxYaUWFsEty8GKfs/VqoaDRlJW+KFtY
743JubqNPu9sMz2AKpfyAWtwznu3ERzMNKWaWAsCkPOwEBzn4I+vIyKsECSw4qu3
KevVj1Kz8owO9SybZws7OJNOlSv0rhbS2ggv6hhiDOsVcNoMC5tconA4M0+XWsIc
kR0ZV6adD3REQADX7/ggjtc7fGjCGT/mXqYYeWurIRAweWxMaIpjWTIKtJJbMIU0
Mt+KjQKCAQAbtzw/QUdhk+TdG8l0TToQ2YAOhYzEFUIc3uopUQAstDX5/oJpiXui
QUHiOQBZe4U9Sg/qr8QclzdVIFmn5w2e/PhU8YPhD3omWQc8MPS3ypMUsyRxelD5
xC5mXUl2BjIpjw5Gcm+MZL4f777cDsWF2+I8zYwklbcqHKNXwCtmjWH3rnw+pvyT
vRNB8aP3GT0ijPQIsfe8/EYDyDCY0MuEP1ms/9jFzFBtic3CbOnphyRNdDGZpH13
9o0PeuTo/m7EIIHRgdcihy78wSNfHLMjQIdMbpHamETtINIz15iTrFZrvB7XgBF7
eESmJOnG1Sq8+iCYW8KZzzyLhdIiiE/9AoIBAQDGZG7/r8feIMKUWGJmm+uWDAEi
FRn0gZap3HZRDkmgYE6Xwr6CwUBp1YWvjQGQdln9BSrc6kXazOQrX+wpaNmW5x90
EMinO3Ekg+c5ivYgw1IxN26bbOnlDUpeUDH2mp4OV9MhMmPB6EfRWbztflK7545j
SJ0sOADajDCq5WeR3IyXT9Pq99wZ1BI4qw/MD7HUzx38n7G3qa/BOQcdyETN1L1l
BZgRlbpzktD2AjX71p8FaVfeRA2R4/BWPAzBEhGdLgitXL1UVZDC/TzZBKwQcwpG
JvKExITQBoOQmIOPbEYoLZ7UAiiOmCi/QlOjswP94gTKW4YHEqu6dqMHaaw+
-----END RSA PRIVATE KEY-----
14 changes: 14 additions & 0 deletions mtr/binlog_streaming/std_data/caching_sha2_full_auth_pubkey.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvV2VNbsQPG0Bh0KC8F4z
CGXvMNcSicCiLXxeLWrJsmKZl0ggf2ydymYUUewq+dVxDdh85sdSvxEmtIWvKSRK
+RRCAURztq2Succd+24SF5IZYjlIJE/U0AYUxHzUcOsannfzui60IaTHpcBFHTJK
6myxGx9MORZmhfv580mfvz4yvgLjS5yGOIS6rlxD9YV1Y04Rx3SXQQBnC7rDBL91
ktNWvbclsonfytY19N9p+Gprms30yRT+BmPFB7TqpReeZa3ivg15g/z3BLNyvj3Y
KiQM3cd7ENJC2x2LRxL5pG684cFNStSjT4FvA+oh45UnU45aOSEjrxNkBG8ci0e+
VKX539rK+nDzTE/MHpnvfHp4DB+kSYBPuKHY2Eaw31NwPpfLWwEJPiDrktJJmRZq
ENMHLXksdiqGhvYmI33wZaZAfjbDZFMfPF5yBMBGDZ3aeNz5Le7uqS6g6XMOoiz/
d2S5RzRrCol1yqCBPtODjfFPC4K8GGYVkWZgSCf/PRt/DgDnZOfZSSYIQNeyr21e
mqgqQ+yhXEGKVjcDTKcbSLiWAdA+GkAzLAXXhafM8mrhpnGKdO4Or6ySz7G1vk2J
t2ZSdP740oVSJi59P9NEgXcbd3c4FzjXSOOsxfhPQfobUk3ikt55lN3fBX3mBvUd
uxNhAcQ02ZD5zXrX6+loiV8CAwEAAQ==
-----END PUBLIC KEY-----
Loading
Loading