Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): add --extra-ca-certs #1528

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions packages/nextclade-cli/src/io/http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustls_pemfile;
use rustls_pki_types::TrustAnchor;
use rustls_platform_verifier::Verifier;
use std::env;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
Expand All @@ -34,6 +35,13 @@ pub struct ProxyConfig {
#[clap(long)]
#[clap(value_hint = ValueHint::Other)]
pub proxy_pass: Option<String>,

/// Path to extra CA certificates
///
/// You can also provide path to CA certificates in environment variable `NEXTCLADE_EXTRA_CA_CERTS`. The argument takes precedence over environment variable if both are provided.
#[clap(long)]
#[clap(value_hint = ValueHint::Other)]
pub extra_ca_certs: Option<PathBuf>,
ivan-aksamentov marked this conversation as resolved.
Show resolved Hide resolved
}

pub struct HttpClient {
Expand Down Expand Up @@ -69,9 +77,12 @@ impl HttpClient {

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

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());

let tls_config = ClientConfig::builder()
.dangerous() // …but the rustls_platform_verifier::Verifier is safe
.with_custom_certificate_verifier(Arc::new(Verifier::new_with_extra_roots(extra_ca_certs()?)))
.with_custom_certificate_verifier(Arc::new(Verifier::new_with_extra_roots(extra_ca_certs(extra_ca_certs_filepath)?)))
.with_no_client_auth();

let client = client_builder
Expand Down Expand Up @@ -125,9 +136,12 @@ impl HttpClient {
}
}

fn extra_ca_certs<'a>() -> Result<impl IntoIterator<Item = TrustAnchor<'a>>, Report> {
match env::var_os("NEXTCLADE_EXTRA_CA_CERTS") {
Some(filename) => {
fn extra_ca_certs<'a>(
extra_ca_certs_filepath: Option<impl AsRef<Path>>,
) -> Result<impl IntoIterator<Item = TrustAnchor<'a>>, Report> {
extra_ca_certs_filepath.map_or_else(
|| Ok(vec![]),
|filename| {
let mut file = open_file_or_stdin(&Some(filename))?;

let anchors = rustls_pemfile::certs(&mut file)
Expand All @@ -140,7 +154,6 @@ fn extra_ca_certs<'a>() -> Result<impl IntoIterator<Item = TrustAnchor<'a>>, Rep
.collect::<Result<Vec<_>, Report>>()?;

Ok(anchors)
}
None => Ok(vec![]),
}
},
)
}
Loading