Change network getters to update the certificate store by default
- Change the network getters, `sq keyserver get`, `sq wkd get`, and `sq dane get` to update the certificate store by default.
This commit is contained in:
parent
62493558c5
commit
ba35945574
4
NEWS
4
NEWS
@ -58,6 +58,10 @@
|
||||
certificate.
|
||||
- `sq wot list` to list authenticated bindings.
|
||||
- `sq wot path` to authenticate and lint a path in a web of trust.
|
||||
- `sq keyserver get`, `sq wkd get`, and `sq dane get` now import any
|
||||
certificates into the certificate store by default instead of
|
||||
exporting them on stdout. It is still possible to export them
|
||||
using the `--output` option.
|
||||
* Deprecated functionality
|
||||
- `sq key generate --creation-time TIME` is deprecated in favor of
|
||||
`sq key generate --time TIME`.
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Network services.
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use anyhow::Context;
|
||||
|
||||
use sequoia_openpgp as openpgp;
|
||||
@ -23,6 +25,9 @@ use net::{
|
||||
dane,
|
||||
};
|
||||
|
||||
use sequoia_cert_store as cert_store;
|
||||
use cert_store::StoreUpdate;
|
||||
|
||||
use crate::{
|
||||
Config,
|
||||
Model,
|
||||
@ -33,7 +38,33 @@ use crate::{
|
||||
|
||||
use crate::sq_cli;
|
||||
|
||||
pub fn dispatch_keyserver(config: Config, c: sq_cli::keyserver::Command) -> Result<()> {
|
||||
// Import the certificates into the local certificate store.
|
||||
//
|
||||
// This does not certify the certificates.
|
||||
fn import_certs(config: &mut Config, certs: Vec<Cert>) -> Result<()> {
|
||||
let cert_store = config.cert_store_mut_or_else()
|
||||
.context("Inserting results")?;
|
||||
|
||||
let mut stats
|
||||
= cert_store::store::MergePublicCollectStats::new();
|
||||
for cert in certs.into_iter() {
|
||||
cert_store.update_by(Cow::Owned(cert.into()), &mut stats)
|
||||
.context("Inserting results")?;
|
||||
}
|
||||
|
||||
eprintln!("Imported {} new certificates, \
|
||||
updated {} certificates, \
|
||||
{} certificates unchanged, \
|
||||
{} errors.",
|
||||
stats.new, stats.updated, stats.unchanged,
|
||||
stats.errors);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn dispatch_keyserver(mut config: Config, c: sq_cli::keyserver::Command)
|
||||
-> Result<()>
|
||||
{
|
||||
let network_policy = c.network_policy.into();
|
||||
let mut ks = KeyServer::new(network_policy, &c.server)
|
||||
.context("Malformed keyserver URI")?;
|
||||
@ -54,20 +85,28 @@ pub fn dispatch_keyserver(config: Config, c: sq_cli::keyserver::Command) -> Resu
|
||||
let cert = rt.block_on(ks.get(handle))
|
||||
.context("Failed to retrieve cert")?;
|
||||
|
||||
if let Some(output) = c.output {
|
||||
let mut output =
|
||||
config.create_or_stdout_safe(c.output.as_deref())?;
|
||||
config.create_or_stdout_safe(Some(&output))?;
|
||||
if !c.binary {
|
||||
cert.armored().serialize(&mut output)
|
||||
} else {
|
||||
cert.serialize(&mut output)
|
||||
}.context("Failed to serialize cert")?;
|
||||
} else {
|
||||
import_certs(&mut config, vec![ cert ])?;
|
||||
}
|
||||
} else if let Ok(Some(addr)) = UserID::from(query.as_str()).email() {
|
||||
let certs = rt.block_on(ks.search(addr))
|
||||
.context("Failed to retrieve certs")?;
|
||||
|
||||
if let Some(output) = c.output {
|
||||
let mut output =
|
||||
config.create_or_stdout_safe(c.output.as_deref())?;
|
||||
config.create_or_stdout_safe(Some(&output))?;
|
||||
serialize_keyring(&mut output, &certs, c.binary)?;
|
||||
} else {
|
||||
import_certs(&mut config, certs)?;
|
||||
}
|
||||
} else {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Query must be a fingerprint, a keyid, \
|
||||
@ -87,7 +126,7 @@ pub fn dispatch_keyserver(config: Config, c: sq_cli::keyserver::Command) -> Resu
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn dispatch_wkd(config: Config, c: sq_cli::wkd::Command) -> Result<()> {
|
||||
pub fn dispatch_wkd(mut config: Config, c: sq_cli::wkd::Command) -> Result<()> {
|
||||
let network_policy: net::Policy = c.network_policy.into();
|
||||
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
@ -131,9 +170,13 @@ pub fn dispatch_wkd(config: Config, c: sq_cli::wkd::Command) -> Result<()> {
|
||||
// ```
|
||||
// But to keep the parallelism with `store export` and `keyserver get`,
|
||||
// The output is armored if not `--binary` option is given.
|
||||
if let Some(output) = c.output {
|
||||
let mut output =
|
||||
config.create_or_stdout_safe(c.output.as_deref())?;
|
||||
config.create_or_stdout_safe(Some(&output))?;
|
||||
serialize_keyring(&mut output, &certs, c.binary)?;
|
||||
} else {
|
||||
import_certs(&mut config, certs)?;
|
||||
}
|
||||
},
|
||||
Generate(c) => {
|
||||
let domain = c.domain;
|
||||
@ -172,7 +215,7 @@ pub fn dispatch_wkd(config: Config, c: sq_cli::wkd::Command) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn dispatch_dane(config: Config, c: sq_cli::dane::Command) -> Result<()> {
|
||||
pub fn dispatch_dane(mut config: Config, c: sq_cli::dane::Command) -> Result<()> {
|
||||
let network_policy: net::Policy = c.network_policy.into();
|
||||
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
@ -193,9 +236,13 @@ pub fn dispatch_dane(config: Config, c: sq_cli::dane::Command) -> Result<()> {
|
||||
// Because it might be created a WkdServer struct, not
|
||||
// doing it for now.
|
||||
let certs = rt.block_on(dane::get(&email_address))?;
|
||||
if let Some(output) = c.output {
|
||||
let mut output =
|
||||
config.create_or_stdout_safe(c.output.as_deref())?;
|
||||
config.create_or_stdout_safe(Some(&output))?;
|
||||
serialize_keyring(&mut output, &certs, c.binary)?;
|
||||
} else {
|
||||
import_certs(&mut config, certs)?;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ pub struct GetCommand {
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
help = "Writes to FILE instead of importing into the certificate store"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ pub struct GetCommand {
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
help = "Writes to FILE instead of importing into the certificate store"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
#[clap(
|
||||
|
@ -75,7 +75,7 @@ pub struct GetCommand {
|
||||
short,
|
||||
long,
|
||||
value_name = "FILE",
|
||||
help = "Writes to FILE or stdout if omitted"
|
||||
help = "Writes to FILE instead of importing into the certificate store"
|
||||
)]
|
||||
pub output: Option<String>,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user