From 1cb4ec9d515e24eb2d7ca4111e71678d3e51c8ce Mon Sep 17 00:00:00 2001 From: arch_agent Date: Mon, 15 Jun 2026 17:09:40 +0200 Subject: [PATCH] Add ./src/main.rs --- src/main.rs | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 src/main.rs diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..fc6bafd --- /dev/null +++ b/src/main.rs @@ -0,0 +1,161 @@ +use anyhow::Result; +use clap::{Parser, Subcommand}; +use colored::*; +use tracing::{info, warn, error}; + +mod config; +mod ioc_fetcher; +mod scanner; +mod trust_scorer; +mod utils; +mod hook; + +use scanner::PackageScanner; +use config::AegisConfig; + +#[derive(Parser)] +#[command(name = "aegisaur")] +#[command(about = "👻 Trust-Scoring + IOC-Scanner für Arch Linux AUR-Pakete")] +#[command(version = env!("CARGO_PKG_VERSION"))] +struct Cli { + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + /// Scannt ein einzelnes AUR-Paket + Scan { + /// Paketname + package: String, + /// Zeigt detaillierte Analyse + #[arg(short, long)] + verbose: bool, + }, + /// Scannt alle installierten AUR-Pakete + ScanAll { + /// Zeigt detaillierte Analyse + #[arg(short, long)] + verbose: bool, + }, + /// Prüft gegen aktuelle IOC-Listen (Atomic Arch, etc.) + CheckIoc { + /// Spezifische Liste prüfen (atomicarch, all) + #[arg(short, long, default_value = "all")] + list: String, + }, + /// Fügt Paket zur Whitelist hinzu + Allow { + /// Paketname + package: String, + }, + /// Entfernt Paket von Whitelist + Deny { + /// Paketname + package: String, + }, + /// Zeigt Konfiguration + Config, + /// Installiert ALPM-Hook + InstallHook, + /// Entfernt ALPM-Hook + RemoveHook, + /// Zeigt Cache-Status + Cache, +} + +#[tokio::main] +async fn main() -> Result<()> { + // Logging initialisieren + tracing_subscriber::fmt() + .with_env_filter("aegisaur=info") + .init(); + + let cli = Cli::parse(); + let config = AegisConfig::load_or_default()?; + let scanner = PackageScanner::new(config).await?; + + match cli.command { + Commands::Scan { package, verbose } => { + println!("{} {}", "🔍 Scanne".cyan(), package.bold()); + let result = scanner.scan_package(&package, verbose).await?; + print_result(&result); + } + Commands::ScanAll { verbose } => { + println!("{}", "🔍 Scanne alle installierten AUR-Pakete...".cyan()); + let results = scanner.scan_all_installed(verbose).await?; + for result in results { + print_result(&result); + println!(); + } + } + Commands::CheckIoc { list } => { + println!("{} {}", "🛡️ Prüfe IOC-Listen:".cyan(), list.yellow()); + let threats = scanner.check_iocs(&list).await?; + if threats.is_empty() { + println!("{}", "✅ Keine Bedrohungen gefunden!".green().bold()); + } else { + println!("{} {}", "⚠️ Bedrohungen gefunden:".red().bold(), threats.len()); + for threat in threats { + println!(" {} {} - {}", "🔴".red(), threat.package, threat.reason); + } + } + } + Commands::Allow { package } => { + scanner.allow_package(&package)?; + println!("{} {}", "✅ Erlaubt:".green(), package); + } + Commands::Deny { package } => { + scanner.deny_package(&package)?; + println!("{} {}", "❌ Entfernt:".yellow(), package); + } + Commands::Config => { + println!("{}", "⚙️ AegisAUR Konfiguration".cyan().bold()); + println!("Config-Path: {}", scanner.config_path()?.display()); + println!("Cache-Path: {}", scanner.cache_path()?.display()); + } + Commands::InstallHook => { + hook::install_alpm_hook()?; + println!("{}", "✅ ALPM-Hook installiert".green().bold()); + } + Commands::RemoveHook => { + hook::remove_alpm_hook()?; + println!("{}", "❌ ALPM-Hook entfernt".yellow().bold()); + } + Commands::Cache => { + scanner.show_cache_status().await?; + } + } + + Ok(()) +} + +fn print_result(result: &scanner::ScanResult) { + let score_color = match result.score { + 0..=30 => "🔴".red(), + 31..=60 => "🟡".yellow(), + 61..=100 => "🟢".green(), + _ => "⚪".white(), + }; + + println!( + "{} {} {} {} {}", + score_color, + result.package.bold(), + format!("({}/100)", result.score).dimmed(), + "-".dimmed(), + result.status_message() + ); + + if !result.warnings.is_empty() { + for warning in &result.warnings { + println!(" {} {}", "⚠️ ".yellow(), warning); + } + } + + if !result.ioc_matches.is_empty() { + for ioc in &result.ioc_matches { + println!(" {} {} - {}", "🚨".red().bold(), "IOC MATCH!".red().bold(), ioc); + } + } +}