Skip to content

Commit

Permalink
Migrate back to using AgentError in Session methods
Browse files Browse the repository at this point in the history
Signed-off-by: Wiktor Kwapisiewicz <[email protected]>
  • Loading branch information
wiktor-k committed Apr 18, 2024
1 parent 36d431d commit 05514c0
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 83 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ On Unix it uses `ssh-agent.sock` Unix domain socket while on Windows it uses a n
use tokio::net::UnixListener as Listener;
#[cfg(windows)]
use ssh_agent_lib::agent::NamedPipeListener as Listener;
use ssh_agent_lib::error::AgentError;
use ssh_agent_lib::agent::{Session, Agent};
use ssh_agent_lib::proto::{Identity, SignRequest};
use ssh_key::{Algorithm, Signature};
Expand All @@ -27,17 +27,17 @@ struct MyAgent;
#[ssh_agent_lib::async_trait]
impl Session for MyAgent {
async fn request_identities(&mut self) -> Result<Vec<Identity>, Box<dyn std::error::Error>> {
async fn request_identities(&mut self) -> Result<Vec<Identity>, AgentError> {
Ok(vec![ /* public keys that this agent knows of */ ])
}
async fn sign(&mut self, request: SignRequest) -> Result<Signature, Box<dyn std::error::Error>> {
async fn sign(&mut self, request: SignRequest) -> Result<Signature, AgentError> {
// get the signature by signing `request.data`
let signature = vec![];
Ok(Signature::new(
Algorithm::new("algorithm")?,
Algorithm::new("algorithm").map_err(AgentError::other)?,
signature,
)?)
).map_err(AgentError::other)?)
}
}
Expand Down
61 changes: 23 additions & 38 deletions examples/key_storage.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use std::error::Error;
use std::sync::{Arc, Mutex};

use async_trait::async_trait;
Expand All @@ -11,6 +10,7 @@ use sha1::Sha1;
#[cfg(windows)]
use ssh_agent_lib::agent::NamedPipeListener as Listener;
use ssh_agent_lib::agent::Session;
use ssh_agent_lib::error::AgentError;
use ssh_agent_lib::proto::extension::SessionBind;
use ssh_agent_lib::proto::{
message, signature, AddIdentity, AddIdentityConstrained, AddSmartcardKeyConstrained,
Expand Down Expand Up @@ -60,24 +60,21 @@ impl KeyStorage {
}
}

fn identity_remove(&self, pubkey: &PublicKey) -> Result<(), Box<dyn Error>> {
fn identity_remove(&self, pubkey: &PublicKey) -> Result<(), AgentError> {
let mut identities = self.identities.lock().unwrap();

if let Some(index) = Self::identity_index_from_pubkey(&identities, pubkey) {
identities.remove(index);
Ok(())
} else {
Err(From::from("Failed to remove identity: identity not found"))
Err(std::io::Error::other("Failed to remove identity: identity not found").into())
}
}
}

#[crate::async_trait]
impl Session for KeyStorage {
async fn sign(
&mut self,
sign_request: SignRequest,
) -> Result<Signature, Box<dyn std::error::Error>> {
async fn sign(&mut self, sign_request: SignRequest) -> Result<Signature, AgentError> {
let pubkey: PublicKey = sign_request.pubkey.clone().into();

if let Some(identity) = self.identity_from_pubkey(&pubkey) {
Expand All @@ -90,7 +87,8 @@ impl Session for KeyStorage {
BigUint::from_bytes_be(key.public.e.as_bytes()),
BigUint::from_bytes_be(key.private.d.as_bytes()),
vec![],
)?;
)
.map_err(AgentError::other)?;
let mut rng = rand::thread_rng();
let data = &sign_request.data;

Expand All @@ -105,20 +103,19 @@ impl Session for KeyStorage {
SigningKey::<Sha1>::new(private_key).sign_with_rng(&mut rng, data)
};
Ok(Signature::new(
Algorithm::new(algorithm)?,
Algorithm::new(algorithm).map_err(AgentError::other)?,
signature.to_bytes().to_vec(),
)?)
)
.map_err(AgentError::other)?)
}
_ => Err(From::from("Signature for key type not implemented")),
_ => Err(std::io::Error::other("Signature for key type not implemented").into()),
}
} else {
Err(From::from("Failed to create signature: identity not found"))
Err(std::io::Error::other("Failed to create signature: identity not found").into())
}
}

async fn request_identities(
&mut self,
) -> Result<Vec<message::Identity>, Box<dyn std::error::Error>> {
async fn request_identities(&mut self) -> Result<Vec<message::Identity>, AgentError> {
let mut identities = vec![];
for identity in self.identities.lock().unwrap().iter() {
identities.push(message::Identity {
Expand All @@ -129,12 +126,9 @@ impl Session for KeyStorage {
Ok(identities)
}

async fn add_identity(
&mut self,
identity: AddIdentity,
) -> Result<(), Box<dyn std::error::Error>> {
async fn add_identity(&mut self, identity: AddIdentity) -> Result<(), AgentError> {
if let Credential::Key { privkey, comment } = identity.credential {
let privkey = PrivateKey::try_from(privkey)?;
let privkey = PrivateKey::try_from(privkey).map_err(AgentError::other)?;
self.identity_add(Identity {
pubkey: PublicKey::from(&privkey),
privkey,
Expand All @@ -150,7 +144,7 @@ impl Session for KeyStorage {
async fn add_identity_constrained(
&mut self,
identity: AddIdentityConstrained,
) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<(), AgentError> {
let AddIdentityConstrained {
identity,
constraints,
Expand All @@ -164,7 +158,7 @@ impl Session for KeyStorage {
}
}
if let Credential::Key { privkey, comment } = identity.credential.clone() {
let privkey = PrivateKey::try_from(privkey)?;
let privkey = PrivateKey::try_from(privkey).map_err(AgentError::other)?;
self.identity_add(Identity {
pubkey: PublicKey::from(&privkey),
privkey,
Expand All @@ -176,19 +170,13 @@ impl Session for KeyStorage {
self.add_identity(identity).await
}

async fn remove_identity(
&mut self,
identity: RemoveIdentity,
) -> Result<(), Box<dyn std::error::Error>> {
async fn remove_identity(&mut self, identity: RemoveIdentity) -> Result<(), AgentError> {
let pubkey: PublicKey = identity.pubkey.into();
self.identity_remove(&pubkey)?;
Ok(())
}

async fn add_smartcard_key(
&mut self,
key: SmartcardKey,
) -> Result<(), Box<dyn std::error::Error>> {
async fn add_smartcard_key(&mut self, key: SmartcardKey) -> Result<(), AgentError> {
info!("Adding smartcard key: {key:?}");

Ok(())
Expand All @@ -197,24 +185,21 @@ impl Session for KeyStorage {
async fn add_smartcard_key_constrained(
&mut self,
key: AddSmartcardKeyConstrained,
) -> Result<(), Box<dyn std::error::Error>> {
) -> Result<(), AgentError> {
info!("Adding smartcard key with constraints: {key:?}");
Ok(())
}
async fn lock(&mut self, pwd: String) -> Result<(), Box<dyn std::error::Error>> {
async fn lock(&mut self, pwd: String) -> Result<(), AgentError> {
info!("Locked with password: {pwd:?}");
Ok(())
}

async fn unlock(&mut self, pwd: String) -> Result<(), Box<dyn std::error::Error>> {
async fn unlock(&mut self, pwd: String) -> Result<(), AgentError> {
info!("Unlocked with password: {pwd:?}");
Ok(())
}

async fn extension(
&mut self,
mut extension: Extension,
) -> Result<(), Box<dyn std::error::Error>> {
async fn extension(&mut self, mut extension: Extension) -> Result<(), AgentError> {
info!("Extension: {extension:?}");
if extension.name == "[email protected]" {
let bind = extension.details.parse::<SessionBind>()?;
Expand Down Expand Up @@ -245,7 +230,7 @@ impl Agent for KeyStorageAgent {
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
async fn main() -> Result<(), AgentError> {
env_logger::init();

#[cfg(not(windows))]
Expand Down
89 changes: 49 additions & 40 deletions src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,76 +81,85 @@ impl ListeningSocket for NamedPipeListener {

#[async_trait]
pub trait Session: 'static + Sync + Send + Sized {
async fn request_identities(&mut self) -> Result<Vec<Identity>, Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 11 }))
async fn request_identities(&mut self) -> Result<Vec<Identity>, AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 11,
}))
}

async fn sign(
&mut self,
_request: SignRequest,
) -> Result<Signature, Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 13 }))
async fn sign(&mut self, _request: SignRequest) -> Result<Signature, AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 13,
}))
}

async fn add_identity(
&mut self,
_identity: AddIdentity,
) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 17 }))
async fn add_identity(&mut self, _identity: AddIdentity) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 17,
}))
}

async fn add_identity_constrained(
&mut self,
_identity: AddIdentityConstrained,
) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 25 }))
) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 25,
}))
}

async fn remove_identity(
&mut self,
_identity: RemoveIdentity,
) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 18 }))
async fn remove_identity(&mut self, _identity: RemoveIdentity) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 18,
}))
}

async fn remove_all_identities(&mut self) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 19 }))
async fn remove_all_identities(&mut self) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 19,
}))
}

async fn add_smartcard_key(
&mut self,
_key: SmartcardKey,
) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 20 }))
async fn add_smartcard_key(&mut self, _key: SmartcardKey) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 20,
}))
}

async fn add_smartcard_key_constrained(
&mut self,
_key: AddSmartcardKeyConstrained,
) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 26 }))
) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 26,
}))
}

async fn remove_smartcard_key(
&mut self,
_key: SmartcardKey,
) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 21 }))
async fn remove_smartcard_key(&mut self, _key: SmartcardKey) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 21,
}))
}

async fn lock(&mut self, _key: String) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 22 }))
async fn lock(&mut self, _key: String) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 22,
}))
}

async fn unlock(&mut self, _key: String) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 23 }))
async fn unlock(&mut self, _key: String) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 23,
}))
}

async fn extension(&mut self, _extension: Extension) -> Result<(), Box<dyn std::error::Error>> {
Err(Box::new(ProtoError::UnsupportedCommand { command: 27 }))
async fn extension(&mut self, _extension: Extension) -> Result<(), AgentError> {
Err(AgentError::from(ProtoError::UnsupportedCommand {
command: 27,
}))
}

async fn handle(&mut self, message: Request) -> Result<Response, Box<dyn std::error::Error>> {
async fn handle(&mut self, message: Request) -> Result<Response, AgentError> {
match message {
Request::RequestIdentities => {
return Ok(Response::IdentitiesAnswer(self.request_identities().await?))
Expand Down
8 changes: 8 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,12 @@ pub enum AgentError {
Proto(#[from] ProtoError),
#[error("Agent: I/O error: {0}")]
IO(#[from] io::Error),
#[error("Other error: {0:#}")]
Other(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
}

impl AgentError {
pub fn other(error: impl std::error::Error + Send + Sync + 'static) -> Self {
Self::Other(Box::new(error))
}
}

0 comments on commit 05514c0

Please sign in to comment.