Add support for sandboxed socket path
Rather than try a single path, try all supported paths, in the preferred order. This avoids breaking compatibility with previous KeePassXC versions. See: https://github.com/keepassxreboot/keepassxc/issues/8018 Fixes: https://github.com/varjolintu/keepassxc-proxy-rust/issues/8 Supercedes: https://github.com/varjolintu/keepassxc-proxy-rust/pull/7
This commit is contained in:
+35
-6
@@ -4,6 +4,7 @@ use std::io::{self, Read, Write};
|
|||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
|
use std::path::PathBuf;
|
||||||
use nix::sys::socket;
|
use nix::sys::socket;
|
||||||
use nix::sys::socket::sockopt::SndBuf;
|
use nix::sys::socket::sockopt::SndBuf;
|
||||||
use nix::sys::socket::sockopt::RcvBuf;
|
use nix::sys::socket::sockopt::RcvBuf;
|
||||||
@@ -39,17 +40,45 @@ pub fn connect(buffer_size: usize) -> io::Result<ProxySocket<PipeClient>> {
|
|||||||
Ok(ProxySocket { inner: client })
|
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))]
|
#[cfg(not(windows))]
|
||||||
pub fn connect(buffer_size: usize) -> io::Result<ProxySocket<UnixStream>> {
|
pub fn connect(buffer_size: usize) -> io::Result<ProxySocket<UnixStream>> {
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
let socket_name = "org.keepassxc.KeePassXC.BrowserServer";
|
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") } {
|
let dirs = get_socket_dirs();
|
||||||
format!("{}/{}", dir, socket_name)
|
let s = dirs
|
||||||
} else {
|
.iter()
|
||||||
format!("/tmp/{}", socket_name)
|
.find_map(|dir| UnixStream::connect(dir.join(socket_name)).ok())
|
||||||
};
|
.ok_or_else(|| io::Error::from(io::ErrorKind::NotFound))?;
|
||||||
let s = UnixStream::connect(socket)?;
|
|
||||||
socket::setsockopt(s.as_raw_fd(), SndBuf, &buffer_size).expect("setsockopt for SndBuf failed");
|
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");
|
socket::setsockopt(s.as_raw_fd(), RcvBuf, &buffer_size).expect("setsockopt for RcvBuf failed");
|
||||||
let timeout: Option<Duration> = Some(Duration::from_secs(1));
|
let timeout: Option<Duration> = Some(Duration::from_secs(1));
|
||||||
|
|||||||
Reference in New Issue
Block a user