Allowing connections only from chrome-extension and self-hosted client
This commit is contained in:
parent
9572f6e5fc
commit
302126ebcf
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1448,7 +1448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ws"
|
name = "ws"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
source = "git+https://github.com/ethcore/ws-rs.git#c0c2a3fc30dc77c4e6d4d90756f8bc3b5cfbc311"
|
source = "git+https://github.com/ethcore/ws-rs.git#5b28de58421b017b01f4565b2c35a46679707789"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -95,7 +95,8 @@ impl Server {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create WebSocket
|
// Create WebSocket
|
||||||
let ws = try!(ws::Builder::new().with_settings(config).build(session::Factory::new(handler)));
|
let origin = format!("{}", addr);
|
||||||
|
let ws = try!(ws::Builder::new().with_settings(config).build(session::Factory::new(handler, origin)));
|
||||||
|
|
||||||
let panic_handler = PanicHandler::new_in_arc();
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
let ph = panic_handler.clone();
|
let ph = panic_handler.clone();
|
||||||
|
@ -21,13 +21,46 @@ use sysui;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
|
|
||||||
|
fn origin_is_allowed(self_origin: &str, header: Option<&Vec<u8>>) -> bool {
|
||||||
|
match header {
|
||||||
|
None => false,
|
||||||
|
Some(h) => {
|
||||||
|
let v = String::from_utf8(h.clone()).ok();
|
||||||
|
match v {
|
||||||
|
Some(ref origin) if origin.starts_with("chrome-extension://") => true,
|
||||||
|
Some(ref origin) if origin.starts_with(self_origin) => true,
|
||||||
|
Some(ref origin) if origin.starts_with(&format!("http://{}", self_origin)) => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn auth_is_valid(_header: Option<&Vec<u8>>) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Session {
|
pub struct Session {
|
||||||
out: ws::Sender,
|
out: ws::Sender,
|
||||||
|
self_origin: String,
|
||||||
handler: Arc<IoHandler>,
|
handler: Arc<IoHandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ws::Handler for Session {
|
impl ws::Handler for Session {
|
||||||
fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
|
fn on_request(&mut self, req: &ws::Request) -> ws::Result<(ws::Response)> {
|
||||||
|
let origin = req.header("origin").or_else(|| req.header("Origin"));
|
||||||
|
let host = req.header("host").or_else(|| req.header("Host"));
|
||||||
|
|
||||||
|
// Check request origin and host header.
|
||||||
|
if !origin_is_allowed(&self.self_origin, origin) && !origin_is_allowed(&self.self_origin, host) {
|
||||||
|
return Ok(ws::Response::forbidden("You are not allowed to access system ui.".into()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check authorization
|
||||||
|
if !auth_is_valid(req.header("authorization")) {
|
||||||
|
return Ok(ws::Response::forbidden("You are not authorized.".into()));
|
||||||
|
}
|
||||||
|
|
||||||
// Detect if it's a websocket request.
|
// Detect if it's a websocket request.
|
||||||
if req.header("sec-websocket-key").is_some() {
|
if req.header("sec-websocket-key").is_some() {
|
||||||
return ws::Response::from_request(req);
|
return ws::Response::from_request(req);
|
||||||
@ -37,7 +70,7 @@ impl ws::Handler for Session {
|
|||||||
sysui::handle(req.resource())
|
sysui::handle(req.resource())
|
||||||
.map_or_else(
|
.map_or_else(
|
||||||
// return error
|
// return error
|
||||||
|| ws::Response::from_request(req),
|
|| Ok(ws::Response::not_found("Page not found".into())),
|
||||||
// or serve the file
|
// or serve the file
|
||||||
|f| {
|
|f| {
|
||||||
let content_len = format!("{}", f.content.as_bytes().len());
|
let content_len = format!("{}", f.content.as_bytes().len());
|
||||||
@ -67,12 +100,14 @@ impl ws::Handler for Session {
|
|||||||
|
|
||||||
pub struct Factory {
|
pub struct Factory {
|
||||||
handler: Arc<IoHandler>,
|
handler: Arc<IoHandler>,
|
||||||
|
self_origin: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Factory {
|
impl Factory {
|
||||||
pub fn new(handler: Arc<IoHandler>) -> Self {
|
pub fn new(handler: Arc<IoHandler>, self_origin: String) -> Self {
|
||||||
Factory {
|
Factory {
|
||||||
handler: handler,
|
handler: handler,
|
||||||
|
self_origin: self_origin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,6 +118,7 @@ impl ws::Factory for Factory {
|
|||||||
fn connection_made(&mut self, sender: ws::Sender) -> Self::Handler {
|
fn connection_made(&mut self, sender: ws::Sender) -> Self::Handler {
|
||||||
Session {
|
Session {
|
||||||
out: sender,
|
out: sender,
|
||||||
|
self_origin: self.self_origin.clone(),
|
||||||
handler: self.handler.clone(),
|
handler: self.handler.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user