blackbeam/mysql_async

SSL/TLS does not seem to be supported

calebschoepp opened this issue · 2 comments

SSL/TLS query parameters don't seem to be supported. Something like mysql_async::Pool::new("mysql://myuser:password@127.0.0.1/db?sslMode=VERIFY_CA") would fail because it wouldn't recognize the ssl-mode query parameter. The error looks like:

thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: UnknownParameter { param: "ssl-mode" }', /Users/caleb/.cargo/registry/src/github.com-1ecc6299db9ec823/mysql_async-0.30.0/src/conn/pool/mod.rs:124:41

It seems like the parsing is just not wired up properly because there is a struct opts.ssl_opts.

Hi.

Regarding SSL query params - not sure about the reason, but support is not implemented, sorry. You'll have to use OptsBuilder for now.

Regarding sslMode - it seem to be a libmysqlclient feature, but mysql_async is a pure-rust driver that doesn't depend on it:
If opts.ssl_opts is given then you should assume REQUIRED + VERIFY_IDENTITY + VERIFY_CA.

  • with_danger_skip_domain_validation turns off VERIFY_IDENTITY
  • with_danger_accept_invalid_certs turns off VERIFY_CA
    Otherwise - DISABLED

Thanks for the quick response @blackbeam. Totally fine if this isn't a high priority.

You'll have to use OptsBuilder for now.

This is the fix we ended up using downstream. We manually parse out an SSL query parameters and then manually add the ssl_opts with the OptsBuilder. We then pull the SSL query parameters out so that it doesn't blow up when trying to parse the rest of the address.

fn build_opts(address: &str) -> Result<Opts, mysql_async::Error> {
    let url = Url::parse(address)?;

    let use_ssl = url
        .query_pairs()
        .any(|(k, v)| is_ssl_param(&k) && v.to_lowercase() != "disabled");

    let query_without_ssl: Vec<(_, _)> = url
        .query_pairs()
        .filter(|(k, _v)| !is_ssl_param(k))
        .collect();
    let mut cleaned_url = url.clone();
    cleaned_url.set_query(None);
    cleaned_url
        .query_pairs_mut()
        .extend_pairs(query_without_ssl);

    Ok(OptsBuilder::from_opts(cleaned_url.as_str())
        .ssl_opts(if use_ssl {
            Some(SslOpts::default())
        } else {
            None
        })
        .into())
}

// Using it
let opts = build_opts(address)?;
let connection_pool = mysql_async::Pool::new(opts);

CC @dicej