Skip to content

Commit

Permalink
Add support for sandboxed socket path
Browse files Browse the repository at this point in the history
Rather than try a single path, try all supported paths, in the preferred
order. This avoids breaking compatibility with previous KeePassXC
versions.

See: keepassxreboot/keepassxc#8018
Fixes: varjolintu#8
Supercedes: varjolintu#7
  • Loading branch information
Hugo Osvaldo Barrera committed Jun 2, 2022
1 parent dda48b6 commit a3b7d20
Showing 1 changed file with 35 additions and 6 deletions.
41 changes: 35 additions & 6 deletions src/proxy_socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::io::{self, Read, Write};
#[cfg(not(windows))]
use std::os::unix::io::AsRawFd;
use std::os::unix::net::UnixStream;
use std::path::PathBuf;
use nix::sys::socket;
use nix::sys::socket::sockopt::SndBuf;
use nix::sys::socket::sockopt::RcvBuf;
Expand Down Expand Up @@ -39,17 +40,45 @@ pub fn connect(buffer_size: usize) -> io::Result<ProxySocket<PipeClient>> {
Ok(ProxySocket { inner: client })
}

#[cfg(not(windows))]
/// Returns the directories where the socket could possible be located.
///
/// These directories should be tried in sequence, until one of them is found
/// to contain the socket.
fn get_socket_dirs() -> Vec<PathBuf> {
let mut dirs = Vec::new();

if !cfg!(target_os = "macos") {
if let Ok(dir) = env::var("XDG_RUNTIME_DIR") {
let xdg_runtime_dir: PathBuf = dir.into();

// Sandbox-friendly path.
// Used in KeePassXC >= 2.7.2 and for all versions on Flatpak.
dirs.push(xdg_runtime_dir.join("app/org.keepassxc.KeePassXC/"));

// Legacy path.
// Used by KeePassXC < 2.7.2.
dirs.push(xdg_runtime_dir);
};
};

// Default for macOS, and final fallback for Linux.
dirs.push(env::temp_dir());

dirs
}

#[cfg(not(windows))]
pub fn connect(buffer_size: usize) -> io::Result<ProxySocket<UnixStream>> {
use std::time::Duration;

let socket_name = "org.keepassxc.KeePassXC.BrowserServer";
let socket = if let Ok(dir) = if cfg!(target_os = "macos") {env::var("TMPDIR") } else { env::var("XDG_RUNTIME_DIR") } {
format!("{}/{}", dir, socket_name)
} else {
format!("/tmp/{}", socket_name)
};
let s = UnixStream::connect(socket)?;
let dirs = get_socket_dirs();
let s = dirs
.iter()
.find_map(|dir| UnixStream::connect(dir.join(socket_name)).ok())
.ok_or_else(|| io::Error::from(io::ErrorKind::NotFound))?;

socket::setsockopt(s.as_raw_fd(), SndBuf, &buffer_size).expect("setsockopt for SndBuf failed");
socket::setsockopt(s.as_raw_fd(), RcvBuf, &buffer_size).expect("setsockopt for RcvBuf failed");
let timeout: Option<Duration> = Some(Duration::from_secs(1));
Expand Down

0 comments on commit a3b7d20

Please sign in to comment.