diff --git a/README.md b/README.md index 7f2377c..b814c92 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,120 @@ -# Plasma-Addon-Synology-NAS +# Synology NAS — KDE Plasma 6 widget +A system-tray widget for **KDE Plasma 6** that lets you browse and mount your +**Synology** (or any **SMB/CIFS**) network shares the same way Plasma Vaults +handles encrypted vaults: click the tray icon, and a popup lists each configured +host with its shares — mount or unmount any of them with one click. + +- Add **multiple** NAS / SMB hosts. +- Auto-discovers each host's shared folders with `smbclient`. +- Mounts real **kernel CIFS** mounts (visible to every app, not just Dolphin). +- Passwords are kept in **KWallet**, never in plain config. +- Privileged mounting is done through a tiny **polkit**-authorized helper — no + passwordless-sudo hacks, no editing `/etc/fstab`. + +> Works with any SMB server. "Synology" is just the friendly name — point it at +> a Synology DSM, a Samba box, a Windows share, a TrueNAS, whatever speaks SMB. + +## Requirements + +Install these with your distribution's package manager: + +| Tool | Provided by (Arch) | Purpose | +|------------------|------------------------|----------------------------------| +| `kpackagetool6` | `plasma-workspace` | install the widget | +| `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 | +| `findmnt` | `util-linux` | detect mounted shares | + +On Debian/Ubuntu the equivalents are `plasma-workspace`, `cifs-utils`, +`smbclient`, `policykit-1`, `kwallet-bin`/`kf6-kwallet`, `util-linux`. + +## Install + +```sh +git clone https://git.houmeres.sk/Houmeres/Plasma-Addon-Synology-NAS.git +cd Plasma-Addon-Synology-NAS +./install.sh +``` + +`install.sh` copies the helper to `/usr/lib/synology-nas/helper` and the polkit +policy to `/usr/share/polkit-1/actions/` (via `sudo`), then installs the widget +for your user with `kpackagetool6`. Re-run it any time to upgrade. + +Then add **Synology NAS** to your panel or system tray (right-click → +*Add Widgets…*), or try it standalone: + +```sh +plasmawindowed sk.houmeres.synologynas +``` + +## Usage + +1. Open the widget's settings (right-click → *Configure…*). +2. Under **NAS Hosts**, add a host: display name, host/IP, username, password + (saved to KWallet), and optionally a domain, a mount-folder override, or an + SMB-version override. +3. Under **General**, optionally set the default mount folder (defaults to + `~/NAS`), SMB version, extra mount options and permission modes. +4. Click the tray icon → **Refresh**. Each host's shares appear; click a share + to **Mount** it (you'll get a polkit prompt) or **Unmount** it. Use the row's + menu to open a mounted share in your file manager. + +Shares mount under `//` (e.g. +`~/NAS/HomeNAS/photos`). + +## How it works + +``` + Plasmoid (QML) Privileged helper (root, via pkexec) + ───────────── ──────────────────────────────────── + smbclient -L ── list shares mount.cifs //host/share + kwallet-query ── read password -o credentials=…,uid=…,forceuid,… + │ umount + ▼ + write 0600 cred file in polkit action: + $XDG_RUNTIME_DIR ───────────► sk.houmeres.synologynas.manage + │ (auth_admin_keep) + └── pkexec helper mount … +``` + +The QML never runs privileged operations directly. It builds a `0600` +credentials file in your `$XDG_RUNTIME_DIR` (reading the password straight from +KWallet, so it never lands in QML, argv or `ps`) and calls the helper through +`pkexec`. The helper treats every argument as hostile: the mount point must +resolve inside your `$HOME` or `/run/media/`, the source must be +`//host/share`, and the credentials file must be your own `0600` file under your +runtime dir. + +## Security notes + +- **Passwords** live in KWallet (folder *Synology NAS*). They are copied into a + transient `0600` credentials file only for the moment of mounting, then + removed. +- The **one** place a password briefly touches process arguments is when you + first *save* it in the config page (`kwallet-query -w`), because the CLI has no + other input channel here. The window is milliseconds and visible only to your + own user (and root). Everything afterward reads from KWallet. +- The privileged helper is intentionally tiny and does **no** recursive + deletion — on unmount it only `rmdir`s the now-empty mount/host directories. + +## Uninstall + +```sh +./uninstall.sh +``` + +Mounted shares stay mounted (unmount them first) and KWallet passwords remain — +remove them with `kwalletmanager` if desired. + +## Limitations / roadmap + +- No mount-at-login persistence yet (planned; the config schema already leaves + room for it). +- Share discovery is via `smbclient -L` only (no Synology DSM API). + +## License + +MIT — see [LICENSE](LICENSE). diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..e9ba5ef --- /dev/null +++ b/install.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# +# install.sh — install the Synology NAS plasmoid + its privileged helper. +# +# Distro-agnostic: the plasmoid is installed per-user with kpackagetool6, and +# the helper + polkit policy go to system paths via sudo. Re-running upgrades +# in place (idempotent). +# +set -eu + +HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +APPLET_ID="sk.houmeres.synologynas" +HELPER_SRC="$HERE/helper/synology-nas-helper" +POLICY_SRC="$HERE/helper/sk.houmeres.synologynas.policy" +HELPER_DEST="/usr/lib/synology-nas/helper" +POLICY_DEST="/usr/share/polkit-1/actions/sk.houmeres.synologynas.policy" + +say() { printf '==> %s\n' "$1"; } +warn() { printf 'WARNING: %s\n' "$1" >&2; } + +# --- dependency check --------------------------------------------------------- +missing=0 +check() { + if command -v "$1" >/dev/null 2>&1; then + return + fi + warn "missing '$1' — install $2" + missing=1 +} +say "Checking dependencies" +check kpackagetool6 "plasma-workspace / plasma-sdk" +check pkexec "polkit" +check mount.cifs "cifs-utils" +check smbclient "smbclient" +check kwallet-query "kwallet (KF6)" +check findmnt "util-linux" +if [ "$missing" -ne 0 ]; then + warn "resolve the above and re-run. Continuing anyway..." +fi + +# --- install helper + polkit policy (root) ------------------------------------ +say "Installing privileged helper to $HELPER_DEST" +sudo install -Dm755 "$HELPER_SRC" "$HELPER_DEST" +say "Installing polkit policy to $POLICY_DEST" +sudo install -Dm644 "$POLICY_SRC" "$POLICY_DEST" + +# --- install / upgrade the plasmoid (user) ------------------------------------ +if kpackagetool6 --type Plasma/Applet --list 2>/dev/null | grep -qx "$APPLET_ID"; then + say "Upgrading plasmoid $APPLET_ID" + kpackagetool6 --type Plasma/Applet --upgrade "$HERE/package" +else + say "Installing plasmoid $APPLET_ID" + kpackagetool6 --type Plasma/Applet --install "$HERE/package" +fi + +cat < "Add Widgets..." -> search + "Synology NAS", or add it to the System Tray's configured entries. + +Test it standalone (no panel needed): + plasmawindowed $APPLET_ID + +If the widget was already loaded, restart the shell to pick up changes: + kquitapp6 plasmashell && kstart plasmashell >/dev/null 2>&1 & +EOF diff --git a/uninstall.sh b/uninstall.sh new file mode 100755 index 0000000..74c7e29 --- /dev/null +++ b/uninstall.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# +# uninstall.sh — remove the Synology NAS plasmoid, helper and polkit policy. +# Mounted shares and stored KWallet passwords are left untouched. +# +set -eu + +APPLET_ID="sk.houmeres.synologynas" +HELPER_DEST="/usr/lib/synology-nas/helper" +POLICY_DEST="/usr/share/polkit-1/actions/sk.houmeres.synologynas.policy" + +say() { printf '==> %s\n' "$1"; } + +if kpackagetool6 --type Plasma/Applet --list 2>/dev/null | grep -qx "$APPLET_ID"; then + say "Removing plasmoid $APPLET_ID" + kpackagetool6 --type Plasma/Applet --remove "$APPLET_ID" || true +fi + +say "Removing helper + polkit policy" +sudo rm -f "$HELPER_DEST" "$POLICY_DEST" +sudo rmdir /usr/lib/synology-nas 2>/dev/null || true + +cat <