Development mode for Signer UI (#1788)
* Development mode for Signer * CLI option for signer-dev * Renaming CLI option * Make obvious that CLI option is insecure. [ci:skip] * Additional warning over security
This commit is contained in:
parent
9de579366a
commit
0c7ab34c32
@ -57,8 +57,8 @@ default = ["ui", "use-precompiled-js"]
|
||||
ui = ["dapps", "ethcore-signer/ui"]
|
||||
use-precompiled-js = ["ethcore-dapps/use-precompiled-js", "ethcore-signer/use-precompiled-js"]
|
||||
dapps = ["ethcore-dapps"]
|
||||
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethcore-dapps/dev", "ethcore-signer/dev"]
|
||||
ipc = ["ethcore/ipc"]
|
||||
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethcore-dapps/dev", "ethcore-signer/dev"]
|
||||
json-tests = ["ethcore/json-tests"]
|
||||
|
||||
[[bin]]
|
||||
|
@ -74,6 +74,9 @@ Account Options:
|
||||
[default: 8180].
|
||||
--signer-path PATH Specify directory where Signer UIs tokens should
|
||||
be stored. [default: $HOME/.parity/signer]
|
||||
--signer-no-validation Disable Origin and Host headers validation for
|
||||
Trusted Signer. WARNING: INSECURE. Used only for
|
||||
development.
|
||||
|
||||
Networking Options:
|
||||
--no-network Disable p2p networking.
|
||||
@ -212,7 +215,7 @@ Footprint Options:
|
||||
the entire system, overrides other cache and queue
|
||||
options.
|
||||
--fast-and-loose Disables DB WAL, which gives a significant speed up
|
||||
but means an unclean exit is unrecoverable.
|
||||
but means an unclean exit is unrecoverable.
|
||||
--db-compaction TYPE Database compaction type. TYPE may be one of:
|
||||
ssd - suitable for SSDs and fast HDDs;
|
||||
hdd - suitable for slow HDDs [default: ssd].
|
||||
@ -337,6 +340,7 @@ pub struct Args {
|
||||
pub flag_no_signer: bool,
|
||||
pub flag_signer_port: u16,
|
||||
pub flag_signer_path: String,
|
||||
pub flag_signer_no_validation: bool,
|
||||
pub flag_force_sealing: bool,
|
||||
pub flag_reseal_on_txs: String,
|
||||
pub flag_reseal_min_period: u64,
|
||||
|
@ -303,6 +303,7 @@ impl Configuration {
|
||||
enabled: self.signer_enabled(),
|
||||
port: self.args.flag_signer_port,
|
||||
signer_path: self.directories().signer,
|
||||
skip_origin_validation: self.args.flag_signer_no_validation,
|
||||
}
|
||||
}
|
||||
|
||||
@ -789,6 +790,19 @@ mod tests {
|
||||
assert_eq!(conf0.signer_enabled(), false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_parse_signer_allow_all_flag() {
|
||||
// given
|
||||
|
||||
// when
|
||||
let conf0 = parse(&["parity", "--signer-no-validation"]);
|
||||
let conf1 = parse(&["parity"]);
|
||||
|
||||
// then
|
||||
assert_eq!(conf0.args.flag_signer_no_validation, true);
|
||||
assert_eq!(conf1.args.flag_signer_no_validation, false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_not_bail_on_empty_line_in_reserved_peers() {
|
||||
let temp = RandomTempPath::new();
|
||||
|
@ -32,6 +32,7 @@ pub struct Configuration {
|
||||
pub enabled: bool,
|
||||
pub port: u16,
|
||||
pub signer_path: String,
|
||||
pub skip_origin_validation: bool,
|
||||
}
|
||||
|
||||
impl Default for Configuration {
|
||||
@ -40,6 +41,7 @@ impl Default for Configuration {
|
||||
enabled: true,
|
||||
port: 8180,
|
||||
signer_path: replace_home("$HOME/.parity/signer"),
|
||||
skip_origin_validation: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,6 +91,11 @@ fn do_start(conf: Configuration, deps: Dependencies) -> Result<SignerServer, Str
|
||||
deps.apis.signer_queue.clone(),
|
||||
codes_path(conf.signer_path),
|
||||
);
|
||||
if conf.skip_origin_validation {
|
||||
warn!("{}", Colour::Red.bold().paint("*** INSECURE *** Running Trusted Signer with no origin validation."));
|
||||
info!("If you do not intend this, exit now.");
|
||||
}
|
||||
let server = server.skip_origin_validation(conf.skip_origin_validation);
|
||||
let server = rpc_apis::setup_rpc(server, deps.apis, rpc_apis::ApiSet::SafeContext);
|
||||
server.start(addr)
|
||||
};
|
||||
|
@ -53,6 +53,7 @@ pub struct ServerBuilder {
|
||||
queue: Arc<ConfirmationsQueue>,
|
||||
handler: Arc<IoHandler>,
|
||||
authcodes_path: PathBuf,
|
||||
skip_origin_validation: bool,
|
||||
}
|
||||
|
||||
impl Extendable for ServerBuilder {
|
||||
@ -68,13 +69,21 @@ impl ServerBuilder {
|
||||
queue: queue,
|
||||
handler: Arc::new(IoHandler::new()),
|
||||
authcodes_path: authcodes_path,
|
||||
skip_origin_validation: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// If set to `true` server will not verify Origin of incoming requests.
|
||||
/// Not recommended. Use only for development.
|
||||
pub fn skip_origin_validation(mut self, skip: bool) -> Self {
|
||||
self.skip_origin_validation = skip;
|
||||
self
|
||||
}
|
||||
|
||||
/// Starts a new `WebSocket` server in separate thread.
|
||||
/// Returns a `Server` handle which closes the server when droped.
|
||||
pub fn start(self, addr: SocketAddr) -> Result<Server, ServerError> {
|
||||
Server::start(addr, self.handler, self.queue, self.authcodes_path)
|
||||
Server::start(addr, self.handler, self.queue, self.authcodes_path, self.skip_origin_validation)
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,10 +98,10 @@ pub struct Server {
|
||||
impl Server {
|
||||
/// Starts a new `WebSocket` server in separate thread.
|
||||
/// Returns a `Server` handle which closes the server when droped.
|
||||
fn start(addr: SocketAddr, handler: Arc<IoHandler>, queue: Arc<ConfirmationsQueue>, authcodes_path: PathBuf) -> Result<Server, ServerError> {
|
||||
fn start(addr: SocketAddr, handler: Arc<IoHandler>, queue: Arc<ConfirmationsQueue>, authcodes_path: PathBuf, skip_origin_validation: bool) -> Result<Server, ServerError> {
|
||||
let config = {
|
||||
let mut config = ws::Settings::default();
|
||||
// It's also used for handling min-sysui requests (browser can make many of them in paralel)
|
||||
// accept only handshakes beginning with GET
|
||||
config.method_strict = true;
|
||||
// Was shutting down server when suspending on linux:
|
||||
config.shutdown_on_interrupt = false;
|
||||
@ -101,7 +110,9 @@ impl Server {
|
||||
|
||||
// Create WebSocket
|
||||
let origin = format!("{}", addr);
|
||||
let ws = try!(ws::Builder::new().with_settings(config).build(session::Factory::new(handler, origin, authcodes_path)));
|
||||
let ws = try!(ws::Builder::new().with_settings(config).build(
|
||||
session::Factory::new(handler, origin, authcodes_path, skip_origin_validation)
|
||||
));
|
||||
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
let ph = panic_handler.clone();
|
||||
|
@ -96,6 +96,7 @@ fn add_headers(mut response: ws::Response, mime: &str) -> ws::Response {
|
||||
|
||||
pub struct Session {
|
||||
out: ws::Sender,
|
||||
skip_origin_validation: bool,
|
||||
self_origin: String,
|
||||
authcodes_path: PathBuf,
|
||||
handler: Arc<IoHandler>,
|
||||
@ -107,9 +108,11 @@ impl ws::Handler for Session {
|
||||
let host = req.header("host").or_else(|| req.header("Host")).map(|x| &x[..]);
|
||||
|
||||
// Check request origin and host header.
|
||||
if !origin_is_allowed(&self.self_origin, origin) && !(origin.is_none() && origin_is_allowed(&self.self_origin, host)) {
|
||||
warn!(target: "signer", "Blocked connection to Signer API from untrusted origin.");
|
||||
return Ok(ws::Response::forbidden(format!("You are not allowed to access system ui. Use: http://{}", self.self_origin)));
|
||||
if !self.skip_origin_validation {
|
||||
if !origin_is_allowed(&self.self_origin, origin) && !(origin.is_none() && origin_is_allowed(&self.self_origin, host)) {
|
||||
warn!(target: "signer", "Blocked connection to Signer API from untrusted origin.");
|
||||
return Ok(ws::Response::forbidden(format!("You are not allowed to access system ui. Use: http://{}", self.self_origin)));
|
||||
}
|
||||
}
|
||||
|
||||
// Detect if it's a websocket request.
|
||||
@ -150,14 +153,16 @@ impl ws::Handler for Session {
|
||||
|
||||
pub struct Factory {
|
||||
handler: Arc<IoHandler>,
|
||||
skip_origin_validation: bool,
|
||||
self_origin: String,
|
||||
authcodes_path: PathBuf,
|
||||
}
|
||||
|
||||
impl Factory {
|
||||
pub fn new(handler: Arc<IoHandler>, self_origin: String, authcodes_path: PathBuf) -> Self {
|
||||
pub fn new(handler: Arc<IoHandler>, self_origin: String, authcodes_path: PathBuf, skip_origin_validation: bool) -> Self {
|
||||
Factory {
|
||||
handler: handler,
|
||||
skip_origin_validation: skip_origin_validation,
|
||||
self_origin: self_origin,
|
||||
authcodes_path: authcodes_path,
|
||||
}
|
||||
@ -171,6 +176,7 @@ impl ws::Factory for Factory {
|
||||
Session {
|
||||
out: sender,
|
||||
handler: self.handler.clone(),
|
||||
skip_origin_validation: self.skip_origin_validation,
|
||||
self_origin: self.self_origin.clone(),
|
||||
authcodes_path: self.authcodes_path.clone(),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user