summaryrefslogtreecommitdiffstats
path: root/sq/src/sq_cli.rs
diff options
context:
space:
mode:
Diffstat (limited to 'sq/src/sq_cli.rs')
-rw-r--r--sq/src/sq_cli.rs678
1 files changed, 342 insertions, 336 deletions
diff --git a/sq/src/sq_cli.rs b/sq/src/sq_cli.rs
index e9904085..8163fdd6 100644
--- a/sq/src/sq_cli.rs
+++ b/sq/src/sq_cli.rs
@@ -1,9 +1,9 @@
/// Command-line parser for sq.
-use clap::{App, Arg, ArgGroup, SubCommand, AppSettings};
+use clap::{Command, Arg, ArgGroup};
-pub fn build() -> App<'static, 'static> {
- configure(App::new("sq"),
+pub fn build() -> Command<'static> {
+ configure(Command::new("sq"),
cfg!(feature = "autocrypt"),
)
}
@@ -19,9 +19,9 @@ pub fn build() -> App<'static, 'static> {
/// - Armor (5xx)
/// - Inspection & packet manipulation (6xx)
pub fn configure(
- app: App<'static, 'static>,
+ app: Command<'static>,
feature_autocrypt: bool,
-) -> App<'static, 'static> {
+) -> Command<'static> {
let version = Box::leak(
format!("{} (sequoia-openpgp {}, using {})",
env!("CARGO_PKG_VERSION"),
@@ -48,23 +48,22 @@ We use the term \"certificate\", or cert for short, to refer to OpenPGP
keys that do not contain secrets. Conversely, we use the term \"key\"
to refer to OpenPGP keys that do contain secrets.
")
- .settings(&[
- AppSettings::SubcommandRequiredElseHelp,
- AppSettings::VersionlessSubcommands,
- ])
- .arg(Arg::with_name("force")
- .short("f").long("force")
+ .subcommand_required(true)
+ .arg_required_else_help(true)
+ .disable_colored_help(true)
+ .arg(Arg::new("force")
+ .short('f').long("force")
.help("Overwrites existing files"))
- .arg(Arg::with_name("known-notation")
+ .arg(Arg::new("known-notation")
.long("known-notation").value_name("NOTATION")
- .multiple(true).number_of_values(1)
+ .multiple_occurrences(true)
.help("Adds NOTATION to the list of known notations")
.long_help("Adds NOTATION to the list of known notations. \
This is used when validating signatures. \
Signatures that have unknown notations with the \
critical bit set are considered invalid."))
- .subcommand(SubCommand::with_name("decrypt")
+ .subcommand(Command::new("decrypt")
.display_order(110)
.about("Decrypts a message")
.long_about(
@@ -100,14 +99,14 @@ $ sq decrypt --recipient-key juliet.pgp --signer-cert romeo.pgp ciphertext.pgp
# Decrypt a file using a password
$ sq decrypt ciphertext.pgp
")
- .arg(Arg::with_name("input")
+ .arg(Arg::new("input")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
- .arg(Arg::with_name("signatures")
- .short("n").long("signatures").value_name("N")
+ .arg(Arg::new("signatures")
+ .short('n').long("signatures").value_name("N")
.help("Sets the threshold of valid signatures to N")
.long_help(
"Sets the threshold of valid signatures to N. \
@@ -115,29 +114,29 @@ $ sq decrypt ciphertext.pgp
verified if this threshold is reached. \
[default: 1 if at least one signer cert file \
is given, 0 otherwise]"))
- .arg(Arg::with_name("sender-cert-file")
+ .arg(Arg::new("sender-cert-file")
.long("signer-cert").value_name("CERT")
- .multiple(true).number_of_values(1)
+ .multiple_occurrences(true)
.help("Verifies signatures with CERT"))
- .arg(Arg::with_name("secret-key-file")
+ .arg(Arg::new("secret-key-file")
.long("recipient-key").value_name("KEY")
- .multiple(true).number_of_values(1)
+ .multiple_occurrences(true)
.help("Decrypts with KEY"))
- .arg(Arg::with_name("private-key-store")
+ .arg(Arg::new("private-key-store")
.long("private-key-store").value_name("KEY_STORE")
.help("Provides parameters for private key store"))
- .arg(Arg::with_name("dump-session-key")
+ .arg(Arg::new("dump-session-key")
.long("dump-session-key")
.help("Prints the session key to stderr"))
- .arg(Arg::with_name("dump")
+ .arg(Arg::new("dump")
.long("dump")
.help("Prints a packet dump to stderr"))
- .arg(Arg::with_name("hex")
- .short("x").long("hex")
+ .arg(Arg::new("hex")
+ .short('x').long("hex")
.help("Prints a hexdump (implies --dump)"))
)
- .subcommand(SubCommand::with_name("encrypt")
+ .subcommand(Command::new("encrypt")
.display_order(100)
.about("Encrypts a message")
.long_about(
@@ -160,35 +159,35 @@ $ sq encrypt --recipient-cert romeo.pgp --signer-key juliet.pgp message.txt
# Encrypt a file using a password
$ sq encrypt --symmetric message.txt
")
- .arg(Arg::with_name("input")
+ .arg(Arg::new("input")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
- .arg(Arg::with_name("binary")
- .short("B").long("binary")
+ .arg(Arg::new("binary")
+ .short('B').long("binary")
.help("Emits binary data"))
- .arg(Arg::with_name("recipients-cert-file")
+ .arg(Arg::new("recipients-cert-file")
.long("recipient-cert").value_name("CERT-RING")
- .multiple(true).number_of_values(1)
+ .multiple_occurrences(true)
.help("Encrypts for all recipients in CERT-RING"))
- .arg(Arg::with_name("signer-key-file")
+ .arg(Arg::new("signer-key-file")
.long("signer-key").value_name("KEY")
- .multiple(true).number_of_values(1)
+ .multiple_occurrences(true)
.help("Signs the message with KEY"))
- .arg(Arg::with_name("private-key-store")
+ .arg(Arg::new("private-key-store")
.long("private-key-store").value_name("KEY_STORE")
.help("Provides parameters for private key store"))
- .arg(Arg::with_name("symmetric")
- .short("s").long("symmetric")
- .multiple(true)
+ .arg(Arg::new("symmetric")
+ .short('s').long("symmetric")
+ .multiple_occurrences(true)
.help("Adds a password to encrypt with")
.long_help("Adds a password to encrypt with. \
The message can be decrypted with \
either one of the recipient's keys, \
or any password."))
- .arg(Arg::with_name("mode")
+ .arg(Arg::new("mode")
.long("mode").value_name("MODE")
.possible_values(&["transport", "rest", "all"])
.default_value("all")
@@ -201,17 +200,17 @@ $ sq encrypt --symmetric message.txt
selects those for encrypting data at rest, \
and all selects all encryption-capable \
subkeys."))
- .arg(Arg::with_name("compression")
+ .arg(Arg::new("compression")
.long("compression").value_name("KIND")
.possible_values(&["none", "pad", "zip", "zlib",
"bzip2"])
.default_value("pad")
.help("Selects compression scheme to use"))
- .arg(Arg::with_name("time")
- .short("t").long("time").value_name("TIME")
+ .arg(Arg::new("time")
+ .short('t').long("time").value_name("TIME")
.help("Chooses keys valid at the specified time and \
sets the signature's creation time"))
- .arg(Arg::with_name("use-expired-subkey")
+ .arg(Arg::new("use-expired-subkey")
.long("use-expired-subkey")
.help("Falls back to expired encryption subkeys")
.long_help(
@@ -220,7 +219,7 @@ $ sq encrypt --symmetric message.txt
to using the one that expired last"))
)
- .subcommand(SubCommand::with_name("sign")
+ .subcommand(Command::new("sign")
.display_order(200)
.about("Signs messages or data files")
.long_about(
@@ -240,22 +239,22 @@ $ sq sign --signer-key juliet.pgp message.txt
# Create a detached signature
$ sq sign --detached --signer-key juliet.pgp message.txt
")
- .arg(Arg::with_name("input")
+ .arg(Arg::new("input")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
- .arg(Arg::with_name("binary")
- .short("B").long("binary")
+ .arg(Arg::new("binary")
+ .short('B').long("binary")
.help("Emits binary data"))
- .arg(Arg::with_name("private-key-store")
+ .arg(Arg::new("private-key-store")
.long("private-key-store").value_name("KEY_STORE")
.help("Provides parameters for private key store"))
- .arg(Arg::with_name("detached")
+ .arg(Arg::new("detached")
.long("detached")
.help("Creates a detached signature"))
- .arg(Arg::with_name("clearsign")
+ .arg(Arg::new("clearsign")
.long("cleartext-signature")
.conflicts_with_all(&[
"detached",
@@ -264,15 +263,15 @@ $ sq sign --detached --signer-key juliet.pgp message.txt
"binary",
])
.help("Creates a cleartext signature"))
- .arg(Arg::with_name("append")
- .short("a").long("append")
+ .arg(Arg::new("append")
+ .short('a').long("append")
.conflicts_with("notarize")
.help("Appends a signature to existing signature"))
- .arg(Arg::with_name("notarize")
- .short("n").long("notarize")
+ .arg(Arg::new("notarize")
+ .short('n').long("notarize")
.conflicts_with("append")
.help("Signs a message and all existing signatures"))
- .arg(Arg::with_name("merge")
+ .arg(Arg::new("merge")
.long("merge").value_name("SIGNED-MESSAGE")
.conflicts_with_all(&[
"append",
@@ -284,18 +283,18 @@ $ sq sign --detached --signer-key juliet.pgp message.txt
])
.help("Merges signatures from the input and \
SIGNED-MESSAGE"))
- .arg(Arg::with_name("secret-key-file")
+ .arg(Arg::new("secret-key-file")
.long("signer-key").value_name("KEY")
- .multiple(true).number_of_values(1)
+ .multiple_occurrences(true)
.help("Signs using KEY"))
- .arg(Arg::with_name("time")
- .short("t").long("time").value_name("TIME")
+ .arg(Arg::new("time")
+ .short('t').long("time").value_name("TIME")
.help("Chooses keys valid at the specified time and \
sets the signature's creation time"))
- .arg(Arg::with_name("notation")
+ .arg(Arg::new("notation")
.value_names(&["NAME", "VALUE"])
.long("notation")
- .multiple(true).number_of_values(2)
+ .multiple_occurrences(true).number_of_values(2)
.help("Adds a notation to the certification.")
.long_help(
"Adds a notation to the certification. \
@@ -310,7 +309,7 @@ $ sq sign --detached --signer-key juliet.pgp message.txt
.conflicts_with("merge"))
)
- .subcommand(SubCommand::with_name("verify")
+ .subcommand(Command::new("verify")
.display_order(210)
.about("Verifies signed messages or detached signatures")
.long_about(
@@ -346,30 +345,30 @@ SEE ALSO:
If you are looking for a standalone program to verify detached
signatures, consider using sequoia-sqv.
")
- .arg(Arg::with_name("input")
+ .arg(Arg::new("input")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
- .arg(Arg::with_name("detached")
+ .arg(Arg::new("detached")
.long("detached").value_name("SIG")
.help("Verifies a detached signature"))
- .arg(Arg::with_name("signatures")
- .short("n").long("signatures").value_name("N")
+ .arg(Arg::new("signatures")
+ .short('n').long("signatures").value_name("N")
.default_value("1")
.help("Sets the threshold of valid signatures to N")
.long_help(
"Sets the threshold of valid signatures to N. \
If this threshold is not reached, the message \
will not be considered verified."))
- .arg(Arg::with_name("sender-cert-file")
+ .arg(Arg::new("sender-cert-file")
.long("signer-cert").value_name("CERT")
- .multiple(true).number_of_values(1)
+ .multiple_occurrences(true)
.help("Verifies signatures with CERT"))
)
- .subcommand(SubCommand::with_name("armor")
+ .subcommand(Command::new("armor")
.display_order(500)
.about("Converts binary to ASCII")
.long_about(
@@ -391,13 +390,13 @@ $ sq armor binary-juliet.pgp
# Convert a binary message to ASCII
$ sq armor binary-message.pgp
")
- .arg(Arg::with_name("input")
+ .arg(Arg::new("input")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
- .arg(Arg::with_name("kind")
+ .arg(Arg::new("kind")
.long("label").value_name("LABEL")
.possible_values(&["auto", "message",
"cert", "key", "sig",
@@ -406,7 +405,7 @@ $ sq armor binary-message.pgp
.help("Selects the kind of armor header"))
)
- .subcommand(SubCommand::with_name("dearmor")
+ .subcommand(Command::new("dearmor")
.display_order(510)
.about("Converts ASCII to binary")
.long_about(
@@ -429,16 +428,16 @@ $ sq dearmor ascii-juliet.pgp
# Convert a ASCII message to binary
$ sq dearmor ascii-message.pgp
")
- .arg(Arg::with_name("input")
+ .arg(Arg::new("input")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
)
- .subcommand(SubCommand::with_name("inspect")
+ .subcommand(Command::new("inspect")
.display_order(600)
.about("Inspects data, like file(1)")
.long_about(
@@ -464,16 +463,16 @@ $ sq inspect message.pgp
# Inspects a detached signature
$ sq inspect message.sig
")
- .arg(Arg::with_name("input")
+ .arg(Arg::new("input")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
- .arg(Arg::with_name("certifications")
+ .arg(Arg::new("certifications")
.long("certifications")
.help("Prints third-party certifications"))
)
.subcommand(
- SubCommand::with_name("key")
+ Command::new("key")
.display_order(300)
.about("Manages keys")
.long_about(
@@ -487,9 +486,10 @@ Conversely, we use the term \"certificate\", or cert for short, to refer
to OpenPGP keys that do not contain secrets. See \"sq keyring\" for
operations on certificates.
")
- .setting(AppSettings::SubcommandRequiredElseHelp)
+ .subcommand_required(true)
+ .arg_required_else_help(true)
.subcommand(
- SubCommand::with_name("generate")
+ Command::new("generate")
.display_order(100)
.about("Generates a new key")
.long_about(
@@ -523,21 +523,21 @@ $ sq key generate --userid \"<juliet@example.org>\" --with-password
# Generates a key with multiple userids
$ sq key generate --userid \"<juliet@example.org>\" --userid \"Juliet Capulet\"
")
- .arg(Arg::with_name("userid")
- .short("u").long("userid").value_name("EMAIL")
- .multiple(true).number_of_values(1)
+ .arg(Arg::new("userid")
+ .short('u').long("userid").value_name("EMAIL")
+ .multiple_occurrences(true)
.help("Adds a userid to the key"))
- .arg(Arg::with_name("cipher-suite")
- .short("c").long("cipher-suite").value_name("CIPHER-SUITE")
+ .arg(Arg::new("cipher-suite")
+ .short('c').long("cipher-suite").value_name("CIPHER-SUITE")
.possible_values(&["rsa3k", "rsa4k", "cv25519"])
.default_value("cv25519")
.help("Selects the cryptographic algorithms for \
the key"))
- .arg(Arg::with_name("with-password")
+ .arg(Arg::new("with-password")
.long("with-password")
.help("Protects the key with a password"))
- .arg(Arg::with_name("creation-time")
+ .arg(Arg::new("creation-time")
.long("creation-time").value_name("CREATION_TIME")
.help("Sets the key's creation time to TIME (as ISO 8601)")
.long_help("\
@@ -553,17 +553,17 @@ default timezone is UTC):
$ sq key generate --creation-time 20110609T1938+0200 --export noam.pgp
"))
- .group(ArgGroup::with_name("expiration-group")
+ .group(ArgGroup::new("expiration-group")
.args(&["expires", "expires-in"]))
- .arg(Arg::with_name("expires")
+ .arg(Arg::new("expires")
.long("expires").value_name("TIME")
.help("Makes the key expire at TIME (as ISO 8601)")
.long_help(
"Makes the key expire at TIME (as ISO 8601). \
Use \"never\" to create keys that do not \
expire."))
- .arg(Arg::with_name("expires-in")
+ .arg(Arg::new("expires-in")
.long("expires-in").value_name("DURATION")
// Catch negative numbers.
.allow_hyphen_values(true)
@@ -574,27 +574,27 @@ $ sq key generate --creation-time 20110609T1938+0200 --export noam.pgp
Either \"N[ymwds]\", for N years, months, \
weeks, days, seconds, or \"never\"."))
- .group(ArgGroup::with_name("cap-sign")
+ .group(ArgGroup::new("cap-sign")
.args(&["can-sign", "cannot-sign"]))
- .arg(Arg::with_name("can-sign")
+ .arg(Arg::new("can-sign")
.long("can-sign")
.help("Adds a signing-capable subkey (default)"))
- .arg(Arg::with_name("cannot-sign")
+ .arg(Arg::new("cannot-sign")
.long("cannot-sign")
.help("Adds no signing-capable subkey"))
- .group(ArgGroup::with_name("cap-authenticate")
+ .group(ArgGroup::new("cap-authenticate")
.args(&["can-authenticate", "cannot-authenticate"]))
- .arg(Arg::with_name("can-authenticate")
+ .arg(Arg::new("can-authenticate")
.long("can-authenticate")
.help("Adds an authentication-capable subkey (default)"))
- .arg(Arg::with_name("cannot-authenticate")
+ .arg(Arg::new("cannot-authenticate")
.long("cannot-authenticate")
.help("Adds no authentication-capable subkey"))
- .group(ArgGroup::with_name("cap-encrypt")
+ .group(ArgGroup::new("cap-encrypt")
.args(&["can-encrypt", "cannot-encrypt"]))
- .arg(Arg::with_name("can-encrypt")
+ .arg(Arg::new("can-encrypt")
.long("can-encrypt").value_name("PURPOSE")
.possible_values(&["transport", "storage",
"universal"])
@@ -606,17 +606,17 @@ $ sq key generate --creation-time 20110609T1938+0200 --export noam.pgp
suitable for transport encryption, storage \
encryption, or both. \
[default: universal]"))
- .arg(Arg::with_name("cannot-encrypt")
+ .arg(Arg::new("cannot-encrypt")
.long("cannot-encrypt")
.help("Adds no encryption-capable subkey"))
- .arg(Arg::with_name("export")
- .short("e").long("export").value_name("OUTFILE")
+ .arg(Arg::new("export")
+ .short('e').long("export").value_name("OUTFILE")
.help("Writes the key to OUTFILE")
.required(true))
- .arg(Arg::with_name("rev-cert")
+ .arg(Arg::new("rev-cert")
.long("rev-cert").value_name("FILE or -")
- .required_if("export", "-")
+ .required_if_eq("export", "-")
.help("Writes the revocation certificate to FILE")
.long_help(
"Writes the revocation certificate to FILE. \
@@ -624,7 +624,7 @@ $ sq key generate --creation-time 20110609T1938+0200 --export noam.pgp
[default: <OUTFILE>.rev]"))
)
.subcommand(
- SubCommand::with_name("password")
+ Command::new("password")
.display_order(105)
.about("Changes password protecting secrets")
.long_about(
@@ -648,20 +648,20 @@ $ sq key password < juliet.key.pgp > juliet.encrypted_key.pgp
# And remove the password again.
$ sq key password --clear < juliet.encrypted_key.pgp > juliet.decrypted_key.pgp
")
- .arg(Arg::with_name("clear")
+ .arg(Arg::new("clear")
.long("clear")
.help("Emit a key with unencrypted secrets"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
- .arg(Arg::with_name("binary")
- .short("B").long("binary")
+ .arg(Arg::new("binary")
+ .short('B').long("binary")
.help("Emits binary data"))
- .arg(Arg::with_name("key")
+ .arg(Arg::new("key")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
)
- .subcommand(SubCommand::with_name("extract-cert")
+ .subcommand(Command::new("extract-cert")
.display_order(110)
.about("Converts a key to a cert")
.long_about(
@@ -681,18 +681,18 @@ $ sq key generate --userid \"<juliet@example.org>\" --export juliet.key.pgp
# Then, this extracts the certificate for distribution
$ sq key extract-cert --output juliet.cert.pgp juliet.key.pgp
")
- .arg(Arg::with_name("input")
+ .arg(Arg::new("input")
.value_name("FILE")
.help("Reads from FILE or stdin if omitted"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
- .arg(Arg::with_name("binary")
- .short("B").long("binary")
+ .arg(Arg::new("binary")
+ .short('B').long("binary")
.help("Emits binary data"))
)
.subcommand(
- SubCommand::with_name("adopt")
+ Command::new("adopt")
.display_order(800)
.about("Binds keys from one certificate to another")
.long_about(
@@ -712,32 +712,32 @@ feasible.
# Adopt an subkey into the new cert
$ sq key adopt --keyring juliet-old.pgp --key 0123456789ABCDEF -- juliet-new.pgp
")
- .arg(Arg::with_name("keyring")
- .short("r").long("keyring").value_name("KEY-RING")
- .multiple(true).number_of_values(1)
+ .arg(Arg::new("keyring")
+ .short('r').long("keyring").value_name("KEY-RING")
+ .multiple_occurrences(true)
.help("Supplies keys for use in --key."))
- .arg(Arg::with_name("key")
- .short("k").long("key").value_name("KEY")
- .multiple(true).number_of_values(1)
+ .arg(Arg::new("key")
+ .short('k').long("key").value_name("KEY")
+ .multiple_occurrences(true)
.required(true)
.help("Adds the key or subkey KEY to the \
TARGET-KEY"))
- .arg(Arg::with_name("allow-broken-crypto")
+ .arg(Arg::new("allow-broken-crypto")
.long("allow-broken-crypto")
.help("Allows adopting keys from certificates \
using broken cryptography"))
- .arg(Arg::with_name("certificate")
+ .arg(Arg::new("certificate")
.value_name("TARGET-KEY")
.help("Adds keys to TARGET-KEY"))
- .arg(Arg::with_name("output")
- .short("o").long("output").value_name("FILE")
+ .arg(Arg::new("output")
+ .short('o').long("output").value_name("FILE")
.help("Writes to FILE or stdout if omitted"))
- .arg(Arg::with_name("binary")
- .short("B").long("binary")
+ .arg(Arg::new("binary")
+ .short('B').long("binary")
.help("Emits binary data"))
)
.subcommand(
- SubCommand::with_name("attest-certifications")
+ Command::new("attest-certifications")
.display_order(200)
.about("Attests to third-party certifications")
.long_about(
@@ -763,28 +763,28 @@ $ sq key attest-certifications juliet.pgp
# Retract prior attestations on the key
$ sq key attest-certifications --none juliet.pgp
")
- .arg(Arg::with_name("none")
+ .arg(Arg::new("none")
.long("none")