mirror of
https://github.com/bee-san/RustScan.git
synced 2026-11-07 09:46:04 -10:00
Build CI to auto-distribute releases (#468)
* refactor(ci): update build ci and add cross-compilation * cron check * remove fmt * cross-compile for tests * lint code * remove duplicate Signed-off-by: leofvo <[email protected]> * fix(code): code lint + fix bad practices Signed-off-by: leofvo <[email protected]> * test(windows): remove windows incompatible function for test when running on windows Signed-off-by: leofvo <[email protected]> * build(release): add release ci/cd * github workflow * cargo.toml improvment Signed-off-by: leofvo <[email protected]> Signed-off-by: leofvo <[email protected]>
This commit is contained in:
1 parent
9e1cb60a05
commit
405f05d42c
15 files changed
+396
-109
No files matched your search
@@ -1,10 +0,0 @@
|
||||
name: Check Markdown links
|
||||
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
markdown-link-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: gaurav-nelson/github-action-markdown-link-check@v1
|
||||
@@ -1,48 +0,0 @@
|
||||
on: [push, pull_request]
|
||||
|
||||
name: Continuous integration
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
# - uses: actions-rs/cargo@v1
|
||||
# with:
|
||||
# command: check
|
||||
|
||||
test:
|
||||
name: Test Suite
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
|
||||
fmt:
|
||||
name: Rustfmt
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
- run: rustup component add rustfmt
|
||||
- uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
@@ -0,0 +1,94 @@
|
||||
name: Build
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
schedule:
|
||||
- cron: '00 01 * * *'
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install stable toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
|
||||
- name: Run cargo check
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
|
||||
test:
|
||||
name: Test Suite
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
rust: [stable]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install stable toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
|
||||
- name: Run cargo test
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
|
||||
lints:
|
||||
name: Lints
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install stable toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
|
||||
- name: Run cargo fmt
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
|
||||
- name: Run cargo clippy
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: clippy
|
||||
args: -- -D warnings
|
||||
|
||||
- name: Run rustdoc lints
|
||||
uses: actions-rs/cargo@v1
|
||||
env:
|
||||
RUSTDOCFLAGS: '-D missing_docs -D rustdoc::missing_doc_code_examples'
|
||||
with:
|
||||
command: doc
|
||||
args: --workspace --all-features --no-deps --document-private-items
|
||||
@@ -0,0 +1,236 @@
|
||||
name: Release
|
||||
on:
|
||||
# schedule:
|
||||
# - cron: '0 0 * * *' # midnight UTC
|
||||
|
||||
push:
|
||||
tags:
|
||||
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
## - release
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- 'package.json'
|
||||
- 'package-lock.json'
|
||||
- 'CHANGELOG.md'
|
||||
- '.github/workflows/release.yml'
|
||||
|
||||
env:
|
||||
BIN_NAME: rustscan
|
||||
PROJECT_NAME: rustscan
|
||||
REPO_NAME: RustScan/RustScan
|
||||
# BREW_TAP: RustScan/homebrew-tap
|
||||
|
||||
jobs:
|
||||
dist:
|
||||
name: Dist
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false # don't fail other jobs if one fails
|
||||
matrix:
|
||||
build: [x86_64-linux, x86_64-macos, x86_64-windows] #, x86_64-win-gnu, win32-msvc
|
||||
include:
|
||||
- build: x86_64-linux
|
||||
os: ubuntu-20.04
|
||||
rust: stable
|
||||
target: x86_64-unknown-linux-gnu
|
||||
cross: false
|
||||
- build: x86_64-macos
|
||||
os: macos-latest
|
||||
rust: stable
|
||||
target: x86_64-apple-darwin
|
||||
cross: false
|
||||
- build: x86_64-windows
|
||||
os: windows-2019
|
||||
rust: stable
|
||||
target: x86_64-pc-windows-msvc
|
||||
cross: false
|
||||
# - build: aarch64-linux
|
||||
# os: ubuntu-20.04
|
||||
# rust: stable
|
||||
# target: aarch64-unknown-linux-gnu
|
||||
# - build: aarch64-macos
|
||||
# os: macos-latest
|
||||
# rust: stable
|
||||
# target: aarch64-apple-darwin
|
||||
# - build: x86_64-win-gnu
|
||||
# os: windows-2019
|
||||
# rust: stable-x86_64-gnu
|
||||
# target: x86_64-pc-windows-gnu
|
||||
# - build: win32-msvc
|
||||
# os: windows-2019
|
||||
# rust: stable
|
||||
# target: i686-pc-windows-msvc
|
||||
|
||||
steps:
|
||||
- name: Strip release binary (linux and macos)
|
||||
if: matrix.build == 'x86_64-windows' # Windows is missing some dependencies
|
||||
run: |
|
||||
git config --global pack.windowMemory "100m"
|
||||
git config --global pack.packSizeLimit "100m"
|
||||
git config --global pack.threads "1"
|
||||
git config --global pack.deltaCacheSize "512m"
|
||||
|
||||
- name: Install python 3.10 for windows
|
||||
if: matrix.build == 'x86_64-windows' # Windows is missing some dependencies
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Install ${{ matrix.rust }} toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.rust }}
|
||||
target: ${{ matrix.target }}
|
||||
override: true
|
||||
|
||||
- name: Run cargo test
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
use-cross: ${{ matrix.cross }}
|
||||
command: test
|
||||
args: --release --locked --target ${{ matrix.target }}
|
||||
|
||||
- name: Build release binary
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
use-cross: ${{ matrix.cross }}
|
||||
command: build
|
||||
args: --release --locked --target ${{ matrix.target }}
|
||||
|
||||
- name: Strip release binary (linux and macos)
|
||||
if: matrix.build == 'x86_64-linux' || matrix.build == 'x86_64-macos'
|
||||
run: strip "target/${{ matrix.target }}/release/$BIN_NAME"
|
||||
|
||||
- name: Strip release binary (arm)
|
||||
if: matrix.build == 'aarch64-linux'
|
||||
run: |
|
||||
docker run --rm -v \
|
||||
"$PWD/target:/target:Z" \
|
||||
rustembedded/cross:${{ matrix.target }} \
|
||||
aarch64-linux-gnu-strip \
|
||||
/target/${{ matrix.target }}/release/$BIN_NAME
|
||||
- name: Build archive
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir dist
|
||||
if [ "${{ matrix.os }}" = "windows-2019" ]; then
|
||||
cp "target/${{ matrix.target }}/release/$BIN_NAME.exe" "dist/"
|
||||
else
|
||||
cp "target/${{ matrix.target }}/release/$BIN_NAME" "dist/"
|
||||
fi
|
||||
- uses: actions/[email protected]
|
||||
with:
|
||||
name: bins-${{ matrix.build }}
|
||||
path: dist
|
||||
|
||||
publish:
|
||||
name: Publish
|
||||
needs: [dist]
|
||||
if: contains(fromJson('["push", "schedule"]'), github.event_name) && startsWith(github.ref, 'refs/tags/')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: false
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
# with:
|
||||
# path: dist
|
||||
# - run: ls -al ./dist
|
||||
- run: ls -al bins-*
|
||||
|
||||
- name: Calculate tag name
|
||||
run: |
|
||||
name=dev
|
||||
if [[ $GITHUB_REF == refs/tags/v* ]]; then
|
||||
name=${GITHUB_REF:10}
|
||||
fi
|
||||
echo ::set-output name=val::$name
|
||||
echo TAG=$name >> $GITHUB_ENV
|
||||
id: tagname
|
||||
|
||||
- name: Build archive
|
||||
shell: bash
|
||||
run: |
|
||||
set -ex
|
||||
rm -rf tmp
|
||||
mkdir tmp
|
||||
mkdir dist
|
||||
for dir in bins-* ; do
|
||||
platform=${dir#"bins-"}
|
||||
unset exe
|
||||
if [[ $platform =~ "windows" ]]; then
|
||||
exe=".exe"
|
||||
fi
|
||||
pkgname=$PROJECT_NAME-$TAG-$platform
|
||||
mkdir tmp/$pkgname
|
||||
# cp LICENSE README.md tmp/$pkgname
|
||||
mv bins-$platform/$BIN_NAME$exe tmp/$pkgname
|
||||
chmod +x tmp/$pkgname/$BIN_NAME$exe
|
||||
if [ "$exe" = "" ]; then
|
||||
tar cJf dist/$pkgname.tar.xz -C tmp $pkgname
|
||||
else
|
||||
(cd tmp && 7z a -r ../dist/$pkgname.zip $pkgname)
|
||||
fi
|
||||
done
|
||||
- name: Upload binaries to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: dist/*
|
||||
file_glob: true
|
||||
tag: ${{ steps.tagname.outputs.val }}
|
||||
overwrite: true
|
||||
|
||||
- name: Extract version
|
||||
id: extract-version
|
||||
run: |
|
||||
printf "::set-output name=%s::%s\n" tag-name "${GITHUB_REF#refs/tags/}"
|
||||
- uses: mislav/bump-homebrew-formula-action@v1
|
||||
with:
|
||||
formula-path: ${{env.PROJECT_NAME}}.rb
|
||||
homebrew-tap: ${{ env.BREW_TAP }}
|
||||
download-url: 'https://github.com/${{ env.REPO_NAME }}/releases/download/${{ steps.extract-version.outputs.tag-name }}/${{env.PROJECT_NAME}}-${{ steps.extract-version.outputs.tag-name }}-x86_64-macos.tar.xz'
|
||||
commit-message: updating formula for ${{ env.PROJECT_NAME }}
|
||||
env:
|
||||
COMMITTER_TOKEN: ${{ secrets.COMMITTER_TOKEN }}
|
||||
#
|
||||
# you can use this initial file in your homebrew-tap if you don't have an initial formula:
|
||||
# <projectname>.rb
|
||||
#
|
||||
# class <Projectname capitalized> < Formula
|
||||
# desc "A test formula"
|
||||
# homepage "http://www.example.com"
|
||||
# url "-----"
|
||||
# version "-----"
|
||||
# sha256 "-----"
|
||||
|
||||
# def install
|
||||
# bin.install "<bin-name>"
|
||||
# end
|
||||
# end
|
||||
|
||||
# Uncomment this section if you want to release your package to crates.io
|
||||
# Before publishing, make sure you have filled out the following fields:
|
||||
# license or license-file, description, homepage, documentation, repository, readme.
|
||||
# Read more: https://doc.rust-lang.org/cargo/reference/publishing.html
|
||||
|
||||
- name: Install ${{ matrix.rust }} toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.rust }}
|
||||
target: ${{ matrix.target }}
|
||||
- run: cargo publish --token ${CRATES_TOKEN}
|
||||
env:
|
||||
CRATES_TOKEN: ${{ secrets.CRATES_TOKEN }}
|
||||
@@ -50,3 +50,8 @@ section = "rust"
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = 'abort'
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[[bin]]
|
||||
name = "rustscan"
|
||||
path = "src/main.rs"
|
||||
@@ -43,7 +43,7 @@ impl Benchmark {
|
||||
.unwrap()
|
||||
.saturating_duration_since(timer.start.unwrap())
|
||||
.as_secs_f32();
|
||||
summary.push_str(&format!("\n{0: <10} | {1: <10}s", timer.name, runtime_secs))
|
||||
summary.push_str(&format!("\n{0: <10} | {1: <10}s", timer.name, runtime_secs));
|
||||
}
|
||||
}
|
||||
summary
|
||||
@@ -85,5 +85,5 @@ fn benchmark() {
|
||||
assert!(benchmarks
|
||||
.summary()
|
||||
.contains("\nRustScan Benchmark Summary\ntest | 0."));
|
||||
assert_ne!(benchmarks.summary().contains("only_start"), true);
|
||||
assert!(!benchmarks.summary().contains("only_start"));
|
||||
}
|
||||
+9
-9
@@ -11,7 +11,7 @@ arg_enum! {
|
||||
/// Represents the strategy in which the port scanning will run.
|
||||
/// - Serial will run from start to end, for example 1 to 1_000.
|
||||
/// - Random will randomize the order in which ports will be scanned.
|
||||
#[derive(Deserialize, Debug, StructOpt, Clone, Copy, PartialEq)]
|
||||
#[derive(Deserialize, Debug, StructOpt, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ScanOrder {
|
||||
Serial,
|
||||
Random,
|
||||
@@ -23,7 +23,7 @@ arg_enum! {
|
||||
/// - none will avoid running any script, only portscan results will be shown.
|
||||
/// - default will run the default embedded nmap script, that's part of RustScan since the beginning.
|
||||
/// - custom will read the ScriptConfig file and the available scripts in the predefined folders
|
||||
#[derive(Deserialize, Debug, StructOpt, Clone, PartialEq, Copy)]
|
||||
#[derive(Deserialize, Debug, StructOpt, Clone, PartialEq, Eq, Copy)]
|
||||
pub enum ScriptsRequired {
|
||||
None,
|
||||
Default,
|
||||
@@ -32,7 +32,7 @@ arg_enum! {
|
||||
}
|
||||
|
||||
/// Represents the range of ports to be scanned.
|
||||
#[derive(Deserialize, Debug, Clone, PartialEq)]
|
||||
#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct PortRange {
|
||||
pub start: u16,
|
||||
pub end: u16,
|
||||
@@ -161,8 +161,8 @@ impl Opts {
|
||||
/// values found within the user configuration file.
|
||||
pub fn merge(&mut self, config: &Config) {
|
||||
if !self.no_config {
|
||||
self.merge_required(&config);
|
||||
self.merge_optional(&config);
|
||||
self.merge_required(config);
|
||||
self.merge_optional(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ impl Opts {
|
||||
if self.top && config.ports.is_some() {
|
||||
let mut ports: Vec<u16> = Vec::with_capacity(config.ports.clone().unwrap().len());
|
||||
for entry in config.ports.clone().unwrap().keys() {
|
||||
ports.push(entry.parse().unwrap())
|
||||
ports.push(entry.parse().unwrap());
|
||||
}
|
||||
self.ports = Some(ports);
|
||||
}
|
||||
@@ -323,8 +323,8 @@ mod tests {
|
||||
opts.merge(&config);
|
||||
|
||||
assert_eq!(opts.addresses, vec![] as Vec<String>);
|
||||
assert_eq!(opts.greppable, true);
|
||||
assert_eq!(opts.accessible, false);
|
||||
assert!(opts.greppable);
|
||||
assert!(!opts.accessible);
|
||||
assert_eq!(opts.timeout, 0);
|
||||
assert_eq!(opts.command, vec![] as Vec<String>);
|
||||
assert_eq!(opts.scan_order, ScanOrder::Serial);
|
||||
@@ -343,7 +343,7 @@ mod tests {
|
||||
assert_eq!(opts.command, config.command.unwrap());
|
||||
assert_eq!(opts.accessible, config.accessible.unwrap());
|
||||
assert_eq!(opts.scan_order, config.scan_order.unwrap());
|
||||
assert_eq!(opts.scripts, ScriptsRequired::Default)
|
||||
assert_eq!(opts.scripts, ScriptsRequired::Default);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
+13
-3
@@ -205,6 +205,7 @@ fn main() {
|
||||
}
|
||||
|
||||
/// Prints the opening title of RustScan
|
||||
#[allow(clippy::items_after_statements)]
|
||||
fn print_opening(opts: &Opts) {
|
||||
debug!("Printing opening");
|
||||
let s = format!(
|
||||
@@ -287,7 +288,7 @@ fn parse_addresses(input: &Opts) -> Vec<IpAddr> {
|
||||
/// This allows us to pass files as hosts or cidr or IPs easily
|
||||
/// Call this everytime you have a possible IP_or_host
|
||||
fn parse_address(address: &str, resolver: &Resolver) -> Vec<IpAddr> {
|
||||
IpCidr::from_str(&address)
|
||||
IpCidr::from_str(address)
|
||||
.map(|cidr| cidr.iter().collect())
|
||||
.ok()
|
||||
.or_else(|| {
|
||||
@@ -339,6 +340,7 @@ fn read_ips_from_file(
|
||||
#[cfg(unix)]
|
||||
fn adjust_ulimit_size(opts: &Opts) -> u64 {
|
||||
use rlimit::Resource;
|
||||
|
||||
if let Some(limit) = opts.ulimit {
|
||||
if Resource::NOFILE.set(limit, limit).is_ok() {
|
||||
detail!(
|
||||
@@ -402,10 +404,14 @@ fn infer_batch_size(opts: &Opts, ulimit: u64) -> u16 {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{adjust_ulimit_size, infer_batch_size, parse_addresses, print_opening, Opts};
|
||||
#[cfg(unix)]
|
||||
use crate::{adjust_ulimit_size, infer_batch_size};
|
||||
|
||||
use crate::{parse_addresses, print_opening, Opts};
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn batch_size_lowered() {
|
||||
let mut opts = Opts::default();
|
||||
opts.batch_size = 50_000;
|
||||
@@ -415,6 +421,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn batch_size_lowered_average_size() {
|
||||
let mut opts = Opts::default();
|
||||
opts.batch_size = 50_000;
|
||||
@@ -423,6 +430,7 @@ mod tests {
|
||||
assert!(batch_size == 3_000);
|
||||
}
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn batch_size_equals_ulimit_lowered() {
|
||||
// because ulimit and batch size are same size, batch size is lowered
|
||||
// to ULIMIT - 100
|
||||
@@ -433,6 +441,7 @@ mod tests {
|
||||
assert!(batch_size == 4_900);
|
||||
}
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn batch_size_adjusted_2000() {
|
||||
// ulimit == batch_size
|
||||
let mut opts = Opts::default();
|
||||
@@ -451,6 +460,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_high_ulimit_no_greppable_mode() {
|
||||
let mut opts = Opts::default();
|
||||
opts.batch_size = 10;
|
||||
@@ -503,7 +513,7 @@ mod tests {
|
||||
opts.addresses = vec!["im_wrong".to_owned(), "300.10.1.1".to_owned()];
|
||||
let ips = parse_addresses(&opts);
|
||||
|
||||
assert_eq!(ips.is_empty(), true);
|
||||
assert!(ips.is_empty());
|
||||
}
|
||||
#[test]
|
||||
fn parse_hosts_file_and_incorrect_hosts() {
|
||||
|
||||
@@ -44,7 +44,7 @@ impl PortStrategy {
|
||||
|
||||
pub fn order(&self) -> Vec<u16> {
|
||||
match self {
|
||||
PortStrategy::Manual(ports) => ports.to_vec(),
|
||||
PortStrategy::Manual(ports) => ports.clone(),
|
||||
PortStrategy::Serial(range) => range.generate(),
|
||||
PortStrategy::Random(range) => range.generate(),
|
||||
}
|
||||
@@ -115,7 +115,7 @@ mod tests {
|
||||
let expected_range = (1..100).into_iter().collect::<Vec<u16>>();
|
||||
assert_ne!(expected_range, result);
|
||||
|
||||
result.sort();
|
||||
result.sort_unstable();
|
||||
assert_eq!(expected_range, result);
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ mod tests {
|
||||
let expected_range = (1..10).into_iter().collect::<Vec<u16>>();
|
||||
assert_ne!(expected_range, result);
|
||||
|
||||
result.sort();
|
||||
result.sort_unstable();
|
||||
assert_eq!(expected_range, result);
|
||||
}
|
||||
}
|
||||
@@ -89,9 +89,8 @@ fn pick_random_coprime(end: u32) -> u32 {
|
||||
for _ in 0..10 {
|
||||
if end.gcd(candidate) == 1 {
|
||||
return candidate;
|
||||
} else {
|
||||
candidate = rng.gen_range(lower_range, upper_range);
|
||||
}
|
||||
candidate = rng.gen_range(lower_range, upper_range);
|
||||
}
|
||||
|
||||
end - 1
|
||||
@@ -127,7 +126,7 @@ mod tests {
|
||||
fn generate_sorted_range(start: u32, end: u32) -> Vec<u16> {
|
||||
let range = RangeIterator::new(start, end);
|
||||
let mut result = range.into_iter().collect::<Vec<u16>>();
|
||||
result.sort();
|
||||
result.sort_unstable();
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@ impl Scanner {
|
||||
}
|
||||
if !self.greppable {
|
||||
if self.accessible {
|
||||
println!("Open {}", socket.to_string());
|
||||
println!("Open {}", socket);
|
||||
} else {
|
||||
println!("Open {}", socket.to_string().purple());
|
||||
}
|
||||
|
||||
@@ -43,10 +43,9 @@ impl<'s> Iterator for SocketIterator<'s> {
|
||||
/// it.next(); // 192.168.0.1:443
|
||||
/// it.next(); // None
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.product_it.next() {
|
||||
None => None,
|
||||
Some((port, ip)) => Some(SocketAddr::new(*ip, *port)),
|
||||
}
|
||||
self.product_it
|
||||
.next()
|
||||
.map(|(port, ip)| SocketAddr::new(*ip, *port))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-12
@@ -72,7 +72,7 @@ pub fn init_scripts(scripts: ScriptsRequired) -> Result<Vec<ScriptFile>> {
|
||||
ScriptsRequired::None => Ok(scripts_to_run),
|
||||
ScriptsRequired::Default => {
|
||||
let default_script =
|
||||
toml::from_str::<ScriptFile>(&DEFAULT).expect("Failed to parse Script file.");
|
||||
toml::from_str::<ScriptFile>(DEFAULT).expect("Failed to parse Script file.");
|
||||
scripts_to_run.push(default_script);
|
||||
Ok(scripts_to_run)
|
||||
}
|
||||
@@ -105,7 +105,7 @@ pub fn init_scripts(scripts: ScriptsRequired) -> Result<Vec<ScriptFile>> {
|
||||
let script_hashset: HashSet<String> =
|
||||
script.tags.clone().unwrap().into_iter().collect();
|
||||
if config_hashset.is_subset(&script_hashset) {
|
||||
scripts_to_run.push(script.to_owned());
|
||||
scripts_to_run.push(script.clone());
|
||||
} else {
|
||||
debug!(
|
||||
"\nScript tags does not match config tags {:?} {}",
|
||||
@@ -134,6 +134,7 @@ pub fn parse_scripts(scripts: Vec<PathBuf>) -> Vec<ScriptFile> {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Script {
|
||||
// Path to the script itself.
|
||||
path: Option<PathBuf>,
|
||||
@@ -293,16 +294,14 @@ impl ScriptFile {
|
||||
let real_path = script.clone();
|
||||
let mut lines_buf = String::new();
|
||||
if let Ok(file) = File::open(script) {
|
||||
for line in io::BufReader::new(file).lines().skip(1) {
|
||||
if let Ok(mut line) = line {
|
||||
if line.starts_with('#') {
|
||||
line.retain(|c| c != '#');
|
||||
line = line.trim().to_string();
|
||||
line.push('\n');
|
||||
lines_buf.push_str(&line);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
for mut line in io::BufReader::new(file).lines().skip(1).flatten() {
|
||||
if line.starts_with('#') {
|
||||
line.retain(|c| c != '#');
|
||||
line = line.trim().to_string();
|
||||
line.push('\n');
|
||||
lines_buf.push_str(&line);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -435,6 +434,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn run_bash_script() {
|
||||
let script_f = ScriptFile::new("fixtures/.rustscan_scripts/test_script.sh".into()).unwrap();
|
||||
let script: Script = into_script(script_f);
|
||||
@@ -456,6 +456,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn run_perl_script() {
|
||||
let script_f = ScriptFile::new("fixtures/.rustscan_scripts/test_script.pl".into()).unwrap();
|
||||
let script: Script = into_script(script_f);
|
||||
|
||||
+14
-13
@@ -4,18 +4,16 @@
|
||||
#[macro_export]
|
||||
macro_rules! warning {
|
||||
($name:expr) => {
|
||||
use ansi_term::Colour::Red;
|
||||
println!("{} {}", Red.bold().paint("[!]"), $name);
|
||||
println!("{} {}", ansi_term::Colour::Red.bold().paint("[!]"), $name);
|
||||
};
|
||||
($name:expr, $greppable:expr, $accessible:expr) => {
|
||||
use ansi_term::Colour::Red;
|
||||
// if not greppable then print, otherwise no else statement so do not print.
|
||||
if !$greppable {
|
||||
if $accessible {
|
||||
// Don't print the ascii art
|
||||
println!("{}", $name);
|
||||
} else {
|
||||
println!("{} {}", Red.bold().paint("[!]"), $name);
|
||||
println!("{} {}", ansi_term::Colour::Red.bold().paint("[!]"), $name);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -24,18 +22,16 @@ macro_rules! warning {
|
||||
#[macro_export]
|
||||
macro_rules! detail {
|
||||
($name:expr) => {
|
||||
use ansi_term::Colour::Blue;
|
||||
println!("{} {}", Blue.bold().paint("[~]"), $name);
|
||||
println!("{} {}", ansi_term::Colour::Blue.bold().paint("[~]"), $name);
|
||||
};
|
||||
($name:expr, $greppable:expr, $accessible:expr) => {
|
||||
use ansi_term::Colour::Blue;
|
||||
// if not greppable then print, otherwise no else statement so do not print.
|
||||
if !$greppable {
|
||||
if $accessible {
|
||||
// Don't print the ascii art
|
||||
println!("{}", $name);
|
||||
} else {
|
||||
println!("{} {}", Blue.bold().paint("[~]"), $name);
|
||||
println!("{} {}", ansi_term::Colour::Blue.bold().paint("[~]"), $name);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -44,18 +40,24 @@ macro_rules! detail {
|
||||
#[macro_export]
|
||||
macro_rules! output {
|
||||
($name:expr) => {
|
||||
use ansi_term::Colour::RGB;
|
||||
println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
println!(
|
||||
"{} {}",
|
||||
RGansi_term::Colour::RGB(0, 255, 9).bold().paint("[>]"),
|
||||
$name
|
||||
);
|
||||
};
|
||||
($name:expr, $greppable:expr, $accessible:expr) => {
|
||||
use ansi_term::Colour::RGB;
|
||||
// if not greppable then print, otherwise no else statement so do not print.
|
||||
if !$greppable {
|
||||
if $accessible {
|
||||
// Don't print the ascii art
|
||||
println!("{}", $name);
|
||||
} else {
|
||||
println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
println!(
|
||||
"{} {}",
|
||||
ansi_term::Colour::RGB(0, 255, 9).bold().paint("[>]"),
|
||||
$name
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -77,6 +79,5 @@ macro_rules! funny_opening {
|
||||
let random_quote = quotes.choose(&mut rand::thread_rng()).unwrap();
|
||||
|
||||
println!("{}\n", random_quote);
|
||||
// println!("{} {}", RGB(0, 255, 9).bold().paint("[>]"), $name);
|
||||
};
|
||||
}
|
||||
+1
-1
@@ -35,7 +35,7 @@ fn run_rustscan_with_timeout(args: &[&str], timeout: Duration) {
|
||||
if tries == 0 {
|
||||
// child hasn't exited yet
|
||||
child.kill().unwrap();
|
||||
child.wait().unwrap().code();
|
||||
child.wait().unwrap().code().unwrap();
|
||||
panic!("Timeout while running command");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user