Skip to content

Commit fbce66e

Browse files
authored
Create main.rs
1 parent bbffbf6 commit fbce66e

File tree

1 file changed

+125
-0
lines changed
  • modules/security/integrity/src

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
use sha2::{Sha256, Digest};
2+
use std::fs;
3+
use std::io;
4+
use std::collections::{HashMap, HashSet};
5+
use std::path::Path;
6+
use walkdir::WalkDir;
7+
use serde::Deserialize; // Tambahkan ini
8+
9+
// 1. Definisikan struktur sesuai isi JSON bertingkat kamu
10+
#[derive(Deserialize)]
11+
struct FileInfo {
12+
sha256: String,
13+
#[allow(dead_code)]
14+
size_bytes: u64,
15+
}
16+
17+
// Fungsi untuk menghitung Hash SHA256 dari sebuah file
18+
fn calculate_hash(path: &Path) -> io::Result<String> {
19+
let mut file = fs::File::open(path)?;
20+
let mut hasher = Sha256::new();
21+
io::copy(&mut file, &mut hasher)?;
22+
Ok(format!("{:x}", hasher.finalize()))
23+
}
24+
25+
fn main() {
26+
let db_path = "tests/database/signed_manifest.json";
27+
28+
// Daftar folder dan file yang wajib diabaikan
29+
let ignored_items = [
30+
".git",
31+
"__pycache__",
32+
".pytest_cache",
33+
".github",
34+
"storm.db",
35+
"signed_manifest.json",
36+
"script/integrity",
37+
"target" // Tambahkan target agar tidak men-scan hasil compile sendiri
38+
];
39+
40+
// 1. Load Database JSON
41+
let data = match fs::read_to_string(db_path) {
42+
Ok(content) => content,
43+
Err(_) => {
44+
println!("[-] ERROR: Manifest file not found in {}", db_path);
45+
return;
46+
}
47+
};
48+
49+
// 2. Gunakan HashMap<String, FileInfo> karena JSON kamu bertingkat
50+
let database: HashMap<String, FileInfo> = match serde_json::from_str(&data) {
51+
Ok(map) => map,
52+
Err(_) => {
53+
println!("[-] ERROR: JSON format in {} damaged or incompatible!", db_path);
54+
return;
55+
}
56+
};
57+
58+
let mut verified_count = 0;
59+
let mut untracked_files = Vec::new();
60+
let mut modified_files = Vec::new();
61+
let mut found_in_disk = HashSet::new();
62+
63+
println!("[*] Starting Integrity Deep Scan...");
64+
65+
// 3. Scan Seluruh Penjuru Tools (Rekursif)
66+
for entry in WalkDir::new(".").into_iter().filter_map(|e| e.ok()) {
67+
let path = entry.path();
68+
let path_str = path.to_str().unwrap_or("");
69+
70+
// Cek filter pengabaian
71+
if ignored_items.iter().any(|&ignored| path_str.contains(ignored)) {
72+
continue;
73+
}
74+
75+
if path.is_file() {
76+
let clean_path = path_str.strip_prefix("./").unwrap_or(path_str);
77+
found_in_disk.insert(clean_path.to_string());
78+
79+
match database.get(clean_path) {
80+
Some(info) => {
81+
let current_hash = calculate_hash(path).unwrap_or_default();
82+
// Bandingkan dengan field sha256 di dalam objek JSON
83+
if current_hash == info.sha256 {
84+
verified_count += 1;
85+
} else {
86+
modified_files.push(clean_path.to_string());
87+
}
88+
}
89+
None => {
90+
untracked_files.push(clean_path.to_string());
91+
}
92+
}
93+
}
94+
}
95+
96+
// 4. Output Hasil Audit (Sudah diperbaiki dengan & agar tidak error move)
97+
if !modified_files.is_empty() {
98+
println!("\n[!] WARNING: The Following Files Have Been Modified!");
99+
for f in &modified_files { println!(" -> {}", f); }
100+
}
101+
102+
if !untracked_files.is_empty() {
103+
println!("\n[?] INFO: Illegal/Unknown Files Found!");
104+
for f in &untracked_files { println!(" -> {}", f); }
105+
}
106+
107+
let mut missing_files = Vec::new();
108+
for (json_path, _) in &database {
109+
if !found_in_disk.contains(json_path) {
110+
missing_files.push(json_path);
111+
}
112+
}
113+
114+
if !missing_files.is_empty() {
115+
println!("\n[!] WARNING: Files Listed But Missing on Disk!");
116+
for f in &missing_files { println!(" -> {}", f); }
117+
}
118+
119+
println!("\n[*] Audit Completed.");
120+
println!("[*] Synchronous: {} | Modified: {} | Untracked: {}",
121+
verified_count,
122+
modified_files.len(),
123+
untracked_files.len());
124+
}
125+

0 commit comments

Comments
 (0)