Added basic whois support

This commit is contained in:
benjamyn committed 2024-03-23 19:02:23 +11:00
1 parent 01d309fd78
commit 670eb3937f
7 files changed
+1572 -37

No files matched your search

+29 -29
View File
@@ -1,6 +1,6 @@
use hickory_resolver::config::*;
use hickory_resolver::proto::rr::rdata::*;
use hickory_resolver::Resolver;
use hickory_resolver::config::*;
use core::fmt;
@@ -8,7 +8,7 @@ use crate::config::Config;
// #[derive(Debug)]
pub struct Domain {
domain_name: String,
pub domain_name: String,
subdomains: Vec<Domain>,
a_records: Vec<A>,
aaaa_records: Vec<AAAA>,
@@ -84,29 +84,29 @@ impl Domain {
}
pub fn lookup_all_records(&mut self) {
// Lookup A records
self.lookup_a();
// Lookup A records
self.lookup_a();
// Lookup AAAA records
// Lookup AAAA records
self.lookup_aaaa();
// Lookup MX records
self.lookup_mx();
// Lookup MX records
self.lookup_mx();
// Lookup TXT records
self.lookup_txt();
// Lookup TXT records
self.lookup_txt();
// Lookup TXT records
self.lookup_ns();
// Lookup TXT records
self.lookup_ns();
// Lookup TXT records
self.lookup_soa();
// Lookup TXT records
self.lookup_soa();
// Do subdomains?
for subdomain in &mut self.subdomains {
// println!("Looking up subdomain: {}", subdomain.domain_name);
subdomain.lookup_all_records();
}
// Do subdomains?
for subdomain in &mut self.subdomains {
// println!("Looking up subdomain: {}", subdomain.domain_name);
subdomain.lookup_all_records();
}
}
fn lookup_a(&mut self) {
@@ -116,8 +116,8 @@ impl Domain {
for entry in rec {
self.a_records.push(entry);
}
},
Err(_err) => {},
}
Err(_err) => {}
}
}
@@ -128,7 +128,7 @@ impl Domain {
for entry in rec {
self.aaaa_records.push(entry);
}
},
}
Err(_err) => {} // Log error
}
}
@@ -140,8 +140,8 @@ impl Domain {
for entry in rec {
self.mx_records.push(entry);
}
},
Err(_err) => {},
}
Err(_err) => {}
}
}
@@ -152,8 +152,8 @@ impl Domain {
for entry in rec {
self.txt_records.push(entry);
}
},
Err(_err) => {},
}
Err(_err) => {}
}
}
@@ -164,8 +164,8 @@ impl Domain {
for entry in rec {
self.ns_records.push(entry);
}
},
Err(_err) => {},
}
Err(_err) => {}
}
}
@@ -176,8 +176,8 @@ impl Domain {
for entry in rec {
self.soa_records.push(entry);
}
},
Err(_err) => {},
}
Err(_err) => {}
}
}
}
+5 -4
View File
@@ -4,14 +4,15 @@ use crate::domain::Domain;
mod config;
use crate::config::Config;
mod whois;
use crate::whois::WhoisData;
fn main() {
let mut test = Domain::new("benjamyn.love".to_string());
let mut test = Domain::new("ventraip.com.au".to_string());
let config = Config::from_file("test.ini".to_string());
test.apply_config(&config);
test.lookup_all_records();
let whois = WhoisData::new(test.domain_name.clone());
println!("{}", test);
println!("Domain: {}\n{}", test.domain_name.clone(), whois);
}
+169
View File
@@ -0,0 +1,169 @@
use core::fmt;
use hickory_resolver::{proto::rr::rdata::name, Name};
use regex::Regex;
use std::fmt::Write as _;
use whois_rust::{WhoIs, WhoIsLookupOptions};
#[derive(Debug)]
enum RegistrantType {
Registrant,
Admin,
Tech,
Billing,
}
struct RegexQuery {
re: Regex,
}
impl RegexQuery {
fn new(expression: String) -> RegexQuery {
let re = Regex::new(&expression).unwrap();
RegexQuery { re }
}
fn get_matches(&self, haystack: &str) -> Vec<String> {
let mut results = vec![];
for (_, [_, rex2]) in self.re.captures_iter(haystack).map(|c| c.extract()) {
results.push(String::from(rex2.trim()));
}
results
}
}
#[derive(Debug)]
struct NameServer {
host: String,
}
impl NameServer {
fn new(host: String) -> NameServer {
NameServer { host }
}
}
#[derive(Debug)]
struct Registrant {
name: String,
org: String,
email: String,
rtype: RegistrantType,
}
impl fmt::Display for Registrant {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "")
}
}
impl Registrant {
fn new(name: String, org: String, email: String, rtype: RegistrantType) -> Registrant {
Registrant {
name,
org,
email,
rtype,
}
}
}
pub struct WhoisData {
registrar: String,
domain_status: String,
registrant: Vec<Registrant>,
nameservers: Vec<NameServer>,
dnssec: String,
}
impl fmt::Display for WhoisData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Registrar: {}\nStatus: {}\nRegistrant: {:?}\nNameservers: {:?}\nDNSSEC: {}",
self.registrar, self.domain_status, self.registrant, self.nameservers, self.dnssec
)
}
}
impl WhoisData {
pub fn new(domain: String) -> WhoisData {
let whois = WhoIs::from_path("servers.json").unwrap();
let result: String = whois
.lookup(WhoIsLookupOptions::from_string(domain).unwrap())
.unwrap();
let registrar_regex = RegexQuery::new(String::from(r"(?i)(.*registrar:)(.*)"));
let domain_status_regex = RegexQuery::new(String::from(r"(?i)(.*domain status:)(.*)"));
// TODO: Capture the registrant info for each type
let registrant_name_regex = RegexQuery::new(String::from(r"(?i)(registrant name:)(.*)"));
let registrant_org_regex = RegexQuery::new(String::from(r"(?i)(registrant org.*:)(.*)"));
let registrant_email_regex = RegexQuery::new(String::from(r"(?i)(registrant email:)(.*)"));
let nameserver_regex =
RegexQuery::new(String::from(r"(?i)(nameservers*:|name servers*:)(.*)"));
let dnssec_regex = RegexQuery::new(String::from(r"(?i)(.*dnssec:)(.*)"));
let registrar_caps = registrar_regex.get_matches(&result);
let registrar: String;
match registrar_caps.get(0) {
Some(reg) => {
registrar = reg.to_string();
}
None => {
registrar = String::from("None");
}
}
let domain_status = domain_status_regex.get_matches(&result);
let reg_name_caps = registrant_name_regex.get_matches(&result);
let reg_name: String;
match reg_name_caps.get(0) {
Some(name) => {
reg_name = name.to_string();
}
None => {
reg_name = String::from("None");
}
}
let reg_org_caps = registrant_org_regex.get_matches(&result);
let reg_org: String;
match reg_org_caps.get(0) {
Some(org) => {
reg_org = org.to_string();
}
None => {
reg_org = String::from("None");
}
}
let reg_email_caps = registrant_email_regex.get_matches(&result);
let reg_email: String;
match reg_email_caps.get(0) {
Some(email) => {
reg_email = email.to_string();
}
None => {
reg_email = String::from("None");
}
}
let mut nameservers = vec![];
for nameserver in nameserver_regex.get_matches(&result) {
nameservers.push(NameServer::new(nameserver));
}
let dnssec = dnssec_regex.get_matches(&result);
// println!("{:?}", registrar[0]);
WhoisData {
registrar: registrar.clone(),
domain_status: domain_status[0].clone(),
registrant: vec![Registrant::new(
reg_name.clone(),
reg_org.clone(),
reg_email,
RegistrantType::Registrant,
)],
nameservers: nameservers,
dnssec: dnssec[0].clone(),
}
}
}