kovra_agent/error.rs
1//! `AgentError` — the agent face's error type (KOV-13).
2//!
3//! It is a *control-flow* error type: it never carries key bytes, a challenge,
4//! or any secret material (I7/I12). A protocol-level fault (malformed frame,
5//! unknown opcode, refused signature) is mapped by the daemon to an
6//! `SSH_AGENT_FAILURE` reply, not surfaced to the peer as text.
7
8use thiserror::Error;
9
10/// Errors raised while serving the ssh-agent protocol.
11#[derive(Debug, Error)]
12pub enum AgentError {
13 /// `$SSH_AUTH_SOCK` was already set — refuse-and-guide (we never hijack an
14 /// existing agent, decision Q5).
15 #[error(
16 "$SSH_AUTH_SOCK is already set ({0}) — another ssh-agent is active.\n\
17 Refusing to hijack it. To use kovra as your agent, start it in a shell \
18 with no agent:\n env -u SSH_AUTH_SOCK kovra ssh-agent\n\
19 then export the printed SSH_AUTH_SOCK in the shells that should use it."
20 )]
21 AuthSockAlreadySet(String),
22
23 /// The socket path could not be bound / cleaned up.
24 #[error("ssh-agent socket error: {0}")]
25 Socket(String),
26
27 /// A core operation failed (no key bytes in the message).
28 #[error("core error: {0}")]
29 Core(#[from] kovra_core::CoreError),
30
31 /// A wire-protocol fault (bounds/length/opcode). Mapped to `FAILURE` on the
32 /// wire — never echoed to the peer. Carries only a short, value-free reason.
33 #[error("protocol error: {0}")]
34 Protocol(String),
35
36 /// Generic I/O on the socket transport.
37 #[error("io error: {0}")]
38 Io(String),
39}
40
41impl From<std::io::Error> for AgentError {
42 fn from(e: std::io::Error) -> Self {
43 AgentError::Io(e.to_string())
44 }
45}