Align sq download with sq verify.

This commit is contained in:
Justus Winter 2024-12-16 15:19:05 +01:00
parent 58a88499ea
commit 792bf62aec
No known key found for this signature in database
GPG Key ID: 686F55B4AB2B3386
4 changed files with 36 additions and 8 deletions

4
NEWS
View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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 {