Changed whois system to trait based system
This commit is contained in:
parent
9d71ba17a5
commit
4515f35181
47
Cargo.lock
generated
47
Cargo.lock
generated
@ -2,6 +2,17 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr"
|
||||
version = "0.15.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a93b8a41dbe230ad5087cc721f8d41611de654542180586b315d9f4cf6b72bef"
|
||||
dependencies = [
|
||||
"psl",
|
||||
"psl-types",
|
||||
"publicsuffix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
@ -308,6 +319,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
|
||||
name = "dns_lookup_project"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"chrono",
|
||||
"configparser",
|
||||
"crossterm",
|
||||
@ -563,6 +575,16 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
@ -857,6 +879,21 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psl"
|
||||
version = "2.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe63c1c8bb438205c1245719638a0b14fe6e3b33f4406ac36b4770a706655345"
|
||||
dependencies = [
|
||||
"psl-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psl-types"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
|
||||
|
||||
[[package]]
|
||||
name = "ptr_meta"
|
||||
version = "0.1.4"
|
||||
@ -877,6 +914,16 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "publicsuffix"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457"
|
||||
dependencies = [
|
||||
"idna 0.3.0",
|
||||
"psl-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
|
||||
13
Cargo.toml
13
Cargo.toml
@ -6,12 +6,13 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
configparser = "3.0.4"
|
||||
crossterm = "0.27.0"
|
||||
configparser = "*"
|
||||
crossterm = "*"
|
||||
hickory-resolver = { version = "0.24.0" }
|
||||
ratatui = "0.26.1"
|
||||
regex = "1.10.3"
|
||||
whois-rust = "1.6.0"
|
||||
ratatui = "*"
|
||||
regex = "*"
|
||||
whois-rust = "*"
|
||||
serde = { version = "*", features = ["derive"] }
|
||||
serde_json = "*"
|
||||
chrono = "0.4.37"
|
||||
chrono = "*"
|
||||
addr = { version = "0.15.6", features = ["publicsuffix"] }
|
||||
|
||||
@ -25,7 +25,6 @@ pub struct App {
|
||||
pub current_state: CurrentState,
|
||||
pub menu_state: MenuState,
|
||||
pub config: Config,
|
||||
pub state: ListState,
|
||||
}
|
||||
|
||||
impl App {
|
||||
@ -38,7 +37,6 @@ impl App {
|
||||
current_state: CurrentState::Lookup,
|
||||
menu_state: MenuState::Main,
|
||||
config: Config::from_file("test.ini".to_string()),
|
||||
state: ListState::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,9 +53,9 @@ impl fmt::Display for Domain {
|
||||
}
|
||||
|
||||
impl Domain {
|
||||
pub fn new(domain: String) -> Domain {
|
||||
pub fn new(domain: &String) -> Domain {
|
||||
Domain {
|
||||
domain_name: domain,
|
||||
domain_name: String::from(domain),
|
||||
subdomains: vec![],
|
||||
a_records: vec![],
|
||||
aaaa_records: vec![],
|
||||
@ -116,7 +116,7 @@ impl Domain {
|
||||
let mut new_domain = String::from(subdomain);
|
||||
new_domain.push_str(".");
|
||||
new_domain.push_str(&self.domain_name);
|
||||
let subdomain = Domain::new(new_domain);
|
||||
let subdomain = Domain::new(&new_domain);
|
||||
self.subdomains.push(subdomain);
|
||||
// println!("Added: {}", new_domain);
|
||||
}
|
||||
|
||||
20
src/main.rs
20
src/main.rs
@ -4,9 +4,6 @@ use crate::domain::Domain;
|
||||
mod config;
|
||||
use crate::config::Config;
|
||||
|
||||
mod whois;
|
||||
use crate::whois::WhoisData;
|
||||
|
||||
mod app;
|
||||
use crate::app::*;
|
||||
|
||||
@ -16,6 +13,10 @@ use crate::ui::*;
|
||||
mod fsutil;
|
||||
use crate::fsutil::*;
|
||||
|
||||
mod whois;
|
||||
use whois::default;
|
||||
use whois::selector::*;
|
||||
|
||||
use crossterm::event::{
|
||||
self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind,
|
||||
};
|
||||
@ -78,12 +79,19 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: &mut App) -> io::Result<
|
||||
// Ignore empty input
|
||||
continue;
|
||||
}
|
||||
let mut domain = Domain::new(app.domain_input.clone());
|
||||
let mut domain = Domain::new(&app.domain_input);
|
||||
domain.apply_config(&app.config);
|
||||
domain.lookup_all_records();
|
||||
app.dns_info = domain.to_vec();
|
||||
let whois = WhoisData::new(app.domain_input.clone());
|
||||
app.whois_info = whois.to_vec();
|
||||
let whois_server = select_whois_server(app.domain_input.clone());
|
||||
match whois_server {
|
||||
Ok(mut whois_data) => {
|
||||
app.whois_info = whois_data.lookup(app.domain_input.clone());
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
// let whois = WhoisData::new(app.domain_input.clone());
|
||||
// app.whois_info = whois.to_vec();
|
||||
}
|
||||
KeyCode::Delete => {
|
||||
app.domain_input = String::new();
|
||||
|
||||
65
src/ui.rs
65
src/ui.rs
@ -1,9 +1,10 @@
|
||||
use ratatui::{
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
prelude::*,
|
||||
style::{Color, Modifier, Style, Styled},
|
||||
text::{Line, Span, Text},
|
||||
widgets::{
|
||||
Block, Borders, Clear, HighlightSpacing, List, ListDirection, ListItem, ListState,
|
||||
Block, Borders, Clear, HighlightSpacing, List, ListDirection, ListItem, ListState, Padding,
|
||||
Paragraph, Wrap,
|
||||
},
|
||||
Frame,
|
||||
@ -14,6 +15,61 @@ use crate::{
|
||||
CurrentState, DomainData, MenuState,
|
||||
};
|
||||
|
||||
struct StatefulList<'a> {
|
||||
state: ListState,
|
||||
items: Vec<ListItem<'a>>,
|
||||
last_selected: Option<usize>,
|
||||
}
|
||||
|
||||
impl StatefulList<'_> {
|
||||
fn with_items<'a>(items: Vec<String>) -> StatefulList<'a> {
|
||||
let mut veclist = Vec::<ListItem>::new();
|
||||
for item in items {
|
||||
veclist.push(ListItem::new(Line::from(item)));
|
||||
}
|
||||
StatefulList {
|
||||
state: ListState::default(),
|
||||
items: veclist,
|
||||
last_selected: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self) {
|
||||
let i = match self.state.selected() {
|
||||
Some(i) => {
|
||||
if i >= self.items.len() - 1 {
|
||||
0
|
||||
} else {
|
||||
i + 1
|
||||
}
|
||||
}
|
||||
None => self.last_selected.unwrap_or(0),
|
||||
};
|
||||
self.state.select(Some(i));
|
||||
}
|
||||
|
||||
fn previous(&mut self) {
|
||||
let i = match self.state.selected() {
|
||||
Some(i) => {
|
||||
if i == 0 {
|
||||
self.items.len() - 1
|
||||
} else {
|
||||
i - 1
|
||||
}
|
||||
}
|
||||
None => self.last_selected.unwrap_or(0),
|
||||
};
|
||||
self.state.select(Some(i));
|
||||
}
|
||||
|
||||
fn unselect(&mut self) {
|
||||
let offset = self.state.offset();
|
||||
self.last_selected = self.state.selected();
|
||||
self.state.select(None);
|
||||
*self.state.offset_mut() = offset;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ui(f: &mut Frame, app: &mut App) {
|
||||
if f.size().width > 100 {
|
||||
app.render_direction = AppRenderDir::Horizontal;
|
||||
@ -44,11 +100,12 @@ pub fn ui(f: &mut Frame, app: &mut App) {
|
||||
|
||||
let title_block = Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default());
|
||||
.style(Style::default())
|
||||
.padding(Padding::horizontal(2));
|
||||
|
||||
let title = Paragraph::new(Span::styled(
|
||||
"Dns Lookup tool",
|
||||
Style::default().fg(Color::White),
|
||||
Style::default().fg(Color::Yellow),
|
||||
))
|
||||
.block(title_block);
|
||||
|
||||
@ -277,7 +334,7 @@ pub fn ui(f: &mut Frame, app: &mut App) {
|
||||
.highlight_symbol(">>")
|
||||
.highlight_spacing(HighlightSpacing::Always)
|
||||
.repeat_highlight_symbol(true);
|
||||
f.render_stateful_widget(items, chunks[1], &mut app.state);
|
||||
// f.render_stateful_widget(items, chunks[1], &mut app.state);
|
||||
|
||||
let footer_block = Block::new().borders(Borders::ALL).style(Style::default());
|
||||
|
||||
|
||||
23
src/whois/au.rs
Normal file
23
src/whois/au.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::whois::whois_base::{
|
||||
NameServer, RegexQuery, Registrant, RegistrantType, Whois, WhoisData,
|
||||
};
|
||||
use whois_rust::{WhoIs, WhoIsLookupOptions};
|
||||
pub struct _Whois {
|
||||
base: WhoisData,
|
||||
elegibility: String,
|
||||
}
|
||||
|
||||
impl Whois for _Whois {
|
||||
fn new() -> Self {
|
||||
_Whois {
|
||||
base: WhoisData::new(),
|
||||
elegibility: String::new(),
|
||||
}
|
||||
}
|
||||
fn to_vec(&self) -> Vec<String> {
|
||||
vec![String::new()]
|
||||
}
|
||||
fn lookup(&mut self, domain: String) -> Vec<String> {
|
||||
self.to_vec()
|
||||
}
|
||||
}
|
||||
@ -1,168 +1,34 @@
|
||||
use core::fmt;
|
||||
use hickory_resolver::proto::{
|
||||
rr::{domain, rdata::name},
|
||||
xfer::dns_handle,
|
||||
use crate::whois::whois_base::{
|
||||
NameServer, RegexQuery, Registrant, RegistrantType, Whois, WhoisData,
|
||||
};
|
||||
use regex::Regex;
|
||||
use whois_rust::{WhoIs, WhoIsLookupOptions};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum RegistrantType {
|
||||
Registrant,
|
||||
Admin,
|
||||
Tech,
|
||||
Billing,
|
||||
pub struct _Whois {
|
||||
base: WhoisData,
|
||||
}
|
||||
|
||||
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, Clone)]
|
||||
struct NameServer {
|
||||
host: String,
|
||||
}
|
||||
|
||||
impl NameServer {
|
||||
fn new(host: String) -> NameServer {
|
||||
NameServer { host }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Eligibility {
|
||||
e_type: String,
|
||||
id: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
pub struct WhoisData {
|
||||
registrar: Option<String>,
|
||||
domain_status: Option<String>,
|
||||
registrant: Option<Vec<Registrant>>,
|
||||
nameservers: Option<Vec<NameServer>>,
|
||||
dnssec: Option<String>,
|
||||
eligibility_type: Option<Eligibility>,
|
||||
}
|
||||
|
||||
impl fmt::Display for WhoisData {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Registrar: {}\nStatus: {}\nRegistrant: {:?}\nNameservers: {:?}\nDNSSEC: {}",
|
||||
self.registrar.clone().unwrap(),
|
||||
self.domain_status.clone().unwrap(),
|
||||
self.registrant.clone().unwrap(),
|
||||
self.nameservers.clone().unwrap(),
|
||||
self.dnssec.clone().unwrap()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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 = WhoisData::return_regex(registrar_regex.get_matches(&result), 0);
|
||||
let domain_status = WhoisData::return_regex(domain_status_regex.get_matches(&result), 0);
|
||||
let reg_name = WhoisData::return_regex(registrant_name_regex.get_matches(&result), 0);
|
||||
let reg_org = WhoisData::return_regex(registrant_org_regex.get_matches(&result), 0);
|
||||
let reg_email = WhoisData::return_regex(registrant_email_regex.get_matches(&result), 0);
|
||||
|
||||
let mut nameservers = vec![];
|
||||
for nameserver in nameserver_regex.get_matches(&result) {
|
||||
nameservers.push(NameServer::new(nameserver));
|
||||
}
|
||||
let mut dnssec = dnssec_regex.get_matches(&result);
|
||||
if dnssec.len() == 0 {
|
||||
dnssec = vec![String::from("Failed to get DNSSEC")];
|
||||
}
|
||||
// println!("{:?}", registrar[0]);
|
||||
WhoisData {
|
||||
registrar: Some(registrar.clone()),
|
||||
domain_status: Some(domain_status.clone()),
|
||||
registrant: Some(vec![Registrant::new(
|
||||
reg_name.clone(),
|
||||
reg_org.clone(),
|
||||
reg_email,
|
||||
RegistrantType::Registrant,
|
||||
)]),
|
||||
nameservers: Some(nameservers),
|
||||
dnssec: Some(dnssec[0].clone()),
|
||||
eligibility_type: None,
|
||||
impl Whois for _Whois {
|
||||
fn new() -> _Whois {
|
||||
_Whois {
|
||||
base: WhoisData::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_vec(&self) -> Vec<String> {
|
||||
fn to_vec(&self) -> Vec<String> {
|
||||
let mut ret_vec: Vec<String> = vec![];
|
||||
let mut registrar = String::from("Registrar: ");
|
||||
registrar.push_str(&self.registrar.clone().unwrap());
|
||||
registrar.push_str(&self.base.registrar.clone().unwrap());
|
||||
ret_vec.push(registrar);
|
||||
|
||||
let mut domain_status = String::from("Status: ");
|
||||
domain_status.push_str(&self.domain_status.clone().unwrap());
|
||||
domain_status.push_str(&self.base.domain_status.clone().unwrap());
|
||||
ret_vec.push(domain_status);
|
||||
|
||||
let mut dnssec = String::from("DNSSEC: ");
|
||||
dnssec.push_str(&self.dnssec.clone().unwrap());
|
||||
dnssec.push_str(&self.base.dnssec.clone().unwrap());
|
||||
ret_vec.push(dnssec);
|
||||
|
||||
let mut registrant_type = String::new();
|
||||
for registrant in &self.registrant.clone().unwrap() {
|
||||
for registrant in &self.base.registrant.clone().unwrap() {
|
||||
match registrant.rtype {
|
||||
RegistrantType::Admin => {
|
||||
registrant_type.push_str("Admin ");
|
||||
@ -193,7 +59,7 @@ impl WhoisData {
|
||||
ret_vec.push(email);
|
||||
}
|
||||
|
||||
for nameserver in &self.nameservers.clone().unwrap() {
|
||||
for nameserver in &self.base.nameservers.clone().unwrap() {
|
||||
let mut tmp = String::from("Nameserver: ");
|
||||
tmp.push_str(&nameserver.host);
|
||||
ret_vec.push(tmp);
|
||||
@ -202,16 +68,50 @@ impl WhoisData {
|
||||
return ret_vec;
|
||||
}
|
||||
|
||||
fn return_regex(caps: Vec<String>, index: usize) -> String {
|
||||
let data: String;
|
||||
match caps.get(index) {
|
||||
Some(tmp) => {
|
||||
data = tmp.to_string();
|
||||
}
|
||||
None => {
|
||||
data = String::from("None");
|
||||
}
|
||||
fn lookup(&mut self, domain: String) -> Vec<String> {
|
||||
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 = WhoisData::return_regex(registrar_regex.get_matches(&result), 0);
|
||||
let domain_status = WhoisData::return_regex(domain_status_regex.get_matches(&result), 0);
|
||||
let reg_name = WhoisData::return_regex(registrant_name_regex.get_matches(&result), 0);
|
||||
let reg_org = WhoisData::return_regex(registrant_org_regex.get_matches(&result), 0);
|
||||
let reg_email = WhoisData::return_regex(registrant_email_regex.get_matches(&result), 0);
|
||||
|
||||
let mut nameservers = vec![];
|
||||
for nameserver in nameserver_regex.get_matches(&result) {
|
||||
nameservers.push(NameServer::new(nameserver));
|
||||
}
|
||||
data
|
||||
let mut dnssec = dnssec_regex.get_matches(&result);
|
||||
if dnssec.len() == 0 {
|
||||
dnssec = vec![String::from("Failed to get DNSSEC")];
|
||||
}
|
||||
// println!("{:?}", registrar[0]);
|
||||
self.base.domain_status = Some(domain_status.clone());
|
||||
self.base.registrant = Some(vec![Registrant::new(
|
||||
reg_name.clone(),
|
||||
reg_org.clone(),
|
||||
reg_email,
|
||||
RegistrantType::Registrant,
|
||||
)]);
|
||||
self.base.nameservers = Some(nameservers);
|
||||
self.base.dnssec = Some(dnssec[0].clone());
|
||||
self.base.registrar = Some(registrar.clone());
|
||||
|
||||
self.to_vec()
|
||||
}
|
||||
}
|
||||
4
src/whois/mod.rs
Normal file
4
src/whois/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
pub mod au;
|
||||
pub mod default;
|
||||
pub mod selector;
|
||||
pub mod whois_base;
|
||||
30
src/whois/selector.rs
Normal file
30
src/whois/selector.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use crate::whois::default;
|
||||
use addr::parse_domain_name;
|
||||
|
||||
use super::{au, whois_base::Whois};
|
||||
|
||||
pub fn select_whois_server(domain: String) -> Result<Box<dyn Whois>, String> {
|
||||
let domain = parse_domain_name(&domain.as_str());
|
||||
match domain {
|
||||
Ok(val) => match val.suffix() {
|
||||
".com.au" => Ok(Box::new(au::_Whois::new())),
|
||||
_ => Ok(Box::new(default::_Whois::new())),
|
||||
},
|
||||
Err(_) => Err(String::from("Failed to select whois server")),
|
||||
}
|
||||
}
|
||||
|
||||
// impl RegexQuery {
|
||||
// pub fn new(expression: String) -> RegexQuery {
|
||||
// let re = Regex::new(&expression).unwrap();
|
||||
// RegexQuery { re }
|
||||
// }
|
||||
|
||||
// pub 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
|
||||
// }
|
||||
// }
|
||||
104
src/whois/whois_base.rs
Normal file
104
src/whois/whois_base.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use core::fmt;
|
||||
use regex::Regex;
|
||||
|
||||
pub trait Whois {
|
||||
fn new() -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
fn lookup(&mut self, domain: String) -> Vec<String>;
|
||||
fn to_vec(&self) -> Vec<String>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum RegistrantType {
|
||||
Registrant,
|
||||
Admin,
|
||||
Tech,
|
||||
Billing,
|
||||
}
|
||||
|
||||
pub struct RegexQuery {
|
||||
re: Regex,
|
||||
}
|
||||
|
||||
impl RegexQuery {
|
||||
pub fn new(expression: String) -> RegexQuery {
|
||||
let re = Regex::new(&expression).unwrap();
|
||||
RegexQuery { re }
|
||||
}
|
||||
|
||||
pub 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, Clone)]
|
||||
pub struct NameServer {
|
||||
pub host: String,
|
||||
}
|
||||
|
||||
impl NameServer {
|
||||
pub fn new(host: String) -> NameServer {
|
||||
NameServer { host }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Registrant {
|
||||
pub name: String,
|
||||
pub org: String,
|
||||
pub email: String,
|
||||
pub rtype: RegistrantType,
|
||||
}
|
||||
|
||||
impl fmt::Display for Registrant {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "")
|
||||
}
|
||||
}
|
||||
|
||||
impl Registrant {
|
||||
pub fn new(name: String, org: String, email: String, rtype: RegistrantType) -> Registrant {
|
||||
Registrant {
|
||||
name,
|
||||
org,
|
||||
email,
|
||||
rtype,
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct WhoisData {
|
||||
pub registrar: Option<String>,
|
||||
pub domain_status: Option<String>,
|
||||
pub registrant: Option<Vec<Registrant>>,
|
||||
pub nameservers: Option<Vec<NameServer>>,
|
||||
pub dnssec: Option<String>,
|
||||
}
|
||||
|
||||
impl WhoisData {
|
||||
pub fn new() -> WhoisData {
|
||||
WhoisData {
|
||||
registrar: None,
|
||||
domain_status: None,
|
||||
registrant: None,
|
||||
nameservers: None,
|
||||
dnssec: None,
|
||||
}
|
||||
}
|
||||
pub fn return_regex(caps: Vec<String>, index: usize) -> String {
|
||||
let data: String;
|
||||
match caps.get(index) {
|
||||
Some(tmp) => {
|
||||
data = tmp.to_string();
|
||||
}
|
||||
None => {
|
||||
data = String::from("None");
|
||||
}
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user