diff --git a/ethcore/src/account_provider/mod.rs b/ethcore/src/account_provider/mod.rs index 0ecbf3b17..9e4944ef0 100755 --- a/ethcore/src/account_provider/mod.rs +++ b/ethcore/src/account_provider/mod.rs @@ -125,6 +125,8 @@ pub struct AccountProvider { transient_sstore: EthMultiStore, /// Accounts in hardware wallets. hardware_store: Option, + /// Disallowed accounts. + blacklisted_accounts: Vec
, } /// Account management settings. @@ -133,6 +135,8 @@ pub struct AccountProviderSettings { pub enable_hardware_wallets: bool, /// Use the classic chain key on the hardware wallet. pub hardware_wallet_classic_key: bool, + /// Disallowed accounts. + pub blacklisted_accounts: Vec
, } impl Default for AccountProviderSettings { @@ -140,6 +144,7 @@ impl Default for AccountProviderSettings { AccountProviderSettings { enable_hardware_wallets: false, hardware_wallet_classic_key: false, + blacklisted_accounts: vec![], } } } @@ -157,13 +162,21 @@ impl AccountProvider { Err(e) => debug!("Error initializing hardware wallets: {}", e), } } + + // Remove blacklisted accounts from address book. + let mut address_book = AddressBook::new(&sstore.local_path()); + for addr in &settings.blacklisted_accounts { + address_book.remove(*addr); + } + AccountProvider { unlocked: RwLock::new(HashMap::new()), - address_book: RwLock::new(AddressBook::new(&sstore.local_path())), + address_book: RwLock::new(address_book), dapps_settings: RwLock::new(DappsSettingsStore::new(&sstore.local_path())), sstore: sstore, transient_sstore: transient_sstore(), hardware_store: hardware_store, + blacklisted_accounts: settings.blacklisted_accounts, } } @@ -176,6 +189,7 @@ impl AccountProvider { sstore: Box::new(EthStore::open(Box::new(MemoryDirectory::default())).expect("MemoryDirectory load always succeeds; qed")), transient_sstore: transient_sstore(), hardware_store: None, + blacklisted_accounts: vec![], } } @@ -197,6 +211,10 @@ impl AccountProvider { /// Does not unlock account! pub fn insert_account(&self, secret: Secret, password: &str) -> Result { let account = self.sstore.insert_account(SecretVaultRef::Root, secret, password)?; + if self.blacklisted_accounts.contains(&account.address) { + self.sstore.remove_account(&account, password)?; + return Err(SSError::InvalidAccount.into()); + } Ok(account.address) } @@ -223,6 +241,10 @@ impl AccountProvider { /// Import a new presale wallet. pub fn import_wallet(&self, json: &[u8], password: &str) -> Result { let account = self.sstore.import_wallet(SecretVaultRef::Root, json, password)?; + if self.blacklisted_accounts.contains(&account.address) { + self.sstore.remove_account(&account, password)?; + return Err(SSError::InvalidAccount.into()); + } Ok(Address::from(account.address).into()) } @@ -234,7 +256,12 @@ impl AccountProvider { /// Returns addresses of all accounts. pub fn accounts(&self) -> Result, Error> { let accounts = self.sstore.accounts()?; - Ok(accounts.into_iter().map(|a| a.address).collect()) + Ok(accounts + .into_iter() + .map(|a| a.address) + .filter(|address| !self.blacklisted_accounts.contains(address)) + .collect() + ) } /// Returns addresses of hardware accounts. @@ -436,6 +463,7 @@ impl AccountProvider { pub fn accounts_info(&self) -> Result, Error> { let r = self.sstore.accounts()? .into_iter() + .filter(|a| !self.blacklisted_accounts.contains(&a.address)) .map(|a| (a.address.clone(), self.account_meta(a.address).ok().unwrap_or_default())) .collect(); Ok(r) @@ -719,7 +747,7 @@ impl AccountProvider { mod tests { use super::{AccountProvider, Unlock, DappId}; use std::time::Instant; - use ethstore::ethkey::{Generator, Random}; + use ethstore::ethkey::{Generator, Random, Address}; use ethstore::{StoreAccountRef, Derivation}; use util::H256; @@ -934,4 +962,16 @@ mod tests { assert_eq!(ap.new_dapps_default_address().unwrap(), address); assert_eq!(ap.dapp_default_address("app1".into()).unwrap(), address); } + + #[test] + fn should_not_return_blacklisted_account() { + // given + let mut ap = AccountProvider::transient_provider(); + let acc = ap.new_account("test").unwrap(); + ap.blacklisted_accounts = vec![acc]; + + // then + assert_eq!(ap.accounts_info().unwrap().keys().cloned().collect::>(), vec![]); + assert_eq!(ap.accounts().unwrap(), vec![]); + } } diff --git a/parity/run.rs b/parity/run.rs index 352f11c5d..5bc720ec2 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -777,6 +777,12 @@ fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str, let account_settings = AccountProviderSettings { enable_hardware_wallets: cfg.enable_hardware_wallets, hardware_wallet_classic_key: spec == &SpecType::Classic, + blacklisted_accounts: match *spec { + SpecType::Morden | SpecType::Ropsten | SpecType::Kovan | SpecType::Dev => vec![], + _ => vec![ + "00a329c0648769a73afac7f9381e08fb43dbea72".into() + ], + }, }; let account_provider = AccountProvider::new( Box::new(EthStore::open_with_iterations(dir, cfg.iterations).map_err(|e| format!("Could not open keys directory: {}", e))?),