Added basic whois support
This commit is contained in:
1 parent
01d309fd78
commit
670eb3937f
7 files changed
+1572
-37
No files matched your search
+29
-29
@@ -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
@@ -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
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user