summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2018-12-11 18:23:54 +0100
committerVladislav Vaintroub <wlad@mariadb.com>2018-12-12 22:51:20 +0100
commit19d3d3e8616ebb65feaac942b19652c5b31b2e93 (patch)
treea3b8779cf924aeb3fc1aa8168f700fc79759a4e5
parentf570da5153aca0db2f83765f638cf0d85260c8e2 (diff)
downloadmariadb-git-19d3d3e8616ebb65feaac942b19652c5b31b2e93.tar.gz
MDEV-16266 - New command FLUSH SSL to reload server's SSL certificate(private key,CRL,etc)
-rw-r--r--include/mysql_com.h1
-rwxr-xr-xmysql-test/lib/generate-ssl-certs.sh5
-rw-r--r--mysql-test/main/flush_ssl.result26
-rw-r--r--mysql-test/main/flush_ssl.test61
-rw-r--r--mysql-test/std_data/server-new-cert.pem69
-rw-r--r--mysql-test/std_data/server-new-key.pem15
-rw-r--r--mysql-test/suite/perfschema/r/dml_setup_instruments.result2
-rw-r--r--sql/mysqld.cc309
-rw-r--r--sql/mysqld.h4
-rw-r--r--sql/sql_acl.cc7
-rw-r--r--sql/sql_reload.cc5
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/sql_yacc_ora.yy2
13 files changed, 306 insertions, 202 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 902c0ff2706..8b0847ab399 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -231,6 +231,7 @@ enum enum_indicator_type
#define REFRESH_DES_KEY_FILE (1ULL << 18)
#define REFRESH_USER_RESOURCES (1ULL << 19)
#define REFRESH_FOR_EXPORT (1ULL << 20) /* FLUSH TABLES ... FOR EXPORT */
+#define REFRESH_SSL (1ULL << 21)
#define REFRESH_GENERIC (1ULL << 30)
#define REFRESH_FAST (1ULL << 31) /* Intern flag */
diff --git a/mysql-test/lib/generate-ssl-certs.sh b/mysql-test/lib/generate-ssl-certs.sh
index 8f15ba9d521..6f492e9f61f 100755
--- a/mysql-test/lib/generate-ssl-certs.sh
+++ b/mysql-test/lib/generate-ssl-certs.sh
@@ -21,6 +21,11 @@ openssl rsa -in server-key.pem -out server-key.pem
# sign the server certificate with CA certificate
openssl ca -keyfile cakey.pem -days 7300 -batch -cert cacert.pem -policy policy_anything -out server-cert.pem -infiles demoCA/server-req.pem
+# Certificate with different validity period (MDEV-7598)
+openssl req -newkey rsa:1024 -keyout server-new-key.pem -out demoCA/server-new-req.pem -days 7301 -nodes -subj '/CN=server-new/C=FI/ST=Helsinki/L=Helsinki/O=MariaDB'
+openssl rsa -in server-new-key.pem -out server-new-key.pem
+openssl ca -keyfile cakey.pem -days 7301 -batch -cert cacert.pem -policy policy_anything -out server-new-cert.pem -infiles demoCA/server-new-req.pem
+
openssl req -newkey rsa:8192 -keyout server8k-key.pem -out demoCA/server8k-req.pem -days 7300 -nodes -subj '/CN=server8k/C=FI/ST=Helsinki/L=Helsinki/O=MariaDB'
openssl rsa -in server8k-key.pem -out server8k-key.pem
openssl ca -keyfile cakey.pem -days 7300 -batch -cert cacert.pem -policy policy_anything -out server8k-cert.pem -infiles demoCA/server8k-req.pem
diff --git a/mysql-test/main/flush_ssl.result b/mysql-test/main/flush_ssl.result
new file mode 100644
index 00000000000..e2941db9f95
--- /dev/null
+++ b/mysql-test/main/flush_ssl.result
@@ -0,0 +1,26 @@
+# Kill the server
+connect ssl_con,localhost,root,,,,,SSL;
+SELECT VARIABLE_VALUE INTO @ssl_not_after FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_server_not_after';
+# Use a different certificate ("Not after" certificate field changed)
+FLUSH SSL;
+# Check new certificate used by new connection
+Result
+OK
+# Check that existing SSL connection still works, and uses old certificate, even if new one is loaded in FLUSH SSL
+connection ssl_con;
+SELECT IF(VARIABLE_VALUE=@ssl_not_after,'OK','FAIL') as Result FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_server_not_after';
+Result
+OK
+disconnect ssl_con;
+connection default;
+SELECT VARIABLE_NAME NAME, VARIABLE_VALUE VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME in ('Ssl_accepts', 'Ssl_finished_accepts');
+NAME VALUE
+SSL_ACCEPTS 1
+SSL_FINISHED_ACCEPTS 1
+FLUSH SSL;
+SELECT VARIABLE_NAME NAME, VARIABLE_VALUE VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME in ('Ssl_accepts', 'Ssl_finished_accepts');
+NAME VALUE
+SSL_ACCEPTS 0
+SSL_FINISHED_ACCEPTS 0
+# Cleanup
+# Kill the server
diff --git a/mysql-test/main/flush_ssl.test b/mysql-test/main/flush_ssl.test
new file mode 100644
index 00000000000..e7bd57b156a
--- /dev/null
+++ b/mysql-test/main/flush_ssl.test
@@ -0,0 +1,61 @@
+# MDEV-16266 Reload SSL certificate
+# This test reloads server SSL certs FLUSH SSL, and checks that
+# 1. old SSL connections (that existed before FLUSH) still work and use old certificate
+# 2. new SSL connection use new certificate
+# 3. if FLUSH SSL runs into error, SSL is still functioning
+# SWtatus variable Ssl_server_not_after is used to tell the old certificate from new.
+
+
+source include/have_ssl_communication.inc;
+
+# Restart server with cert. files located in temp directory
+# We are going to remove / replace them within the test,
+# so we can't use the ones in std_data directly.
+
+let $ssl_cert=$MYSQLTEST_VARDIR/tmp/ssl_cert.pem;
+let $ssl_key=$MYSQLTEST_VARDIR/tmp/ssl_key.pem;
+
+copy_file $MYSQL_TEST_DIR/std_data/server-key.pem $ssl_key;
+copy_file $MYSQL_TEST_DIR/std_data/server-cert.pem $ssl_cert;
+
+let $restart_parameters=--ssl-key=$ssl_key --ssl-cert=$ssl_cert;
+--source include/kill_mysqld.inc
+--source include/start_mysqld.inc
+
+connect ssl_con,localhost,root,,,,,SSL;
+SELECT VARIABLE_VALUE INTO @ssl_not_after FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_server_not_after';
+let $ssl_not_after=`SELECT @ssl_not_after`;
+
+remove_file $ssl_cert;
+remove_file $ssl_key;
+
+--echo # Use a different certificate ("Not after" certificate field changed)
+copy_file $MYSQL_TEST_DIR/std_data/server-new-key.pem $ssl_key;
+copy_file $MYSQL_TEST_DIR/std_data/server-new-cert.pem $ssl_cert;
+
+FLUSH SSL;
+
+--echo # Check new certificate used by new connection
+exec $MYSQL --ssl -e "SELECT IF(VARIABLE_VALUE <> '$ssl_not_after', 'OK', 'FAIL') as Result FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_server_not_after'";
+
+--echo # Check that existing SSL connection still works, and uses old certificate, even if new one is loaded in FLUSH SSL
+connection ssl_con;
+SELECT IF(VARIABLE_VALUE=@ssl_not_after,'OK','FAIL') as Result FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME='Ssl_server_not_after';
+
+disconnect ssl_con;
+connection default;
+
+SELECT VARIABLE_NAME NAME, VARIABLE_VALUE VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME in ('Ssl_accepts', 'Ssl_finished_accepts');
+FLUSH SSL;
+#Check that accepts are zeroed by FLUSH SSL.
+SELECT VARIABLE_NAME NAME, VARIABLE_VALUE VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME in ('Ssl_accepts', 'Ssl_finished_accepts');
+
+--echo # Cleanup
+remove_file $ssl_cert;
+remove_file $ssl_key;
+# restart with usuall SSL
+let $restart_parameters=;
+--source include/kill_mysqld.inc
+--source include/start_mysqld.inc
+
+
diff --git a/mysql-test/std_data/server-new-cert.pem b/mysql-test/std_data/server-new-cert.pem
new file mode 100644
index 00000000000..d780cebf68f
--- /dev/null
+++ b/mysql-test/std_data/server-new-cert.pem
@@ -0,0 +1,69 @@
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number: 7 (0x7)
+ Signature Algorithm: sha256WithRSAEncryption
+ Issuer: CN=cacert, C=FI, ST=Helsinki, L=Helsinki, O=MariaDB
+ Validity
+ Not Before: Dec 11 17:13:59 2018 GMT
+ Not After : Dec 7 17:13:59 2038 GMT
+ Subject: C=FI, ST=Helsinki, L=Helsinki, O=MariaDB, CN=server-new
+ Subject Public Key Info:
+ Public Key Algorithm: rsaEncryption
+ Public-Key: (1024 bit)
+ Modulus:
+ 00:c9:40:33:d7:fb:b7:a2:bc:4e:d4:65:27:1a:c9:
+ da:8b:2e:fc:a9:60:1a:69:e8:fd:e3:13:78:b6:08:
+ 3b:3e:fd:d3:b0:d3:6c:a1:79:bd:85:ca:be:a1:0a:
+ 4e:2a:ee:2c:8d:da:72:e6:85:56:ec:3a:7c:46:a3:
+ d3:18:e7:19:19:8d:14:7e:de:d2:a4:2f:22:56:1c:
+ 21:03:24:f6:2d:55:4e:49:25:9f:32:01:94:66:47:
+ e4:fa:fa:45:b1:b7:33:26:da:f1:c7:29:3b:ba:fe:
+ e8:d4:f1:fc:29:57:6b:3a:be:ef:2e:1d:da:ef:0a:
+ d7:54:8d:67:00:7b:7a:29:2b
+ Exponent: 65537 (0x10001)
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ FF:42:5E:88:AC:6A:C8:80:63:A8:AF:20:C6:BE:E8:A4:02:D5:42:AF
+ X509v3 Authority Key Identifier:
+ keyid:1C:C7:2B:AA:1B:B1:BB:2E:9A:F4:0F:B1:86:60:57:38:C2:41:05:12
+
+ Signature Algorithm: sha256WithRSAEncryption
+ 7c:cc:c1:93:43:83:a9:ea:19:9d:1c:a1:f8:e1:c1:61:58:c0:
+ db:ef:43:6e:d7:cf:4d:75:38:6e:cb:03:25:5d:21:af:03:b1:
+ 86:5f:b3:d1:e2:6f:8c:89:55:b7:82:6a:c0:d6:46:08:0c:68:
+ 9d:ef:cc:2e:79:f5:d8:0b:f2:13:3a:52:cc:08:d5:3a:f0:d8:
+ 5c:9e:85:a7:38:31:9d:7c:61:2b:59:ee:c0:16:a6:16:dd:80:
+ e2:ef:96:3d:b0:13:ec:9b:9a:91:69:3f:6c:46:87:05:55:b7:
+ 32:85:51:da:02:c3:ac:2d:c3:5e:9a:51:f8:96:75:0b:63:29:
+ 4e:47:47:f1:82:a6:ad:44:3d:51:b3:19:8b:ae:26:a9:15:a0:
+ 73:b6:70:6e:4f:72:9d:69:4e:b2:9b:2a:a8:50:87:b8:9f:c0:
+ a7:37:0f:9e:bc:4c:80:b9:b8:47:28:8e:33:c3:7f:d7:fe:31:
+ f0:a9:1c:7a:f7:a3:34:21:d4:e4:53:86:a3:7e:1d:1c:a7:65:
+ fb:ec:f9:1f:17:1e:4f:19:f9:fe:dd:ee:53:0f:b5:98:b7:7a:
+ ef:12:6c:8d:32:78:66:a5:42:d7:3d:a5:09:f8:06:05:a4:ff:
+ bd:4e:e7:85:c4:f0:dc:dc:20:26:84:91:69:e8:cf:3b:27:9f:
+ 35:36:cc:ff
+-----BEGIN CERTIFICATE-----
+MIIDIjCCAgqgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQ8wDQYDVQQDDAZjYWNl
+cnQxCzAJBgNVBAYTAkZJMREwDwYDVQQIDAhIZWxzaW5raTERMA8GA1UEBwwISGVs
+c2lua2kxEDAOBgNVBAoMB01hcmlhREIwHhcNMTgxMjExMTcxMzU5WhcNMzgxMjA3
+MTcxMzU5WjBaMQswCQYDVQQGEwJGSTERMA8GA1UECAwISGVsc2lua2kxETAPBgNV
+BAcMCEhlbHNpbmtpMRAwDgYDVQQKDAdNYXJpYURCMRMwEQYDVQQDDApzZXJ2ZXIt
+bmV3MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJQDPX+7eivE7UZScaydqL
+LvypYBpp6P3jE3i2CDs+/dOw02yheb2Fyr6hCk4q7iyN2nLmhVbsOnxGo9MY5xkZ
+jRR+3tKkLyJWHCEDJPYtVU5JJZ8yAZRmR+T6+kWxtzMm2vHHKTu6/ujU8fwpV2s6
+vu8uHdrvCtdUjWcAe3opKwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIB
+DQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU/0Je
+iKxqyIBjqK8gxr7opALVQq8wHwYDVR0jBBgwFoAUHMcrqhuxuy6a9A+xhmBXOMJB
+BRIwDQYJKoZIhvcNAQELBQADggEBAHzMwZNDg6nqGZ0cofjhwWFYwNvvQ27Xz011
+OG7LAyVdIa8DsYZfs9Hib4yJVbeCasDWRggMaJ3vzC559dgL8hM6UswI1Trw2Fye
+hac4MZ18YStZ7sAWphbdgOLvlj2wE+ybmpFpP2xGhwVVtzKFUdoCw6wtw16aUfiW
+dQtjKU5HR/GCpq1EPVGzGYuuJqkVoHO2cG5Pcp1pTrKbKqhQh7ifwKc3D568TIC5
+uEcojjPDf9f+MfCpHHr3ozQh1ORThqN+HRynZfvs+R8XHk8Z+f7d7lMPtZi3eu8S
+bI0yeGalQtc9pQn4BgWk/71O54XE8NzcICaEkWnozzsnnzU2zP8=
+-----END CERTIFICATE-----
diff --git a/mysql-test/std_data/server-new-key.pem b/mysql-test/std_data/server-new-key.pem
new file mode 100644
index 00000000000..093666d5c1b
--- /dev/null
+++ b/mysql-test/std_data/server-new-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDJQDPX+7eivE7UZScaydqLLvypYBpp6P3jE3i2CDs+/dOw02yh
+eb2Fyr6hCk4q7iyN2nLmhVbsOnxGo9MY5xkZjRR+3tKkLyJWHCEDJPYtVU5JJZ8y
+AZRmR+T6+kWxtzMm2vHHKTu6/ujU8fwpV2s6vu8uHdrvCtdUjWcAe3opKwIDAQAB
+AoGBAKlH3dPxIdg6+TvjEe+Qlsm4bkKyWcV4fAaDnGfRqLQloej9DkUNOAPQNGUV
+XAb0bHmtpDSPODxgPaTVrH0n9o1tTXrfIijSM7zm0Ub2H7YPMNMUSae+9K3bdXoL
+aHjlYYXBXULa093nXOXNmjX17pBKUmiAkKCoqxTMx9QGW8rRAkEA/aqjdIrbaEJd
+Mky4bLzaSZITls/8+LPekUpH+TXdjgSMMaDxd4OXAnA34fssPOhsD8yzgeo2XZZj
+Snk4wfBHrwJBAMsaITNwvAXj3joX/eTD4Q/FcwdaPt4dL2BS13uJrva/TZGEAnOn
+n5nu2exZDslxyoKA5SBl2oZbhtCAA1elWUUCQQCeo8rZpcWVrHtQa76i8nCpthte
+I/EXMJYu0v+0EUXf/WQX3YllrvwP4FJyl3yREuIR93kD9I/Pc6/g8XLXhwetAkB1
+VG8BrIqyTGVA4kNGOPJ3jfVZtgTDg9CusKzTLULqQLGq8rwH3DoTTyyNoRUtwpLe
+uV+kS7LmE1HaeVl09IyRAkBXb/5p2D+Dfb/3/mx5/YuFNwB07sY+H0CrzO1qSo62
+q0nzNK3/irTzqtuerwy/YkBTz/T75GePIK4P0b9elNlb
+-----END RSA PRIVATE KEY-----
diff --git a/mysql-test/suite/perfschema/r/dml_setup_instruments.result b/mysql-test/suite/perfschema/r/dml_setup_instruments.result
index ff184806e2e..307c5c5366a 100644
--- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result
+++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result
@@ -22,13 +22,13 @@ NAME ENABLED TIMED
wait/synch/rwlock/sql/LOCK_dboptions YES YES
wait/synch/rwlock/sql/LOCK_grant YES YES
wait/synch/rwlock/sql/LOCK_SEQUENCE YES YES
+wait/synch/rwlock/sql/LOCK_ssl_refresh YES YES
wait/synch/rwlock/sql/LOCK_system_variables_hash YES YES
wait/synch/rwlock/sql/LOCK_sys_init_connect YES YES
wait/synch/rwlock/sql/LOCK_sys_init_slave YES YES
wait/synch/rwlock/sql/LOGGER::LOCK_logger YES YES
wait/synch/rwlock/sql/MDL_context::LOCK_waiting_for YES YES
wait/synch/rwlock/sql/MDL_lock::rwlock YES YES
-wait/synch/rwlock/sql/Query_cache_query::lock YES YES
select * from performance_schema.setup_instruments
where name like 'Wait/Synch/Cond/sql/%'
and name not in (
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 993f1391b52..db07555196c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -770,6 +770,7 @@ mysql_mutex_t LOCK_prepared_stmt_count;
mysql_mutex_t LOCK_des_key_file;
#endif
mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
+mysql_rwlock_t LOCK_ssl_refresh;
mysql_prlock_t LOCK_system_variables_hash;
mysql_cond_t COND_thread_count, COND_start_thread;
pthread_t signal_thread;
@@ -1033,7 +1034,8 @@ PSI_rwlock_key key_rwlock_LOCK_grant, key_rwlock_LOCK_logger,
key_rwlock_LOCK_sys_init_connect, key_rwlock_LOCK_sys_init_slave,
key_rwlock_LOCK_system_variables_hash, key_rwlock_query_cache_query_lock,
key_LOCK_SEQUENCE,
- key_rwlock_LOCK_vers_stats, key_rwlock_LOCK_stat_serial;
+ key_rwlock_LOCK_vers_stats, key_rwlock_LOCK_stat_serial,
+ key_rwlock_LOCK_ssl_refresh;
static PSI_rwlock_info all_server_rwlocks[]=
{
@@ -1048,7 +1050,8 @@ static PSI_rwlock_info all_server_rwlocks[]=
{ &key_rwlock_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
{ &key_rwlock_query_cache_query_lock, "Query_cache_query::lock", 0},
{ &key_rwlock_LOCK_vers_stats, "Vers_field_stats::lock", 0},
- { &key_rwlock_LOCK_stat_serial, "TABLE_SHARE::LOCK_stat_serial", 0}
+ { &key_rwlock_LOCK_stat_serial, "TABLE_SHARE::LOCK_stat_serial", 0},
+ { &key_rwlock_LOCK_ssl_refresh, "LOCK_ssl_refresh", PSI_FLAG_GLOBAL }
};
#ifdef HAVE_MMAP
@@ -2276,6 +2279,7 @@ static void clean_up_mutexes()
mysql_mutex_destroy(&LOCK_rpl_status);
#endif /* HAVE_REPLICATION */
mysql_mutex_destroy(&LOCK_active_mi);
+ mysql_rwlock_destroy(&LOCK_ssl_refresh);
mysql_rwlock_destroy(&LOCK_sys_init_connect);
mysql_rwlock_destroy(&LOCK_sys_init_slave);
mysql_mutex_destroy(&LOCK_global_system_variables);
@@ -4688,6 +4692,7 @@ static int init_thread_environment()
#endif /* HAVE_OPENSSL */
mysql_rwlock_init(key_rwlock_LOCK_sys_init_connect, &LOCK_sys_init_connect);
mysql_rwlock_init(key_rwlock_LOCK_sys_init_slave, &LOCK_sys_init_slave);
+ mysql_rwlock_init(key_rwlock_LOCK_ssl_refresh, &LOCK_ssl_refresh);
mysql_rwlock_init(key_rwlock_LOCK_grant, &LOCK_grant);
mysql_cond_init(key_COND_thread_count, &COND_thread_count, NULL);
mysql_cond_init(key_COND_thread_cache, &COND_thread_cache, NULL);
@@ -4781,6 +4786,60 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
}
#endif /* HAVE_OPENSSL10 */
+
+struct SSL_ACCEPTOR_STATS
+{
+ long accept;
+ long accept_good;
+ long cache_size;
+ long verify_mode;
+ long verify_depth;
+ long zero;
+ const char *session_cache_mode;
+
+ SSL_ACCEPTOR_STATS():
+ accept(),accept_good(),cache_size(),verify_mode(),verify_depth(),zero(),
+ session_cache_mode("NONE")
+ {
+ }
+
+ void init()
+ {
+ DBUG_ASSERT(ssl_acceptor_fd !=0 && ssl_acceptor_fd->ssl_context != 0);
+ SSL_CTX *ctx= ssl_acceptor_fd->ssl_context;
+ accept= 0;
+ accept_good= 0;
+ verify_mode= SSL_CTX_get_verify_mode(ctx);
+ verify_depth= SSL_CTX_get_verify_depth(ctx);
+ cache_size= SSL_CTX_sess_get_cache_size(ctx);
+ switch (SSL_CTX_get_session_cache_mode(ctx))
+ {
+ case SSL_SESS_CACHE_OFF:
+ session_cache_mode= "OFF"; break;
+ case SSL_SESS_CACHE_CLIENT:
+ session_cache_mode= "CLIENT"; break;
+ case SSL_SESS_CACHE_SERVER:
+ session_cache_mode= "SERVER"; break;
+ case SSL_SESS_CACHE_BOTH:
+ session_cache_mode= "BOTH"; break;
+ case SSL_SESS_CACHE_NO_AUTO_CLEAR:
+ session_cache_mode= "NO_AUTO_CLEAR"; break;
+ case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
+ session_cache_mode= "NO_INTERNAL_LOOKUP"; break;
+ default:
+ session_cache_mode= "Unknown"; break;
+ }
+ }
+};
+
+static SSL_ACCEPTOR_STATS ssl_acceptor_stats;
+void ssl_acceptor_stats_update(int sslaccept_ret)
+{
+ statistic_increment(ssl_acceptor_stats.accept, &LOCK_status);
+ if (!sslaccept_ret)
+ statistic_increment(ssl_acceptor_stats.accept_good,&LOCK_status);
+}
+
static void init_ssl()
{
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
@@ -4801,6 +4860,9 @@ static void init_ssl()
opt_use_ssl = 0;
have_ssl= SHOW_OPTION_DISABLED;
}
+ else
+ ssl_acceptor_stats.init();
+
if (global_system_variables.log_warnings > 0)
{
ulong err;
@@ -4819,6 +4881,34 @@ static void init_ssl()
#endif /* HAVE_OPENSSL && ! EMBEDDED_LIBRARY */
}
+/* Reinitialize SSL (FLUSH SSL) */
+int reinit_ssl()
+{
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
+ if (!opt_use_ssl)
+ return 0;
+
+ enum enum_ssl_init_error error = SSL_INITERR_NOERROR;
+ st_VioSSLFd *new_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);
+
+ if (!new_fd)
+ {
+ my_printf_error(ER_UNKNOWN_ERROR, "Failed to refresh SSL, error: %s", MYF(0),
+ sslGetErrString(error));
+#ifndef HAVE_YASSL
+ ERR_clear_error();
+#endif
+ return 1;
+ }
+ mysql_rwlock_wrlock(&LOCK_ssl_refresh);
+ free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
+ ssl_acceptor_fd= new_fd;
+ ssl_acceptor_stats.init();
+ mysql_rwlock_unlock(&LOCK_ssl_refresh);
+ return 0;
+#endif
+}
static void end_ssl()
{
@@ -7441,187 +7531,6 @@ static int show_flush_commands(THD *thd, SHOW_VAR *var, char *buff,
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
-/* Functions relying on CTX */
-static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var,
- char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var,
- char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var,
- char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_LONG;
- var->value= buff;
- *((long *)buff)= (!ssl_acceptor_fd ? 0 :
- SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
- return 0;
-}
-
-static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var,
- char *buff,
- enum enum_var_type scope)
-{
- var->type= SHOW_CHAR;
- if (!ssl_acceptor_fd)
- var->value= const_cast<char*>("NONE");
- else
- switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
- {
- case SSL_SESS_CACHE_OFF:
- var->value= const_cast<char*>("OFF"); break;
- case SSL_SESS_CACHE_CLIENT:
- var->value= const_cast<char*>("CLIENT"); break;
- case SSL_SESS_CACHE_SERVER:
- var->value= const_cast<char*>("SERVER"); break;
- case SSL_SESS_CACHE_BOTH:
- var->value= const_cast<char*>("BOTH"); break;
- case SSL_SESS_CACHE_NO_AUTO_CLEAR:
- var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
- case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
- var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
- default:
- var->value= const_cast<char*>("Unknown"); break;
- }
- return 0;
-}
/*
Functions relying on SSL
@@ -8126,28 +8035,28 @@ SHOW_VAR status_vars[]= {
{"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count_), SHOW_LONG_STATUS},
#ifdef HAVE_OPENSSL
#ifndef EMBEDDED_LIBRARY
- {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_SIMPLE_FUNC},
- {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_SIMPLE_FUNC},
- {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_SIMPLE_FUNC},
+ {"Ssl_accept_renegotiates", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
+ {"Ssl_accepts", (char*) &ssl_acceptor_stats.accept, SHOW_LONG},
+ {"Ssl_callback_cache_hits", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
{"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_SIMPLE_FUNC},
{"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_SIMPLE_FUNC},
- {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_SIMPLE_FUNC},
- {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_SIMPLE_FUNC},
- {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_SIMPLE_FUNC},
- {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_SIMPLE_FUNC},
+ {"Ssl_client_connects", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
+ {"Ssl_connect_renegotiates", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
+ {"Ssl_ctx_verify_depth", (char*) &ssl_acceptor_stats.verify_depth, SHOW_LONG},
+ {"Ssl_ctx_verify_mode", (char*) &ssl_acceptor_stats.verify_mode, SHOW_LONG},
{"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_SIMPLE_FUNC},
- {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_SIMPLE_FUNC},
- {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_SIMPLE_FUNC},
+ {"Ssl_finished_accepts", (char*) &ssl_acceptor_stats.accept_good, SHOW_LONG},
+ {"Ssl_finished_connects", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
{"Ssl_server_not_after", (char*) &show_ssl_get_server_not_after, SHOW_SIMPLE_FUNC},
{"Ssl_server_not_before", (char*) &show_ssl_get_server_not_before, SHOW_SIMPLE_FUNC},
- {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_SIMPLE_FUNC},
- {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_SIMPLE_FUNC},
- {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_SIMPLE_FUNC},
- {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_SIMPLE_FUNC},
- {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_SIMPLE_FUNC},
- {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_SIMPLE_FUNC},
- {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_SIMPLE_FUNC},
- {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_SIMPLE_FUNC},
+ {"Ssl_session_cache_hits", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
+ {"Ssl_session_cache_misses", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
+ {"Ssl_session_cache_mode", (char*) &ssl_acceptor_stats.session_cache_mode, SHOW_CHAR_PTR},
+ {"Ssl_session_cache_overflows", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
+ {"Ssl_session_cache_size", (char*) &ssl_acceptor_stats.cache_size, SHOW_LONG},
+ {"Ssl_session_cache_timeouts", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
+ {"Ssl_sessions_reused", (char*) &ssl_acceptor_stats.zero, SHOW_LONG},
+ {"Ssl_used_session_cache_entries",(char*) &ssl_acceptor_stats.zero, SHOW_LONG},
{"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_SIMPLE_FUNC},
{"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_SIMPLE_FUNC},
{"Ssl_version", (char*) &show_ssl_get_version, SHOW_SIMPLE_FUNC},
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 9c02b9127a2..c84e1d08efe 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -96,6 +96,9 @@ extern void init_net_server_extension(THD *thd);
extern void handle_accepted_socket(MYSQL_SOCKET new_sock, MYSQL_SOCKET sock);
extern void create_new_thread(CONNECT *connect);
+extern void ssl_acceptor_stats_update(int sslaccept_ret);
+extern int reinit_ssl();
+
extern "C" MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info;
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *files_charset_info ;
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *national_charset_info;
@@ -633,6 +636,7 @@ extern mysql_mutex_t LOCK_des_key_file;
extern mysql_mutex_t LOCK_server_started;
extern mysql_cond_t COND_server_started;
extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
+extern mysql_rwlock_t LOCK_ssl_refresh;
extern mysql_prlock_t LOCK_system_variables_hash;
extern mysql_cond_t COND_thread_count, COND_start_thread;
extern mysql_cond_t COND_manager;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index b99ef01f880..85b54009219 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -12641,7 +12641,12 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
return packet_error;
DBUG_PRINT("info", ("IO layer change in progress..."));
- if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, &errptr))
+ mysql_rwlock_rdlock(&LOCK_ssl_refresh);
+ int ssl_ret = sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, &errptr);
+ mysql_rwlock_unlock(&LOCK_ssl_refresh);
+ ssl_acceptor_stats_update(ssl_ret);
+
+ if(ssl_ret)
{
DBUG_PRINT("error", ("Failed to accept new SSL connection"));
return packet_error;
diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc
index 48c5e9552e5..7a5cabc8880 100644
--- a/sql/sql_reload.cc
+++ b/sql/sql_reload.cc
@@ -416,6 +416,11 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
#endif
if (options & REFRESH_USER_RESOURCES)
reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
+ if (options & REFRESH_SSL)
+ {
+ if (reinit_ssl())
+ result= 1;
+ }
if (options & REFRESH_GENERIC)
{
List_iterator_fast<LEX_CSTRING> li(thd->lex->view_list);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index fa8c15ac7e1..f628ef098a1 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -14486,6 +14486,8 @@ flush_option:
{ Lex->type|= REFRESH_DES_KEY_FILE; }
| RESOURCES
{ Lex->type|= REFRESH_USER_RESOURCES; }
+ | SSL_SYM
+ { Lex->type|= REFRESH_SSL;}
| IDENT_sys remember_tok_start
{
Lex->type|= REFRESH_GENERIC;
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 27d3132be0d..5708962aabe 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -14541,6 +14541,8 @@ flush_option:
{ Lex->type|= REFRESH_DES_KEY_FILE; }
| RESOURCES
{ Lex->type|= REFRESH_USER_RESOURCES; }
+ | SSL_SYM
+ { Lex->type|= REFRESH_SSL;}
| IDENT_sys remember_tok_start
{
Lex->type|= REFRESH_GENERIC;