Skip to content

Commit

Permalink
Share instance configuration accross login contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
sosthene-nitrokey committed Sep 4, 2024
1 parent 9f51c41 commit fe24604
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 85 deletions.
6 changes: 3 additions & 3 deletions pkcs11/src/backend/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use nethsm_sdk_rs::{
models::UserRole,
ureq,
};
use std::{thread, time::Duration};
use std::{sync::Arc, thread, time::Duration};

use crate::config::config_file::{RetryConfig, UserConfig};

Expand All @@ -19,7 +19,7 @@ use super::{ApiError, Error};
pub struct LoginCtx {
operator: Option<UserConfig>,
administrator: Option<UserConfig>,
instances: Vec<Configuration>,
instances: Arc<[Configuration]>,
index: usize,
ck_state: CK_STATE,
retries: Option<RetryConfig>,
Expand Down Expand Up @@ -65,7 +65,7 @@ impl LoginCtx {
pub fn new(
operator: Option<UserConfig>,
administrator: Option<UserConfig>,
instances: Vec<Configuration>,
instances: Arc<[Configuration]>,
retries: Option<RetryConfig>,
) -> Self {
let mut ck_state = CKS_RO_PUBLIC_SESSION;
Expand Down
2 changes: 1 addition & 1 deletion pkcs11/src/config/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct Slot {
pub label: String,
pub retries: Option<RetryConfig>,
pub _description: Option<String>,
pub instances: Vec<Configuration>,
pub instances: Arc<[Configuration]>,
pub operator: Option<UserConfig>,
pub administrator: Option<UserConfig>,
pub db: Arc<(Mutex<Db>, Condvar)>,
Expand Down
166 changes: 85 additions & 81 deletions pkcs11/src/config/initialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@ impl ServerCertVerifier for FingerprintVerifier {
}

fn slot_from_config(slot: &SlotConfig) -> Result<Slot, InitializationError> {
let mut instances = vec![];

let default_user = slot
.operator
.as_ref()
Expand All @@ -203,88 +201,94 @@ fn slot_from_config(slot: &SlotConfig) -> Result<Slot, InitializationError> {
slot.retries
);

for instance in slot.instances.iter() {
let tls_conf = rustls::ClientConfig::builder();

let tls_conf = if instance.danger_insecure_cert {
tls_conf
.dangerous()
.with_custom_certificate_verifier(Arc::new(DangerIgnoreVerifier))
.with_no_client_auth()
} else if !instance.sha256_fingerprints.is_empty() {
let fingerprints = instance
.sha256_fingerprints
.iter()
.map(|f| f.value.clone())
.collect();
tls_conf
.dangerous()
.with_custom_certificate_verifier(Arc::new(FingerprintVerifier { fingerprints }))
.with_no_client_auth()
} else {
let mut roots = rustls::RootCertStore::empty();
let native_certs = rustls_native_certs::load_native_certs().map_err(|err| {
error!("Failed to load certificates: {err}");
InitializationError::NoCerts
})?;

let (added, failed) = roots.add_parsable_certificates(native_certs);
// panic!("{:?}", (added, failed));
debug!("Added {added} certifcates and failed to parse {failed} certificates");

if added == 0 {
error!("Added no native certificates");
return Err(InitializationError::NoCerts);
let instances = slot
.instances
.iter()
.map(|instance| {
let tls_conf = rustls::ClientConfig::builder();

let tls_conf = if instance.danger_insecure_cert {
tls_conf
.dangerous()
.with_custom_certificate_verifier(Arc::new(DangerIgnoreVerifier))
.with_no_client_auth()
} else if !instance.sha256_fingerprints.is_empty() {
let fingerprints = instance
.sha256_fingerprints
.iter()
.map(|f| f.value.clone())
.collect();
tls_conf
.dangerous()
.with_custom_certificate_verifier(Arc::new(FingerprintVerifier {
fingerprints,
}))
.with_no_client_auth()
} else {
let mut roots = rustls::RootCertStore::empty();
let native_certs = rustls_native_certs::load_native_certs().map_err(|err| {
error!("Failed to load certificates: {err}");
InitializationError::NoCerts
})?;

let (added, failed) = roots.add_parsable_certificates(native_certs);
// panic!("{:?}", (added, failed));
debug!("Added {added} certifcates and failed to parse {failed} certificates");

if added == 0 {
error!("Added no native certificates");
return Err(InitializationError::NoCerts);
}

tls_conf.with_root_certificates(roots).with_no_client_auth()
};

info!(
"Instance configured with: max_idle_connection: {:?}",
instance.max_idle_connections
);

let max_idle_connections = instance
.max_idle_connections
.or_else(|| available_parallelism().ok().map(Into::into))
.unwrap_or(100);

// 100 idle connections is the default
// By default there is 1 idle connection per host, but we are only connecting to 1 host.
// So we need to allow the connection pool to scale to match the number of threads
let mut builder = ureq::AgentBuilder::new()
.tls_config(Arc::new(tls_conf))
.max_idle_connections(max_idle_connections)
.max_idle_connections_per_host(max_idle_connections);

if let Some(t) = slot.timeout_seconds {
builder = builder
.timeout(Duration::from_secs(t))
.timeout_connect(Duration::from_secs(10));
}
if let Some(keepalive) = slot.tcp_keepalive {
builder = builder
.tcp_keepalive_time(Duration::from_secs(keepalive.time_seconds))
.tcp_keepalive_interval(Duration::from_secs(keepalive.interval_seconds))
.tcp_keepalive_retries(keepalive.retries);
}

tls_conf.with_root_certificates(roots).with_no_client_auth()
};

info!(
"Instance configured with: max_idle_connection: {:?}",
instance.max_idle_connections
);

let max_idle_connections = instance
.max_idle_connections
.or_else(|| available_parallelism().ok().map(Into::into))
.unwrap_or(100);

// 100 idle connections is the default
// By default there is 1 idle connection per host, but we are only connecting to 1 host.
// So we need to allow the connection pool to scale to match the number of threads
let mut builder = ureq::AgentBuilder::new()
.tls_config(Arc::new(tls_conf))
.max_idle_connections(max_idle_connections)
.max_idle_connections_per_host(max_idle_connections);

if let Some(t) = slot.timeout_seconds {
builder = builder
.timeout(Duration::from_secs(t))
.timeout_connect(Duration::from_secs(10));
}
if let Some(keepalive) = slot.tcp_keepalive {
builder = builder
.tcp_keepalive_time(Duration::from_secs(keepalive.time_seconds))
.tcp_keepalive_interval(Duration::from_secs(keepalive.interval_seconds))
.tcp_keepalive_retries(keepalive.retries);
}

if let Some(max_idle_duration) = slot.connections_max_idle_duration {
builder = builder.max_idle_duration(Duration::from_secs(max_idle_duration));
}

let agent = builder.build();
if let Some(max_idle_duration) = slot.connections_max_idle_duration {
builder = builder.max_idle_duration(Duration::from_secs(max_idle_duration));
}

let api_config = nethsm_sdk_rs::apis::configuration::Configuration {
client: agent,
base_path: instance.url.clone(),
basic_auth: Some((default_user.username.clone(), default_user.password.clone())),
user_agent: Some(DEFAULT_USER_AGENT.to_string()),
..Default::default()
};
instances.push(api_config);
}
let agent = builder.build();

let api_config = nethsm_sdk_rs::apis::configuration::Configuration {
client: agent,
base_path: instance.url.clone(),
basic_auth: Some((default_user.username.clone(), default_user.password.clone())),
user_agent: Some(DEFAULT_USER_AGENT.to_string()),
..Default::default()
};
Ok(api_config)
})
.collect::<Result<_, InitializationError>>()?;

Ok(Slot {
_description: slot.description.clone(),
Expand Down

0 comments on commit fe24604

Please sign in to comment.