wraith/src-tauri/src/commands/scanner_commands.rs
Vantz Stockwell 2d0964f6b2
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 3m7s
feat: network scanner + SFTP context menu + CI fix
Network scanner (through SSH exec channels):
- scan_network: ping sweep + ARP table + reverse DNS on remote network
- scan_ports: TCP connect scan via bash /dev/tcp (parallel batches of 20)
- quick_scan: 24 common ports (SSH, HTTP, RDP, SMB, DB, etc.)
- Cross-platform: Linux + macOS
- No agent/nmap required — uses standard POSIX commands
- All scans run on the remote host through existing SSH tunnel

SFTP context menu:
- Right-click on files/folders shows Edit, Download, Rename, Delete
- Right-click on folders shows Open Folder
- Teleport menu to body for proper z-index layering
- Click-away handler to close menu
- Rename uses sftp_rename invoke

CI fix:
- Added default-run = "wraith" to Cargo.toml
- The [[bin]] entry for wraith-mcp-bridge confused Cargo about which
  binary is the Tauri app main binary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:56:42 -04:00

45 lines
1.5 KiB
Rust

//! Tauri commands for network scanning through SSH sessions.
use tauri::State;
use crate::scanner::{self, DiscoveredHost, PortResult};
use crate::AppState;
/// Discover hosts on the remote network via ARP + ping sweep.
/// `subnet` should be the first 3 octets, e.g. "192.168.1"
#[tauri::command]
pub async fn scan_network(
session_id: String,
subnet: String,
state: State<'_, AppState>,
) -> Result<Vec<DiscoveredHost>, String> {
let session = state.ssh.get_session(&session_id)
.ok_or_else(|| format!("SSH session {} not found", session_id))?;
scanner::scan_network(&session.handle, &subnet).await
}
/// Scan specific ports on a target host through an SSH session.
#[tauri::command]
pub async fn scan_ports(
session_id: String,
target: String,
ports: Vec<u16>,
state: State<'_, AppState>,
) -> Result<Vec<PortResult>, String> {
let session = state.ssh.get_session(&session_id)
.ok_or_else(|| format!("SSH session {} not found", session_id))?;
scanner::scan_ports(&session.handle, &target, &ports).await
}
/// Quick scan of common ports (22, 80, 443, 3389, etc.) on a target.
#[tauri::command]
pub async fn quick_scan(
session_id: String,
target: String,
state: State<'_, AppState>,
) -> Result<Vec<PortResult>, String> {
let session = state.ssh.get_session(&session_id)
.ok_or_else(|| format!("SSH session {} not found", session_id))?;
scanner::quick_port_scan(&session.handle, &target).await
}