From 6a6662195e85bbd990987ce6e541b048a6f4c194 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 29 May 2020 13:35:43 -0400 Subject: [PATCH] net: Add option to temporarily accept certs that failed the handshake. --- Cargo.lock | 1 + components/net/connector.rs | 6 +++- components/net/fetch/methods.rs | 46 ++++++++++++++++++------ components/net_traits/Cargo.toml | 1 + components/net_traits/lib.rs | 5 +++ components/script/dom/servoparser/mod.rs | 2 ++ resources/badcert.html | 21 ++++++++++- resources/servo.css | 4 +++ 8 files changed, 73 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56608679feb..7b13cfce465 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3609,6 +3609,7 @@ dependencies = [ "pixels", "serde", "servo_arc", + "servo_rand", "servo_url", "std_test_override", "time", diff --git a/components/net/connector.rs b/components/net/connector.rs index 41ab42e2184..0e47666f864 100644 --- a/components/net/connector.rs +++ b/components/net/connector.rs @@ -98,12 +98,16 @@ pub type Connector = HttpsConnector; pub type TlsConfig = SslConnectorBuilder; #[derive(Clone)] -pub struct ExtraCerts(pub Arc>>>); +pub struct ExtraCerts(Arc>>>); impl ExtraCerts { pub(crate) fn new() -> Self { Self(Arc::new(Mutex::new(vec![]))) } + + pub(crate) fn add(&self, bytes: Vec) { + self.0.lock().unwrap().push(bytes); + } } struct Host(String); diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index 457b462bc0b..a73255bf66b 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -25,7 +25,7 @@ use net_traits::request::{ use net_traits::request::{CredentialsMode, Destination, Referrer, Request, RequestMode}; use net_traits::response::{Response, ResponseBody, ResponseType}; use net_traits::{FetchTaskTarget, NetworkError, ReferrerPolicy, ResourceFetchTiming}; -use net_traits::{ResourceAttribute, ResourceTimeValue}; +use net_traits::{ResourceAttribute, ResourceTimeValue, ResourceTimingType}; use servo_arc::Arc as ServoArc; use servo_url::ServoUrl; use std::borrow::Cow; @@ -282,7 +282,10 @@ pub fn main_fetch( false }; - if (same_origin && !cors_flag) || current_url.scheme() == "data" { + if (same_origin && !cors_flag) || + current_url.scheme() == "data" || + current_url.scheme() == "chrome" + { // Substep 1. request.response_tainting = ResponseTainting::Basic; @@ -606,6 +609,17 @@ fn range_not_satisfiable_error(response: &mut Response) { response.raw_status = Some((StatusCode::RANGE_NOT_SATISFIABLE.as_u16(), reason.into())); } +fn create_blank_reply(url: ServoUrl, timing_type: ResourceTimingType) -> Response { + let mut response = Response::new(url, ResourceFetchTiming::new(timing_type)); + response + .headers + .typed_insert(ContentType::from(mime::TEXT_HTML_UTF_8)); + *response.body.lock().unwrap() = ResponseBody::Done(vec![]); + response.status = Some((StatusCode::OK, "OK".to_string())); + response.raw_status = Some((StatusCode::OK.as_u16(), b"OK".to_vec())); + response +} + /// [Scheme fetch](https://fetch.spec.whatwg.org#scheme-fetch) fn scheme_fetch( request: &mut Request, @@ -617,15 +631,25 @@ fn scheme_fetch( let url = request.current_url(); match url.scheme() { - "about" if url.path() == "blank" => { - let mut response = Response::new(url, ResourceFetchTiming::new(request.timing_type())); - response - .headers - .typed_insert(ContentType::from(mime::TEXT_HTML_UTF_8)); - *response.body.lock().unwrap() = ResponseBody::Done(vec![]); - response.status = Some((StatusCode::OK, "OK".to_string())); - response.raw_status = Some((StatusCode::OK.as_u16(), b"OK".to_vec())); - response + "about" if url.path() == "blank" => create_blank_reply(url, request.timing_type()), + + "chrome" if url.path() == "allowcert" => { + let mut secret = None; + let mut cert_bytes = None; + for (name, value) in url.as_url().query_pairs() { + match &*name { + "secret" => secret = Some(value), + "bytes" => cert_bytes = base64::decode(value.as_bytes()).ok(), + _ => (), + } + } + if let (Some(secret), Some(bytes)) = (secret, cert_bytes) { + if secret.parse() == Ok(*net_traits::PRIVILEGED_SECRET) { + context.state.extra_certs.add(bytes); + } + } + + create_blank_reply(url, request.timing_type()) }, "http" | "https" => http_fetch( diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml index 543d2b538c9..0e663b91bfd 100644 --- a/components/net_traits/Cargo.toml +++ b/components/net_traits/Cargo.toml @@ -33,6 +33,7 @@ piston_image = { package = "image", version = "0.23" } pixels = { path = "../pixels" } serde = "1.0" servo_arc = { path = "../servo_arc" } +servo_rand = { path = "../rand" } servo_url = { path = "../url" } time = "0.1" url = "2.0" diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index cd0f78013ba..6dea965d7f8 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -30,6 +30,7 @@ use ipc_channel::router::ROUTER; use ipc_channel::Error as IpcError; use mime::Mime; use msg::constellation_msg::HistoryStateId; +use servo_rand::RngCore; use servo_url::{ImmutableOrigin, ServoUrl}; use time::precise_time_ns; use webrender_api::{ImageData, ImageDescriptor, ImageKey}; @@ -811,3 +812,7 @@ impl WebrenderIpcSender { } } } + +lazy_static! { + pub static ref PRIVILEGED_SECRET: u32 = servo_rand::ServoRng::new().next_u32(); +} diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index d2d1831c490..3949f70c53e 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -821,6 +821,8 @@ impl FetchResponseListener for ParserContext { let page = page.replace("${reason}", &reason); let page = page.replace("${bytes}", std::str::from_utf8(&bytes).unwrap_or_default()); + let page = + page.replace("${secret}", &net_traits::PRIVILEGED_SECRET.to_string()); parser.push_string_input_chunk(page); parser.parse_sync(); } diff --git a/resources/badcert.html b/resources/badcert.html index 15fc425a376..9f37bcaa2a1 100644 --- a/resources/badcert.html +++ b/resources/badcert.html @@ -4,6 +4,25 @@

${reason}

-
${bytes}
+
${bytes}
+ + + diff --git a/resources/servo.css b/resources/servo.css index bc8d4f1223a..ed6bc3e93dd 100644 --- a/resources/servo.css +++ b/resources/servo.css @@ -1,3 +1,7 @@ +button { + cursor: default; +} + button, input { background: white;