Migrating from pass to Bitwarden
pass,
sometimes called "password-store",
is a great password manager.
It's nothing more than a shell script
that uses tried and tested unix tools like gpg
in order to store passwords in a safe and secure manner.
Nevertheless, pass lacks some features that I find important:
namely, sync.
Sure, you can put your entire pass
directory into a git
repository and sync it like that,
but, especially with the death of
Android-Password-Store,
actually using pass
on my phone is a bit of a pain.
A good alternative is Bitwarden:
a free and self-hostable password manager
with sync features and a well-maintained Android app.
In this blogpost I'll take you through the steps
of migrating from pass
to Bitwarden.
Migrating passwords with rbw
I'll assume that you already have Vaultwarden set up and running on your homeserver.
On the client, we can install rbw, a third-party command line Bitwarden client.
We can then write a simple shell script
(let's call it pass2rbw.sh
)
to read out all pass
entries
and add them to the bitwarden vault using rbw
.
A note here on formats: rbw
uses a fixed format where
the username is passed as a command-line option,
while the password is stored in the first line of the note,
with the rest of the note being freeform text.
pass
, on the other hand, does not have a fixed format.
The entirety of the note is freeform text.
Personally, I put the username on the first line
and the password on the second,
which is the format that my script uses.
Adjust it to fit your own setup.
#!/bin/sh
# Change into the password-store directory
cd ~/.password-store
# Get a list of all the password name
list=$(find . -name '*.gpg' | cut -c 3- | sed 's/\.gpg$//')
# go back to the directory the script was launched from
cd -
for i in $list
do
# Get the text of the pass entry
text=$(pass show $i)
# Get username (first line)
username=$(echo "$text" | head -n 1)
# Get password (second line)
password=$(echo "$text" | tail -n +2 | head -n 1)
# Get the rest of the entry
note=$(echo "$text" | tail -n +3)
# Put the password and note into a file
echo "$password" > ./PASSWORD
echo "$note" >> ./PASSWORD
# Add it to RBW
EDITOR=$(realpath ./not-an-editor.sh) rbw add "$i" "$username"
done
There doesn't seem to be a non-interactive way to add entries to rbw
;
rbw add
always spawns a text editor to enter the note text.
We get around this by overriding the $EDITOR
variable and pointing
it to a special ./not-an-editor.sh
script that just copies
the contents of the PASSWORD file created earlier by the script
into the target file created by rbw
:
#!/bin/sh
cat PASSWORD > "$1"
Make sure that not-an-editor.sh
and pass2rbw.sh
are executable
and run them.
Once you've verified that the entries have been transferred
correctly,
don't forget to shred
the temporary PASSWORD
file.
Autotype
I used to have a nice autotype script that would
let me choose a pass
entry using rofi,
and autotype it using xdotool
.
Although rofi-rbw already exists, I would like to write my own script that works with just BASH and doesn't depend on Python. Here it is:
#!/bin/bash
# Enable using custom keys in rofi
echo -en "\0use-hot-keys\x1ftrue\n"
if [ -z "$1" ]; then
# First call (no selection provided)...
rbw unlocked > /dev/null 2>&1
if [ "$?" -ne 0 ]
then
# If `rbw` is not unlocked, spawn a terminal
# and prompt the user to unlock.
coproc (
alacritty -e rbw unlock
> /dev/null 2>&1
)
# Close rofi after spawning terminal
killall rofi
else
# If `rbw` is unlocked,
# list all entries
rbw ls
fi
else
# Second call (selection provided)...
# Get name, username, and password
NAME=$1
FIRSTLINE=$(rbw get -f user "$NAME")
SECONDLINE=$(rbw get "$NAME")
# Unpress all modifiers
xdotool keyup Control Alt Super
case $ROFI_RETV in
1 )
# User hit `enter`:
# autotype username <tab> password <enter>
coproc (
sleep 0.2
test "$FIRSTLINE" && {
echo "$FIRSTLINE" |
tr -d '\n' |
xdotool type --file - --delay 20
xdotool key Tab
}
test "$SECONDLINE" && {
echo "$SECONDLINE" |
tr -d '\n' |
xdotool type --file - --delay 20
}
xdotool key Enter
)
;;
10 )
# User hit custom key 1:
# autotype just the username
coproc (
sleep 0.2
echo "$FIRSTLINE" |
tr -d '\n' |
xdotool type --file - --delay 20
)
;;
11 )
# User hit custom key 2:
# autotype just the password
coproc (
sleep 0.2
echo "$SECONDLINE" |
tr -d '\n' |
xdotool type --file - --delay 20
)
;;
esac
fi
Once you've changed alacritty
to reflect the terminal
emulator that you use,
you can run the script with rofi like this:
rofi \
-theme solarized \
-show RBW:~/.config/rofi/rofi_rbw.sh \
-kb-row-up 'Up' \
-kb-remove-to-sol '' `# Unset existing Ctrl+p shortcut` \
-kb-custom-1 "Ctrl+u" \
-kb-custom-2 "Ctrl+p"