opgpcard: Allow sign and decrypt to write to file

- Sometimes, it is more convenient to give the target filename as an
    argument, instead of using pipes.

  - Add an optional argument -o/--output to opgpcard sign and opgpcard
    decrypt.
This commit is contained in:
Nora Widdecke 2022-10-27 21:10:29 +02:00
parent 678cc30455
commit b489c7da4d
No known key found for this signature in database
GPG key ID: 2D4111B31DBB99B6
2 changed files with 20 additions and 3 deletions

View file

@ -36,6 +36,10 @@ pub struct DecryptCommand {
/// Input file (stdin if unset) /// Input file (stdin if unset)
#[clap(name = "input")] #[clap(name = "input")]
input: Option<PathBuf>, input: Option<PathBuf>,
/// Output file (stdout if unset)
#[clap(name = "output", long = "output", short = 'o')]
pub output: Option<PathBuf>,
} }
pub fn decrypt(command: DecryptCommand) -> Result<(), Box<dyn std::error::Error>> { pub fn decrypt(command: DecryptCommand) -> Result<(), Box<dyn std::error::Error>> {
@ -59,7 +63,8 @@ pub fn decrypt(command: DecryptCommand) -> Result<(), Box<dyn std::error::Error>
let db = DecryptorBuilder::from_reader(input)?; let db = DecryptorBuilder::from_reader(input)?;
let mut decryptor = db.with_policy(&p, None, d)?; let mut decryptor = db.with_policy(&p, None, d)?;
std::io::copy(&mut decryptor, &mut std::io::stdout())?; let mut sink = util::open_or_stdout(command.output.as_deref())?;
std::io::copy(&mut decryptor, &mut sink)?;
Ok(()) Ok(())
} }

View file

@ -41,11 +41,20 @@ pub struct SignCommand {
/// Input file (stdin if unset) /// Input file (stdin if unset)
#[clap(name = "input")] #[clap(name = "input")]
pub input: Option<PathBuf>, pub input: Option<PathBuf>,
/// Output file (stdout if unset)
#[clap(name = "output", long = "output", short = 'o')]
pub output: Option<PathBuf>,
} }
pub fn sign(command: SignCommand) -> Result<(), Box<dyn std::error::Error>> { pub fn sign(command: SignCommand) -> Result<(), Box<dyn std::error::Error>> {
if command.detached { if command.detached {
sign_detached(&command.ident, command.user_pin, command.input.as_deref()) sign_detached(
&command.ident,
command.user_pin,
command.input.as_deref(),
command.output.as_deref(),
)
} else { } else {
Err(anyhow::anyhow!("Only detached signatures are supported for now").into()) Err(anyhow::anyhow!("Only detached signatures are supported for now").into())
} }
@ -55,6 +64,7 @@ pub fn sign_detached(
ident: &str, ident: &str,
pin_file: Option<PathBuf>, pin_file: Option<PathBuf>,
input: Option<&Path>, input: Option<&Path>,
output: Option<&Path>,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
let mut input = util::open_or_stdin(input)?; let mut input = util::open_or_stdin(input)?;
@ -71,7 +81,9 @@ pub fn sign_detached(
let mut sign = util::verify_to_sign(&mut card, user_pin.as_deref())?; let mut sign = util::verify_to_sign(&mut card, user_pin.as_deref())?;
let s = sign.signer(&|| println!("Touch confirmation needed for signing"))?; let s = sign.signer(&|| println!("Touch confirmation needed for signing"))?;
let message = Armorer::new(Message::new(std::io::stdout())).build()?; let sink = util::open_or_stdout(output)?;
let message = Armorer::new(Message::new(sink)).build()?;
let mut signer = Signer::new(message, s).detached().build()?; let mut signer = Signer::new(message, s).detached().build()?;
std::io::copy(&mut input, &mut signer)?; std::io::copy(&mut input, &mut signer)?;