💾 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
-=-=-=-=-=-=-
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.
+-----------------+ +-----------+ | 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.
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.
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:
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.
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
$ ./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.
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.
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
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: