Skip to content

Commit

Permalink
feat: support gpg-agent extra socket
Browse files Browse the repository at this point in the history
  • Loading branch information
nomeaning777 committed Nov 16, 2023
1 parent b2ca868 commit 40fe606
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 10 deletions.
12 changes: 12 additions & 0 deletions client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,20 @@ fn default_gpg_agent_sock() -> String {
.to_owned()
}

fn default_gpg_agent_extra_sock() -> String {
dirs::runtime_dir()
.unwrap()
.join("gnupg/S.gpg-agent.extra")
.to_str()
.unwrap()
.to_owned()
}

#[derive(Serialize, Deserialize, Debug)]
pub struct GpgAgentConfig {
#[serde(default = "default_gpg_agent_sock")]
pub gpg_agent_sock: String,

#[serde(default = "default_gpg_agent_extra_sock")]
pub gpg_agent_extra_sock: String,
}
40 changes: 32 additions & 8 deletions client/src/gpg_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,18 @@ use std::path::Path;
use tokio::io::AsyncWriteExt;
use tokio::net::{UnixListener, UnixStream};

async fn handle_stream(mut stream: UnixStream) -> std::io::Result<()> {
enum SocketType {
Default,
Extra,
}

async fn handle_stream(mut stream: UnixStream, socket_type: SocketType) -> std::io::Result<()> {
let mut server = VmSocket::connect(CONFIG.service_port).await?;
server.write_all(b"gpga").await?;
match socket_type {
SocketType::Default => server.write_all(b"0").await?,
SocketType::Extra => server.write_all(b"1").await?,
}

let (client_r, client_w) = stream.split();
let (server_r, server_w) = server.split();
Expand All @@ -23,18 +32,33 @@ async fn handle_stream(mut stream: UnixStream) -> std::io::Result<()> {
pub async fn gpg_agent_forward(config: &'static GpgAgentConfig) -> std::io::Result<()> {
// Remove existing socket
let _ = std::fs::create_dir_all(Path::new(&config.gpg_agent_sock).parent().unwrap());
let _ = std::fs::create_dir_all(Path::new(&config.gpg_agent_extra_sock).parent().unwrap());
let _ = std::fs::remove_file(&config.gpg_agent_sock);
let _ = std::fs::remove_file(&config.gpg_agent_extra_sock);

let listener = UnixListener::bind(&config.gpg_agent_sock)?;
let default_listener = UnixListener::bind(&config.gpg_agent_sock)?;
let extra_listener = UnixListener::bind(&config.gpg_agent_extra_sock)?;
let _ = std::fs::set_permissions(&config.gpg_agent_sock, Permissions::from_mode(0o600));
let _ = std::fs::set_permissions(&config.gpg_agent_extra_sock, Permissions::from_mode(0o600));

loop {
let stream = listener.accept().await?.0;

tokio::task::spawn(async move {
if let Err(err) = handle_stream(stream).await {
eprintln!("Failed to transfer: {}", err);
tokio::select! {
stream = default_listener.accept() => {
let stream = stream?.0;
tokio::task::spawn(async move {
if let Err(err) = handle_stream(stream, SocketType::Default).await {
eprintln!("Failed to transfer: {}", err);
}
});
}
stream = extra_listener.accept() => {
let stream = stream?.0;
tokio::task::spawn(async move {
if let Err(err) = handle_stream(stream, SocketType::Extra).await {
eprintln!("Failed to transfer: {}", err);
}
});
}
});
}
}
}
20 changes: 18 additions & 2 deletions server/src/gpg_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,30 @@ use super::util::{connect_stream, either};

use anyhow::{anyhow, Context as _, Result};
use tokio::fs::read;
use tokio::io::AsyncWriteExt;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpStream;
use tokio::process::Command;

enum SocketType {
Default,
Extra,
}
pub async fn handle_gpg_agent(mut stream: TcpStream) -> Result<()> {
let mut socket_type = [0u8; 1];
stream.read_exact(&socket_type).await?;

let socket_type = match socket_type[0] {
b'0' => SocketType::Default,
b'1' => SocketType::Extra,
_ => return Err(anyhow!("invalid socket type")),
};

let gpg_conf = Command::new("gpgconf.exe")
.arg("--list-dir")
.arg("agent-socket")
.arg(match socket_type {
SocketType::Default => "agent-socket",
SocketType::Extra => "agent-extra-socket",
})
.stdout(Stdio::piped())
.spawn()?;
let output = gpg_conf.wait_with_output().await?;
Expand Down

0 comments on commit 40fe606

Please sign in to comment.