Skip to content

Commit c85c4d2

Browse files
committed
Add client ssl tests for MariaDB and MySQL
1 parent 69594ac commit c85c4d2

File tree

7 files changed

+178
-19
lines changed

7 files changed

+178
-19
lines changed

sqlx-core/src/mysql/options/parse.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ impl FromStr for MySqlConnectOptions {
4343

4444
for (key, value) in url.query_pairs().into_iter() {
4545
match &*key {
46-
"ssl-mode" => {
46+
"sslmode" | "ssl-mode" => {
4747
options = options.ssl_mode(value.parse().map_err(Error::config)?);
4848
}
4949

50-
"ssl-ca" => {
50+
"sslca" | "ssl-ca" => {
5151
options = options.ssl_ca(&*value);
5252
}
5353

@@ -59,9 +59,9 @@ impl FromStr for MySqlConnectOptions {
5959
options = options.collation(&*value);
6060
}
6161

62-
"sslcert" => options = options.ssl_client_cert(&*value),
62+
"sslcert" | "ssl-cert" => options = options.ssl_client_cert(&*value),
6363

64-
"sslkey" => options = options.ssl_client_key(&*value),
64+
"sslkey" | "ssl-key" => options = options.ssl_client_key(&*value),
6565

6666
"statement-cache-capacity" => {
6767
options =

tests/.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*
22
!certs/*
33
!keys/*
4+
!mysql/my.cnf
45
!mssql/*.sh
56
!postgres/pg_hba.conf
67
!*/*.sql

tests/docker-compose.yml

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,21 @@ services:
1919
MYSQL_ROOT_PASSWORD: password
2020
MYSQL_DATABASE: sqlx
2121

22+
mysql_8_client_ssl:
23+
build:
24+
context: .
25+
dockerfile: mysql/Dockerfile
26+
args:
27+
IMAGE: mysql:8.0.27
28+
volumes:
29+
- "./mysql/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
30+
ports:
31+
- 3306
32+
environment:
33+
MYSQL_ROOT_HOST: '%'
34+
MYSQL_DATABASE: sqlx
35+
MYSQL_ALLOW_EMPTY_PASSWORD: 1
36+
2237
mysql_5_7:
2338
image: mysql:5.7
2439
volumes:
@@ -30,6 +45,21 @@ services:
3045
MYSQL_ROOT_PASSWORD: password
3146
MYSQL_DATABASE: sqlx
3247

48+
mysql_5_7_client_ssl:
49+
build:
50+
context: .
51+
dockerfile: mysql/Dockerfile
52+
args:
53+
IMAGE: mysql:5.7
54+
volumes:
55+
- "./mysql/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
56+
ports:
57+
- 3306
58+
environment:
59+
MYSQL_ROOT_HOST: '%'
60+
MYSQL_DATABASE: sqlx
61+
MYSQL_ALLOW_EMPTY_PASSWORD: 1
62+
3363
mysql_5_6:
3464
image: mysql:5.6
3565
volumes:
@@ -41,6 +71,21 @@ services:
4171
MYSQL_ROOT_PASSWORD: password
4272
MYSQL_DATABASE: sqlx
4373

74+
mysql_5_6_client_ssl:
75+
build:
76+
context: .
77+
dockerfile: mysql/Dockerfile
78+
args:
79+
IMAGE: mysql:5.6
80+
volumes:
81+
- "./mysql/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
82+
ports:
83+
- 3306
84+
environment:
85+
MYSQL_ROOT_HOST: '%'
86+
MYSQL_DATABASE: sqlx
87+
MYSQL_ALLOW_EMPTY_PASSWORD: 1
88+
4489
#
4590
# MariaDB 10.6, 10.5, 10.4, 10.3, 10.2
4691
# https://mariadb.org/about/#maintenance-policy
@@ -56,6 +101,20 @@ services:
56101
MYSQL_ROOT_PASSWORD: password
57102
MYSQL_DATABASE: sqlx
58103

104+
mariadb_10_6_client_ssl:
105+
build:
106+
context: .
107+
dockerfile: mysql/Dockerfile
108+
args:
109+
IMAGE: mariadb:10.6
110+
volumes:
111+
- "./mysql/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
112+
ports:
113+
- 3306
114+
environment:
115+
MARIADB_DATABASE: sqlx
116+
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: 1
117+
59118
mariadb_10_5:
60119
image: mariadb:10.5
61120
volumes:
@@ -66,6 +125,20 @@ services:
66125
MYSQL_ROOT_PASSWORD: password
67126
MYSQL_DATABASE: sqlx
68127

128+
mariadb_10_5_client_ssl:
129+
build:
130+
context: .
131+
dockerfile: mysql/Dockerfile
132+
args:
133+
IMAGE: mariadb:10.5
134+
volumes:
135+
- "./mysql/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
136+
ports:
137+
- 3306
138+
environment:
139+
MARIADB_DATABASE: sqlx
140+
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: 1
141+
69142
mariadb_10_4:
70143
image: mariadb:10.4
71144
volumes:
@@ -76,6 +149,20 @@ services:
76149
MYSQL_ROOT_PASSWORD: password
77150
MYSQL_DATABASE: sqlx
78151

152+
mariadb_10_4_client_ssl:
153+
build:
154+
context: .
155+
dockerfile: mysql/Dockerfile
156+
args:
157+
IMAGE: mariadb:10.4
158+
volumes:
159+
- "./mysql/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
160+
ports:
161+
- 3306
162+
environment:
163+
MARIADB_DATABASE: sqlx
164+
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: 1
165+
79166
mariadb_10_3:
80167
image: mariadb:10.3
81168
volumes:
@@ -86,6 +173,20 @@ services:
86173
MYSQL_ROOT_PASSWORD: password
87174
MYSQL_DATABASE: sqlx
88175

176+
mariadb_10_3_client_ssl:
177+
build:
178+
context: .
179+
dockerfile: mysql/Dockerfile
180+
args:
181+
IMAGE: mariadb:10.3
182+
volumes:
183+
- "./mysql/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
184+
ports:
185+
- 3306
186+
environment:
187+
MARIADB_DATABASE: sqlx
188+
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: 1
189+
89190
mariadb_10_2:
90191
image: mariadb:10.2
91192
volumes:
@@ -96,6 +197,20 @@ services:
96197
MYSQL_ROOT_PASSWORD: password
97198
MYSQL_DATABASE: sqlx
98199

200+
mariadb_10_2_client_ssl:
201+
build:
202+
context: .
203+
dockerfile: mysql/Dockerfile
204+
args:
205+
IMAGE: mariadb:10.2
206+
volumes:
207+
- "./mysql/setup.sql:/docker-entrypoint-initdb.d/setup.sql"
208+
ports:
209+
- 3306
210+
environment:
211+
MARIADB_DATABASE: sqlx
212+
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: 1
213+
99214
#
100215
# PostgreSQL 14.x, 13.x, 12.x, 11.x 10.x, 9.6.x
101216
# https://www.postgresql.org/support/versioning/

tests/docker.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,29 @@ def start_database(driver, database, cwd):
5656

5757
port = int(res.stdout[1:-2].decode())
5858

59+
# need additional permissions to connect to MySQL when using SSL
60+
res = subprocess.run(
61+
["docker", "exec", f"sqlx_{driver}_1", "mysql", "-u", "root", "-e", "GRANT ALL PRIVILEGES ON *.* TO 'root' WITH GRANT OPTION;"],
62+
stdout=subprocess.PIPE,
63+
stderr=subprocess.PIPE,
64+
cwd=dir_tests,
65+
)
66+
67+
if res.returncode != 0:
68+
print(res.stderr, file=sys.stderr)
69+
70+
# do not set password in URL if authenticating using SSL key file
71+
if driver.endswith("client_ssl"):
72+
password = ""
73+
else:
74+
password = ":password"
75+
5976
# construct appropriate database URL
6077
if driver.startswith("mysql") or driver.startswith("mariadb"):
61-
return f"mysql://root:password@127.0.0.1:{port}/{database}"
78+
return f"mysql://root{password}@localhost:{port}/{database}"
6279

6380
elif driver.startswith("postgres"):
64-
if driver.endswith("client_ssl"):
65-
return f"postgres://postgres@localhost:{port}/{database}"
66-
else:
67-
return f"postgres://postgres:password@localhost:{port}/{database}"
81+
return f"postgres://postgres{password}@localhost:{port}/{database}"
6882

6983
elif driver.startswith("mssql"):
7084
return f"mssql://sa:[email protected]:{port}/{database}"

tests/mysql/Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ARG IMAGE
2+
FROM ${IMAGE}
3+
4+
# Copy SSL certificate (and key)
5+
COPY certs/server.crt /etc/mysql/ssl/server.crt
6+
COPY certs/ca.crt /etc/mysql/ssl/ca.crt
7+
COPY keys/server.key /etc/mysql/ssl/server.key
8+
COPY mysql/my.cnf /etc/mysql/my.cnf
9+
10+
# Fix permissions
11+
RUN chown mysql:mysql /etc/mysql/ssl/server.crt /etc/mysql/ssl/server.key
12+
RUN chmod 0600 /etc/mysql/ssl/server.crt /etc/mysql/ssl/server.key
13+
14+
# Create dir for secure-file-priv
15+
RUN mkdir -p /var/lib/mysql-files

tests/mysql/my.cnf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[mysqld]
2+
ssl-ca=/etc/mysql/ssl/ca.crt
3+
ssl-cert=/etc/mysql/ssl/server.crt
4+
ssl-key=/etc/mysql/ssl/server.key

tests/x.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,6 @@ def run(command, comment=None, env=None, service=None, tag=None, args=None, data
138138
tag=f"postgres_{version}" if runtime == "async-std" else f"postgres_{version}_{runtime}",
139139
)
140140

141-
## +ssl
142-
for version in ["14", "13", "12", "11", "10", "9_6"]:
143-
run(
144-
f"cargo test --no-default-features --features macros,offline,any,all-types,postgres,runtime-{runtime}-{tls}",
145-
comment=f"test postgres {version} ssl",
146-
database_url_args="sslmode=verify-ca&sslrootcert=.%2Ftests%2Fcerts%2Fca.crt",
147-
service=f"postgres_{version}",
148-
tag=f"postgres_{version}_ssl" if runtime == "async-std" else f"postgres_{version}_ssl_{runtime}",
149-
)
150-
151141
## +client-ssl
152142
for version in ["14_client_ssl", "13_client_ssl", "12_client_ssl", "11_client_ssl", "10_client_ssl", "9_6_client_ssl"]:
153143
run(
@@ -170,6 +160,16 @@ def run(command, comment=None, env=None, service=None, tag=None, args=None, data
170160
tag=f"mysql_{version}" if runtime == "async-std" else f"mysql_{version}_{runtime}",
171161
)
172162

163+
## +client-ssl
164+
for version in ["8_client_ssl", "5_7_client_ssl", "5_6_client_ssl"]:
165+
run(
166+
f"cargo test --no-default-features --features macros,offline,any,all-types,mysql,runtime-{runtime}-{tls}",
167+
comment=f"test mysql {version} no-password",
168+
database_url_args="sslmode=verify_ca&ssl-ca=.%2Ftests%2Fcerts%2Fca.crt&ssl-key=.%2Ftests%2Fkeys%2Fclient.key&ssl-cert=.%2Ftests%2Fcerts%2Fclient.crt",
169+
service=f"mysql_{version}",
170+
tag=f"mysql_{version}_no_password" if runtime == "async-std" else f"mysql_{version}_no_password_{runtime}",
171+
)
172+
173173
#
174174
# mariadb
175175
#
@@ -182,6 +182,16 @@ def run(command, comment=None, env=None, service=None, tag=None, args=None, data
182182
tag=f"mariadb_{version}" if runtime == "async-std" else f"mariadb_{version}_{runtime}",
183183
)
184184

185+
## +client-ssl
186+
for version in ["10_6_client_ssl", "10_5_client_ssl", "10_4_client_ssl", "10_3_client_ssl", "10_2_client_ssl"]:
187+
run(
188+
f"cargo test --no-default-features --features macros,offline,any,all-types,mysql,runtime-{runtime}-{tls}",
189+
comment=f"test mariadb {version} no-password",
190+
database_url_args="sslmode=verify_ca&ssl-ca=.%2Ftests%2Fcerts%2Fca.crt&ssl-key=.%2Ftests%2Fkeys%2Fclient.key&ssl-cert=.%2Ftests%2Fcerts%2Fclient.crt",
191+
service=f"mariadb_{version}",
192+
tag=f"mariadb_{version}_no_password" if runtime == "async-std" else f"mariadb_{version}_no_password_{runtime}",
193+
)
194+
185195
#
186196
# mssql
187197
#

0 commit comments

Comments
 (0)