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
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
use hashbrown::HashSet;
use integer_encoding::{FixedInt, VarInt};
use secretbox::CipherType::Salsa20;
use secretbox::SecretBox;
use std::io::{Error, Read, Write};
use std::net::{Shutdown, TcpStream};

/// Connections provides an interface for manage sets of connections on top of a particular
/// ACN.
pub mod service;
pub mod utils;

#[derive(Debug)]
pub enum ServiceError {
    ClosedNormally,
    ConnectionFailed(String),
    ListenFailed(String),
}

#[derive(Clone)]
pub struct InboundConnection(());
#[derive(Clone)]
pub struct OutboundConnection(());

#[derive(Clone, Eq, PartialEq, Hash)]
pub struct Capability(pub &'static str);

pub struct Connection<Direction> {
    conn: TcpStream,
    direction: Direction,
    key: Vec<u8>,
    hostname: String,
    capabilities: HashSet<Capability>,
}

pub trait ConnectionInterface {
    fn set_hostname(&mut self, hostname: &String);
    fn hostname(&self) -> String;
    fn enable_encryption(&mut self, key: Vec<u8>);
    fn send(&mut self, amsg: &String) -> Result<(), Error>;
    fn send_encrypted(&mut self, msg: Vec<u8>) -> Result<(), Error>;
    fn expect_encrypted(&mut self) -> Vec<u8>;
    fn expect(&mut self) -> Result<Vec<u8>, Error>;
    fn shutdown(&mut self);

    fn set_capability(&mut self, capability: &Capability);
    fn has_capability(&self, capability: &Capability) -> bool;
}

impl<Direction> ConnectionInterface for Connection<Direction> {
    fn set_hostname(&mut self, hostname: &String) {
        self.hostname = hostname.clone()
    }

    fn hostname(&self) -> String {
        self.hostname.clone()
    }

    fn enable_encryption(&mut self, key: Vec<u8>) {
        self.key = key
    }

    fn send(&mut self, amsg: &String) -> Result<(), Error> {
        let mut len = [0u8; 2];
        (amsg.len() as u16).encode_var(&mut len);
        let mut msg = vec![];
        msg.extend_from_slice(len.as_slice());
        msg.extend_from_slice(amsg.as_bytes());
        let mut msg = msg;
        while msg.len() < 8192 {
            msg.push(0);
        }
        self.conn.write_all(msg.as_slice())
    }

    fn send_encrypted(&mut self, msg: Vec<u8>) -> Result<(), Error> {
        let mut msg = msg;
        while msg.len() < 8192 - 40 {
            msg.push(0);
        }
        let secret_box = SecretBox::new(&self.key, Salsa20).unwrap();
        let msg = secret_box.easy_seal(msg.as_slice());
        self.conn.write_all(msg.as_slice())
    }

    fn expect_encrypted(&mut self) -> Vec<u8> {
        let secret_box = SecretBox::new(&self.key, Salsa20).unwrap();
        let mut result = [0u8; 8192];
        match self.conn.read_exact(&mut result) {
            Err(e) => {
                eprintln!("{}", e.to_string());
                return vec![];
            }
            _ => {}
        }

        let msg = match secret_box.easy_unseal(&result) {
            Some(msg) => msg,
            _ => {
                return vec![];
            }
        };

        let msg = msg.as_slice();
        let _len_bytes = [0u8; 2];
        let len = u16::decode_fixed(&msg[0..2]) as usize;
        if len > 8192 {
            eprintln!("invalid length: {}", len);
            return vec![]; // lol no.
        }
        msg[2..len + 2].to_vec()
    }

    fn expect(&mut self) -> Result<Vec<u8>, Error> {
        let mut msg = [0; 8192];
        let result = self.conn.read_exact(&mut msg);
        match result {
            Err(e) => Err(e),
            Ok(()) => {
                // TODO why did I decide to use varints here?!?!
                let len = u16::decode_var(&msg[0..2]).unwrap().0 as usize;
                println!("{} [{}]", len, String::from_utf8(msg[2..len + 2].to_vec()).unwrap());
                return Ok(msg[2..len + 2].to_vec());
            }
        }
    }

    fn shutdown(&mut self) {
        match self.conn.shutdown(Shutdown::Both) {
            _ => {} // If anything bad happens we will know soon enough...
        }
    }

    fn set_capability(&mut self, capability: &Capability) {
        self.capabilities.insert(capability.clone());
    }

    fn has_capability(&self, capability: &Capability) -> bool {
        self.capabilities.contains(capability)
    }
}

impl<Direction> Connection<Direction>
where
    Direction: Clone,
{
    pub fn new_inbound(conn: TcpStream) -> Connection<InboundConnection> {
        Connection {
            conn,
            direction: InboundConnection(()),
            key: vec![],
            hostname: String::new(),
            capabilities: HashSet::new(),
        }
    }

    pub fn new_outbound(conn: TcpStream) -> Connection<OutboundConnection> {
        Connection {
            conn,
            direction: OutboundConnection(()),
            key: vec![],
            hostname: String::new(),
            capabilities: HashSet::new(),
        }
    }

    pub fn try_clone(&self) -> Connection<Direction> {
        Connection {
            conn: self.conn.try_clone().unwrap(),
            direction: self.direction.clone(),
            key: self.key.clone(),
            hostname: self.hostname.clone(),
            capabilities: self.capabilities.clone(),
        }
    }
}

pub struct Hostname {}