Skip to content

Commit

Permalink
Moved config to appconfig, moved static ruleset to cloned one, improv…
Browse files Browse the repository at this point in the history
…ed ruleset strategy, created ruleevent, adapt structure to manage ruleevent
  • Loading branch information
okynos committed Apr 24, 2024
1 parent 62898ed commit fe238f1
Show file tree
Hide file tree
Showing 17 changed files with 1,782 additions and 305 deletions.
1,291 changes: 1,291 additions & 0 deletions src/appconfig.rs

Large diffs are not rendered by default.

52 changes: 26 additions & 26 deletions src/auditevent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use serde_json::{json, to_string};
use reqwest::Client;
use std::collections::HashMap;


use crate::config;
use crate::appconfig;
use crate::appconfig::*;
use crate::utils;
use crate::hash;

Expand Down Expand Up @@ -106,10 +106,10 @@ impl Event {
pub fn from(syscall: HashMap<String, String>,
cwd: HashMap<String, String>, proctitle: HashMap<String, String>,
paths: Vec<HashMap<String, String>>,
config: config::Config) -> Self {
cfg: AppConfig) -> Self {

let parent = get_parent(paths.clone(), cwd["cwd"].as_str(), config.clone());
let path = get_item_path(paths.clone(), cwd["cwd"].as_str(), config.clone());
let parent = get_parent(paths.clone(), cwd["cwd"].as_str(), cfg.clone());
let path = get_item_path(paths.clone(), cwd["cwd"].as_str(), cfg.clone());

let command = if proctitle["proctitle"].contains('/') ||
proctitle["proctitle"].contains("bash") {
Expand All @@ -124,26 +124,26 @@ impl Event {
.split(':').collect::<Vec<&str>>()[0]); // Getting the 13 digits timestamp

let event_path = parent["name"].clone();
let index = config.get_index(event_path.as_str(),
cwd["cwd"].as_str(), config.audit.clone().to_vec());
let labels = config.get_labels(index, config.audit.clone());
let index = cfg.get_index(event_path.as_str(),
cwd["cwd"].as_str(), cfg.audit.clone().to_vec());
let labels = cfg.get_labels(index, cfg.audit.clone());

Event{
id: utils::get_uuid(),
proctitle: proctitle["proctitle"].clone(),
command,
timestamp: clean_timestamp,
hostname: utils::get_hostname(),
node: config.node,
version: String::from(config::VERSION),
node: cfg.node,
version: String::from(appconfig::VERSION),
labels,
operation: utils::get_field(path.clone(), "nametype"),
path: utils::clean_path(&event_path),
file: utils::get_filename_path(path["name"].clone().as_str()),
size: utils::get_file_size(path["name"].clone().as_str()),
checksum: hash::get_checksum(format!("{}/{}",
parent["name"].clone(), path["name"].clone()),
config.events_max_file_checksum),
cfg.events_max_file_checksum),
fpid: utils::get_pid(),
system: String::from(utils::get_os()),

Expand Down Expand Up @@ -346,7 +346,7 @@ impl Event {
// ------------------------------------------------------------------------

// Function to send events through network
pub async fn send(&self, index: String, cfg: config::Config) {
pub async fn send(&self, index: String, cfg: AppConfig) {
let event = self.get_json();

// Splunk endpoint integration
Expand Down Expand Up @@ -396,13 +396,13 @@ impl Event {
// ------------------------------------------------------------------------

// Function to manage event destination
pub async fn process(&self, destination: &str, index_name: String, cfg: config::Config){
pub async fn process(&self, destination: &str, index_name: String, cfg: AppConfig){
match destination {
config::BOTH_MODE => {
appconfig::BOTH_MODE => {
self.log(&cfg.get_events_file());
self.send(index_name, cfg).await;
},
config::NETWORK_MODE => {
appconfig::NETWORK_MODE => {
self.send(index_name, cfg).await;
},
_ => self.log(&cfg.get_events_file())
Expand All @@ -421,7 +421,7 @@ fn get_field(map: HashMap<String, String>,field: &str) -> String {

// ----------------------------------------------------------------------------

pub fn get_parent(paths: Vec<HashMap<String, String>>, cwd: &str, cfg: config::Config) -> HashMap<String, String> {
pub fn get_parent(paths: Vec<HashMap<String, String>>, cwd: &str, cfg: AppConfig) -> HashMap<String, String> {
match paths.iter().find(|p|{
utils::get_field((*p).clone(), "nametype") == "PARENT" &&
cfg.path_in(p["name"].as_str(), cwd, cfg.audit.clone())
Expand All @@ -433,7 +433,7 @@ pub fn get_parent(paths: Vec<HashMap<String, String>>, cwd: &str, cfg: config::C

// ----------------------------------------------------------------------------

pub fn get_item_path(paths: Vec<HashMap<String, String>>, cwd: &str, cfg: config::Config) -> HashMap<String, String> {
pub fn get_item_path(paths: Vec<HashMap<String, String>>, cwd: &str, cfg: AppConfig) -> HashMap<String, String> {
match paths.iter().rfind(|p|{
utils::get_field((*p).clone(), "nametype") != "PARENT" &&
utils::get_field((*p).clone(), "nametype") != "UNKNOWN" &&
Expand Down Expand Up @@ -504,7 +504,7 @@ impl fmt::Debug for Event {
mod tests {
use super::*;
use crate::auditevent::Event;
use crate::config::Config;
use crate::appconfig::*;
use tokio_test::block_on;
use std::fs;

Expand Down Expand Up @@ -585,7 +585,7 @@ mod tests {
#[test]
fn test_from() {
if utils::get_os() == "linux" {
let cfg = Config::new(&utils::get_os(),
let cfg = AppConfig::new(&utils::get_os(),
Some("test/unit/config/linux/audit_from_test.yml"));
let syscall = HashMap::<String, String>::from([
(String::from("syscall"), String::from("syscall")),
Expand Down Expand Up @@ -673,7 +673,7 @@ mod tests {
assert_eq!(String::from("1659026449689"), event.timestamp);
assert_eq!(utils::get_hostname(), event.hostname);
assert_eq!(String::from("FIM"), event.node);
assert_eq!(String::from(config::VERSION), event.version);
assert_eq!(String::from(appconfig::VERSION), event.version);
assert_eq!(String::from("/tmp"), event.path);
assert_eq!(String::from("test.txt"), event.file);
assert_eq!(0, event.size);
Expand Down Expand Up @@ -940,7 +940,7 @@ mod tests {
#[test]
fn test_send() {
let event = create_test_event();
let cfg = config::Config::new(&utils::get_os(), None);
let cfg = AppConfig::new(&utils::get_os(), None);
block_on( event.send(String::from("test"), cfg) );
}

Expand All @@ -949,20 +949,20 @@ mod tests {
#[test]
fn test_send_splunk() {
let event = create_test_event();
let cfg = Config::new(&utils::get_os(), Some("test/unit/config/common/test_send_splunk.yml"));
let cfg = AppConfig::new(&utils::get_os(), Some("test/unit/config/common/test_send_splunk.yml"));
block_on( event.send(String::from("test"), cfg) );
}

// ------------------------------------------------------------------------

#[test]
fn test_process() {
let cfg = Config::new(&utils::get_os(), None);
let cfg = AppConfig::new(&utils::get_os(), None);
let event = create_test_event();

block_on(event.process(config::NETWORK_MODE, String::from("test"), cfg.clone()));
block_on(event.process(config::FILE_MODE, String::from("test2"), cfg.clone()));
block_on(event.process(config::BOTH_MODE, String::from("test3"), cfg.clone()));
block_on(event.process(appconfig::NETWORK_MODE, String::from("test"), cfg.clone()));
block_on(event.process(appconfig::FILE_MODE, String::from("test2"), cfg.clone()));
block_on(event.process(appconfig::BOTH_MODE, String::from("test3"), cfg.clone()));
}

// ------------------------------------------------------------------------
Expand Down
20 changes: 10 additions & 10 deletions src/event.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
// Copyright (C) 2021, Achiefs.

use crate::config;
use crate::appconfig::*;
use crate::ruleset::*;

use notify::event::*;

pub trait Event {
fn format_json(&self) -> String;
fn clone(&self) -> Self;
fn log(&self, file: String);
async fn send(&self, cfg: config::Config);
//async fn route(&self);
async fn process(&self, cfg: config::Config);
async fn send(&self, cfg: AppConfig);
async fn process(&self, cfg: AppConfig, _ruleset: Ruleset);
fn get_string(&self, field: String) -> String;
}

// ----------------------------------------------------------------------------

/*pub async fn route(event: &dyn Event) {
let config = unsafe { super::GCONFIG.clone().unwrap() };
match config.get_events_destination().as_str() {
config::BOTH_MODE => {
event.log(config.get_events_file());
let cfg = unsafe { super::GCONFIG.clone().unwrap() };
match cfg.get_events_destination().as_str() {
appconfig::BOTH_MODE => {
event.log(cfg.get_events_file());
event.send().await;
},
config::NETWORK_MODE => {
appconfig::NETWORK_MODE => {
event.send().await;
},
_ => event.log(config.get_events_file())
_ => event.log(cfg.get_events_file())
}
}*/

Expand Down
4 changes: 2 additions & 2 deletions src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub fn get_checksum(filename: String, read_limit: usize) -> String {
iteration += 1;
};
if data_read > read_limit {
info!("File '{}' checksum skipped. File size is above limit", filename);
info!("File '{}' checksum skipped. File size is above limit.", filename);
String::from("UNKNOWN")
}else{
encode(hasher.finalize())
Expand All @@ -63,7 +63,7 @@ pub fn get_checksum(filename: String, read_limit: usize) -> String {
}
}
}else{
debug!("Cannot produce checksum of a directory");
debug!("Cannot produce checksum of a removed file or directory.");
String::from("UNKNOWN")
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::path::Path;
// Handle time intervals
use std::time::Duration;

use crate::config;
use crate::appconfig::*;

fn get_template_path() -> String {
let relative_path = "./../../config/index_template.json";
Expand All @@ -32,7 +32,7 @@ fn get_template_path() -> String {

// ----------------------------------------------------------------------------

pub async fn push_template(cfg: config::Config){
pub async fn push_template(cfg: AppConfig){
let template_path = get_template_path();
info!("Loaded index template from: {}", template_path);
let file = File::open(template_path).await.unwrap();
Expand Down Expand Up @@ -64,13 +64,13 @@ pub async fn push_template(cfg: config::Config){
#[cfg(test)]
mod tests {
use super::*;
use crate::config;
use crate::appconfig;
use crate::utils;

#[test]
fn test_push_template() {
tokio_test::block_on( push_template(
config::Config::new(&utils::get_os(), Some("test/unit/config/common/test_push_template.yml"))));
AppConfig::new(&utils::get_os(), Some("test/unit/config/common/test_push_template.yml"))));
}

#[test]
Expand Down
43 changes: 43 additions & 0 deletions src/init.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (C) 2024, Achiefs.

use crate::ruleset::Ruleset;
use crate::appconfig::*;
use crate::utils;


pub fn init() -> (AppConfig, Ruleset) {
use std::path::Path;
use simplelog::WriteLogger;
use simplelog::Config;
use std::fs;

println!("[INFO] Achiefs File Integrity Monitoring software starting!");
println!("[INFO] Reading config...");
let cfg = AppConfig::new(&utils::get_os(), None);

// Create folders to store logs based on config.yml
fs::create_dir_all(
Path::new( &cfg.clone().log_file
).parent().unwrap().to_str().unwrap()
).unwrap();

// Create logger output to write generated logs.
WriteLogger::init(
cfg.clone().get_level_filter(),
Config::default(),
fs::OpenOptions::new()
.create(true)
.append(true)
.open(cfg.clone().log_file)
.expect("Unable to open log file")
).unwrap();

println!("[INFO] Configuration successfully read, forwarding output to log file.");
println!("[INFO] Log file: '{}'", cfg.clone().log_file);
println!("[INFO] Log level: '{}'", cfg.clone().log_level);

let ruleset = Ruleset::new(&utils::get_os(), None);

log_panics::init();
(cfg, ruleset)
}
14 changes: 7 additions & 7 deletions src/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl fmt::Debug for Integration {
mod tests {
use super::*;
use notify::event::*;
use crate::config::*;
use crate::appconfig::*;
use std::path::PathBuf;
use crate::monitorevent::MonitorEvent;

Expand Down Expand Up @@ -201,9 +201,9 @@ mod tests {
#[cfg(target_os = "windows")]
#[test]
fn test_get_event_integration_windows() {
let config = Config::new("windows", Some("test/unit/config/windows/monitor_integration.yml"));
let cfg = AppConfig::new("windows", Some("test/unit/config/windows/monitor_integration.yml"));

let integrations = config.get_integrations(2, config.monitor.clone());
let integrations = cfg.get_integrations(2, cfg.monitor.clone());
let event = create_dummy_event_windows("tmp", "CREATE");
let integration = get_event_integration(event, integrations.clone()).unwrap();

Expand All @@ -215,7 +215,7 @@ mod tests {
assert_eq!(integration.script, "C:\\tmp\\remover.ps1");
assert_eq!(integration.parameters, "");

let integrations2 = config.get_integrations(3, config.monitor.clone());
let integrations2 = cfg.get_integrations(3, cfg.monitor.clone());
let event2 = create_dummy_event_windows("tmp2", "MODIFY");
let integration2 = get_event_integration(event2, integrations2.clone()).unwrap();

Expand All @@ -234,10 +234,10 @@ mod tests {
#[test]
fn test_get_event_integration_unix() {
let os = utils::get_os();
let config = Config::new(&os, Some(format!("test/unit/config/{}/monitor_integration.yml", os).as_str()));
let cfg = AppConfig::new(&os, Some(format!("test/unit/config/{}/monitor_integration.yml", os).as_str()));

let event = create_dummy_event_unix("etc", "CREATE");
let integrations = config.get_integrations(2, config.monitor.clone());
let integrations = cfg.get_integrations(2, cfg.monitor.clone());
let integration = get_event_integration(event, integrations).unwrap();

assert_eq!(integration.name, "rmfile");
Expand All @@ -249,7 +249,7 @@ mod tests {
assert_eq!(integration.parameters, "");

let event2 = create_dummy_event_unix("etc2", "MODIFY");
let integrations2 = config.get_integrations(3, config.monitor.clone());
let integrations2 = cfg.get_integrations(3, cfg.monitor.clone());
let integration2 = get_event_integration(event2, integrations2).unwrap();

assert_eq!(integration2.name, "rmfile2");
Expand Down
Loading

0 comments on commit fe238f1

Please sign in to comment.