From 53c4ed09a341ab62ef975d002ec76f65ce93d4e0 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 27 Mar 2016 01:35:42 +0100 Subject: [PATCH 1/3] Unlock accounts on CLI. --- parity/main.rs | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index 731bba9a1..187e855b9 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -39,6 +39,7 @@ extern crate rpassword; #[cfg(feature = "rpc")] extern crate ethcore_rpc as rpc; +use std::fs::File; use std::net::{SocketAddr, IpAddr}; use std::env; use std::process::exit; @@ -89,6 +90,11 @@ Protocol Options: [default: $HOME/.web3/keys]. --identity NAME Specify your node's name. +Account Options: + --unlock ACCOUNT Unlock ACCOUNT for the duration of the execution. + --password FILE Provide a file containing a password for unlocking + an account. + Networking Options: --port PORT Override the port on which the node should listen [default: 30303]. @@ -176,6 +182,8 @@ struct Args { flag_chain: String, flag_db_path: String, flag_identity: String, + flag_unlock: Vec, + flag_password: Vec, flag_cache: Option, flag_keys_path: String, flag_bootnodes: Option, @@ -490,6 +498,29 @@ impl Configuration { } } + fn passwords(&self) -> Vec { + self.args.flag_password.iter().map(|filename| { + let mut buffer = String::new(); + File::open(filename).and_then(|mut f| f.read_to_string(&mut buffer)).unwrap_or_else(|_| die!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)); + buffer + }).collect() + } + + fn account_service(&self) -> AccountService { + // Secret Store + let account_service = AccountService::new(); + let passwords = self.passwords(); + for d in &self.args.flag_unlock { + let a = Address::from_str(clean_0x(&d)).unwrap_or_else(|_| { + die!("{}: Invalid address for --unlock. Must be 40 hex characters, without the 0x at the beginning.", d) + }); + if passwords.iter().find(|p| account_service.unlock_account(&a, p).is_ok()).is_none() { + die!("No password given to unlock account {}. Pass the password using `--password`.", a); + } + } + account_service + } + #[cfg_attr(feature="dev", allow(useless_format))] fn execute_client(&self) { // Setup panic handler @@ -504,6 +535,9 @@ impl Configuration { let net_settings = self.net_settings(&spec); let sync_config = self.sync_config(&spec); + // Secret Store + let account_service = Arc::new(self.account_service()); + // Build client let mut service = ClientService::start(self.client_config(), spec, net_settings, &Path::new(&self.path())).unwrap(); panic_handler.forward_from(&service); @@ -519,9 +553,6 @@ impl Configuration { // Sync let sync = EthSync::register(service.network(), sync_config, client.clone(), miner.clone()); - // Secret Store - let account_service = Arc::new(AccountService::new()); - // Setup rpc if self.args.flag_jsonrpc || self.args.flag_rpc { let url = format!("{}:{}", From 8805d04183995a69cf39cc28717c460a8b5a6277 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 27 Mar 2016 01:41:28 +0100 Subject: [PATCH 2/3] Minor refactor. --- parity/main.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index 187e855b9..12dd569a3 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -498,18 +498,15 @@ impl Configuration { } } - fn passwords(&self) -> Vec { - self.args.flag_password.iter().map(|filename| { - let mut buffer = String::new(); - File::open(filename).and_then(|mut f| f.read_to_string(&mut buffer)).unwrap_or_else(|_| die!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)); - buffer - }).collect() - } - fn account_service(&self) -> AccountService { // Secret Store + let passwords = self.args.flag_password.iter().map(|filename| { + let mut buffer = String::new(); + File::open(filename).and_then(|mut f| f.read_to_string(&mut buffer)).unwrap_or_else(|_| die!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)); + buffer + }).collect::>(); + let account_service = AccountService::new(); - let passwords = self.passwords(); for d in &self.args.flag_unlock { let a = Address::from_str(clean_0x(&d)).unwrap_or_else(|_| { die!("{}: Invalid address for --unlock. Must be 40 hex characters, without the 0x at the beginning.", d) From 156a2336de9efaeb788983a14d349b5fcd18050a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 27 Mar 2016 03:15:41 +0200 Subject: [PATCH 3/3] Allow passwords on multiple lines in --password files. --- parity/main.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/parity/main.rs b/parity/main.rs index 12dd569a3..5d95085c5 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -39,6 +39,7 @@ extern crate rpassword; #[cfg(feature = "rpc")] extern crate ethcore_rpc as rpc; +use std::io::{BufRead, BufReader}; use std::fs::File; use std::net::{SocketAddr, IpAddr}; use std::env; @@ -500,11 +501,13 @@ impl Configuration { fn account_service(&self) -> AccountService { // Secret Store - let passwords = self.args.flag_password.iter().map(|filename| { - let mut buffer = String::new(); - File::open(filename).and_then(|mut f| f.read_to_string(&mut buffer)).unwrap_or_else(|_| die!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename)); - buffer - }).collect::>(); + let passwords = self.args.flag_password.iter().flat_map(|filename| { + BufReader::new(&File::open(filename).unwrap_or_else(|_| die!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename))) + .lines() + .map(|l| l.unwrap()) + .collect::>() + .into_iter() + }).collect::>(); let account_service = AccountService::new(); for d in &self.args.flag_unlock {