mirror of
https://github.com/str4d/rage.git
synced 2025-04-04 19:37:51 +03:00
Merge pull request #446 from str4d/167-blast-furnace
age: Wrap connections in a blast furnace
This commit is contained in:
commit
71484d7fd2
2 changed files with 70 additions and 7 deletions
|
@ -59,6 +59,11 @@ rec-missing-plugin = Have you installed the plugin?
|
||||||
|
|
||||||
err-plugin-identity = '{$plugin_name}' couldn't use an identity: {$message}
|
err-plugin-identity = '{$plugin_name}' couldn't use an identity: {$message}
|
||||||
err-plugin-recipient = '{$plugin_name}' couldn't use recipient {$recipient}: {$message}
|
err-plugin-recipient = '{$plugin_name}' couldn't use recipient {$recipient}: {$message}
|
||||||
|
|
||||||
|
err-plugin-died = '{$plugin_name}' unexpectedly died.
|
||||||
|
rec-plugin-died-1 = If you are developing a plugin, run with {$env_var} for more information.
|
||||||
|
rec-plugin-died-2 = Warning: this prints private encryption key material to standard error.
|
||||||
|
|
||||||
err-plugin-multiple = Plugin returned multiple errors:
|
err-plugin-multiple = Plugin returned multiple errors:
|
||||||
|
|
||||||
err-read-identity-encrypted-without-passphrase =
|
err-read-identity-encrypted-without-passphrase =
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use age_core::{
|
use age_core::{
|
||||||
format::{FileKey, Stanza},
|
format::{FileKey, Stanza},
|
||||||
io::{DebugReader, DebugWriter},
|
io::{DebugReader, DebugWriter},
|
||||||
plugin::{Connection, Reply, Response, IDENTITY_V1, RECIPIENT_V1},
|
plugin::{Connection, Reply, Response, UnidirSend, IDENTITY_V1, RECIPIENT_V1},
|
||||||
secrecy::ExposeSecret,
|
secrecy::ExposeSecret,
|
||||||
};
|
};
|
||||||
use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine};
|
use base64::{prelude::BASE64_STANDARD_NO_PAD, Engine};
|
||||||
|
@ -23,7 +23,7 @@ use crate::{
|
||||||
error::{DecryptError, EncryptError, PluginError},
|
error::{DecryptError, EncryptError, PluginError},
|
||||||
fl,
|
fl,
|
||||||
util::parse_bech32,
|
util::parse_bech32,
|
||||||
Callbacks,
|
wfl, wlnfl, Callbacks,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Plugin HRPs are age1[name] and AGE-PLUGIN-[NAME]-
|
// Plugin HRPs are age1[name] and AGE-PLUGIN-[NAME]-
|
||||||
|
@ -214,14 +214,72 @@ impl Plugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connect(
|
fn connect(&self, state_machine: &str) -> io::Result<BlastFurnace> {
|
||||||
&self,
|
let conn = Connection::open(&self.path, state_machine)?;
|
||||||
state_machine: &str,
|
Ok(BlastFurnace {
|
||||||
) -> io::Result<Connection<DebugReader<ChildStdout>, DebugWriter<ChildStdin>>> {
|
binary_name: self.binary_name.clone(),
|
||||||
Connection::open(&self.path, state_machine)
|
conn,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Wraps a connection and gracefully handles plugin explosions.
|
||||||
|
struct BlastFurnace {
|
||||||
|
binary_name: String,
|
||||||
|
conn: Connection<DebugReader<ChildStdout>, DebugWriter<ChildStdin>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlastFurnace {
|
||||||
|
fn handle_errors(&self, res: io::Result<()>) -> io::Result<()> {
|
||||||
|
res.map_err(|e| match e.kind() {
|
||||||
|
io::ErrorKind::UnexpectedEof => io::Error::new(
|
||||||
|
io::ErrorKind::ConnectionAborted,
|
||||||
|
PluginDiedError {
|
||||||
|
binary_name: self.binary_name.clone(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
_ => e,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unidir_send<
|
||||||
|
P: FnOnce(UnidirSend<DebugReader<ChildStdout>, DebugWriter<ChildStdin>>) -> io::Result<()>,
|
||||||
|
>(
|
||||||
|
&mut self,
|
||||||
|
phase_steps: P,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
let res = self.conn.unidir_send(phase_steps);
|
||||||
|
self.handle_errors(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bidir_receive<H>(&mut self, commands: &[&str], handler: H) -> io::Result<()>
|
||||||
|
where
|
||||||
|
H: FnMut(Stanza, Reply<DebugReader<ChildStdout>, DebugWriter<ChildStdin>>) -> Response,
|
||||||
|
{
|
||||||
|
let res = self.conn.bidir_receive(commands, handler);
|
||||||
|
self.handle_errors(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct PluginDiedError {
|
||||||
|
binary_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for PluginDiedError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
wlnfl!(
|
||||||
|
f,
|
||||||
|
"err-plugin-died",
|
||||||
|
plugin_name = self.binary_name.as_str(),
|
||||||
|
)?;
|
||||||
|
wlnfl!(f, "rec-plugin-died-1", env_var = "AGEDEBUG=plugin")?;
|
||||||
|
wfl!(f, "rec-plugin-died-2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for PluginDiedError {}
|
||||||
|
|
||||||
fn handle_confirm<R: io::Read, W: io::Write, C: Callbacks>(
|
fn handle_confirm<R: io::Read, W: io::Write, C: Callbacks>(
|
||||||
command: Stanza,
|
command: Stanza,
|
||||||
reply: Reply<R, W>,
|
reply: Reply<R, W>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue