#[cfg(unix)]
use auths_core::agent::{AgentStatus, add_identity, agent_sign, check_agent_status};
#[cfg(unix)]
use auths_core::crypto::ssh::{construct_sshsig_pem, construct_sshsig_signed_data};
use auths_sdk::ports::agent::{AgentSigningError, AgentSigningPort};
#[cfg(unix)]
use crate::commands::agent::{ensure_agent_running, get_default_socket_path};
#[cfg(unix)]
pub struct CliAgentAdapter;
#[cfg(unix)]
impl AgentSigningPort for CliAgentAdapter {
fn try_sign(
&self,
namespace: &str,
pubkey: &[u8],
data: &[u8],
) -> Result<String, AgentSigningError> {
if pubkey.len() != 32 {
return Err(AgentSigningError::Unavailable(
"no public key available for agent signing".into(),
));
}
let socket_path =
get_default_socket_path().map_err(|e| AgentSigningError::Unavailable(e.to_string()))?;
match check_agent_status(&socket_path) {
AgentStatus::Running { key_count } if key_count > 0 => {}
AgentStatus::Running { .. } => {
return Err(AgentSigningError::Unavailable(
"agent running but no keys loaded".into(),
));
}
AgentStatus::ConnectionFailed => {
return Err(AgentSigningError::ConnectionFailed(
"agent socket unreachable".into(),
));
}
AgentStatus::NotRunning => {
return Err(AgentSigningError::Unavailable("agent not running".into()));
}
}
let sig_data = construct_sshsig_signed_data(data, namespace)
.map_err(|e| AgentSigningError::SigningFailed(e.to_string()))?;
let raw_sig = agent_sign(&socket_path, pubkey, &sig_data)
.map_err(|e| AgentSigningError::SigningFailed(e.to_string()))?;
construct_sshsig_pem(pubkey, &raw_sig, namespace)
.map_err(|e| AgentSigningError::SigningFailed(e.to_string()))
}
fn ensure_running(&self) -> Result<(), AgentSigningError> {
ensure_agent_running(true)
.map(|_| ())
.map_err(|e| AgentSigningError::StartupFailed(e.to_string()))
}
fn add_identity(&self, _namespace: &str, pkcs8_der: &[u8]) -> Result<(), AgentSigningError> {
let socket_path = get_default_socket_path()
.map_err(|e| AgentSigningError::ConnectionFailed(e.to_string()))?;
add_identity(&socket_path, pkcs8_der)
.map(|_| ())
.map_err(|e| AgentSigningError::SigningFailed(e.to_string()))
}
}