x11_input_mirror/
connector.rs

1use encryption::ChaCha;
2
3use std::io::{Read, Write};
4use std::net::{SocketAddr, TcpStream};
5use std::time::Duration;
6
7pub struct Connector {
8    conns: Vec<(TcpStream, SocketAddr, ChaCha)>,
9}
10
11impl Connector {
12    pub fn connect(addrs: Vec<SocketAddr>, max_ping: Duration, password: &str) -> Connector {
13        let should_be_encrypted = !password.is_empty();
14        let should_be_encrypted_num = if should_be_encrypted { 1 } else { 0 };
15
16        let conns = addrs
17            .into_iter()
18            .map(|addr| {
19                let mut conn = TcpStream::connect(addr)
20                    .unwrap_or_else(|_| panic!("Cannot connect to {}", addr));
21                conn.set_nodelay(true)
22                    .unwrap_or_else(|_| panic!("Cannot connect to {} - set_nodelay failed", addr));
23                conn.set_read_timeout(Some(max_ping)).unwrap_or_else(|_| {
24                    panic!("Cannot connect to {} - set_read_timeout failed", addr)
25                });
26                conn.set_write_timeout(Some(max_ping)).unwrap_or_else(|_| {
27                    panic!("Cannot connect to {} - set_write_timeout failed", addr)
28                });
29
30                // handshake3 - should be encrypted?
31                let mut buf = [0u8; 1];
32                buf[0] = should_be_encrypted_num;
33                conn.write_all(&buf)
34                    .unwrap_or_else(|_| panic!("Cannot connect to {} - handshake3 failed", addr));
35
36                // handshake4 - should be encrypted? + generate nonce
37                let mut buf = [0u8; 25];
38                conn.read_exact(&mut buf)
39                    .unwrap_or_else(|_| panic!("Cannot connect to {} - handshake4 failed", addr));
40                if buf[0] != should_be_encrypted_num {
41                    panic!("Server {} has different SecurityConfig", addr);
42                }
43                let mut nonce = [0u8; 24];
44                nonce.copy_from_slice(&buf[1..]);
45
46                // handshake5
47                let mut chacha = ChaCha::new(should_be_encrypted, password, &nonce);
48                let mut buf = [0u8; 14];
49                buf[..].copy_from_slice(b"ping_fds321sfr");
50                chacha.xor(&mut buf);
51                conn.write_all(&buf)
52                    .unwrap_or_else(|_| panic!("Cannot connect to {} - handshake5 failed", addr));
53
54                // handshake6
55                let mut buf = [0u8; 1];
56                conn.read_exact(&mut buf).unwrap_or_else(|_| {
57                    panic!("Server {} uses different password? Cannot connect to {} - handshake6 failed", addr, addr)
58                });
59
60                (conn, addr, chacha)
61            })
62            .collect::<Vec<_>>();
63        Connector { conns }
64    }
65    pub fn write(&mut self, data: [u8; 16]) {
66        for (conn, addr, chacha) in &mut self.conns {
67            let mut conn = conn;
68            let mut data = data;
69            {
70                let (ldata, rdata) = &mut data.split_at_mut(8);
71                rdata.copy_from_slice(ldata);
72            }
73            chacha.xor(&mut data[..8]);
74            chacha.xor(&mut data[8..]);
75            conn.write_all(&data)
76                .unwrap_or_else(|_| panic!("Connection to server {} lost", addr));
77        }
78    }
79}