From 36f8f9a9bd23614c7fea302b0aef3e11af75baea Mon Sep 17 00:00:00 2001 From: holly sparkles Date: Tue, 1 Aug 2023 23:12:02 +0200 Subject: [PATCH] feat: add registering keys with ssh-agent --- src/main.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4fc1059..f9517c8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ -use std::env; +use std::{env, process::{Command, Stdio}}; use gumdrop::Options; -use anyhow::Result; +use anyhow::{Result, Context}; mod util; mod bwutil; @@ -13,6 +13,13 @@ const BW_FIELD_KEY_FILENAME: &str = "private"; const BW_FIELD_KEY_PASSPHRASE: &str = "passphrase"; fn main() -> Result<()> { + // This environment variable only set when calling ssh-agent, so return the passphrase to authenticate and then quit. + let unlock_passphrase = env::var(BW_FIELD_KEY_PASSPHRASE); + if unlock_passphrase.is_ok() { + println!("{}", unlock_passphrase.unwrap()); + return Ok(()) + } + let args: util::Cli = util::Cli::parse_args_default_or_exit(); if args.version { println!("{}", &util::get_version_string()?); @@ -47,7 +54,8 @@ fn main() -> Result<()> { if let Some(attachments) = &item.attachments { for attachment in attachments { if attachment.file_name.eq(&key_filename) { - println!("{:#?}", item); + //println!("{:#?}", item); + let _key = register_key(&item.id, &attachment.id, &key_passphrase, &session_token)?; } } } @@ -98,3 +106,40 @@ fn check_session_token(args: &util::Cli) -> Result { Ok(session_token) } + +fn register_key(item_id: &str, attachment_id: &str, passphrase: &str, session_token: &str) -> Result<()> { + let bw_command = Command::new("bw") + .arg("get") + .arg("attachment") + .arg(attachment_id) + .arg("--itemid") + .arg(item_id) + .arg("--raw") + .arg("--session") + .arg(session_token) + .stdout(Stdio::piped()) + .spawn() + .with_context(|| + format!("Error running command:\n `bw get attachment {} --itemid {} --raw --session **REDACTED**`", attachment_id, item_id) + )?; + + let app_path = env::current_exe()?; + let app_path = app_path.to_string_lossy().to_string(); + + let ssh_command = Command::new("ssh-add") + .env("SSH_ASKPASS", &app_path) + .env(BW_FIELD_KEY_PASSPHRASE, passphrase) + .arg("-") + .stdin(Stdio::from(bw_command.stdout.unwrap())) // Pipe through. + .spawn() + .with_context(|| + format!("Error running command:\n `SSH_ASKPASS=\"{}\" {}=\"{}\"ssh-add -`", app_path, BW_FIELD_KEY_PASSPHRASE, passphrase) + )?; + let output = ssh_command.wait_with_output().unwrap(); + let result = String::from_utf8(output.stdout).unwrap(); + if !result.is_empty() { + println!("{:?}", result); + } + + Ok(()) +} \ No newline at end of file -- libgit2 1.7.2