Skip to content

Commit 59648f8

Browse files
authored
Merge pull request #45 from wiktor-k/jcspencer/draft-14
Add SSH_AGENT_EXTENSION_RESPONSE message type (RFC Draft 14)
2 parents aaee1b8 + 4674183 commit 59648f8

File tree

7 files changed

+698
-439
lines changed

7 files changed

+698
-439
lines changed

examples/key_storage.rs

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use sha1::Sha1;
1111
use ssh_agent_lib::agent::NamedPipeListener as Listener;
1212
use ssh_agent_lib::agent::Session;
1313
use ssh_agent_lib::error::AgentError;
14-
use ssh_agent_lib::proto::extension::SessionBind;
14+
use ssh_agent_lib::proto::extension::{QueryResponse, RestrictDestination, SessionBind};
1515
use ssh_agent_lib::proto::{
1616
message, signature, AddIdentity, AddIdentityConstrained, AddSmartcardKeyConstrained,
1717
Credential, Extension, KeyConstraint, RemoveIdentity, SignRequest, SmartcardKey,
@@ -151,12 +151,13 @@ impl Session for KeyStorage {
151151
} = identity;
152152
info!("Would use these constraints: {constraints:#?}");
153153
for constraint in constraints {
154-
if let KeyConstraint::Extension(name, mut details) = constraint {
155-
if name == "restrict-destination-v00@openssh.com" {
156-
if let Ok(destination_constraint) = details.parse::<SessionBind>() {
157-
info!("Destination constraint: {destination_constraint:?}");
158-
}
154+
if let KeyConstraint::Extension(mut extension) = constraint {
155+
if let Some(destination) =
156+
extension.parse_key_constraint::<RestrictDestination>()?
157+
{
158+
info!("Destination constraint: {destination:?}");
159159
}
160+
160161
if let Credential::Key { privkey, comment } = identity.credential.clone() {
161162
let privkey = PrivateKey::try_from(privkey).map_err(AgentError::other)?;
162163
self.identity_add(Identity {
@@ -199,13 +200,28 @@ impl Session for KeyStorage {
199200
Ok(())
200201
}
201202

202-
async fn extension(&mut self, mut extension: Extension) -> Result<(), AgentError> {
203+
async fn extension(
204+
&mut self,
205+
mut extension: Extension,
206+
) -> Result<Option<Extension>, AgentError> {
203207
info!("Extension: {extension:?}");
204-
if extension.name == "session-bind@openssh.com" {
205-
let bind = extension.details.parse::<SessionBind>()?;
206-
info!("Bind: {bind:?}");
208+
209+
match extension.name.as_str() {
210+
"query" => {
211+
let response = Extension::new_message(QueryResponse {
212+
extensions: vec!["query".into(), "session-bind@openssh.com".into()],
213+
})?;
214+
Ok(Some(response))
215+
}
216+
"session-bind@openssh.com" => match extension.parse_message::<SessionBind>()? {
217+
Some(bind) => {
218+
info!("Bind: {bind:?}");
219+
Ok(None)
220+
}
221+
None => Err(AgentError::Failure),
222+
},
223+
_ => Err(AgentError::Failure),
207224
}
208-
Ok(())
209225
}
210226
}
211227

src/agent.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ pub trait Session: 'static + Sync + Send + Sized {
176176
}
177177

178178
/// Invoke a custom, vendor-specific extension on the agent.
179-
async fn extension(&mut self, _extension: Extension) -> Result<(), AgentError> {
179+
async fn extension(&mut self, _extension: Extension) -> Result<Option<Extension>, AgentError> {
180180
Err(AgentError::from(ProtoError::UnsupportedCommand {
181181
command: 27,
182182
}))
@@ -206,7 +206,12 @@ pub trait Session: 'static + Sync + Send + Sized {
206206
Request::AddSmartcardKeyConstrained(key) => {
207207
self.add_smartcard_key_constrained(key).await?
208208
}
209-
Request::Extension(extension) => self.extension(extension).await?,
209+
Request::Extension(extension) => {
210+
return match self.extension(extension).await? {
211+
Some(response) => Ok(Response::ExtensionResponse(response)),
212+
None => Ok(Response::Success),
213+
}
214+
}
210215
}
211216
Ok(Response::Success)
212217
}
@@ -224,6 +229,10 @@ pub trait Session: 'static + Sync + Send + Sized {
224229
log::debug!("Request: {incoming_message:?}");
225230
let response = match self.handle(incoming_message).await {
226231
Ok(message) => message,
232+
Err(AgentError::ExtensionFailure) => {
233+
log::error!("Extension failure handling message");
234+
Response::ExtensionFailure
235+
}
227236
Err(e) => {
228237
log::error!("Error handling message: {:?}", e);
229238
Response::Failure

src/error.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ pub enum AgentError {
2020
/// Other unspecified error.
2121
#[error("Other error: {0:#}")]
2222
Other(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
23+
24+
/// Generic agent extension failure
25+
#[error("Generic agent extension failure")]
26+
ExtensionFailure,
27+
28+
/// Generic agent failure
29+
#[error("Generic agent failure")]
30+
Failure,
2331
}
2432

2533
impl AgentError {

0 commit comments

Comments
 (0)