Add ./src/hook.rs
This commit is contained in:
+147
@@ -0,0 +1,147 @@
|
|||||||
|
use anyhow::{Context, Result};
|
||||||
|
use std::io::Write;
|
||||||
|
use std::path::Path;
|
||||||
|
use tracing::{info, warn};
|
||||||
|
|
||||||
|
const ALPM_HOOK_PATH: &str = "/usr/share/libalpm/hooks/aegisaur-pre-install.hook";
|
||||||
|
const HOOK_SCRIPT_PATH: &str = "/usr/share/libalpm/hooks/aegisaur-check.sh";
|
||||||
|
|
||||||
|
/// Installiert den ALPM-Hook für Pre-Install-Checks
|
||||||
|
pub fn install_alpm_hook() -> Result<()> {
|
||||||
|
// Hook-Definition
|
||||||
|
let hook_content = r#"[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = *
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = AegisAUR Security Scan
|
||||||
|
When = PreTransaction
|
||||||
|
Exec = /usr/share/libalpm/hooks/aegisaur-check.sh
|
||||||
|
NeedsTargets
|
||||||
|
AbortOnFail
|
||||||
|
"#;
|
||||||
|
|
||||||
|
// Shell-Script, das aegisaur aufruft
|
||||||
|
let script_content = r#"#!/bin/bash
|
||||||
|
# AegisAUR Pre-Install Hook
|
||||||
|
# Prüft Pakete vor der Installation
|
||||||
|
|
||||||
|
AUR_SCANNER="/usr/bin/aegisaur"
|
||||||
|
TMPFILE=$(mktemp)
|
||||||
|
|
||||||
|
# Alle zu installierenden Pakete durch aegisaur prüfen
|
||||||
|
while read -r package; do
|
||||||
|
# Nur AUR-Pakete prüfen (Foreign packages)
|
||||||
|
if pacman -Qi "$package" >/devdev/null 2>&1; then
|
||||||
|
# Paket ist bereits installiert (Upgrade)
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prüfe ob es ein AUR/Foreign Paket ist
|
||||||
|
if pacman -Si "$package" >/dev/null 2>&1; then
|
||||||
|
# Offizielles Repo-Paket, immer OK
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# AUR Paket gefunden - scanne es
|
||||||
|
if [[ -x "$AUR_SCANNER" ]]; then
|
||||||
|
RESULT=$($AUR_SCANNER scan "$package" --json 2>/devnull)
|
||||||
|
SCORE=$(echo "$RESULT" | grep -oP '"score":\s*\K\d+')
|
||||||
|
STATUS=$(echo "$RESULT" | grep -oP '"status":\s*"\K[^"]+')
|
||||||
|
|
||||||
|
if [[ "$STATUS" == "IOCDetected" ]] || [[ "$STATUS" == "Dangerous" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ 🚨 AEGISAUR SECURITY ALERT 🚨 ║"
|
||||||
|
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo "Paket: $package"
|
||||||
|
echo "Status: $STATUS"
|
||||||
|
echo "Score: $SCORE/100"
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ DIESES PAKET IST ALS GEFÄHRLICH EINGESTUFT!"
|
||||||
|
echo ""
|
||||||
|
echo "Möchtest du die Installation abbrechen? (Ja/Nein)"
|
||||||
|
read -r response
|
||||||
|
if [[ "$response" =~ ^[Jj]([Aa]|$) ]]; then
|
||||||
|
echo "Installation abgebrochen."
|
||||||
|
rm -f "$TMPFILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "WARNUNG: Installation wird fortgesetzt auf eigenes Risiko!"
|
||||||
|
echo "$package ($STATUS - Score: $SCORE)" >> "$TMPFILE"
|
||||||
|
elif [[ "$STATUS" == "Suspicious" ]] || [[ "$STATUS" == "Warning" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ AegisAUR Warnung für $package: $STATUS (Score: $SCORE/100)"
|
||||||
|
echo "$package ($STATUS - Score: $SCORE)" >> "$TMPFILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Zusammenfassung anzeigen falls Warnungen vorhanden
|
||||||
|
if [[ -s "$TMPFILE" ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "╔══════════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ AegisAUR Scan Zusammenfassung ║"
|
||||||
|
echo "╚══════════════════════════════════════════════════════════════╝"
|
||||||
|
cat "$TMPFILE"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f "$TMPFILE"
|
||||||
|
exit 0
|
||||||
|
"#;
|
||||||
|
|
||||||
|
// Hook-Datei schreiben
|
||||||
|
info!("Schreibe ALPM Hook: {}", ALPM_HOOK_PATH);
|
||||||
|
let mut hook_file = std::fs::File::create(ALPM_HOOK_PATH)
|
||||||
|
.context("Konnte ALPM Hook nicht erstellen (Root-Rechte nötig)")?;
|
||||||
|
hook_file.write_all(hook_content.as_bytes())?;
|
||||||
|
|
||||||
|
// Script schreiben
|
||||||
|
info!("Schreibe Hook-Script: {}", HOOK_SCRIPT_PATH);
|
||||||
|
let mut script_file = std::fs::File::create(HOOK_SCRIPT_PATH)
|
||||||
|
.context("Konnte Hook-Script nicht erstellen")?;
|
||||||
|
script_file.write_all(script_content.as_bytes())?;
|
||||||
|
|
||||||
|
// Script executable machen
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
let mut perms = std::fs::metadata(HOOK_SCRIPT_PATH)?.permissions();
|
||||||
|
perms.set_mode(0o755);
|
||||||
|
std::fs::set_permissions(HOOK_SCRIPT_PATH, perms)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("ALPM Hook erfolgreich installiert");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Entfernt den ALPM-Hook
|
||||||
|
pub fn remove_alpm_hook() -> Result<()> {
|
||||||
|
info!("Entferne ALPM Hook...");
|
||||||
|
|
||||||
|
if Path::new(ALPM_HOOK_PATH).exists() {
|
||||||
|
std::fs::remove_file(ALPM_HOOK_PATH)?;
|
||||||
|
info!("Hook-Datei entfernt: {}", ALPM_HOOK_PATH);
|
||||||
|
} else {
|
||||||
|
warn!("Hook-Datei nicht gefunden: {}", ALPM_HOOK_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if Path::new(HOOK_SCRIPT_PATH).exists() {
|
||||||
|
std::fs::remove_file(HOOK_SCRIPT_PATH)?;
|
||||||
|
info!("Script entfernt: {}", HOOK_SCRIPT_PATH);
|
||||||
|
} else {
|
||||||
|
warn!("Script nicht gefunden: {}", HOOK_SCRIPT_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("ALPM Hook erfolgreich entfernt");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prüft ob Hook installiert ist
|
||||||
|
pub fn is_hook_installed() -> bool {
|
||||||
|
Path::new(ALPM_HOOK_PATH).exists() && Path::new(HOOK_SCRIPT_PATH).exists()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user