Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isolate config logic and add e2e config tests #432

Merged
merged 1 commit into from
May 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# The content of the config.rs file should not change in a breaking way.
# See https://github.com/parallaxsecond/parsec/issues/393 for details.
src/utils/config.rs @parallaxsecond/admin
4 changes: 4 additions & 0 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ run_key_mappings_tests() {
RUST_BACKTRACE=1 cargo test $TEST_FEATURES --manifest-path ./e2e_tests/Cargo.toml key_mappings
}

# During end-to-end tests, Parsec is configured with the socket in /tmp/
# Individual tests might change that, but set the default after.
export PARSEC_SERVICE_ENDPOINT="unix:/tmp/parsec.sock"

# Parse arguments
NO_CARGO_CLEAN=
NO_STRESS_TEST=
Expand Down
19 changes: 1 addition & 18 deletions e2e_tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,8 @@ use parsec_client::core::interface::operations::psa_key_attributes::{
Attributes, EccFamily, Lifetime, Policy, Type, UsageFlags,
};
use parsec_client::core::interface::requests::{Opcode, ProviderId, ResponseStatus, Result};
use parsec_client::core::ipc_handler::unix_socket;
use parsec_client::error::Error;
use std::collections::HashSet;
use std::time::Duration;

const TEST_SOCKET_PATH: &str = "/tmp/parsec.sock";
const TEST_TIMEOUT: Duration = Duration::from_secs(60);

/// Client structure automatically choosing a provider and high-level operation functions.
#[derive(Debug)]
Expand Down Expand Up @@ -58,20 +53,8 @@ impl TestClient {
env_logger::try_init();
}

let mut basic_client = BasicClient::new_naked();

let ipc_handler =
unix_socket::Handler::new(TEST_SOCKET_PATH.into(), Some(TEST_TIMEOUT)).unwrap();
basic_client.set_ipc_handler(Box::from(ipc_handler));
basic_client.set_timeout(Some(Duration::from_secs(10)));

basic_client.set_default_provider().unwrap();
basic_client
.set_default_auth(Some(String::from("root")))
.unwrap();

TestClient {
basic_client,
basic_client: BasicClient::new(Some(String::from("root"))).unwrap(),
created_keys: Some(HashSet::new()),
}
}
Expand Down
31 changes: 31 additions & 0 deletions e2e_tests/tests/all_providers/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use e2e_tests::TestClient;
use log::{error, info};
use parsec_client::core::interface::operations::list_providers::Uuid;
use parsec_client::core::interface::operations::psa_algorithm::Hash;
use parsec_client::core::interface::requests::ResponseStatus;
use std::env;
use std::fs;
use std::path::PathBuf;
Expand Down Expand Up @@ -129,3 +131,32 @@ fn pkcs11_encrypt_software() {
.unwrap();
assert_eq!(&plaintext_msg[..], &plaintext[..]);
}

#[test]
fn various_fields() {
set_config("various_field_check.toml");
reload_service();

env::set_var("PARSEC_SERVICE_ENDPOINT", "unix:/tmp/toto.sock");

let mut client = TestClient::new();
// Try to send a bit less than 1KiB, should work
let _ = client
.hash_compute(Hash::Sha256, &vec![0xDD; 1019])
.unwrap();
// Try to send 1KiB and one byte, should fail
assert_eq!(
client
.hash_compute(Hash::Sha256, &vec![0xDD; 1025])
.unwrap_err(),
ResponseStatus::BodySizeExceedsLimit
);

let _ = client.generate_bytes(1024).unwrap();
assert_eq!(
client.generate_bytes(1025).unwrap_err(),
ResponseStatus::ResponseTooLarge
);

env::set_var("PARSEC_SERVICE_ENDPOINT", "unix:/tmp/parsec.sock");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[core_settings]
allow_root = true
thread_pool_size = 2
idle_listener_sleep_duration = 12
log_level = "trace"
log_timestamp = true
# 1 KiB max for requests
body_len_limit = 1024
log_error_details = true
# 1 KiB max for responses
buffer_size_limit = 1024

[listener]
listener_type = "DomainSocket"
timeout = 202
socket_path = "/tmp/toto.sock"

[authenticator]
auth_type = "Direct"

[[key_manager]]
name = "I-want-to-speak-to-the-manager"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

manager_type = "OnDisk"
store_path = "/tmp/the-mappings"

[[provider]]
provider_type = "MbedCrypto"
key_info_manager = "I-want-to-speak-to-the-manager"
11 changes: 5 additions & 6 deletions src/authenticators/direct_authenticator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
//! This authenticator does not offer any security value and should only be used in environments
//! where all the clients and the service are mutually trustworthy.

use super::{Admin, AdminList, Application, Authenticate};
use super::{AdminList, Application, Authenticate};
use crate::front::listener::ConnectionMetadata;
use crate::utils::config::Admin;
use log::error;
use parsec_interface::operations::list_authenticators;
use parsec_interface::requests::request::RequestAuth;
Expand Down Expand Up @@ -73,7 +74,7 @@ impl Authenticate for DirectAuthenticator {

#[cfg(test)]
mod test {
use super::super::{Admin, Authenticate};
use super::super::Authenticate;
use super::DirectAuthenticator;
use crate::authenticators::ApplicationName;
use parsec_interface::requests::request::RequestAuth;
Expand Down Expand Up @@ -126,11 +127,9 @@ mod test {
#[test]
fn admin_check() {
let admin_name = String::from("admin_name");
let admin = toml::from_str(&format!("name = '{}'", admin_name)).unwrap();
let authenticator = DirectAuthenticator {
admins: vec![Admin {
name: admin_name.clone(),
}]
.into(),
admins: vec![admin].into(),
};

let app_name = "app_name".to_string();
Expand Down
33 changes: 1 addition & 32 deletions src/authenticators/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ pub mod direct_authenticator;
pub mod unix_peer_credentials_authenticator;

use crate::front::listener::ConnectionMetadata;
use crate::utils::config::Admin;
use parsec_interface::operations::list_authenticators;
use parsec_interface::requests::request::RequestAuth;
use parsec_interface::requests::Result;
use serde::Deserialize;
use std::ops::Deref;
use zeroize::Zeroize;

/// String wrapper for app names
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
Expand Down Expand Up @@ -114,36 +113,6 @@ impl std::fmt::Display for ApplicationName {
}
}

/// Authenticator configuration structure
#[derive(Deserialize, Debug, Zeroize)]
#[zeroize(drop)]
#[serde(tag = "auth_type")]
pub enum AuthenticatorConfig {
/// Direct authentication
Direct {
/// List of service admins
admins: Option<Vec<Admin>>,
},
/// Unix Peer Credentials authentication
UnixPeerCredentials {
/// List of service admins
admins: Option<Vec<Admin>>,
},
}

/// Structure defining the properties of a service admin
#[derive(Deserialize, Debug, Zeroize, Clone)]
#[zeroize(drop)]
pub struct Admin {
name: String,
}

impl Admin {
fn name(&self) -> &str {
&self.name
}
}

#[derive(Debug, Clone, Default)]
struct AdminList(Vec<Admin>);

Expand Down
11 changes: 5 additions & 6 deletions src/authenticators/unix_peer_credentials_authenticator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
//!
//! Currently, the stringified UID is used as the application name.

use super::{Admin, AdminList, Application, Authenticate};
use super::{AdminList, Application, Authenticate};
use crate::front::listener::ConnectionMetadata;
use crate::utils::config::Admin;
use log::error;
use parsec_interface::operations::list_authenticators;
use parsec_interface::requests::request::RequestAuth;
Expand Down Expand Up @@ -98,7 +99,7 @@ impl Authenticate for UnixPeerCredentialsAuthenticator {

#[cfg(test)]
mod test {
use super::super::{Admin, Authenticate};
use super::super::Authenticate;
use super::UnixPeerCredentialsAuthenticator;
use crate::authenticators::ApplicationName;
use crate::front::domain_socket::peer_credentials;
Expand Down Expand Up @@ -227,11 +228,9 @@ mod test {
peer_credentials::peer_cred(&_sock_b).unwrap(),
);

let admin = toml::from_str(&format!("name = '{}'", get_current_uid())).unwrap();
let authenticator = UnixPeerCredentialsAuthenticator {
admins: vec![Admin {
name: get_current_uid().to_string(),
}]
.into(),
admins: vec![admin].into(),
};

let req_auth_data = cred_a.uid.to_le_bytes().to_vec();
Expand Down
2 changes: 1 addition & 1 deletion src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

use anyhow::Result;
use log::{info, trace};
use parsec_service::utils::{ServiceBuilder, ServiceConfig};
use parsec_service::utils::{config::ServiceConfig, ServiceBuilder};
use signal_hook::{consts::SIGHUP, consts::SIGINT, consts::SIGTERM, flag};
use std::io::{Error, ErrorKind};
use std::sync::{
Expand Down
19 changes: 0 additions & 19 deletions src/front/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//! trait acts as an interface for the operations that must be supported by any implementation
//! of the IPC mechanism used as a Parsec front.
use derivative::Derivative;
use serde::Deserialize;
use std::time::Duration;

/// This trait is created to allow the iterator returned by incoming to iterate over a trait object
Expand All @@ -15,24 +14,6 @@ pub trait ReadWrite: std::io::Read + std::io::Write {}
// Automatically implements ReadWrite for all types that implement Read and Write.
impl<T: std::io::Read + std::io::Write> ReadWrite for T {}

/// Type of the Listener used
#[derive(Copy, Clone, Deserialize, Debug)]
pub enum ListenerType {
/// Listener using Unix Domain Socket
DomainSocket,
}

/// Configuration of the Listener
#[derive(Clone, Deserialize, Debug)]
pub struct ListenerConfig {
/// Type of the Listener
pub listener_type: ListenerType,
/// Timeout of the Listener before the connection errors out (in milliseconds)
pub timeout: u64,
/// Path of the Unix Domain socket
pub socket_path: Option<String>,
}

/// Specifies metadata associated with a connection, if any.
#[derive(Copy, Clone, Debug)]
pub enum ConnectionMetadata {
Expand Down
19 changes: 1 addition & 18 deletions src/key_info_managers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
//! means but it has to be persistent.

use crate::authenticators::ApplicationName;
use crate::utils::config::{KeyInfoManagerConfig, KeyInfoManagerType};
use anyhow::Result;
use derivative::Derivative;
use parsec_interface::operations::psa_key_attributes::Attributes;
Expand All @@ -20,24 +21,6 @@ use zeroize::Zeroize;

pub mod on_disk_manager;

/// Type of the KeyInfoManager
#[derive(Copy, Clone, Deserialize, Debug)]
pub enum KeyInfoManagerType {
/// KeyInfoManager storing the mappings on disk
OnDisk,
}

/// KeyInfoManager configuration
#[derive(Deserialize, Debug)]
pub struct KeyInfoManagerConfig {
/// Name of the KeyInfoManager
pub name: String,
/// Type of the KeyInfoManager
pub manager_type: KeyInfoManagerType,
/// Path used to store the mappings
pub store_path: Option<String>,
}

/// This structure corresponds to a unique identifier of the key. It is used internally by the Key
/// ID manager to refer to a key.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
Expand Down
Loading