1mod http;
2mod uri;
3mod domain;
4mod status;
5
6use std::time::{Duration, Instant};
7use std::collections::HashMap;
8use std::sync::{Mutex, Arc};
9use std::sync::mpsc::{channel ,Sender, Receiver};
10use tokio::time::{timeout};
11
12pub use status::ScanStatus;
13pub use http::{RequestMethod, ResponseStatus};
14
15#[derive(Clone)]
19pub struct UriScanner {
20 base_uri: String,
22 word_list: Vec<String>,
24 request_method: RequestMethod,
26 timeout: Duration,
28 accept_invalid_certs: bool,
30 scan_result: UriScanResult,
32 content_list: Vec<Vec<u8>>,
34 tx: Arc<Mutex<Sender<String>>>,
36 rx: Arc<Mutex<Receiver<String>>>,
38}
39
40#[derive(Clone)]
44pub struct DomainScanner {
45 base_domain: String,
47 word_list: Vec<String>,
49 timeout: Duration,
51 scan_result: DomainScanResult,
53 tx: Arc<Mutex<Sender<String>>>,
55 rx: Arc<Mutex<Receiver<String>>>,
57}
58
59#[derive(Clone)]
61pub struct UriScanResult {
62 pub responses: HashMap<String, ResponseStatus>,
66 pub scan_time: Duration,
68 pub scan_status: ScanStatus,
70}
71
72#[derive(Clone)]
74pub struct DomainScanResult {
75 pub domain_map: HashMap<String, Vec<String>>,
79 pub scan_time: Duration,
81 pub scan_status: ScanStatus,
83}
84
85impl UriScanner{
86 pub fn new() -> Result<UriScanner, String> {
88 let ini_scan_result = UriScanResult{
89 responses: HashMap::new(),
90 scan_time: Duration::from_millis(0),
91 scan_status: ScanStatus::Ready,
92 };
93 let (tx, rx) = channel();
94 let uri_scanner = UriScanner{
95 base_uri: String::new(),
96 word_list: vec![],
97 request_method: RequestMethod::Head,
98 timeout: Duration::from_millis(30000),
99 accept_invalid_certs: false,
100 scan_result: ini_scan_result,
101 content_list: vec![],
102 tx: Arc::new(Mutex::new(tx)),
103 rx: Arc::new(Mutex::new(rx)),
104 };
105 Ok(uri_scanner)
106 }
107 pub fn set_base_uri(&mut self, base_uri: String) {
109 self.base_uri = base_uri;
110 }
111 pub fn add_word(&mut self, word: String) {
113 if word.len() != 0 { self.word_list.push(word) }
114 }
115 pub fn set_request_method(&mut self, method: RequestMethod) {
117 self.request_method = method;
118 }
119 pub fn set_timeout(&mut self, timeout: Duration){
121 self.timeout = timeout;
122 }
123 pub fn set_accept_invalid_certs(&mut self, accept: bool) {
125 self.accept_invalid_certs = accept;
126 }
127 pub fn add_content(&mut self, content: Vec<u8>) {
129 if content.len() != 0 { self.content_list.push(content) }
130 }
131 pub async fn run_scan(&mut self){
135 let start_time = Instant::now();
136 let res = timeout(self.timeout, uri::scan_uri(&self.base_uri, &self.word_list, &self.request_method, self.accept_invalid_certs, &self.content_list, &self.tx)).await;
137 match res {
138 Ok(responses) => {
139 self.scan_result.responses = responses;
140 self.scan_result.scan_status = ScanStatus::Done;
141 },
142 Err(_) => {
143 self.scan_result.scan_status = ScanStatus::Timeout;
144 },
145 }
146 self.scan_result.scan_time = Instant::now().duration_since(start_time);
148 }
149 pub fn get_result(&mut self) -> UriScanResult{
151 return self.scan_result.clone();
152 }
153 pub async fn scan(&mut self) -> UriScanResult {
155 self.run_scan().await;
156 self.scan_result.clone()
157 }
158 pub fn get_progress_receiver(&self) -> Arc<Mutex<Receiver<String>>> {
160 self.rx.clone()
161 }
162}
163
164impl DomainScanner {
165 pub fn new() -> Result<DomainScanner, String> {
167 let ini_scan_result = DomainScanResult {
168 domain_map: HashMap::new(),
169 scan_time: Duration::from_millis(0),
170 scan_status: ScanStatus::Ready,
171 };
172 let (tx, rx) = channel();
173 let domain_scanner = DomainScanner {
174 base_domain: String::new(),
175 word_list: vec![],
176 timeout: Duration::from_millis(30000),
177 scan_result: ini_scan_result,
178 tx: Arc::new(Mutex::new(tx)),
179 rx: Arc::new(Mutex::new(rx)),
180 };
181 Ok(domain_scanner)
182 }
183 pub fn set_base_domain(&mut self, base_domain: String) {
185 self.base_domain = base_domain;
186 }
187 pub fn add_word(&mut self, word: String) {
189 self.word_list.push(word);
190 }
191 pub fn set_timeout(&mut self, timeout: Duration){
193 self.timeout = timeout;
194 }
195 pub async fn run_scan(&mut self){
199 let start_time = Instant::now();
200 let res = timeout(self.timeout, domain::scan_domain(&self.base_domain, &self.word_list, &self.tx)).await;
201 match res {
202 Ok(domain_map) => {
203 self.scan_result.domain_map = domain_map;
204 self.scan_result.scan_status = ScanStatus::Done;
205 },
206 Err(_) => {
207 self.scan_result.scan_status = ScanStatus::Timeout;
208 },
209 }
210 self.scan_result.scan_time = Instant::now().duration_since(start_time);
212 }
213 pub fn get_result(&mut self) -> DomainScanResult{
215 return self.scan_result.clone();
216 }
217 pub async fn scan(&mut self) -> DomainScanResult {
219 self.run_scan().await;
220 self.scan_result.clone()
221 }
222 pub fn get_progress_receiver(&self) -> Arc<Mutex<Receiver<String>>> {
224 self.rx.clone()
225 }
226}