diff options
author | Jesse Luehrs <doy@tozt.net> | 2020-05-02 18:45:50 -0400 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2020-05-02 18:59:11 -0400 |
commit | f035ac5470c7fbcf791e361cb2d611de7edafb0f (patch) | |
tree | 8d75832af542bb27ca32163fbadc67758dde50cb /src | |
parent | bcf1df8dd65fb24c767ca91159fc5639dbd5375f (diff) | |
download | rbw-f035ac5470c7fbcf791e361cb2d611de7edafb0f.tar.gz rbw-f035ac5470c7fbcf791e361cb2d611de7edafb0f.zip |
check protocol version before agent communication
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/rbw-agent/actions.rs | 10 | ||||
-rw-r--r-- | src/bin/rbw-agent/agent.rs | 4 | ||||
-rw-r--r-- | src/bin/rbw/actions.rs | 18 | ||||
-rw-r--r-- | src/bin/rbw/commands.rs | 24 | ||||
-rw-r--r-- | src/protocol.rs | 4 |
5 files changed, 60 insertions, 0 deletions
diff --git a/src/bin/rbw-agent/actions.rs b/src/bin/rbw-agent/actions.rs index 8823424..52c34fa 100644 --- a/src/bin/rbw-agent/actions.rs +++ b/src/bin/rbw-agent/actions.rs @@ -256,6 +256,16 @@ pub async fn encrypt( Ok(()) } +pub async fn version(sock: &mut crate::sock::Sock) -> anyhow::Result<()> { + sock.send(&rbw::protocol::Response::Version { + version: rbw::protocol::VERSION, + }) + .await + .context("failed to send response")?; + + Ok(()) +} + async fn respond_ack(sock: &mut crate::sock::Sock) -> anyhow::Result<()> { sock.send(&rbw::protocol::Response::Ack) .await diff --git a/src/bin/rbw-agent/agent.rs b/src/bin/rbw-agent/agent.rs index 9021569..72d6077 100644 --- a/src/bin/rbw-agent/agent.rs +++ b/src/bin/rbw-agent/agent.rs @@ -156,6 +156,10 @@ async fn handle_request( true } rbw::protocol::Action::Quit => std::process::exit(0), + rbw::protocol::Action::Version => { + crate::actions::version(sock).await?; + true + } }; if set_timeout { diff --git a/src/bin/rbw/actions.rs b/src/bin/rbw/actions.rs index 273b038..399b7f3 100644 --- a/src/bin/rbw/actions.rs +++ b/src/bin/rbw/actions.rs @@ -82,6 +82,24 @@ pub fn encrypt(plaintext: &str) -> anyhow::Result<String> { } } +pub fn version() -> anyhow::Result<u32> { + let mut sock = crate::sock::Sock::connect() + .context("failed to connect to rbw-agent")?; + sock.send(&rbw::protocol::Request { + tty: std::env::var("TTY").ok(), + action: rbw::protocol::Action::Version, + })?; + + let res = sock.recv()?; + match res { + rbw::protocol::Response::Version { version } => Ok(version), + rbw::protocol::Response::Error { error } => { + Err(anyhow::anyhow!("failed to get version: {}", error)) + } + _ => Err(anyhow::anyhow!("unexpected message: {:?}", res)), + } +} + fn simple_action( action: rbw::protocol::Action, desc: &str, diff --git a/src/bin/rbw/commands.rs b/src/bin/rbw/commands.rs index 6c9d18c..b29987d 100644 --- a/src/bin/rbw/commands.rs +++ b/src/bin/rbw/commands.rs @@ -493,6 +493,30 @@ pub fn stop_agent() -> anyhow::Result<()> { } fn ensure_agent() -> anyhow::Result<()> { + ensure_agent_once()?; + let version = crate::actions::version()?; + if version != rbw::protocol::VERSION { + log::debug!( + "client protocol version is {} but agent protocol version is {}", + rbw::protocol::VERSION, + version + ); + crate::actions::quit()?; + ensure_agent_once()?; + let version = crate::actions::version()?; + if version != rbw::protocol::VERSION { + crate::actions::quit()?; + return Err(anyhow::anyhow!( + "incompatible protocol versions: client ({}), agent ({})", + rbw::protocol::VERSION, + version + )); + } + } + Ok(()) +} + +fn ensure_agent_once() -> anyhow::Result<()> { let agent_path = std::env::var("RBW_AGENT"); let agent_path = agent_path .as_ref() diff --git a/src/protocol.rs b/src/protocol.rs index de8833c..2ef99cd 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -1,3 +1,5 @@ +pub const VERSION: u32 = 1; + #[derive(serde::Serialize, serde::Deserialize, Debug)] pub struct Request { pub tty: Option<String>, @@ -14,6 +16,7 @@ pub enum Action { Decrypt { cipherstring: String }, Encrypt { plaintext: String }, Quit, + Version, } #[derive(serde::Serialize, serde::Deserialize, Debug)] @@ -23,4 +26,5 @@ pub enum Response { Error { error: String }, Decrypt { plaintext: String }, Encrypt { cipherstring: String }, + Version { version: u32 }, } |