77import org .slf4j .Logger ;
88import org .slf4j .LoggerFactory ;
99
10+ import java .io .File ;
1011import java .io .IOException ;
1112import java .net .UnixDomainSocketAddress ;
1213import 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