rulefile error handling is implemented

This commit is contained in:
ichiichi11
2020-11-22 11:05:52 +09:00
parent d976ddc4d0
commit da5f4119fb
2 changed files with 46 additions and 19 deletions

View File

@@ -6,7 +6,7 @@ use crate::detections::rule;
use crate::detections::rule::RuleNode; use crate::detections::rule::RuleNode;
use crate::yaml::ParseYaml; use crate::yaml::ParseYaml;
use chrono::{TimeZone, Utc}; use chrono::{DateTime, FixedOffset, ParseError, ParseResult, TimeZone, Utc};
use evtx::EvtxParser; use evtx::EvtxParser;
use serde_json::{Error, Value}; use serde_json::{Error, Value};
@@ -30,7 +30,7 @@ impl Detection {
return Option::None; return Option::None;
} }
//// refer https://rust-lang-nursery.github.io/rust-cookbook/encoding/complex.html //// https://rust-lang-nursery.github.io/rust-cookbook/encoding/complex.html
let result_json: Result<Value, Error> = let result_json: Result<Value, Error> =
serde_json::from_str(&result_record.unwrap().data); serde_json::from_str(&result_record.unwrap().data);
if result_json.is_err() { if result_json.is_err() {
@@ -55,19 +55,24 @@ impl Detection {
.into_iter() .into_iter()
.map(|rule_file| rule::parse_rule(rule_file)) .map(|rule_file| rule::parse_rule(rule_file))
.filter_map(|mut rule| { .filter_map(|mut rule| {
return rule let err_msgs_result = rule.init();
.init() if err_msgs_result.is_ok() {
.or_else(|err_msgs| { return Option::Some(rule);
print!( }
"Failed to parse Rule file. See following detail. [rule file title:{}]",
rule.yaml["title"].as_str().unwrap_or("") // ruleファイルの初期化失敗時のエラーを表示する部分
); err_msgs_result.err().iter().for_each(|err_msgs| {
err_msgs.iter().for_each(|err_msg| println!("{}", err_msg)); // TODO 本当はファイルパスを出力したい
println!("\n"); // ParseYamlの変更が必要なので、一旦yamlのタイトルを表示。
return Result::Err(err_msgs); println!(
}) "[Failed to parse Rule file. See following detail. rule file title:{}]",
.and_then(|_empty| Result::Ok(rule)) rule.yaml["title"].as_str().unwrap_or("")
.ok(); );
err_msgs.iter().for_each(|err_msg| println!("{}", err_msg));
println!("");
});
return Option::None;
}) })
.collect(); .collect();
@@ -78,14 +83,35 @@ impl Detection {
.iter() .iter()
.filter(|event_record| rule.select(event_record)) .filter(|event_record| rule.select(event_record))
.for_each(|event_record| { .for_each(|event_record| {
message.insert( let event_time = Detection::get_event_time(event_record);
Utc.ymd(1996, 2, 27).and_hms(1, 5, 1), // TODO ログから日付がとれない場合に本当は時刻不明という感じで表示したい。
event_record.to_string(), // しかし、Messageクラスのinsertメソッドが、UTCクラスのインスタンスを必ず渡すようなインタフェースになっているので、
) // やむなくUtc.ymd(1970, 1, 1).and_hms(0, 0, 0)を渡している。
// Messageクラスのinsertメソッドの引数をDateTime<UTC>からOption<DateTime<UTC>>に変更して、
// insertメソッドでOption::Noneが渡された場合に時刻不明だと分かるように表示させるような実装にした方がいいかも
let utc_event_time = event_time
.and_then(|datetime| {
let utc = Utc.from_local_datetime(&datetime.naive_utc()).unwrap();
return Option::Some(utc);
})
.or(Option::Some(Utc.ymd(1970, 1, 1).and_hms(0, 0, 0)));
message.insert(utc_event_time.unwrap(), event_record.to_string())
}); });
}); });
// output message // output message
message.debug(); message.debug();
} }
fn get_event_time(event_record: &Value) -> Option<DateTime<FixedOffset>> {
let system_time =
&event_record["Event"]["System"]["TimeCreated"]["#attributes"]["SystemTime"];
let system_time_str = system_time.as_str().unwrap_or("");
if system_time_str.is_empty() {
return Option::None;
}
return DateTime::parse_from_rfc3339(system_time_str).ok();
}
} }

View File

@@ -383,6 +383,7 @@ impl LeafMatcher for RegexMatcher {
); );
return Result::Err(vec![errmsg]); return Result::Err(vec![errmsg]);
} }
self.re = re_result.ok();
return Result::Ok(()); return Result::Ok(());
} }