ssh_packet/trans.rs
1//! Messages involved in the SSH's **transport** (`SSH-TRANS`) part of the protocol,
2//! as defined in the [RFC 4253](https://datatracker.ietf.org/doc/html/rfc4253)
3//! and [RFC 5656](https://datatracker.ietf.org/doc/html/rfc5656).
4
5use binrw::binrw;
6
7use super::{Packet, arch};
8
9impl Packet for Disconnect<'_> {}
10impl Packet for Ignore<'_> {}
11impl Packet for Unimplemented {}
12impl Packet for Debug<'_> {}
13impl Packet for ServiceRequest<'_> {}
14impl Packet for ServiceAccept<'_> {}
15impl Packet for KexInit<'_> {}
16impl Packet for NewKeys {}
17impl Packet for KexdhInit<'_> {}
18impl Packet for KexdhReply<'_> {}
19impl Packet for KexEcdhInit<'_> {}
20impl Packet for KexEcdhReply<'_> {}
21
22/// The `SSH_MSG_DISCONNECT` message.
23///
24/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-11.1>.
25#[binrw]
26#[derive(Debug, Clone)]
27#[brw(big, magic = 1_u8)]
28pub struct Disconnect<'b> {
29 /// Reason for disconnection.
30 pub reason: DisconnectReason,
31
32 /// Description of the reason for disconnection.
33 pub description: arch::Utf8<'b>,
34
35 /// Language tag.
36 pub language: arch::Ascii<'b>,
37}
38
39/// The `reason` for disconnect in the `SSH_MSG_DISCONNECT` message.
40#[binrw]
41#[derive(Debug, Clone)]
42#[brw(big)]
43pub enum DisconnectReason {
44 /// `SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT`.
45 #[brw(magic = 1_u32)]
46 HostNotAllowedToConnect,
47
48 /// `SSH_DISCONNECT_PROTOCOL_ERROR`.
49 #[brw(magic = 2_u32)]
50 ProtocolError,
51
52 /// `SSH_DISCONNECT_KEY_EXCHANGE_FAILED`.
53 #[brw(magic = 3_u32)]
54 KeyExchangeFailed,
55
56 /// `SSH_DISCONNECT_RESERVED`.
57 #[brw(magic = 4_u32)]
58 Reserved,
59
60 /// `SSH_DISCONNECT_MAC_ERROR`.
61 #[brw(magic = 5_u32)]
62 MacError,
63
64 /// `SSH_DISCONNECT_COMPRESSION_ERROR`.
65 #[brw(magic = 6_u32)]
66 CompressionError,
67
68 /// `SSH_DISCONNECT_SERVICE_NOT_AVAILABLE`.
69 #[brw(magic = 7_u32)]
70 ServiceNotAvailable,
71
72 /// `SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED`.
73 #[brw(magic = 8_u32)]
74 ProtocolVersionNotSupported,
75
76 /// `SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE`.
77 #[brw(magic = 9_u32)]
78 HostKeyNotVerifiable,
79
80 /// `SSH_DISCONNECT_CONNECTION_LOST`.
81 #[brw(magic = 10_u32)]
82 ConnectionLost,
83
84 /// `SSH_DISCONNECT_BY_APPLICATION`.
85 #[brw(magic = 11_u32)]
86 ByApplication,
87
88 /// `SSH_DISCONNECT_TOO_MANY_CONNECTIONS`.
89 #[brw(magic = 12_u32)]
90 TooManyConnections,
91
92 /// `SSH_DISCONNECT_AUTH_CANCELLED_BY_USER`.
93 #[brw(magic = 13_u32)]
94 AuthCancelledByUser,
95
96 /// `SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE`.
97 #[brw(magic = 14_u32)]
98 NoMoreAuthMethodsAvailable,
99
100 /// `SSH_DISCONNECT_ILLEGAL_USER_NAME`.
101 #[brw(magic = 15_u32)]
102 IllegalUserName,
103
104 /// Any other disconnect reason, may be non-standard.
105 ///
106 /// The 'reason' values in the range of `0xFE000000`
107 /// through `0xFFFFFFFF` are reserved for PRIVATE USE.
108 Other(u32),
109}
110
111/// The `SSH_MSG_IGNORE` message.
112///
113/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-11.2>.
114#[binrw]
115#[derive(Debug, Default, Clone)]
116#[brw(big, magic = 2_u8)]
117pub struct Ignore<'b> {
118 /// A random blob of data to ignore.
119 pub data: arch::Bytes<'b>,
120}
121
122/// The `SSH_MSG_UNIMPLEMENTED` message.
123///
124/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-11.4>.
125#[binrw]
126#[derive(Debug, Clone)]
127#[brw(big, magic = 3_u8)]
128pub struct Unimplemented {
129 /// Packet sequence number of rejected message.
130 pub seq: u32,
131}
132
133/// The `SSH_MSG_DEBUG` message.
134///
135/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-11.3>.
136#[binrw]
137#[derive(Debug, Default, Clone)]
138#[brw(big, magic = 4_u8)]
139pub struct Debug<'b> {
140 /// Whether the debug data should be forcefully displayed.
141 pub always_display: arch::Bool,
142
143 /// The debug message.
144 pub message: arch::Utf8<'b>,
145
146 /// Language tag.
147 pub language: arch::Ascii<'b>,
148}
149
150/// The `SSH_MSG_SERVICE_REQUEST` message.
151///
152/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-10>.
153#[binrw]
154#[derive(Debug, Clone)]
155#[brw(big, magic = 5_u8)]
156pub struct ServiceRequest<'b> {
157 /// The service name to request.
158 pub service_name: arch::Ascii<'b>,
159}
160
161/// The `SSH_MSG_SERVICE_ACCEPT` message.
162///
163/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-10>.
164#[binrw]
165#[derive(Debug, Clone)]
166#[brw(big, magic = 6_u8)]
167pub struct ServiceAccept<'b> {
168 /// Service name accepted to be requested.
169 pub service_name: arch::Ascii<'b>,
170}
171
172/// The `SSH_MSG_KEXINIT` message.
173///
174/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-7.1>.
175#[binrw]
176#[derive(Debug, Clone)]
177#[brw(big, magic = 20_u8)]
178pub struct KexInit<'b> {
179 /// The kex-init cookie.
180 pub cookie: [u8; 16],
181
182 /// Kex algorithms.
183 pub kex_algorithms: arch::NameList<'b>,
184
185 /// Server host-key algorithms.
186 pub server_host_key_algorithms: arch::NameList<'b>,
187
188 /// Client -> server encryption algorithms.
189 pub encryption_algorithms_client_to_server: arch::NameList<'b>,
190
191 /// Server -> client encryption algorithms.
192 pub encryption_algorithms_server_to_client: arch::NameList<'b>,
193
194 /// Client -> server MAC algorithms.
195 pub mac_algorithms_client_to_server: arch::NameList<'b>,
196
197 /// Server -> client MAC algorithms.
198 pub mac_algorithms_server_to_client: arch::NameList<'b>,
199
200 /// Client -> server compression algorithms.
201 pub compression_algorithms_client_to_server: arch::NameList<'b>,
202
203 /// Server -> client compression algorithms.
204 pub compression_algorithms_server_to_client: arch::NameList<'b>,
205
206 /// Client -> server languages.
207 pub languages_client_to_server: arch::NameList<'b>,
208
209 /// Server -> client languages.
210 pub languages_server_to_client: arch::NameList<'b>,
211
212 /// Whether the first kex packet follows.
213 pub first_kex_packet_follows: arch::Bool,
214
215 #[bw(calc = 0)]
216 _reserved: u32,
217}
218
219/// The `SSH_MSG_NEWKEYS` message.
220///
221/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-7.3>.
222#[binrw]
223#[derive(Debug, Default, Clone)]
224#[brw(big, magic = 21_u8)]
225pub struct NewKeys;
226
227/// The `SSH_MSG_KEXDH_INIT` message.
228///
229/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-8>.
230#[binrw]
231#[derive(Debug, Clone)]
232#[brw(big, magic = 30_u8)]
233pub struct KexdhInit<'b> {
234 /// Exchange value sent by the client.
235 pub e: arch::MpInt<'b>,
236}
237
238/// The `SSH_MSG_KEXDH_REPLY` message.
239///
240/// see <https://datatracker.ietf.org/doc/html/rfc4253#section-8>.
241#[binrw]
242#[derive(Debug, Clone)]
243#[brw(big, magic = 31_u8)]
244pub struct KexdhReply<'b> {
245 /// Server's public host key.
246 pub k_s: arch::Bytes<'b>,
247
248 /// Exchange value sent by the server.
249 pub f: arch::MpInt<'b>,
250
251 /// Signature of the exchange hash.
252 pub signature: arch::Bytes<'b>,
253}
254
255/// The `SSH_MSG_KEX_ECDH_INIT` message.
256///
257/// see <https://datatracker.ietf.org/doc/html/rfc5656#section-4>.
258#[binrw]
259#[derive(Debug, Clone)]
260#[brw(big, magic = 30_u8)]
261pub struct KexEcdhInit<'b> {
262 /// Client's ephemeral public key octet string.
263 pub q_c: arch::Bytes<'b>,
264}
265
266/// The `SSH_MSG_KEX_ECDH_REPLY` message.
267///
268/// see <https://datatracker.ietf.org/doc/html/rfc5656#section-4>.
269#[binrw]
270#[derive(Debug, Clone)]
271#[brw(big, magic = 31_u8)]
272pub struct KexEcdhReply<'b> {
273 /// Server's public host key.
274 pub k_s: arch::Bytes<'b>,
275
276 /// Server's ephemeral public key octet string.
277 pub q_s: arch::Bytes<'b>,
278
279 /// Signature of the exchange hash.
280 pub signature: arch::Bytes<'b>,
281}