Skip to content

Instantly share code, notes, and snippets.

@kazlauskis
Created July 13, 2017 14:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kazlauskis/c3ff35a08e758d1983ce3cae3b8b786c to your computer and use it in GitHub Desktop.
Save kazlauskis/c3ff35a08e758d1983ce3cae3b8b786c to your computer and use it in GitHub Desktop.
Export Password Store (aka pass) passwords to a KeePass compatible imports file
#!/bin/bash
#
# Export Password Store (aka pass) passwords to a KeePass compatible imports file.
# Note: this does not respect the folder structure (yet). Also, multiline notes are not exported correctly.
#
# Author: Karolis Kazlauskis
# 2017
entries='' # pass entries found
# loop through every file in the dir
FILES=()
while read file; do
password=''
login=''
user=''
url=''
notes=''
# clean up the file name
file=$(sed 's/.gpg//g' <<< $file)
file=$(sed 's/.*\.password-store\///g' <<< $file)
# set title of the key
title=$(sed 's/.*\///g' <<< $file)
echo "\n $title ($file)"
info=($(pass "$file"))
echo "${info[@]}"
# extract the parts of the key
password=${info[@]:0:1}
info=("${info[@]:1}")
shopt -s nocasematch
if [ "${info[0]}" == 'login:' ]; then
login=${info[1]}
elif [ "${info[0]}" == 'UserName:' ]; then
user=${info[1]}
elif [ "${info[0]}" == 'Notes:' ]; then
notes=${info[1]}
elif [ "${info[0]}" == 'url:' ] || [ "${info[0]}" == 'URL:' ]; then
url=${info[1]}
fi
info=("${info[@]:1}")
info=("${info[@]:1}")
if [ "${info[0]}" == 'login:' ]; then
login=${info[1]}
elif [ "${info[0]}" == 'UserName:' ]; then
user=${info[1]}
elif [ "${info[0]}" == 'Notes:' ]; then
notes=${info[1]}
elif [ "${info[0]}" == 'url:' ] || [ "${info[0]}" == 'URL:' ]; then
url=${info[1]}
fi
info=("${info[@]:1}")
info=("${info[@]:1}")
if [ "${info[0]}" == 'login:' ]; then
login=${info[1]}
elif [ "${info[0]}" == 'UserName:' ]; then
user=${info[1]}
elif [ "${info[0]}" == 'Notes:' ]; then
notes=${info[1]}
elif [ "${info[0]}" == 'url:' ] || [ "${info[0]}" == 'URL:' ]; then
url=${info[1]}
fi
info=("${info[@]:1}")
info=("${info[@]:1}")
if [ "${info[0]}" == 'login:' ]; then
login=${info[1]}
elif [ "${info[0]}" == 'UserName:' ]; then
user=${info[1]}
elif [ "${info[0]}" == 'Notes:' ]; then
notes=${info[1]}
elif [ "${info[0]}" == 'url:' ] || [ "${info[0]}" == 'URL:' ]; then
url=${info[1]}
fi
# escape xml
password=$(sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&#39;/g' <<< ${password})
login=$(sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&#39;/g' <<< ${login})
user=$(sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&#39;/g' <<< ${user})
url=$(sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&#39;/g' <<< ${url})
notes=$(sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g; s/"/\&quot;/g; s/'"'"'/\&#39;/g' <<< ${notes})
# add to the entries
entries+=$(cat << EndOfMessage
<Entry>
<UUID>$(uuidgen)</UUID>
<String>
<Key>Title</Key>
<Value>${title}</Value>
</String>
<String>
<Key>UserName</Key>
<Value>${user}</Value>
</String>
<String>
<Key>Password</Key>
<Value ProtectInMemory="True">${password}</Value>
</String>
<String>
<Key>URL</Key>
<Value>${url}</Value>
</String>
<String>
<Key>Notes</Key>
<Value>${notes}</Value>
</String>
</Entry>
EndOfMessage
)
done <<< "$(find ~/.password-store/ -name '*.gpg' )"
# write it to the file
cat > exports.xml << EndOfMessage
<?xml version="1.0" encoding="UTF-8"?>
<KeePassFile>
<Meta>
<DatabaseName>Database</DatabaseName>
</Meta>
<Root>
<Group>
<UUID>$(uuidgen)</UUID>
<Name>Imports</Name>
${entries}
</Group>
</Root>
</KeePassFile>
EndOfMessage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment