Skip to main content

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}