diff --git a/mysql-test/r/ssl-sha512.result b/mysql-test/r/ssl-sha512.result index 8ff1be9..d2d42cf 100644 --- a/mysql-test/r/ssl-sha512.result +++ b/mysql-test/r/ssl-sha512.result @@ -5,6 +5,7 @@ Warning 1287 Using GRANT statement to modify existing user's properties other th Variable_name Value have_openssl YES have_ssl YES +ssl ON ssl_ca MYSQL_TEST_DIR/std_data/ca-sha512.pem ssl_capath ssl_cert MYSQL_TEST_DIR/std_data/server-cert-sha512.pem diff --git a/mysql-test/r/ssl_crl.result b/mysql-test/r/ssl_crl.result index 08b47ec..0ec55cf 100644 --- a/mysql-test/r/ssl_crl.result +++ b/mysql-test/r/ssl_crl.result @@ -2,6 +2,7 @@ Variable_name Value have_openssl YES have_ssl YES +ssl ON ssl_ca MYSQL_TEST_DIR/std_data/crl-ca-cert.pem ssl_capath ssl_cert MYSQL_TEST_DIR/std_data/crl-server-cert.pem @@ -13,6 +14,7 @@ ssl_key MYSQL_TEST_DIR/std_data/crl-server-key.pem Variable_name Value have_openssl YES have_ssl YES +ssl ON ssl_ca MYSQL_TEST_DIR/std_data/crl-ca-cert.pem ssl_capath ssl_cert MYSQL_TEST_DIR/std_data/crl-server-cert.pem diff --git a/mysql-test/r/ssl_crl_clients_valid.result b/mysql-test/r/ssl_crl_clients_valid.result index 45097ab..0b30622 100644 --- a/mysql-test/r/ssl_crl_clients_valid.result +++ b/mysql-test/r/ssl_crl_clients_valid.result @@ -4,6 +4,7 @@ Variable_name Value have_openssl YES have_ssl YES +ssl ON ssl_ca MYSQL_TEST_DIR/std_data/crl-ca-cert.pem ssl_capath ssl_cert MYSQL_TEST_DIR/std_data/crl-client-cert.pem diff --git a/mysql-test/r/ssl_crl_crlpath.result b/mysql-test/r/ssl_crl_crlpath.result index b4b4d13..f6e4ab8 100644 --- a/mysql-test/r/ssl_crl_crlpath.result +++ b/mysql-test/r/ssl_crl_crlpath.result @@ -2,6 +2,7 @@ Variable_name Value have_openssl YES have_ssl YES +ssl ON ssl_ca MYSQL_TEST_DIR/std_data/crl-ca-cert.pem ssl_capath ssl_cert MYSQL_TEST_DIR/std_data/crl-server-cert.pem @@ -13,6 +14,7 @@ ssl_key MYSQL_TEST_DIR/std_data/crl-server-key.pem Variable_name Value have_openssl YES have_ssl YES +ssl ON ssl_ca MYSQL_TEST_DIR/std_data/crl-ca-cert.pem ssl_capath ssl_cert MYSQL_TEST_DIR/std_data/crl-server-cert.pem diff --git a/mysql-test/r/ssl_reload.result b/mysql-test/r/ssl_reload.result new file mode 100644 index 0000000..0f9a25c --- /dev/null +++ b/mysql-test/r/ssl_reload.result @@ -0,0 +1,7 @@ +set @@global.ssl = on; +1 +1 +set @@global.ssl = on; +set @@global.ssl = on; +1 +1 diff --git a/mysql-test/r/ssl_session_reuse.result b/mysql-test/r/ssl_session_reuse.result index fb70ec9..c87312f 100644 --- a/mysql-test/r/ssl_session_reuse.result +++ b/mysql-test/r/ssl_session_reuse.result @@ -1,7 +1,11 @@ # test ssl session reuse Variable_name Value +ssl ON +Variable_name Value Ssl_sessions_reused 0 Variable_name Value +ssl ON +Variable_name Value Ssl_sessions_reused 1 Variable_name Value Ssl_session_cache_hits 2 diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index f4d793f..5fc7d3c 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -951,6 +951,7 @@ select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key; # # # # # show variables like 'ssl%'; Variable_name Value +ssl # ssl_ca # ssl_capath # ssl_cert # @@ -960,6 +961,7 @@ ssl_crlpath # ssl_key # select * from performance_schema.session_variables where variable_name like 'ssl%' order by 1; VARIABLE_NAME VARIABLE_VALUE +ssl # ssl_ca # ssl_capath # ssl_cert # diff --git a/mysql-test/suite/auth_sec/r/openssl_cert_generation.result b/mysql-test/suite/auth_sec/r/openssl_cert_generation.result index a701921..973a8b6 100644 --- a/mysql-test/suite/auth_sec/r/openssl_cert_generation.result +++ b/mysql-test/suite/auth_sec/r/openssl_cert_generation.result @@ -70,6 +70,7 @@ Pattern "Skipping generation of RSA key pair" found # auto_generate_certs, ssl_ca, ssl_cert and ssl_key should be set. show variables like 'ssl%'; Variable_name Value +ssl ON ssl_ca ca.pem ssl_capath ssl_cert server-cert.pem @@ -112,6 +113,7 @@ Pattern "Auto generated RSA key files through --sha256_password_auto_generate_rs # auto_generate_certs, ssl_ca, ssl_cert and ssl_key should be set. show variables like 'ssl%'; Variable_name Value +ssl ON ssl_ca ca.pem ssl_capath ssl_cert server-cert.pem @@ -156,6 +158,7 @@ Pattern "Auto generated RSA key files through --sha256_password_auto_generate_rs # No ssl variables should be set show variables like 'ssl%'; Variable_name Value +ssl OFF ssl_ca ssl_capath ssl_cert diff --git a/mysql-test/suite/sys_vars/r/ssl_basic.result b/mysql-test/suite/sys_vars/r/ssl_basic.result new file mode 100644 index 0000000..ef95e1a --- /dev/null +++ b/mysql-test/suite/sys_vars/r/ssl_basic.result @@ -0,0 +1,43 @@ +SET @start_value = @@global.ssl; +SELECT @start_value; +@start_value +1 +SET @@global.ssl = 1; +SET @@global.ssl = on; +SET @@global.ssl = true; +SET @@global.ssl = 2; +ERROR 42000: Variable 'ssl' can't be set to the value of '2' +SET @@global.ssl = -1; +ERROR 42000: Variable 'ssl' can't be set to the value of '-1' +SET @@global.ssl = TRUEF; +ERROR 42000: Variable 'ssl' can't be set to the value of 'TRUEF' +SET @@global.ssl = TRUE_F; +ERROR 42000: Variable 'ssl' can't be set to the value of 'TRUE_F' +SET @@global.ssl = FALSE0; +ERROR 42000: Variable 'ssl' can't be set to the value of 'FALSE0' +SET @@global.ssl = OON; +ERROR 42000: Variable 'ssl' can't be set to the value of 'OON' +SET @@global.ssl = ONN; +ERROR 42000: Variable 'ssl' can't be set to the value of 'ONN' +SET @@global.ssl = OOFF; +ERROR 42000: Variable 'ssl' can't be set to the value of 'OOFF' +SET @@global.ssl = 0FF; +ERROR 42000: Variable 'ssl' can't be set to the value of '0FF' +SET @@global.ssl = ' '; +ERROR 42000: Variable 'ssl' can't be set to the value of ' ' +SET @@global.ssl = " "; +ERROR 42000: Variable 'ssl' can't be set to the value of ' ' +SET @@global.ssl = ''; +ERROR 42000: Variable 'ssl' can't be set to the value of '' +SET @@session.ssl = 1; +ERROR HY000: Variable 'ssl' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.ssl; +ERROR HY000: Variable 'ssl' is a GLOBAL variable +SET global.ssl = 1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'global.ssl = 1' at line 1 +SELECT global.ssl; +ERROR 42S02: Unknown table 'global' in field list +SET @@global.ssl = @start_value; +SELECT @@global.ssl; +@@global.ssl +1 diff --git a/mysql-test/suite/sys_vars/t/ssl_basic.test b/mysql-test/suite/sys_vars/t/ssl_basic.test new file mode 100644 index 0000000..21561d6 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/ssl_basic.test @@ -0,0 +1,51 @@ +--source include/load_sysvars.inc +--source include/have_openssl.inc + +# Store the global value in a temp variable. +SET @start_value = @@global.ssl; +SELECT @start_value; + +SET @@global.ssl = 1; +SET @@global.ssl = on; +SET @@global.ssl = true; + +# Illegal values for @@global.ssl. +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = 2; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = -1; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = TRUEF; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = TRUE_F; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = FALSE0; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = OON; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = ONN; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = OOFF; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = 0FF; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = ' '; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = " "; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@global.ssl = ''; + +# ssl is a global variable. +--Error ER_GLOBAL_VARIABLE +SET @@session.ssl = 1; +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.ssl; + +--Error ER_PARSE_ERROR +SET global.ssl = 1; +--Error ER_UNKNOWN_TABLE +SELECT global.ssl; + +# Restore the initial value. +SET @@global.ssl = @start_value; +SELECT @@global.ssl; diff --git a/mysql-test/t/ssl_reload.test b/mysql-test/t/ssl_reload.test new file mode 100644 index 0000000..3ca2b20 --- /dev/null +++ b/mysql-test/t/ssl_reload.test @@ -0,0 +1,42 @@ +--copy_file $MYSQL_TEST_DIR/std_data/cacert.pem $MYSQL_TMP_DIR/cacert.pem +--copy_file $MYSQL_TEST_DIR/std_data/server-cert.pem $MYSQL_TMP_DIR/server-cert.pem +--copy_file $MYSQL_TEST_DIR/std_data/server-key.pem $MYSQL_TMP_DIR/server-key.pem + +let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; +--exec echo "wait" > $restart_file +--shutdown_server +--source include/wait_until_disconnected.inc +--exec echo "restart:--ssl-ca=$MYSQL_TMP_DIR/cacert.pem --ssl-cert=$MYSQL_TMP_DIR/server-cert.pem --ssl-key=$MYSQL_TMP_DIR/server-key.pem" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +# This should succeed. +set @@global.ssl = on; +--exec $MYSQL --ssl-mode=VERIFY_IDENTITY --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem test -e "select 1" + +--remove_file $MYSQL_TMP_DIR/cacert.pem +--remove_file $MYSQL_TMP_DIR/server-cert.pem +--remove_file $MYSQL_TMP_DIR/server-key.pem +--copy_file $MYSQL_TEST_DIR/std_data/expired-ca.pem $MYSQL_TMP_DIR/cacert.pem +--copy_file $MYSQL_TEST_DIR/std_data/expired-server-cert.pem $MYSQL_TMP_DIR/server-cert.pem +--copy_file $MYSQL_TEST_DIR/std_data/expired-server-key.pem $MYSQL_TMP_DIR/server-key.pem +set @@global.ssl = on; + +# This should fail because of reloaded certs. +--error 1 +--exec $MYSQL --ssl-mode=VERIFY_IDENTITY --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem test -e "select 1" + +--remove_file $MYSQL_TMP_DIR/cacert.pem +--remove_file $MYSQL_TMP_DIR/server-cert.pem +--remove_file $MYSQL_TMP_DIR/server-key.pem +--copy_file $MYSQL_TEST_DIR/std_data/cacert.pem $MYSQL_TMP_DIR/cacert.pem +--copy_file $MYSQL_TEST_DIR/std_data/server-cert.pem $MYSQL_TMP_DIR/server-cert.pem +--copy_file $MYSQL_TEST_DIR/std_data/server-key.pem $MYSQL_TMP_DIR/server-key.pem + +# This should succeed. +set @@global.ssl = on; +--exec $MYSQL --ssl-mode=VERIFY_IDENTITY --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem test -e "select 1" + +--remove_file $MYSQL_TMP_DIR/cacert.pem +--remove_file $MYSQL_TMP_DIR/server-cert.pem +--remove_file $MYSQL_TMP_DIR/server-key.pem diff --git a/sql/auth/sql_auth_cache.cc b/sql/auth/sql_auth_cache.cc index 0300ee9..b92c795 100644 --- a/sql/auth/sql_auth_cache.cc +++ b/sql/auth/sql_auth_cache.cc @@ -1503,6 +1503,7 @@ validate_user_plugin_records() acl_user->host.get_host()); } } + mysql_rwlock_rdlock(&LOCK_use_ssl); if (acl_user->plugin.str == sha256_password_plugin_name.str && sha256_rsa_auth_status() && !ssl_acceptor_fd) { @@ -1518,6 +1519,7 @@ validate_user_plugin_records() static_cast(acl_user->host.get_host_len()), acl_user->host.get_host(), missing); } + mysql_rwlock_unlock(&LOCK_use_ssl); } } unlock_plugin_data(); diff --git a/sql/auth/sql_authentication.cc b/sql/auth/sql_authentication.cc index 99c8135..cd3a2a4 100644 --- a/sql/auth/sql_authentication.cc +++ b/sql/auth/sql_authentication.cc @@ -732,11 +732,13 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, protocol->add_client_capability(CAN_CLIENT_COMPRESS); + mysql_rwlock_rdlock(&LOCK_use_ssl); if (ssl_acceptor_fd) { protocol->add_client_capability(CLIENT_SSL); protocol->add_client_capability(CLIENT_SSL_VERIFY_SERVER_CERT); } + mysql_rwlock_unlock(&LOCK_use_ssl); if (data_len) { @@ -1669,16 +1671,22 @@ skip_to_ssl: #endif /* Do the SSL layering. */ + mysql_rwlock_rdlock(&LOCK_use_ssl); if (!ssl_acceptor_fd) + { + mysql_rwlock_unlock(&LOCK_use_ssl); return packet_error; + } DBUG_PRINT("info", ("IO layer change in progress...")); if (sslaccept(ssl_acceptor_fd, protocol->get_vio(), timeout_to_seconds(protocol->get_net()->read_timeout), &errptr)) { DBUG_PRINT("error", ("Failed to accept new SSL connection")); + mysql_rwlock_unlock(&LOCK_use_ssl); return packet_error; } + mysql_rwlock_unlock(&LOCK_use_ssl); DBUG_PRINT("info", ("Reading user information over SSL layer")); int rc= protocol->read_packet(); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4f30248..feedb39 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -730,6 +730,7 @@ static PSI_mutex_key key_BINLOG_LOCK_binlog_end_pos; static PSI_mutex_key key_BINLOG_LOCK_sync; static PSI_mutex_key key_BINLOG_LOCK_sync_queue; static PSI_mutex_key key_BINLOG_LOCK_xids; +static PSI_rwlock_key key_rwlock_LOCK_use_ssl; static PSI_rwlock_key key_rwlock_global_sid_lock; static PSI_rwlock_key key_rwlock_gtid_mode_lock; static PSI_rwlock_key key_rwlock_LOCK_system_variables_hash; @@ -1208,6 +1209,7 @@ mysql_mutex_t LOCK_sql_slave_skip_counter; mysql_mutex_t LOCK_slave_net_timeout; mysql_mutex_t LOCK_log_throttle_qni; mysql_mutex_t LOCK_offline_mode; +mysql_rwlock_t LOCK_use_ssl; mysql_rwlock_t LOCK_sys_init_connect, LOCK_sys_init_slave; mysql_rwlock_t LOCK_system_variables_hash; my_thread_handle signal_thread_id; @@ -2235,6 +2237,7 @@ static void clean_up_mutexes() mysql_mutex_destroy(&LOCK_status); mysql_mutex_destroy(&LOCK_manager); mysql_mutex_destroy(&LOCK_crypt); + mysql_rwlock_destroy(&LOCK_use_ssl); mysql_mutex_destroy(&LOCK_user_conn); mysql_rwlock_destroy(&LOCK_sys_init_connect); mysql_rwlock_destroy(&LOCK_sys_init_slave); @@ -4130,6 +4133,7 @@ static int init_thread_environment() mysql_mutex_init(key_LOCK_user_conn, &LOCK_user_conn, MY_MUTEX_INIT_FAST); mysql_mutex_init(key_LOCK_global_system_variables, &LOCK_global_system_variables, MY_MUTEX_INIT_FAST); + mysql_rwlock_init(key_rwlock_LOCK_use_ssl, &LOCK_use_ssl); mysql_rwlock_init(key_rwlock_LOCK_system_variables_hash, &LOCK_system_variables_hash); mysql_mutex_init(key_LOCK_prepared_stmt_count, @@ -4413,6 +4417,7 @@ static int init_ssl_communication() static void end_ssl() { #ifdef HAVE_OPENSSL + mysql_rwlock_rdlock(&LOCK_use_ssl); if (ssl_acceptor_fd) { if (ssl_acceptor) @@ -4420,6 +4425,7 @@ static void end_ssl() free_vio_ssl_fd(ssl_acceptor_fd); ssl_acceptor_fd= 0; } + mysql_rwlock_unlock(&LOCK_use_ssl); deinit_rsa_keys(); #endif /* HAVE_OPENSSL */ } @@ -7532,12 +7538,6 @@ struct my_option my_long_options[]= &opt_sporadic_binlog_dump_fail, &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef HAVE_OPENSSL - {"ssl", 0, - "Enable SSL for connection (automatically enabled with other flags).", - &opt_use_ssl, &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 1, 0, 0, - 0, 0, 0}, -#endif #ifdef _WIN32 {"standalone", 0, "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG, @@ -8071,8 +8071,10 @@ static int show_ssl_ctx_sess_accept(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8080,8 +8082,10 @@ static int show_ssl_ctx_sess_accept_good(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8089,8 +8093,10 @@ static int show_ssl_ctx_sess_connect_good(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8098,8 +8104,10 @@ static int show_ssl_ctx_sess_accept_renegotiate(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8107,8 +8115,10 @@ static int show_ssl_ctx_sess_connect_renegotiate(THD*, SHOW_VAR *var, char *buff { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8116,8 +8126,10 @@ static int show_ssl_ctx_sess_cb_hits(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8125,8 +8137,10 @@ static int show_ssl_ctx_sess_hits(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8134,8 +8148,10 @@ static int show_ssl_ctx_sess_cache_full(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8143,8 +8159,10 @@ static int show_ssl_ctx_sess_misses(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8152,8 +8170,10 @@ static int show_ssl_ctx_sess_timeouts(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8161,8 +8181,10 @@ static int show_ssl_ctx_sess_number(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8170,8 +8192,10 @@ static int show_ssl_ctx_sess_connect(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8179,8 +8203,10 @@ static int show_ssl_ctx_sess_get_cache_size(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8188,8 +8214,10 @@ static int show_ssl_ctx_get_verify_mode(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8197,14 +8225,17 @@ static int show_ssl_ctx_get_verify_depth(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_LONG; var->value= buff; + mysql_rwlock_rdlock(&LOCK_use_ssl); *((long *)buff)= (!ssl_acceptor_fd ? 0 : SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context)); + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } static int show_ssl_ctx_get_session_cache_mode(THD*, SHOW_VAR *var, char*) { var->type= SHOW_CHAR; + mysql_rwlock_rdlock(&LOCK_use_ssl); if (!ssl_acceptor_fd) var->value= const_cast("NONE"); else @@ -8225,6 +8256,7 @@ static int show_ssl_ctx_get_session_cache_mode(THD*, SHOW_VAR *var, char*) default: var->value= const_cast("Unknown"); break; } + mysql_rwlock_unlock(&LOCK_use_ssl); return 0; } @@ -8381,10 +8413,12 @@ static int show_ssl_get_server_not_before(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_CHAR; + mysql_rwlock_rdlock(&LOCK_use_ssl); if (ssl_acceptor_fd) { X509 *cert= SSL_get_certificate(ssl_acceptor); ASN1_TIME *not_before= X509_get_notBefore(cert); + mysql_rwlock_unlock(&LOCK_use_ssl); if (not_before == NULL) { @@ -8401,7 +8435,10 @@ show_ssl_get_server_not_before(THD*, SHOW_VAR *var, char *buff) } } else + { var->value= empty_c_string; + mysql_rwlock_unlock(&LOCK_use_ssl); + } return 0; } @@ -8420,10 +8457,12 @@ static int show_ssl_get_server_not_after(THD*, SHOW_VAR *var, char *buff) { var->type= SHOW_CHAR; + mysql_rwlock_rdlock(&LOCK_use_ssl); if (ssl_acceptor_fd) { X509 *cert= SSL_get_certificate(ssl_acceptor); ASN1_TIME *not_after= X509_get_notAfter(cert); + mysql_rwlock_unlock(&LOCK_use_ssl); if (not_after == NULL) { @@ -8440,7 +8479,10 @@ show_ssl_get_server_not_after(THD*, SHOW_VAR *var, char *buff) } } else + { var->value= empty_c_string; + mysql_rwlock_unlock(&LOCK_use_ssl); + } return 0; } @@ -10584,6 +10626,7 @@ static PSI_rwlock_info all_server_rwlocks[]= { &key_rwlock_LOCK_sys_init_connect, "LOCK_sys_init_connect", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}, { &key_rwlock_LOCK_sys_init_slave, "LOCK_sys_init_slave", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}, { &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}, + { &key_rwlock_LOCK_use_ssl, "LOCK_use_ssl", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}, { &key_rwlock_global_sid_lock, "gtid_commit_rollback", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}, { &key_rwlock_gtid_mode_lock, "gtid_mode_lock", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}, { &key_rwlock_channel_map_lock, "channel_map_lock", 0, 0, PSI_DOCUMENT_ME}, diff --git a/sql/mysqld.h b/sql/mysqld.h index f5ec04e..e130145 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -208,6 +208,7 @@ extern ulonglong slave_rows_search_algorithms_options; extern bool opt_require_secure_transport; extern bool opt_slave_preserve_commit_order; +extern bool opt_use_ssl; #ifndef DBUG_OFF extern uint slave_rows_last_search_algorithm_used; @@ -699,6 +700,7 @@ extern PSI_statement_info stmt_info_rpl; #endif /* HAVE_PSI_STATEMENT_INTERFACE */ #ifdef HAVE_OPENSSL +extern SSL *ssl_acceptor; extern struct st_VioSSLFd * ssl_acceptor_fd; #endif /* HAVE_OPENSSL */ @@ -760,6 +762,7 @@ extern mysql_cond_t COND_manager; extern mysql_rwlock_t LOCK_sys_init_connect; extern mysql_rwlock_t LOCK_sys_init_slave; extern mysql_rwlock_t LOCK_system_variables_hash; +extern mysql_rwlock_t LOCK_use_ssl; extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher, *opt_ssl_key, *opt_ssl_crl, *opt_ssl_crlpath, *opt_tls_version; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 58651f9..f6f0350 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -4549,6 +4549,69 @@ static Sys_var_ulong Sys_max_execution_time( #define SSL_OPT(X) CMD_LINE(REQUIRED_ARG,X) #endif +#ifdef HAVE_OPENSSL +static bool reload_ssl(sys_var *self MY_ATTRIBUTE((unused)), + THD *thd MY_ATTRIBUTE((unused)), + enum_var_type type MY_ATTRIBUTE((unused))) +{ + if (opt_use_ssl == false || ssl_acceptor_fd == nullptr) { + return true; + } + + enum enum_ssl_init_error error= SSL_INITERR_NOERROR; + long ssl_ctx_flags= process_tls_version(opt_tls_version); + struct st_VioSSLFd *new_ssl_fd = new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, + opt_ssl_ca, opt_ssl_capath, + opt_ssl_cipher, &error, + opt_ssl_crl, opt_ssl_crlpath, ssl_ctx_flags); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + ERR_remove_thread_state(0); +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + + if (new_ssl_fd != nullptr) { + SSL *new_ssl_acceptor= SSL_new(new_ssl_fd->ssl_context); + if (new_ssl_acceptor != nullptr) { + free_vio_ssl_fd(ssl_acceptor_fd); + SSL_free(ssl_acceptor); + ssl_acceptor_fd = new_ssl_fd; + ssl_acceptor = new_ssl_acceptor; + return false; + } else { + LogErr(WARNING_LEVEL, ER_SSL_LIBRARY_ERROR, sslGetErrString(error)); + free_vio_ssl_fd(new_ssl_fd); + } + } + return true; +} + +static bool check_ssl(sys_var *self, THD *thd MY_ATTRIBUTE((unused)), set_var * var) +{ + /* + The ssl variable is not actually dynamic, but we want to be able to run + SET @@global.ssl = 1 to reload ssl settings. This check prevents the + variable from being actually changed. + */ + if (opt_use_ssl != var->save_result.ulonglong_value) + { + my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), + self->name.str, "read only"); + return true; + } + return false; +} + +static PolyLock_rwlock PLock_use_ssl(&LOCK_use_ssl); +static Sys_var_bool Sys_use_ssl( + "ssl", + "Enable SSL for connection", + NON_PERSIST GLOBAL_VAR(opt_use_ssl), + CMD_LINE(OPT_ARG), + DEFAULT(TRUE), + &PLock_use_ssl, + NOT_IN_BINLOG, + ON_CHECK(check_ssl), + ON_UPDATE(reload_ssl)); +#endif /* If you are adding new system variable for SSL communication, please take a look at do_auto_cert_generation() function in sql_authentication.cc and