diff --git a/mysql-test/r/dd_is_compatibility_ci.result b/mysql-test/r/dd_is_compatibility_ci.result index 6b7618a69b40..0be81318dc45 100644 --- a/mysql-test/r/dd_is_compatibility_ci.result +++ b/mysql-test/r/dd_is_compatibility_ci.result @@ -153,6 +153,7 @@ WHERE table_schema LIKE 'information_schema' ORDER BY table_name COLLATE UTF8_GENERAL_CI; SELECT * FROM v1; table_name +AUTHINFO CHARACTER_SETS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY diff --git a/mysql-test/r/dd_is_compatibility_cs.result b/mysql-test/r/dd_is_compatibility_cs.result index 3eb794d4e8a7..3a06fa7233d1 100644 --- a/mysql-test/r/dd_is_compatibility_cs.result +++ b/mysql-test/r/dd_is_compatibility_cs.result @@ -153,6 +153,7 @@ WHERE table_schema LIKE 'information_schema' ORDER BY table_name COLLATE UTF8_GENERAL_CI; SELECT * FROM v1; table_name +AUTHINFO CHARACTER_SETS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY diff --git a/mysql-test/r/information_schema_authinfo.result b/mysql-test/r/information_schema_authinfo.result new file mode 100644 index 000000000000..92491a82a1fd --- /dev/null +++ b/mysql-test/r/information_schema_authinfo.result @@ -0,0 +1,6 @@ +# +# Test case for information_schema.authinfo table +# (SSL connection) +# +include/assert.inc [SSL field for the current connection must be set to 1] +include/assert.inc [Info field (peer certificate) for the current connection must be non-empty] diff --git a/mysql-test/r/information_schema_authinfo_nossl.result b/mysql-test/r/information_schema_authinfo_nossl.result new file mode 100644 index 000000000000..dc8f6befd719 --- /dev/null +++ b/mysql-test/r/information_schema_authinfo_nossl.result @@ -0,0 +1,6 @@ +# +# Test case for information_schema.authinfo table +# (non-SSL connection) +# +include/assert.inc [SSL field for the current connection must be set to 0] +include/assert.inc [Info field (peer certificate) for the current connection must be NULL] diff --git a/mysql-test/r/information_schema_ci.result b/mysql-test/r/information_schema_ci.result index 8709532143b3..63958e3663a6 100644 --- a/mysql-test/r/information_schema_ci.result +++ b/mysql-test/r/information_schema_ci.result @@ -60,6 +60,7 @@ table_name COLLATE utf8_general_ci not like 'ndb_%' AND table_name COLLATE utf8_general_ci not like 'innodb_%'; select * from v1; c +AUTHINFO CHARACTER_SETS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY @@ -609,8 +610,8 @@ from information_schema.tables where table_schema='information_schema' order by table_name collate utf8_general_ci limit 2; TABLE_NAME TABLE_TYPE ENGINE +AUTHINFO SYSTEM VIEW NULL CHARACTER_SETS SYSTEM VIEW NULL -COLLATIONS SYSTEM VIEW NULL show tables from information_schema like "T%"; Tables_in_information_schema (T%) TABLES @@ -846,7 +847,7 @@ table_schema IN ('mysql', 'information_schema', 'test', 'mysqltest') AND table_name not like 'ndb%' AND table_name COLLATE utf8_general_ci not like 'innodb_%' GROUP BY TABLE_SCHEMA; TABLE_SCHEMA count(*) -information_schema 35 +information_schema 36 mysql 31 create table t1 (i int, j int); create trigger trg1 before insert on t1 for each row @@ -1287,6 +1288,7 @@ group by c2.column_type order by num limit 1) and t.table_name not like 'INNODB_%' group by t.table_name order by num1, t.table_name COLLATE utf8_general_ci; TABLE_NAME group_concat(t.table_schema, '.', t.table_name) num1 +AUTHINFO information_schema.AUTHINFO 1 CHARACTER_SETS information_schema.CHARACTER_SETS 1 COLLATIONS information_schema.COLLATIONS 1 COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1 @@ -2418,6 +2420,7 @@ AND t.table_name NOT LIKE 'ndb%' ORDER BY t.table_name COLLATE utf8_general_ci, c1.column_name COLLATE utf8_general_ci; TABLE_NAME COLUMN_NAME +AUTHINFO ID CHARACTER_SETS CHARACTER_SET_NAME COLLATIONS COLLATION_NAME COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME @@ -2472,6 +2475,7 @@ AND t.table_name NOT LIKE 'ndb%' ORDER BY t.table_name COLLATE utf8_general_ci, c1.column_name COLLATE utf8_general_ci; TABLE_NAME COLUMN_NAME +AUTHINFO ID CHARACTER_SETS CHARACTER_SET_NAME COLLATIONS COLLATION_NAME COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME diff --git a/mysql-test/r/information_schema_cs.result b/mysql-test/r/information_schema_cs.result index bf06b16d49c6..1f23c077c4b2 100644 --- a/mysql-test/r/information_schema_cs.result +++ b/mysql-test/r/information_schema_cs.result @@ -60,6 +60,7 @@ table_name COLLATE utf8_general_ci not like 'ndb_%' AND table_name COLLATE utf8_general_ci not like 'innodb_%'; select * from v1; c +AUTHINFO CHARACTER_SETS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY @@ -609,8 +610,8 @@ from information_schema.tables where table_schema='information_schema' order by table_name collate utf8_general_ci limit 2; TABLE_NAME TABLE_TYPE ENGINE +AUTHINFO SYSTEM VIEW NULL CHARACTER_SETS SYSTEM VIEW NULL -COLLATIONS SYSTEM VIEW NULL show tables from information_schema like "T%"; Tables_in_information_schema (T%) TABLES @@ -846,7 +847,7 @@ table_schema IN ('mysql', 'information_schema', 'test', 'mysqltest') AND table_name not like 'ndb%' AND table_name COLLATE utf8_general_ci not like 'innodb_%' GROUP BY TABLE_SCHEMA; TABLE_SCHEMA count(*) -information_schema 35 +information_schema 36 mysql 31 create table t1 (i int, j int); create trigger trg1 before insert on t1 for each row @@ -1287,6 +1288,7 @@ group by c2.column_type order by num limit 1) and t.table_name not like 'INNODB_%' group by t.table_name order by num1, t.table_name COLLATE utf8_general_ci; TABLE_NAME group_concat(t.table_schema, '.', t.table_name) num1 +AUTHINFO information_schema.AUTHINFO 1 CHARACTER_SETS information_schema.CHARACTER_SETS 1 COLLATIONS information_schema.COLLATIONS 1 COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1 @@ -2418,6 +2420,7 @@ AND t.table_name NOT LIKE 'ndb%' ORDER BY t.table_name COLLATE utf8_general_ci, c1.column_name COLLATE utf8_general_ci; TABLE_NAME COLUMN_NAME +AUTHINFO ID CHARACTER_SETS CHARACTER_SET_NAME COLLATIONS COLLATION_NAME COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME @@ -2472,6 +2475,7 @@ AND t.table_name NOT LIKE 'ndb%' ORDER BY t.table_name COLLATE utf8_general_ci, c1.column_name COLLATE utf8_general_ci; TABLE_NAME COLUMN_NAME +AUTHINFO ID CHARACTER_SETS CHARACTER_SET_NAME COLLATIONS COLLATION_NAME COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index e18525136d7e..c6f7c6b60e21 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -6,6 +6,7 @@ drop function if exists f2; use INFORMATION_SCHEMA; show tables where Tables_in_information_schema NOT LIKE 'INNODB%' and Tables_in_information_schema NOT LIKE 'ndb%'; Tables_in_information_schema +AUTHINFO CHARACTER_SETS COLLATIONS COLLATION_CHARACTER_SET_APPLICABILITY diff --git a/mysql-test/r/mysqlshow_ci.result b/mysql-test/r/mysqlshow_ci.result index b209a9087af0..9b286328f49c 100644 --- a/mysql-test/r/mysqlshow_ci.result +++ b/mysql-test/r/mysqlshow_ci.result @@ -79,6 +79,7 @@ Database: information_schema +---------------------------------------+ | Tables | +---------------------------------------+ +| AUTHINFO | | CHARACTER_SETS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLLATIONS | @@ -150,6 +151,7 @@ Database: INFORMATION_SCHEMA +---------------------------------------+ | Tables | +---------------------------------------+ +| AUTHINFO | | CHARACTER_SETS | | COLLATION_CHARACTER_SET_APPLICABILITY | | COLLATIONS | diff --git a/mysql-test/r/mysqlshow_cs.result b/mysql-test/r/mysqlshow_cs.result index 270372da1932..63dbf741a10c 100644 --- a/mysql-test/r/mysqlshow_cs.result +++ b/mysql-test/r/mysqlshow_cs.result @@ -79,6 +79,7 @@ Database: information_schema +---------------------------------------+ | Tables | +---------------------------------------+ +| AUTHINFO | | CHARACTER_SETS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | @@ -150,6 +151,7 @@ Database: INFORMATION_SCHEMA +---------------------------------------+ | Tables | +---------------------------------------+ +| AUTHINFO | | CHARACTER_SETS | | COLLATIONS | | COLLATION_CHARACTER_SET_APPLICABILITY | diff --git a/mysql-test/suite/audit_null/r/event_params_cert.result b/mysql-test/suite/audit_null/r/event_params_cert.result index 2289e5fa89b8..9023323531c5 100644 --- a/mysql-test/suite/audit_null/r/event_params_cert.result +++ b/mysql-test/suite/audit_null/r/event_params_cert.result @@ -8,7 +8,7 @@ SELECT * FROM foo; i SHOW STATUS LIKE "Audit_null_generic_event_response"; Variable_name Value -Audit_null_generic_event_response connection_certificate:-----BEGIN CERTIFICATE-----\nMIIDyDCCArCgAwIBAgIJAOG0pVw936YVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNV\nBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcMCVN0b2NraG9sbTEP\nMA0GA1UECgwGT3JhY2xlMQ4wDAYDVQQLDAVNeVNRTDELMAkGA1UEAwwCQ0EwHhcN\nMTQxMjA1MDQ0OTIzWhcNMjkxMjAxMDQ0OTIzWjBnMQswCQYDVQQGEwJTRTESMBAG\nA1UECAwJU3RvY2tob2xtMRIwEAYDVQQHDAlTdG9ja2hvbG0xDzANBgNVBAoMBk9y\nYWNsZTEOMAwGA1UECwwFTXlTUUwxDzANBgNVBAMMBkNsaWVudDCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAMjRof6kjPMbF3EbdDUR4A5sQAr7wPfw67vJ\nHaHH17CK9vHP+mvQeWTru2mlDYAG31IU0oUyz7/OKkcoW80LKKu7BzPVi9O0csSm\ntcw3uQOoeFYlWB8XMHzRCrvsPKMDkJeZkkmus1eWXBrp6AIjrsjJBVBj5XehmnMG\ndA5GUCjYyU/EHDe4UhgLrxkr1OVmdKTz8No +Audit_null_generic_event_response connection_certificate:-----BEGIN CERTIFICATE-----\nMIIDyDCCArCgAwIBAgIJAOG0pVw936YVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNV\nBAYTAlNFMRIwEAYDVQQIDAlTdG9ja2hvbG0xEjAQBgNVBAcMCVN0b2NraG9sbTEP\nMA0GA1UECgwGT3JhY2xlMQ4wDAYDVQQLDAVNeVNRTDELMAkGA1UEAwwCQ0EwHhcN\nMTQxMjA1MDQ0OTIzWhcNMjkxMjAx DROP USER cert_auth@localhost; DROP TABLE foo; UNINSTALL PLUGIN null_audit; diff --git a/mysql-test/suite/audit_null/t/event_params_cert.test b/mysql-test/suite/audit_null/t/event_params_cert.test index 97cca0a28a68..dee3749050af 100644 --- a/mysql-test/suite/audit_null/t/event_params_cert.test +++ b/mysql-test/suite/audit_null/t/event_params_cert.test @@ -14,7 +14,10 @@ SET @@null_audit_extended_log = 1; SELECT * FROM foo; ---replace_regex /.*(connection_certificate:[^;]*).*/\1/ +# As "certificate:" part in the status var may be truncated because of the +# max status var length limit, taking only first 255 chars here to make this +# test stable +--replace_regex /.*(connection_certificate:[^;]{255}).*/\1/ SHOW STATUS LIKE "Audit_null_generic_event_response"; disconnect con1; diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_ci.result b/mysql-test/suite/funcs_1/r/is_columns_is_ci.result index 0e195d1a021d..3be68f698dbf 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_ci.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_ci.result @@ -6,6 +6,11 @@ ORDER BY table_schema, table_name COLLATE utf8_general_ci, ordinal_position; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT GENERATION_EXPRESSION SRS_ID +def information_schema AUTHINFO ID 1 NO bigint NULL NULL NULL NULL NULL NULL NULL bigint(21) unsigned select NULL +def information_schema AUTHINFO USER 2 NO varchar 10 32 NULL NULL NULL utf8 utf8_general_ci varchar(32) select NULL +def information_schema AUTHINFO HOST 3 NO varchar 21 64 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NULL +def information_schema AUTHINFO SSL 4 NO int NULL NULL NULL NULL NULL NULL NULL int(7) select NULL +def information_schema AUTHINFO INFO 5 YES varchar 21845 65535 NULL NULL NULL utf8 utf8_general_ci varchar(65535) select NULL def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NULL def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NULL def information_schema CHARACTER_SETS DESCRIPTION 3 NULL NO varchar 2048 6144 NULL NULL NULL utf8 utf8_general_ci varchar(2048) select NULL @@ -458,6 +463,11 @@ WHERE table_schema = 'information_schema' AND table_name <> 'PROFILING' AND table_name not like 'INNODB_%' AND table_name not like 'ndb%' ORDER BY TABLE_SCHEMA, TABLE_NAME COLLATE utf8_general_ci, ORDINAL_POSITION; COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE +NULL information_schema AUTHINFO ID bigint NULL NULL NULL NULL bigint(21) unsigned +3.2000 information_schema AUTHINFO USER varchar 10 32 utf8 utf8_general_ci varchar(32) +3.0476 information_schema AUTHINFO HOST varchar 21 64 utf8 utf8_general_ci varchar(64) +NULL information_schema AUTHINFO SSL int NULL NULL NULL NULL int(7) +3.0000 information_schema AUTHINFO INFO varchar 21845 65535 utf8 utf8_general_ci varchar(65535) 3.0000 information_schema CHARACTER_SETS CHARACTER_SET_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 2048 6144 utf8 utf8_general_ci varchar(2048) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_cs.result b/mysql-test/suite/funcs_1/r/is_columns_is_cs.result index 93fb2b8cfc91..5d9b20e89160 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_cs.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_cs.result @@ -6,6 +6,11 @@ ORDER BY table_schema, table_name COLLATE utf8_general_ci, ordinal_position; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT GENERATION_EXPRESSION SRS_ID +def information_schema AUTHINFO ID 1 NO bigint NULL NULL NULL NULL NULL NULL NULL bigint(21) unsigned select NULL +def information_schema AUTHINFO USER 2 NO varchar 10 32 NULL NULL NULL utf8 utf8_general_ci varchar(32) select NULL +def information_schema AUTHINFO HOST 3 NO varchar 21 64 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NULL +def information_schema AUTHINFO SSL 4 NO int NULL NULL NULL NULL NULL NULL NULL int(7) select NULL +def information_schema AUTHINFO INFO 5 YES varchar 21845 65535 NULL NULL NULL utf8 utf8_general_ci varchar(65535) select NULL def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NULL def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select NULL def information_schema CHARACTER_SETS DESCRIPTION 3 NULL NO varchar 2048 6144 NULL NULL NULL utf8 utf8_general_ci varchar(2048) select NULL @@ -458,6 +463,11 @@ WHERE table_schema = 'information_schema' AND table_name <> 'PROFILING' AND table_name not like 'INNODB_%' AND table_name not like 'ndb%' ORDER BY TABLE_SCHEMA, TABLE_NAME COLLATE utf8_general_ci, ORDINAL_POSITION; COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE +NULL information_schema AUTHINFO ID bigint NULL NULL NULL NULL bigint(21) unsigned +3.2000 information_schema AUTHINFO USER varchar 10 32 utf8 utf8_general_ci varchar(32) +3.0476 information_schema AUTHINFO HOST varchar 21 64 utf8 utf8_general_ci varchar(64) +NULL information_schema AUTHINFO SSL int NULL NULL NULL NULL int(7) +3.0000 information_schema AUTHINFO INFO varchar 21845 65535 utf8 utf8_general_ci varchar(65535) 3.0000 information_schema CHARACTER_SETS CHARACTER_SET_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 2048 6144 utf8 utf8_general_ci varchar(2048) diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index f60dc317fff8..7c60b97c8046 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -17,6 +17,29 @@ AND table_name not like 'ndb%' ORDER BY table_schema,table_name COLLATE utf8_general_ci; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME AUTHINFO +TABLE_TYPE SYSTEM VIEW +ENGINE NULL +VERSION 10 +ROW_FORMAT NULL +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT #AI# +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION NULL +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE NULL @@ -818,6 +841,29 @@ AND table_name not like 'ndb%' ORDER BY table_schema,table_name COLLATE utf8_general_ci; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME AUTHINFO +TABLE_TYPE SYSTEM VIEW +ENGINE NULL +VERSION 10 +ROW_FORMAT NULL +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT #AI# +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION NULL +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE NULL diff --git a/mysql-test/t/information_schema_authinfo-client.opt b/mysql-test/t/information_schema_authinfo-client.opt new file mode 100644 index 000000000000..88ed9f04cf43 --- /dev/null +++ b/mysql-test/t/information_schema_authinfo-client.opt @@ -0,0 +1,4 @@ +--ssl-mode=VERIFY_CA +--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 diff --git a/mysql-test/t/information_schema_authinfo-master.opt b/mysql-test/t/information_schema_authinfo-master.opt new file mode 100644 index 000000000000..317b93f46621 --- /dev/null +++ b/mysql-test/t/information_schema_authinfo-master.opt @@ -0,0 +1,4 @@ +--ssl=1 +--ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem +--ssl-cert=$MYSQL_TEST_DIR/std_data/server-cert.pem +--ssl-key=$MYSQL_TEST_DIR/std_data/server-key.pem diff --git a/mysql-test/t/information_schema_authinfo.test b/mysql-test/t/information_schema_authinfo.test new file mode 100644 index 000000000000..6adbd9794552 --- /dev/null +++ b/mysql-test/t/information_schema_authinfo.test @@ -0,0 +1,14 @@ +--source include/have_ssl.inc + +--echo # +--echo # Test case for information_schema.authinfo table +--echo # (SSL connection) +--echo # + +--let $assert_text= SSL field for the current connection must be set to 1 +--let $assert_cond= [ SELECT `ssl` = 1 FROM information_schema.authinfo WHERE id = CONNECTION_ID() ] +--source include/assert.inc + +--let $assert_text= Info field (peer certificate) for the current connection must be non-empty +--let $assert_cond= [ SELECT LENGTH(info) > 0 FROM information_schema.authinfo WHERE id = CONNECTION_ID() ] +--source include/assert.inc diff --git a/mysql-test/t/information_schema_authinfo_nossl.test b/mysql-test/t/information_schema_authinfo_nossl.test new file mode 100644 index 000000000000..1797665da3e4 --- /dev/null +++ b/mysql-test/t/information_schema_authinfo_nossl.test @@ -0,0 +1,12 @@ +--echo # +--echo # Test case for information_schema.authinfo table +--echo # (non-SSL connection) +--echo # + +--let $assert_text= SSL field for the current connection must be set to 0 +--let $assert_cond= [ SELECT `ssl` = 0 FROM information_schema.authinfo WHERE id = CONNECTION_ID() ] +--source include/assert.inc + +--let $assert_text= Info field (peer certificate) for the current connection must be NULL +--let $assert_cond= [ SELECT info IS NULL FROM information_schema.authinfo WHERE id = CONNECTION_ID() ] +--source include/assert.inc diff --git a/sql/auth/sql_authentication.cc b/sql/auth/sql_authentication.cc index 8eaa3508a67e..7ff3d830ea44 100644 --- a/sql/auth/sql_authentication.cc +++ b/sql/auth/sql_authentication.cc @@ -1843,9 +1843,6 @@ static bool read_client_connect_attrs(char **ptr, size_t *max_bytes_available, return false; } -typedef std::string Sql_string_t; -static Sql_string_t x509_cert_write(X509 *cert); - static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) { #if defined(HAVE_OPENSSL) Vio *vio = thd->get_protocol_classic()->get_vio(); @@ -1877,7 +1874,6 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) { if (vio_type(vio) == VIO_TYPE_SSL && SSL_get_verify_result(ssl) == X509_V_OK && (cert = SSL_get_peer_certificate(ssl))) { - thd->set_connection_certificate(x509_cert_write(cert)); X509_free(cert); return 0; } @@ -1927,7 +1923,6 @@ static bool acl_check_ssl(THD *thd, const ACL_USER *acl_user) { } OPENSSL_free(ptr); } - thd->set_connection_certificate(x509_cert_write(cert)); X509_free(cert); return 0; #else /* HAVE_OPENSSL */ @@ -3374,6 +3369,8 @@ int acl_authenticate(THD *thd, enum_server_command command) { DBUG_RETURN(1); } + thd->update_connection_certificate(); + /* Check whether the account has been locked. */ @@ -4167,6 +4164,8 @@ static SYS_VAR *sha256_password_sysvars[] = { MYSQL_SYSVAR(private_key_path), MYSQL_SYSVAR(public_key_path), MYSQL_SYSVAR(auto_generate_rsa_keys), 0}; +typedef std::string Sql_string_t; + /** Exception free resize diff --git a/sql/sql_audit.cc b/sql/sql_audit.cc index 32ce28d70bf1..659d7eee92f3 100644 --- a/sql/sql_audit.cc +++ b/sql/sql_audit.cc @@ -380,8 +380,9 @@ int mysql_audit_notify(THD *thd, mysql_event_general_subclass_t subclass, event.general_sql_command = sql_statement_names[thd->lex->sql_command]; event.affected_rows = thd->get_row_count_func(); event.port = mysqld_port; - event.connection_certificate.str = thd->connection_certificate().c_str(); - event.connection_certificate.length = thd->connection_certificate().size(); + event.connection_certificate.str = thd->get_connection_certificate().c_str(); + event.connection_certificate.length = + thd->get_connection_certificate().size(); thd_get_audit_query(thd, &event.general_query, (const CHARSET_INFO **)&event.general_charset); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f26e4a1f16ad..068e48460e42 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -865,7 +866,7 @@ void THD::cleanup_connection(void) { sp_cache_clear(&sp_proc_cache); sp_cache_clear(&sp_func_cache); - m_connection_certificate = ""; + reset_connection_certificate(); clear_error(); // clear the warnings @@ -897,13 +898,45 @@ void THD::cleanup_connection(void) { #endif } -void THD::set_connection_certificate(std::string const &cert) { - DBUG_ASSERT(m_connection_certificate.empty()); - m_connection_certificate = cert; -} +std::string THD::extract_peer_certificate_info(const THD *thd, bool printable) { + // Extracting user certificate from the thread + if (!thd->has_net_vio_ssl_arg()) return {}; + + auto ssl = static_cast(thd->get_net_vio_ssl_arg()); + + // Creating new X509 abstraction + auto cert_deleter = [](X509 *cert) { + if (cert != nullptr) X509_free(cert); + }; + using x509_ptr = std::unique_ptr; + + x509_ptr cert{SSL_get_peer_certificate(ssl), cert_deleter}; + if (!cert) return {}; + + // Creating new memory-based BIO object + auto bio_deleter = [](BIO *bio) { + if (bio != nullptr) BIO_free(bio); + }; + using bio_ptr = std::unique_ptr; + + bio_ptr bio{BIO_new(BIO_s_mem()), bio_deleter}; + if (!bio) return {}; + + // Printing the certificate to the bio object + int print_result = 0; + if (printable) + print_result = X509_print(bio.get(), cert.get()); + else + print_result = PEM_write_bio_X509(bio.get(), cert.get()); + if (print_result != 1) return {}; + + // Extracting data from the bio object + BUF_MEM *buf_mem; + BIO_get_mem_ptr(bio.get(), &buf_mem); + assert(buf_mem->length <= buf_mem->max); + if (buf_mem->data == nullptr) return {}; -std::string const &THD::connection_certificate() const noexcept { - return m_connection_certificate; + return std::string{buf_mem->data, buf_mem->length}; } /* @@ -1071,7 +1104,7 @@ void THD::release_resources() { if (current_thd == this) restore_globals(); - m_connection_certificate = ""; + reset_connection_certificate(); m_release_resources_done = true; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 3dba9bf6d8d9..b2f808a74a6a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1511,6 +1511,15 @@ class THD : public MDL_context_owner, NET net; // client connection descriptor String packet; // dynamic buffer for network I/O public: + bool has_net_vio() const noexcept { return net.vio != nullptr; } + const Vio *get_net_vio() const noexcept { return net.vio; } + bool has_net_vio_ssl_arg() const noexcept { + return has_net_vio() && get_net_vio()->ssl_arg != nullptr; + } + const void *get_net_vio_ssl_arg() const noexcept { + return has_net_vio() ? get_net_vio()->ssl_arg : nullptr; + } + void set_skip_readonly_check() { skip_readonly_check = true; } bool is_cmd_skip_readonly() { return skip_readonly_check; } @@ -3323,10 +3332,28 @@ class THD : public MDL_context_owner, Gtid_set owned_gtid_set; #endif + public: + static std::string extract_peer_certificate_info(const THD *thd, + bool printable); + + private: + friend int acl_authenticate(THD *, enum_server_command); + std::string m_connection_certificate; - std::string const &connection_certificate() const noexcept; - void set_connection_certificate(std::string const &cert); + void update_connection_certificate() { + m_connection_certificate = + extract_peer_certificate_info(this, false /* pem format */); + } + void reset_connection_certificate() { + m_connection_certificate.clear(); + m_connection_certificate.shrink_to_fit(); + } + + public: + std::string const &get_connection_certificate() const noexcept { + return m_connection_certificate; + } /* Replication related context. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 388bc4dc975a..0d00e9663b27 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1914,6 +1914,101 @@ static const char *thread_state_info(THD *tmp) { } } +/** + This class implements callback function used by fill_schema_authinfo() + to populate all the client SSL auth information into I_S table. +*/ +class Fill_authinfo_list : public Do_THD_Impl { + private: + THD *const m_thd; + TABLE *const m_table; + const char *const m_user; + + public: + Fill_authinfo_list(THD *thd, TABLE_LIST *tables) noexcept + : m_thd(thd), + m_table(tables->table), + m_user(thd->security_context()->check_access(PROCESS_ACL) + ? nullptr + : thd->security_context()->priv_user().str) {} + + virtual void operator()(THD *current_thd) override { + const auto current_sctx = current_thd->security_context(); + const auto current_sctx_user = current_sctx->user(); + + if (!current_thd->has_net_vio() && + current_thd->system_thread == NON_SYSTEM_THREAD) + return; + if (m_user != nullptr && (current_sctx_user.str == nullptr || + strcmp(current_sctx_user.str, m_user) != 0)) + return; + + restore_record(m_table, s->default_values); + + /* ID */ + m_table->field[0]->store(static_cast(current_thd->thread_id()), + /*unsigned=*/true); + + /* USER */ + const char *val = current_sctx_user.str + ? current_sctx_user.str + : (current_thd->system_thread != NON_SYSTEM_THREAD + ? "system user" + : "unauthenticated user"); + m_table->field[1]->store(val, strlen(val), system_charset_info); + + /* HOST */ + const auto current_sctx_host = current_sctx->host(); + const auto current_sctx_ip = current_sctx->ip(); + const auto current_sctx_host_or_ip = current_sctx->host_or_ip(); + + std::string host_and_port; + if (current_sctx_host.str != nullptr && current_sctx_host.str[0] != '\0') { + host_and_port.assign(current_sctx_host.str, current_sctx_host.length); + } else if (current_sctx_ip.str != nullptr && + current_sctx_ip.str[0] != '\0') { + host_and_port.assign(current_sctx_ip.str, current_sctx_ip.length); + } else if (current_sctx_host_or_ip.str != nullptr && + current_sctx_host_or_ip.str[0] == '\0') { + host_and_port.assign(current_sctx_host_or_ip.str, + current_sctx_host_or_ip.length); + } + if (!host_and_port.empty() && current_thd->peer_port != 0) { + host_and_port += ':'; + host_and_port += std::to_string(current_thd->peer_port); + } + m_table->field[2]->store(host_and_port.c_str(), host_and_port.size(), + system_charset_info); + + /* SSL */ + const auto ssl = current_thd->has_net_vio_ssl_arg(); + m_table->field[3]->store(ssl, /*unsigned=*/true); + + /* Info */ + const auto cert = THD::extract_peer_certificate_info( + current_thd, true /* printable format */); + if (!cert.empty()) { + const auto width = std::min( + static_cast(PROCESS_LIST_INFO_WIDTH), cert.size()); + m_table->field[4]->store(cert.c_str(), width, system_charset_info); + m_table->field[4]->set_notnull(); + } + + schema_table_store_record(m_thd, m_table); + } +}; + +int fill_schema_authinfo(THD *thd, TABLE_LIST *tables, Item *) { + DBUG_ENTER("fill_schema_authinfo"); + + Fill_authinfo_list fill_authinfo_list(thd, tables); + if (!thd->killed) { + Global_THD_manager::get_instance()->do_for_all_thd_copy( + &fill_authinfo_list); + } + DBUG_RETURN(0); +} + /** This class implements callback function used by mysqld_list_processes() to list all the client process information. @@ -4993,6 +5088,17 @@ ST_FIELD_INFO processlist_fields_info[] = { SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}}; +ST_FIELD_INFO authinfo_fields_info[] = { + {"ID", 21, MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, "Id", SKIP_OPEN_TABLE}, + {"USER", USERNAME_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User", + SKIP_OPEN_TABLE}, + {"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host", + SKIP_OPEN_TABLE}, + {"SSL", 7, MYSQL_TYPE_LONG, 0, 0, "Ssl", SKIP_OPEN_TABLE}, + {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info", + SKIP_OPEN_TABLE}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}}; + ST_FIELD_INFO plugin_fields_info[] = { {"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN_TABLE}, @@ -5091,6 +5197,8 @@ ST_SCHEMA_TABLE schema_tables[] = { {"TMP_TABLE_KEYS", tmp_table_keys_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_tmp_table_keys_record, -1, -1, 1, 0}, + {"AUTHINFO", authinfo_fields_info, create_schema_table, + fill_schema_authinfo, make_old_format, 0, -1, -1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; int initialize_schema_table(st_plugin_int *plugin) {