aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.rs33
-rw-r--r--src/client/certificate.rs41
2 files changed, 51 insertions, 23 deletions
diff --git a/src/client.rs b/src/client.rs
index 24ec550..ec9cc46 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -28,8 +28,8 @@ use crate::{
};
use self::certificate::{
- load_known_hosts_store_from_config, CertVerificationInfo, CertVerificationStatus,
- CertVerifierAction, CertificateInteractionEvent, CertificateUpdateEvent,
+ load_known_hosts_store_from_config, CertConnectionAbortEvent, CertInteractionEvent,
+ CertTrustUpdateEvent, CertVerificationInfo, CertVerificationStatus, CertVerifierAction,
CertificateVerificationMode, SkipServerVerification, TofuServerVerification,
};
@@ -98,12 +98,16 @@ enum ClientState {
pub(crate) enum InternalAsyncMessage {
Connected,
LostConnection,
- CertificateActionRequest {
+ CertificateInteractionRequest {
status: CertVerificationStatus,
info: CertVerificationInfo,
action_sender: oneshot::Sender<CertVerifierAction>,
},
- TrustedCertificateUpdate(CertVerificationInfo),
+ CertificateTrustUpdate(CertVerificationInfo),
+ CertificateConnectionAbort {
+ status: CertVerificationStatus,
+ cert_info: CertVerificationInfo,
+ },
}
#[derive(Debug, Clone)]
@@ -386,8 +390,9 @@ fn update_sync_client(
mut client: ResMut<Client>,
mut connection_events: EventWriter<ConnectionEvent>,
mut connection_lost_events: EventWriter<ConnectionLostEvent>,
- mut certificate_interaction_events: EventWriter<CertificateInteractionEvent>,
- mut certificate_update_events: EventWriter<CertificateUpdateEvent>,
+ mut certificate_interaction_events: EventWriter<CertInteractionEvent>,
+ mut cert_trust_update_events: EventWriter<CertTrustUpdateEvent>,
+ mut cert_connection_abort_events: EventWriter<CertConnectionAbortEvent>,
) {
while let Ok(message) = client.internal_receiver.try_recv() {
match message {
@@ -399,19 +404,22 @@ fn update_sync_client(
client.state = ClientState::Disconnected;
connection_lost_events.send(ConnectionLostEvent);
}
- InternalAsyncMessage::CertificateActionRequest {
+ InternalAsyncMessage::CertificateInteractionRequest {
status,
info,
action_sender,
} => {
- certificate_interaction_events.send(CertificateInteractionEvent {
+ certificate_interaction_events.send(CertInteractionEvent {
status,
info,
action_sender: Mutex::new(Some(action_sender)),
});
}
- InternalAsyncMessage::TrustedCertificateUpdate(info) => {
- certificate_update_events.send(CertificateUpdateEvent(info));
+ InternalAsyncMessage::CertificateTrustUpdate(info) => {
+ cert_trust_update_events.send(CertTrustUpdateEvent(info));
+ }
+ InternalAsyncMessage::CertificateConnectionAbort { status, cert_info } => {
+ cert_connection_abort_events.send(CertConnectionAbortEvent { status, cert_info });
}
}
}
@@ -429,8 +437,9 @@ impl Plugin for QuinnetClientPlugin {
fn build(&self, app: &mut App) {
app.add_event::<ConnectionEvent>()
.add_event::<ConnectionLostEvent>()
- .add_event::<CertificateInteractionEvent>()
- .add_event::<CertificateUpdateEvent>()
+ .add_event::<CertInteractionEvent>()
+ .add_event::<CertTrustUpdateEvent>()
+ .add_event::<CertConnectionAbortEvent>()
// StartupStage::PreStartup so that resources created in commands are available to default startup_systems
.add_startup_system_to_stage(StartupStage::PreStartup, start_async_client)
.add_system(update_sync_client);
diff --git a/src/client/certificate.rs b/src/client/certificate.rs
index 33587da..94f2abe 100644
--- a/src/client/certificate.rs
+++ b/src/client/certificate.rs
@@ -21,7 +21,7 @@ pub const DEFAULT_CERT_VERIFIER_BEHAVIOUR: CertVerifierBehaviour =
CertVerifierBehaviour::ImmediateAction(CertVerifierAction::AbortConnection);
/// Event raised when a user/app interaction is needed for the server's certificate validation
-pub struct CertificateInteractionEvent {
+pub struct CertInteractionEvent {
/// The current status of the verification
pub status: CertVerificationStatus,
/// Server & Certificate info
@@ -30,7 +30,7 @@ pub struct CertificateInteractionEvent {
pub(crate) action_sender: Mutex<Option<oneshot::Sender<CertVerifierAction>>>,
}
-impl CertificateInteractionEvent {
+impl CertInteractionEvent {
pub fn apply_cert_verifier_action(
&self,
action: CertVerifierAction,
@@ -48,7 +48,13 @@ impl CertificateInteractionEvent {
}
/// Event raised when a new certificate is trusted
-pub struct CertificateUpdateEvent(pub CertVerificationInfo);
+pub struct CertTrustUpdateEvent(pub CertVerificationInfo);
+
+/// Event raised when a connection is aborted during the certificate verification
+pub struct CertConnectionAbortEvent {
+ pub status: CertVerificationStatus,
+ pub cert_info: CertVerificationInfo,
+}
/// How the client should handle the server certificate.
#[derive(Debug, Clone)]
@@ -250,19 +256,19 @@ impl TofuServerVerification {
.unwrap_or(&DEFAULT_CERT_VERIFIER_BEHAVIOUR);
match behaviour {
CertVerifierBehaviour::ImmediateAction(action) => {
- self.apply_verifier_immediate_action(action, cert_info)
+ self.apply_verifier_immediate_action(action, status, cert_info)
}
CertVerifierBehaviour::RequestClientAction => {
let (action_sender, cert_action_recv) = oneshot::channel::<CertVerifierAction>();
self.to_sync_client
- .try_send(InternalAsyncMessage::CertificateActionRequest {
- status,
+ .try_send(InternalAsyncMessage::CertificateInteractionRequest {
+ status: status.clone(),
info: cert_info.clone(),
action_sender,
})
.unwrap();
match block_on(cert_action_recv) {
- Ok(action) => self.apply_verifier_immediate_action(&action, cert_info),
+ Ok(action) => self.apply_verifier_immediate_action(&action, status, cert_info),
Err(err) => Err(rustls::Error::InvalidCertificateData(format!(
"Failed to receive CertVerifierAction: {}",
err
@@ -275,12 +281,25 @@ impl TofuServerVerification {
fn apply_verifier_immediate_action(
&self,
action: &CertVerifierAction,
+ status: CertVerificationStatus,
cert_info: CertVerificationInfo,
) -> Result<rustls::client::ServerCertVerified, rustls::Error> {
match action {
- CertVerifierAction::AbortConnection => Err(rustls::Error::InvalidCertificateData(
- format!("CertVerifierAction requested to abort the connection"),
- )),
+ CertVerifierAction::AbortConnection => {
+ match self.to_sync_client.try_send(
+ InternalAsyncMessage::CertificateConnectionAbort {
+ status: status,
+ cert_info,
+ },
+ ) {
+ Ok(_) => Err(rustls::Error::InvalidCertificateData(format!(
+ "CertVerifierAction requested to abort the connection"
+ ))),
+ Err(_) => Err(rustls::Error::General(format!(
+ "Failed to signal CertificateConnectionAbort"
+ ))),
+ }
+ }
CertVerifierAction::TrustOnce => Ok(rustls::client::ServerCertVerified::assertion()),
CertVerifierAction::TrustAndStore => {
// If we need to store them to a file
@@ -298,7 +317,7 @@ impl TofuServerVerification {
// In all cases raise an event containing the new certificate entry
match self
.to_sync_client
- .try_send(InternalAsyncMessage::TrustedCertificateUpdate(cert_info))
+ .try_send(InternalAsyncMessage::CertificateTrustUpdate(cert_info))
{
Ok(_) => Ok(rustls::client::ServerCertVerified::assertion()),
Err(_) => Err(rustls::Error::General(format!(