Skip to main content

rusty_sockslib/
handshake.rs

1use crate::helpers::{IntoError, Res};
2
3pub struct Handshake {
4    pub version: u8,
5    pub num_methods: u8,
6    pub methods: Vec<u8>,
7}
8
9impl Handshake {
10    pub fn from_data(data: &[u8]) -> Res<Handshake> {
11        // VER, NMETHODS.
12        if data.len() < 2 {
13            return "Handshake too short: need at least a version and a method count.".into_error();
14        }
15
16        let version = data[0];
17        let num_methods = data[1];
18        let methods_end = 2 + usize::from(num_methods);
19
20        if data.len() < methods_end {
21            return "Handshake too short for the stated number of methods.".into_error();
22        }
23
24        let methods = data[2..methods_end].to_vec();
25
26        Ok(Handshake { version, num_methods, methods })
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33    use pretty_assertions::assert_eq;
34
35    #[test]
36    fn parses_greeting() {
37        // VER=5, NMETHODS=2, METHODS=[NO_AUTH, GSSAPI].
38        let data = [0x05, 0x02, 0x00, 0x01];
39        let handshake = Handshake::from_data(&data).unwrap();
40
41        assert_eq!(handshake.version, 5);
42        assert_eq!(handshake.num_methods, 2);
43        assert_eq!(handshake.methods, vec![0x00, 0x01]);
44    }
45
46    #[test]
47    fn rejects_truncated_greeting() {
48        // Fewer than two bytes: not even a version and method count.
49        assert!(Handshake::from_data(&[0x05]).is_err());
50    }
51
52    #[test]
53    fn rejects_greeting_missing_methods() {
54        // Claims five methods but provides none.
55        assert!(Handshake::from_data(&[0x05, 0x05]).is_err());
56    }
57}