From 059aecab8943bf78acff30fbbc8876b263d3ce19 Mon Sep 17 00:00:00 2001 From: Duncan McGreggor Date: Fri, 15 Dec 2023 01:42:04 -0600 Subject: [PATCH] Added initial support for hashes. --- Cargo.lock | 32 +++++++++++++++++++++++++++ rucksack/Cargo.toml | 2 ++ rucksack/src/command/handlers/list.rs | 14 ++++++++++++ rucksack/src/output/column.rs | 1 + rucksack/src/output/option.rs | 5 +++++ rucksack/src/output/result.rs | 5 +++++ 6 files changed, 59 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index e574007..e1dd30d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,6 +235,15 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.14.0" @@ -476,6 +485,16 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dirs" version = "5.0.1" @@ -1172,6 +1191,7 @@ dependencies = [ "clap", "clap_complete", "confyg", + "digest", "log", "passwords", "prettytable-rs", @@ -1180,6 +1200,7 @@ dependencies = [ "rucksack-lib", "secrecy", "serde", + "sha2", "twyg", "versions", ] @@ -1308,6 +1329,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shellexpand" version = "3.1.0" diff --git a/rucksack/Cargo.toml b/rucksack/Cargo.toml index cedde90..1215827 100644 --- a/rucksack/Cargo.toml +++ b/rucksack/Cargo.toml @@ -20,12 +20,14 @@ anyhow = "1.0" clap = { version = "4.0", features = ["string", "env"] } clap_complete = "4.0" confyg = "0.2" +digest = "0.10.7" log = "0.4" passwords = "3.1" prettytable-rs = "0.10.0" rpassword = "7.1" secrecy = "0.8" serde = { version = "1.0", features = ["derive"] } +sha2 = "0.10" twyg = "0.2" versions = "6.0.0" diff --git a/rucksack/src/command/handlers/list.rs b/rucksack/src/command/handlers/list.rs index bd7f9e4..d09f82b 100644 --- a/rucksack/src/command/handlers/list.rs +++ b/rucksack/src/command/handlers/list.rs @@ -126,6 +126,7 @@ use anyhow::Result; use clap::ArgMatches; use passwords::{analyzer, scorer}; +use sha2::{Digest, Sha256}; use rucksack_db::records; use rucksack_db::Status; @@ -331,6 +332,19 @@ fn process_records(matches: &ArgMatches, app: &App, mut opts: Opts) -> Result<() let entry = groups.entry(record.password()).or_default(); entry.push(result.clone()); } + // Hashes + if !opts.hash_fields.is_empty() && !opts.built_hashes { + let mut vals: Vec = vec![]; + for col in opts.hash_fields.iter() { + let val = result.get(col).unwrap().to_owned(); + vals.push(val); + } + let hash = format!( + "{:x}", + Sha256::new().chain_update(vals.join(":")).finalize() + ); + result.add(Column::Hash, hash); + } results.push(result); } sort(&mut results, sort_by); diff --git a/rucksack/src/output/column.rs b/rucksack/src/output/column.rs index 4ca49d2..a452d49 100644 --- a/rucksack/src/output/column.rs +++ b/rucksack/src/output/column.rs @@ -8,6 +8,7 @@ pub enum Column { Category, Count, Created, + Hash, Id, Imported, Key, diff --git a/rucksack/src/output/option.rs b/rucksack/src/output/option.rs index af9ba3f..d634f2e 100644 --- a/rucksack/src/output/option.rs +++ b/rucksack/src/output/option.rs @@ -1,12 +1,17 @@ +use super::Column; + #[derive(Clone, Debug, Default)] pub struct Opts { pub backup_files: bool, + pub built_hashes: bool, pub categories: bool, pub decrypted: bool, pub group_by_category: bool, pub group_by_kind: bool, pub group_by_name: bool, pub group_by_password: bool, + pub group_by_hash: bool, + pub hash_fields: Vec, pub kinds: bool, pub latest_only: bool, pub only_deleted: bool, diff --git a/rucksack/src/output/result.rs b/rucksack/src/output/result.rs index 1505409..03b2c6d 100644 --- a/rucksack/src/output/result.rs +++ b/rucksack/src/output/result.rs @@ -33,6 +33,11 @@ pub fn category(cat: String) -> ResultRow { ResultRow { hashmap } } +pub fn hash(hash: String) -> ResultRow { + let hashmap: HashMap = HashMap::from([(Column::Hash, hash)]); + ResultRow { hashmap } +} + pub fn kind(kind: String) -> ResultRow { let hashmap: HashMap = HashMap::from([(Column::Kind, kind)]); ResultRow { hashmap }