From 742d2416d7842c7d402543c11080cd202e086c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20Bene=C5=A1?= Date: Fri, 17 Jul 2026 19:00:27 +0200 Subject: [PATCH] Fix: store KWallet passwords via D-Bus (kwallet-query -w never persists) kwallet-query --write-password returns success but does not create the folder or persist the secret, so saved host passwords were silently lost and share enumeration failed with NT_STATUS_LOGON_FAILURE. Write/delete now go through the kwalletd6 D-Bus API via qdbus6 (open/createFolder/writePassword). Reads stay on kwallet-query (they work). Also drop smbclient -N (was forcing an anonymous session) and silence KWallet read stderr. Adds qt6-tools dep. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 3 ++- install.sh | 1 + package/contents/code/nas.js | 30 ++++++++++++++++++++---------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index b814c92..14e8607 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,8 @@ Install these with your distribution's package manager: | `mount.cifs` | `cifs-utils` | mount CIFS shares | | `smbclient` | `smbclient` | list shares on a host | | `pkexec` | `polkit` | authorize the mount helper | -| `kwallet-query` | `kwallet` (KF6) | store/read passwords in KWallet | +| `kwallet-query` | `kwallet` (KF6) | read passwords from KWallet | +| `qdbus6` | `qt6-tools` | write passwords to KWallet (D-Bus) | | `findmnt` | `util-linux` | detect mounted shares | On Debian/Ubuntu the equivalents are `plasma-workspace`, `cifs-utils`, diff --git a/install.sh b/install.sh index e9ba5ef..041e699 100755 --- a/install.sh +++ b/install.sh @@ -33,6 +33,7 @@ check pkexec "polkit" check mount.cifs "cifs-utils" check smbclient "smbclient" check kwallet-query "kwallet (KF6)" +check qdbus6 "qt6-tools" check findmnt "util-linux" if [ "$missing" -ne 0 ]; then warn "resolve the above and re-run. Continuing anyway..." diff --git a/package/contents/code/nas.js b/package/contents/code/nas.js index 2c3e948..0aa3e57 100644 --- a/package/contents/code/nas.js +++ b/package/contents/code/nas.js @@ -21,6 +21,8 @@ // KWallet folder + wallet used for all stored NAS passwords. var WALLET = "kdewallet"; var WALLET_FOLDER = "Synology NAS"; +var APPID = "synology-nas"; +var KWD = "org.kde.kwalletd6 /modules/kwalletd6 org.kde.KWallet"; var HELPER = "/usr/lib/synology-nas/helper"; // POSIX single-quote escaping: wrap in '...' and replace ' with '\''. @@ -73,8 +75,8 @@ function unc(host, share) { // env var (read by smbclient) so it never reaches argv. function enumerateCmd(host) { var script = - "export PASSWD=\"$(kwallet-query -f 'Synology NAS' -r \"$1\" " + WALLET + ")\"\n" + - "exec smbclient -L \"//$2\" -U \"$3\" -g -N 2>/dev/null"; + "export PASSWD=\"$(kwallet-query -f 'Synology NAS' -r \"$1\" " + WALLET + " 2>/dev/null)\"\n" + + "exec smbclient -L \"//$2\" -U \"$3\" -g 2>/dev/null"; return shCmd(script, [walletKey(host), host.host, host.username || ""]); } @@ -99,7 +101,7 @@ function mountCmd(settings, host, share) { "cf=\"$runtime/$1.cred\"\n" + "trap 'rm -f \"$cf\"' EXIT INT TERM\n" + "{ printf 'username=%s\\n' \"$3\"; printf 'domain=%s\\n' \"$4\"; " + - "printf 'password='; kwallet-query -f 'Synology NAS' -r \"$2\" " + WALLET + "; } > \"$cf\" || exit 1\n" + + "printf 'password='; kwallet-query -f 'Synology NAS' -r \"$2\" " + WALLET + " 2>/dev/null; } > \"$cf\" || exit 1\n" + "chmod 600 \"$cf\"\n" + "exec pkexec " + HELPER + " mount \"$5\" \"$6\" \"$cf\" \"$7\" \"$8\" \"$9\" \"${10}\"\n"; var args = [ @@ -132,18 +134,26 @@ function openCmd(path) { return shCmd("exec xdg-open \"$1\"", [path]); } -// Save a password to KWallet (used by the config page). kwallet-query reads the -// secret from stdin; we feed it via printf from a positional param. The value -// is in this process's argv for the brief write (unavoidable with a CLI-only -// KWallet path) — see the security notes in the README. +// Save a password to KWallet (used by the config page). Uses the kwalletd6 +// D-Bus API via qdbus6: `kwallet-query --write-password` reports success but +// does not actually persist (nor create the folder), so we open the wallet, +// ensure the folder exists, and writePassword. The password is in this +// process's argv for the brief write — see the security notes in the README. function savePasswordCmd(host, password) { - var script = "printf '%s' \"$2\" | kwallet-query -f 'Synology NAS' -w \"$1\" " + WALLET; + var script = + "h=$(qdbus6 " + KWD + ".open " + WALLET + " 0 " + APPID + ")\n" + + "[ -n \"$h\" ] || exit 1\n" + + "qdbus6 " + KWD + ".createFolder \"$h\" '" + WALLET_FOLDER + "' " + APPID + " >/dev/null\n" + + "exec qdbus6 " + KWD + ".writePassword \"$h\" '" + WALLET_FOLDER + "' \"$1\" \"$2\" " + APPID; return shCmd(script, [walletKey(host), password]); } -// Remove a host's stored password (best effort; overwrites with empty). +// Remove a host's stored password (best effort). function deletePasswordCmd(host) { - var script = "printf '' | kwallet-query -f 'Synology NAS' -w \"$1\" " + WALLET + " 2>/dev/null || true"; + var script = + "h=$(qdbus6 " + KWD + ".open " + WALLET + " 0 " + APPID + ")\n" + + "[ -n \"$h\" ] || exit 0\n" + + "qdbus6 " + KWD + ".removeEntry \"$h\" '" + WALLET_FOLDER + "' \"$1\" " + APPID + " >/dev/null 2>&1 || true"; return shCmd(script, [walletKey(host)]); }