Ubuntu – Use KDE wallet to authenticate a mount call

kdekwalletmountpasswordsamba

I am using a command similar to the following to mount some NAS samba shares in my Kubuntu 18.04 system:

sudo mount -t cifs -o "username=MyUser" //MyServer/MyFolder ~/SharedFolders/MyFolder

This works fine. However it asks for the password every time. I would like to use the KDE password wallet (or some similar agent) for authentication.

I want the password being asked at the GUI a single time, then it should be stored permanently and reused for future mount calls.

Is something like that possible with mount?

If not, is there an automatable alternative in KDE?

Best Answer

There is no way to tell mount which program to use for storing/reading passwords, but there are a few KDE tools you can combine to automate the process.

For storing/reading passwords: kwalletcli
For a GUI password prompt: kdialog
You should be able to install them with your package manager.

I wrote a script that does this (with a few extra options). It should be doing everything you asked for: if the password does not exist, a GUI prompt is shown (if available) and the password is stored in a wallet for later use.

You can update the password from the command line with kwalletcli again, but the only way I could find to delete them is the KWalletManager GUI app.

Here's the script as of 2020-08-22:

#!/bin/sh

usage() {
    echo "Usage: $0 [-u username] [-o options] share mount"
    echo
    echo "Defaults for optional parameters:"
    echo
    echo "  username:  the output of 'id -un', i.e. the current user"
    echo "  options:   defaults,uid=1000,gid=1000,iocharset=utf8"
    echo "             Pass an empty string to clear default options"
    exit 2
}

while getopts "u:o:" opt; do
    case "$opt" in
        u) USERNAME="$OPTARG" ;;
        o) OPTIONS="$OPTARG" ;;
        *) usage ;;
    esac
done
shift $((OPTIND-1))

[ "$#" -ne 2 ] && usage

# Mount settings
USERNAME="${USERNAME:-$(id -un)}"
OPTIONS="${OPTIONS-defaults,uid=1000,gid=1000,iocharset=utf8}"
SHARE="$1"
MOUNT="$2"

# Wallet settings
FOLDER="CIFS credentials"
ENTRY="$USERNAME@${SHARE#//}"

read_password() {
    PASS_PROMPT="Password for $USERNAME@${SHARE#//}: "

    if command -v kdialog >/dev/null 2>&1; then
        PASSWORD="$(kdialog --password "$PASS_PROMPT")"
    else
        # from https://stackoverflow.com/a/28393320/6702490
        trap 'stty echo' EXIT
        stty -echo
        printf "%s" "$PASS_PROMPT"
        read -r PASSWORD
        printf "\n"
        stty echo
        trap - EXIT
    fi
}

if ! PASSWORD="$(kwalletcli -f "$FOLDER" -e "$ENTRY" 2>/dev/null)"; then
    if read_password && [ -n "$PASSWORD" ]; then
        kwalletcli -f "$FOLDER" -e "$ENTRY" -p "$PASSWORD"
    else
        echo "Empty/no password entered, skipping writing password to wallet and mount."
        exit 1
    fi
fi

sudo mount -t cifs -o "${OPTIONS}${OPTIONS:+,}username=$USERNAME,password=$PASSWORD" "$SHARE" "$MOUNT"

Note: using kwallet-query would be the better option since it comes bundled with KDE/kwallet and supports non-default wallets, but I wasn't able to make it store a password. There were no errors shown and no non-zero exit code, but the password wouldn't be written to the wallet.