Align sq download
with sq verify
.
This commit is contained in:
parent
58a88499ea
commit
792bf62aec
4
NEWS
4
NEWS
@ -65,6 +65,10 @@
|
|||||||
has its desired name. There are two benefits: no one sees
|
has its desired name. There are two benefits: no one sees
|
||||||
partially written files, and one can safely use the same file as
|
partially written files, and one can safely use the same file as
|
||||||
input and output.
|
input and output.
|
||||||
|
- `sq download --signature` is now called `sq download
|
||||||
|
--signature-url`.
|
||||||
|
- `sq download` now requires one of `--signature-url`, `--message`,
|
||||||
|
or `--cleartext` like `sq verify`.
|
||||||
|
|
||||||
* Changes in 0.41.0
|
* Changes in 0.41.0
|
||||||
** New functionality
|
** New functionality
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Command-line parser for `sq download`.
|
//! Command-line parser for `sq download`.
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::{ArgGroup, Parser};
|
||||||
|
|
||||||
use crate::cli::examples;
|
use crate::cli::examples;
|
||||||
use examples::Action;
|
use examples::Action;
|
||||||
@ -21,7 +21,7 @@ const EXAMPLES: Actions = Actions {
|
|||||||
).command(&[
|
).command(&[
|
||||||
"sq", "download",
|
"sq", "download",
|
||||||
"--url=file://debian/SHA512SUMS",
|
"--url=file://debian/SHA512SUMS",
|
||||||
"--signature=file://debian/SHA512SUMS.sign",
|
"--signature-url=file://debian/SHA512SUMS.sign",
|
||||||
"--signer=DF9B9C49EAA9298432589D76DA87E80D6294BE9B",
|
"--signer=DF9B9C49EAA9298432589D76DA87E80D6294BE9B",
|
||||||
"--output=SHA512SUMS",
|
"--output=SHA512SUMS",
|
||||||
]).build(),
|
]).build(),
|
||||||
@ -42,6 +42,8 @@ authenticated, the data is deleted, if possible.
|
|||||||
",
|
",
|
||||||
after_help = EXAMPLES,
|
after_help = EXAMPLES,
|
||||||
)]
|
)]
|
||||||
|
#[clap(group(ArgGroup::new("kind")
|
||||||
|
.args(&["detached", "message", "cleartext"]).required(true)))]
|
||||||
pub struct Command {
|
pub struct Command {
|
||||||
#[clap(
|
#[clap(
|
||||||
long = "url",
|
long = "url",
|
||||||
@ -51,7 +53,7 @@ pub struct Command {
|
|||||||
pub url: String,
|
pub url: String,
|
||||||
|
|
||||||
#[clap(
|
#[clap(
|
||||||
long = "signature",
|
long = "signature-url",
|
||||||
value_name = "URL",
|
value_name = "URL",
|
||||||
help = "URL of the signature",
|
help = "URL of the signature",
|
||||||
long_help = "\
|
long_help = "\
|
||||||
@ -63,7 +65,21 @@ If no signature is specified, then the signature is assumed to be \
|
|||||||
inline.
|
inline.
|
||||||
",
|
",
|
||||||
)]
|
)]
|
||||||
pub signature: Option<String>,
|
pub detached: Option<String>,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
long = "message",
|
||||||
|
value_name = "SIG",
|
||||||
|
help = "Verify an inline signed message"
|
||||||
|
)]
|
||||||
|
pub message: bool,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
long = "cleartext",
|
||||||
|
value_name = "SIG",
|
||||||
|
help = "Verify a cleartext-signed message"
|
||||||
|
)]
|
||||||
|
pub cleartext: bool,
|
||||||
|
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
pub signers: CertDesignators<FileCertUserIDEmailDomainArgs,
|
pub signers: CertDesignators<FileCertUserIDEmailDomainArgs,
|
||||||
|
@ -174,7 +174,7 @@ pub fn dispatch(sq: Sq, c: download::Command)
|
|||||||
-> Result<()>
|
-> Result<()>
|
||||||
{
|
{
|
||||||
let url = c.url;
|
let url = c.url;
|
||||||
let signature = c.signature;
|
let signature_url = c.detached;
|
||||||
let signatures = c.signatures;
|
let signatures = c.signatures;
|
||||||
let signers =
|
let signers =
|
||||||
sq.resolve_certs_or_fail(&c.signers, sequoia_wot::FULLY_TRUSTED)?;
|
sq.resolve_certs_or_fail(&c.signers, sequoia_wot::FULLY_TRUSTED)?;
|
||||||
@ -285,9 +285,10 @@ pub fn dispatch(sq: Sq, c: download::Command)
|
|||||||
// than 'static. Instead, we set up a scoped thread, which can
|
// than 'static. Instead, we set up a scoped thread, which can
|
||||||
// use variables with lifetimes less than static, and then do the
|
// use variables with lifetimes less than static, and then do the
|
||||||
// processing there.
|
// processing there.
|
||||||
|
let signature_url_ = signature_url.clone();
|
||||||
let (mut data_file, signature_file) = std::thread::scope(|scope| {
|
let (mut data_file, signature_file) = std::thread::scope(|scope| {
|
||||||
// Schedule the download of the signature.
|
// Schedule the download of the signature.
|
||||||
if let Some(ref url) = signature {
|
if let Some(ref url) = signature_url_ {
|
||||||
let sig_file = tempfile::NamedTempFile::new()?;
|
let sig_file = tempfile::NamedTempFile::new()?;
|
||||||
|
|
||||||
let getter = get!(
|
let getter = get!(
|
||||||
@ -508,7 +509,7 @@ pub fn dispatch(sq: Sq, c: download::Command)
|
|||||||
"Internal error while downloading data file"));
|
"Internal error while downloading data file"));
|
||||||
};
|
};
|
||||||
|
|
||||||
if signature.is_some() && signature_file.is_none() {
|
if signature_url_.is_some() && signature_file.is_none() {
|
||||||
return Err(anyhow::anyhow!(
|
return Err(anyhow::anyhow!(
|
||||||
"Internal error while downloading signature file"));
|
"Internal error while downloading signature file"));
|
||||||
}
|
}
|
||||||
@ -533,6 +534,8 @@ pub fn dispatch(sq: Sq, c: download::Command)
|
|||||||
data_file.as_ref().try_clone()?, data_file.path(),
|
data_file.as_ref().try_clone()?, data_file.path(),
|
||||||
Default::default())?.into_boxed(),
|
Default::default())?.into_boxed(),
|
||||||
signature_file.as_ref().map(|f| f.path().to_path_buf()),
|
signature_file.as_ref().map(|f| f.path().to_path_buf()),
|
||||||
|
"--signature-url",
|
||||||
|
signature_url.map(PathBuf::from),
|
||||||
&mut output_file,
|
&mut output_file,
|
||||||
signatures,
|
signatures,
|
||||||
signers);
|
signers);
|
||||||
|
@ -42,6 +42,8 @@ pub fn dispatch(sq: Sq, command: cli::verify::Command)
|
|||||||
sq.resolve_certs_or_fail(&command.signers, sequoia_wot::FULLY_TRUSTED)?;
|
sq.resolve_certs_or_fail(&command.signers, sequoia_wot::FULLY_TRUSTED)?;
|
||||||
|
|
||||||
let result = verify(sq, input,
|
let result = verify(sq, input,
|
||||||
|
command.detached.clone(),
|
||||||
|
"--signature-file",
|
||||||
command.detached,
|
command.detached,
|
||||||
&mut output, signatures, signers);
|
&mut output, signatures, signers);
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
@ -63,6 +65,8 @@ pub fn dispatch(sq: Sq, command: cli::verify::Command)
|
|||||||
pub fn verify(mut sq: Sq,
|
pub fn verify(mut sq: Sq,
|
||||||
input: Box<dyn BufferedReader<Cookie>>,
|
input: Box<dyn BufferedReader<Cookie>>,
|
||||||
detached: Option<PathBuf>,
|
detached: Option<PathBuf>,
|
||||||
|
detached_sig_arg: &str,
|
||||||
|
detached_sig_value: Option<PathBuf>,
|
||||||
output: &mut dyn io::Write,
|
output: &mut dyn io::Write,
|
||||||
signatures: usize, certs: Vec<Cert>)
|
signatures: usize, certs: Vec<Cert>)
|
||||||
-> Result<()> {
|
-> Result<()> {
|
||||||
@ -71,7 +75,8 @@ pub fn verify(mut sq: Sq,
|
|||||||
|
|
||||||
let (kind, sig) = Kind::identify(&mut sq, sig)?;
|
let (kind, sig) = Kind::identify(&mut sq, sig)?;
|
||||||
kind.expect_or_else(&sq, "verify", Kind::DetachedSig,
|
kind.expect_or_else(&sq, "verify", Kind::DetachedSig,
|
||||||
"--signature-file", Some(&sig_path))?;
|
detached_sig_arg,
|
||||||
|
detached_sig_value.as_deref())?;
|
||||||
|
|
||||||
Some(sig)
|
Some(sig)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user