ssh_agent_lib/proto/message/
request.rs1use ssh_encoding::{CheckedSum, Decode, Encode, Reader, Writer};
4
5use super::{
6 AddIdentity, AddIdentityConstrained, AddSmartcardKeyConstrained, Extension, RemoveIdentity,
7 SignRequest, SmartcardKey,
8};
9use crate::proto::{Error, Result};
10
11#[derive(Clone, PartialEq, Debug)]
17pub enum Request {
18 RequestIdentities,
21
22 SignRequest(SignRequest),
25
26 AddIdentity(AddIdentity),
28
29 RemoveIdentity(RemoveIdentity),
31
32 RemoveAllIdentities,
34
35 AddSmartcardKey(SmartcardKey),
38
39 RemoveSmartcardKey(SmartcardKey),
41
42 Lock(String),
44
45 Unlock(String),
47
48 AddIdConstrained(AddIdentityConstrained),
51
52 AddSmartcardKeyConstrained(AddSmartcardKeyConstrained),
56
57 Extension(Extension),
60}
61
62impl Request {
63 pub fn message_id(&self) -> u8 {
67 match self {
68 Self::RequestIdentities => 11,
69 Self::SignRequest(_) => 13,
70 Self::AddIdentity(_) => 17,
71 Self::RemoveIdentity(_) => 18,
72 Self::RemoveAllIdentities => 19,
73 Self::AddSmartcardKey(_) => 20,
74 Self::RemoveSmartcardKey(_) => 21,
75 Self::Lock(_) => 22,
76 Self::Unlock(_) => 23,
77 Self::AddIdConstrained(_) => 25,
78 Self::AddSmartcardKeyConstrained(_) => 26,
79 Self::Extension(_) => 27,
80 }
81 }
82}
83
84impl Decode for Request {
85 type Error = Error;
86
87 fn decode(reader: &mut impl Reader) -> Result<Self> {
88 let message_type = u8::decode(reader)?;
89
90 match message_type {
91 11 => Ok(Self::RequestIdentities),
92 13 => SignRequest::decode(reader).map(Self::SignRequest),
93 17 => AddIdentity::decode(reader).map(Self::AddIdentity),
94 18 => RemoveIdentity::decode(reader).map(Self::RemoveIdentity),
95 19 => Ok(Self::RemoveAllIdentities),
96 20 => SmartcardKey::decode(reader).map(Self::AddSmartcardKey),
97 21 => SmartcardKey::decode(reader).map(Self::RemoveSmartcardKey),
98 22 => Ok(String::decode(reader).map(Self::Lock)?),
99 23 => Ok(String::decode(reader).map(Self::Unlock)?),
100 25 => AddIdentityConstrained::decode(reader).map(Self::AddIdConstrained),
101 26 => AddSmartcardKeyConstrained::decode(reader).map(Self::AddSmartcardKeyConstrained),
102 27 => Extension::decode(reader).map(Self::Extension),
103 command => Err(Error::UnsupportedCommand { command }),
104 }
105 }
106}
107
108impl Encode for Request {
109 fn encoded_len(&self) -> ssh_encoding::Result<usize> {
110 let message_id_len = 1;
111 let payload_len = match self {
112 Self::RequestIdentities => 0,
113 Self::SignRequest(request) => request.encoded_len()?,
114 Self::AddIdentity(identity) => identity.encoded_len()?,
115 Self::RemoveIdentity(identity) => identity.encoded_len()?,
116 Self::RemoveAllIdentities => 0,
117 Self::AddSmartcardKey(key) => key.encoded_len()?,
118 Self::RemoveSmartcardKey(key) => key.encoded_len()?,
119 Self::Lock(passphrase) => passphrase.encoded_len()?,
120 Self::Unlock(passphrase) => passphrase.encoded_len()?,
121 Self::AddIdConstrained(key) => key.encoded_len()?,
122 Self::AddSmartcardKeyConstrained(key) => key.encoded_len()?,
123 Self::Extension(extension) => extension.encoded_len()?,
124 };
125
126 [message_id_len, payload_len].checked_sum()
127 }
128
129 fn encode(&self, writer: &mut impl Writer) -> ssh_encoding::Result<()> {
130 let message_id: u8 = self.message_id();
131 message_id.encode(writer)?;
132
133 match self {
134 Self::RequestIdentities => {}
135 Self::SignRequest(request) => request.encode(writer)?,
136 Self::AddIdentity(identity) => identity.encode(writer)?,
137 Self::RemoveIdentity(identity) => identity.encode(writer)?,
138 Self::RemoveAllIdentities => {}
139 Self::AddSmartcardKey(key) => key.encode(writer)?,
140 Self::RemoveSmartcardKey(key) => key.encode(writer)?,
141 Self::Lock(passphrase) => passphrase.encode(writer)?,
142 Self::Unlock(passphrase) => passphrase.encode(writer)?,
143 Self::AddIdConstrained(identity) => identity.encode(writer)?,
144 Self::AddSmartcardKeyConstrained(key) => key.encode(writer)?,
145 Self::Extension(extension) => extension.encode(writer)?,
146 };
147
148 Ok(())
149 }
150}