diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml deleted file mode 100644 index 540435bdf..000000000 --- a/.github/workflows/markdown.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Check Markdown links - -on: - push: - branches: - - master - paths-ignore: - - '.github/**' - schedule: - # Run everyday at 9:00 AM (See https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07) - - cron: "0 9 * * *" - -jobs: - markdown-link-check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - uses: gaurav-nelson/github-action-markdown-link-check@v1 - with: - use-quiet-mode: 'yes' - config-file: './.github/workflows/mlc_config.json' \ No newline at end of file diff --git a/benches/benchmark_portscan.rs b/benches/benchmark_portscan.rs index 42fcd6cc5..d7c989b86 100644 --- a/benches/benchmark_portscan.rs +++ b/benches/benchmark_portscan.rs @@ -97,7 +97,7 @@ fn criterion_benchmark(c: &mut Criterion) { let mut address_group = c.benchmark_group("address parsing"); address_group.measurement_time(Duration::from_secs(10)); address_group.bench_function("parse addresses with exclusions", |b| { - b.iter(|| bench_address_parsing()) + b.iter(bench_address_parsing) }); address_group.finish(); } diff --git a/justfile b/justfile index 78c0171a5..d2e205a13 100644 --- a/justfile +++ b/justfile @@ -1,5 +1,5 @@ test: - cargo nextest run + cargo test cargo clippy -- --deny warnings cargo clippy --tests -- --deny warnings cargo fmt --check diff --git a/src/address.rs b/src/address.rs index 7d325ca61..f8fdb091a 100644 --- a/src/address.rs +++ b/src/address.rs @@ -418,17 +418,6 @@ mod tests { assert_eq!(ips.len(), 256); } - #[test] - fn resolver_default_cloudflare() { - let opts = Opts::default(); - - let resolver = get_resolver(&opts.resolver); - let lookup = resolver.lookup_ip("www.example.com.").unwrap(); - - assert!(opts.resolver.is_none()); - assert!(lookup.iter().next().is_some()); - } - #[test] fn resolver_args_google_dns() { // https://developers.google.com/speed/public-dns diff --git a/src/input.rs b/src/input.rs index 26605317a..8a08845af 100644 --- a/src/input.rs +++ b/src/input.rs @@ -113,7 +113,7 @@ pub struct Opts { /// it will do every port at the same time. Although, your OS may not /// support this. #[arg(short, long, default_value = "4500")] - pub batch_size: u16, + pub batch_size: usize, /// The timeout in milliseconds before a port is assumed to be closed. #[arg(short, long, default_value = "1500")] @@ -126,7 +126,7 @@ pub struct Opts { /// Automatically ups the ULIMIT with the value you provided. #[arg(short, long)] - pub ulimit: Option, + pub ulimit: Option, /// The order of scanning to be performed. The "serial" option will /// scan ports in ascending order while the "random" option will scan @@ -200,7 +200,7 @@ impl Opts { merge_required!( addresses, greppable, accessible, batch_size, timeout, tries, scan_order, scripts, - command, udp + command, udp, no_banner ); } @@ -262,10 +262,10 @@ pub struct Config { range: Option, greppable: Option, accessible: Option, - batch_size: Option, + batch_size: Option, timeout: Option, tries: Option, - ulimit: Option, + ulimit: Option, resolver: Option, scan_order: Option, command: Option>, @@ -273,6 +273,7 @@ pub struct Config { exclude_ports: Option>, exclude_addresses: Option>, udp: Option, + no_banner: Option, } #[cfg(not(tarpaulin_include))] @@ -293,7 +294,14 @@ impl Config { /// pub fn read(custom_config_path: Option) -> Self { let mut content = String::new(); - let config_path = custom_config_path.unwrap_or_else(default_config_path); + let config_path = custom_config_path.unwrap_or_else(|| { + let path = default_config_path(); + match path.exists() { + true => path, + false => old_default_config_path(), + } + }); + if config_path.exists() { content = match fs::read_to_string(config_path) { Ok(content) => content, @@ -315,6 +323,15 @@ impl Config { /// Constructs default path to config toml pub fn default_config_path() -> PathBuf { + let Some(mut config_path) = dirs::config_dir() else { + panic!("Could not infer config file path."); + }; + config_path.push(".rustscan.toml"); + config_path +} + +/// Returns the deprecated home directory config path used for backwards compatibility. +pub fn old_default_config_path() -> PathBuf { let Some(mut config_path) = dirs::home_dir() else { panic!("Could not infer config file path."); }; @@ -348,6 +365,7 @@ mod tests { exclude_ports: None, exclude_addresses: None, udp: Some(false), + no_banner: None, } } } diff --git a/src/main.rs b/src/main.rs index f802987df..08e6eaf80 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,9 +23,9 @@ extern crate dirs; // Average value for Ubuntu #[cfg(unix)] -const DEFAULT_FILE_DESCRIPTORS_LIMIT: u64 = 8000; +const DEFAULT_FILE_DESCRIPTORS_LIMIT: usize = 8000; // Safest batch size based on experimentation -const AVERAGE_BATCH_SIZE: u16 = 3000; +const AVERAGE_BATCH_SIZE: usize = 3000; #[macro_use] extern crate log; @@ -78,10 +78,10 @@ fn main() { } #[cfg(unix)] - let batch_size: u16 = infer_batch_size(&opts, adjust_ulimit_size(&opts)); + let batch_size: usize = infer_batch_size(&opts, adjust_ulimit_size(&opts)); #[cfg(not(unix))] - let batch_size: u16 = AVERAGE_BATCH_SIZE; + let batch_size: usize = AVERAGE_BATCH_SIZE; let scanner = Scanner::new( &ips, @@ -173,7 +173,7 @@ fn main() { ); match script.run() { Ok(script_result) => { - detail!(script_result.to_string(), opts.greppable, opts.accessible); + detail!(script_result.clone(), opts.greppable, opts.accessible); } Err(e) => { warning!(&format!("Error {e}"), opts.greppable, opts.accessible); @@ -219,13 +219,26 @@ The Modern Day Port Scanner."#; opts.greppable, opts.accessible ); + + if opts.config_path.is_none() { + let old_config_path = input::old_default_config_path(); + detail!( + format!( + "For backwards compatibility, the config file may also be at {old_config_path:?}" + ), + opts.greppable, + opts.accessible + ); + } } #[cfg(unix)] -fn adjust_ulimit_size(opts: &Opts) -> u64 { +fn adjust_ulimit_size(opts: &Opts) -> usize { use rlimit::Resource; + use std::convert::TryInto; if let Some(limit) = opts.ulimit { + let limit = limit as u64; if Resource::NOFILE.set(limit, limit).is_ok() { detail!( format!("Automatically increasing ulimit value to {limit}."), @@ -242,14 +255,12 @@ fn adjust_ulimit_size(opts: &Opts) -> u64 { } let (soft, _) = Resource::NOFILE.get().unwrap(); - soft + soft.try_into().unwrap_or(usize::MAX) } #[cfg(unix)] -fn infer_batch_size(opts: &Opts, ulimit: u64) -> u16 { - use std::convert::TryInto; - - let mut batch_size: u64 = opts.batch_size.into(); +fn infer_batch_size(opts: &Opts, ulimit: usize) -> usize { + let mut batch_size = opts.batch_size; // Adjust the batch size when the ulimit value is lower than the desired batch size if ulimit < batch_size { @@ -260,7 +271,7 @@ fn infer_batch_size(opts: &Opts, ulimit: u64) -> u16 { // When the OS supports high file limits like 8000, but the user // selected a batch size higher than this we should reduce it to // a lower number. - if ulimit < AVERAGE_BATCH_SIZE.into() { + if ulimit < AVERAGE_BATCH_SIZE { // ulimit is smaller than aveage batch size // user must have very small ulimit // decrease batch size to half of ulimit @@ -269,7 +280,7 @@ fn infer_batch_size(opts: &Opts, ulimit: u64) -> u16 { batch_size = ulimit / 2; } else if ulimit > DEFAULT_FILE_DESCRIPTORS_LIMIT { info!("Batch size is now average batch size"); - batch_size = AVERAGE_BATCH_SIZE.into(); + batch_size = AVERAGE_BATCH_SIZE; } else { batch_size = ulimit - 100; } @@ -282,8 +293,6 @@ fn infer_batch_size(opts: &Opts, ulimit: u64) -> u16 { } batch_size - .try_into() - .expect("Couldn't fit the batch size into a u16.") } #[cfg(test)] diff --git a/src/scanner/mod.rs b/src/scanner/mod.rs index 92038eacd..760783479 100644 --- a/src/scanner/mod.rs +++ b/src/scanner/mod.rs @@ -29,7 +29,7 @@ use std::{ #[derive(Debug)] pub struct Scanner { ips: Vec, - batch_size: u16, + batch_size: usize, timeout: Duration, tries: NonZeroU8, greppable: bool, @@ -44,7 +44,7 @@ pub struct Scanner { impl Scanner { pub fn new( ips: &[IpAddr], - batch_size: u16, + batch_size: usize, timeout: Duration, tries: u8, greppable: bool, diff --git a/tests/timelimits.rs b/tests/timelimits.rs index 37ce67b17..6b32ba451 100644 --- a/tests/timelimits.rs +++ b/tests/timelimits.rs @@ -44,7 +44,7 @@ fn run_rustscan_with_timeout(args: &[&str], timeout: Duration) { let end = Instant::now(); let duration = end.saturating_duration_since(start).as_secs_f32(); - println!("time: {:1.1}s", duration); + println!("time: {duration:1.1}s"); } mod timelimits {