2024-03-23 19:27:34 +11:00

180 lines
5.0 KiB
Rust

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<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:|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(),
}
}
}