Skip to content

Commit ccd293e

Browse files
committed
Update systemd unit file with new hierarchy
Signed-off-by: Hugues de Valon <[email protected]>
1 parent 599be48 commit ccd293e

File tree

19 files changed

+98
-78
lines changed

19 files changed

+98
-78
lines changed

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ features = ["pkcs11-provider", "tpm-provider", "tss-esapi/docs", "mbed-crypto-pr
5252

5353
[features]
5454
default = []
55-
no-parsec-user-and-clients-group = []
5655
mbed-crypto-provider = ["psa-crypto"]
5756
pkcs11-provider = ["pkcs11", "picky-asn1-der", "picky-asn1", "picky-asn1-x509", "psa-crypto", "rand"]
5857
tpm-provider = ["tss-esapi", "picky-asn1-der", "picky-asn1", "picky-asn1-x509", "hex"]

ci.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ while [ "$#" -gt 0 ]; do
6767
PROVIDER_NAME=$1
6868
cp $(pwd)/e2e_tests/provider_cfg/$1/config.toml $CONFIG_PATH
6969
if [ "$PROVIDER_NAME" = "all" ]; then
70-
FEATURES="--features=all-providers,no-parsec-user-and-clients-group"
70+
FEATURES="--features=all-providers"
7171
TEST_FEATURES="--features=all-providers"
7272
else
73-
FEATURES="--features=$1-provider,no-parsec-user-and-clients-group"
73+
FEATURES="--features=$1-provider"
7474
TEST_FEATURES="--features=$1-provider"
7575
fi
7676
;;

config.toml

+7-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ listener_type = "DomainSocket"
4444
# timeout expires, the connection is dropped.
4545
timeout = 200 # in milliseconds
4646

47+
# Specify the Unix Domain Socket path. The path is fixed and should always be the default one for
48+
# clients to connect. However, it is useful to change it for tests.
49+
# WARNING: If a file already exists at that path, the service will remove it before creating the
50+
# socket file.
51+
#socket_path = "/run/parsec/parsec.sock"
52+
4753
# (Required) Configuration for the components managing key info for providers.
4854
# Defined as an array of tables: https://github.com/toml-lang/toml#user-content-array-of-tables
4955
[[key_manager]]
@@ -54,7 +60,7 @@ name = "on-disk-manager"
5460
manager_type = "OnDisk"
5561

5662
# Path to the location where the mapping will be persisted (in this case, the filesystem path)
57-
#store_path = "./mappings"
63+
#store_path = "/var/lib/parsec/mappings"
5864

5965
# (Required) Provider configurations.
6066
# Defined as an array of tables: https://github.com/toml-lang/toml#user-content-array-of-tables

e2e_tests/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ parsec-client = { version = "0.9.0", features = ["testing"] }
1818
log = "0.4.11"
1919
rand = "0.7.3"
2020

21+
[patch.crates-io]
22+
# Just to make the CI pass, update with the newest version
23+
parsec-client = { git = 'https://github.com/hug-dev/parsec-client-rust', branch = 'new-socket-path' }
24+
2125
[dev-dependencies]
2226
ring = "0.16.15"
2327
env_logger = "0.7.1"

e2e_tests/provider_cfg/all/config.toml

+2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ allow_root = true
1010
[listener]
1111
listener_type = "DomainSocket"
1212
timeout = 200 # in milliseconds
13+
socket_path = "/tmp/parsec.sock"
1314

1415
[[key_manager]]
1516
name = "on-disk-manager"
1617
manager_type = "OnDisk"
18+
store_path = "./mappings"
1719

1820
[[provider]]
1921
provider_type = "MbedCrypto"

e2e_tests/provider_cfg/mbed-crypto/config.toml

+2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ listener_type = "DomainSocket"
1212
# The timeout needs to be smaller than the test client timeout (five seconds) as it is testing
1313
# that the service does not hang for very big values of body or authentication length.
1414
timeout = 3000 # in milliseconds
15+
socket_path = "/tmp/parsec.sock"
1516

1617
[[key_manager]]
1718
name = "on-disk-manager"
1819
manager_type = "OnDisk"
20+
store_path = "./mappings"
1921

2022
[[provider]]
2123
provider_type = "MbedCrypto"

e2e_tests/provider_cfg/pkcs11/config.toml

+2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ listener_type = "DomainSocket"
1212
# The timeout needs to be smaller than the test client timeout (five seconds) as it is testing
1313
# that the service does not hang for very big values of body or authentication length.
1414
timeout = 3000 # in milliseconds
15+
socket_path = "/tmp/parsec.sock"
1516

1617
[[key_manager]]
1718
name = "on-disk-manager"
1819
manager_type = "OnDisk"
20+
store_path = "./mappings"
1921

2022
[[provider]]
2123
provider_type = "Pkcs11"

e2e_tests/provider_cfg/tpm/config.toml

+2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ listener_type = "DomainSocket"
1212
# The timeout needs to be smaller than the test client timeout (five seconds) as it is testing
1313
# that the service does not hang for very big values of body or authentication length.
1414
timeout = 3000 # in milliseconds
15+
socket_path = "/tmp/parsec.sock"
1516

1617
[[key_manager]]
1718
name = "on-disk-manager"
1819
manager_type = "OnDisk"
20+
store_path = "./mappings"
1921

2022
[[provider]]
2123
provider_type = "Tpm"

e2e_tests/src/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,15 @@ use parsec_client::core::interface::operations::psa_key_attributes::{
2222
Attributes, EccFamily, Lifetime, Policy, Type, UsageFlags,
2323
};
2424
use parsec_client::core::interface::requests::{Opcode, ProviderID, ResponseStatus, Result};
25+
use parsec_client::core::ipc_handler::unix_socket;
2526
use parsec_client::core::secrecy::{ExposeSecret, Secret};
2627
use parsec_client::error::Error;
2728
use std::collections::HashSet;
2829
use std::time::Duration;
2930

31+
const TEST_SOCKET_PATH: &str = "/tmp/parsec.sock";
32+
const TEST_TIMEOUT: Duration = Duration::from_secs(1);
33+
3034
/// Client structure automatically choosing a provider and high-level operation functions.
3135
#[derive(Debug)]
3236
pub struct TestClient {
@@ -58,6 +62,9 @@ impl TestClient {
5862
created_keys: Some(HashSet::new()),
5963
};
6064

65+
let ipc_handler = unix_socket::Handler::new(TEST_SOCKET_PATH.into(), Some(TEST_TIMEOUT));
66+
client.basic_client.set_ipc_handler(Box::from(ipc_handler));
67+
6168
let crypto_provider = client.find_crypto_provider();
6269
client.set_provider(crypto_provider);
6370
client

e2e_tests/src/raw_request.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const MAX_BODY_SIZE: usize = 1 << 31;
1313
#[derive(Copy, Clone, Debug)]
1414
pub struct RawRequestClient;
1515

16-
static SOCKET_PATH: &str = "/run/parsec/parsec.sock";
16+
static SOCKET_PATH: &str = "/tmp/parsec.sock";
1717
const TIMEOUT: Duration = Duration::from_secs(5);
1818

1919
#[allow(clippy::new_without_default)]

e2e_tests/tests/per_provider/normal_tests/export_key.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,14 @@ fn export_without_create() {
9191
}
9292

9393
#[test]
94-
fn import_and_export_public_key() -> Result<()> {
94+
fn import_and_export_key() -> Result<()> {
9595
let mut client = TestClient::new();
9696

9797
if !client.is_operation_supported(Opcode::PsaExportKey) {
9898
return Ok(());
9999
}
100100

101-
let key_name = String::from("import_and_export_public_key");
101+
let key_name = String::from("import_and_export_key");
102102
let key_data = vec![
103103
48, 129, 137, 2, 129, 129, 0, 153, 165, 220, 135, 89, 101, 254, 229, 28, 33, 138, 247, 20,
104104
102, 253, 217, 247, 246, 142, 107, 51, 40, 179, 149, 45, 117, 254, 236, 161, 109, 16, 81,

e2e_tests/tests/per_provider/normal_tests/ping.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use parsec_client::core::interface::requests::Opcode;
77
use parsec_client::core::interface::requests::ProviderID;
88
use parsec_client::core::interface::requests::ResponseStatus;
99
use parsec_client::core::interface::requests::Result;
10+
use parsec_client::core::ipc_handler::unix_socket;
11+
use std::time::Duration;
1012

1113
#[test]
1214
fn test_ping() -> Result<()> {
@@ -20,7 +22,13 @@ fn test_ping() -> Result<()> {
2022

2123
#[test]
2224
fn mangled_ping() {
23-
let client = RequestClient::default();
25+
let client = RequestClient {
26+
ipc_handler: Box::from(unix_socket::Handler::new(
27+
"/tmp/parsec.sock".into(),
28+
Some(Duration::from_secs(1)),
29+
)),
30+
..Default::default()
31+
};
2432
let mut req = Request::new();
2533
req.header.provider = ProviderID::Core;
2634
req.header.opcode = Opcode::Ping;

fuzz/config.toml

+2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
[listener]
44
listener_type = "DomainSocket"
55
timeout = 200 # in milliseconds
6+
socket_path = "/tmp/parsec.sock"
67

78
[[key_manager]]
89
name = "on-disk-manager"
910
manager_type = "OnDisk"
11+
store_path = "./mappings"
1012

1113
# [[provider]]
1214
# provider_type = "MbedCryptoProvider"

src/front/domain_socket.rs

+49-66
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,19 @@
77
use super::listener;
88
use listener::Listen;
99
use listener::{Connection, ConnectionMetadata};
10-
use log::error;
11-
#[cfg(not(feature = "no-parsec-user-and-clients-group"))]
12-
use std::ffi::CString;
10+
use log::{error, warn};
1311
use std::fs;
1412
use std::fs::Permissions;
1513
use std::io::{Error, ErrorKind, Result};
14+
use std::os::unix::fs::FileTypeExt;
1615
use std::os::unix::fs::PermissionsExt;
1716
use std::os::unix::io::FromRawFd;
1817
use std::os::unix::net::UnixListener;
19-
use std::path::Path;
18+
use std::path::PathBuf;
2019
use std::time::Duration;
2120

22-
static SOCKET_PATH: &str = "/run/parsec/parsec.sock";
23-
#[cfg(not(feature = "no-parsec-user-and-clients-group"))]
21+
static DEFAULT_SOCKET_PATH: &str = "/run/parsec/parsec.sock";
2422
const PARSEC_USERNAME: &str = "parsec";
25-
#[cfg(not(feature = "no-parsec-user-and-clients-group"))]
2623
const PARSEC_GROUPNAME: &str = "parsec-clients";
2724

2825
/// Unix Domain Socket IPC manager
@@ -38,29 +35,37 @@ pub struct DomainSocketListener {
3835

3936
impl DomainSocketListener {
4037
/// Initialise the connection to the Unix socket.
41-
pub fn new(timeout: Duration) -> Result<Self> {
42-
#[cfg(not(feature = "no-parsec-user-and-clients-group"))]
43-
DomainSocketListener::check_user_details()?;
38+
pub fn new(timeout: Duration, socket_path: PathBuf) -> Result<Self> {
39+
DomainSocketListener::check_user_details();
4440

4541
// If Parsec was service activated or not started under systemd, this
4642
// will return `0`. `1` will be returned in case Parsec is socket activated.
4743
let listener = match sd_notify::listen_fds()? {
4844
0 => {
49-
let socket = Path::new(SOCKET_PATH);
50-
let parent_dir = socket.parent().unwrap();
51-
if !parent_dir.exists() {
52-
fs::create_dir_all(parent_dir)?;
53-
} else if socket.exists() {
54-
fs::remove_file(&socket)?;
45+
if socket_path.exists() {
46+
let meta = fs::metadata(&socket_path)?;
47+
if meta.file_type().is_socket() {
48+
warn!(
49+
"Removing the existing socket file at {}.",
50+
socket_path.display()
51+
);
52+
fs::remove_file(&socket_path)?;
53+
} else {
54+
error!(
55+
"A file exists at {} but is not a Unix Domain Socket.",
56+
socket_path.display()
57+
);
58+
}
5559
}
5660

57-
let listener = UnixListener::bind(SOCKET_PATH)?;
61+
// Will fail if a file already exists at the path.
62+
let listener = UnixListener::bind(&socket_path)?;
5863
listener.set_nonblocking(true)?;
5964

6065
// Set the socket's permission to 666 to allow clients of different user to
6166
// connect.
6267
let permissions = Permissions::from_mode(0o666);
63-
fs::set_permissions(SOCKET_PATH, permissions)?;
68+
fs::set_permissions(socket_path, permissions)?;
6469

6570
listener
6671
}
@@ -88,53 +93,17 @@ impl DomainSocketListener {
8893
Ok(Self { listener, timeout })
8994
}
9095

91-
#[cfg(not(feature = "no-parsec-user-and-clients-group"))]
92-
fn check_user_details() -> Result<()> {
96+
fn check_user_details() {
9397
// Check Parsec is running as parsec user
9498
if users::get_current_username() != Some(PARSEC_USERNAME.into()) {
95-
error!(
96-
"Incorrect user. Parsec should be run as user {}.",
99+
warn!(
100+
"Incorrect user. Parsec should be run as user {}. Follow recommendations to install Parsec securely or clients might not be able to connect.",
97101
PARSEC_USERNAME
98102
);
99-
return Err(Error::new(
100-
ErrorKind::PermissionDenied,
101-
"Parsec run as incorrect user",
102-
));
103103
}
104-
// Check Parsec client group exists and parsec user is a member of it
105-
if let Some(parsec_clients_group) = users::get_group_by_name(PARSEC_GROUPNAME) {
106-
if let Some(groups) = users::get_user_groups(PARSEC_USERNAME, users::get_current_gid())
107-
{
108-
// Split to make `clippy` happy
109-
let parsec_user_in_parsec_clients_group = groups.into_iter().any(|group| {
110-
group.gid() == parsec_clients_group.gid()
111-
&& group.name() == parsec_clients_group.name()
112-
});
113-
// Check the parsec user is a member of the parsec clients group
114-
if parsec_user_in_parsec_clients_group {
115-
return Ok(());
116-
}
117-
error!(
118-
"{} user not a member of {}.",
119-
PARSEC_USERNAME, PARSEC_GROUPNAME
120-
);
121-
Err(Error::new(
122-
ErrorKind::PermissionDenied,
123-
"User permissions incorrect",
124-
))
125-
} else {
126-
error!("Retrieval of groups for user {} failed.", PARSEC_USERNAME);
127-
Err(Error::new(
128-
ErrorKind::InvalidInput,
129-
"Failed to retrieve user groups",
130-
))
131-
}
132-
} else {
133-
error!("{} group does not exist.", PARSEC_GROUPNAME);
134-
Err(Error::new(
135-
ErrorKind::PermissionDenied,
136-
"Group permissions incorrect",
137-
))
104+
// Check Parsec client group exists
105+
if users::get_group_by_name(PARSEC_GROUPNAME).is_none() {
106+
warn!("{} group does not exist. Follow recommendations to install Parsec securely or clients might not be able to connect.", PARSEC_GROUPNAME);
138107
}
139108
}
140109
}
@@ -190,15 +159,19 @@ impl Listen for DomainSocketListener {
190159
}
191160

192161
/// Builder for `DomainSocketListener`
193-
#[derive(Copy, Clone, Debug, Default)]
162+
#[derive(Clone, Debug, Default)]
194163
pub struct DomainSocketListenerBuilder {
195164
timeout: Option<Duration>,
165+
socket_path: Option<PathBuf>,
196166
}
197167

198168
impl DomainSocketListenerBuilder {
199169
/// Create a new DomainSocketListener builder
200170
pub fn new() -> Self {
201-
DomainSocketListenerBuilder { timeout: None }
171+
DomainSocketListenerBuilder {
172+
timeout: None,
173+
socket_path: None,
174+
}
202175
}
203176

204177
/// Add a timeout on the Unix Domain Socket used
@@ -207,12 +180,22 @@ impl DomainSocketListenerBuilder {
207180
self
208181
}
209182

183+
/// Specify the Unix Domain Socket path
184+
pub fn with_socket_path(mut self, socket_path: PathBuf) -> Self {
185+
self.socket_path = Some(socket_path);
186+
self
187+
}
188+
210189
/// Build the builder into the listener
211190
pub fn build(self) -> Result<DomainSocketListener> {
212-
DomainSocketListener::new(self.timeout.ok_or_else(|| {
213-
error!("The listener timeout was not set.");
214-
Error::new(ErrorKind::InvalidInput, "listener timeout missing")
215-
})?)
191+
DomainSocketListener::new(
192+
self.timeout.ok_or_else(|| {
193+
error!("The listener timeout was not set.");
194+
Error::new(ErrorKind::InvalidInput, "listener timeout missing")
195+
})?,
196+
self.socket_path
197+
.unwrap_or_else(|| DEFAULT_SOCKET_PATH.into()),
198+
)
216199
}
217200
}
218201

src/front/front_end.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl FrontEndHandler {
107107
if crate::utils::GlobalConfig::log_error_details() {
108108
if let Some(app_name_string) = app_name {
109109
info!(
110-
"Response from application name \"{}\" sent back",
110+
"Response for application name \"{}\" sent back",
111111
app_name_string
112112
);
113113
} else {

0 commit comments

Comments
 (0)