Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't enable SSL with MariaDB driver library. (#1182) #1183

Merged
merged 4 commits into from
Jun 1, 2021
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- {os: ubuntu-16.04, ruby: 2.4, db: mariadb10.0, allow-failure: true}
# Comment out due to ci/setup.sh stucking.
# - {os: ubuntu-18.04, ruby: 2.4, db: mariadb10.1}
# `service mysql restart` fails.
# Allow failure due to the issue #965, #1165.
Copy link
Contributor

@junaruga junaruga Apr 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened a PR #1193 to fix #965 and #1152 . After the PR will be merged, we can remove #965. There will be only #1165 .

- {os: ubuntu-20.04, ruby: 2.4, db: mariadb10.3, allow-failure: true}
- {os: ubuntu-18.04, ruby: 2.4, db: mysql57}
# Allow failure due to the issue #1165.
Expand Down
7 changes: 6 additions & 1 deletion ci/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,13 @@ fi

# Install MariaDB 10.3 if DB=mariadb10.3
if [[ -n ${GITHUB_ACTIONS-} && -n ${DB-} && x$DB =~ ^xmariadb10.3 ]]; then
sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
sudo apt-get purge -y 'mysql-common*' 'mysql-client*' 'mysql-server*'
sudo mv /etc/mysql "/etc/mysql-$(date +%Y%m%d-%H%M%S)"
sudo mv /var/lib/mysql "/var/lib/mysql-$(date +%Y%m%d-%H%M%S)"
sudo apt-get install -y -o Dpkg::Options::='--force-confnew' mariadb-server mariadb-server-10.3 libmariadb-dev
CHANGED_PASSWORD=true
CHANGED_PASSWORD_BY_RECREATE=true
fi

# Install MySQL/MariaDB if OS=darwin
Expand Down
4 changes: 2 additions & 2 deletions ext/mysql2/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ static VALUE rb_set_ssl_mode_option(VALUE self, VALUE setting) {
#ifdef HAVE_CONST_MYSQL_OPT_SSL_ENFORCE
GET_CLIENT(self);
int val = NUM2INT( setting );
// Either MySQL 5.7.3 - 5.7.10, or Connector/C 6.1.3 - 6.1.x
if ((version >= 50703 && version < 50711) || (version >= 60103 && version < 60200)) {
// Either MySQL 5.7.3 - 5.7.10, or Connector/C 6.1.3 - 6.1.x, or MariaDB 10.x
if ((version >= 50703 && version < 50711) || (version >= 60103 && version < 60200) || (version >= 100000 && version < 110000)) {
if (val == SSL_MODE_DISABLED || val == SSL_MODE_REQUIRED) {
my_bool b = ( val == SSL_MODE_REQUIRED );
int result = mysql_options( wrapper->client, MYSQL_OPT_SSL_ENFORCE, &b );
Expand Down
82 changes: 53 additions & 29 deletions spec/mysql2/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,39 +126,63 @@ def connect(*args)
expect(Mysql2::Client).to respond_to(:default_query_options)
end

it "should be able to connect via SSL options" do
ssl = @client.query "SHOW VARIABLES LIKE 'have_ssl'"
ssl_uncompiled = ssl.any? { |x| x['Value'] == 'OFF' }
pending("DON'T WORRY, THIS TEST PASSES - but SSL is not compiled into your MySQL daemon.") if ssl_uncompiled
ssl_disabled = ssl.any? { |x| x['Value'] == 'DISABLED' }
pending("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.") if ssl_disabled

# You may need to adjust the lines below to match your SSL certificate paths
ssl_client = nil
option_overrides = {
'host' => 'mysql2gem.example.com', # must match the certificates
:sslkey => '/etc/mysql/client-key.pem',
:sslcert => '/etc/mysql/client-cert.pem',
:sslca => '/etc/mysql/ca-cert.pem',
:sslcipher => 'DHE-RSA-AES256-SHA',
:sslverify => true,
}
%i[sslkey sslcert sslca].each do |item|
unless File.exist?(option_overrides[item])
pending("DON'T WORRY, THIS TEST PASSES - but #{option_overrides[item]} does not exist.")
break
context "SSL" do
before(:example) do
ssl = @client.query "SHOW VARIABLES LIKE 'have_ssl'"
ssl_uncompiled = ssl.any? { |x| x['Value'] == 'OFF' }
ssl_disabled = ssl.any? { |x| x['Value'] == 'DISABLED' }
if ssl_uncompiled
skip("DON'T WORRY, THIS TEST PASSES - but SSL is not compiled into your MySQL daemon.")
elsif ssl_disabled
skip("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.")
else
%i[sslkey sslcert sslca].each do |item|
unless File.exist?(option_overrides[item])
skip("DON'T WORRY, THIS TEST PASSES - but #{option_overrides[item]} does not exist.")
break
end
end
end
end
expect do
ssl_client = new_client(option_overrides)
end.not_to raise_error

results = Hash[ssl_client.query('SHOW STATUS WHERE Variable_name LIKE "Ssl_%"').map { |x| x.values_at('Variable_name', 'Value') }]
expect(results['Ssl_cipher']).not_to be_empty
expect(results['Ssl_version']).not_to be_empty
let(:option_overrides) do
{
'host' => 'mysql2gem.example.com', # must match the certificates
:sslkey => '/etc/mysql/client-key.pem',
:sslcert => '/etc/mysql/client-cert.pem',
:sslca => '/etc/mysql/ca-cert.pem',
:sslcipher => 'DHE-RSA-AES256-SHA',
:sslverify => true,
}
end

let(:ssl_client) do
new_client(option_overrides)
end

%i[disabled preferred required verify_ca verify_identity].each do |ssl_mode|
it "should set ssl_mode option #{ssl_mode}" do
options = {
ssl_mode: ssl_mode,
}
options.merge!(option_overrides)
# Relax the matching condition by checking if an error is not raised.
# TODO: Verify warnings by checking stderr.
expect do
new_client(options)
end.not_to raise_error
end
end

expect(ssl_client.ssl_cipher).not_to be_empty
expect(results['Ssl_cipher']).to eql(ssl_client.ssl_cipher)
it "should be able to connect via SSL options" do
# You may need to adjust the lines below to match your SSL certificate paths
results = Hash[ssl_client.query('SHOW STATUS WHERE Variable_name LIKE "Ssl_%"').map { |x| x.values_at('Variable_name', 'Value') }]
expect(results['Ssl_cipher']).not_to be_empty
expect(results['Ssl_version']).not_to be_empty

expect(ssl_client.ssl_cipher).not_to be_empty
expect(results['Ssl_cipher']).to eql(ssl_client.ssl_cipher)
end
end

def run_gc
Expand Down