summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorEmīls <emils@mullvad.net>2019-11-26 15:50:38 +0000
committerEmīls <emils@mullvad.net>2019-11-27 09:55:19 +0000
commitc47dbfdc1dbc26b5d43cd0f55c147296458c55b0 (patch)
tree8ac685df9282865dd7bf45ce7f5e0ecddc7be172
parent86fb4a15f385d500100b5978e7f5eb16ee750b43 (diff)
downloadmullvadvpn-c47dbfdc1dbc26b5d43cd0f55c147296458c55b0.tar.xz
mullvadvpn-c47dbfdc1dbc26b5d43cd0f55c147296458c55b0.zip
Check if resolvconf generates contents of /etc/resolv.conf
-rw-r--r--talpid-core/src/dns/linux/resolvconf.rs41
1 files changed, 40 insertions, 1 deletions
diff --git a/talpid-core/src/dns/linux/resolvconf.rs b/talpid-core/src/dns/linux/resolvconf.rs
index 3a32eaf406..8bb2c0b885 100644
--- a/talpid-core/src/dns/linux/resolvconf.rs
+++ b/talpid-core/src/dns/linux/resolvconf.rs
@@ -29,6 +29,9 @@ pub enum Error {
#[error(display = "Detected dnsmasq is runing and misconfigured")]
DnsmasqMisconfigurationError,
+
+ #[error(display = "Current /etc/resolv.conf is not generated by resolvconf")]
+ ResolvconfNotInUseError,
}
pub struct Resolvconf {
@@ -43,7 +46,18 @@ impl Resolvconf {
return Err(Error::ResolvconfUsesResolved);
}
- if Self::is_dnsmasq_running() && Self::is_dnsmasq_configured_wrong() {
+ let is_dnsmasq_running = Self::is_dnsmasq_running();
+
+ // Check if resolvconf is managing DNS by /etc/resolv.conf
+ if !is_dnsmasq_running
+ && !(Self::check_if_resolvconf_is_symlinked_correctly()
+ || Self::check_if_resolvconf_was_generated())
+ {
+ return Err(Error::ResolvconfNotInUseError);
+ }
+
+ // Check if resolvconf can manage DNS via dnsmasq
+ if is_dnsmasq_running && Self::is_dnsmasq_configured_wrong() {
return Err(Error::DnsmasqMisconfigurationError);
}
@@ -146,4 +160,29 @@ impl Resolvconf {
.any(|line| line.trim().starts_with("no-resolv"))
})
}
+
+ // Returns true if /etc/resolv.conf contents indicate that they've been generated by resolvconf
+ fn check_if_resolvconf_was_generated() -> bool {
+ match fs::read_to_string("/etc/resolv.conf") {
+ Ok(contents) => contents.contains("Generated by resolvconf"),
+ Err(err) => {
+ log::error!("Couldn't read /etc/resolv.conf - {}", err);
+ return false;
+ }
+ }
+ }
+
+ // Returns true if /etc/resolv.conf is symlinked to resolvconf's runtime directory
+ // (`/var/run/resolvconf`)
+ fn check_if_resolvconf_is_symlinked_correctly() -> bool {
+ match fs::canonicalize("/etc/resolv.conf") {
+ Err(err) => {
+ if err.kind() != io::ErrorKind::NotFound {
+ log::error!("Failed to canonicalize /etc/resolv.conf - {}", err);
+ }
+ false
+ }
+ Ok(path) => path.starts_with("/var/run/resolvconf"),
+ }
+ }
}