diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2019-02-01 12:24:38 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2019-02-01 12:24:38 +0100 |
| commit | 86ea31a4a3a9d6f4c23043abd993a42170eb2ed2 (patch) | |
| tree | 6e3777aa027102ad710f9e965b628bf8c1a9ead8 | |
| parent | c697a40bb0534b2f8e3f9b94b0580bb7f079892d (diff) | |
| download | mullvadvpn-86ea31a4a3a9d6f4c23043abd993a42170eb2ed2.tar.xz mullvadvpn-86ea31a4a3a9d6f4c23043abd993a42170eb2ed2.zip | |
Fix dns/firewall code to work with new structure
| -rw-r--r-- | Cargo.lock | 14 | ||||
| -rw-r--r-- | talpid-core/Cargo.toml | 1 | ||||
| -rw-r--r-- | talpid-core/src/dns/linux/mod.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/dns/linux/systemd_resolved.rs | 3 | ||||
| -rw-r--r-- | talpid-core/src/dns/macos.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/dns/mod.rs | 47 | ||||
| -rw-r--r-- | talpid-core/src/dns/windows.rs | 2 | ||||
| -rw-r--r-- | talpid-core/src/lib.rs | 7 | ||||
| -rw-r--r-- | talpid-core/src/linux.rs | 24 | ||||
| -rw-r--r-- | talpid-core/src/security/linux.rs | 23 | ||||
| -rw-r--r-- | talpid-core/src/security/mod.rs | 48 | ||||
| -rw-r--r-- | talpid-core/src/tunnel_state_machine/mod.rs | 6 |
12 files changed, 104 insertions, 75 deletions
diff --git a/Cargo.lock b/Cargo.lock index 973752aab2..df7b6ae630 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -299,6 +299,18 @@ dependencies = [ ] [[package]] +name = "err-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.20 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.18 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "errno" version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1772,6 +1784,7 @@ dependencies = [ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "dbus 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "duct 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", + "err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2392,6 +2405,7 @@ dependencies = [ "checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a" "checksum duct 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f87f5af80601599209bff21146e4113e8c54471151049deebc37e75b78e42729" "checksum env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)" = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38" +"checksum err-derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3d8ff65eb6c2fc68e76557239d16f5698fd56603925b89856d3f0f7105fd4543" "checksum errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2a071601ed01b988f896ab14b95e67335d1eeb50190932a1320f7fe3cadc84e" "checksum errno-dragonfly 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml index 7c96a8e831..cc76d632e0 100644 --- a/talpid-core/Cargo.toml +++ b/talpid-core/Cargo.toml @@ -43,6 +43,7 @@ rtnetlink = { git = "https://github.com/mullvad/netlink", branch = "best-effort- nftnl = { git = "https://github.com/mullvad/nftnl-rs", rev = "f0b1492fd2fd1f737dbffd047c9c60c300e6f7d6", features = ["nftnl-1-1-0"] } mnl = { git = "https://github.com/mullvad/mnl-rs", rev = "f0d19501b9b85be9a1ffaec8317a378bcbdf4fa6", features = ["mnl-1-0-4"] } which = "2.0" +err-derive = "0.1.5" [target.'cfg(target_os = "macos")'.dependencies] pfctl = "0.2" diff --git a/talpid-core/src/dns/linux/mod.rs b/talpid-core/src/dns/linux/mod.rs index 74267e2c19..17ec6b7e39 100644 --- a/talpid-core/src/dns/linux/mod.rs +++ b/talpid-core/src/dns/linux/mod.rs @@ -31,7 +31,7 @@ pub struct DnsMonitor { inner: Option<DnsMonitorHolder>, } -impl super::super::DnsMonitorT for DnsMonitor { +impl super::DnsMonitorT for DnsMonitor { type Error = Error; fn new(_cache_dir: impl AsRef<Path>) -> Result<Self> { diff --git a/talpid-core/src/dns/linux/systemd_resolved.rs b/talpid-core/src/dns/linux/systemd_resolved.rs index f4eac9e486..6734a1819c 100644 --- a/talpid-core/src/dns/linux/systemd_resolved.rs +++ b/talpid-core/src/dns/linux/systemd_resolved.rs @@ -1,4 +1,5 @@ -use super::{super::iface_index, RESOLV_CONF_PATH}; +use super::RESOLV_CONF_PATH; +use crate::linux::iface_index; use dbus::{ arg::RefArg, stdintf::*, BusType, Interface, Member, Message, MessageItem, MessageItemArray, Signature, diff --git a/talpid-core/src/dns/macos.rs b/talpid-core/src/dns/macos.rs index a1fad021de..d65fdbf6c0 100644 --- a/talpid-core/src/dns/macos.rs +++ b/talpid-core/src/dns/macos.rs @@ -126,7 +126,7 @@ pub struct DnsMonitor { state: Arc<Mutex<Option<State>>>, } -impl super::super::DnsMonitorT for DnsMonitor { +impl super::DnsMonitorT for DnsMonitor { type Error = Error; /// Creates and returns a new `DnsMonitor`. This spawns a background thread that will monitor diff --git a/talpid-core/src/dns/mod.rs b/talpid-core/src/dns/mod.rs index a997abd665..2631be00a9 100644 --- a/talpid-core/src/dns/mod.rs +++ b/talpid-core/src/dns/mod.rs @@ -1,3 +1,5 @@ +use std::{net::IpAddr, path::Path}; + #[cfg(target_os = "macos")] #[path = "macos.rs"] mod imp; @@ -10,6 +12,47 @@ mod imp; #[path = "windows.rs"] mod imp; -pub use self::imp::{DnsError, Error}; +pub use self::imp::Error; + +/// Sets and monitors system DNS settings. Makes sure the desired DNS servers are being used. +pub struct DnsMonitor { + inner: imp::DnsMonitor, +} + +impl DnsMonitor { + /// Returns a new `DnsMonitor` that can set and monitor the system DNS. + pub fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Error> { + Ok(DnsMonitor { + inner: imp::DnsMonitor::new(cache_dir)?, + }) + } + + /// Set DNS to the given servers. And start monitoring the system for changes. + pub fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), Error> { + log::info!( + "Setting DNS servers to {}", + servers + .iter() + .map(|ip| ip.to_string()) + .collect::<Vec<String>>() + .join(", ") + ); + self.inner.set(interface, servers) + } + + /// Reset system DNS settings to what it was before being set by this instance. + pub fn reset(&mut self) -> Result<(), Error> { + log::info!("Resetting DNS"); + self.inner.reset() + } +} + +trait DnsMonitorT: Sized { + type Error: ::std::error::Error; + + fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Self::Error>; + + fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), Self::Error>; -pub use self::imp::{DnsMonitor, Error as DnsError};
\ No newline at end of file + fn reset(&mut self) -> Result<(), Self::Error>; +} diff --git a/talpid-core/src/dns/windows.rs b/talpid-core/src/dns/windows.rs index 6c04c03e57..6f7cf3f07f 100644 --- a/talpid-core/src/dns/windows.rs +++ b/talpid-core/src/dns/windows.rs @@ -47,7 +47,7 @@ pub struct DnsMonitor { backup_writer: SystemStateWriter, } -impl super::super::DnsMonitorT for DnsMonitor { +impl super::DnsMonitorT for DnsMonitor { type Error = Error; fn new(cache_dir: impl AsRef<Path>) -> Result<Self> { diff --git a/talpid-core/src/lib.rs b/talpid-core/src/lib.rs index 437fb2ff6f..f0337970c5 100644 --- a/talpid-core/src/lib.rs +++ b/talpid-core/src/lib.rs @@ -40,7 +40,14 @@ pub mod mpsc; /// Abstractions over operating system network security settings. pub mod security; +/// Abstractions over operating system DNS settings. +pub mod dns; + /// State machine to handle tunnel configuration. pub mod tunnel_state_machine; mod mktemp; + +/// Misc utilities for the Linux platform. +#[cfg(target_os = "linux")] +mod linux; diff --git a/talpid-core/src/linux.rs b/talpid-core/src/linux.rs new file mode 100644 index 0000000000..2822d5837b --- /dev/null +++ b/talpid-core/src/linux.rs @@ -0,0 +1,24 @@ +use std::{ffi::{self, CString}, io}; + +/// Converts an interface name into the corresponding index. +pub fn iface_index(name: &str) -> Result<libc::c_uint, IfaceIndexLookupError> { + let c_name = CString::new(name) + .map_err(|e| IfaceIndexLookupError::InvalidInterfaceName(name.to_owned(), e))?; + let index = unsafe { libc::if_nametoindex(c_name.as_ptr()) }; + if index == 0 { + Err(IfaceIndexLookupError::InterfaceLookupError( + name.to_owned(), + io::Error::last_os_error(), + )) + } else { + Ok(index) + } +} + +#[derive(Debug, err_derive::Error)] +pub enum IfaceIndexLookupError { + #[error(display = "Invalid network interface name: {}", _0)] + InvalidInterfaceName(String, #[error(cause)] ffi::NulError), + #[error(display = "Failed to get index for interface {}", _0)] + InterfaceLookupError(String, #[error(cause)] io::Error), +} diff --git a/talpid-core/src/security/linux.rs b/talpid-core/src/security/linux.rs index 464ed515f1..7f25e8c9f8 100644 --- a/talpid-core/src/security/linux.rs +++ b/talpid-core/src/security/linux.rs @@ -11,7 +11,6 @@ use nftnl::{ use std::{ env, ffi::{CStr, CString}, - io, net::{IpAddr, Ipv4Addr}, }; use talpid_types::net::{Endpoint, TransportProtocol}; @@ -29,15 +28,13 @@ error_chain! { /// Failed to verify that our tables are set. Probably means that /// it's the host does not support nftables properly. NetfilterTableNotSetError{ description("Failed to set firewall rules") } - /// The name is not a valid Linux network interface name - InvalidInterfaceName(name: String) { - description("Invalid network interface name") - display("Invalid network interface name: {}", name) - } } links { Nftnl(nftnl::Error, nftnl::ErrorKind) #[doc = "Error in nftnl"]; } + foreign_links { + IfaceIndexLookupError(crate::linux::IfaceIndexLookupError); + } } lazy_static! { @@ -416,7 +413,7 @@ fn allow_interface_rule<'a>( } fn check_iface(rule: &mut Rule, direction: Direction, iface: &str) -> Result<()> { - let iface_index = iface_index(iface)?; + let iface_index = crate::linux::iface_index(iface)?; rule.add_expr(&match direction { Direction::In => nft_expr!(meta iif), Direction::Out => nft_expr!(meta oif), @@ -425,18 +422,6 @@ fn check_iface(rule: &mut Rule, direction: Direction, iface: &str) -> Result<()> Ok(()) } -fn iface_index(name: &str) -> Result<libc::c_uint> { - let c_name = - CString::new(name).chain_err(|| ErrorKind::InvalidInterfaceName(name.to_owned()))?; - let index = unsafe { libc::if_nametoindex(c_name.as_ptr()) }; - if index == 0 { - let error = io::Error::last_os_error(); - Err(error).chain_err(|| ErrorKind::InvalidInterfaceName(name.to_owned())) - } else { - Ok(index) - } -} - fn check_net(rule: &mut Rule, end: End, net: IpNetwork) -> Result<()> { // Must check network layer protocol before loading network layer payload check_l3proto(rule, net.ip())?; diff --git a/talpid-core/src/security/mod.rs b/talpid-core/src/security/mod.rs index 10ad9d8556..75bb4cef87 100644 --- a/talpid-core/src/security/mod.rs +++ b/talpid-core/src/security/mod.rs @@ -4,7 +4,7 @@ use ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network}; use lazy_static::lazy_static; #[cfg(unix)] use std::net::{Ipv4Addr, Ipv6Addr}; -use std::{fmt, net::IpAddr, path::Path}; +use std::{fmt, net::IpAddr}; use talpid_types::net::Endpoint; @@ -20,6 +20,8 @@ mod imp; #[path = "windows/mod.rs"] mod imp; +pub use self::imp::Error; + #[cfg(unix)] lazy_static! { @@ -138,40 +140,6 @@ impl NetworkSecurity { } } -/// Sets and monitors system DNS settings. Makes sure the desired DNS servers are being used. -pub struct DnsMonitor { - inner: imp::DnsMonitor, -} - -impl DnsMonitor { - /// Returns a new `DnsMonitor` that can set and monitor the system DNS. - pub fn new(cache_dir: impl AsRef<Path>) -> Result<Self, DnsError> { - Ok(DnsMonitor { - inner: imp::DnsMonitor::new(cache_dir)?, - }) - } - - /// Set DNS to the given servers. And start monitoring the system for changes. - pub fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), DnsError> { - log::info!( - "Setting DNS servers to {}", - servers - .iter() - .map(|ip| ip.to_string()) - .collect::<Vec<String>>() - .join(", ") - ); - self.inner.set(interface, servers) - } - - /// Reset system DNS settings to what it was before being set by this instance. - pub fn reset(&mut self) -> Result<(), DnsError> { - log::info!("Resetting DNS"); - self.inner.reset() - } -} - - /// Abstract firewall interaction trait. Used by the OS specific implementations. trait NetworkSecurityT: Sized { /// The error type thrown by the implementer of this trait @@ -187,13 +155,3 @@ trait NetworkSecurityT: Sized { /// modifying the system. fn reset_policy(&mut self) -> ::std::result::Result<(), Self::Error>; } - -trait DnsMonitorT: Sized { - type Error: ::std::error::Error; - - fn new(cache_dir: impl AsRef<Path>) -> Result<Self, Self::Error>; - - fn set(&mut self, interface: &str, servers: &[IpAddr]) -> Result<(), Self::Error>; - - fn reset(&mut self) -> Result<(), Self::Error>; -} diff --git a/talpid-core/src/tunnel_state_machine/mod.rs b/talpid-core/src/tunnel_state_machine/mod.rs index 8e20e3a159..5226c315e8 100644 --- a/talpid-core/src/tunnel_state_machine/mod.rs +++ b/talpid-core/src/tunnel_state_machine/mod.rs @@ -29,11 +29,7 @@ use self::{ disconnected_state::DisconnectedState, disconnecting_state::{AfterDisconnect, DisconnectingState}, }; -use crate::{ - mpsc::IntoSender, - offline, - security::{DnsMonitor, NetworkSecurity}, -}; +use crate::{dns::DnsMonitor, mpsc::IntoSender, offline, security::NetworkSecurity}; error_chain! { errors { |
