diff --git a/MANIFEST b/MANIFEST index 1e920d0a..925a7b2e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -86,6 +86,7 @@ t/90utf8_params.t t/91errcheck.t t/92ssl_connection.t t/92ssl_optional.t +t/92ssl_options.t t/92ssl_backronym_vulnerability.t t/92ssl_riddle_vulnerability.t t/93net_ssleay.t diff --git a/dbdimp.c b/dbdimp.c index df301440..08a0d9dd 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -1679,6 +1679,17 @@ static bool mariadb_dr_connect( HV* processed = newHV(); HE* he; SV** svp; + size_t i; + + const char * const mariadb_ssl_attributes[] = { + "mariadb_ssl_optional", + "mariadb_ssl_verify_server_cert", + "mariadb_ssl_client_key", + "mariadb_ssl_client_cert", + "mariadb_ssl_ca_file", + "mariadb_ssl_ca_path", + "mariadb_ssl_cipher", + }; sv_2mortal(newRV_noinc((SV *)processed)); /* Automatically free HV processed */ @@ -2054,13 +2065,8 @@ static bool mariadb_dr_connect( imp_dbh->disable_fallback_for_server_prepare ? 1 : 0); (void)hv_stores(processed, "mariadb_ssl", &PL_sv_yes); - (void)hv_stores(processed, "mariadb_ssl_optional", &PL_sv_yes); - (void)hv_stores(processed, "mariadb_ssl_verify_server_cert", &PL_sv_yes); - (void)hv_stores(processed, "mariadb_ssl_client_key", &PL_sv_yes); - (void)hv_stores(processed, "mariadb_ssl_client_cert", &PL_sv_yes); - (void)hv_stores(processed, "mariadb_ssl_ca_file", &PL_sv_yes); - (void)hv_stores(processed, "mariadb_ssl_ca_path", &PL_sv_yes); - (void)hv_stores(processed, "mariadb_ssl_cipher", &PL_sv_yes); + for (i = 0; i < sizeof(mariadb_ssl_attributes)/sizeof(*mariadb_ssl_attributes); i++) + (void)hv_store(processed, mariadb_ssl_attributes[i], strlen(mariadb_ssl_attributes[i]), &PL_sv_yes, 0); if ((svp = hv_fetchs(hv, "mariadb_ssl", FALSE)) && *svp && SvTRUE(*svp)) { char *client_key = NULL; @@ -2254,6 +2260,16 @@ static bool mariadb_dr_connect( } else { + for (i = 0; i < sizeof(mariadb_ssl_attributes)/sizeof(*mariadb_ssl_attributes); i++) + { + if ((svp = hv_fetch(hv, mariadb_ssl_attributes[i], strlen(mariadb_ssl_attributes[i]), FALSE)) && *svp) + { + mariadb_dr_do_error(dbh, CR_SSL_CONNECTION_ERROR, SvPVX(sv_2mortal(newSVpvf("SSL connection error: SSL attribute %s was specified but SSL encryption was not enabled via mariadb_ssl=1", mariadb_ssl_attributes[i]))), "HY000"); + mariadb_db_disconnect(dbh, imp_dbh); + return FALSE; + } + } + #ifdef HAVE_SSL_MODE unsigned int ssl_mode = SSL_MODE_DISABLED; mysql_options(sock, MYSQL_OPT_SSL_MODE, &ssl_mode); diff --git a/lib/DBD/MariaDB.pod b/lib/DBD/MariaDB.pod index 3153b92c..ebe483c0 100644 --- a/lib/DBD/MariaDB.pod +++ b/lib/DBD/MariaDB.pod @@ -294,6 +294,8 @@ When set MariaDB or MySQL server certificate is checked that it is signed by some CA certificate in the list. I value is not verified unless L|/mariadb_ssl_verify_server_cert> is enabled. +Requires L|/mariadb_ssl>. + =item mariadb_ssl_ca_path The path to a directory that contains trusted SSL certificate authority @@ -306,6 +308,8 @@ L|/mariadb_ssl_verify_server_cert> is enabled. Please note that this option is supported only if your MariaDB or MySQL client was compiled with OpenSSL library, and not with default yaSSL library. +Requires L|/mariadb_ssl>. + =item mariadb_ssl_verify_server_cert Checks the server's I value in the certificate that the server @@ -316,16 +320,22 @@ attacks. Verification of the host name is disabled by default. +Requires L|/mariadb_ssl>. + =item mariadb_ssl_client_key The name of the SSL key file in PEM format to use for establishing a secure connection. +Requires L|/mariadb_ssl>. + =item mariadb_ssl_client_cert The name of the SSL certificate file in PEM format to use for establishing a secure connection. +Requires L|/mariadb_ssl>. + =item mariadb_ssl_cipher A list of permissible ciphers to use for connection encryption. If no cipher in @@ -334,6 +344,8 @@ the list is supported, encrypted connections will not work. mariadb_ssl_cipher=AES128-SHA mariadb_ssl_cipher=DHE-RSA-AES256-SHA:AES128-SHA +Requires L|/mariadb_ssl>. + =item mariadb_ssl_optional Setting I to true disables strict SSL enforcement and @@ -350,6 +362,8 @@ could refuse connection to MariaDB or MySQL server if underlying libmariadb or libmysqlclient library is vulnerable. Option I can be used to make SSL connection vulnerable. +Requires L|/mariadb_ssl>. + =item mariadb_local_infile The C capability for C may be disabled in the MariaDB or MySQL diff --git a/t/92ssl_options.t b/t/92ssl_options.t new file mode 100644 index 00000000..58eebc33 --- /dev/null +++ b/t/92ssl_options.t @@ -0,0 +1,16 @@ +use strict; +use warnings; + +use Test::More; +use DBI; + +use vars qw($test_dsn $test_user $test_password); +use lib 't', '.'; +require "lib.pl"; + +plan tests => 1; + +my $dbh = DBI->connect($test_dsn, $test_user, $test_password, { PrintError => 0, RaiseError => 0, mariadb_ssl => 0, mariadb_ssl_verify_server_cert => 1 }); +ok(! defined $dbh && $DBI::errstr =~ /but SSL encryption was not enabled/, + 'DBD::MariaDB cannot use other ssl options if ssl is not enabled' +) or diag(defined $dbh ? 'Connection succeeded' : "Unexpected error: $DBI::errstr");