Skip to content

Commit

Permalink
Merge pull request #521 from str4d/374-pipe-input-with-passphrase
Browse files Browse the repository at this point in the history
rage: Allow piping input when encrypting with passphrase on Unix
  • Loading branch information
str4d authored Aug 28, 2024
2 parents 51760e3 + a709c93 commit c5f0d61
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 4 deletions.
4 changes: 4 additions & 0 deletions rage/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ to 1.0.0 are beta releases.
### Added
- Partial French translation!

### Fixed
- [Unix] Files can now be encrypted with `rage --passphrase` when piped over
stdin, without requiring an explicit `-` argument as `INPUT`.

## [0.10.0] - 2024-02-04
### Added
- Russian translation!
Expand Down
7 changes: 6 additions & 1 deletion rage/src/bin/rage/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,18 @@ macro_rules! wlnfl {

pub(crate) enum EncryptError {
Age(age::EncryptError),
BrokenPipe { is_stdout: bool, source: io::Error },
BrokenPipe {
is_stdout: bool,
source: io::Error,
},
IdentityRead(age::cli_common::ReadError),
Io(io::Error),
MissingRecipients,
MixedIdentityAndPassphrase,
MixedRecipientAndPassphrase,
MixedRecipientsFileAndPassphrase,
PassphraseTimedOut,
#[cfg(not(unix))]
PassphraseWithoutFileArgument,
PluginNameFlag,
}
Expand Down Expand Up @@ -84,6 +88,7 @@ impl fmt::Display for EncryptError {
wfl!(f, "err-enc-mixed-recipients-file-passphrase")
}
EncryptError::PassphraseTimedOut => wfl!(f, "err-passphrase-timed-out"),
#[cfg(not(unix))]
EncryptError::PassphraseWithoutFileArgument => {
wfl!(f, "err-enc-passphrase-without-file")
}
Expand Down
10 changes: 8 additions & 2 deletions rage/src/bin/rage/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ fn encrypt(opts: AgeOptions) -> Result<(), error::EncryptError> {
(Format::Binary, file_io::OutputFormat::Binary)
};

#[cfg(not(unix))]
let has_file_argument = opts.input.is_some();

let (input, output) = set_up_io(opts.input, opts.output, output_format)?;
Expand All @@ -134,8 +135,13 @@ fn encrypt(opts: AgeOptions) -> Result<(), error::EncryptError> {
return Err(error::EncryptError::MixedRecipientsFileAndPassphrase);
}

if !has_file_argument {
return Err(error::EncryptError::PassphraseWithoutFileArgument);
// The `rpassword` crate opens `/dev/tty` directly on Unix, so we don't have
// any conflict with stdin.
#[cfg(not(unix))]
{
if !has_file_argument {
return Err(error::EncryptError::PassphraseWithoutFileArgument);
}
}

match read_or_generate_passphrase() {
Expand Down
10 changes: 9 additions & 1 deletion rage/tests/cli_tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
#[test]
fn cli_tests() {
trycmd::TestCases::new().case("tests/cmd/*/*.toml");
let tests = trycmd::TestCases::new();

tests.case("tests/cmd/*/*.toml");

#[cfg(unix)]
tests.case("tests/unix/*/*.toml");

#[cfg(not(unix))]
tests.case("tests/windows/*/*.toml");
}
16 changes: 16 additions & 0 deletions rage/tests/unix/rage/encrypt-passphrase-without-file-argument.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
bin.name = "rage"
args = "-p"
status = "failed"
stdin = ""
stdout = ""
stderr = """
Error: Parsing Error: Error { input: "", code: Tag }
[ Did rage not do what you expected? Could an error be more useful? ]
[ Tell us: https://str4d.xyz/rage/report ]
"""

# We get an error from the `pinentry` crate because we've passed a real but invalid binary
# that does not speak the pinentry protocol.
[env.add]
PINENTRY_PROGRAM = "true"

0 comments on commit c5f0d61

Please sign in to comment.