Merge pull request #6168 from paritytech/secretstore_stresstest
SecretStore: bunch of fixes and improvements
This commit is contained in:
commit
fefc756870
@ -76,8 +76,10 @@ path = "$HOME/.parity/dapps"
|
|||||||
user = "test_user"
|
user = "test_user"
|
||||||
pass = "test_pass"
|
pass = "test_pass"
|
||||||
|
|
||||||
[secretstore]
|
[secretstore]
|
||||||
disable = false
|
disable = false
|
||||||
|
disable_http = false
|
||||||
|
disable_acl_check = false
|
||||||
nodes = []
|
nodes = []
|
||||||
http_interface = "local"
|
http_interface = "local"
|
||||||
http_port = 8082
|
http_port = 8082
|
||||||
|
@ -217,6 +217,10 @@ usage! {
|
|||||||
// Secret Store
|
// Secret Store
|
||||||
flag_no_secretstore: bool = false,
|
flag_no_secretstore: bool = false,
|
||||||
or |c: &Config| otry!(c.secretstore).disable.clone(),
|
or |c: &Config| otry!(c.secretstore).disable.clone(),
|
||||||
|
flag_no_secretstore_http: bool = false,
|
||||||
|
or |c: &Config| otry!(c.secretstore).disable_http.clone(),
|
||||||
|
flag_no_secretstore_acl_check: bool = false,
|
||||||
|
or |c: &Config| otry!(c.secretstore).disable_acl_check.clone(),
|
||||||
flag_secretstore_secret: Option<String> = None,
|
flag_secretstore_secret: Option<String> = None,
|
||||||
or |c: &Config| otry!(c.secretstore).self_secret.clone().map(Some),
|
or |c: &Config| otry!(c.secretstore).self_secret.clone().map(Some),
|
||||||
flag_secretstore_nodes: String = "",
|
flag_secretstore_nodes: String = "",
|
||||||
@ -520,6 +524,8 @@ struct Dapps {
|
|||||||
#[derive(Default, Debug, PartialEq, Deserialize)]
|
#[derive(Default, Debug, PartialEq, Deserialize)]
|
||||||
struct SecretStore {
|
struct SecretStore {
|
||||||
disable: Option<bool>,
|
disable: Option<bool>,
|
||||||
|
disable_http: Option<bool>,
|
||||||
|
disable_acl_check: Option<bool>,
|
||||||
self_secret: Option<String>,
|
self_secret: Option<String>,
|
||||||
nodes: Option<Vec<String>>,
|
nodes: Option<Vec<String>>,
|
||||||
interface: Option<String>,
|
interface: Option<String>,
|
||||||
@ -796,6 +802,8 @@ mod tests {
|
|||||||
flag_no_dapps: false,
|
flag_no_dapps: false,
|
||||||
|
|
||||||
flag_no_secretstore: false,
|
flag_no_secretstore: false,
|
||||||
|
flag_no_secretstore_http: false,
|
||||||
|
flag_no_secretstore_acl_check: false,
|
||||||
flag_secretstore_secret: None,
|
flag_secretstore_secret: None,
|
||||||
flag_secretstore_nodes: "".into(),
|
flag_secretstore_nodes: "".into(),
|
||||||
flag_secretstore_interface: "local".into(),
|
flag_secretstore_interface: "local".into(),
|
||||||
@ -1031,6 +1039,8 @@ mod tests {
|
|||||||
}),
|
}),
|
||||||
secretstore: Some(SecretStore {
|
secretstore: Some(SecretStore {
|
||||||
disable: None,
|
disable: None,
|
||||||
|
disable_http: None,
|
||||||
|
disable_acl_check: None,
|
||||||
self_secret: None,
|
self_secret: None,
|
||||||
nodes: None,
|
nodes: None,
|
||||||
interface: None,
|
interface: None,
|
||||||
|
@ -234,6 +234,8 @@ API and Console Options:
|
|||||||
|
|
||||||
Secret Store Options:
|
Secret Store Options:
|
||||||
--no-secretstore Disable Secret Store functionality. (default: {flag_no_secretstore})
|
--no-secretstore Disable Secret Store functionality. (default: {flag_no_secretstore})
|
||||||
|
--no-secretstore-http Disable Secret Store HTTP API. (default: {flag_no_secretstore_http})
|
||||||
|
--no-acl-check Disable ACL check (useful for test environments). (default: {flag_no_secretstore_acl_check})
|
||||||
--secretstore-secret SECRET Hex-encoded secret key of this node.
|
--secretstore-secret SECRET Hex-encoded secret key of this node.
|
||||||
(required, default: {flag_secretstore_secret:?}).
|
(required, default: {flag_secretstore_secret:?}).
|
||||||
--secretstore-nodes NODES Comma-separated list of other secret store cluster nodes in form
|
--secretstore-nodes NODES Comma-separated list of other secret store cluster nodes in form
|
||||||
|
@ -609,6 +609,8 @@ impl Configuration {
|
|||||||
fn secretstore_config(&self) -> Result<SecretStoreConfiguration, String> {
|
fn secretstore_config(&self) -> Result<SecretStoreConfiguration, String> {
|
||||||
Ok(SecretStoreConfiguration {
|
Ok(SecretStoreConfiguration {
|
||||||
enabled: self.secretstore_enabled(),
|
enabled: self.secretstore_enabled(),
|
||||||
|
http_enabled: self.secretstore_http_enabled(),
|
||||||
|
acl_check_enabled: self.secretstore_acl_check_enabled(),
|
||||||
self_secret: self.secretstore_self_secret()?,
|
self_secret: self.secretstore_self_secret()?,
|
||||||
nodes: self.secretstore_nodes()?,
|
nodes: self.secretstore_nodes()?,
|
||||||
interface: self.secretstore_interface(),
|
interface: self.secretstore_interface(),
|
||||||
@ -1071,6 +1073,14 @@ impl Configuration {
|
|||||||
!self.args.flag_no_secretstore && cfg!(feature = "secretstore")
|
!self.args.flag_no_secretstore && cfg!(feature = "secretstore")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn secretstore_http_enabled(&self) -> bool {
|
||||||
|
!self.args.flag_no_secretstore_http && cfg!(feature = "secretstore")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn secretstore_acl_check_enabled(&self) -> bool {
|
||||||
|
!self.args.flag_no_secretstore_acl_check
|
||||||
|
}
|
||||||
|
|
||||||
fn ui_enabled(&self) -> bool {
|
fn ui_enabled(&self) -> bool {
|
||||||
if self.args.flag_force_ui {
|
if self.args.flag_force_ui {
|
||||||
return true;
|
return true;
|
||||||
@ -1376,6 +1386,7 @@ mod tests {
|
|||||||
whisper: Default::default(),
|
whisper: Default::default(),
|
||||||
};
|
};
|
||||||
expected.secretstore_conf.enabled = cfg!(feature = "secretstore");
|
expected.secretstore_conf.enabled = cfg!(feature = "secretstore");
|
||||||
|
expected.secretstore_conf.http_enabled = cfg!(feature = "secretstore");
|
||||||
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Run(expected));
|
assert_eq!(conf.into_command().unwrap().cmd, Cmd::Run(expected));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,10 @@ pub enum NodeSecretKey {
|
|||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
/// Is secret store functionality enabled?
|
/// Is secret store functionality enabled?
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
|
/// Is HTTP API enabled?
|
||||||
|
pub http_enabled: bool,
|
||||||
|
/// Is ACL check enabled.
|
||||||
|
pub acl_check_enabled: bool,
|
||||||
/// This node secret.
|
/// This node secret.
|
||||||
pub self_secret: Option<NodeSecretKey>,
|
pub self_secret: Option<NodeSecretKey>,
|
||||||
/// Other nodes IDs + addresses.
|
/// Other nodes IDs + addresses.
|
||||||
@ -83,6 +87,7 @@ mod server {
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use ethcore_secretstore;
|
use ethcore_secretstore;
|
||||||
use ethkey::KeyPair;
|
use ethkey::KeyPair;
|
||||||
|
use ansi_term::Colour::Red;
|
||||||
use super::{Configuration, Dependencies, NodeSecretKey};
|
use super::{Configuration, Dependencies, NodeSecretKey};
|
||||||
|
|
||||||
/// Key server
|
/// Key server
|
||||||
@ -93,6 +98,10 @@ mod server {
|
|||||||
impl KeyServer {
|
impl KeyServer {
|
||||||
/// Create new key server
|
/// Create new key server
|
||||||
pub fn new(mut conf: Configuration, deps: Dependencies) -> Result<Self, String> {
|
pub fn new(mut conf: Configuration, deps: Dependencies) -> Result<Self, String> {
|
||||||
|
if !conf.acl_check_enabled {
|
||||||
|
warn!("Running SecretStore with disabled ACL check: {}", Red.bold().paint("everyone has access to stored keys"));
|
||||||
|
}
|
||||||
|
|
||||||
let self_secret: Arc<ethcore_secretstore::NodeKeyPair> = match conf.self_secret.take() {
|
let self_secret: Arc<ethcore_secretstore::NodeKeyPair> = match conf.self_secret.take() {
|
||||||
Some(NodeSecretKey::Plain(secret)) => Arc::new(ethcore_secretstore::PlainNodeKeyPair::new(
|
Some(NodeSecretKey::Plain(secret)) => Arc::new(ethcore_secretstore::PlainNodeKeyPair::new(
|
||||||
KeyPair::from_secret(secret).map_err(|e| format!("invalid secret: {}", e))?)),
|
KeyPair::from_secret(secret).map_err(|e| format!("invalid secret: {}", e))?)),
|
||||||
@ -117,12 +126,14 @@ mod server {
|
|||||||
None => return Err("self secret is required when using secretstore".into()),
|
None => return Err("self secret is required when using secretstore".into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut conf = ethcore_secretstore::ServiceConfiguration {
|
let key_server_name = format!("{}:{}", conf.interface, conf.port);
|
||||||
listener_address: ethcore_secretstore::NodeAddress {
|
let mut cconf = ethcore_secretstore::ServiceConfiguration {
|
||||||
|
listener_address: if conf.http_enabled { Some(ethcore_secretstore::NodeAddress {
|
||||||
address: conf.http_interface.clone(),
|
address: conf.http_interface.clone(),
|
||||||
port: conf.http_port,
|
port: conf.http_port,
|
||||||
},
|
}) } else { None },
|
||||||
data_path: conf.data_path.clone(),
|
data_path: conf.data_path.clone(),
|
||||||
|
acl_check_enabled: conf.acl_check_enabled,
|
||||||
cluster_config: ethcore_secretstore::ClusterConfiguration {
|
cluster_config: ethcore_secretstore::ClusterConfiguration {
|
||||||
threads: 4,
|
threads: 4,
|
||||||
listener_address: ethcore_secretstore::NodeAddress {
|
listener_address: ethcore_secretstore::NodeAddress {
|
||||||
@ -137,10 +148,10 @@ mod server {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
conf.cluster_config.nodes.insert(self_secret.public().clone(), conf.cluster_config.listener_address.clone());
|
cconf.cluster_config.nodes.insert(self_secret.public().clone(), cconf.cluster_config.listener_address.clone());
|
||||||
|
|
||||||
let key_server = ethcore_secretstore::start(deps.client, self_secret, conf)
|
let key_server = ethcore_secretstore::start(deps.client, self_secret, cconf)
|
||||||
.map_err(Into::<String>::into)?;
|
.map_err(|e| format!("Error starting KeyServer {}: {}", key_server_name, e))?;
|
||||||
|
|
||||||
Ok(KeyServer {
|
Ok(KeyServer {
|
||||||
_key_server: key_server,
|
_key_server: key_server,
|
||||||
@ -156,6 +167,8 @@ impl Default for Configuration {
|
|||||||
let data_dir = default_data_path();
|
let data_dir = default_data_path();
|
||||||
Configuration {
|
Configuration {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
http_enabled: true,
|
||||||
|
acl_check_enabled: true,
|
||||||
self_secret: None,
|
self_secret: None,
|
||||||
nodes: BTreeMap::new(),
|
nodes: BTreeMap::new(),
|
||||||
interface: "127.0.0.1".to_owned(),
|
interface: "127.0.0.1".to_owned(),
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
use futures::{future, Future};
|
use futures::{future, Future};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::{Mutex, RwLock};
|
||||||
use ethkey::public_to_address;
|
use ethkey::public_to_address;
|
||||||
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify};
|
use ethcore::client::{Client, BlockChainClient, BlockId, ChainNotify};
|
||||||
use native_contracts::SecretStoreAclStorage;
|
use native_contracts::SecretStoreAclStorage;
|
||||||
@ -47,6 +48,12 @@ struct CachedContract {
|
|||||||
contract: Option<SecretStoreAclStorage>,
|
contract: Option<SecretStoreAclStorage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Dummy ACL storage implementation (check always passed).
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct DummyAclStorage {
|
||||||
|
prohibited: RwLock<HashMap<Public, HashSet<ServerKeyId>>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl OnChainAclStorage {
|
impl OnChainAclStorage {
|
||||||
pub fn new(client: &Arc<Client>) -> Arc<Self> {
|
pub fn new(client: &Arc<Client>) -> Arc<Self> {
|
||||||
let acl_storage = Arc::new(OnChainAclStorage {
|
let acl_storage = Arc::new(OnChainAclStorage {
|
||||||
@ -113,36 +120,22 @@ impl CachedContract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
impl DummyAclStorage {
|
||||||
pub mod tests {
|
/// Prohibit given requestor access to given documents
|
||||||
use std::collections::{HashMap, HashSet};
|
#[cfg(test)]
|
||||||
use parking_lot::RwLock;
|
pub fn prohibit(&self, public: Public, document: ServerKeyId) {
|
||||||
use types::all::{Error, ServerKeyId, Public};
|
self.prohibited.write()
|
||||||
use super::AclStorage;
|
.entry(public)
|
||||||
|
.or_insert_with(Default::default)
|
||||||
#[derive(Default, Debug)]
|
.insert(document);
|
||||||
/// Dummy ACL storage implementation
|
}
|
||||||
pub struct DummyAclStorage {
|
}
|
||||||
prohibited: RwLock<HashMap<Public, HashSet<ServerKeyId>>>,
|
|
||||||
}
|
impl AclStorage for DummyAclStorage {
|
||||||
|
fn check(&self, public: &Public, document: &ServerKeyId) -> Result<bool, Error> {
|
||||||
impl DummyAclStorage {
|
Ok(self.prohibited.read()
|
||||||
#[cfg(test)]
|
.get(public)
|
||||||
/// Prohibit given requestor access to given document
|
.map(|docs| !docs.contains(document))
|
||||||
pub fn prohibit(&self, public: Public, document: ServerKeyId) {
|
.unwrap_or(true))
|
||||||
self.prohibited.write()
|
|
||||||
.entry(public)
|
|
||||||
.or_insert_with(Default::default)
|
|
||||||
.insert(document);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AclStorage for DummyAclStorage {
|
|
||||||
fn check(&self, public: &Public, document: &ServerKeyId) -> Result<bool, Error> {
|
|
||||||
Ok(self.prohibited.read()
|
|
||||||
.get(public)
|
|
||||||
.map(|docs| !docs.contains(document))
|
|
||||||
.unwrap_or(true))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ use types::all::{Error, Public, MessageHash, EncryptedMessageSignature, NodeAddr
|
|||||||
/// To sign message with server key: GET /{server_key_id}/{signature}/{message_hash}
|
/// To sign message with server key: GET /{server_key_id}/{signature}/{message_hash}
|
||||||
|
|
||||||
pub struct KeyServerHttpListener<T: KeyServer + 'static> {
|
pub struct KeyServerHttpListener<T: KeyServer + 'static> {
|
||||||
_http_server: HttpListening,
|
http_server: Option<HttpListening>,
|
||||||
handler: Arc<KeyServerSharedHttpHandler<T>>,
|
handler: Arc<KeyServerSharedHttpHandler<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,19 +74,20 @@ struct KeyServerSharedHttpHandler<T: KeyServer + 'static> {
|
|||||||
|
|
||||||
impl<T> KeyServerHttpListener<T> where T: KeyServer + 'static {
|
impl<T> KeyServerHttpListener<T> where T: KeyServer + 'static {
|
||||||
/// Start KeyServer http listener
|
/// Start KeyServer http listener
|
||||||
pub fn start(listener_address: &NodeAddress, key_server: T) -> Result<Self, Error> {
|
pub fn start(listener_address: Option<NodeAddress>, key_server: T) -> Result<Self, Error> {
|
||||||
let shared_handler = Arc::new(KeyServerSharedHttpHandler {
|
let shared_handler = Arc::new(KeyServerSharedHttpHandler {
|
||||||
key_server: key_server,
|
key_server: key_server,
|
||||||
});
|
});
|
||||||
let handler = KeyServerHttpHandler {
|
|
||||||
handler: shared_handler.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let listener_addr: &str = &format!("{}:{}", listener_address.address, listener_address.port);
|
let http_server = listener_address
|
||||||
let http_server = HttpServer::http(&listener_addr).expect("cannot start HttpServer");
|
.map(|listener_address| format!("{}:{}", listener_address.address, listener_address.port))
|
||||||
let http_server = http_server.handle(handler).expect("cannot start HttpServer");
|
.map(|listener_address| HttpServer::http(&listener_address).expect("cannot start HttpServer"))
|
||||||
|
.map(|http_server| http_server.handle(KeyServerHttpHandler {
|
||||||
|
handler: shared_handler.clone(),
|
||||||
|
}).expect("cannot start HttpServer"));
|
||||||
|
|
||||||
let listener = KeyServerHttpListener {
|
let listener = KeyServerHttpListener {
|
||||||
_http_server: http_server,
|
http_server: http_server,
|
||||||
handler: shared_handler,
|
handler: shared_handler,
|
||||||
};
|
};
|
||||||
Ok(listener)
|
Ok(listener)
|
||||||
@ -128,7 +129,7 @@ impl <T> MessageSigner for KeyServerHttpListener<T> where T: KeyServer + 'static
|
|||||||
impl<T> Drop for KeyServerHttpListener<T> where T: KeyServer + 'static {
|
impl<T> Drop for KeyServerHttpListener<T> where T: KeyServer + 'static {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// ignore error as we are dropping anyway
|
// ignore error as we are dropping anyway
|
||||||
let _ = self._http_server.close();
|
self.http_server.take().map(|mut s| { let _ = s.close(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +319,7 @@ mod tests {
|
|||||||
fn http_listener_successfully_drops() {
|
fn http_listener_successfully_drops() {
|
||||||
let key_server = DummyKeyServer;
|
let key_server = DummyKeyServer;
|
||||||
let address = NodeAddress { address: "127.0.0.1".into(), port: 9000 };
|
let address = NodeAddress { address: "127.0.0.1".into(), port: 9000 };
|
||||||
let listener = KeyServerHttpListener::start(&address, key_server).unwrap();
|
let listener = KeyServerHttpListener::start(Some(address), key_server).unwrap();
|
||||||
drop(listener);
|
drop(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ pub mod tests {
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use ethcrypto;
|
use ethcrypto;
|
||||||
use ethkey::{self, Secret, Random, Generator};
|
use ethkey::{self, Secret, Random, Generator};
|
||||||
use acl_storage::tests::DummyAclStorage;
|
use acl_storage::DummyAclStorage;
|
||||||
use key_storage::tests::DummyKeyStorage;
|
use key_storage::tests::DummyKeyStorage;
|
||||||
use node_key_pair::PlainNodeKeyPair;
|
use node_key_pair::PlainNodeKeyPair;
|
||||||
use key_server_set::tests::MapKeyServerSet;
|
use key_server_set::tests::MapKeyServerSet;
|
||||||
|
@ -262,7 +262,7 @@ impl ClusterCore {
|
|||||||
fn connect_future(handle: &Handle, data: Arc<ClusterData>, node_address: SocketAddr) -> BoxedEmptyFuture {
|
fn connect_future(handle: &Handle, data: Arc<ClusterData>, node_address: SocketAddr) -> BoxedEmptyFuture {
|
||||||
let disconnected_nodes = data.connections.disconnected_nodes().keys().cloned().collect();
|
let disconnected_nodes = data.connections.disconnected_nodes().keys().cloned().collect();
|
||||||
net_connect(&node_address, handle, data.self_key_pair.clone(), disconnected_nodes)
|
net_connect(&node_address, handle, data.self_key_pair.clone(), disconnected_nodes)
|
||||||
.then(move |result| ClusterCore::process_connection_result(data, false, result))
|
.then(move |result| ClusterCore::process_connection_result(data, Some(node_address), result))
|
||||||
.then(|_| finished(()))
|
.then(|_| finished(()))
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@ impl ClusterCore {
|
|||||||
/// Accept connection future.
|
/// Accept connection future.
|
||||||
fn accept_connection_future(handle: &Handle, data: Arc<ClusterData>, stream: TcpStream, node_address: SocketAddr) -> BoxedEmptyFuture {
|
fn accept_connection_future(handle: &Handle, data: Arc<ClusterData>, stream: TcpStream, node_address: SocketAddr) -> BoxedEmptyFuture {
|
||||||
net_accept_connection(node_address, stream, handle, data.self_key_pair.clone())
|
net_accept_connection(node_address, stream, handle, data.self_key_pair.clone())
|
||||||
.then(move |result| ClusterCore::process_connection_result(data, true, result))
|
.then(move |result| ClusterCore::process_connection_result(data, None, result))
|
||||||
.then(|_| finished(()))
|
.then(|_| finished(()))
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
@ -370,10 +370,10 @@ impl ClusterCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Process connection future result.
|
/// Process connection future result.
|
||||||
fn process_connection_result(data: Arc<ClusterData>, is_inbound: bool, result: Result<DeadlineStatus<Result<NetConnection, Error>>, io::Error>) -> IoFuture<Result<(), Error>> {
|
fn process_connection_result(data: Arc<ClusterData>, outbound_addr: Option<SocketAddr>, result: Result<DeadlineStatus<Result<NetConnection, Error>>, io::Error>) -> IoFuture<Result<(), Error>> {
|
||||||
match result {
|
match result {
|
||||||
Ok(DeadlineStatus::Meet(Ok(connection))) => {
|
Ok(DeadlineStatus::Meet(Ok(connection))) => {
|
||||||
let connection = Connection::new(is_inbound, connection);
|
let connection = Connection::new(outbound_addr.is_none(), connection);
|
||||||
if data.connections.insert(connection.clone()) {
|
if data.connections.insert(connection.clone()) {
|
||||||
ClusterCore::process_connection_messages(data.clone(), connection)
|
ClusterCore::process_connection_messages(data.clone(), connection)
|
||||||
} else {
|
} else {
|
||||||
@ -381,15 +381,21 @@ impl ClusterCore {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Ok(DeadlineStatus::Meet(Err(err))) => {
|
Ok(DeadlineStatus::Meet(Err(err))) => {
|
||||||
warn!(target: "secretstore_net", "{}: protocol error {} when establishind connection", data.self_key_pair.public(), err);
|
warn!(target: "secretstore_net", "{}: protocol error {} when establishing {} connection{}",
|
||||||
|
data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" },
|
||||||
|
outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default());
|
||||||
finished(Ok(())).boxed()
|
finished(Ok(())).boxed()
|
||||||
},
|
},
|
||||||
Ok(DeadlineStatus::Timeout) => {
|
Ok(DeadlineStatus::Timeout) => {
|
||||||
warn!(target: "secretstore_net", "{}: timeout when establishind connection", data.self_key_pair.public());
|
warn!(target: "secretstore_net", "{}: timeout when establishing {} connection{}",
|
||||||
|
data.self_key_pair.public(), if outbound_addr.is_some() { "outbound" } else { "inbound" },
|
||||||
|
outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default());
|
||||||
finished(Ok(())).boxed()
|
finished(Ok(())).boxed()
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(target: "secretstore_net", "{}: network error {} when establishind connection", data.self_key_pair.public(), err);
|
warn!(target: "secretstore_net", "{}: network error {} when establishing {} connection{}",
|
||||||
|
data.self_key_pair.public(), err, if outbound_addr.is_some() { "outbound" } else { "inbound" },
|
||||||
|
outbound_addr.map(|a| format!(" with {}", a)).unwrap_or_default());
|
||||||
finished(Ok(())).boxed()
|
finished(Ok(())).boxed()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -467,7 +467,7 @@ impl Ord for DecryptionSessionId {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use super::super::super::acl_storage::tests::DummyAclStorage;
|
use acl_storage::DummyAclStorage;
|
||||||
use ethkey::{self, KeyPair, Random, Generator, Public, Secret};
|
use ethkey::{self, KeyPair, Random, Generator, Public, Secret};
|
||||||
use key_server_cluster::{NodeId, DocumentKeyShare, SessionId, Error, EncryptedDocumentKeyShadow, SessionMeta};
|
use key_server_cluster::{NodeId, DocumentKeyShare, SessionId, Error, EncryptedDocumentKeyShadow, SessionMeta};
|
||||||
use key_server_cluster::cluster::tests::DummyCluster;
|
use key_server_cluster::cluster::tests::DummyCluster;
|
||||||
|
@ -399,7 +399,7 @@ impl SessionImpl {
|
|||||||
// check state
|
// check state
|
||||||
if data.state != SessionState::WaitingForKeysDissemination {
|
if data.state != SessionState::WaitingForKeysDissemination {
|
||||||
match data.state {
|
match data.state {
|
||||||
SessionState::WaitingForInitializationComplete => return Err(Error::TooEarlyForRequest),
|
SessionState::WaitingForInitializationComplete | SessionState::WaitingForInitializationConfirm(_) => return Err(Error::TooEarlyForRequest),
|
||||||
_ => return Err(Error::InvalidStateForRequest),
|
_ => return Err(Error::InvalidStateForRequest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1104,7 +1104,7 @@ pub mod tests {
|
|||||||
secret1: math::generate_random_scalar().unwrap().into(),
|
secret1: math::generate_random_scalar().unwrap().into(),
|
||||||
secret2: math::generate_random_scalar().unwrap().into(),
|
secret2: math::generate_random_scalar().unwrap().into(),
|
||||||
publics: vec![math::generate_random_point().unwrap().into()],
|
publics: vec![math::generate_random_point().unwrap().into()],
|
||||||
}).unwrap_err(), Error::InvalidStateForRequest);
|
}).unwrap_err(), Error::TooEarlyForRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -36,7 +36,7 @@ pub use super::node_key_pair::PlainNodeKeyPair;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub use super::key_storage::tests::DummyKeyStorage;
|
pub use super::key_storage::tests::DummyKeyStorage;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub use super::acl_storage::tests::DummyAclStorage;
|
pub use super::acl_storage::DummyAclStorage;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub use super::key_server_set::tests::MapKeyServerSet;
|
pub use super::key_server_set::tests::MapKeyServerSet;
|
||||||
|
|
||||||
|
@ -572,7 +572,7 @@ mod tests {
|
|||||||
use std::collections::{BTreeMap, VecDeque};
|
use std::collections::{BTreeMap, VecDeque};
|
||||||
use ethkey::{self, Random, Generator, Public};
|
use ethkey::{self, Random, Generator, Public};
|
||||||
use util::H256;
|
use util::H256;
|
||||||
use super::super::super::acl_storage::tests::DummyAclStorage;
|
use acl_storage::DummyAclStorage;
|
||||||
use key_server_cluster::{NodeId, SessionId, SessionMeta, Error, KeyStorage};
|
use key_server_cluster::{NodeId, SessionId, SessionMeta, Error, KeyStorage};
|
||||||
use key_server_cluster::cluster::tests::DummyCluster;
|
use key_server_cluster::cluster::tests::DummyCluster;
|
||||||
use key_server_cluster::generation_session::{Session as GenerationSession};
|
use key_server_cluster::generation_session::{Session as GenerationSession};
|
||||||
|
@ -200,7 +200,7 @@ pub mod tests {
|
|||||||
use devtools::RandomTempPath;
|
use devtools::RandomTempPath;
|
||||||
use ethkey::{Random, Generator, Public, Secret};
|
use ethkey::{Random, Generator, Public, Secret};
|
||||||
use util::Database;
|
use util::Database;
|
||||||
use super::super::types::all::{Error, NodeAddress, ServiceConfiguration, ClusterConfiguration, ServerKeyId};
|
use types::all::{Error, NodeAddress, ServiceConfiguration, ClusterConfiguration, ServerKeyId};
|
||||||
use super::{DB_META_KEY_VERSION, KeyStorage, PersistentKeyStorage, DocumentKeyShare,
|
use super::{DB_META_KEY_VERSION, KeyStorage, PersistentKeyStorage, DocumentKeyShare,
|
||||||
SerializableDocumentKeyShareV0, SerializableDocumentKeyShareV1, upgrade_db};
|
SerializableDocumentKeyShareV0, SerializableDocumentKeyShareV1, upgrade_db};
|
||||||
|
|
||||||
@ -234,10 +234,8 @@ pub mod tests {
|
|||||||
fn persistent_key_storage() {
|
fn persistent_key_storage() {
|
||||||
let path = RandomTempPath::create_dir();
|
let path = RandomTempPath::create_dir();
|
||||||
let config = ServiceConfiguration {
|
let config = ServiceConfiguration {
|
||||||
listener_address: NodeAddress {
|
listener_address: None,
|
||||||
address: "0.0.0.0".to_owned(),
|
acl_check_enabled: true,
|
||||||
port: 8082,
|
|
||||||
},
|
|
||||||
data_path: path.as_str().to_owned(),
|
data_path: path.as_str().to_owned(),
|
||||||
cluster_config: ClusterConfiguration {
|
cluster_config: ClusterConfiguration {
|
||||||
threads: 1,
|
threads: 1,
|
||||||
|
@ -73,10 +73,14 @@ pub use self::node_key_pair::{PlainNodeKeyPair, KeyStoreNodeKeyPair};
|
|||||||
pub fn start(client: Arc<Client>, self_key_pair: Arc<NodeKeyPair>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> {
|
pub fn start(client: Arc<Client>, self_key_pair: Arc<NodeKeyPair>, config: ServiceConfiguration) -> Result<Box<KeyServer>, Error> {
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
let acl_storage = acl_storage::OnChainAclStorage::new(&client);
|
let acl_storage: Arc<acl_storage::AclStorage> = if config.acl_check_enabled {
|
||||||
|
acl_storage::OnChainAclStorage::new(&client)
|
||||||
|
} else {
|
||||||
|
Arc::new(acl_storage::DummyAclStorage::default())
|
||||||
|
};
|
||||||
let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?;
|
let key_server_set = key_server_set::OnChainKeyServerSet::new(&client, config.cluster_config.nodes.clone())?;
|
||||||
let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?);
|
let key_storage = Arc::new(key_storage::PersistentKeyStorage::new(&config)?);
|
||||||
let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, self_key_pair, acl_storage, key_storage)?;
|
let key_server = key_server::KeyServerImpl::new(&config.cluster_config, key_server_set, self_key_pair, acl_storage, key_storage)?;
|
||||||
let listener = http_listener::KeyServerHttpListener::start(&config.listener_address, key_server)?;
|
let listener = http_listener::KeyServerHttpListener::start(config.listener_address, key_server)?;
|
||||||
Ok(Box::new(listener))
|
Ok(Box::new(listener))
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,10 @@ pub struct NodeAddress {
|
|||||||
#[binary]
|
#[binary]
|
||||||
/// Secret store configuration
|
/// Secret store configuration
|
||||||
pub struct ServiceConfiguration {
|
pub struct ServiceConfiguration {
|
||||||
/// HTTP listener address.
|
/// HTTP listener address. If None, HTTP API is disabled.
|
||||||
pub listener_address: NodeAddress,
|
pub listener_address: Option<NodeAddress>,
|
||||||
|
/// Is ACL check enabled. If false, everyone has access to all keys. Useful for tests only.
|
||||||
|
pub acl_check_enabled: bool,
|
||||||
/// Data directory path for secret store
|
/// Data directory path for secret store
|
||||||
pub data_path: String,
|
pub data_path: String,
|
||||||
/// Cluster configuration.
|
/// Cluster configuration.
|
||||||
|
Loading…
Reference in New Issue
Block a user