Skip to content

Commit 9754975

Browse files
author
Thomas Constantine Moore
committed
add ssl_ca to accepted connection url query params
1 parent 66cb13d commit 9754975

4 files changed

Lines changed: 50 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ for Rust libraries in [RFC #1105](https://github.com/rust-lang/rfcs/blob/master/
88

99
### Added
1010

11+
* `MysqlConnection::establish` is able to initiate SSL connection while specifying certificate roots. The database URL should contain `ssl_ca` parameter with a path pointing to the certificate roots. [See docs](https://dev.mysql.com/doc/refman/5.7/en/connection-options.html#option_general_ssl-ca) if desired.
12+
1113
* `MysqlConnection::establish` is able to initiate SSL connection. The database URL should contain `ssl_mode` parameter with a value of the [MySQL client command option `--ssl-mode`](https://dev.mysql.com/doc/refman/5.7/en/connection-options.html#option_general_ssl-mode) if desired.
1214

1315
* `Connection` and `SimpleConnection` traits are implemented for a broader range

diesel/src/mysql/connection/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@ impl Connection for MysqlConnection {
5858

5959
/// Establishes a new connection to the MySQL database
6060
/// `database_url` may be enhanced by GET parameters
61-
/// `mysql://[user[:password]@]host/database_name[?unix_socket=socket-path&ssl_mode=SSL_MODE*]`
61+
/// `mysql://[user[:password]@]host/database_name[?unix_socket=socket-path&ssl_mode=SSL_MODE*&ssl_ca=/etc/ssl/certs/ca-certificates.crt]`
6262
///
63-
/// * `unix_socket` excepts the path to the unix socket
63+
/// * `unix_socket` expects the path to the unix socket
64+
/// * `ssl_ca` accepts a path to the system's certificate roots
6465
/// * `ssl_mode` expects a value defined for MySQL client command option `--ssl-mode`
6566
/// See <https://dev.mysql.com/doc/refman/5.7/en/connection-options.html#option_general_ssl-mode>
6667
fn establish(database_url: &str) -> ConnectionResult<Self> {

diesel/src/mysql/connection/raw.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ impl RawConnection {
5151
if let Some(ssl_mode) = connection_options.ssl_mode() {
5252
self.set_ssl_mode(ssl_mode)
5353
}
54+
if let Some(ssl_ca) = connection_options.ssl_ca() {
55+
self.set_ssl_ca(ssl_ca)
56+
}
5457

5558
unsafe {
5659
// Make sure you don't use the fake one!
@@ -197,6 +200,16 @@ impl RawConnection {
197200
)
198201
};
199202
}
203+
204+
fn set_ssl_ca(&self, ssl_ca: &CStr) {
205+
unsafe {
206+
mysqlclient_sys::mysql_options(
207+
self.0.as_ptr(),
208+
mysqlclient_sys::mysql_option::MYSQL_OPT_SSL_CA,
209+
ssl_ca.as_ptr() as *const std::ffi::c_void,
210+
)
211+
};
212+
}
200213
}
201214

202215
impl Drop for RawConnection {

diesel/src/mysql/connection/url.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub struct ConnectionOptions {
4949
unix_socket: Option<CString>,
5050
client_flags: CapabilityFlags,
5151
ssl_mode: Option<mysql_ssl_mode>,
52+
ssl_ca: Option<CString>,
5253
}
5354

5455
impl ConnectionOptions {
@@ -76,6 +77,11 @@ impl ConnectionOptions {
7677
_ => None,
7778
};
7879

80+
let ssl_ca = match query_pairs.get("ssl_ca") {
81+
Some(v) => Some(CString::new(v.as_bytes())?),
82+
_ => None,
83+
};
84+
7985
let ssl_mode = match query_pairs.get("ssl_mode") {
8086
Some(v) => {
8187
let ssl_mode = match v.to_lowercase().as_str() {
@@ -123,6 +129,7 @@ impl ConnectionOptions {
123129
unix_socket: unix_socket,
124130
client_flags: client_flags,
125131
ssl_mode: ssl_mode,
132+
ssl_ca: ssl_ca,
126133
})
127134
}
128135

@@ -150,6 +157,10 @@ impl ConnectionOptions {
150157
self.unix_socket.as_deref()
151158
}
152159

160+
pub fn ssl_ca(&self) -> Option<&CStr> {
161+
self.ssl_ca.as_deref()
162+
}
163+
153164
pub fn client_flags(&self) -> CapabilityFlags {
154165
self.client_flags
155166
}
@@ -293,6 +304,27 @@ fn unix_socket_tests() {
293304
);
294305
}
295306

307+
#[test]
308+
fn ssl_ca_tests() {
309+
let ssl_ca = "/etc/ssl/certs/ca-certificates.crt";
310+
let username = "foo";
311+
let password = "bar";
312+
let db_url = format!(
313+
"mysql://{}:{}@localhost?ssl_ca={}",
314+
username, password, ssl_ca
315+
);
316+
let conn_opts = ConnectionOptions::parse(db_url.as_str()).unwrap();
317+
let cstring = |s| CString::new(s).unwrap();
318+
assert_eq!(None, conn_opts.host);
319+
assert_eq!(None, conn_opts.port);
320+
assert_eq!(cstring(username), conn_opts.user);
321+
assert_eq!(cstring(password), conn_opts.password.unwrap());
322+
assert_eq!(
323+
CString::new(ssl_ca).unwrap(),
324+
conn_opts.ssl_ca.unwrap()
325+
);
326+
}
327+
296328
#[test]
297329
fn ssl_mode() {
298330
let ssl_mode = |url| ConnectionOptions::parse(url).unwrap().ssl_mode();

0 commit comments

Comments
 (0)