💾 Archived View for kenogo.org › blog › 20221201.gmi captured on 2023-01-29 at 02:37:46. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

Using Unix pass in Qubes OS

Homepage

Blog

Introduction

The Unix program [pass] is my password manager of choice. It keeps your passwords as gpg-encrypted files in the directory `~/.password-store'. There also exists a [dmenu] script called [passmenu] that can be bound to a keybinding to easily access your passwords. To get this to work in Qubes OS, you need to put in some work. In this blog post, I share the [qrexec] service I'm using for this purpose.

pass

dmenu

passmenu

qrexec

Architecture

    +-----------------+                   +-----------+
    | vault-passwords |<----split gpg---->| vault-gpg |
    +-----------------+                   +-----------+
            |
            | passmenu qrexec
            v
        +---------+
        | browser |
        +---------+

Above, the qubes and their communication channels used for passmenu under Qubes OS are shown. The qube `vault-password' contains the gpg-encrypted passwords in `~/.password-store'. The qube `vault-gpg' contains the private PGP key needed to decrypt the passwords. They are set up using Qubes' [split gpg] feature so that `vault-passwords' can decrypt the gpg files without having access to the private key itself. Both qubes are set up without internet access.

split gpg

Then, we have some qube that needs access to the passwords. It might be connected to the internet, which is why we don't want to store our passwords directly in that qube. In this example, I have called this Qube `browser'. This blog post will describe how the `vault-passwords' qube can send passwords to the `browser' qube.

Usage

The password access must always come from `vault-passwords'. We can not allow the `browser' qube to request passwords from `vault-passwords' and then have `vault-passwords' return them, because that could allow a malicious `browser' qube to potentially request arbitrary passwords.

Instead, using the qrexec service described here works as follows:

Prerequisites

In `vault-passwords', you need to put modified versions of [pass] and [passmenu] into the home directory and ensure they are executable. The scripts are modified as follows.

pass

passmenu

For pass, replace the lines

    gpg="gpg"
    ...
    which gpg2 &>/dev/null && gpg="gpg2"

with

    gpg="/usr/bin/qubes-gpg-client-wrapper"
    ...
    which gpg2 &>/dev/null && gpg="/usr/bin/qubes-gpg-client-wrapper"

This makes sure that pass uses our [split gpg] setup to decrypt the password files. I will not go into how to setup split gpg in this blog post. Confirm the modified script and your split gpg setup are working by executing

split gpg

    $ ./pass your/password

and observing whether the password is successfully shown.

For passmenu, replace the following

    if [[ $typeit -eq 0 ]]; then
        pass show -c "$password" 2>/dev/null
    else
        pass show "$password" | { IFS= read -r pass; printf %s "$pass"; } | $xdotool
    fi

with

    ~/pass show "$password" | {IFS= read -r pass; printf %s "$pass"; }

This makes sure passmenu uses our modified version of pass and that it neither copies the password to the clipboard nor types it, but instead outputs it to stdout. This is necessary so that the password can be sent over qrexec to the `browser' qube.

The qrexec service

In `vault-passwords', create `~/qubes-passmenu-sender' with the following contents and make it executable.

    #!/bin/sh
    xterm -e "echo 'Passmenu started...'; sh" &
    childpid=$!
    ~/passmenu
    kill $childpid

This script is basically just supposed to start your modified passmenu script. However, there is the problem that passmenu doesn't grab the focus of your keyboard under Qubes unless you are inside a window of `vault-passwords'. I've used the hacky solution of starting XTerm to let that grab the focus for passmenu. It's not pretty, but it works.

In the template qube for `browser', create `/etc/qubes-rpc/qubes.Passmenu' with the following contents and make it executable. Also, make sure that xdotool is installed in the template.

    #!/bin/sh
    
    read pass
    sleep 0.5  # Wait for vault-passwords window to close
    xdotool type "$pass"

Finally, create `/etc/qubes-rpc/policy/qubes.Passmenu' with the following contents:

    vault-passwords @anyvm ask
    @anyvm @anyvm deny

With this setup, `vault-passwords' can send passwords to any desired qube and you have to enter the destination qube when starting the qrexec service. Another policy might be more useful to you. For example, you could set

    vault-passwords browser allow
    @anyvm @anyvm deny

if you always use the same `browser' qube and want to specify that as the destination qube when configuring the keybinding.

After completing the steps above, confirm the qrexec service is working by running

    $ qrexec-client-vm browser qubes.Passmenu ~/qubes-passmenu-sender

in `vault-passwords'. It should then work as specified in the section Usage.

Keybinding

All that is missing now is to set a keybinding in `dom0'. Head into the keyboard settings and add a keybinding (I use `Super+p') for the command

    qvm-run vault-passwords qrexec-client-vm default qubes.Passmenu \
        ~/qubes-passmenu-sender

Final words

I hope this post has been useful. If you happen to find a less hacky solution to let passmenu grab focus, please contact me at:

keno@goertz-berlin.com