use core::fmt; use regex::Regex; 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 { 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, nameservers: Vec, 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:|registrar *name:)(.*)")); let domain_status_regex = RegexQuery::new(String::from(r"(?i)(.*domain status:|.*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.*:|registrant:)(.*)")); 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_caps = domain_status_regex.get_matches(&result); let domain_status: String; match domain_status_caps.get(0) { Some(status) => { domain_status = status.to_string(); } None => { domain_status = String::from("None"); } } 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.clone(), registrant: vec![Registrant::new( reg_name.clone(), reg_org.clone(), reg_email, RegistrantType::Registrant, )], nameservers: nameservers, dnssec: dnssec[0].clone(), } } }