10 Commits
Author SHA1 Message Date
nelsbrock c22d4bdb27 chore: release version 0.4.0 2026-05-22 19:53:19 +02:00
nelsbrock 3439e51865 chore: upgrade and update dependencies 2026-05-22 19:52:13 +02:00
nelsbrock a07aaca068 feat: rename --stop-after to --count/-n 2026-05-22 19:51:41 +02:00
nelsbrock 20c0a919c5 refactor: replace with_context calls with context calls 2026-05-10 18:13:47 +02:00
nelsbrock 3ea0de1cdb refactor: remove ref_self variable 2026-05-10 18:08:14 +02:00
nelsbrock 9f992caef9 refactor: fix some pedantic clippy lints 2026-05-10 18:02:54 +02:00
nelsbrock c8bedabe1f fix: determine workers count before prompting for password 2026-05-10 17:51:43 +02:00
nelsbrock e8b83d41cb make small improvements to CLI
- set meaningful value names for options
- add backticks around CLI options in user-facing messages
2026-05-10 17:34:56 +02:00
nelsbrock 6af66fd292 add --workers option 2026-05-10 17:28:01 +02:00
nelsbrock bc07cba585 remove unnecessary clone() 2026-05-10 16:21:11 +02:00
4 changed files with 97 additions and 89 deletions
Generated
+56 -58
View File
@@ -105,9 +105,9 @@ dependencies = [
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.5.0" version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]] [[package]]
name = "base64" name = "base64"
@@ -145,7 +145,16 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [ dependencies = [
"bit-vec", "bit-vec 0.8.0",
]
[[package]]
name = "bit-set"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ddef2995421ab6a5c779542c81ee77c115206f4ad9d5a8e05f4ff49716a3dd"
dependencies = [
"bit-vec 0.9.1",
] ]
[[package]] [[package]]
@@ -154,6 +163,12 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]]
name = "bit-vec"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71798fca2c1fe1086445a7258a4bc81e6e49dcd24c8d0dd9a1e57395b603f51"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.11.1" version = "2.11.1"
@@ -200,9 +215,9 @@ dependencies = [
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.20.2" version = "3.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]] [[package]]
name = "bzip2" name = "bzip2"
@@ -420,9 +435,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
[[package]] [[package]]
name = "either" name = "either"
version = "1.15.0" version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
[[package]] [[package]]
name = "ena" name = "ena"
@@ -455,7 +470,7 @@ version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1e1dacd0d2082dfcf1351c4bdd566bbe89a2b263235a2b50058f1e130a47277" checksum = "e1e1dacd0d2082dfcf1351c4bdd566bbe89a2b263235a2b50058f1e130a47277"
dependencies = [ dependencies = [
"bit-set", "bit-set 0.8.0",
"regex-automata", "regex-automata",
"regex-syntax", "regex-syntax",
] ]
@@ -474,14 +489,13 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]] [[package]]
name = "fingerprunk" name = "fingerprunk"
version = "0.3.0" version = "0.4.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap", "clap",
"ctrlc", "ctrlc",
"fancy-regex", "fancy-regex",
"num-integer", "num-integer",
"num_cpus",
"rpassword", "rpassword",
"sequoia-openpgp", "sequoia-openpgp",
] ]
@@ -605,12 +619,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]] [[package]]
name = "iana-time-zone" name = "iana-time-zone"
version = "0.1.65" version = "0.1.65"
@@ -788,9 +796,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.98" version = "0.3.99"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"futures-util", "futures-util",
@@ -809,12 +817,12 @@ dependencies = [
[[package]] [[package]]
name = "lalrpop" name = "lalrpop"
version = "0.22.2" version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" checksum = "98a80a963123205c7157323c99611bc4abb65dcbd62ef46dc4bac74a3941bc75"
dependencies = [ dependencies = [
"ascii-canvas", "ascii-canvas",
"bit-set", "bit-set 0.9.1",
"ena", "ena",
"itertools 0.14.0", "itertools 0.14.0",
"lalrpop-util", "lalrpop-util",
@@ -830,12 +838,11 @@ dependencies = [
[[package]] [[package]]
name = "lalrpop-util" name = "lalrpop-util"
version = "0.22.2" version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" checksum = "884f3e747ed2dcee867cda1b0c31a048f9e20de2d916a248949319921a2e666e"
dependencies = [ dependencies = [
"regex-automata", "regex-automata",
"rustversion",
] ]
[[package]] [[package]]
@@ -846,9 +853,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]] [[package]]
name = "libbz2-rs-sys" name = "libbz2-rs-sys"
version = "0.2.3" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a6a8c165077efc8f3a971534c50ea6a1a18b329ef4a66e897a7e3a1494565f" checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c"
[[package]] [[package]]
name = "libc" name = "libc"
@@ -956,9 +963,9 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]] [[package]]
name = "nix" name = "nix"
version = "0.31.2" version = "0.31.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cfg-if", "cfg-if",
@@ -994,16 +1001,6 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "num_cpus"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
dependencies = [
"hermit-abi",
"libc",
]
[[package]] [[package]]
name = "objc2" name = "objc2"
version = "0.6.4" version = "0.6.4"
@@ -1067,19 +1064,20 @@ dependencies = [
[[package]] [[package]]
name = "petgraph" name = "petgraph"
version = "0.7.1" version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455"
dependencies = [ dependencies = [
"fixedbitset", "fixedbitset",
"hashbrown 0.15.5",
"indexmap", "indexmap",
] ]
[[package]] [[package]]
name = "phf_shared" name = "phf_shared"
version = "0.11.3" version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266"
dependencies = [ dependencies = [
"siphasher", "siphasher",
] ]
@@ -1258,9 +1256,9 @@ checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
[[package]] [[package]]
name = "sequoia-openpgp" name = "sequoia-openpgp"
version = "2.2.0" version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0620e44a7d514adf7df87b44db235f13b81fed7ddc265adb26f014d42626ac47" checksum = "c847f0f148cf238c3aec88d092fd3c4301c21e906829ea9e415ea7531f7ec094"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"argon2", "argon2",
@@ -1315,9 +1313,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.149" version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
@@ -1384,9 +1382,9 @@ checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
[[package]] [[package]]
name = "string_cache" name = "string_cache"
version = "0.8.9" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901"
dependencies = [ dependencies = [
"new_debug_unreachable", "new_debug_unreachable",
"parking_lot", "parking_lot",
@@ -1558,9 +1556,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.121" version = "0.2.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
@@ -1571,9 +1569,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.121" version = "0.2.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@@ -1581,9 +1579,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.121" version = "0.2.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"proc-macro2", "proc-macro2",
@@ -1594,9 +1592,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.121" version = "0.2.122"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -1916,9 +1914,9 @@ dependencies = [
[[package]] [[package]]
name = "zerofrom" name = "zerofrom"
version = "0.1.7" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272"
dependencies = [ dependencies = [
"zerofrom-derive", "zerofrom-derive",
] ]
+2 -3
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "fingerprunk" name = "fingerprunk"
version = "0.3.0" version = "0.4.0"
authors = ["Niklas Elsbrock <mail@nelsbrock.de>"] authors = ["Niklas Elsbrock <mail@nelsbrock.de>"]
edition = "2024" edition = "2024"
description = "CLI tool for brute-forcing OpenPGP keys with cool fingerprints" description = "CLI tool for brute-forcing OpenPGP keys with cool fingerprints"
@@ -15,6 +15,5 @@ clap = { version = "4.6.1", features = ["derive"] }
ctrlc = "3.5.2" ctrlc = "3.5.2"
fancy-regex = "0.18.0" fancy-regex = "0.18.0"
num-integer = "0.1.46" num-integer = "0.1.46"
num_cpus = "1.17.0"
rpassword = "7.5.2" rpassword = "7.5.2"
sequoia-openpgp = "2.2.0" sequoia-openpgp = "2.3.0"
+12 -16
View File
@@ -3,7 +3,7 @@
use std::{ use std::{
fmt::{self, Write}, fmt::{self, Write},
io, io,
num::NonZeroU64, num::NonZero,
sync::{ sync::{
atomic::{AtomicBool, AtomicU64, Ordering}, atomic::{AtomicBool, AtomicU64, Ordering},
mpsc, mpsc,
@@ -38,9 +38,10 @@ enum Message {
pub struct Config { pub struct Config {
pub regex: Regex, pub regex: Regex,
pub status_enabled: bool, pub status_enabled: bool,
pub stop_after: Option<NonZeroU64>, pub count: Option<NonZero<u64>>,
pub password: Option<Password>, pub password: Option<Password>,
pub userids: Vec<UserID>, pub userids: Vec<UserID>,
pub workers: NonZero<usize>,
} }
#[derive(Debug)] #[derive(Debug)]
@@ -83,24 +84,20 @@ impl Fingerprunk {
} }
thread::scope(|scope| { thread::scope(|scope| {
let ref_self = &self;
let status_displayer = if self.config.status_enabled { let status_displayer = if self.config.status_enabled {
Some( Some(
thread::Builder::new() thread::Builder::new()
.name("status_displayer".to_string()) .name("status_displayer".to_string())
.spawn_scoped(scope, move || ref_self.status_displayer_thread())?, .spawn_scoped(scope, || self.status_displayer_thread())?,
) )
} else { } else {
None None
}; };
for num in 0..num_cpus::get() { for num in 0..self.config.workers.get() {
let sender = sender.clone();
thread::Builder::new() thread::Builder::new()
.name(format!("worker-{num:03}")) .name(format!("worker-{num:03}"))
.spawn_scoped(scope, move || ref_self.worker_thread(sender))?; .spawn_scoped(scope, || self.worker_thread(&sender))?;
} }
let mut stdout = io::stdout().lock(); let mut stdout = io::stdout().lock();
@@ -109,12 +106,12 @@ impl Fingerprunk {
for message in receiver { for message in receiver {
match message { match message {
Message::Key(key) => { Message::Key(key) => {
let cert = self.key_to_cert(&key)?; let cert = self.key_to_cert(key)?;
self.serialize_cert(cert, &mut stdout)?; self.serialize_cert(&cert, &mut stdout)?;
// Increase "found" counter and stop if enough matches have been found // Increase "found" counter and stop if enough matches have been found
let prev = self.counter_found.fetch_add(1, Ordering::Relaxed); let prev = self.counter_found.fetch_add(1, Ordering::Relaxed);
if self.config.stop_after.is_some_and(|s| prev + 1 == s.get()) { if self.config.count.is_some_and(|s| prev + 1 == s.get()) {
break; break;
} }
} }
@@ -134,7 +131,7 @@ impl Fingerprunk {
}) })
} }
fn worker_thread(&self, sender: mpsc::SyncSender<Message>) { fn worker_thread(&self, sender: &mpsc::SyncSender<Message>) {
let mut fingerprint_hex = String::with_capacity(20 * 2); let mut fingerprint_hex = String::with_capacity(20 * 2);
while !self.stop.load(Ordering::Relaxed) { while !self.stop.load(Ordering::Relaxed) {
@@ -160,7 +157,7 @@ impl Fingerprunk {
.expect("should check regex without error") .expect("should check regex without error")
} }
fn key_to_cert(&self, key: &SecretKey) -> anyhow::Result<Cert> { fn key_to_cert(&self, mut key: SecretKey) -> anyhow::Result<Cert> {
let creation_time = SystemTime::now(); let creation_time = SystemTime::now();
let mut signer = key let mut signer = key
@@ -174,7 +171,6 @@ impl Fingerprunk {
// Create certificate // Create certificate
let mut cert = Cert::try_from(Packet::SecretKey({ let mut cert = Cert::try_from(Packet::SecretKey({
let mut key = key.clone();
if let Some(ref password) = self.config.password { if let Some(ref password) = self.config.password {
let (k, mut secret) = key.take_secret(); let (k, mut secret) = key.take_secret();
secret.encrypt_in_place(&k, password)?; secret.encrypt_in_place(&k, password)?;
@@ -204,7 +200,7 @@ impl Fingerprunk {
Ok(cert) Ok(cert)
} }
fn serialize_cert(&self, cert: Cert, to: impl io::Write) -> anyhow::Result<()> { fn serialize_cert(&self, cert: &Cert, to: impl io::Write) -> anyhow::Result<()> {
let mut comments = cert.armor_headers(); let mut comments = cert.armor_headers();
comments.push(format!( comments.push(format!(
"Generated with Fingerprunk. Regex: {}", "Generated with Fingerprunk. Regex: {}",
+27 -12
View File
@@ -1,9 +1,9 @@
use std::{ use std::{
io::{self, IsTerminal}, io::{self, IsTerminal},
num::NonZeroU64, num::NonZero,
}; };
use anyhow::{Context as AnyhowContext, anyhow}; use anyhow::{Context, anyhow};
use clap::{ArgAction, Parser, ValueEnum}; use clap::{ArgAction, Parser, ValueEnum};
use fancy_regex::Regex; use fancy_regex::Regex;
use fingerprunk::Fingerprunk; use fingerprunk::Fingerprunk;
@@ -31,8 +31,8 @@ struct Args {
status: StatusEnabled, status: StatusEnabled,
/// Stop once the specified number of matching keys has been found. /// Stop once the specified number of matching keys has been found.
#[arg(long)] #[arg(short = 'n', long, value_name = "NUM")]
stop_after: Option<NonZeroU64>, count: Option<NonZero<u64>>,
/// Prompt for a password and use it to encrypt matching keys. /// Prompt for a password and use it to encrypt matching keys.
/// ///
@@ -50,6 +50,13 @@ struct Args {
/// Disables the warning about importing keys without user IDs into GnuPG. /// Disables the warning about importing keys without user IDs into GnuPG.
#[arg(long, conflicts_with = "userid", action = ArgAction::SetTrue)] #[arg(long, conflicts_with = "userid", action = ArgAction::SetTrue)]
no_userid: bool, no_userid: bool,
/// Use the specified amount of worker threads.
///
/// If not specified, the amount of worker threads will be set to the amount of the machine's
/// available parallelism.
#[arg(long, value_name = "NUM")]
workers: Option<NonZero<usize>>,
} }
#[derive(ValueEnum, Clone, Copy, Debug, Default)] #[derive(ValueEnum, Clone, Copy, Debug, Default)]
@@ -73,24 +80,33 @@ impl StatusEnabled {
fn main() -> anyhow::Result<()> { fn main() -> anyhow::Result<()> {
let args = Args::parse(); let args = Args::parse();
let workers = match args.workers {
Some(workers) => workers,
None => std::thread::available_parallelism().context(
"unable to determine available parallelism, \
use `--workers <NUM>` to specify amount of worker threads",
)?,
};
if !args.no_userid && args.userid.is_empty() { if !args.no_userid && args.userid.is_empty() {
eprintln!( eprintln!(
"WARNING: No user ID was provided.\n\ "WARNING: No user ID was provided.\n\
You may experience problems importing generated keys into GnuPG.\n\ You may experience problems importing generated keys into GnuPG.\n\
Use the --userid option to add a user ID.\n" Use `--userid <USERID>` to add a user ID.\n"
) );
} }
let password = if args.password { let password = if args.password {
let password = rpassword::prompt_password( let password = rpassword::prompt_password(
"Enter password for encrypting found keys (leave empty for no encryption): ", "Enter password for encrypting found keys (leave empty for no encryption): ",
) )
.with_context(|| "Failed to prompt password")?; .context("Failed to prompt password")?;
if password.is_empty() { if password.is_empty() {
None None
} else { } else {
let password_retype = rpassword::prompt_password("Retype password: ") let password_retype = rpassword::prompt_password("Retype password: ")
.with_context(|| "Failed to prompt password retype")?; .context("Failed to prompt password retype")?;
if password_retype == password { if password_retype == password {
Some(password.into()) Some(password.into())
} else { } else {
@@ -104,12 +120,11 @@ fn main() -> anyhow::Result<()> {
let config = fingerprunk::Config { let config = fingerprunk::Config {
regex: args.regex, regex: args.regex,
status_enabled: args.status.evaluate(), status_enabled: args.status.evaluate(),
stop_after: args.stop_after, count: args.count,
password, password,
userids: args.userid, userids: args.userid,
workers,
}; };
Fingerprunk::new_from_config(config).run()?; Fingerprunk::new_from_config(config).run()
Ok(())
} }