use super::{ScanContext, ScanPhase};
use crate::protocols::tester::ProtocolTester;
use crate::{Args, Result};
use async_trait::async_trait;
pub struct ProtocolPhase;
impl ProtocolPhase {
pub fn new() -> Self {
Self
}
fn configure_tester(&self, context: &ScanContext) -> ProtocolTester {
let target = context.target();
let mut tester = if let Some(ref mtls_config) = context.mtls_config {
ProtocolTester::with_mtls(target.clone(), mtls_config.clone())
} else {
ProtocolTester::new(target.clone())
};
if context.args.starttls.rdp {
tester = tester.with_rdp(true);
}
if context.args.tls.bugs {
tester = tester.with_bugs_mode(true);
}
if let Some(starttls_proto) = context.args.starttls_protocol() {
tester = tester.with_starttls(Some(starttls_proto));
}
if let Some(ref sni) = context.args.tls.sni_name {
tester = tester.with_sni(Some(sni.clone()));
}
if let Some(protocols) = context.args.protocols_to_test() {
tester = tester.with_protocol_filter(Some(protocols));
}
if context.args.network.test_all_ips {
tester = tester.with_test_all_ips(true);
}
tester
}
}
impl Default for ProtocolPhase {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl ScanPhase for ProtocolPhase {
fn name(&self) -> &'static str {
"Testing SSL/TLS Protocols"
}
fn should_run(&self, args: &Args) -> bool {
args.scan.protocols || args.scan.all || args.target.is_some()
}
async fn execute(&self, context: &mut ScanContext) -> Result<()> {
let tester = self.configure_tester(context);
let protocol_results = tester.test_all_protocols().await?;
context.results.protocols = protocol_results;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
#[test]
fn test_protocol_phase_should_run() {
let phase = ProtocolPhase::new();
let mut args = Args::default();
args.scan.protocols = true;
assert!(phase.should_run(&args));
let mut args = Args::default();
args.scan.all = true;
assert!(phase.should_run(&args));
let mut args = Args::default();
args.target = Some("example.com".to_string());
assert!(phase.should_run(&args));
let args = Args::default();
assert!(!phase.should_run(&args));
}
#[test]
fn test_protocol_phase_name() {
let phase = ProtocolPhase::new();
assert_eq!(phase.name(), "Testing SSL/TLS Protocols");
}
}