diff options
Diffstat (limited to 'src/main/java/com/it_jaros/jscanner/Scanner.java')
| -rw-r--r-- | src/main/java/com/it_jaros/jscanner/Scanner.java | 72 |
1 files changed, 18 insertions, 54 deletions
diff --git a/src/main/java/com/it_jaros/jscanner/Scanner.java b/src/main/java/com/it_jaros/jscanner/Scanner.java index 7aeee03..286afde 100644 --- a/src/main/java/com/it_jaros/jscanner/Scanner.java +++ b/src/main/java/com/it_jaros/jscanner/Scanner.java @@ -1,20 +1,14 @@ package com.it_jaros.jscanner; -import java.io.BufferedReader; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.*; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.LockSupport; -import java.util.stream.Stream; public class Scanner implements AutoCloseable { @@ -25,7 +19,6 @@ public class Scanner implements AutoCloseable { private final Semaphore socketLimit; private final boolean bannerRecognition; private final boolean disableOnlineCheck; - private final boolean quiet; private final int maxHostsLimit; private final int maxWorkersPerHost; private final int timeoutInMillis; @@ -38,7 +31,6 @@ public class Scanner implements AutoCloseable { int maxWorkersPerHost, int maxHostsLimit, boolean disableOnlineCheck, - boolean quiet, boolean bannerRecognition ) { this.delayInNanos = TimeUnit.MILLISECONDS.toNanos(Math.max(0, delayInMillis)); @@ -46,52 +38,24 @@ public class Scanner implements AutoCloseable { this.disableOnlineCheck = disableOnlineCheck; this.maxHostsLimit = maxHostsLimit; this.maxWorkersPerHost = maxWorkersPerHost; - this.quiet = quiet; this.socketLimit = new Semaphore(socketLimit); this.timeoutInMillis = timeoutInMillis; } public Scanner(ScanOptions options) { - this(options.openSocketLimit(), options.timeoutInMillis(), options.delayInMillis(), options.maxWorkersPerHost(), options.maxHostsLimit(), options.disableHostCheck(), options.quiet(), options.bannerRecognition()); + this(options.openSocketLimit(), options.timeoutInMillis(), options.delayInMillis(), options.maxWorkersPerHost(), options.maxHostsLimit(), options.disableHostCheck(), options.bannerRecognition()); } - public Scan createScan(ScanOptions options) { - if (options.hostsFile() != null) { - return createScan(options.hostsFile(), options.ports()); - } - return createScan(options.hostsArgv(), options.ports()); - } - - public Scan createScan(String sourceFile, String ports) { - try (BufferedReader reader = Files.newBufferedReader(Path.of(sourceFile))) { - return createScan(reader.lines(), ports); - } catch (FileNotFoundException | NoSuchFileException e) { - System.out.printf("Could not open file %s%n", sourceFile); - } catch (IOException e) { - System.out.printf("Error while trying to read hosts: %s -> %s %n", e.getClass().getSimpleName(), e.getMessage()); - } - - return null; - } - - public Scan createScan(Stream<String> hosts, String ports) { - return new Scan(hosts.toList(), ports, new ScanState(new Counter(), new ProgressBar(quiet))); - } - - public Scan createScan(List<String> hostsArgv, String ports) { - return new Scan(hostsArgv, ports, new ScanState(new Counter(), new ProgressBar(quiet))); - } public List<ScanResult> runScan(Scan scan) { if (scan == null) { throw new IllegalArgumentException("Scan argument cannot be null"); } - ScanState scanState = scan.state(); - scanState.getProgressBar().start(); + scan.start(); try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) { CompletionService<ScanResult> completionService = new ExecutorCompletionService<>(executor); - Queue<String> hostsInQueue = new ArrayDeque<>(scan.hosts()); + Queue<String> hostsInQueue = new ArrayDeque<>(scan.getHosts()); int hostsToProcess = hostsInQueue.size(); int activeHostWorkers = 0; @@ -100,7 +64,7 @@ public class Scanner implements AutoCloseable { while (!hostsInQueue.isEmpty() && activeHostWorkers < maxHostsLimit && !cancelled) { activeHostWorkers++; final String host = hostsInQueue.poll(); - completionService.submit(() -> scanHostPorts(host, scan.ports(), scanState)); + completionService.submit(() -> scanHostPorts(host, scan.getPorts(), scan)); } try { @@ -110,7 +74,7 @@ public class Scanner implements AutoCloseable { } activeHostWorkers--; hostsToProcess--; - scanState.addScanResult(finishedHost.get()); + scan.addScanResult(finishedHost.get()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } catch (ExecutionException e) { @@ -123,30 +87,30 @@ public class Scanner implements AutoCloseable { } } - scanState.getProgressBar().stop(); - return scanState.getSnapshotOfScanResults(); + scan.stop(); + return scan.getResults(); } - private ScanResult scanHostPorts(String host, String ports, ScanState scanState) { + private ScanResult scanHostPorts(String host, String ports, Scan scan) { PortRange portRange = new PortRange(ports); - AtomicLong portSlotFactory = new AtomicLong(System.nanoTime()); BitSet openPorts = new BitSet(PortRange.MAX_PORT); BitSet filteredPorts = new BitSet(PortRange.MAX_PORT); - HashMap<Integer, ServiceType> bannerRecognition = new HashMap<>(); + HashMap<Integer, ServiceType> serviceTypes = new HashMap<>(); // Give progressbar the current progress object which is then updated in the sub virtual threads Progress progress = new Progress(host, portRange.getTotal(), new AtomicInteger(), new AtomicInteger(), new AtomicInteger()); - scanState.getProgressBar().submit(progress); + scan.addHostProgress(progress); if (!disableOnlineCheck && !checkHostOnline(host)) { // Visually show that this host is basically done progress.done().set(progress.total()); - return new ScanResult(host, openPorts, filteredPorts, bannerRecognition); + return new ScanResult(host, openPorts, filteredPorts, serviceTypes); } try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) { CompletionService<PortResult> completionService = new ExecutorCompletionService<>(executor); List<Throwable> errors = new ArrayList<>(); + AtomicLong portSlotFactory = new AtomicLong(System.nanoTime()); int activePerHostWorkers = 0; int portsToProcess = portRange.getTotal(); while (portsToProcess > 0 && !cancelled) { @@ -155,7 +119,7 @@ public class Scanner implements AutoCloseable { final int currentPort = portRange.next(); completionService.submit(() -> { waitForSlot(portSlotFactory); - return checkPort(host, currentPort, scanState); + return checkPort(host, currentPort, scan); }); } @@ -174,7 +138,7 @@ public class Scanner implements AutoCloseable { switch (portResult.getState()) { case OPEN -> { openPorts.set(portResult.getPort()); - bannerRecognition.put(portResult.getPort(), ServiceDetector.detect(portResult.getBanner())); + serviceTypes.put(portResult.getPort(), ServiceDetector.detect(portResult.getBanner())); } case FILTERED -> filteredPorts.set(portResult.getPort()); } @@ -194,7 +158,7 @@ public class Scanner implements AutoCloseable { } } - return new ScanResult(host, openPorts, filteredPorts, bannerRecognition); + return new ScanResult(host, openPorts, filteredPorts, serviceTypes); } private boolean checkHostOnline(String host) { @@ -216,7 +180,7 @@ public class Scanner implements AutoCloseable { } } - private PortResult checkPort(String host, int port, ScanState scanState) { + private PortResult checkPort(String host, int port, Scan scan) { PortResult result = new PortResult(); result.setPort(port); result.setState(PortState.UNKNOWN); @@ -224,7 +188,7 @@ public class Scanner implements AutoCloseable { // don't allow more sockets then specified socketLimit.acquireUninterruptibly(); // count how many ports are concurrently checked - scanState.getCounter().inc(); + scan.incSocketCounter(); try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port), timeoutInMillis); @@ -240,7 +204,7 @@ public class Scanner implements AutoCloseable { // NoRouteToHostException: this can be safely ignored because the port is closed if a host is unreachable // Will happen a lot when scanning for open ports, so not needed } finally { - scanState.getCounter().dec(); + scan.decSocketCounter(); socketLimit.release(); } |
