Skip to content

Commit 689c602

Browse files
committed
Merge pull request #535 from sodabrew/travis_ssl
Enable SSL tests on Travis
2 parents 8e46e5c + fc30a7c commit 689c602

File tree

5 files changed

+110
-27
lines changed

5 files changed

+110
-27
lines changed

.travis.yml

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,7 @@ before_install:
77
- |
88
bash -c " # Install MariaDB if DB=mariadb
99
if [[ x$DB =~ xmariadb ]]; then
10-
sudo service mysql stop
11-
sudo apt-get purge '^mysql*' 'libmysql*'
12-
sudo apt-get install python-software-properties
13-
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
14-
if [[ x$DB = xmariadb55 ]]; then
15-
sudo add-apt-repository 'deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu precise main'
16-
elif [[ x$DB = xmariadb10 ]]; then
17-
sudo add-apt-repository 'deb http://ftp.osuosl.org/pub/mariadb/repo/10.0/ubuntu precise main'
18-
fi
19-
sudo apt-get update
20-
sudo apt-get -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -y install mariadb-server libmariadbd-dev
10+
sudo bash .travis_mariadb.sh '$DB'
2111
fi
2212
"
2313
- |
@@ -27,6 +17,10 @@ before_install:
2717
mysql.server start
2818
fi
2919
"
20+
- |
21+
bash -c " # Configure SSL support
22+
sudo bash .travis_ssl.sh
23+
"
3024
- mysqld --version
3125
- mysql -u root -e "CREATE DATABASE IF NOT EXISTS test"
3226
os:

.travis_mariadb.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/bin/bash
2+
3+
service mysql stop
4+
apt-get purge '^mysql*' 'libmysql*'
5+
apt-get install python-software-properties
6+
apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
7+
8+
if [[ x$1 = xmariadb55 ]]; then
9+
add-apt-repository 'deb http://ftp.osuosl.org/pub/mariadb/repo/5.5/ubuntu precise main'
10+
elif [[ x$1 = xmariadb10 ]]; then
11+
add-apt-repository 'deb http://ftp.osuosl.org/pub/mariadb/repo/10.0/ubuntu precise main'
12+
fi
13+
14+
apt-get update
15+
apt-get -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -y install mariadb-server libmariadbd-dev

.travis_ssl.sh

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/bin/bash
2+
3+
# Halt the tests on error
4+
set -e
5+
6+
# Whever MySQL configs live, go there (this is for cross-platform)
7+
cd $(my_print_defaults --help | grep my.cnf | xargs find 2>/dev/null | xargs dirname)
8+
9+
# Create config files to run openssl in batch mode
10+
# Set the CA startdate to yesterday to avoid "ASN: before date in the future"
11+
# (there can be 90k seconds in a daylight saving change day)
12+
13+
echo "
14+
[ ca ]
15+
default_startdate = $(ruby -e 'print (Time.now - 90000).strftime("%y%m%d000000Z")')
16+
17+
[ req ]
18+
distinguished_name = req_distinguished_name
19+
20+
[ req_distinguished_name ]
21+
# If this isn't set, the error is "error, no objects specified in config file"
22+
commonName = Common Name (hostname, IP, or your name)
23+
24+
countryName_default = US
25+
stateOrProvinceName_default = CA
26+
localityName_default = San Francisco
27+
0.organizationName_default = test_example
28+
organizationalUnitName_default = Testing
29+
emailAddress_default = [email protected]
30+
" | tee ca.cnf cert.cnf
31+
32+
# The client and server certs must have a diferent common name than the CA
33+
# to avoid "SSL connection error: error:00000001:lib(0):func(0):reason(1)"
34+
35+
echo "
36+
commonName_default = ca_name
37+
" >> ca.cnf
38+
39+
echo "
40+
commonName_default = cert_name
41+
" >> cert.cnf
42+
43+
# Generate a set of certificates
44+
openssl genrsa -out ca-key.pem 2048
45+
openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem -batch -config ca.cnf
46+
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout pkcs8-server-key.pem -out server-req.pem -batch -config cert.cnf
47+
openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
48+
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout pkcs8-client-key.pem -out client-req.pem -batch -config cert.cnf
49+
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
50+
51+
# Convert format from PKCS#8 to PKCS#1
52+
openssl rsa -in pkcs8-server-key.pem -out server-key.pem
53+
openssl rsa -in pkcs8-client-key.pem -out client-key.pem
54+
55+
# Put the configs into the server
56+
echo "
57+
[mysqld]
58+
ssl-ca=/etc/mysql/ca-cert.pem
59+
ssl-cert=/etc/mysql/server-cert.pem
60+
ssl-key=/etc/mysql/server-key.pem
61+
" >> my.cnf
62+
63+
# FIXME The startdate code above isn't doing the trick, we must wait until the minute moves
64+
ruby -e 'start = Time.now.min; while Time.now.min == start; sleep 2; end'
65+
66+
# Ok, let's see what we got!
67+
service mysql restart || brew services restart mysql

ext/mysql2/client.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,26 +169,30 @@ static void *nogvl_connect(void *ptr) {
169169

170170
#ifndef _WIN32
171171
/*
172-
* Redirect clientfd to a dummy socket for mysql_close to
173-
* write, shutdown, and close on as a no-op.
174-
* We do this hack because we want to call mysql_close to release
175-
* memory, but do not want mysql_close to drop connections in the
176-
* parent if the socket got shared in fork.
172+
* Redirect clientfd to /dev/null for mysql_close and SSL_close to write,
173+
* shutdown, and close. The hack is needed to prevent shutdown() from breaking
174+
* a socket that may be in use by the parent or other processes after fork.
175+
*
176+
* /dev/null is used to absorb writes; previously a dummy socket was used, but
177+
* it could not abosrb writes and caused openssl to go into an infinite loop.
178+
*
177179
* Returns Qtrue or Qfalse (success or failure)
180+
*
181+
* Note: if this function is needed on Windows, use "nul" instead of "/dev/null"
178182
*/
179183
static VALUE invalidate_fd(int clientfd)
180184
{
181185
#ifdef SOCK_CLOEXEC
182186
/* Atomically set CLOEXEC on the new FD in case another thread forks */
183-
int sockfd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
187+
int sockfd = open("/dev/null", O_RDWR | O_CLOEXEC);
184188
if (sockfd < 0) {
185189
/* Maybe SOCK_CLOEXEC is defined but not available on this kernel */
186-
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
190+
int sockfd = open("/dev/null", O_RDWR);
187191
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
188192
}
189193
#else
190194
/* Well we don't have SOCK_CLOEXEC, so just set FD_CLOEXEC quickly */
191-
int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
195+
int sockfd = open("/dev/null", O_RDWR);
192196
fcntl(sockfd, F_SETFD, FD_CLOEXEC);
193197
#endif
194198

spec/mysql2/client_spec.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,20 @@ def connect *args
109109
end
110110

111111
it "should be able to connect via SSL options" do
112-
ssl = @client.query "SHOW VARIABLES LIKE 'have_%ssl'"
113-
ssl_enabled = ssl.any? {|x| x['Value'] == 'ENABLED'}
114-
pending("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.") unless ssl_enabled
115-
pending("DON'T WORRY, THIS TEST PASSES - but you must update the SSL cert paths in this test and remove this pending state.")
112+
ssl = @client.query "SHOW VARIABLES LIKE 'have_ssl'"
113+
ssl_uncompiled = ssl.any? {|x| x['Value'] == 'OFF'}
114+
pending("DON'T WORRY, THIS TEST PASSES - but SSL is not compiled into your MySQL daemon.") if ssl_uncompiled
115+
ssl_disabled = ssl.any? {|x| x['Value'] == 'DISABLED'}
116+
pending("DON'T WORRY, THIS TEST PASSES - but SSL is not enabled in your MySQL daemon.") if ssl_disabled
117+
118+
# You may need to adjust the lines below to match your SSL certificate paths
116119
ssl_client = nil
117120
lambda {
118121
ssl_client = Mysql2::Client.new(
119-
:sslkey => '/path/to/client-key.pem',
120-
:sslcert => '/path/to/client-cert.pem',
121-
:sslca => '/path/to/ca-cert.pem',
122-
:sslcapath => '/path/to/newcerts/',
122+
:sslkey => '/etc/mysql/client-key.pem',
123+
:sslcert => '/etc/mysql/client-cert.pem',
124+
:sslca => '/etc/mysql/ca-cert.pem',
125+
:sslcapath => '/etc/mysql/',
123126
:sslcipher => 'DHE-RSA-AES256-SHA'
124127
)
125128
}.should_not raise_error(Mysql2::Error)

0 commit comments

Comments
 (0)