Add tests for rustscan scripting engine (#286) (#289)

* Add tests for rustscan scripting engine (#286)

* Increase test coverage

* Add more scripting tests

Co-authored-by: Bee <[email protected]>
This commit is contained in:
OskarandBee authored and GitHub committed 2020-10-17 23:43:03 +01:00
1 parent 172ad63553
commit 859eb0e83a
8 files changed
+130 -4

No files matched your search

File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -4,6 +4,6 @@
#ports_separator = ","
#call_format = "nmap -vvv -p {{port}} {{ip}}"
# Sriptfile parser stops at the first blank line with parsing.
# Scriptfile parser stops at the first blank line with parsing.
# This script will run the system installed nmap, ports will be concatenated with "," .
# Unused field: trigger_port = "80"
@@ -0,0 +1,7 @@
#!intentional_blank_line
#tags = "core_approved"
#developer = [ "example", "https://example.org" ]
#ports_separator = ","
#call_format = "nmap -vvv -p {{port}} {{ip}}"
# tags has to be an array, thus this file won't be parsed
+3 -3
View File
@@ -6,9 +6,9 @@ tags = ["core_approved", "example"]
# If it's present then only those scripts will run which has a tag ports = "80". Not yet implemented.
#
# ex.:
# ports = [80]
# ports = [80,81,8080]
ports = [80]
# ports = ["80"]
# ports = ["80","81","8080"]
ports = ["80"]
# Only this developer(s) scripts to run. Not yet implemented.
developer = ["example"]
+118
View File
@@ -60,6 +60,7 @@ ports_separator = ","
call_format = "nmap -vvv -p {{port}} {{ip}}"
"#;
#[cfg(not(tarpaulin_include))]
pub fn init_scripts(scripts: ScriptsRequired) -> Result<Vec<ScriptFile>> {
let mut scripts_to_run: Vec<ScriptFile> = Vec::new();
@@ -350,3 +351,120 @@ impl ScriptConfig {
Ok(config)
}
}
#[cfg(test)]
mod tests {
use super::{find_scripts, parse_scripts, Script, ScriptFile};
// Function for testing only, it inserts static values into ip and open_ports
// Doesn't use impl in case it's implemented in the super module at some point
fn into_script(script_f: ScriptFile) -> Script {
Script::build(
script_f.path,
"127.0.0.1".parse().unwrap(),
vec![80, 8080],
script_f.port,
script_f.ports_separator,
script_f.tags,
script_f.call_format,
)
}
#[test]
fn find_and_parse_scripts() {
let scripts = find_scripts("fixtures/".into()).unwrap();
let scripts = parse_scripts(scripts);
assert_eq!(scripts.len(), 4);
}
#[test]
#[should_panic]
fn find_invalid_folder() {
let scripts = find_scripts("Cargo.toml".into()).unwrap();
}
#[test]
#[should_panic]
fn open_script_file_invalid_headers() {
ScriptFile::new("fixtures/.rustscan_scripts/test_script_invalid_headers.txt".into())
.unwrap();
}
#[test]
#[should_panic]
fn open_script_file_invalid_call_format() {
let mut script_f =
ScriptFile::new("fixtures/.rustscan_scripts/test_script.txt".into()).unwrap();
script_f.call_format = Some("qwertyuiop".to_string());
let script: Script = into_script(script_f);
let output = script.run().unwrap();
}
#[test]
#[should_panic]
fn open_script_file_missing_call_format() {
let mut script_f =
ScriptFile::new("fixtures/.rustscan_scripts/test_script.txt".into()).unwrap();
script_f.call_format = None;
let script: Script = into_script(script_f);
let output = script.run().unwrap();
}
#[test]
#[should_panic]
fn open_nonexisting_script_file() {
ScriptFile::new("qwertyuiop.txt".into()).unwrap();
}
#[test]
fn parse_txt_script() {
let script_f =
ScriptFile::new("fixtures/.rustscan_scripts/test_script.txt".into()).unwrap();
assert_eq!(
script_f.tags,
Some(vec!["core_approved".to_string(), "example".to_string()])
);
assert_eq!(
script_f.developer,
Some(vec![
"example".to_string(),
"https://example.org".to_string()
])
);
assert_eq!(script_f.ports_separator, Some(",".to_string()));
assert_eq!(
script_f.call_format,
Some("nmap -vvv -p {{port}} {{ip}}".to_string())
);
}
#[test]
fn run_bash_script() {
let script_f = ScriptFile::new("fixtures/.rustscan_scripts/test_script.sh".into()).unwrap();
let script: Script = into_script(script_f);
let output = script.run().unwrap();
// output has a newline at the end by default, .trim() trims it
assert_eq!(output.trim(), "127.0.0.1 80,8080");
}
#[test]
fn run_python_script() {
let script_f = ScriptFile::new("fixtures/.rustscan_scripts/test_script.py".into()).unwrap();
let script: Script = into_script(script_f);
let output = script.run().unwrap();
// output has a newline at the end by default, .trim() trims it
assert_eq!(
output.trim(),
"Python script ran with arguments ['fixtures/.rustscan_scripts/test_script.py', '127.0.0.1', '80,8080']"
);
}
#[test]
fn run_perl_script() {
let script_f = ScriptFile::new("fixtures/.rustscan_scripts/test_script.pl".into()).unwrap();
let script: Script = into_script(script_f);
let output = script.run().unwrap();
// output has a newline at the end by default, .trim() trims it
assert_eq!(output.trim(), "Total args passed to fixtures/.rustscan_scripts/test_script.pl : 2\nArg # 1 : 127.0.0.1\nArg # 2 : 80,8080");
}
}
+1
View File
@@ -13,6 +13,7 @@ use wait_timeout::ChildExt;
const TIMEOUT_MARGIN: u32 = 3;
#[cfg(not(tarpaulin_include))]
fn run_rustscan_with_timeout(args: &[&str], timeout: Duration) {
println!("Running: target/debug/rustscan: {}", args.join(" "));