fix: Build-Fehler behoben - v0.1.0 funktioniert
Rust CI / Test (push) Failing after 2s
Rust CI / Release (x86_64-unknown-linux-gnu) (push) Has been skipped
Rust CI / Release (x86_64-unknown-linux-musl) (push) Has been skipped

Behobene Fehler:
- Instant/SystemTime mismatch mit chrono Duration
- dirs crate -> directories ProjDirs migration
- Display Traits für ThreatType und ConfidenceLevel
- async/await Korrektur in main.rs
- IOC_SOURCES Const Array entfernt
- Scanner mutability fix für allow/deny

Warnungen: Nicht kritisch (unused code in MVP)
This commit is contained in:
Thuumate 👻
2026-06-15 17:50:00 +02:00
parent 5190aca72c
commit aedf6676e8
5 changed files with 3059 additions and 47 deletions
+34 -43
View File
@@ -1,50 +1,10 @@
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use std::time::{Duration, Instant};
use std::time::Duration;
use tokio::fs;
use tracing::{debug, info, warn};
/// Bekannte IOC-Quellen (alle ohne Authentifizierung)
pub const IOC_SOURCES: [&[(&str, &str)]; 4] = [
// (Name, URL)
[
(
"atomic_arch_gist",
"https://gist.githubusercontent.com/Kidev/85756c3dcad3623ca5604a8135bafd14/raw",
),
(
"aur_malware_list",
"https://raw.githubusercontent.com/archlinux/aurweb/master/schema/",
), // Fallback
],
// Dynamische Community-Listen
[
(
"community_blocklist",
"https://raw.githubusercontent.com/Kidev/AUR-Blocklist/main/blocklist.txt",
),
(
"arch_security_advisories",
"https://security.archlinux.org/advisories.json",
),
],
// AUR Metadata (RPC API - KEIN Auth nötig)
[
(
"aur_rpc_base",
"https://aur.archlinux.org/rpc/v5/info?arg[]={}",
),
],
// Extra: Arch Wiki Security Seite (HTML scraping als Fallback)
[
(
"arch_wiki_security",
"https://wiki.archlinux.org/title/Security",
),
],
];
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IocEntry {
pub package_name: String,
@@ -67,6 +27,22 @@ pub enum ThreatType {
Unknown(String),
}
impl std::fmt::Display for ThreatType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
ThreatType::MaliciousBuildScript => "MaliciousBuildScript",
ThreatType::CredentialStealer => "CredentialStealer",
ThreatType::Rootkit => "Rootkit",
ThreatType::Cryptominer => "Cryptominer",
ThreatType::Backdoor => "Backdoor",
ThreatType::Typosquatting => "Typosquatting",
ThreatType::OrphanTakeover => "OrphanTakeover",
ThreatType::Unknown(s) => return write!(f, "Unknown({})", s),
};
write!(f, "{}", s)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ConfidenceLevel {
Critical, // Bestätigt von Arch Team / CISA
@@ -75,6 +51,18 @@ pub enum ConfidenceLevel {
Low, // Einzelner Report
}
impl std::fmt::Display for ConfidenceLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
ConfidenceLevel::Critical => "Critical",
ConfidenceLevel::High => "High",
ConfidenceLevel::Medium => "Medium",
ConfidenceLevel::Low => "Low",
};
write!(f, "{}", s)
}
}
pub struct IocFetcher {
client: reqwest::Client,
cache_dir: std::path::PathBuf,
@@ -142,9 +130,12 @@ impl IocFetcher {
if cache_file.exists() {
let metadata = fs::metadata(&cache_file).await?;
let modified = metadata.modified()?;
let age = Instant::now() - modified;
let modified_datetime: chrono::DateTime<chrono::Local> = modified.into();
let now = chrono::Local::now();
let age = now.signed_duration_since(modified_datetime);
if age < self.cache_ttl {
let cache_ttl_duration = chrono::Duration::from_std(self.cache_ttl)?;
if age < cache_ttl_duration {
let content = fs::read_to_string(&cache_file).await?;
let iocs: Vec<IocEntry> = serde_json::from_str(&content)
.context("Konnte Cache nicht parsen")?;
+3 -3
View File
@@ -72,8 +72,8 @@ async fn main() -> Result<()> {
.init();
let cli = Cli::parse();
let config = AegisConfig::load_or_default()?;
let scanner = PackageScanner::new(config).await?;
let config = AegisConfig::load_or_default().await?;
let mut scanner = PackageScanner::new(config).await?;
match cli.command {
Commands::Scan { package, verbose } => {
@@ -97,7 +97,7 @@ async fn main() -> Result<()> {
} else {
println!("{} {}", "⚠️ Bedrohungen gefunden:".red().bold(), threats.len());
for threat in threats {
println!(" {} {} - {}", "🔴".red(), threat.package, threat.reason);
println!(" {} {} - {}", "🔴".red(), threat.package, threat.action_required);
}
}
}
+2 -1
View File
@@ -57,7 +57,8 @@ pub struct PackageScanner {
impl PackageScanner {
pub async fn new(config: AegisConfig) -> Result<Self> {
let cache_dir = dirs::cache_dir()
let cache_dir = directories::ProjectDirs::from("eu", "heimatlosen", "aegisaur")
.map(|pd| pd.cache_dir().to_path_buf())
.unwrap_or_else(|| PathBuf::from("/tmp"))
.join("aegisaur");