fixed error

- changed writer from stderr to bufwriter

- changed alert,warn function arg fro String to borrow-String
This commit is contained in:
DustInDark
2021-12-21 14:44:26 +09:00
parent f1c9418ab4
commit bccdd8fef9
7 changed files with 184 additions and 119 deletions

View File

@@ -36,8 +36,8 @@ pub struct DisplayFormat<'a> {
pub fn after_fact() { pub fn after_fact() {
let fn_emit_csv_err = |err: Box<dyn Error>| { let fn_emit_csv_err = |err: Box<dyn Error>| {
AlertMessage::alert( AlertMessage::alert(
&mut std::io::stderr().lock(), &mut BufWriter::new(std::io::stderr().lock()),
format!("Failed to write CSV. {}", err), &format!("Failed to write CSV. {}", err),
) )
.ok(); .ok();
process::exit(1); process::exit(1);
@@ -51,8 +51,8 @@ pub fn after_fact() {
Ok(file) => Box::new(BufWriter::new(file)), Ok(file) => Box::new(BufWriter::new(file)),
Err(err) => { Err(err) => {
AlertMessage::alert( AlertMessage::alert(
&mut std::io::stderr().lock(), &mut BufWriter::new(std::io::stderr().lock()),
format!("Failed to open file. {}", err), &format!("Failed to open file. {}", err),
) )
.ok(); .ok();
process::exit(1); process::exit(1);

View File

@@ -5,6 +5,7 @@ use clap::{App, AppSettings, ArgMatches};
use hashbrown::HashMap; use hashbrown::HashMap;
use hashbrown::HashSet; use hashbrown::HashSet;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::io::BufWriter;
use std::sync::RwLock; use std::sync::RwLock;
lazy_static! { lazy_static! {
pub static ref CONFIG: RwLock<ConfigReader> = RwLock::new(ConfigReader::new()); pub static ref CONFIG: RwLock<ConfigReader> = RwLock::new(ConfigReader::new());
@@ -140,8 +141,8 @@ impl TargetEventTime {
Ok(dt) => Some(dt.with_timezone(&Utc)), Ok(dt) => Some(dt.with_timezone(&Utc)),
Err(err) => { Err(err) => {
AlertMessage::alert( AlertMessage::alert(
&mut std::io::stderr().lock(), &mut BufWriter::new(std::io::stderr().lock()),
format!("start-timeline field: {}", err), &format!("start-timeline field: {}", err),
) )
.ok(); .ok();
None None
@@ -157,8 +158,8 @@ impl TargetEventTime {
Ok(dt) => Some(dt.with_timezone(&Utc)), Ok(dt) => Some(dt.with_timezone(&Utc)),
Err(err) => { Err(err) => {
AlertMessage::alert( AlertMessage::alert(
&mut std::io::stderr().lock(), &mut BufWriter::new(std::io::stderr().lock()),
format!("end-timeline field: {}", err), &format!("end-timeline field: {}", err),
) )
.ok(); .ok();
None None

View File

@@ -1,8 +1,10 @@
extern crate csv; extern crate csv;
use crate::detections::configs;
use crate::detections::print::AlertMessage; use crate::detections::print::AlertMessage;
use crate::detections::print::ERROR_LOG_PATH; use crate::detections::print::ERROR_LOG_PATH;
use crate::detections::print::MESSAGES; use crate::detections::print::MESSAGES;
use crate::detections::print::QUIET_ERRORS_FLAG;
use crate::detections::rule; use crate::detections::rule;
use crate::detections::rule::AggResult; use crate::detections::rule::AggResult;
use crate::detections::rule::RuleNode; use crate::detections::rule::RuleNode;
@@ -88,10 +90,10 @@ impl Detection {
err_msgs_result.err().iter().for_each(|err_msgs| { err_msgs_result.err().iter().for_each(|err_msgs| {
let errmsg_body = let errmsg_body =
format!("Failed to parse rule file. (FilePath : {})", rule.rulepath); format!("Failed to parse rule file. (FilePath : {})", rule.rulepath);
AlertMessage::warn(&mut std::io::stdout().lock(), errmsg_body).ok(); AlertMessage::warn(&mut std::io::stdout().lock(), &errmsg_body).ok();
err_msgs.iter().for_each(|err_msg| { err_msgs.iter().for_each(|err_msg| {
AlertMessage::warn(&mut std::io::stdout().lock(), err_msg.to_string()).ok(); AlertMessage::warn(&mut std::io::stdout().lock(), &err_msg.to_string()).ok();
}); });
parseerror_count += 1; parseerror_count += 1;
println!(""); // 一行開けるためのprintln println!(""); // 一行開けるためのprintln

View File

@@ -249,6 +249,7 @@ impl AlertMessage {
mod tests { mod tests {
use crate::detections::print::{AlertMessage, Message}; use crate::detections::print::{AlertMessage, Message};
use serde_json::Value; use serde_json::Value;
use std::io::BufWriter;
#[test] #[test]
fn test_create_and_append_message() { fn test_create_and_append_message() {
@@ -361,17 +362,21 @@ mod tests {
#[test] #[test]
fn test_error_message() { fn test_error_message() {
let input = "TEST!"; let input = "TEST!";
let stdout = std::io::stdout(); AlertMessage::alert(
let mut stdout = stdout.lock(); &mut BufWriter::new(std::io::stdout().lock()),
AlertMessage::alert(&mut stdout, input.to_string()).expect("[ERROR] TEST!"); &input.to_string(),
)
.expect("[ERROR] TEST!");
} }
#[test] #[test]
fn test_warn_message() { fn test_warn_message() {
let input = "TESTWarn!"; let input = "TESTWarn!";
let stdout = std::io::stdout(); AlertMessage::warn(
let mut stdout = stdout.lock(); &mut BufWriter::new(std::io::stdout().lock()),
AlertMessage::warn(&mut stdout, input.to_string()).expect("[WARN] TESTWarn!"); &input.to_string(),
)
.expect("[WARN] TESTWarn!");
} }
#[test] #[test]

View File

@@ -1,5 +1,7 @@
use crate::detections::configs;
use crate::detections::print::AlertMessage; use crate::detections::print::AlertMessage;
use crate::detections::print::ERROR_LOG_PATH; use crate::detections::print::ERROR_LOG_PATH;
use crate::detections::print::QUIET_ERRORS_FLAG;
use crate::detections::rule::AggResult; use crate::detections::rule::AggResult;
use crate::detections::rule::AggregationParseInfo; use crate::detections::rule::AggregationParseInfo;
use crate::detections::rule::Message; use crate::detections::rule::Message;
@@ -69,35 +71,41 @@ fn get_alias_value_in_record(
return Some(value.to_string().replace("\"", "")); return Some(value.to_string().replace("\"", ""));
} }
None => { None => {
AlertMessage::alert( let errmsg = match is_by_alias {
&mut BufWriter::new( true => format!(
OpenOptions::new() "count by clause alias value not found in count process. rule file:{} EventID:{}",
.append(true) Path::new(&rule.rulepath)
.open(ERROR_LOG_PATH.to_string()) .file_name()
.unwrap(), .unwrap()
), .to_str()
match is_by_alias { .unwrap(),
true => format!( utils::get_event_value(&utils::get_event_id_key(), record).unwrap()
"count by clause alias value not found in count process. rule file:{} EventID:{}", ),
Path::new(&rule.rulepath) false => format!(
.file_name() "count field clause alias value not found in count process. rule file:{} EventID:{}",
.unwrap() Path::new(&rule.rulepath)
.to_str() .file_name()
.unwrap(), .unwrap()
utils::get_event_value(&utils::get_event_id_key(), record).unwrap() .to_str()
), .unwrap(),
false => format!( utils::get_event_value(&utils::get_event_id_key(), record).unwrap()
"count field clause alias value not found in count process. rule file:{} EventID:{}", ),
Path::new(&rule.rulepath) };
.file_name() if configs::CONFIG.read().unwrap().args.is_present("verbose") {
.unwrap() AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok();
.to_str() }
.unwrap(), if !*QUIET_ERRORS_FLAG {
utils::get_event_value(&utils::get_event_id_key(), record).unwrap() AlertMessage::alert(
), &mut BufWriter::new(
}, OpenOptions::new()
) .append(true)
.ok(); .open(ERROR_LOG_PATH.to_string())
.unwrap(),
),
&errmsg,
)
.ok();
}
return None; return None;
} }
}; };
@@ -190,16 +198,22 @@ impl TimeFrameInfo {
ttype = "d".to_owned(); ttype = "d".to_owned();
tnum.retain(|c| c != 'd'); tnum.retain(|c| c != 'd');
} else { } else {
AlertMessage::alert( let errmsg = format!("Timeframe is invalid. Input value:{}", value);
&mut BufWriter::new( if configs::CONFIG.read().unwrap().args.is_present("verbose") {
OpenOptions::new() AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok();
.append(true) }
.open(ERROR_LOG_PATH.to_string()) if !*QUIET_ERRORS_FLAG {
.unwrap(), AlertMessage::alert(
), &mut BufWriter::new(
format!("Timeframe is invalid. Input value:{}", value), OpenOptions::new()
) .append(true)
.ok(); .open(ERROR_LOG_PATH.to_string())
.unwrap(),
),
&errmsg,
)
.ok();
}
} }
return TimeFrameInfo { return TimeFrameInfo {
timetype: ttype, timetype: ttype,
@@ -227,16 +241,22 @@ pub fn get_sec_timeframe(timeframe: &Option<TimeFrameInfo>) -> Option<i64> {
} }
} }
Err(err) => { Err(err) => {
AlertMessage::alert( let errmsg = format!("Timeframe number is invalid. timeframe. {}", err);
&mut BufWriter::new( if configs::CONFIG.read().unwrap().args.is_present("verbose") {
OpenOptions::new() AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok();
.append(true) }
.open(ERROR_LOG_PATH.to_string()) if !*QUIET_ERRORS_FLAG {
.unwrap(), AlertMessage::alert(
), &mut BufWriter::new(
format!("Timeframe number is invalid. timeframe.{}", err), OpenOptions::new()
) .append(true)
.ok(); .open(ERROR_LOG_PATH.to_string())
.unwrap(),
),
&errmsg,
)
.ok();
}
return Option::None; return Option::None;
} }
} }

View File

@@ -7,6 +7,7 @@ use evtx::{EvtxParser, ParserSettings};
use hayabusa::detections::detection::{self, EvtxRecordInfo}; use hayabusa::detections::detection::{self, EvtxRecordInfo};
use hayabusa::detections::print::AlertMessage; use hayabusa::detections::print::AlertMessage;
use hayabusa::detections::print::ERROR_LOG_PATH; use hayabusa::detections::print::ERROR_LOG_PATH;
use hayabusa::detections::print::QUIET_ERRORS_FLAG;
use hayabusa::detections::rule::{get_detection_keys, RuleNode}; use hayabusa::detections::rule::{get_detection_keys, RuleNode};
use hayabusa::filter; use hayabusa::filter;
use hayabusa::omikuji::Omikuji; use hayabusa::omikuji::Omikuji;
@@ -73,8 +74,8 @@ impl App {
if let Some(csv_path) = configs::CONFIG.read().unwrap().args.value_of("output") { if let Some(csv_path) = configs::CONFIG.read().unwrap().args.value_of("output") {
if Path::new(csv_path).exists() { if Path::new(csv_path).exists() {
AlertMessage::alert( AlertMessage::alert(
&mut std::io::stderr().lock(), &mut BufWriter::new(std::io::stderr().lock()),
format!( &format!(
" The file {} already exists. Please specify a different filename.", " The file {} already exists. Please specify a different filename.",
csv_path csv_path
), ),
@@ -83,12 +84,19 @@ impl App {
return; return;
} }
} }
AlertMessage::create_error_log(ERROR_LOG_PATH.to_string()); if !configs::CONFIG
.read()
.unwrap()
.args
.is_present("quiet-errors")
{
AlertMessage::create_error_log(ERROR_LOG_PATH.to_string());
}
if let Some(filepath) = configs::CONFIG.read().unwrap().args.value_of("filepath") { if let Some(filepath) = configs::CONFIG.read().unwrap().args.value_of("filepath") {
if !filepath.ends_with(".evtx") { if !filepath.ends_with(".evtx") {
AlertMessage::alert( AlertMessage::alert(
&mut std::io::stderr().lock(), &mut BufWriter::new(std::io::stderr().lock()),
"--filepath only accepts .evtx files.".to_owned(), &"--filepath only accepts .evtx files.".to_string(),
) )
.ok(); .ok();
return; return;
@@ -98,8 +106,8 @@ impl App {
let evtx_files = self.collect_evtxfiles(&directory); let evtx_files = self.collect_evtxfiles(&directory);
if evtx_files.len() == 0 { if evtx_files.len() == 0 {
AlertMessage::alert( AlertMessage::alert(
&mut std::io::stderr().lock(), &mut BufWriter::new(std::io::stderr().lock()),
"No .evtx files were found.".to_owned(), &"No .evtx files were found.".to_string(),
) )
.ok(); .ok();
return; return;
@@ -124,16 +132,22 @@ impl App {
fn collect_evtxfiles(&self, dirpath: &str) -> Vec<PathBuf> { fn collect_evtxfiles(&self, dirpath: &str) -> Vec<PathBuf> {
let entries = fs::read_dir(dirpath); let entries = fs::read_dir(dirpath);
if entries.is_err() { if entries.is_err() {
AlertMessage::alert( let errmsg = format!("{}", entries.unwrap_err());
&mut BufWriter::new( if configs::CONFIG.read().unwrap().args.is_present("verbose") {
OpenOptions::new() AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg).ok();
.append(true) }
.open(ERROR_LOG_PATH.to_string()) if !*QUIET_ERRORS_FLAG {
.unwrap(), AlertMessage::alert(
), &mut BufWriter::new(
format!("{}", entries.unwrap_err()), OpenOptions::new()
) .append(true)
.ok(); .open(ERROR_LOG_PATH.to_string())
.unwrap(),
),
&errmsg,
)
.ok();
}
return vec![]; return vec![];
} }
@@ -165,7 +179,11 @@ impl App {
match fs::read_to_string("./contributors.txt") { match fs::read_to_string("./contributors.txt") {
Ok(contents) => println!("{}", contents), Ok(contents) => println!("{}", contents),
Err(err) => { Err(err) => {
AlertMessage::alert(&mut std::io::stderr().lock(), format!("{}", err)).ok(); AlertMessage::alert(
&mut BufWriter::new(std::io::stderr().lock()),
&format!("{}", err),
)
.ok();
} }
} }
} }
@@ -232,16 +250,22 @@ impl App {
evtx_filepath, evtx_filepath,
record_result.unwrap_err() record_result.unwrap_err()
); );
AlertMessage::alert( if configs::CONFIG.read().unwrap().args.is_present("verbose") {
&mut BufWriter::new( AlertMessage::alert(&mut BufWriter::new(std::io::stderr().lock()), &errmsg)
OpenOptions::new() .ok();
.append(true) }
.open(ERROR_LOG_PATH.to_string()) if !*QUIET_ERRORS_FLAG {
.unwrap(), AlertMessage::alert(
), &mut BufWriter::new(
errmsg, OpenOptions::new()
) .append(true)
.ok(); .open(ERROR_LOG_PATH.to_string())
.unwrap(),
),
&errmsg,
)
.ok();
}
continue; continue;
} }

View File

@@ -4,6 +4,7 @@ extern crate yaml_rust;
use crate::detections::configs; use crate::detections::configs;
use crate::detections::print::AlertMessage; use crate::detections::print::AlertMessage;
use crate::detections::print::ERROR_LOG_PATH; use crate::detections::print::ERROR_LOG_PATH;
use crate::detections::print::QUIET_ERRORS_FLAG;
use crate::filter::RuleExclude; use crate::filter::RuleExclude;
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::OsStr; use std::ffi::OsStr;
@@ -74,19 +75,25 @@ impl ParseYaml {
// 個別のファイルの読み込みは即終了としない。 // 個別のファイルの読み込みは即終了としない。
let read_content = self.read_file(path); let read_content = self.read_file(path);
if read_content.is_err() { if read_content.is_err() {
AlertMessage::warn( let errmsg = format!(
&mut BufWriter::new( "fail to read file: {}\n{} ",
OpenOptions::new() entry.path().display(),
.append(true) read_content.unwrap_err()
.open(ERROR_LOG_PATH.to_string()) );
.unwrap(), if configs::CONFIG.read().unwrap().args.is_present("verbose") {
), AlertMessage::warn(&mut BufWriter::new(std::io::stderr().lock()), &errmsg)?;
format!( }
"fail to read file: {}\n{} ", if !*QUIET_ERRORS_FLAG {
entry.path().display(), AlertMessage::warn(
read_content.unwrap_err() &mut BufWriter::new(
), OpenOptions::new()
)?; .append(true)
.open(ERROR_LOG_PATH.to_string())
.unwrap(),
),
&errmsg,
)?;
}
self.errorrule_count += 1; self.errorrule_count += 1;
return io::Result::Ok(ret); return io::Result::Ok(ret);
} }
@@ -94,19 +101,25 @@ impl ParseYaml {
// ここも個別のファイルの読み込みは即終了としない。 // ここも個別のファイルの読み込みは即終了としない。
let yaml_contents = YamlLoader::load_from_str(&read_content.unwrap()); let yaml_contents = YamlLoader::load_from_str(&read_content.unwrap());
if yaml_contents.is_err() { if yaml_contents.is_err() {
AlertMessage::warn( let errmsg = format!(
&mut BufWriter::new( "Failed to parse yml: {}\n{} ",
OpenOptions::new() entry.path().display(),
.append(true) yaml_contents.unwrap_err()
.open(ERROR_LOG_PATH.to_string()) );
.unwrap(), if configs::CONFIG.read().unwrap().args.is_present("verbose") {
), AlertMessage::warn(&mut BufWriter::new(std::io::stderr().lock()), &errmsg)?;
format!( }
"Failed to parse yml: {}\n{} ", if !*QUIET_ERRORS_FLAG {
entry.path().display(), AlertMessage::warn(
yaml_contents.unwrap_err() &mut BufWriter::new(
), OpenOptions::new()
)?; .append(true)
.open(ERROR_LOG_PATH.to_string())
.unwrap(),
),
&errmsg,
)?;
}
self.errorrule_count += 1; self.errorrule_count += 1;
return io::Result::Ok(ret); return io::Result::Ok(ret);
} }