Skip to content

Commit

Permalink
servo: Merge #14716 - Implement HSTS fetch step (from mrnayak:hsts); …
Browse files Browse the repository at this point in the history
…r=jdm

Implemented step nine of the main fetch. If current URL scheme is 'HTTP' and
current URL's host is domain and if current URL's host matched with Known
HSTS Host Domain Name Matching results in either a superdomain match with
an asserted includeSubDomains directive or a congruent match then we
change request scheme to 'https'. This change has been made in method.rs

A test case to validate this has been added in fetch.rs. For asserting
https scheme, a https localhost was required. For this purpose I have
created a self-signed certificate and refactored fetch-context and
connector.rs to programmatically trust this certificate for running this
test case.

This should fix servo/servo#14363
<!-- Please describe your changes on the following line: -->

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [X] `./mach build -d` does not report any errors
- [X] `./mach test-tidy` does not report any errors
- [X] These changes fix #14363

<!-- Either: -->
- [X] There are tests for these changes

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

Source-Repo: https://github.com/servo/servo
Source-Revision: c7991d596f7453d09c2b2a98eecce72f182a4e24

UltraBlame original commit: fb3cb6e8f720e2772efba1fae1ea4dc87b8e8a72
  • Loading branch information
marco-c committed Oct 1, 2019
1 parent 1e8fab4 commit c65e0f2
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 9 deletions.
4 changes: 2 additions & 2 deletions servo/components/net/connector.rs
Expand Up @@ -27,11 +27,11 @@ const DEFAULT_CIPHERS: &'static str = concat!(
"AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA"
);

pub fn create_http_connector() -> Arc<Pool<Connector>> {
pub fn create_http_connector(certificate_file: &str) -> Arc<Pool<Connector>> {
let mut context = SslContext::new(SslMethod::Sslv23).unwrap();
context.set_CA_file(&resources_dir_path()
.expect("Need certificate file to make network requests")
.join("certs")).unwrap();
.join(certificate_file)).unwrap();
context.set_cipher_list(DEFAULT_CIPHERS).unwrap();
context.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION);
let connector = HttpsConnector::new(ServoSslClient {
Expand Down
10 changes: 9 additions & 1 deletion servo/components/net/fetch/methods.rs
Expand Up @@ -189,7 +189,15 @@ pub fn main_fetch(request: Rc<Request>,
}



if !request.current_url().is_secure_scheme() && request.current_url().domain().is_some() {
if context.state
.hsts_list
.read()
.unwrap()
.is_host_secure(request.current_url().domain().unwrap()) {
request.url_list.borrow_mut().last_mut().unwrap().as_mut_url().unwrap().set_scheme("https").unwrap();
}
}



Expand Down
4 changes: 2 additions & 2 deletions servo/components/net/http_loader.rs
Expand Up @@ -76,13 +76,13 @@ pub struct HttpState {
}

impl HttpState {
pub fn new() -> HttpState {
pub fn new(certificate_path: &str) -> HttpState {
HttpState {
hsts_list: Arc::new(RwLock::new(HstsList::new())),
cookie_jar: Arc::new(RwLock::new(CookieStorage::new(150))),
auth_cache: Arc::new(RwLock::new(AuthCache::new())),
blocked_content: Arc::new(None),
connector_pool: create_http_connector(),
connector_pool: create_http_connector(certificate_path),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions servo/components/net/resource_thread.rs
Expand Up @@ -109,13 +109,13 @@ fn create_resource_groups(config_dir: Option<&Path>)
cookie_jar: Arc::new(RwLock::new(cookie_jar)),
auth_cache: Arc::new(RwLock::new(auth_cache)),
hsts_list: Arc::new(RwLock::new(hsts_list.clone())),
connector: create_http_connector(),
connector: create_http_connector("certs"),
};
let private_resource_group = ResourceGroup {
cookie_jar: Arc::new(RwLock::new(CookieStorage::new(150))),
auth_cache: Arc::new(RwLock::new(AuthCache::new())),
hsts_list: Arc::new(RwLock::new(HstsList::new())),
connector: create_http_connector(),
connector: create_http_connector("certs"),
};
(resource_group, private_resource_group)
}
Expand Down
28 changes: 28 additions & 0 deletions servo/resources/privatekey_for_testing.key
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+CuREmlBxE/Ca
amA/y5LJ9RdF4hyJv3/alew/X/x1BiZNdajO1O2VEfIG0iU9terLOg2l8IfuG+Eb
FTOnBIcmGo0vl5OmwEZ1Uhvla+FPqXtOEWEVVnC7/aA+H2GCsp97/2dssMi8//Fl
Mk0UXHvkhjXPO3dwpSiVfIzU2LYXYgua6JFnCG0u629EO61fNF15WoA6seoH1a2t
gTLCsQbapNfUek2T9TCohk2jpkOHxnZNn/KnuM2Anw3N6Ski0Bj+doj/r9xF9CHH
NBng51UMkIGClEJqGj9yzquBd45c09LoG4OAXZKyoQ6q6utidCVYbKh7RaLoHuoq
isg2mUbHAgMBAAECggEBAIIL0/76Flf7DCeu6aReO1nGRSHGRD8i82vyMhOALLMr
/SP+gwDehqH/AL8YKPHcvgpJ9LL8MRiIrXcqAAmnuJAjlT/fGuP+KXj5MivBshIg
aUeX7vZ6C3UpbvFz6fdVInvo365qH0PuZRMZ49MuIn3UNZhVGjvUWTxKWdkBX0IJ
3+aKPEOcx5MInZTr/rNttQq4h898JVM80mzsUBzUzbUgUXJ0vgVyXSBJKGP6PMP2
pFs/X6QRAvqR69pZ2DarztG7G5EJq2sT2Nymfg4isETiRFM75bPRAmCr+eJQdY7f
jGpxhcTCO0dEP3WgG3M6ZNhtKO4vsm3PhdE06fFdxikCgYEA8GP45n/Yiu272dvX
iKNxYWQ1Yv7A04T7QN8+930/AXIkDw9k86zAstU6Wo47CKseZCKoNMxLO/eD+7tm
SqiMxNEUuxmwb8YYwH/aX27uIdKDahgY6SwLHYFFrBAxU+pm0HVGgLDn6VKPs/db
R31KbJgPr9i2oV1Rt2vha60UIcMCgYEAymH7UEpZ8QRxW1h6lzX/LoTHZHB5t5R5
UUDR7SErbeM4SpPsJtR2ZuWriW2TAEhBbxgGAGhctLfbdeuYAO+F0PaZlYW/sZx6
Ei0OWhdd+k/QVj0VHQWCN2oKfjpRj1yYwCcGt7Xei7B0aXVE2A5Aj2bLU+Q9i4x9
0h3Dac06Uq0CgYA8lLUxQZ7MxETHDoQuxyHXrW1W2WS26Zh4LMqtjD7Imn9D3FlQ
n4SgjOP71kRCVv19ts41IBcFscbtNbj9r6RqJVbYIA063e129cGOs2IH3AmKPzBn
8tWKRf3M8ve7ciMe/a8a13pabpgQfpHeXlDXNSse4bqEyAPD+cgBXsjoCQKBgC1q
jY44ETUADTw1f9U9HdXfoCtO/lGPNSZhyHpRbkCLtA8wYNdZ6HQw6Cy/9TQkAuMe
XgJraRp5A/vTcdoL5li9bjvatujxt4cqq0TWZ5WLobIopPtNSCqNVmt7ROBKJFFC
sMQ7QQTSBV3BHkDp+dz0cX6TAqi1T2r+mOK+Vm9FAoGACIFwOYapBqeDsPwhUiRl
sud+oD28TwbCbQoEVhy5ZoZQZ9S4t7eUaVEYyt/aW1EfeREtvaM5/9DsSmi9f+pw
02XIkZQJplLTDD/0uaCxk0pSJdP9eXkYAEQvEMXs0ING3qIaro2eSVNlO4On9+RY
sz4GyDlleF1ZMsMCTRiNqmg=
-----END PRIVATE KEY-----
22 changes: 22 additions & 0 deletions servo/resources/self_signed_certificate_for_testing.crt
@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDlzCCAn+gAwIBAgIJAMVJtbFvDf6vMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV
BAYTAlVTMQswCQYDVQQIDAJOQzEQMA4GA1UEBwwHUmFsZWlnaDEQMA4GA1UECgwH
TW96aWxsYTEOMAwGA1UECwwFU2Vydm8xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0x
NjEyMjMwNTMyMzFaFw0xNzEyMjMwNTMyMzFaMGIxCzAJBgNVBAYTAlVTMQswCQYD
VQQIDAJOQzEQMA4GA1UEBwwHUmFsZWlnaDEQMA4GA1UECgwHTW96aWxsYTEOMAwG
A1UECwwFU2Vydm8xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAL4K5ESaUHET8JpqYD/Lksn1F0XiHIm/f9qV7D9f/HUG
Jk11qM7U7ZUR8gbSJT216ss6DaXwh+4b4RsVM6cEhyYajS+Xk6bARnVSG+Vr4U+p
e04RYRVWcLv9oD4fYYKyn3v/Z2ywyLz/8WUyTRRce+SGNc87d3ClKJV8jNTYthdi
C5rokWcIbS7rb0Q7rV80XXlagDqx6gfVra2BMsKxBtqk19R6TZP1MKiGTaOmQ4fG
dk2f8qe4zYCfDc3pKSLQGP52iP+v3EX0Icc0GeDnVQyQgYKUQmoaP3LOq4F3jlzT
0ugbg4BdkrKhDqrq62J0JVhsqHtFouge6iqKyDaZRscCAwEAAaNQME4wHQYDVR0O
BBYEFF3/tb9Rfmn4MZ+wepwmZpp/wfkDMB8GA1UdIwQYMBaAFF3/tb9Rfmn4MZ+w
epwmZpp/wfkDMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAD+xK7U/
21bGNLyadlU/4+IZR1ABe0m8QfWNgwIQZGLGOkaiBg8EGzSuyc01uFv6EfnEBXCX
hEs/cc3JA4LDvGQIgkM8yqEJHsFED2X8sNFs9WiTFM2hCeLwcSNAiJYnOwPXKc+t
ObS5CIFZb2yGfgwv0/zTw7mdQNmdk7LiYlOa9EivvuzG/elT76pijWR5ISKUuOeh
JWmGwZb+XimM5DrCfDQ8cdPSMcnb1Jvkf/Rq1UfnBvvuPmI9XJ2MTnLbn6iwugqE
/+lVNcS8FmPZO1R/jhtU44nKhJvT7FgXuisTPrcTi0WdqjVnQAN3ZeUAFZeVfwan
trAwXF0Zvul1HqE=
-----END CERTIFICATE-----
52 changes: 51 additions & 1 deletion servo/tests/unit/net/fetch.rs
Expand Up @@ -18,11 +18,17 @@ use hyper::header::{Encoding, Location, Pragma, Quality, QualityItem, SetCookie,
use hyper::header::{Headers, Host, HttpDate, Referer as HyperReferer};
use hyper::method::Method;
use hyper::mime::{Mime, SubLevel, TopLevel};
use hyper::server::{Request as HyperRequest, Response as HyperResponse};
use hyper::net::Openssl;
use hyper::server::{Request as HyperRequest, Response as HyperResponse, Server};
use hyper::status::StatusCode;
use hyper::uri::RequestUri;
use msg::constellation_msg::TEST_PIPELINE_ID;
use net::fetch::cors_cache::CorsCache;
use net::fetch::methods::FetchContext;
use net::filemanager_thread::FileManager;
use net::hsts::HstsEntry;
use net::test::HttpState;
use net_traits::IncludeSubdomains;
use net_traits::NetworkError;
use net_traits::ReferrerPolicy;
use net_traits::request::{Origin, RedirectMode, Referrer, Request, RequestMode};
Expand Down Expand Up @@ -506,6 +512,50 @@ fn test_fetch_with_local_urls_only() {
assert!(server_response.is_network_error());
}

#[test]
fn test_fetch_with_hsts() {
static MESSAGE: &'static [u8] = b"";
let handler = move |_: HyperRequest, response: HyperResponse| {
response.send(MESSAGE).unwrap();
};

let path = resources_dir_path().expect("Cannot find resource dir");
let mut cert_path = path.clone();
cert_path.push("self_signed_certificate_for_testing.crt");

let mut key_path = path.clone();
key_path.push("privatekey_for_testing.key");

let ssl = Openssl::with_cert_and_key(cert_path.into_os_string(), key_path.into_os_string())
.unwrap();

let mut server = Server::https("0.0.0.0:0", ssl).unwrap().handle_threads(handler, 1).unwrap();

let context = FetchContext {
state: HttpState::new("self_signed_certificate_for_testing.crt"),
user_agent: DEFAULT_USER_AGENT.into(),
devtools_chan: None,
filemanager: FileManager::new(),
};

{
let mut list = context.state.hsts_list.write().unwrap();
list.push(HstsEntry::new("localhost".to_owned(), IncludeSubdomains::NotIncluded, None)
.unwrap());
}
let url_string = format!("http://localhost:{}", server.socket.port());
let url = ServoUrl::parse(&url_string).unwrap();
let origin = Origin::Origin(url.origin());
let mut request = Request::new(url, Some(origin), false, None);
*request.referrer.borrow_mut() = Referrer::NoReferrer;

request.local_urls_only = false;
let response = fetch_with_context(request, &context);
let _ = server.close();
assert_eq!(response.internal_response.unwrap().url().unwrap().scheme(),
"https");
}

fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response {
let handler = move |request: HyperRequest, mut response: HyperResponse| {
let redirects = match request.uri {
Expand Down
2 changes: 1 addition & 1 deletion servo/tests/unit/net/lib.rs
Expand Up @@ -55,7 +55,7 @@ struct FetchResponseCollector {

fn new_fetch_context(dc: Option<Sender<DevtoolsControlMsg>>) -> FetchContext {
FetchContext {
state: HttpState::new(),
state: HttpState::new("certs"),
user_agent: DEFAULT_USER_AGENT.into(),
devtools_chan: dc,
filemanager: FileManager::new(),
Expand Down

0 comments on commit c65e0f2

Please sign in to comment.