Skip to content

Commit

Permalink
Be more careful with sending notification
Browse files Browse the repository at this point in the history
  • Loading branch information
obelisk committed Dec 4, 2023
1 parent a44aff7 commit 22a07dd
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 12 deletions.
1 change: 1 addition & 0 deletions rustica-agent-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
&mut config.updatable_configuration,
&mut config.signatory,
&config.certificate_options,
&None,
)
.await
{
Expand Down
24 changes: 16 additions & 8 deletions rustica-agent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,18 +248,12 @@ impl SshAgentHandler for Handler {
// All other cases require us to fetch a certificate from one
// of the configured servers
_ => {
// Send a notification in case the user is going to need to
// tap their key to prove ownership before receiving their
// certificate
if let Some(f) = &self.notification_function {
f()
}

// Fetch a new certificate from one of the servers
fetch_new_certificate(
&mut configuration,
&self.signatory,
&self.certificate_options,
&self.notification_function,
)
.await
.map(|cert| {
Expand Down Expand Up @@ -332,7 +326,10 @@ impl SshAgentHandler for Handler {
})?;

if let Some(f) = &self.notification_function {
println!("Trying to send a notification");
f()
} else {
println!("No notification function set");
}

if let Some(pin) = &descriptor.pin {
Expand Down Expand Up @@ -402,6 +399,13 @@ impl SshAgentHandler for Handler {

match private_key {
Some(key) => {
if let Some(f) = &self.notification_function {
debug!("Trying to send a notification");
f()
} else {
debug!("No notification function set");
}

let signature = match key.sign(&data) {
None => return Err(AgentError::from("Signing Error")),
Some(signature) => signature,
Expand Down Expand Up @@ -585,9 +589,13 @@ pub async fn fetch_new_certificate(
configuration: &mut UpdatableConfiguration,
signatory: &Signatory,
options: &CertificateConfig,
notification_function: &Option<Box<dyn Fn() + Send + Sync>>,
) -> Result<Certificate, RusticaAgentLibraryError> {
for server in configuration.get_servers_mut() {
match server.refresh_certificate_async(signatory, options).await {
match server
.refresh_certificate_async(signatory, options, notification_function)
.await
{
Ok((cert, mtls_credentials)) => {
let parsed_cert = Certificate::from_string(&cert.cert)
.map_err(|e| RusticaAgentLibraryError::ServerReturnedInvalidCertificate(e))?;
Expand Down
10 changes: 8 additions & 2 deletions rustica-agent/src/rustica/cert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ impl RusticaServer {
&self,
signatory: &Signatory,
options: &CertificateConfig,
notification_function: &Option<Box<dyn Fn() + Send + Sync>>,
) -> Result<(RusticaCert, Option<MtlsCredentials>), RefreshError> {
let (mut client, challenge) = super::complete_rustica_challenge(self, signatory).await?;
let (mut client, challenge) =
super::complete_rustica_challenge(self, signatory, notification_function).await?;

let current_timestamp = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
Ok(ts) => ts.as_secs(),
Expand Down Expand Up @@ -68,7 +70,11 @@ impl RusticaServer {
signatory: &mut Signatory,
options: &CertificateConfig,
handle: &Handle,
notification_function: &Option<Box<dyn Fn() + Send + Sync>>,
) -> Result<(RusticaCert, Option<MtlsCredentials>), RefreshError> {
handle.block_on(async { self.refresh_certificate_async(signatory, options).await })
handle.block_on(async {
self.refresh_certificate_async(signatory, options, notification_function)
.await
})
}
}
6 changes: 4 additions & 2 deletions rustica-agent/src/rustica/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ impl RusticaServer {
signatory: &mut Signatory,
attestation: &PIVAttestation,
) -> Result<(), RefreshError> {
let (mut client, challenge) = super::complete_rustica_challenge(self, signatory).await?;
let (mut client, challenge) =
super::complete_rustica_challenge(self, signatory, &None).await?;

let request = RegisterKeyRequest {
certificate: attestation.certificate.clone(),
Expand Down Expand Up @@ -57,7 +58,8 @@ impl RusticaServer {
application: &str,
attestation: &U2FAttestation,
) -> Result<(), RefreshError> {
let (mut client, challenge) = super::complete_rustica_challenge(self, signatory).await?;
let (mut client, challenge) =
super::complete_rustica_challenge(self, signatory, &None).await?;

let request = RegisterU2fKeyRequest {
auth_data: attestation.auth_data.clone(),
Expand Down
7 changes: 7 additions & 0 deletions rustica-agent/src/rustica/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub async fn get_rustica_client(
pub async fn complete_rustica_challenge(
server: &RusticaServer,
signatory: &Signatory,
notification_function: &Option<Box<dyn Fn() + Send + Sync>>,
) -> Result<(RusticaClient<tonic::transport::Channel>, Challenge), RefreshError> {
let ssh_pubkey = match signatory {
Signatory::Yubikey(signer) => {
Expand Down Expand Up @@ -111,6 +112,12 @@ pub async fn complete_rustica_challenge(
return Err(RefreshError::ServerChallengeNotForClientKey);
}

// We need to sign the challenge so let's notify the user they
// will need to interact with their device if (if a device is being used)
if let Some(f) = notification_function {
f();
}

let resigned_certificate = match signatory {
Signatory::Yubikey(signer) => {
let signature = signer
Expand Down

0 comments on commit 22a07dd

Please sign in to comment.