diff --git a/src/async_resolver.rs b/src/async_resolver.rs index 1436a8b0..b0c0d9cb 100644 --- a/src/async_resolver.rs +++ b/src/async_resolver.rs @@ -16,10 +16,13 @@ use crate::message::rcode::Rcode; use crate::message::rdata::Rdata; use crate::message::resource_record::ResourceRecord; use crate::message::rrtype::Rrtype; +use crate::tsig; use crate::message::{self, DnsMessage}; use crate::resolver_cache::ResolverCache; use std::net::IpAddr; +use std::time::SystemTime; use std::sync::{Arc, Mutex}; +use std::vec; /// Asynchronous resolver for DNS queries. /// @@ -165,6 +168,11 @@ impl AsyncResolver { Rclass::from(rclass), ) .await; + + + if self.config.get_tsig(){ + self.verify_tsig(response.clone()); + } return self.check_error_from_msg(response); } @@ -413,6 +421,44 @@ impl AsyncResolver { _ => Err(ClientError::ResponseError(rcode.into()))?, } } + + /// Verifies tsig + pub fn verify_tsig(&self, + response: Result) + -> Result { + let lookup_response = match response { + Ok(val) => Ok(val), + Err(_) => Err(ClientError::TemporaryError("no DNS message found")), + }; + + let dns_response = lookup_response.unwrap().to_dns_msg(); + + let key_bytes = self.config.get_key(); + let shared_key_name = self.config.get_key_name(); + let time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(); + let algorithm = String::from(self.config.get_algorithm()); + let alg_list = vec![(algorithm, true)]; + let mac = dns_response.get_mac(); + + let (_val, rcode) = tsig::process_tsig( + &dns_response, + &key_bytes, + shared_key_name.clone().unwrap(), + time, + alg_list, + mac, + ); + + match rcode { + Rcode::NOERROR => Ok(LookupResponse::new(dns_response)), + Rcode::FORMERR => Err(ClientError::FormatError("The name server was unable to interpret the query."))?, + Rcode::SERVFAIL => Err(ClientError::ServerFailure("The name server was unable to process this query due to a problem with the name server."))?, + Rcode::NXDOMAIN => Err(ClientError::NameError("The domain name referenced in the query does not exist."))?, + Rcode::NOTIMP => Err(ClientError::NotImplemented("The name server does not support the requested kind of query."))?, + Rcode::REFUSED => Err(ClientError::Refused("The name server refuses to perform the specified operation for policy reasons."))?, + _ => Err(ClientError::ResponseError(rcode.into()))?, + } + } } // Getters