v0.1.0: logo, i18n pt/en, CI com caches, testes e documentação
- Logo oficial (sabia.png) e conjunto de ícones do app desktop. - Interface em português e inglês: tradutor por observação do DOM, seletor de idioma e checagem de cobertura de tradução no CI. - CI/CD com caches (rust-cache, .deb do Tauri em cache) e pipeline de release multiplataforma (CLI em 5 alvos + app desktop via tauri-action), templates de issue/PR. - Suíte de testes de integração do sabia-core (scan e2e, handshake/crack 4-way e PMKID, pcap, trilha de auditoria) — 46 testes verdes. - Documentação completa pt/en: README, ROADMAP, SECURITY, CONTRIBUTING, CHANGELOG e docs/ (cli, interface, arquitetura), com enquadramento de uso autorizado. - Correções de clippy (-D warnings) e formatação em toda a árvore. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
df27974359
commit
791538c9d9
112 files changed
+15620
-494
No files matched your search
@@ -0,0 +1,77 @@
|
||||
//! Integração: trilha de auditoria encadeada por hash — grava entradas,
|
||||
//! confirma que a cadeia valida, depois adultera um registro no disco e
|
||||
//! confirma que a verificação detecta a falha.
|
||||
|
||||
mod common;
|
||||
|
||||
use sabia_core::audit::AuditLog;
|
||||
use std::io::Write;
|
||||
|
||||
#[test]
|
||||
fn chain_validates_after_recording_entries() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let path = dir.path().join("audit.log");
|
||||
|
||||
{
|
||||
let mut log = AuditLog::open(&path).expect("open");
|
||||
log.record("monitor-on", "wlan0", "modo monitor ativado")
|
||||
.expect("record 1");
|
||||
log.record("scan-start", "wlan0", "início da captura")
|
||||
.expect("record 2");
|
||||
log.record("deauth", "00:11:22:33:44:55", "teste de deautenticação")
|
||||
.expect("record 3");
|
||||
}
|
||||
|
||||
let entries = AuditLog::read_entries(&path, None).expect("read_entries");
|
||||
assert_eq!(entries.len(), 3);
|
||||
assert_eq!(entries[0].action, "monitor-on");
|
||||
assert_eq!(entries[2].action, "deauth");
|
||||
// cadeia encadeada corretamente
|
||||
assert_eq!(entries[1].prev_hash, entries[0].hash);
|
||||
assert_eq!(entries[2].prev_hash, entries[1].hash);
|
||||
|
||||
let result = AuditLog::verify(&path).expect("verify");
|
||||
assert_eq!(
|
||||
result, None,
|
||||
"cadeia íntegra não deve apontar entrada inválida"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tampering_with_an_entry_breaks_verification() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let path = dir.path().join("audit.log");
|
||||
|
||||
{
|
||||
let mut log = AuditLog::open(&path).expect("open");
|
||||
log.record("monitor-on", "wlan0", "modo monitor ativado")
|
||||
.expect("record 1");
|
||||
log.record("scan-start", "wlan0", "início da captura")
|
||||
.expect("record 2");
|
||||
log.record("scan-stop", "wlan0", "fim da captura")
|
||||
.expect("record 3");
|
||||
}
|
||||
|
||||
// Confirma que, intacta, a cadeia passa.
|
||||
assert_eq!(AuditLog::verify(&path).expect("verify ok"), None);
|
||||
|
||||
// Adultera o "detail" da segunda entrada sem recalcular o hash,
|
||||
// simulando uma edição retroativa do log.
|
||||
let contents = std::fs::read_to_string(&path).expect("read");
|
||||
let mut lines: Vec<String> = contents.lines().map(|l| l.to_string()).collect();
|
||||
assert_eq!(lines.len(), 3);
|
||||
assert!(lines[1].contains("início da captura"));
|
||||
lines[1] = lines[1].replace("início da captura", "evento adulterado");
|
||||
|
||||
let mut file = std::fs::File::create(&path).expect("recreate");
|
||||
for line in &lines {
|
||||
writeln!(file, "{line}").expect("write tampered line");
|
||||
}
|
||||
|
||||
let result = AuditLog::verify(&path).expect("verify");
|
||||
assert_eq!(
|
||||
result,
|
||||
Some(1),
|
||||
"verificação deveria apontar a entrada adulterada (índice 1)"
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user