Skip to content

Commit

Permalink
Merge pull request #1536 from nextstrain/trs/rustls-tls-native-roots
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-aksamentov authored Oct 16, 2024
2 parents dac1fa7 + 08b32e5 commit e717280
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 93 deletions.
111 changes: 24 additions & 87 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,9 @@ owo-colors = "=3.5.0"
pretty_assertions = "=1.3.0"
rayon = "=1.7.0"
regex = "=1.8.4"
reqwest = { version = "=0.12.8", default-features = false, features = ["blocking", "deflate", "gzip", "brotli", "socks", "rustls-tls"] }
reqwest = { version = "=0.12.8", default-features = false, features = ["blocking", "deflate", "gzip", "brotli", "socks", "rustls-tls-native-roots", "rustls-tls-webpki-roots"] }
rstest = "=0.17.0"
rstest_reuse = "=0.5.0"
rustls-platform-verifier = "=0.3.4"
schemars = { version = "=0.8.12", features = ["chrono", "either", "enumset", "indexmap"] }
semver = { version = "=1.0.17", features = ["serde"] }
serde = { version = "=1.0.164", features = ["derive"] }
Expand Down
3 changes: 3 additions & 0 deletions docs/user/nextclade-cli/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ For short help type: `nextclade -h`, for extended help type: `nextclade --help`.
* `-x`, `--proxy <PROXY>` — Pass all traffic over proxy server. HTTP, HTTPS, and SOCKS5 proxies are supported
* `--proxy-user <PROXY_USER>` — Username for basic authentication on proxy server, if applicable. Only valid when `--proxy` is also supplied. `--proxy-user` and `--proxy-pass` must be either both specified or both omitted
* `--proxy-pass <PROXY_PASS>` — Password for basic authentication on proxy server, if applicable. Only valid when `--proxy` is also supplied. `--proxy-user` and `--proxy-pass` must be either both specified or both omitted
* `--extra-ca-certs <EXTRA_CA_CERTS>` — Path to extra CA certificates as a PEM bundle



Expand All @@ -255,6 +256,7 @@ For short help type: `nextclade -h`, for extended help type: `nextclade --help`.
* `-x`, `--proxy <PROXY>` — Pass all traffic over proxy server. HTTP, HTTPS, and SOCKS5 proxies are supported
* `--proxy-user <PROXY_USER>` — Username for basic authentication on proxy server, if applicable. Only valid when `--proxy` is also supplied. `--proxy-user` and `--proxy-pass` must be either both specified or both omitted
* `--proxy-pass <PROXY_PASS>` — Password for basic authentication on proxy server, if applicable. Only valid when `--proxy` is also supplied. `--proxy-user` and `--proxy-pass` must be either both specified or both omitted
* `--extra-ca-certs <EXTRA_CA_CERTS>` — Path to extra CA certificates as a PEM bundle



Expand Down Expand Up @@ -295,6 +297,7 @@ For short help type: `nextclade -h`, for extended help type: `nextclade --help`.
* `-x`, `--proxy <PROXY>` — Pass all traffic over proxy server. HTTP, HTTPS, and SOCKS5 proxies are supported
* `--proxy-user <PROXY_USER>` — Username for basic authentication on proxy server, if applicable. Only valid when `--proxy` is also supplied. `--proxy-user` and `--proxy-pass` must be either both specified or both omitted
* `--proxy-pass <PROXY_PASS>` — Password for basic authentication on proxy server, if applicable. Only valid when `--proxy` is also supplied. `--proxy-user` and `--proxy-pass` must be either both specified or both omitted
* `--extra-ca-certs <EXTRA_CA_CERTS>` — Path to extra CA certificates as a PEM bundle



Expand Down
1 change: 0 additions & 1 deletion packages/nextclade-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ pretty_assertions = { workspace = true }
rayon = { workspace = true }
regex = { workspace = true }
reqwest = { workspace = true }
rustls-platform-verifier = { workspace = true }
schemars = { workspace = true }
semver = { workspace = true }
serde = { workspace = true }
Expand Down
37 changes: 34 additions & 3 deletions packages/nextclade-cli/src/io/http_client.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use clap::{Parser, ValueHint};
use eyre::Report;
use eyre::{Report, WrapErr};
use log::info;
use nextclade::io::file::open_file_or_stdin;
use nextclade::make_internal_error;
use nextclade::utils::info::{this_package_name, this_package_version_str};
use reqwest::blocking::Client;
use reqwest::tls::Certificate;
use reqwest::{Method, Proxy};
use rustls_platform_verifier;
use std::env;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::time::Duration;
use url::Url;
Expand All @@ -27,6 +30,15 @@ pub struct ProxyConfig {
#[clap(long)]
#[clap(value_hint = ValueHint::Other)]
pub proxy_pass: Option<String>,

/// Path to extra CA certificates as a PEM bundle.
///
/// You can also provide the path to CA certificates in the environment variable `NEXTCLADE_EXTRA_CA_CERTS`. The argument takes precedence over the environment variable if both are provided.
///
/// Default CA certificates are those obtained from the platform/OS-level trust store plus those from a baked-in copy of Mozilla's common CA trust store. You can override the certs obtained from the platform trust store by setting `SSL_CERT_FILE` or `SSL_CERT_DIR`. Filenames in the latter must be hashed in the style of OpenSSL's `c_rehash` utility.
#[clap(long)]
#[clap(value_hint = ValueHint::Other)]
pub extra_ca_certs: Option<PathBuf>,
}

pub struct HttpClient {
Expand Down Expand Up @@ -60,10 +72,16 @@ impl HttpClient {
client_builder
};

let extra_ca_certs_filepath = env::var_os("NEXTCLADE_EXTRA_CA_CERTS").map(PathBuf::from);
let extra_ca_certs_filepath = proxy_conf.extra_ca_certs.as_ref().or(extra_ca_certs_filepath.as_ref());

for cert in extra_ca_certs(extra_ca_certs_filepath)? {
client_builder = client_builder.add_root_certificate(cert);
}

let user_agent = format!("{} {}", this_package_name(), this_package_version_str());

let client = client_builder
.use_preconfigured_tls(rustls_platform_verifier::tls_config())
.connection_verbose(verbose)
.connect_timeout(Some(Duration::from_secs(60)))
.user_agent(user_agent)
Expand Down Expand Up @@ -112,3 +130,16 @@ impl HttpClient {
Ok(content)
}
}

fn extra_ca_certs(extra_ca_certs_filepath: Option<impl AsRef<Path>>) -> Result<Vec<Certificate>, Report> {
extra_ca_certs_filepath.map_or_else(
|| Ok(vec![]),
|filename| {
let mut pem = vec![];

open_file_or_stdin(&Some(filename))?.read_to_end(&mut pem)?;

Certificate::from_pem_bundle(&pem).wrap_err("While reading PEM bundle")
},
)
}

0 comments on commit e717280

Please sign in to comment.