diff --git a/src/afterfact.rs b/src/afterfact.rs index 10b2272c..0c5de957 100644 --- a/src/afterfact.rs +++ b/src/afterfact.rs @@ -1,6 +1,7 @@ use crate::detections::configs; use crate::detections::print; use crate::detections::print::AlertMessage; +use crate::detections::print::ERROR_LOG_PATH; use chrono::{DateTime, Local, TimeZone, Utc}; use serde::Serialize; use std::error::Error; @@ -36,7 +37,7 @@ pub struct DisplayFormat<'a> { pub fn after_fact() { let fn_emit_csv_err = |err: Box| { AlertMessage::alert( - &mut std::io::stderr().lock(), + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), format!("Failed to write CSV. {}", err), true, ) @@ -55,7 +56,7 @@ pub fn after_fact() { Ok(file) => Box::new(BufWriter::new(file)), Err(err) => { AlertMessage::alert( - &mut std::io::stderr().lock(), + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), format!("Failed to open file. {}", err), true, ) diff --git a/src/detections/detection.rs b/src/detections/detection.rs index bd69d450..dd8af7a2 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -2,6 +2,7 @@ extern crate csv; use crate::detections::configs; use crate::detections::print::AlertMessage; +use crate::detections::print::ERROR_LOG_PATH; use crate::detections::print::MESSAGES; use crate::detections::rule; use crate::detections::rule::AggResult; @@ -12,6 +13,8 @@ use crate::yaml::ParseYaml; use hashbrown; use serde_json::Value; use std::collections::HashMap; +use std::fs::File; +use std::io::BufWriter; use tokio::{runtime::Runtime, spawn, task::JoinHandle}; use std::sync::Arc; @@ -59,7 +62,7 @@ impl Detection { rulefile_loader.read_dir(rulespath.unwrap_or(DIRPATH_RULES), &level, exclude_ids); if result_readdir.is_err() { AlertMessage::alert( - &mut std::io::stderr().lock(), + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), format!("{}", result_readdir.unwrap_err()), true, ) diff --git a/src/detections/print.rs b/src/detections/print.rs index cfca0d7d..2f878dbd 100644 --- a/src/detections/print.rs +++ b/src/detections/print.rs @@ -12,10 +12,10 @@ use std::env; use std::fs::create_dir; use std::fs::remove_file; use std::fs::File; - use std::io::BufWriter; -use std::io::{self, Write}; use std::path::Path; + +use std::io::{self, Write}; use std::sync::Mutex; #[derive(Debug)] @@ -43,25 +43,9 @@ lazy_static! { "./hayabusa-logs/errorlog-{}.log", Local::now().format("%Y%m%d_%H%M%S") ); - pub static ref ERROR_LOG_WRITER: Mutex> = - Mutex::new(get_error_file_writer(ERROR_LOG_PATH.to_string())); pub static ref ALERT_COUNT_IN_ERROR_LOG: Mutex = Mutex::new(Counter::new()); } -//対象のディレクトリが存在することを確認後、最初の定型文を追加して、ファイルのbufwriterを返す関数 -fn get_error_file_writer(path_str: String) -> BufWriter { - let path = Path::new(&path_str); - if !path.parent().unwrap().exists() { - create_dir(path.parent().unwrap()).ok(); - } - // 1行目は必ず実行したコマンド情報を入れておく。 - let mut ret = BufWriter::new(File::create(path).unwrap()); - ret.write(format!("user input: {:?}\n", format_args!("{:?}", env::args())).as_bytes()) - .ok(); - ret.flush().ok(); - return ret; -} - #[derive(Copy, Clone)] /// エラーログに出力したエラー回数を保持した構造体 pub struct Counter { @@ -224,14 +208,38 @@ impl Message { } impl AlertMessage { + //対象のディレクトリが存在することを確認後、最初の定型文を追加して、ファイルのbufwriterを返す関数 + pub fn create_error_log(path_str: String) { + let path = Path::new(&path_str); + if !path.parent().unwrap().exists() { + create_dir(path.parent().unwrap()).ok(); + } + // 1行目は必ず実行したコマンド情報を入れておく。 + let mut ret = BufWriter::new(File::create(path).unwrap()); + + ret.write( + format!( + "user input: {:?}\n", + format_args!( + "{}", + env::args() + .map(|arg| arg) + .collect::>() + .join(" ") + ) + ) + .as_bytes(), + ) + .unwrap(); + ret.flush().ok(); + } + /// ERRORメッセージを表示する関数。error_log_flagでfalseの場合は外部へのエラーログの書き込みは行わずに指定されたwを用いた出力のみ行う。trueの場合はwを用いた出力を行わずにエラーログへの出力を行う pub fn alert(w: &mut W, contents: String, error_log_flag: bool) -> io::Result<()> { if error_log_flag { ALERT_COUNT_IN_ERROR_LOG.lock().unwrap().countup(); - writeln!(ERROR_LOG_WRITER.lock().unwrap(), "[ERROR] {}", contents) - } else { - writeln!(w, "[ERROR] {}", contents) } + writeln!(w, "[ERROR] {}", contents) } // WARNメッセージを表示する関数 @@ -243,20 +251,20 @@ impl AlertMessage { pub fn output_error_log_exist() { let error_log_path_str = ERROR_LOG_PATH.to_string(); if ALERT_COUNT_IN_ERROR_LOG.lock().unwrap().count == 0 { - if remove_file(error_log_path_str).is_err() { + if remove_file(&error_log_path_str).is_err() { AlertMessage::alert( &mut std::io::stderr().lock(), - format!("failed to remove file. filepath:{}", error_log_path_str), + format!("failed to remove file. filepath:{}", &error_log_path_str), false, ) .ok(); } return; } - println!(format!( + println!( "Generated error was output to {}. Please see the file for details", - error_log_path_str - )); + &error_log_path_str + ); } } diff --git a/src/detections/rule/count.rs b/src/detections/rule/count.rs index c0821416..3698eb39 100644 --- a/src/detections/rule/count.rs +++ b/src/detections/rule/count.rs @@ -1,4 +1,5 @@ use crate::detections::print::AlertMessage; +use crate::detections::print::ERROR_LOG_PATH; use crate::detections::rule::AggResult; use crate::detections::rule::AggregationParseInfo; use crate::detections::rule::Message; @@ -6,6 +7,8 @@ use crate::detections::rule::RuleNode; use chrono::{DateTime, TimeZone, Utc}; use serde_json::Value; use std::collections::HashMap; +use std::fs::File; +use std::io::BufWriter; use std::num::ParseIntError; use crate::detections::rule::aggregation_parser::AggregationConditionToken; @@ -57,7 +60,7 @@ pub fn create_count_key(rule: &RuleNode, record: &Value) -> String { } None => { AlertMessage::alert( - &mut std::io::stderr().lock(), + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), format!("field_value alias not found.value:{}", field_value), true, ) @@ -74,7 +77,7 @@ pub fn create_count_key(rule: &RuleNode, record: &Value) -> String { } None => { AlertMessage::alert( - &mut std::io::stderr().lock(), + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), format!("by_field_value alias not found.value:{}", by_field_value), true, ) @@ -157,7 +160,7 @@ impl TimeFrameInfo { tnum.retain(|c| c != 'd'); } else { AlertMessage::alert( - &mut std::io::stderr().lock(), + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), format!("Timeframe is invalid. Input value:{}", value), true, ) @@ -190,7 +193,7 @@ pub fn get_sec_timeframe(timeframe: &Option) -> Option { } Err(err) => { AlertMessage::alert( - &mut std::io::stderr().lock(), + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), format!("Timeframe number is invalid. timeframe.{}", err), true, ) diff --git a/src/main.rs b/src/main.rs index 7b62df09..e6382ee7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use chrono::{DateTime, Local}; use evtx::{EvtxParser, ParserSettings}; use hayabusa::detections::detection::{self, EvtxRecordInfo}; use hayabusa::detections::print::AlertMessage; +use hayabusa::detections::print::ERROR_LOG_PATH; use hayabusa::detections::rule::{get_detection_keys, RuleNode}; use hayabusa::filter; use hayabusa::omikuji::Omikuji; @@ -16,6 +17,7 @@ use pbr::ProgressBar; use serde_json::Value; use std::collections::{HashMap, HashSet}; use std::fmt::Display; +use std::io::BufWriter; use std::sync::Arc; use std::{ fs::{self, File}, @@ -66,6 +68,7 @@ impl App { ); return; } + AlertMessage::create_error_log(ERROR_LOG_PATH.to_string()); if let Some(filepath) = configs::CONFIG.read().unwrap().args.value_of("filepath") { if !filepath.ends_with(".evtx") { AlertMessage::alert( @@ -107,9 +110,12 @@ impl App { fn collect_evtxfiles(&self, dirpath: &str) -> Vec { let entries = fs::read_dir(dirpath); if entries.is_err() { - let stderr = std::io::stderr(); - let mut stderr = stderr.lock(); - AlertMessage::alert(&mut stderr, format!("{}", entries.unwrap_err()), true).ok(); + AlertMessage::alert( + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), + format!("{}", entries.unwrap_err()), + true, + ) + .ok(); return vec![]; } @@ -141,7 +147,7 @@ impl App { match fs::read_to_string("./contributors.txt") { Ok(contents) => println!("{}", contents), Err(err) => { - AlertMessage::alert(&mut std::io::stderr().lock(), format!("{}", err), true).ok(); + AlertMessage::alert(&mut std::io::stderr().lock(), format!("{}", err), false).ok(); } } } @@ -209,7 +215,12 @@ impl App { evtx_filepath, record_result.unwrap_err() ); - AlertMessage::alert(&mut std::io::stderr().lock(), errmsg, true).ok(); + AlertMessage::alert( + &mut BufWriter::new(File::open(ERROR_LOG_PATH.to_string()).unwrap()), + errmsg, + true, + ) + .ok(); continue; }