remotefs_ssh/ssh/
key_method.rs

1/// [`KeyMethod`] method type for SSH key exchange.
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub enum MethodType {
4    Kex,
5    HostKey,
6    CryptClientServer,
7    CryptServerClient,
8    MacClientServer,
9    MacServerClient,
10    CompClientServer,
11    CompServerClient,
12    LangClientServer,
13    LangServerClient,
14    SignAlgo,
15}
16
17#[cfg(feature = "libssh2")]
18impl From<MethodType> for ssh2::MethodType {
19    fn from(t: MethodType) -> Self {
20        match t {
21            MethodType::Kex => ssh2::MethodType::Kex,
22            MethodType::HostKey => ssh2::MethodType::HostKey,
23            MethodType::CryptClientServer => ssh2::MethodType::CryptCs,
24            MethodType::CryptServerClient => ssh2::MethodType::CryptSc,
25            MethodType::MacClientServer => ssh2::MethodType::MacCs,
26            MethodType::MacServerClient => ssh2::MethodType::MacSc,
27            MethodType::CompClientServer => ssh2::MethodType::CompCs,
28            MethodType::CompServerClient => ssh2::MethodType::CompSc,
29            MethodType::LangClientServer => ssh2::MethodType::LangCs,
30            MethodType::LangServerClient => ssh2::MethodType::LangSc,
31            MethodType::SignAlgo => ssh2::MethodType::SignAlgo,
32        }
33    }
34}
35
36#[cfg(feature = "libssh2")]
37impl From<ssh2::MethodType> for MethodType {
38    fn from(t: ssh2::MethodType) -> Self {
39        match t {
40            ssh2::MethodType::Kex => MethodType::Kex,
41            ssh2::MethodType::HostKey => MethodType::HostKey,
42            ssh2::MethodType::CryptCs => MethodType::CryptClientServer,
43            ssh2::MethodType::CryptSc => MethodType::CryptServerClient,
44            ssh2::MethodType::MacCs => MethodType::MacClientServer,
45            ssh2::MethodType::MacSc => MethodType::MacServerClient,
46            ssh2::MethodType::CompCs => MethodType::CompClientServer,
47            ssh2::MethodType::CompSc => MethodType::CompServerClient,
48            ssh2::MethodType::LangCs => MethodType::LangClientServer,
49            ssh2::MethodType::LangSc => MethodType::LangServerClient,
50            ssh2::MethodType::SignAlgo => MethodType::SignAlgo,
51        }
52    }
53}
54
55/// Ssh key method.
56/// Defined by [`MethodType`] (see ssh2 docs) and the list of supported algorithms.
57pub struct KeyMethod {
58    pub(crate) method_type: MethodType,
59    algos: Vec<String>,
60}
61
62impl KeyMethod {
63    /// Instantiates a new [`KeyMethod`]
64    pub fn new(method_type: MethodType, algos: &[String]) -> Self {
65        Self {
66            method_type,
67            algos: algos.to_vec(),
68        }
69    }
70
71    /// Get preferred algos in ssh protocol syntax
72    pub(crate) fn prefs(&self) -> String {
73        self.algos.join(",")
74    }
75
76    #[cfg(feature = "libssh")]
77    pub fn ssh_opts(&self) -> Option<libssh_rs::SshOption> {
78        let values = self.algos.join(",");
79
80        match self.method_type {
81            MethodType::Kex => Some(libssh_rs::SshOption::KeyExchange(values)),
82            MethodType::HostKey => Some(libssh_rs::SshOption::HostKeys(values)),
83            MethodType::CryptClientServer => Some(libssh_rs::SshOption::CiphersCS(values)),
84            MethodType::CryptServerClient => Some(libssh_rs::SshOption::CiphersSC(values)),
85            MethodType::MacClientServer => Some(libssh_rs::SshOption::HmacCS(values)),
86            MethodType::MacServerClient => Some(libssh_rs::SshOption::HmacSC(values)),
87            _ => None,
88        }
89    }
90}
91
92#[cfg(test)]
93mod tests {
94
95    #[cfg(feature = "libssh2")]
96    use ssh2::MethodType as Ssh2MethodType;
97
98    #[cfg(feature = "libssh2")]
99    use super::*;
100
101    #[test]
102    #[cfg(feature = "libssh2")]
103    fn test_should_convert_method_type() {
104        assert_eq!(MethodType::from(Ssh2MethodType::Kex), MethodType::Kex);
105        assert_eq!(
106            MethodType::from(Ssh2MethodType::HostKey),
107            MethodType::HostKey
108        );
109        assert_eq!(
110            MethodType::from(Ssh2MethodType::CryptCs),
111            MethodType::CryptClientServer
112        );
113        assert_eq!(
114            MethodType::from(Ssh2MethodType::CryptSc),
115            MethodType::CryptServerClient
116        );
117        assert_eq!(
118            MethodType::from(Ssh2MethodType::MacCs),
119            MethodType::MacClientServer
120        );
121        assert_eq!(
122            MethodType::from(Ssh2MethodType::MacSc),
123            MethodType::MacServerClient
124        );
125        assert_eq!(
126            MethodType::from(Ssh2MethodType::CompCs),
127            MethodType::CompClientServer
128        );
129        assert_eq!(
130            MethodType::from(Ssh2MethodType::CompSc),
131            MethodType::CompServerClient
132        );
133        assert_eq!(
134            MethodType::from(Ssh2MethodType::LangCs),
135            MethodType::LangClientServer
136        );
137        assert_eq!(
138            MethodType::from(Ssh2MethodType::LangSc),
139            MethodType::LangServerClient
140        );
141        assert_eq!(
142            MethodType::from(Ssh2MethodType::SignAlgo),
143            MethodType::SignAlgo
144        );
145    }
146
147    #[test]
148    #[cfg(feature = "libssh2")]
149    fn test_should_convert_method_type_back() {
150        assert!(matches!(
151            Ssh2MethodType::from(MethodType::Kex),
152            Ssh2MethodType::Kex
153        ));
154        assert!(matches!(
155            Ssh2MethodType::from(MethodType::HostKey),
156            Ssh2MethodType::HostKey
157        ));
158        assert!(matches!(
159            Ssh2MethodType::from(MethodType::CryptClientServer),
160            Ssh2MethodType::CryptCs
161        ));
162        assert!(matches!(
163            Ssh2MethodType::from(MethodType::CryptServerClient),
164            Ssh2MethodType::CryptSc
165        ));
166        assert!(matches!(
167            Ssh2MethodType::from(MethodType::MacClientServer),
168            Ssh2MethodType::MacCs
169        ));
170        assert!(matches!(
171            Ssh2MethodType::from(MethodType::MacServerClient),
172            Ssh2MethodType::MacSc
173        ));
174        assert!(matches!(
175            Ssh2MethodType::from(MethodType::CompClientServer),
176            Ssh2MethodType::CompCs
177        ));
178        assert!(matches!(
179            Ssh2MethodType::from(MethodType::CompServerClient),
180            Ssh2MethodType::CompSc
181        ));
182        assert!(matches!(
183            Ssh2MethodType::from(MethodType::LangClientServer),
184            Ssh2MethodType::LangCs
185        ));
186        assert!(matches!(
187            Ssh2MethodType::from(MethodType::LangServerClient),
188            Ssh2MethodType::LangSc
189        ));
190        assert!(matches!(
191            Ssh2MethodType::from(MethodType::SignAlgo),
192            Ssh2MethodType::SignAlgo
193        ));
194    }
195}