Only use the resource manager's HSTS list.

Simplifies a bunch of stuff.
This commit is contained in:
Sam Gibson 2015-08-15 17:22:45 +10:00
parent ffc3877deb
commit c093ce8a5a
4 changed files with 81 additions and 68 deletions

View file

@ -9,7 +9,7 @@ use net_traits::ProgressMsg::{Payload, Done};
use net_traits::hosts::replace_hosts;
use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, LoadConsumer, IncludeSubdomains};
use resource_task::{start_sending_opt, start_sending_sniffed_opt};
use hsts::{HSTSList, secure_url};
use hsts::secure_url;
use file_loader;
use file_loader;
@ -37,7 +37,6 @@ use std::collections::HashSet;
use std::error::Error;
use std::io::{self, Read, Write};
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::mpsc::{Sender, channel};
use util::task::spawn_named;
use util::resource_files::resources_dir_path;
@ -52,12 +51,11 @@ use uuid;
use std::fs::File;
pub fn factory(resource_mgr_chan: IpcSender<ControlMsg>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<Mutex<HSTSList>>)
devtools_chan: Option<Sender<DevtoolsControlMsg>>)
-> Box<FnBox(LoadData, LoadConsumer, Arc<MIMEClassifier>) + Send> {
box move |load_data, senders, classifier| {
spawn_named(format!("http_loader for {}", load_data.url.serialize()),
move || load_for_consumer(load_data, senders, classifier, resource_mgr_chan, devtools_chan, hsts_list))
move || load_for_consumer(load_data, senders, classifier, resource_mgr_chan, devtools_chan))
}
}
@ -89,15 +87,6 @@ fn read_block<R: Read>(reader: &mut R) -> Result<ReadResult, ()> {
}
}
fn request_must_be_secured(hsts_list: &HSTSList, url: &Url) -> bool {
match url.domain() {
Some(ref h) => {
hsts_list.is_host_secure(h)
},
_ => false
}
}
fn inner_url(url: &Url) -> Url {
let inner_url = url.non_relative_scheme_data().unwrap();
Url::parse(inner_url).unwrap()
@ -107,10 +96,9 @@ fn load_for_consumer(load_data: LoadData,
start_chan: LoadConsumer,
classifier: Arc<MIMEClassifier>,
resource_mgr_chan: IpcSender<ControlMsg>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<Mutex<HSTSList>>) {
devtools_chan: Option<Sender<DevtoolsControlMsg>>) {
match load::<WrappedHttpRequest>(load_data, resource_mgr_chan, devtools_chan, hsts_list, &NetworkHttpRequestFactory) {
match load::<WrappedHttpRequest>(load_data, resource_mgr_chan, devtools_chan, &NetworkHttpRequestFactory) {
Err(LoadError::UnsupportedScheme(url)) => {
let s = format!("{} request, but we don't support that scheme", &*url.scheme);
send_error(url, s, start_chan)
@ -320,10 +308,18 @@ fn set_cookies_from_response(url: Url, response: &HttpResponse, resource_mgr_cha
}
}
fn request_must_be_secured(url: &Url, resource_mgr_chan: &IpcSender<ControlMsg>) -> bool {
let (tx, rx) = ipc::channel().unwrap();
resource_mgr_chan.send(
ControlMsg::GetHostMustBeSecured(url.domain().unwrap().to_string(), tx)
).unwrap();
rx.recv().unwrap()
}
pub fn load<A>(mut load_data: LoadData,
resource_mgr_chan: IpcSender<ControlMsg>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<Mutex<HSTSList>>,
request_factory: &HttpRequestFactory<R=A>)
-> Result<(Box<Read>, Metadata), LoadError> where A: HttpRequest + 'static {
// FIXME: At the time of writing this FIXME, servo didn't have any central
@ -352,7 +348,7 @@ pub fn load<A>(mut load_data: LoadData,
loop {
iters = iters + 1;
if &*url.scheme != "https" && request_must_be_secured(&hsts_list.lock().unwrap(), &url) {
if &*url.scheme != "https" && request_must_be_secured(&url, &resource_mgr_chan) {
info!("{} is in the strict transport security list, requesting secure host", url);
url = secure_url(&url);
}

View file

@ -29,7 +29,6 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use std::borrow::ToOwned;
use std::boxed::FnBox;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::mpsc::{channel, Sender};
pub enum ProgressSender {
@ -161,23 +160,26 @@ impl ResourceChannelManager {
fn start(&mut self) {
loop {
match self.from_client.recv().unwrap() {
ControlMsg::Load(load_data, consumer) => {
self.resource_manager.load(load_data, consumer)
}
ControlMsg::SetCookiesForUrl(request, cookie_list, source) => {
self.resource_manager.set_cookies_for_url(request, cookie_list, source)
}
ControlMsg::GetCookiesForUrl(url, consumer, source) => {
consumer.send(self.resource_manager.cookie_storage.cookies_for_url(&url, source)).unwrap();
}
ControlMsg::SetHSTSEntryForHost(host, include_subdomains, max_age) => {
if let Some(entry) = HSTSEntry::new(host, include_subdomains, Some(max_age)) {
self.resource_manager.add_hsts_entry(entry)
}
}
ControlMsg::Exit => {
break
}
ControlMsg::Load(load_data, consumer) => {
self.resource_manager.load(load_data, consumer)
}
ControlMsg::SetCookiesForUrl(request, cookie_list, source) => {
self.resource_manager.set_cookies_for_url(request, cookie_list, source)
}
ControlMsg::GetCookiesForUrl(url, consumer, source) => {
consumer.send(self.resource_manager.cookie_storage.cookies_for_url(&url, source)).unwrap();
}
ControlMsg::SetHSTSEntryForHost(host, include_subdomains, max_age) => {
if let Some(entry) = HSTSEntry::new(host, include_subdomains, Some(max_age)) {
self.resource_manager.add_hsts_entry(entry)
}
}
ControlMsg::GetHostMustBeSecured(host, consumer) => {
consumer.send(self.resource_manager.is_host_sts(&*host)).unwrap();
}
ControlMsg::Exit => {
break
}
}
}
}
@ -189,7 +191,7 @@ pub struct ResourceManager {
resource_task: IpcSender<ControlMsg>,
mime_classifier: Arc<MIMEClassifier>,
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
hsts_list: Arc<Mutex<HSTSList>>
hsts_list: HSTSList
}
impl ResourceManager {
@ -203,7 +205,7 @@ impl ResourceManager {
resource_task: resource_task,
mime_classifier: Arc::new(MIMEClassifier::new()),
devtools_chan: devtools_channel,
hsts_list: Arc::new(Mutex::new(hsts_list))
hsts_list: hsts_list
}
}
}
@ -221,11 +223,11 @@ impl ResourceManager {
}
pub fn add_hsts_entry(&mut self, entry: HSTSEntry) {
self.hsts_list.lock().unwrap().push(entry);
self.hsts_list.push(entry);
}
pub fn is_host_sts(&self, host: &str) -> bool {
self.hsts_list.lock().unwrap().is_host_secure(host)
self.hsts_list.is_host_secure(host)
}
fn load(&mut self, mut load_data: LoadData, consumer: LoadConsumer) {
@ -241,7 +243,7 @@ impl ResourceManager {
let loader = match &*load_data.url.scheme {
"file" => from_factory(file_loader::factory),
"http" | "https" | "view-source" =>
http_loader::factory(self.resource_task.clone(), self.devtools_chan.clone(), self.hsts_list.clone()),
http_loader::factory(self.resource_task.clone(), self.devtools_chan.clone()),
"data" => from_factory(data_loader::factory),
"about" => from_factory(about_loader::factory),
_ => {

View file

@ -161,6 +161,7 @@ pub enum ControlMsg {
GetCookiesForUrl(Url, IpcSender<Option<String>>, CookieSource),
/// Store a domain's STS information
SetHSTSEntryForHost(String, IncludeSubdomains, u64),
GetHostMustBeSecured(String, IpcSender<bool>),
Exit
}