1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// This file is part of the rusftp project
//
// Copyright (C) ANEO, 2024-2024. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License")
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::BTreeMap;
use bytes::Bytes;
use serde::{Deserialize, Serialize};
/// Version reply from the server.
///
/// internal: `SSH_FXP_VERSION`
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Version {
/// Version of the protocol used for the rest of the communication
pub version: u32,
/// List of extensions supported by the server
///
/// Implementations MUST silently ignore any extensions whose name they do not recognize.
#[serde(rename = "extensions_implicit_length")]
pub extensions: BTreeMap<Bytes, Bytes>,
}
#[cfg(test)]
mod test {
use crate::{
message::test_utils::{encode_decode, fail_decode},
wire::Error,
};
use super::Version;
use bytes::Bytes;
const VERSION_VALID: &[u8] = b"\xfe\xdc\xba\x98\0\0\0\x03key\0\0\0\x05value";
#[test]
fn encode_success() {
for (version, map, encoded) in [
(0u32, &[] as &[(&[u8], &[u8])], b"\0\0\0\0" as &[u8]),
(0xfedcba98, &[], b"\xfe\xdc\xba\x98"),
(0xfedcba98, &[(b"key", b"value")], VERSION_VALID),
(
0xfedcba98,
&[(b"key0", b"value0"), (b"key1", b"value1")],
b"\xfe\xdc\xba\x98\0\0\0\x04key0\0\0\0\x06value0\0\0\0\x04key1\0\0\0\x06value1",
),
] {
encode_decode(
Version {
version,
extensions: map
.iter()
.map(|(k, v)| (Bytes::from_static(k), Bytes::from_static(v)))
.collect(),
},
encoded,
);
}
}
#[test]
fn decode_failure() {
for i in 5..VERSION_VALID.len() {
assert_eq!(
fail_decode::<Version>(&VERSION_VALID[..i]),
Error::NotEnoughData
);
}
}
}