Password-store, the one true unix way of password management has served me well for over 6 years. However, as I'm starting to use other devices in tandem such as my phone and laptop, I've become jealous of those who can easily fill in their credentials with a click of a button.
Right now, my workflow on my desktop and laptop computers (which run windows) are:
- open windows terminal, ssh into my server that holds my passwords
- run
pass
- copy the output
- paste it where I need it
It's been very cumbersome, but the friction was low enough that I haven't done anything about it. However, it's time to make things a bit easier as this workflow has been feeling more cumbersome recently.
I had tried to make a nicer workflow for pass
on
windows, but getting gpg
running properly has been a
nightmare, and I eventually gave up. Further, passff
extension can't connect to the local instance of pass
properly and keeps complaining. I'm sure I could get it to work easily
on linux or *BSD, but here we are!
Exporting from password-store
As password-store deals with basic tools, exporting passwords is superbly easy. In fact, this is one of the main reasons I've stuck to it for so long, because I always knew my passwords were safe and in my control.
To do all this, I'm using linux under WSL on windows as I don't want
to deal with Windows's idiosyncrasies with gpg
and
pass
.
To export passwords from pass
, gpg
can be
used directly after importing your key and decrypting individual files.
The below snippet assumes you have your passwords in passwd
directory and want the decrypted files in passwd-decrypted
directory with the same directory structure. First, we copy the
directory as is, deleting all the gpg files inside to preserve the
directory structure.
$ cp -r passwd passwd-decrypted
$ find passwd-decrypted -type f -name '*.gpg' -delete
And decrypt.
$ find passwd -type f -name '*.gpg' -exec gpg --output 'passwd-decrypted/{}.txt' --decrypt '{}' \;
You can remove the extension too with any bash-compatible shell.
$ shopt -s globstar # enables recursive glob for bash 4+
$ for f in **/*.gpg.txt; do mv "$f" "${f/%.gpg.txt/}"; done
Now we have a directory full of decrypted passwords.
Importing into Bitwarden
Bitwarden expects either csv
or json
with
a
specific format. The issue at this point is converting the free form
text format that pass
allows, to a more structured format
that Bitwarden expects. This solely depends on how you have structured
your pass
passwords. Mine are in the following format:
<password>
username: <username>
email: <email>
www: <url>
totpauth://...
multiline free-form notes
Unfortunately, even though more recently I've tried to adhere to this
format, I haven't always. So there are a lot of files without much
structure, which means I have to manually import them. The only reliable
part of my password collection is the first line, and if exists,
otpauth://
.
set -eux
function add {
filename="$1"
folder=$(dirname "${filename}")
if [[ "x$folder" = "x." ]]; then
name=$(basename "${filename}")
else
name="${folder}-"$(basename "${filename}")
fi
password=$(cat "$filename" | head -n 1)
username=$(cat "$filename" | grep -E '^(email|username):' | head -n 1 | cut -d: -f2- | sed 's/^[ \t]*//')
totp=$(cat "$filename" | grep otpauth)
url=$(cat "$filename" | grep -E '^(url|www|website):' | head -n 1 | cut -d: -f2- | sed 's/^[ \t]*//')
notes=$(cat "$filename")
echo -n "Adding $name..."
item_template=$(bw get template item)
login_template=$(bw get template item.login)
item_login=$(echo $login_template | jq --arg u "${username}" '.username=$u' | jq --arg p "${password}" '.password=$p' | jq ".totp=\"${totp}\"" | jq ".uris=[\"${url}\"]")
item=$(echo $item_template | jq ".name=\"${name}\"" | jq ".login=${item_login}" | jq --arg n "${notes}" '.notes=$n')
echo "$item" | bw encode | bw create item >/dev/null
echo "done"
}
# find * ... to remove the preceeding ./
find /path/to/passwd/decrypted/* -type f | while read f; do add "$f"; done
Note that the above script is extremely hacky and fails at the mere sight of anything being imperfect. Use with caution. It does handle quotes in passwords though, which is nice.
And finally sync.
$ bw sync
At last I can click to autofill everywhere I go!