Skip to main content

iris_core/protocols/stream/ssh/
mod.rs

1//! SSH handshake parsing.
2
3mod handshake;
4pub mod parser;
5
6pub use self::handshake::*;
7use serde::Serialize;
8
9/// Parsed SSH handshake contents.
10#[derive(Debug, Default, Serialize)]
11pub struct Ssh {
12    /// Client protocol version exchange message.
13    pub client_version_exchange: Option<SshVersionExchange>,
14    /// Server protocol version exchange message.
15    pub server_version_exchange: Option<SshVersionExchange>,
16
17    /// Key Exchange message.
18    pub key_exchange: Option<SshKeyExchange>,
19
20    /// Client Diffie-Hellman Key Exchange message.
21    pub client_dh_key_exchange: Option<SshDhInit>,
22    /// Server Diffie-Hellman Key Exchange message.
23    pub server_dh_key_exchange: Option<SshDhResponse>,
24
25    /// Client New Keys message.
26    pub client_new_keys: Option<SshNewKeys>,
27    /// Server New Keys message.
28    pub server_new_keys: Option<SshNewKeys>,
29
30    #[serde(skip_serializing)]
31    pub(crate) last_body_offset: Option<usize>,
32}
33
34impl Ssh {
35    /// Returns the SSH protocol version used by the client (e.g. 2.0).
36    pub fn protocol_version_ctos(&self) -> &str {
37        match &self.client_version_exchange {
38            Some(client_version_exchange) => match &client_version_exchange.protoversion {
39                Some(protoversion) => protoversion.as_str(),
40                None => "",
41            },
42            None => "",
43        }
44    }
45
46    /// Returns the SSH software version used by the client.
47    pub fn software_version_ctos(&self) -> &str {
48        match &self.client_version_exchange {
49            Some(client_version_exchange) => match &client_version_exchange.softwareversion {
50                Some(softwareversion) => softwareversion.as_str(),
51                None => "",
52            },
53            None => "",
54        }
55    }
56
57    /// Returns comments, or `""` if there are no comments, in the protocol version exchange message sent from the client.
58    pub fn comments_ctos(&self) -> &str {
59        match &self.client_version_exchange {
60            Some(client_version_exchange) => match &client_version_exchange.comments {
61                Some(comments) => comments.as_str(),
62                None => "",
63            },
64            None => "",
65        }
66    }
67
68    /// Returns the SSH protocol version used by the server (e.g. 2.0).
69    pub fn protocol_version_stoc(&self) -> &str {
70        match &self.server_version_exchange {
71            Some(server_version_exchange) => match &server_version_exchange.protoversion {
72                Some(protoversion) => protoversion.as_str(),
73                None => "",
74            },
75            None => "",
76        }
77    }
78
79    /// Returns the SSH software version used by the server.
80    pub fn software_version_stoc(&self) -> &str {
81        match &self.server_version_exchange {
82            Some(server_version_exchange) => match &server_version_exchange.softwareversion {
83                Some(softwareversion) => softwareversion.as_str(),
84                None => "",
85            },
86            None => "",
87        }
88    }
89
90    /// Returns comments, or `""` if there are no comments, in the protocol version exchange message sent from the server.
91    pub fn comments_stoc(&self) -> &str {
92        match &self.server_version_exchange {
93            Some(server_version_exchange) => match &server_version_exchange.comments {
94                Some(comments) => comments.as_str(),
95                None => "",
96            },
97            None => "",
98        }
99    }
100
101    /// Returns the cookie used in SSH key exchange.
102    pub fn key_exchange_cookie_stoc(&self) -> Vec<u8> {
103        match &self.key_exchange {
104            Some(key_exchange) => key_exchange.cookie.to_vec(),
105            None => vec![],
106        }
107    }
108
109    /// Returns the key exchange algorithms used in SSH key exchange.
110    pub fn kex_algs_stoc(&self) -> Vec<String> {
111        match &self.key_exchange {
112            Some(key_exchange) => key_exchange
113                .kex_algs
114                .iter()
115                .map(|c| c.to_string())
116                .collect(),
117            None => vec![],
118        }
119    }
120
121    /// Returns the algorithms supported for the server host key.
122    pub fn server_host_key_algs_stoc(&self) -> Vec<String> {
123        match &self.key_exchange {
124            Some(key_exchange) => key_exchange
125                .server_host_key_algs
126                .iter()
127                .map(|c| c.to_string())
128                .collect(),
129            None => vec![],
130        }
131    }
132
133    /// Returns the symmetric encryption algorithms (ciphers) supported by the client.
134    pub fn encryption_algs_ctos(&self) -> Vec<String> {
135        match &self.key_exchange {
136            Some(key_exchange) => key_exchange
137                .encryption_algs_client_to_server
138                .iter()
139                .map(|c| c.to_string())
140                .collect(),
141            None => vec![],
142        }
143    }
144
145    /// Returns the symmetric encryption algorithms (ciphers) supported by the server.
146    pub fn encryption_algs_stoc(&self) -> Vec<String> {
147        match &self.key_exchange {
148            Some(key_exchange) => key_exchange
149                .encryption_algs_server_to_client
150                .iter()
151                .map(|c| c.to_string())
152                .collect(),
153            None => vec![],
154        }
155    }
156
157    /// Returns the MAC algorithms supported by the client.
158    pub fn mac_algs_ctos(&self) -> Vec<String> {
159        match &self.key_exchange {
160            Some(key_exchange) => key_exchange
161                .mac_algs_client_to_server
162                .iter()
163                .map(|c| c.to_string())
164                .collect(),
165            None => vec![],
166        }
167    }
168
169    /// Returns the MAC algorithms supported by the server.
170    pub fn mac_algs_stoc(&self) -> Vec<String> {
171        match &self.key_exchange {
172            Some(key_exchange) => key_exchange
173                .mac_algs_server_to_client
174                .iter()
175                .map(|c| c.to_string())
176                .collect(),
177            None => vec![],
178        }
179    }
180
181    /// Returns the compression algorithms supported by the client.
182    pub fn compression_algs_ctos(&self) -> Vec<String> {
183        match &self.key_exchange {
184            Some(key_exchange) => key_exchange
185                .compression_algs_client_to_server
186                .iter()
187                .map(|c| c.to_string())
188                .collect(),
189            None => vec![],
190        }
191    }
192
193    /// Returns the compression algorithms supported by the server.
194    pub fn compression_algs_stoc(&self) -> Vec<String> {
195        match &self.key_exchange {
196            Some(key_exchange) => key_exchange
197                .compression_algs_server_to_client
198                .iter()
199                .map(|c| c.to_string())
200                .collect(),
201            None => vec![],
202        }
203    }
204
205    /// Returns the language tags (if any) supported by the client.
206    pub fn languages_ctos(&self) -> Vec<String> {
207        match &self.key_exchange {
208            Some(key_exchange) => key_exchange
209                .languages_client_to_server
210                .iter()
211                .map(|c| c.to_string())
212                .collect(),
213            None => vec![],
214        }
215    }
216
217    /// Returns the language tags (if any) supported by the server.
218    pub fn languages_stoc(&self) -> Vec<String> {
219        match &self.key_exchange {
220            Some(key_exchange) => key_exchange
221                .languages_server_to_client
222                .iter()
223                .map(|c| c.to_string())
224                .collect(),
225            None => vec![],
226        }
227    }
228}