diff options
| author | Emīls <emils@mullvad.net> | 2019-11-26 15:50:38 +0000 |
|---|---|---|
| committer | Emīls <emils@mullvad.net> | 2019-11-27 09:55:19 +0000 |
| commit | c47dbfdc1dbc26b5d43cd0f55c147296458c55b0 (patch) | |
| tree | 8ac685df9282865dd7bf45ce7f5e0ecddc7be172 | |
| parent | 86fb4a15f385d500100b5978e7f5eb16ee750b43 (diff) | |
| download | mullvadvpn-c47dbfdc1dbc26b5d43cd0f55c147296458c55b0.tar.xz mullvadvpn-c47dbfdc1dbc26b5d43cd0f55c147296458c55b0.zip | |
Check if resolvconf generates contents of /etc/resolv.conf
| -rw-r--r-- | talpid-core/src/dns/linux/resolvconf.rs | 41 |
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"), + } + } } |
