diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/interface/config.rs | 4 | ||||
-rw-r--r-- | src/interface/mod.rs | 8 | ||||
-rw-r--r-- | src/interface/peer_server.rs | 33 | ||||
-rw-r--r-- | src/ip_packet.rs | 6 | ||||
-rw-r--r-- | src/main.rs | 4 | ||||
-rw-r--r-- | src/noise.rs | 4 | ||||
-rw-r--r-- | src/protocol/peer.rs | 18 | ||||
-rw-r--r-- | src/router.rs | 10 | ||||
-rw-r--r-- | src/timer.rs | 1 | ||||
-rw-r--r-- | src/types.rs | 81 |
10 files changed, 44 insertions, 125 deletions
diff --git a/src/interface/config.rs b/src/interface/config.rs index e3505d0..792ccf6 100644 --- a/src/interface/config.rs +++ b/src/interface/config.rs @@ -4,7 +4,7 @@ // * Configuration service should use channels to report updates it receives over its interface. use bytes::BytesMut; -use failure::Error; +use failure::{Error, err_msg}; use std::fs::{create_dir, remove_file}; use std::mem; use std::iter::Iterator; @@ -58,7 +58,7 @@ impl UpdateEvent { "endpoint" => { info.endpoint = Some(value.parse()?); }, "remove" => { remove_pending_peer = true; } "allowed_ip" => { - let (ip, cidr) = value.split_at(value.find('/').ok_or_else(|| format_err!("ip/cidr format error"))?); + let (ip, cidr) = value.split_at(value.find('/').ok_or_else(|| err_msg("ip/cidr format error"))?); info.allowed_ips.push((ip.parse()?, (&cidr[1..]).parse()?)) }, _ => { warn!("unrecognized configuration pair: {}={}", key, value)} diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 3925eff..395f97b 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -53,9 +53,9 @@ pub enum UtunPacket { impl UtunPacket { pub fn payload(&self) -> &[u8] { - match self { - &UtunPacket::Inet4(ref payload) => &payload, - &UtunPacket::Inet6(ref payload) => &payload, + use self::UtunPacket::*; + match *self { + Inet4(ref payload) | Inet6(ref payload) => payload, } } @@ -203,7 +203,7 @@ impl Interface { let peer = Rc::new(RefCell::new(peer)); - state.router.add_allowed_ips(&info.allowed_ips, peer.clone()); + state.router.add_allowed_ips(&info.allowed_ips, &peer); let _ = state.index_map.insert(our_index, peer.clone()); let _ = state.pubkey_map.insert(info.pub_key, peer); diff --git a/src/interface/peer_server.rs b/src/interface/peer_server.rs index f070a18..ed44e10 100644 --- a/src/interface/peer_server.rs +++ b/src/interface/peer_server.rs @@ -9,7 +9,7 @@ use std::net::{IpAddr, Ipv6Addr, SocketAddr}; use std::time::{Duration, Instant}; use byteorder::{ByteOrder, LittleEndian}; -use failure::Error; +use failure::{Error, err_msg}; use futures::{self, Async, Future, Stream, Sink, Poll, unsync, stream}; use socket2::{Socket, Domain, Type, Protocol}; use tokio_core::net::{UdpSocket, UdpCodec, UdpFramed}; @@ -41,7 +41,7 @@ impl UdpCodec for VecUdpCodec { buf.append(&mut data); let mapped_ip = match addr.ip() { IpAddr::V4(v4addr) => IpAddr::V6(v4addr.to_ipv6_mapped()), - v6addr => v6addr.clone() + v6addr => v6addr }; addr.set_ip(mapped_ip); addr @@ -101,7 +101,7 @@ impl PeerServer { self.handle.spawn(self.tunnel_tx.clone().send(packet).then(|_| Ok(()))); } - fn handle_incoming_packet(&mut self, addr: SocketAddr, packet: Vec<u8>) -> Result<(), Error> { + fn handle_incoming_packet(&mut self, addr: SocketAddr, packet: &[u8]) -> Result<(), Error> { trace!("got a UDP packet from {:?} of length {}, packet type {}", &addr, packet.len(), packet[0]); let mut state = self.shared_state.borrow_mut(); match packet[0] { @@ -109,7 +109,7 @@ impl PeerServer { ensure!(packet.len() == 148, "handshake init packet length is incorrect"); { let pubkey = state.interface_info.pub_key.as_ref() - .ok_or_else(|| format_err!("must have local interface key"))?; + .ok_or_else(|| err_msg("must have local interface key"))?; let (mac_in, mac_out) = packet.split_at(116); Noise::verify_mac1(pubkey, mac_in, &mac_out[..16])?; } @@ -117,11 +117,11 @@ impl PeerServer { info!("got handshake initiation request (0x01)"); let handshake = Peer::process_incoming_handshake( - &state.interface_info.private_key.ok_or_else(|| format_err!("no private key!"))?, - &packet)?; + &state.interface_info.private_key.ok_or_else(|| err_msg("no private key!"))?, + packet)?; let peer_ref = state.pubkey_map.get(handshake.their_pubkey()) - .ok_or_else(|| format_err!("unknown peer pubkey"))?.clone(); + .ok_or_else(|| err_msg("unknown peer pubkey"))?.clone(); let mut peer = peer_ref.borrow_mut(); let (response, next_index) = peer.complete_incoming_handshake(addr, handshake)?; @@ -134,7 +134,7 @@ impl PeerServer { ensure!(packet.len() == 92, "handshake resp packet length is incorrect"); { let pubkey = state.interface_info.pub_key.as_ref() - .ok_or_else(|| format_err!("must have local interface key"))?; + .ok_or_else(|| err_msg("must have local interface key"))?; let (mac_in, mac_out) = packet.split_at(60); Noise::verify_mac1(pubkey, mac_in, &mac_out[..16])?; } @@ -145,7 +145,7 @@ impl PeerServer { .ok_or_else(|| format_err!("unknown our_index ({})", our_index))? .clone(); let mut peer = peer_ref.borrow_mut(); - let dead_index = peer.process_incoming_handshake_response(&packet)?; + let dead_index = peer.process_incoming_handshake_response(packet)?; if let Some(index) = dead_index { let _ = state.index_map.remove(&index); } @@ -168,7 +168,7 @@ impl PeerServer { let nonce = LittleEndian::read_u64(&packet[8..]); let peer_ref = state.index_map.get(&our_index_received) - .ok_or_else(|| format_err!("unknown our_index"))? + .ok_or_else(|| err_msg("unknown our_index"))? .clone(); let (raw_packet, dead_index) = { @@ -180,7 +180,8 @@ impl PeerServer { let _ = state.index_map.remove(&index); } - if raw_packet.len() == 0 { + if raw_packet.is_empty() { + debug!("received keepalive."); return Ok(()) // short-circuit on keep-alives } @@ -211,7 +212,7 @@ impl PeerServer { let (init_packet, our_index) = peer.initiate_new_session(private_key).unwrap(); let _ = state.index_map.insert(our_index, peer_ref.clone()); - let endpoint = peer.info.endpoint.ok_or_else(|| format_err!("no endpoint for peer"))?; + let endpoint = peer.info.endpoint.ok_or_else(|| err_msg("no endpoint for peer"))?; self.send_to_peer((endpoint, init_packet)); info!("sent rekey"); @@ -245,12 +246,12 @@ impl PeerServer { Ok(Async::Ready(None)) | Err(_) => bail!("channel failure"), }; - ensure!(packet.payload().len() != 0 && packet.payload().len() < MAX_CONTENT_SIZE, + ensure!(!packet.payload().is_empty() && packet.payload().len() < MAX_CONTENT_SIZE, "illegal packet size"); trace_packet("received UTUN packet: ", packet.payload()); let state = self.shared_state.borrow(); - let peer = state.router.route_to_peer(packet.payload()).ok_or_else(|| format_err!("no route to peer"))?; + let peer = state.router.route_to_peer(packet.payload()).ok_or_else(|| err_msg("no route to peer"))?; let mut peer = peer.borrow_mut(); peer.handle_outgoing_transport(packet.payload())? @@ -258,7 +259,7 @@ impl PeerServer { self.send_to_peer((endpoint, out_packet)); let _ = self.outgoing_rx.poll(); // if we haven't short-circuited yet, take the packet out of the queue - return Ok(true) + Ok(true) } } @@ -282,7 +283,7 @@ impl Future for PeerServer { loop { match self.udp_stream.poll() { Ok(Async::Ready(Some((addr, packet)))) => { - let _ = self.handle_incoming_packet(addr, packet).map_err(|e| warn!("UDP ERR: {:?}", e)); + let _ = self.handle_incoming_packet(addr, &packet).map_err(|e| warn!("UDP ERR: {:?}", e)); }, Ok(Async::NotReady) => break, Ok(Async::Ready(None)) | Err(_) => return Err(()), diff --git a/src/ip_packet.rs b/src/ip_packet.rs index d5398dd..67ec7d4 100644 --- a/src/ip_packet.rs +++ b/src/ip_packet.rs @@ -9,13 +9,13 @@ pub enum IpPacket<'a> { impl<'a> IpPacket<'a> { pub fn new(packet: &'a [u8]) -> Option<Self> { - if packet.len() == 0 { + if packet.is_empty() { return None; } match packet[0] >> 4 { - 4 => Ipv4Packet::new(&packet).map(|packet| IpPacket::V4(packet)), - 6 => Ipv6Packet::new(&packet).map(|packet| IpPacket::V6(packet)), + 4 => Ipv4Packet::new(packet).map(IpPacket::V4), + 6 => Ipv6Packet::new(packet).map(IpPacket::V6), _ => None } } diff --git a/src/main.rs b/src/main.rs index a50e73b..6fb7fe5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,10 @@ #![feature(try_trait)] #![feature(test)] +#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))] +#![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))] +#![cfg_attr(feature = "cargo-clippy", allow(decimal_literal_representation))] + #[macro_use] extern crate failure; #[macro_use] extern crate lazy_static; #[macro_use] extern crate log; diff --git a/src/noise.rs b/src/noise.rs index 4870f41..255a3ff 100644 --- a/src/noise.rs +++ b/src/noise.rs @@ -12,10 +12,10 @@ lazy_static! { /// Wrapper around the `snow` library to easily setup the handshakes for WireGuard. pub struct Noise {} impl Noise { - fn new_foundation<'a>(local_privkey: &'a [u8]) -> NoiseBuilder<'a> { + fn new_foundation(local_privkey: &[u8]) -> NoiseBuilder { NoiseBuilder::new(NOISE_PARAMS.clone()) .local_private_key(local_privkey) - .prologue("WireGuard v1 zx2c4 Jason@zx2c4.com".as_bytes()) + .prologue(b"WireGuard v1 zx2c4 Jason@zx2c4.com") } pub fn build_initiator(local_privkey: &[u8], remote_pubkey: &[u8], psk: &Option<[u8; 32]>) -> Result<Session, Error> { diff --git a/src/protocol/peer.rs b/src/protocol/peer.rs index cf2f7f9..b52c24f 100644 --- a/src/protocol/peer.rs +++ b/src/protocol/peer.rs @@ -1,7 +1,7 @@ use anti_replay::AntiReplay; use byteorder::{ByteOrder, LittleEndian}; use consts::{TRANSPORT_OVERHEAD, TRANSPORT_HEADER_SIZE, MAX_SEGMENT_SIZE, REJECT_AFTER_MESSAGES}; -use failure::{Error, SyncFailure}; +use failure::{Error, SyncFailure, err_msg}; use noise::Noise; use std::{self, mem}; use std::fmt::{self, Debug, Display, Formatter}; @@ -28,10 +28,6 @@ impl PartialEq for Peer { fn eq(&self, other: &Peer) -> bool { self.info.pub_key == other.info.pub_key } - - fn ne(&self, other: &Peer) -> bool { - self.info.pub_key != other.info.pub_key - } } #[derive(Debug, PartialEq)] @@ -124,7 +120,7 @@ impl Peer { pub fn initiate_new_session(&mut self, private_key: &[u8]) -> Result<(Vec<u8>, u32), Error> { let noise = Noise::build_initiator( - &private_key, + private_key, &self.info.pub_key, &self.info.psk)?; let mut session: Session = noise.into(); @@ -205,7 +201,7 @@ impl Peer { pub fn process_incoming_handshake_response(&mut self, packet: &[u8]) -> Result<Option<u32>, Error> { let their_index = LittleEndian::read_u32(&packet[4..]); - let mut session = mem::replace(&mut self.sessions.next, None).ok_or_else(|| format_err!("no next session"))?; + let mut session = mem::replace(&mut self.sessions.next, None).ok_or_else(|| err_msg("no next session"))?; let _ = session.noise.read_message(&packet[12..60], &mut []).map_err(SyncFailure::new)?; session.their_index = their_index; @@ -224,7 +220,7 @@ impl Peer { let mut raw_packet = vec![0u8; MAX_SEGMENT_SIZE]; let session_type = { - let (session, session_type) = self.find_session(our_index).ok_or_else(|| format_err!("no session with index"))?; + let (session, session_type) = self.find_session(our_index).ok_or_else(|| err_msg("no session with index"))?; ensure!(session.noise.is_handshake_finished(), "session is not ready for transport packets"); session.anti_replay.update(nonce)?; @@ -253,8 +249,8 @@ impl Peer { } pub fn handle_outgoing_transport(&mut self, packet: &[u8]) -> Result<(SocketAddr, Vec<u8>), Error> { - let session = self.sessions.current.as_mut().ok_or_else(|| format_err!("no current noise session"))?; - let endpoint = self.info.endpoint.ok_or_else(|| format_err!("no known peer endpoint"))?; + let session = self.sessions.current.as_mut().ok_or_else(|| err_msg("no current noise session"))?; + let endpoint = self.info.endpoint.ok_or_else(|| err_msg("no known peer endpoint"))?; let mut out_packet = vec![0u8; packet.len() + TRANSPORT_OVERHEAD]; let nonce = session.noise.sending_nonce().map_err(SyncFailure::new)?; @@ -278,7 +274,7 @@ impl Peer { if let Some(ref endpoint) = self.info.endpoint { s.push_str(&format!("endpoint={}:{}\n", endpoint.ip().to_string(),endpoint.port())); } - for &(ip, cidr) in self.info.allowed_ips.iter() { + for &(ip, cidr) in &self.info.allowed_ips { s.push_str(&format!("allowed_ip={}/{}\n", ip, cidr)); } s.push_str(&format!("tx_bytes={}\nrx_bytes={}\n", self.tx_bytes, self.rx_bytes)); diff --git a/src/router.rs b/src/router.rs index 252a653..dc6443e 100644 --- a/src/router.rs +++ b/src/router.rs @@ -1,4 +1,4 @@ -use failure::Error; +use failure::{Error, err_msg}; use interface::SharedPeer; use treebitmap::{IpLookupTable, IpLookupTableOps}; use std::net::{Ipv4Addr, Ipv6Addr, IpAddr}; @@ -18,7 +18,7 @@ impl Router { } } - pub fn add_allowed_ips(&mut self, allowed_ips: &[(IpAddr, u32)], peer: SharedPeer) { + pub fn add_allowed_ips(&mut self, allowed_ips: &[(IpAddr, u32)], peer: &SharedPeer) { for &(ip_addr, mask) in allowed_ips { self.add_allowed_ip(ip_addr, mask, peer.clone()); } @@ -39,17 +39,17 @@ impl Router { } pub fn route_to_peer(&self, packet: &[u8]) -> Option<SharedPeer> { - match IpPacket::new(&packet) { + match IpPacket::new(packet) { Some(packet) => self.get_peer_from_ip(packet.get_destination()), _ => None } } pub fn validate_source(&self, packet: &[u8], peer: &SharedPeer) -> Result<(), Error> { - let routed_peer = match IpPacket::new(&packet) { + let routed_peer = match IpPacket::new(packet) { Some(packet) => self.get_peer_from_ip(packet.get_source()), _ => None - }.ok_or_else(|| format_err!("no peer found on route"))?; + }.ok_or_else(|| err_msg("no peer found on route"))?; ensure!(&routed_peer == peer, "peer mismatch"); Ok(()) diff --git a/src/timer.rs b/src/timer.rs index 6d033dd..75e3fbf 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -6,7 +6,6 @@ use interface::SharedPeer; #[derive(Debug)] pub enum TimerMessage { - // PersistentKeepAlive(SharedPeer, u32), KeepAlive(SharedPeer, u32), Rekey(SharedPeer, u32), } diff --git a/src/types.rs b/src/types.rs index 0191ed7..c17cbb1 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,4 @@ use base64; -use std::io::{Cursor, Read, Write}; -use byteorder::{LittleEndian, WriteBytesExt, ReadBytesExt}; use std::fmt::{self, Display, Formatter}; use std::net::{IpAddr, SocketAddr}; @@ -26,82 +24,3 @@ pub struct InterfaceInfo { pub pub_key: Option<[u8; 32]>, pub listen_port: Option<u16>, } - -pub enum Message { - HandshakeInitiation(HandshakeInitiationMessage), -// HandshakeResponse(HandshakeResponseMessage), -// Transport(TransportMessage), -// CookieReply(CookieReplyMessage), - Other(Vec<u8>) -} - -// TODO use TryFrom -impl<'a> From<&'a [u8]> for Message { - fn from(bytes: &'a [u8]) -> Self { - use self::Message::*; - let mut cursor = Cursor::new(bytes); - match cursor.read_u8().unwrap() { - 1 => HandshakeInitiation(HandshakeInitiationMessage::from(&bytes[4..])), - _ => Other((&bytes[4..]).to_owned()) - } - } -} - -impl From<Message> for Vec<u8> { - fn from(message: Message) -> Self { - use self::Message::*; - match message { - HandshakeInitiation(message) => { - let mut bytes = vec![1u8, 0, 0, 0]; - bytes.append(&mut message.into()); - bytes - }, - _ => unimplemented!() - } - } -} - -pub struct HandshakeInitiationMessage { - pub sender_i: u32, - pub payload: [u8; 76], - pub mac1: [u8; 16], - pub mac2: [u8; 16] -} - -impl HandshakeInitiationMessage { - pub fn new() -> Self { - HandshakeInitiationMessage { - sender_i: 0, - payload: [0u8; 76], - mac1: [0u8; 16], - mac2: [0u8; 16], - } - } -} - -impl<'a> From<&'a [u8]> for HandshakeInitiationMessage { - - fn from(bytes: &'a [u8]) -> Self { - let mut message = HandshakeInitiationMessage::new(); - let mut cursor = Cursor::new(bytes); - - message.sender_i = cursor.read_u32::<LittleEndian>().unwrap(); - cursor.read_exact(&mut message.payload[..]).unwrap(); - cursor.read_exact(&mut message.mac1[..]).unwrap(); - cursor.read_exact(&mut message.mac2[..]).unwrap(); - message - } -} - -impl From<HandshakeInitiationMessage> for Vec<u8> { - fn from(message: HandshakeInitiationMessage) -> Self { - let mut cursor = vec![]; - cursor.write_all(&[1u8, 0, 0, 0]).unwrap(); - cursor.write_u32::<LittleEndian>(message.sender_i).unwrap(); - cursor.write_all(&message.payload).unwrap(); - cursor.write_all(&message.mac1).unwrap(); - cursor.write_all(&message.mac2).unwrap(); - - cursor - } -}
\ No newline at end of file |