Skip to content

Commit bfdf7cf

Browse files
committed
Find out which KeePassXC variant is used
Enables KeePassXC installed via Flatpak and Snap
1 parent 951e1e4 commit bfdf7cf

File tree

3 files changed

+104
-5
lines changed

3 files changed

+104
-5
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.keepassxc;
2+
3+
public enum KeePassXCType {
4+
Repo,
5+
AppImage,
6+
Snap,
7+
Flatpak
8+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.keepassxc;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import java.util.Optional;
7+
8+
public class KindOfKeePassXC {
9+
private static final Logger log = LoggerFactory.getLogger(KindOfKeePassXC.class);
10+
11+
static Optional<KeePassXCType> determineType() {
12+
var processHandle = ProcessHandle.allProcesses()
13+
.filter(ph -> ph.info().command().isPresent() && ph.info().command().get().contains("KeePassXC"))
14+
.findFirst();
15+
if (processHandle.isPresent() && processHandle.get().info().command().get().contains("AppImage")) {
16+
log.debug("Found running KeePassXC AppImage");
17+
return Optional.of(KeePassXCType.AppImage);
18+
}
19+
20+
processHandle = ProcessHandle.allProcesses()
21+
.filter(ph -> ph.info().commandLine().isPresent() && ph.info().commandLine().get().contains("keepassxc"))
22+
.findFirst();
23+
if (processHandle.isPresent()) {
24+
log.debug("Found running KeePassXC installed from repository");
25+
return Optional.of(KeePassXCType.Repo);
26+
}
27+
28+
processHandle = ProcessHandle.allProcesses()
29+
.filter(ph -> ph.info().command().isPresent() && ph.info().command().get().contains("keepassxc"))
30+
.findFirst();
31+
if (processHandle.isPresent() && processHandle.get().info().command().get().contains("app")) {
32+
log.debug("Found running KeePassXC installed via Flatpak");
33+
return Optional.of(KeePassXCType.Flatpak);
34+
}
35+
36+
if (processHandle.isPresent() && processHandle.get().info().command().get().contains("snap")) {
37+
log.debug("Found running KeePassXC installed via Snap");
38+
return Optional.of(KeePassXCType.Snap);
39+
}
40+
41+
log.debug("Could not find running KeePassXC application");
42+
return Optional.empty();
43+
}
44+
}

src/main/java/org/keepassxc/LinuxMacConnection.java

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.slf4j.Logger;
88
import org.slf4j.LoggerFactory;
99

10+
import java.io.File;
1011
import java.io.IOException;
1112
import java.net.UnixDomainSocketAddress;
1213
import java.nio.ByteBuffer;
@@ -22,12 +23,15 @@ public class LinuxMacConnection extends Connection {
2223

2324
private final int BUFFER_SIZE = 1024;
2425
private SocketChannel socket;
25-
private final UnixDomainSocketAddress socketAddress;
26+
private UnixDomainSocketAddress socketAddress;
2627
private final ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
2728
private final Charset charset = StandardCharsets.UTF_8;
2829
private final CharsetDecoder charsetDecoder = charset.newDecoder();
2930
private final CharBuffer charBuffer = CharBuffer.allocate(BUFFER_SIZE);
3031

32+
private static final String FLATPAK_PATH = "/app/org.keepassxc.KeePassXC";
33+
private static final String SNAP_PATH = System.getProperty("user.home") + "/snap/keepassxc/common";
34+
3135
public LinuxMacConnection() {
3236
var socketPath = getSocketPath();
3337
this.socketAddress = UnixDomainSocketAddress.of(socketPath + "/" + PROXY_NAME);
@@ -100,15 +104,30 @@ protected JSONObject getCleartextResponse() {
100104
}
101105

102106
/**
103-
* Get the os-specific directory, where runtime files and sockets are kept.
107+
* Get the os-specific and KeePassXC installation-specific directory, where runtime files and sockets are kept.
104108
*
105109
* @return The socket path.
106110
*/
107111
private String getSocketPath() {
108112
if (SystemUtils.IS_OS_LINUX) {
109-
var path = System.getenv("XDG_RUNTIME_DIR");
110-
if (null == path) path = System.getenv("TMPDIR");
111-
return (null == path) ? "/tmp" : path;
113+
var type = KindOfKeePassXC.determineType();
114+
if (type.isEmpty()) {
115+
return getXDGPath();
116+
} else {
117+
switch (type.get()) {
118+
case Repo, AppImage -> {
119+
return getXDGPath();
120+
}
121+
case Flatpak -> {
122+
log.debug("Using XDG_RUNTIME_DIR" + FLATPAK_PATH);
123+
return System.getenv("XDG_RUNTIME_DIR") + FLATPAK_PATH;
124+
}
125+
case Snap -> {
126+
log.debug("Using " + SNAP_PATH);
127+
return SNAP_PATH;
128+
}
129+
}
130+
}
112131
}
113132
if (SystemUtils.IS_OS_MAC_OSX) {
114133
return System.getenv("TMPDIR");
@@ -118,6 +137,34 @@ private String getSocketPath() {
118137
}
119138
}
120139

140+
/**
141+
* Find the XDG_RUNTIME_DIR KeePassXC is using.
142+
* When installed from a repo or run as an AppImage, it depends on the KeePassXC version, where it creates its socket:
143+
* KeePassXC <2.7.2 create it in the XDG_RUNTIME_DIR
144+
* KeePassXC 2.7.2+ create it in XDG_RUNTIME_DIR/app/org.keepassxc.KeePassXC/
145+
*
146+
* @return The correct socket path.
147+
*/
148+
private String getXDGPath() {
149+
var path = System.getenv("XDG_RUNTIME_DIR");
150+
log.debug("Checking if XDG_RUNTIME_DIR exists ...");
151+
if (null == path) {
152+
log.debug("Unable to find XDG_RUNTIME_DIR");
153+
path = System.getenv("TMPDIR");
154+
log.debug("Using TEMPDIR");
155+
return (null == path) ? "/tmp" : path;
156+
} else {
157+
var flatpakPath = new File(path + FLATPAK_PATH);
158+
if (flatpakPath.exists()) {
159+
log.debug("Using XDG_RUNTIME_DIR" + FLATPAK_PATH);
160+
return path + FLATPAK_PATH;
161+
} else {
162+
log.debug("Using XDG_RUNTIME_DIR");
163+
return path;
164+
}
165+
}
166+
}
167+
121168
@Override
122169
protected boolean isConnected() {
123170
return null != socket && socket.isOpen();

0 commit comments

Comments
 (0)