From 3da348e128900ef629ebf47cee96cf5852124f9c Mon Sep 17 00:00:00 2001 From: Abdullah Alyan Date: Tue, 28 Nov 2023 17:11:15 +0300 Subject: [PATCH] DRAFT: Add support to http.sslVerify --- gix-transport/Cargo.toml | 2 +- .../client/blocking_io/http/curl/remote.rs | 3 + .../src/client/blocking_io/http/mod.rs | 2 + .../client/blocking_io/http/reqwest/remote.rs | 63 +++++++++++-------- gix/src/repository/config/transport.rs | 8 +++ .../repository/config/transport_options.rs | 4 ++ src/plumbing/progress.rs | 4 -- 7 files changed, 56 insertions(+), 30 deletions(-) diff --git a/gix-transport/Cargo.toml b/gix-transport/Cargo.toml index 7c5d6714313..53e8328b008 100644 --- a/gix-transport/Cargo.toml +++ b/gix-transport/Cargo.toml @@ -78,7 +78,7 @@ base64 = { version = "0.21.0", optional = true } curl = { version = "0.4", optional = true } # for http-client-reqwest -reqwest = { version = "0.11.12", optional = true, default-features = false, features = ["blocking"] } +reqwest = { version = "0.11.12", optional = true, default-features = false, features = ["blocking", "rustls-tls"] } ## If used in conjunction with `async-client`, the `connect()` method will become available along with supporting the git protocol over TCP, ## where the TCP stream is created using this crate. diff --git a/gix-transport/src/client/blocking_io/http/curl/remote.rs b/gix-transport/src/client/blocking_io/http/curl/remote.rs index e6b0bee03fe..1557f5a9cbd 100644 --- a/gix-transport/src/client/blocking_io/http/curl/remote.rs +++ b/gix-transport/src/client/blocking_io/http/curl/remote.rs @@ -157,6 +157,7 @@ pub fn new() -> ( verbose, ssl_ca_info, ssl_version, + ssl_verify, http_version, backend, }, @@ -194,6 +195,8 @@ pub fn new() -> ( } } + handle.ssl_verify_peer(ssl_verify)?; + if let Some(http_version) = http_version { let version = match http_version { HttpVersion::V1_1 => curl::easy::HttpVersion::V11, diff --git a/gix-transport/src/client/blocking_io/http/mod.rs b/gix-transport/src/client/blocking_io/http/mod.rs index 055b4ea591a..a7baf2c93ef 100644 --- a/gix-transport/src/client/blocking_io/http/mod.rs +++ b/gix-transport/src/client/blocking_io/http/mod.rs @@ -179,6 +179,8 @@ pub struct Options { pub ssl_ca_info: Option, /// The SSL version or version range to use, or `None` to let the TLS backend determine which versions are acceptable. pub ssl_version: Option, + /// Controls whether to perform ssl identity verification or not + pub ssl_verify: bool, /// The HTTP version to enforce. If unset, it is implementation defined. pub http_version: Option, /// Backend specific options, if available. diff --git a/gix-transport/src/client/blocking_io/http/reqwest/remote.rs b/gix-transport/src/client/blocking_io/http/reqwest/remote.rs index 7f8e8284604..5c86116329c 100644 --- a/gix-transport/src/client/blocking_io/http/reqwest/remote.rs +++ b/gix-transport/src/client/blocking_io/http/reqwest/remote.rs @@ -46,36 +46,43 @@ impl Default for Remote { // We may error while configuring, which is expected as part of the internal protocol. The error will be // received and the sender of the request might restart us. - let client = reqwest::blocking::ClientBuilder::new() - .connect_timeout(std::time::Duration::from_secs(20)) - .http1_title_case_headers() - .redirect(reqwest::redirect::Policy::custom({ - let allow_redirects = allow_redirects.clone(); - move |attempt| { - if allow_redirects.load(atomic::Ordering::Relaxed) { - let curr_url = attempt.url(); - let prev_urls = attempt.previous(); + fn setup_client_builder(allow_redirects: Arc) -> reqwest::blocking::ClientBuilder { + reqwest::blocking::ClientBuilder::new() + .connect_timeout(std::time::Duration::from_secs(20)) + .http1_title_case_headers() + .redirect(reqwest::redirect::Policy::custom({ + let allow_redirects = allow_redirects.clone(); + move |attempt| { + if allow_redirects.load(atomic::Ordering::Relaxed) { + let curr_url = attempt.url(); + let prev_urls = attempt.previous(); - match prev_urls.first() { - Some(prev_url) if prev_url.host_str() != curr_url.host_str() => { - // git does not want to be redirected to a different host. - attempt.stop() - } - _ => { - // emulate default git behaviour which relies on curl default behaviour apparently. - const CURL_DEFAULT_REDIRS: usize = 50; - if prev_urls.len() >= CURL_DEFAULT_REDIRS { - attempt.error("too many redirects") - } else { - attempt.follow() + match prev_urls.first() { + Some(prev_url) if prev_url.host_str() != curr_url.host_str() => { + // git does not want to be redirected to a different host. + attempt.stop() + } + _ => { + // emulate default git behaviour which relies on curl default behaviour apparently. + const CURL_DEFAULT_REDIRS: usize = 50; + if prev_urls.len() >= CURL_DEFAULT_REDIRS { + attempt.error("too many redirects") + } else { + attempt.follow() + } } } + } else { + attempt.stop() } - } else { - attempt.stop() } - } - })) + })) + } + + let client_ssl_verify = setup_client_builder(allow_redirects.clone()).build()?; + + let client_no_ssl_verify = setup_client_builder(allow_redirects.clone()) + .danger_accept_invalid_certs(false) .build()?; for Request { @@ -86,6 +93,12 @@ impl Default for Remote { config, } in req_recv { + let client = if config.ssl_verify { + &client_ssl_verify + } else { + &client_no_ssl_verify + }; + let effective_url = redirect::swap_tails(redirected_base_url.as_deref(), &base_url, url.clone()); let mut req_builder = if upload_body_kind.is_some() { client.post(&effective_url) diff --git a/gix/src/repository/config/transport.rs b/gix/src/repository/config/transport.rs index 99b5a7f47ff..1b1f06cbe1e 100644 --- a/gix/src/repository/config/transport.rs +++ b/gix/src/repository/config/transport.rs @@ -405,6 +405,14 @@ impl crate::Repository { } } + { + let key = "http.sslVerify"; + opts.ssl_verify = config + .boolean_filter_by_key(key, &mut trusted_only) + .and_then(Result::ok) + .unwrap_or(true) + } + #[cfg(feature = "blocking-http-transport-curl")] { let key = "http.schannelCheckRevoke"; diff --git a/gix/tests/repository/config/transport_options.rs b/gix/tests/repository/config/transport_options.rs index 85f7b8e6299..c47bb799484 100644 --- a/gix/tests/repository/config/transport_options.rs +++ b/gix/tests/repository/config/transport_options.rs @@ -55,6 +55,7 @@ mod http { verbose, ssl_ca_info, ssl_version, + ssl_verify, http_version, backend, } = http_options(&repo, None, "https://example.com/does/not/matter"); @@ -106,6 +107,9 @@ mod http { max: version }) ); + + assert!(ssl_verify); + assert_eq!(http_version, Some(HttpVersion::V1_1)); } diff --git a/src/plumbing/progress.rs b/src/plumbing/progress.rs index 21b56fa71d8..5a9f033ec55 100644 --- a/src/plumbing/progress.rs +++ b/src/plumbing/progress.rs @@ -408,10 +408,6 @@ static GIT_CONFIG: &[Record] = &[ config: "http.sslCipherList", usage: NotPlanned { reason: "on demand" } }, - Record { - config: "http.sslVerify", - usage: NotPlanned { reason: "on demand" } - }, Record { config: "http.sslCert", usage: NotPlanned { reason: "on demand" }