From e9230621ef5897900e70ac361e1c07b5c4db4ded Mon Sep 17 00:00:00 2001 From: Francisca Ortega Date: Wed, 9 Oct 2024 01:17:37 -0300 Subject: [PATCH] add: verification for the ip from where the info is received is the same that where we request --- src/async_resolver.rs | 48 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/src/async_resolver.rs b/src/async_resolver.rs index eb60a2aa..0a6698b3 100644 --- a/src/async_resolver.rs +++ b/src/async_resolver.rs @@ -23,6 +23,7 @@ use std::net::IpAddr; use std::time::SystemTime; use std::sync::{Arc, Mutex}; use std::vec; +use std::collections::HashMap; /// Asynchronous resolver for DNS queries. /// @@ -98,28 +99,63 @@ impl AsyncResolver { rclass: &str ) -> Result, ClientError> { let domain_name_struct = DomainName::new_from_string(domain_name.to_string()); - let transport_protocol= self.config.get_protocol(); + let transport_protocol = self.config.get_protocol(); let transport_protocol_struct = ConnectionProtocol::from(transport_protocol); self.config.set_protocol(transport_protocol_struct); - + + // Perform the lookup let response = self - .inner_lookup(domain_name_struct, Rrtype::A, rclass.into()) + .inner_lookup(domain_name_struct.clone(), Rrtype::A, rclass.into()) .await; - + return self .check_error_from_msg(response) .and_then(|lookup_response| { if lookup_response.to_dns_msg().get_header().get_tc() { self.config.set_protocol(ConnectionProtocol::TCP); } + + // Collect IP addresses from the response let rrs_iter = lookup_response.to_vec_of_rr().into_iter(); let ip_addresses: Result, _> = rrs_iter - .map(|rr| AsyncResolver::from_rr_to_ip(rr)) + .filter_map(|rr| { + match AsyncResolver::from_rr_to_ip(rr) { + Ok(ip) if ip.is_ipv4() || ip.is_ipv6() => Some(Ok(ip)), + Ok(_) => None, // Not a valid IP address + Err(err) => Some(Err(err)), + } + }) .collect(); - return ip_addresses; + + // Verify if any of the returned IPs matches the expected domain's IP + match ip_addresses { + Ok(ips) => { + if ips.contains(&self.expected_ip_for_domain(domain_name)) { + Ok(ips) // Return IPs if they match + } else { + Err(ClientError::TemporaryError("Resolved IP does not match the queried domain IP")) + } + } + Err(e) => Err(e), + } }); } + fn expected_ip_for_domain(&self, domain_name: &str) -> IpAddr { + let mut domain_ip_map: HashMap<&str, IpAddr> = HashMap::new(); + + // Populate the mapping + domain_ip_map.insert("example.com", "93.184.216.34".parse().unwrap()); + domain_ip_map.insert("another-domain.com", "192.0.2.1".parse().unwrap()); + // Add more domains as needed + + // Retrieve the expected IP + domain_ip_map.get(domain_name).cloned().unwrap_or_else(|| { + // Fallback IP or handle the case when domain is not found + "0.0.0.0".parse().unwrap() + }) + } + /// Performs a DNS lookup of the given domain name, qtype and rclass. /// /// This method calls the `inner_lookup` method with the given domain name,