From 000292e940476b267f6c2f9296efae36580388a7 Mon Sep 17 00:00:00 2001 From: Jan Starke Date: Fri, 2 Feb 2024 13:20:01 +0100 Subject: [PATCH 01/10] formattable datetime for mactime2 and evtxls --- Cargo.lock | 1 + Cargo.toml | 1 + README.md | 36 +++++++++++++++++++++ src/bin/evtxls/main.rs | 16 +++------- src/common/forensics_timestamp.rs | 40 ++++++++++++++++++------ src/common/formattable_datetime.rs | 50 ++++++++++++++++++++++++++++++ src/common/mod.rs | 2 ++ 7 files changed, 125 insertions(+), 21 deletions(-) create mode 100644 src/common/formattable_datetime.rs diff --git a/Cargo.lock b/Cargo.lock index 75ebced..616c1b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -732,6 +732,7 @@ dependencies = [ "getset", "indicatif", "lazy-regex", + "lazy_static", "lnk", "log", "matches", diff --git a/Cargo.toml b/Cargo.toml index 32f34b7..b407952 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -110,6 +110,7 @@ log = {version = "0.4", features = [ "release_max_level_info" ]} serde = { version = "1.0", features = ["derive"] } simplelog = "0.12" winstructs = "0.3.0" +lazy_static = "1.4" regex = {version = "1", optional=true} clap-markdown = "0.1.3" diff --git a/README.md b/README.md index d142116..d607b49 100644 --- a/README.md +++ b/README.md @@ -53,3 +53,39 @@ mactime2 --autocomplete bash | sudo tee /etc/bash_completion.d/mactime2 would install a autocompletion script in `/etc/bash_completion.d/mactime2`. +# Usage + +## Configuring the global timestamp format + +Per default, the DFIR toolkit uses an RFC3339-compliant data format. If you want to, you can change the data format +being used by setting the `DFIR_DATE` environment variable. Let's look at an example: + +```shell +$ mac2time2 -b tests/data/mactime2/sample.bodyfile -d | head +1970-01-01T00:00:00+00:00,0,macb,V/V---------,0,0,62447617,"/$OrphanFiles" +2022-04-18T10:28:59+00:00,4096,m...,d/drwxr-xr-x,0,0,42729473,"/proc" +2022-04-18T10:28:59+00:00,4096,m...,d/drwxr-xr-x,0,0,36306945,"/sys" +2022-04-21T00:57:50+00:00,7,m...,l/lrwxrwxrwx,0,0,12,"/bin -> usr/bin" +2022-04-21T00:57:50+00:00,7,m...,l/lrwxrwxrwx,0,0,13,"/lib -> usr/lib" +2022-04-21T00:57:50+00:00,9,m...,l/lrwxrwxrwx,0,0,14,"/lib32 -> usr/lib32" +2022-04-21T00:57:50+00:00,9,m...,l/lrwxrwxrwx,0,0,15,"/lib64 -> usr/lib64" +2022-04-21T00:57:50+00:00,10,m...,l/lrwxrwxrwx,0,0,16,"/libx32 -> usr/libx32" +2022-04-21T00:57:50+00:00,8,m...,l/lrwxrwxrwx,0,0,17,"/sbin -> usr/sbin" +2022-04-21T00:57:51+00:00,4096,m...,d/drwxr-xr-x,0,0,38010881,"/srv" +``` + +```shell +$ DFIR_DATE="%F %T (%Z)" mac2time2 -b tests/data/mactime2/sample.bodyfile -d | head +1970-01-01 00:00:00 (UTC),0,macb,V/V---------,0,0,62447617,"/$OrphanFiles" +2022-04-18 10:28:59 (UTC),4096,m...,d/drwxr-xr-x,0,0,42729473,"/proc" +2022-04-18 10:28:59 (UTC),4096,m...,d/drwxr-xr-x,0,0,36306945,"/sys" +2022-04-21 00:57:50 (UTC),7,m...,l/lrwxrwxrwx,0,0,12,"/bin -> usr/bin" +2022-04-21 00:57:50 (UTC),7,m...,l/lrwxrwxrwx,0,0,13,"/lib -> usr/lib" +2022-04-21 00:57:50 (UTC),9,m...,l/lrwxrwxrwx,0,0,14,"/lib32 -> usr/lib32" +2022-04-21 00:57:50 (UTC),9,m...,l/lrwxrwxrwx,0,0,15,"/lib64 -> usr/lib64" +2022-04-21 00:57:50 (UTC),10,m...,l/lrwxrwxrwx,0,0,16,"/libx32 -> usr/libx32" +2022-04-21 00:57:50 (UTC),8,m...,l/lrwxrwxrwx,0,0,17,"/sbin -> usr/sbin" +2022-04-21 00:57:51 (UTC),4096,m...,d/drwxr-xr-x,0,0,38010881,"/srv" +``` + +The value of `DFIR_DATE` can be any format string which can also be used in `DateTime::strftime` () \ No newline at end of file diff --git a/src/bin/evtxls/main.rs b/src/bin/evtxls/main.rs index a278074..57230a4 100644 --- a/src/bin/evtxls/main.rs +++ b/src/bin/evtxls/main.rs @@ -16,7 +16,7 @@ use evtx::{EvtxParser, ParserSettings, SerializedEvtxRecord}; use highlighted_string::HighlightedStringBuilder; use serde_json::Value; -use dfir_toolkit::common::FancyParser; +use dfir_toolkit::common::{FancyParser, FormattableDatetime}; use crate::system_field::FilterBySystemField; @@ -145,18 +145,10 @@ impl EvtxLs { .unwrap_or_else(|| "".to_owned()) .replace("\\u001b", "\u{001b}"); - let output = match self.cli.delimiter { - None => format!( - "{} {system_fields}{event_data}", - record.timestamp.format("%FT%T%.3f") - ), - Some(d) => format!( - "{}{d}{system_fields}{event_data}", - record.timestamp.to_rfc3339() - ), - } - .normal(); + let timestamp = FormattableDatetime::from(&record.timestamp); + let delimiter = self.cli.delimiter.unwrap_or(' '); + let output=format!("{timestamp}{delimiter}{system_fields}{event_data}").normal(); println!("{output}"); Ok(()) diff --git a/src/common/forensics_timestamp.rs b/src/common/forensics_timestamp.rs index da85748..8d86eb7 100644 --- a/src/common/forensics_timestamp.rs +++ b/src/common/forensics_timestamp.rs @@ -1,8 +1,15 @@ use std::fmt::Display; -use chrono::{NaiveDateTime, LocalResult}; -use chrono_tz::Tz; use chrono::offset::TimeZone; +use chrono::{DateTime, FixedOffset, LocalResult, NaiveDateTime}; +use chrono_tz::Tz; +use lazy_static::lazy_static; + +lazy_static! { + static ref TIMESTAMP_FORMAT: Option = std::env::var("DFIR_DATE").ok(); + static ref ZERO: DateTime = + DateTime::::parse_from_rfc3339("0000-00-00T00:00:00+00:00").unwrap(); +} pub struct ForensicsTimestamp { unix_ts: i64, @@ -11,10 +18,24 @@ pub struct ForensicsTimestamp { } impl ForensicsTimestamp { - pub fn new(unix_ts: i64, src_zone: Tz, dst_zone: Tz) -> Self { Self { - unix_ts, src_zone, dst_zone + unix_ts, + src_zone, + dst_zone, + } + } + + fn display_datetime( + dt: &DateTime, + f: &mut std::fmt::Formatter<'_>, + ) -> std::fmt::Result + where + ::Offset: std::fmt::Display, + { + match &*TIMESTAMP_FORMAT { + Some(format) => dt.format(format).fmt(f), + None => dt.to_rfc3339().fmt(f), } } } @@ -22,7 +43,8 @@ impl ForensicsTimestamp { impl Display for ForensicsTimestamp { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.unix_ts >= 0 { - let src_timestamp = match self.src_zone + let src_timestamp = match self + .src_zone .from_local_datetime(&NaiveDateTime::from_timestamp_opt(self.unix_ts, 0).unwrap()) { LocalResult::None => { @@ -31,10 +53,10 @@ impl Display for ForensicsTimestamp { LocalResult::Single(t) => t, LocalResult::Ambiguous(t1, _t2) => t1, }; - let dst_timestamp = src_timestamp.with_timezone(&self.dst_zone); - write!(f, "{}", dst_timestamp.to_rfc3339()) + + Self::display_datetime(&src_timestamp.with_timezone(&self.dst_zone), f) } else { - write!(f, "0000-00-00T00:00:00+00:00") + Self::display_datetime(&*ZERO, f) } } -} \ No newline at end of file +} diff --git a/src/common/formattable_datetime.rs b/src/common/formattable_datetime.rs new file mode 100644 index 0000000..8ef20b2 --- /dev/null +++ b/src/common/formattable_datetime.rs @@ -0,0 +1,50 @@ +use std::fmt::Display; + +use chrono::{DateTime, FixedOffset, TimeZone}; +use lazy_static::lazy_static; + +lazy_static! { + static ref TIMESTAMP_FORMAT: Option = std::env::var("DFIR_DATE").ok(); + static ref ZERO: DateTime = + DateTime::::parse_from_rfc3339("0000-00-00T00:00:00+00:00").unwrap(); +} + +/// Wrapper around [`DateTime`] to alow customization of the Timestamp output +/// using the `DFIR_DATE` environment variable +/// +pub struct FormattableDatetime(DateTime) +where + ::Offset: std::fmt::Display; + +impl From> for FormattableDatetime +where + TZ: TimeZone, + ::Offset: std::fmt::Display, +{ + fn from(value: DateTime) -> Self { + Self(value) + } +} + +impl From<&DateTime> for FormattableDatetime +where + TZ: TimeZone, + ::Offset: std::fmt::Display, +{ + fn from(value: &DateTime) -> Self { + Self(value.clone()) + } +} + +impl Display for FormattableDatetime +where + TZ: TimeZone, + ::Offset: std::fmt::Display, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &*TIMESTAMP_FORMAT { + Some(format) => self.0.format(format).fmt(f), + None => self.0.to_rfc3339().fmt(f), + } + } +} diff --git a/src/common/mod.rs b/src/common/mod.rs index bc7ae23..ba026d6 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -4,10 +4,12 @@ mod parse_cli; mod rfc3339_datetime; mod tzargument; mod file_input; +mod formattable_datetime; pub use forensics_timestamp::*; pub use parse_cli::*; pub use rfc3339_datetime::*; pub use tzargument::*; +pub use formattable_datetime::*; pub use file_input::*; \ No newline at end of file From 60e0a51d1db8504611ecd27c6185ff965204dddb Mon Sep 17 00:00:00 2001 From: Jan Starke Date: Fri, 2 Feb 2024 13:26:57 +0100 Subject: [PATCH 02/10] support for formattable dates in regdump --- src/bin/regdump/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/regdump/main.rs b/src/bin/regdump/main.rs index 8c19f2d..5948cde 100644 --- a/src/bin/regdump/main.rs +++ b/src/bin/regdump/main.rs @@ -1,7 +1,7 @@ use anyhow::{bail, Result}; use dfir_toolkit::common::bodyfile::Bodyfile3Line; -use dfir_toolkit::common::FancyParser; +use dfir_toolkit::common::{FancyParser, FormattableDatetime}; use nt_hive2::*; use simplelog::{Config, SimpleLogger}; use std::fs::File; @@ -80,7 +80,7 @@ where if cli.hide_timestamps { println!("\n[{}]", ¤t_path); } else { - println!("\n[{}]; {}", ¤t_path, keynode.timestamp()); + println!("\n[{}]; {}", ¤t_path, FormattableDatetime::from(keynode.timestamp())); } print_values(keynode); From 7a336ea370157d2b91152812b6213056fbdb11f2 Mon Sep 17 00:00:00 2001 From: Jan Starke Date: Fri, 2 Feb 2024 13:27:31 +0100 Subject: [PATCH 03/10] bump version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 616c1b7..03bd81c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,7 +702,7 @@ dependencies = [ [[package]] name = "dfir-toolkit" -version = "0.9.0" +version = "0.10.0" dependencies = [ "anyhow", "assert-json-diff", diff --git a/Cargo.toml b/Cargo.toml index b407952..ea26302 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dfir-toolkit" -version = "0.9.0" +version = "0.10.0" edition = "2021" authors = ["Jan Starke ", "Deborah Mahn "] description = "CLI tools for digital forensics and incident response" From 4f0e0226d53cf4f7d3d17354fe8d6208c284587c Mon Sep 17 00:00:00 2001 From: Jan Starke Date: Mon, 5 Feb 2024 10:47:31 +0100 Subject: [PATCH 04/10] fix warning --- src/bin/evtxanalyze/sessions/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bin/evtxanalyze/sessions/mod.rs b/src/bin/evtxanalyze/sessions/mod.rs index c65b6bb..1ba0f87 100644 --- a/src/bin/evtxanalyze/sessions/mod.rs +++ b/src/bin/evtxanalyze/sessions/mod.rs @@ -10,7 +10,6 @@ mod active_directory_domain_name; pub use session::*; pub use session_store::*; pub use session_event::*; -pub use session_event_templates::*; pub use session_event_error::*; pub use session_as_json::*; pub use session_as_csv::*; From f5ed50fc820997853a2c7d472aec28ff2f602359 Mon Sep 17 00:00:00 2001 From: Jan Starke Date: Mon, 5 Feb 2024 10:52:56 +0100 Subject: [PATCH 05/10] fix clippy complaints --- src/bin/evtxanalyze/pstree/unique_pid.rs | 2 +- src/bin/evtxcat/main.rs | 2 +- src/bin/evtxls/main.rs | 2 +- src/bin/evtxscan/main.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/evtxanalyze/pstree/unique_pid.rs b/src/bin/evtxanalyze/pstree/unique_pid.rs index 8d29d30..f03794d 100644 --- a/src/bin/evtxanalyze/pstree/unique_pid.rs +++ b/src/bin/evtxanalyze/pstree/unique_pid.rs @@ -37,7 +37,7 @@ impl Ord for UniquePid { } } -#[allow(clippy::incorrect_partial_ord_impl_on_ord_type)] +#[allow(clippy::non_canonical_partial_ord_impl)] impl PartialOrd for UniquePid { fn partial_cmp(&self, other: &Self) -> Option { if self.pid != other.pid { diff --git a/src/bin/evtxcat/main.rs b/src/bin/evtxcat/main.rs index 4a2b510..46e44b9 100644 --- a/src/bin/evtxcat/main.rs +++ b/src/bin/evtxcat/main.rs @@ -19,7 +19,7 @@ use record_list_formatter::RecordListFormatter; fn main() -> Result<()> { let cli = Cli::parse_cli(); - let path = PathBuf::try_from(&cli.evtx_file)?; + let path = PathBuf::from(&cli.evtx_file); let parser = EvtxParser::from_path(path)?; diff --git a/src/bin/evtxls/main.rs b/src/bin/evtxls/main.rs index 57230a4..6f52691 100644 --- a/src/bin/evtxls/main.rs +++ b/src/bin/evtxls/main.rs @@ -37,7 +37,7 @@ impl EvtxLs { let mut records = Vec::new(); for f_name in self.cli.evtx_files.iter() { - let path = PathBuf::try_from(&f_name)?; + let path = PathBuf::from(&f_name); let settings = ParserSettings::default().num_threads(0); let parser = EvtxParser::from_path(path)?.with_configuration(settings); diff --git a/src/bin/evtxscan/main.rs b/src/bin/evtxscan/main.rs index 23d72e7..95d9c9a 100644 --- a/src/bin/evtxscan/main.rs +++ b/src/bin/evtxscan/main.rs @@ -16,7 +16,7 @@ fn main() -> Result<()> { let mut record_ids: Vec = Vec::new(); let mut records: HashMap> = HashMap::new(); - let path = PathBuf::try_from(&cli.evtx_file)?; + let path = PathBuf::from(&cli.evtx_file); let mut parser = EvtxParser::from_path(path)?; for record in parser.records_json_value() { From c2b7fb0f6f36e62d5c11132afbabd3eb649c7f35 Mon Sep 17 00:00:00 2001 From: Bitbee0 <92975980+Bitbee0@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:00:31 +0100 Subject: [PATCH 06/10] Update formattable_datetime.rs typing correction --- src/common/formattable_datetime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/formattable_datetime.rs b/src/common/formattable_datetime.rs index 8ef20b2..4634e45 100644 --- a/src/common/formattable_datetime.rs +++ b/src/common/formattable_datetime.rs @@ -9,7 +9,7 @@ lazy_static! { DateTime::::parse_from_rfc3339("0000-00-00T00:00:00+00:00").unwrap(); } -/// Wrapper around [`DateTime`] to alow customization of the Timestamp output +/// Wrapper around [`DateTime`] to allow customization of the timestamp output /// using the `DFIR_DATE` environment variable /// pub struct FormattableDatetime(DateTime) From 9bf3de4f389d24e4987122f95ad663a75c2f76b8 Mon Sep 17 00:00:00 2001 From: Bitbee0 <92975980+Bitbee0@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:02:21 +0100 Subject: [PATCH 07/10] Update update-md.sh --- scripts/update-md.sh | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/scripts/update-md.sh b/scripts/update-md.sh index e4be5a4..658c3aa 100755 --- a/scripts/update-md.sh +++ b/scripts/update-md.sh @@ -58,8 +58,46 @@ mactime2 --autocomplete bash | sudo tee /etc/bash_completion.d/mactime2 would install a autocompletion script in `/etc/bash_completion.d/mactime2`. +# Usage + +## Configuring the global timestamp format + +Per default, the DFIR toolkit uses an RFC3339-compliant data format. If you want to, you can change the data format +being used by setting the `DFIR_DATE` environment variable. Let's look at an example: + +```shell +$ mac2time2 -b tests/data/mactime2/sample.bodyfile -d | head +1970-01-01T00:00:00+00:00,0,macb,V/V---------,0,0,62447617,"/$OrphanFiles" +2022-04-18T10:28:59+00:00,4096,m...,d/drwxr-xr-x,0,0,42729473,"/proc" +2022-04-18T10:28:59+00:00,4096,m...,d/drwxr-xr-x,0,0,36306945,"/sys" +2022-04-21T00:57:50+00:00,7,m...,l/lrwxrwxrwx,0,0,12,"/bin -> usr/bin" +2022-04-21T00:57:50+00:00,7,m...,l/lrwxrwxrwx,0,0,13,"/lib -> usr/lib" +2022-04-21T00:57:50+00:00,9,m...,l/lrwxrwxrwx,0,0,14,"/lib32 -> usr/lib32" +2022-04-21T00:57:50+00:00,9,m...,l/lrwxrwxrwx,0,0,15,"/lib64 -> usr/lib64" +2022-04-21T00:57:50+00:00,10,m...,l/lrwxrwxrwx,0,0,16,"/libx32 -> usr/libx32" +2022-04-21T00:57:50+00:00,8,m...,l/lrwxrwxrwx,0,0,17,"/sbin -> usr/sbin" +2022-04-21T00:57:51+00:00,4096,m...,d/drwxr-xr-x,0,0,38010881,"/srv" +``` + +```shell +$ DFIR_DATE="%F %T (%Z)" mac2time2 -b tests/data/mactime2/sample.bodyfile -d | head +1970-01-01 00:00:00 (UTC),0,macb,V/V---------,0,0,62447617,"/$OrphanFiles" +2022-04-18 10:28:59 (UTC),4096,m...,d/drwxr-xr-x,0,0,42729473,"/proc" +2022-04-18 10:28:59 (UTC),4096,m...,d/drwxr-xr-x,0,0,36306945,"/sys" +2022-04-21 00:57:50 (UTC),7,m...,l/lrwxrwxrwx,0,0,12,"/bin -> usr/bin" +2022-04-21 00:57:50 (UTC),7,m...,l/lrwxrwxrwx,0,0,13,"/lib -> usr/lib" +2022-04-21 00:57:50 (UTC),9,m...,l/lrwxrwxrwx,0,0,14,"/lib32 -> usr/lib32" +2022-04-21 00:57:50 (UTC),9,m...,l/lrwxrwxrwx,0,0,15,"/lib64 -> usr/lib64" +2022-04-21 00:57:50 (UTC),10,m...,l/lrwxrwxrwx,0,0,16,"/libx32 -> usr/libx32" +2022-04-21 00:57:50 (UTC),8,m...,l/lrwxrwxrwx,0,0,17,"/sbin -> usr/sbin" +2022-04-21 00:57:51 (UTC),4096,m...,d/drwxr-xr-x,0,0,38010881,"/srv" +``` + +The value of `DFIR_DATE` can be any format string which can also be used in `DateTime::strftime` () + + EOF for B in $(cd src/bin; echo *); do cargo run --bin $B -- --markdown-help >>doc/$B.md -done \ No newline at end of file +done From 91a4962be5d99c240f4d2b54482ad35ebeee0a1c Mon Sep 17 00:00:00 2001 From: Bitbee0 <92975980+Bitbee0@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:56:38 +0100 Subject: [PATCH 08/10] Correct typo in update-md.sh --- scripts/update-md.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/update-md.sh b/scripts/update-md.sh index 658c3aa..8bdb537 100755 --- a/scripts/update-md.sh +++ b/scripts/update-md.sh @@ -21,7 +21,7 @@ cat >README.md <<'EOF' - [Tools](#tools) - [x] [`cleanhive`](https://github.com/dfir-dd/dfir-toolkit/blob/main/doc/cleanhive.md) - [x] [`evtx2bodyfile`](https://github.com/dfir-dd/dfir-toolkit/blob/main/doc/evtx2bodyfile.md) - - [x] [`evtxanalyze`](https://github.com/dfir-dd/dfir-toolkit/blob/main/doc/avtxanalyze.md) + - [x] [`evtxanalyze`](https://github.com/dfir-dd/dfir-toolkit/blob/main/doc/evtxanalyze.md) - [x] [`evtxscan`](https://github.com/dfir-dd/dfir-toolkit/blob/main/doc/evtxscan.md) - [x] [`evtxcat`](https://github.com/dfir-dd/dfir-toolkit/blob/main/doc/evtxcat.md) - [x] [`evtxls`](https://github.com/dfir-dd/dfir-toolkit/blob/main/doc/evtxls.md) From 1b918e794b95bad8afaa5979315804551e692644 Mon Sep 17 00:00:00 2001 From: Jan Starke Date: Tue, 6 Feb 2024 09:47:32 +0100 Subject: [PATCH 09/10] add error handling for invalid format strings --- src/common/forensics_timestamp.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/common/forensics_timestamp.rs b/src/common/forensics_timestamp.rs index 8d86eb7..37f60dd 100644 --- a/src/common/forensics_timestamp.rs +++ b/src/common/forensics_timestamp.rs @@ -1,12 +1,23 @@ use std::fmt::Display; +use chrono::format::StrftimeItems; use chrono::offset::TimeZone; use chrono::{DateTime, FixedOffset, LocalResult, NaiveDateTime}; use chrono_tz::Tz; use lazy_static::lazy_static; lazy_static! { - static ref TIMESTAMP_FORMAT: Option = std::env::var("DFIR_DATE").ok(); + static ref TIMESTAMP_FORMAT: Option = { + if let Ok(format) = std::env::var("DFIR_DATE") { + if StrftimeItems::new(&format).any(|i| i == chrono::format::Item::Error) { + panic!("ERROR: invalid date format: '{format}'! Aborting execution!") + } else { + Some(format) + } + } else { + None + } + }; static ref ZERO: DateTime = DateTime::::parse_from_rfc3339("0000-00-00T00:00:00+00:00").unwrap(); } From bea212bc16dfb125bf704c354292db0906d07c7d Mon Sep 17 00:00:00 2001 From: Jan Starke Date: Tue, 6 Feb 2024 14:56:02 +0100 Subject: [PATCH 10/10] better error message --- src/common/forensics_timestamp.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/common/forensics_timestamp.rs b/src/common/forensics_timestamp.rs index 37f60dd..94f9d04 100644 --- a/src/common/forensics_timestamp.rs +++ b/src/common/forensics_timestamp.rs @@ -10,7 +10,16 @@ lazy_static! { static ref TIMESTAMP_FORMAT: Option = { if let Ok(format) = std::env::var("DFIR_DATE") { if StrftimeItems::new(&format).any(|i| i == chrono::format::Item::Error) { - panic!("ERROR: invalid date format: '{format}'! Aborting execution!") + eprintln!(); + eprintln!("ERROR: invalid date format: '{format}' stored in environment variable $DFIR_DATE!"); + eprintln!(); + eprintln!("Please take a look at"); + eprintln!(); + eprintln!(" "); + eprintln!(); + eprintln!("to see which format strings are accepted."); + eprintln!(); + std::process::exit(-1); } else { Some(format) }