summaryrefslogtreecommitdiffstats
path: root/sq
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2021-01-15 10:50:44 +0100
committerJustus Winter <justus@sequoia-pgp.org>2021-01-15 11:34:49 +0100
commita9ac52a46fa38d60664ddd8f2d046803ba111a33 (patch)
tree589f453cb9501433443ddb483cf137c2c7fb5c36 /sq
parent263df5c5510a0685cc98274234456510aaa16713 (diff)
sq: Drop public key store integration.
- We want to release sq without it depending on the key store. The keystore is little more than a prototype, but because it keeps state, it has the potential to break if we change it later.
Diffstat (limited to 'sq')
-rw-r--r--sq/Cargo.toml4
-rw-r--r--sq/src/commands/mappings.rs222
-rw-r--r--sq/src/commands/mod.rs52
-rw-r--r--sq/src/sq-usage.rs222
-rw-r--r--sq/src/sq.rs41
-rw-r--r--sq/src/sq_cli.rs85
6 files changed, 7 insertions, 619 deletions
diff --git a/sq/Cargo.toml b/sq/Cargo.toml
index 1c79f069..a32c32b6 100644
--- a/sq/Cargo.toml
+++ b/sq/Cargo.toml
@@ -25,15 +25,12 @@ maintenance = { status = "actively-developed" }
buffered-reader = { path = "../buffered-reader", version = "1.0.0", default-features = false }
sequoia-openpgp = { path = "../openpgp", version = "1.0.0", default-features = false }
sequoia-autocrypt = { path = "../autocrypt", version = "0.22", default-features = false }
-sequoia-core = { path = "../core", version = "0.22", default-features = false }
sequoia-ipc = { path = "../ipc", version = "0.22", default-features = false }
sequoia-net = { path = "../net", version = "0.22", default-features = false }
-sequoia-store = { path = "../store", version = "0.22", default-features = false }
anyhow = "1.0.18"
chrono = "0.4.10"
clap = "2.33"
itertools = "0.9"
-prettytable-rs = "0.8.0"
tempfile = "3.1"
crossterm = "0.13"
tokio = { version = "0.2.19", features = ["rt-core", "io-util", "io-driver"] }
@@ -55,7 +52,6 @@ path = "src/sq-usage.rs"
default = [
"buffered-reader/compression",
"sequoia-openpgp/default",
- "sequoia-store/background-services"
]
crypto-nettle = ["sequoia-openpgp/crypto-nettle"]
crypto-cng = ["sequoia-openpgp/crypto-cng"]
diff --git a/sq/src/commands/mappings.rs b/sq/src/commands/mappings.rs
deleted file mode 100644
index 0846cb52..00000000
--- a/sq/src/commands/mappings.rs
+++ /dev/null
@@ -1,222 +0,0 @@
-use anyhow::Context;
-
-use prettytable::{Table, Cell, Row, row, cell};
-
-use sequoia_openpgp as openpgp;
-use openpgp::{
- Result,
- cert::{
- Cert,
- },
- parse::Parse,
- serialize::Serialize,
-};
-use sequoia_store as store;
-use store::{
- Mapping,
- LogIter,
-};
-
-use crate::{
- Config,
- help_warning,
- commands::dump::Convert,
- open_or_stdin,
- create_or_stdout,
-};
-
-pub fn dispatch_mapping(config: Config, m: &clap::ArgMatches) -> Result<()> {
- let mapping = Mapping::open(&config.context, config.network_policy,
- &config.realm_name, &config.mapping_name)
- .context("Failed to open the mapping")?;
-
- match m.subcommand() {
- ("list", Some(_)) => {
- list_bindings(&mapping, &config.realm_name, &config.mapping_name)?;
- },
- ("add", Some(m)) => {
- let fp = m.value_of("fingerprint").unwrap().parse()
- .expect("Malformed fingerprint");
- mapping.add(m.value_of("label").unwrap(), &fp)?;
- },
- ("import", Some(m)) => {
- let label = m.value_of("label").unwrap();
- help_warning(label);
- let mut input = open_or_stdin(m.value_of("input"))?;
- let cert = Cert::from_reader(&mut input)?;
- mapping.import(label, &cert)?;
- },
- ("export", Some(m)) => {
- let cert = mapping.lookup(m.value_of("label").unwrap())?.cert()?;
- let mut output = create_or_stdout(m.value_of("output"),
- config.force)?;
- if m.is_present("binary") {
- cert.serialize(&mut output)?;
- } else {
- cert.armored().serialize(&mut output)?;
- }
- },
- ("delete", Some(m)) => {
- if m.is_present("label") == m.is_present("the-mapping") {
- return Err(anyhow::anyhow!(
- "Please specify either a label or --the-mapping."));
- }
-
- if m.is_present("the-mapping") {
- mapping.delete().context("Failed to delete the mapping")?;
- } else {
- let binding = mapping.lookup(m.value_of("label").unwrap())
- .context("Failed to get key")?;
- binding.delete().context("Failed to delete the binding")?;
- }
- },
- ("stats", Some(m)) => {
- mapping_print_stats(&mapping,
- m.value_of("label").unwrap())?;
- },
- ("log", Some(m)) => {
- if m.is_present("label") {
- let binding = mapping.lookup(m.value_of("label").unwrap())
- .context("No such key")?;
- print_log(binding.log().context("Failed to get log")?, false);
- } else {
- print_log(mapping.log().context("Failed to get log")?, true);
- }
- },
- _ => unreachable!(),
- }
-
- Ok(())
-}
-
-pub fn dispatch_list(config: Config, m: &clap::ArgMatches) -> Result<()> {
- match m.subcommand() {
- ("mappings", Some(m)) => {
- let mut table = Table::new();
- table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
- table.set_titles(row!["realm", "name", "network policy"]);
-
- for (realm, name, network_policy, _)
- in Mapping::list(&config.context, m.value_of("prefix").unwrap_or(""))? {
- table.add_row(Row::new(vec![
- Cell::new(&realm),
- Cell::new(&name),
- Cell::new(&format!("{:?}", network_policy))
- ]));
- }
-
- table.printstd();
- },
- ("bindings", Some(m)) => {
- for (realm, name, _, mapping)
- in Mapping::list(&config.context, m.value_of("prefix").unwrap_or(""))? {
- list_bindings(&mapping, &realm, &name)?;
- }
- },
- ("keys", Some(_)) => {
- let mut table = Table::new();
- table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
- table.set_titles(row!["fingerprint", "updated", "status"]);
-
- for (fingerprint, key) in store::Store::list_keys(&config.context)? {
- let stats = key.stats()
- .context("Failed to get key stats")?;
- table.add_row(Row::new(vec![
- Cell::new(&fingerprint.to_string()),
- if let Some(t) = stats.updated {
- Cell::new(&t.convert().to_string())
- } else {
- Cell::new("")
- },
- Cell::new("")
- ]));
- }
-
- table.printstd();
- },
- ("log", Some(_)) => {
- print_log(store::Store::server_log(&config.context)?, true);
- },
- _ => unreachable!(),
- }
-
- Ok(())
-}
-
-fn list_bindings(mapping: &Mapping, realm: &str, name: &str)
- -> Result<()> {
- if mapping.iter()?.count() == 0 {
- println!("No label-key bindings in the \"{}/{}\" mapping.",
- realm, name);
- return Ok(());
- }
-
- println!("Realm: {:?}, mapping: {:?}:", realm, name);
-
- let mut table = Table::new();
- table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
- table.set_titles(row!["label", "fingerprint"]);
- for (label, fingerprint, _) in mapping.iter()? {
- table.add_row(Row::new(vec![
- Cell::new(&label),
- Cell::new(&fingerprint.to_string())]));
- }
- table.printstd();
- Ok(())
-}
-
-fn print_log(iter: LogIter, with_slug: bool) {
- let mut table = Table::new();
- table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
- let mut head = row!["timestamp", "message"];
- if with_slug {
- head.insert_cell(1, Cell::new("slug"));
- }
- table.set_titles(head);
-
- for entry in iter {
- let mut row = row![&entry.timestamp.convert().to_string(),
- &entry.short()];
- if with_slug {
- row.insert_cell(1, Cell::new(&entry.slug));
- }
- table.add_row(row);
- }
-
- table.printstd();
-}
-
-pub fn mapping_print_stats(mapping: &store::Mapping, label: &str) -> Result<()> {
- fn print_stamps(st: &store::Stamps) -> Result<()> {
- println!("{} messages using this key", st.count);
- if let Some(t) = st.first {
- println!(" First: {}", t.convert());
- }
- if let Some(t) = st.last {
- println!(" Last: {}", t.convert());
- }
- Ok(())
- }
-
- fn print_stats(st: &store::Stats) -> Result<()> {
- if let Some(t) = st.created {
- println!(" Created: {}", t.convert());
- }
- if let Some(t) = st.updated {
- println!(" Updated: {}", t.convert());
- }
- print!(" Encrypted ");
- print_stamps(&st.encryption)?;
- print!(" Verified ");
- print_stamps(&st.verification)?;
- Ok(())
- }
-
- let binding = mapping.lookup(label)?;
- println!("Binding {:?}", label);
- print_stats(&binding.stats().context("Failed to get stats")?)?;
- let key = binding.key().context("Failed to get key")?;
- println!("Key");
- print_stats(&key.stats().context("Failed to get stats")?)?;
- Ok(())
-}
diff --git a/sq/src/commands/mod.rs b/sq/src/commands/mod.rs
index 330c71bd..96246ec7 100644
--- a/sq/src/commands/mod.rs
+++ b/sq/src/commands/mod.rs
@@ -25,7 +25,6 @@ use crate::openpgp::serialize::stream::{
padding::Padder,
};
use crate::openpgp::policy::Policy;
-use sequoia_store as store;
use crate::{
Config,
@@ -43,7 +42,6 @@ pub mod key;
pub mod merge_signatures;
pub use self::merge_signatures::merge_signatures;
pub mod certring;
-pub mod mappings;
/// Returns suitable signing keys from a given list of Certs.
fn get_signing_keys(certs: &[openpgp::Cert], p: &dyn Policy,
@@ -200,6 +198,7 @@ pub fn encrypt<'a>(policy: &'a dyn Policy,
}
struct VHelper {
+ #[allow(dead_code)]
config: Config,
signatures: usize,
certs: Option<Vec<Cert>>,
@@ -325,8 +324,8 @@ impl VHelper {
}
impl VerificationHelper for VHelper {
- fn get_certs(&mut self, ids: &[openpgp::KeyHandle]) -> Result<Vec<Cert>> {
- let mut certs = self.certs.take().unwrap();
+ fn get_certs(&mut self, _ids: &[openpgp::KeyHandle]) -> Result<Vec<Cert>> {
+ let certs = self.certs.take().unwrap();
// Get all keys.
let seen: HashSet<_> = certs.iter()
.flat_map(|cert| {
@@ -336,51 +335,6 @@ impl VerificationHelper for VHelper {
// Explicitly provided keys are trusted.
self.trusted = seen.clone();
- use sequoia_store::Mapping;
- let mapping = Mapping::open(&self.config.context,
- self.config.network_policy,
- &self.config.realm_name,
- &self.config.mapping_name)
- .context("Failed to open the mapping")?;
-
- // Try to get missing Certs from the mapping.
- for id in ids.iter().map(|i| KeyID::from(i))
- .filter(|i| !seen.contains(i))
- {
- let _ =
- mapping.lookup_by_subkeyid(&id)
- .and_then(|binding| {
- self.labels.insert(id.clone(), binding.label()?);
-
- // Keys from our mapping are trusted.
- self.trusted.insert(id.clone());
-
- binding.cert()
- })
- .and_then(|cert| {
- certs.push(cert);
- Ok(())
- });
- }
-
- // Update seen.
- let seen = self.trusted.clone();
-
- // Try to get missing Certs from the pool.
- for id in ids.iter().map(|i| KeyID::from(i.clone()))
- .filter(|i| !seen.contains(i))
- {
- let _ =
- store::Store::lookup_by_subkeyid(&self.config.context, &id)
- .and_then(|key| {
- // Keys from the pool are NOT trusted.
- key.cert()
- })
- .and_then(|cert| {
- certs.push(cert);
- Ok(())
- });
- }
Ok(certs)
}
diff --git a/sq/src/sq-usage.rs b/sq/src/sq-usage.rs
index 9519d098..5c0ff4f1 100644
--- a/sq/src/sq-usage.rs
+++ b/sq/src/sq-usage.rs
@@ -14,11 +14,9 @@
//! -V, --version Prints version information
//!
//! OPTIONS:
-//! --home <DIRECTORY> Sets the home directory to use
//! --known-notation <NOTATION>... The notation name is considered known. This is used when validating
//! signatures. Signatures that have unknown notations with the critical bit set
//! are considered invalid.
-//! -m, --mapping <MAPPING> Sets the realm and mapping to use [default: org.sequoia-pgp.contacts/default]
//! -p, --policy <NETWORK-POLICY> Sets the network policy to use
//!
//! SUBCOMMANDS:
@@ -26,7 +24,6 @@
//! encrypt Encrypts a message
//! sign Signs a message
//! verify Verifies a message
-//! mapping Interacts with key mappings
//! merge-signatures Merges two signatures
//! keyserver Interacts with keyservers
//! autocrypt Autocrypt support
@@ -36,7 +33,6 @@
//! help Prints this message or the help of the given subcommand(s)
//! inspect Inspects a sequence of OpenPGP packets
//! key Manipulates keys
-//! list Lists key mappings and known keys
//! packet OpenPGP Packet manipulation
//! wkd Interacts with Web Key Directories
//! ```
@@ -92,7 +88,6 @@
//! transport encryption, rest selects those for encrypting data at rest, and all selects all encryption-capable
//! subkeys [default: all] [possible values: transport, rest, all]
//! -o, --output <FILE> Sets the output file to use
-//! -r, --recipient <LABEL>... Recipient to encrypt for (can be given multiple times)
//! --recipients-cert-file <CERTS-FILE>...
//! Recipients to encrypt for, given as a file (can be given multiple times)
//!
@@ -154,145 +149,6 @@
//! <FILE> Sets the input file to use
//! ```
//!
-//! ## Subcommand mapping
-//!
-//! ```text
-//! Interacts with key mappings
-//!
-//! USAGE:
-//! sq mapping <SUBCOMMAND>
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! SUBCOMMANDS:
-//! add Add a key identified by fingerprint
-//! delete Deletes bindings or mappings
-//! export Exports a key
-//! help Prints this message or the help of the given subcommand(s)
-//! import Imports a key
-//! list Lists keys in the mapping
-//! log Lists the keystore log
-//! stats Get stats for the given label
-//! ```
-//!
-//! ### Subcommand mapping add
-//!
-//! ```text
-//! Add a key identified by fingerprint
-//!
-//! USAGE:
-//! sq mapping add <LABEL> <FINGERPRINT>
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! ARGS:
-//! <LABEL> Label to use
-//! <FINGERPRINT> Key to add
-//! ```
-//!
-//! ### Subcommand mapping delete
-//!
-//! ```text
-//! Deletes bindings or mappings
-//!
-//! USAGE:
-//! sq mapping delete [FLAGS] [LABEL]
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! --the-mapping Delete the selected mapping (change with --mapping)
-//! -V, --version Prints version information
-//!
-//! ARGS:
-//! <LABEL> Delete binding with this label
-//! ```
-//!
-//! ### Subcommand mapping export
-//!
-//! ```text
-//! Exports a key
-//!
-//! USAGE:
-//! sq mapping export [FLAGS] [OPTIONS] <LABEL>
-//!
-//! FLAGS:
-//! -B, --binary Don't ASCII-armor encode the OpenPGP data
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! OPTIONS:
-//! -o, --output <FILE> Sets the output file to use
-//!
-//! ARGS:
-//! <LABEL> Label to use
-//! ```
-//!
-//! ### Subcommand mapping import
-//!
-//! ```text
-//! Imports a key
-//!
-//! USAGE:
-//! sq mapping import <LABEL> [FILE]
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! ARGS:
-//! <LABEL> Label to use
-//! <FILE> Sets the input file to use
-//! ```
-//!
-//! ### Subcommand mapping list
-//!
-//! ```text
-//! Lists keys in the mapping
-//!
-//! USAGE:
-//! sq mapping list
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//! ```
-//!
-//! ### Subcommand mapping log
-//!
-//! ```text
-//! Lists the keystore log
-//!
-//! USAGE:
-//! sq mapping log [LABEL]
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! ARGS:
-//! <LABEL> List messages related to this label
-//! ```
-//!
-//! ### Subcommand mapping stats
-//!
-//! ```text
-//! Get stats for the given label
-//!
-//! USAGE:
-//! sq mapping stats <LABEL>
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! ARGS:
-//! <LABEL> Label to use
-//! ```
-//!
//! ## Subcommand merge-signatures
//!
//! ```text
@@ -678,84 +534,6 @@
//! -u, --userid <EMAIL>... Add userid to the key (can be given multiple times)
//! ```
//!
-//! ## Subcommand list
-//!
-//! ```text
-//! Lists key mappings and known keys
-//!
-//! USAGE:
-//! sq list <SUBCOMMAND>
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! SUBCOMMANDS:
-//! bindings Lists all bindings in all key mappings
-//! help Prints this message or the help of the given subcommand(s)
-//! keys Lists all keys in the common key pool
-//! log Lists the server log
-//! mappings Lists key mappings
-//! ```
-//!
-//! ### Subcommand list bindings
-//!
-//! ```text
-//! Lists all bindings in all key mappings
-//!
-//! USAGE:
-//! sq list bindings [PREFIX]
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! ARGS:
-//! <PREFIX> List only bindings from mappings with the given realm prefix
-//! ```
-//!
-//! ### Subcommand list keys
-//!
-//! ```text
-//! Lists all keys in the common key pool
-//!
-//! USAGE:
-//! sq list keys
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//! ```
-//!
-//! ### Subcommand list log
-//!
-//! ```text
-//! Lists the server log
-//!
-//! USAGE:
-//! sq list log
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//! ```
-//!
-//! ### Subcommand list mappings
-//!
-//! ```text
-//! Lists key mappings
-//!
-//! USAGE:
-//! sq list mappings [PREFIX]
-//!
-//! FLAGS:
-//! -h, --help Prints help information
-//! -V, --version Prints version information
-//!
-//! ARGS:
-//! <PREFIX> List only mappings with the given realm prefix
-//! ```
-//!
//! ## Subcommand packet
//!
//! ```text
diff --git a/sq/src/sq.rs b/sq/src/sq.rs
index 148ea8e0..f9777c2c 100644
--- a/sq/src/sq.rs
+++ b/sq/src/sq.rs
@@ -12,9 +12,7 @@ use chrono::{DateTime, offset::Utc};
use buffered_reader::File;
use sequoia_openpgp as openpgp;
-use sequoia_core;
use sequoia_net;
-use sequoia_store::Mapping;
use openpgp::{
Result,
@@ -33,7 +31,6 @@ use crate::openpgp::parse::Parse;
use crate::openpgp::serialize::{Serialize, stream::{Message, Armorer}};
use crate::openpgp::cert::prelude::*;
use crate::openpgp::policy::StandardPolicy as P;
-use sequoia_core::Context;
use sequoia_net as net;
use sequoia_net::{KeyServer, wkd};
@@ -228,6 +225,7 @@ fn decrypt_key<R>(key: Key<key::SecretParts, R>, passwords: &mut Vec<String>)
///
/// This should be used wherever a positional argument is followed by
/// an optional positional argument.
+#[allow(dead_code)]
fn help_warning(arg: &str) {
if arg == "help" {
eprintln!("Warning: \"help\" is not a subcommand here. \
@@ -235,12 +233,10 @@ fn help_warning(arg: &str) {
}
}
+#[allow(dead_code)]
pub struct Config {
force: bool,
network_policy: net::Policy,
- context: sequoia_core::Context,
- realm_name: String,
- mapping_name: String,
}
fn main() -> Result<()> {
@@ -265,26 +261,10 @@ fn main() -> Result<()> {
},
};
let force = matches.is_present("force");
- let (realm_name, mapping_name) = {
- let s = matches.value_of("mapping").expect("has a default value");
- if let Some(i) = s.find('/') {
- (&s[..i], &s[i+1..])
- } else {
- (s, "default")
- }
- };
- let mut builder = Context::configure();
- if let Some(dir) = matches.value_of("home") {
- builder = builder.home(dir);
- }
- let ctx = builder.build()?;
let config = Config {
force,
network_policy,
- context: ctx,
- realm_name: realm_name.into(),
- mapping_name: mapping_name.into(),
};
@@ -313,20 +293,9 @@ fn main() -> Result<()> {
m.is_present("dump"), m.is_present("hex"))?;
},
("encrypt", Some(m)) => {
- let mapping = Mapping::open(&config.context,
- config.network_policy,
- &config.realm_name,
- &config.mapping_name)
- .context("Failed to open the mapping")?;
- let mut recipients = m.values_of("recipients-cert-file")
+ let recipients = m.values_of("recipients-cert-file")
.map(load_certs)
.unwrap_or(Ok(vec![]))?;
- if let Some(r) = m.values_of("recipient") {
- for recipient in r {
- recipients.push(mapping.lookup(recipient)
- .context("No such key found")?.cert()?);
- }
- }
let mut input = open_or_stdin(m.value_of("input"))?;
let output =
create_or_stdout_pgp(m.value_of("output"), force,
@@ -593,10 +562,6 @@ fn main() -> Result<()> {
_ => unreachable!(),
}
},
- ("mapping", Some(m)) =>
- commands::mappings::dispatch_mapping(config, m)?,
- ("list", Some(m)) =>
- commands::mappings::dispatch_list(config, m)?,
("key", Some(m)) => match m.subcommand() {
("generate", Some(m)) => commands::key::generate(m, force)?,
("adopt", Some(m)) => commands::key::adopt(m, policy)?,
diff --git a/sq/src/sq_cli.rs b/sq/src/sq_cli.rs
index 11496248..29ced67d 100644
--- a/sq/src/sq_cli.rs
+++ b/sq/src/sq_cli.rs
@@ -11,14 +11,6 @@ pub fn build() -> App<'static, 'static> {
.version(env!("CARGO_PKG_VERSION"))
.about("Sequoia is an implementation of OpenPGP. This is a command-line frontend.")
.setting(AppSettings::SubcommandRequiredElseHelp)
- .arg(Arg::with_name("home").value_name("DIRECTORY")
- .long("home")
- .help("Sets the home directory to use"))
- .arg(Arg::with_name("mapping").value_name("MAPPING")
- .long("mapping")
- .short("m")
- .default_value("org.sequoia-pgp.contacts/default")
- .help("Sets the realm and mapping to use"))
.arg(Arg::with_name("policy").value_name("NETWORK-POLICY")
.long("policy")
.short("p")
@@ -92,15 +84,6 @@ pub fn build() -> App<'static, 'static> {
.long("binary")
.short("B")
.help("Don't ASCII-armor encode the OpenPGP data"))
- .arg(Arg::with_name("recipient")
- .long("recipient")
- .short("r")
- .multiple(true)
- .takes_value(true)
- .value_name("LABEL")
- .number_of_values(1)
- .help("Recipient to encrypt for \
- (can be given multiple times)"))
.arg(Arg::with_name("recipients-cert-file")
.long("recipients-cert-file")
.multiple(true)
@@ -330,73 +313,7 @@ pub fn build() -> App<'static, 'static> {
.about("Sends a key")
.arg(Arg::with_name("input").value_name("FILE")
.help("Sets the input file to use"))))
- .subcommand(SubCommand::with_name("mapping")
- .display_order(30)
- .about("Interacts with key mappings")
- .setting(AppSettings::SubcommandRequiredElseHelp)
- .subcommand(SubCommand::with_name("list")
- .about("Lists keys in the mapping"))
- .subcommand(SubCommand::with_name("add")
- .about("Add a key identified by fingerprint")
- .arg(Arg::with_name("label").value_name("LABEL")
- .required(true)
- .help("Label to use"))
- .arg(Arg::with_name("fingerprint").value_name("FINGERPRINT")
- .required(true)
- .help("Key to add")))