Use rustls-tls with manual SSL_CERT_FILE implementation

This commit is contained in:
Charlie Marsh 2024-03-10 22:12:36 -04:00
parent b9b4109ad8
commit 425bcb9e4b
4 changed files with 44 additions and 52 deletions

52
Cargo.lock generated
View File

@ -2857,7 +2857,6 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pin-project-lite", "pin-project-lite",
"rustls", "rustls",
"rustls-native-certs",
"rustls-pemfile", "rustls-pemfile",
"serde", "serde",
"serde_json", "serde_json",
@ -2873,6 +2872,7 @@ dependencies = [
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-streams", "wasm-streams",
"web-sys", "web-sys",
"webpki-roots",
"winreg", "winreg",
] ]
@ -3092,18 +3092,6 @@ dependencies = [
"sct", "sct",
] ]
[[package]]
name = "rustls-native-certs"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
dependencies = [
"openssl-probe",
"rustls-pemfile",
"schannel",
"security-framework",
]
[[package]] [[package]]
name = "rustls-pemfile" name = "rustls-pemfile"
version = "1.0.4" version = "1.0.4"
@ -3160,15 +3148,6 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "schannel"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534"
dependencies = [
"windows-sys 0.52.0",
]
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@ -3211,29 +3190,6 @@ version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "security-framework"
version = "2.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de"
dependencies = [
"bitflags 1.3.2",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.197" version = "1.0.197"
@ -4915,6 +4871,12 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "webpki-roots"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
[[package]] [[package]]
name = "weezl" name = "weezl"
version = "0.1.8" version = "0.1.8"

View File

@ -76,7 +76,7 @@ rand = { version = "0.8.5" }
rayon = { version = "1.8.0" } rayon = { version = "1.8.0" }
reflink-copy = { version = "0.1.14" } reflink-copy = { version = "0.1.14" }
regex = { version = "1.10.2" } regex = { version = "1.10.2" }
reqwest = { version = "0.11.23", default-features = false, features = ["json", "gzip", "brotli", "stream", "rustls-tls-native-roots"] } reqwest = { version = "0.11.23", default-features = false, features = ["json", "gzip", "brotli", "stream", "rustls-tls"] }
reqwest-middleware = { version = "0.2.4" } reqwest-middleware = { version = "0.2.4" }
reqwest-retry = { version = "0.3.0" } reqwest-retry = { version = "0.3.0" }
rkyv = { version = "0.7.43", features = ["strict", "validation"] } rkyv = { version = "0.7.43", features = ["strict", "validation"] }

View File

@ -1,8 +1,10 @@
use std::ffi::OsStr;
use std::fmt::Debug; use std::fmt::Debug;
use std::io::Read;
use http::HeaderValue; use http::HeaderValue;
use netrc::{Netrc, Result}; use netrc::Netrc;
use reqwest::{Request, Response}; use reqwest::{Certificate, Request, Response};
use reqwest_middleware::{Middleware, Next}; use reqwest_middleware::{Middleware, Next};
use task_local_extensions::Extensions; use task_local_extensions::Extensions;
use url::Url; use url::Url;
@ -56,7 +58,7 @@ pub(crate) struct NetrcMiddleware {
} }
impl NetrcMiddleware { impl NetrcMiddleware {
pub(crate) fn new() -> Result<Self> { pub(crate) fn new() -> netrc::Result<Self> {
Netrc::new().map(|nrc| NetrcMiddleware { nrc }) Netrc::new().map(|nrc| NetrcMiddleware { nrc })
} }
} }
@ -121,3 +123,18 @@ where
header.set_sensitive(true); header.set_sensitive(true);
header header
} }
#[derive(thiserror::Error, Debug)]
pub(crate) enum CertificateError {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Reqwest(#[from] reqwest::Error),
}
/// Return the `Certificate` from the provided file.
pub(crate) fn read_certificate(ssl_cert_file: &OsStr) -> Result<Certificate, CertificateError> {
let mut buf = Vec::new();
fs_err::File::open(ssl_cert_file)?.read_to_end(&mut buf)?;
Ok(Certificate::from_pem(&buf)?)
}

View File

@ -29,7 +29,7 @@ use uv_warnings::warn_user_once;
use crate::cached_client::CacheControl; use crate::cached_client::CacheControl;
use crate::html::SimpleHtml; use crate::html::SimpleHtml;
use crate::middleware::{NetrcMiddleware, OfflineMiddleware}; use crate::middleware::{read_certificate, NetrcMiddleware, OfflineMiddleware};
use crate::remote_metadata::wheel_metadata_from_remote_zip; use crate::remote_metadata::wheel_metadata_from_remote_zip;
use crate::rkyvutil::OwnedArchive; use crate::rkyvutil::OwnedArchive;
use crate::{CachedClient, CachedClientError, Error, ErrorKind}; use crate::{CachedClient, CachedClientError, Error, ErrorKind};
@ -111,12 +111,25 @@ impl RegistryClientBuilder {
// Initialize the base client. // Initialize the base client.
let client = self.client.unwrap_or_else(|| { let client = self.client.unwrap_or_else(|| {
// Disallow any connections. // Disallow any connections.
let client_core = ClientBuilder::new() let builder = ClientBuilder::new()
.user_agent(user_agent_string) .user_agent(user_agent_string)
.pool_max_idle_per_host(20) .pool_max_idle_per_host(20)
.timeout(std::time::Duration::from_secs(timeout)); .timeout(std::time::Duration::from_secs(timeout));
client_core.build().expect("Failed to build HTTP client.") // Add the `SSL_CERT_FILE`, if set.
let builder = if let Some(ssl_cert_file) = env::var_os("SSL_CERT_FILE") {
match read_certificate(&ssl_cert_file) {
Ok(certificate) => builder.add_root_certificate(certificate),
Err(err) => {
warn!("Failed to read SSL certificate file: {err}");
builder
}
}
} else {
builder
};
builder.build().expect("Failed to build HTTP client.")
}); });
// Wrap in any relevant middleware. // Wrap in any relevant middleware.