Skip to content

Instantly share code, notes, and snippets.

@garfvl
Last active May 11, 2023 08:13
Show Gist options
  • Save garfvl/23eb3cfc994cb1d8726b41304522e54d to your computer and use it in GitHub Desktop.
Save garfvl/23eb3cfc994cb1d8726b41304522e54d to your computer and use it in GitHub Desktop.
passk: simplistic script to store ssh keys in pass/gopass and use them. Works with gopass, should work with pass.
#!/bin/bash
command=$1
PASSK_BACKEND=${PASSK_BACKEND:-gopass}
pass_show() {
case $PASSK_BACKEND in
pass)
pass show "$1"
;;
gopass)
gopass show -u "$1"
;;
esac
}
pass_list() {
case $PASSK_BACKEND in
pass)
prefix=${PASSWORD_STORE_DIR:-~/.password-store}
find "$prefix" -iname "*.gpg" -printf "%P\n" | sed 's/.gpg$//'
;;
gopass)
gopass list -f
;;
esac
}
pass_find() {
case $PASSK_BACKEND in
pass)
test -n "$(pass_list | grep -E "^$1$")"
;;
gopass)
gopass find "$1" > /dev/null 2>&1
;;
esac
}
pass_insert() {
case $PASSK_BACKEND in
pass)
pass insert -m "$1"
;;
gopass)
gopass insert -m "$1"
;;
esac
}
# for _normal -p $service explanation, see: https://zsh.sourceforge.io/Doc/Release/Completion-System.html#index-_005fnormal
# Note: this is similar to _precommand function
zsh_completion='
_complete_passk() {
keys_list=$(passk list)
command_list="run list pub gen"
if (( CURRENT == 2 )); then
_alternative "commands:command:($command_list)" "entries:entry:($keys_list)"
elif (( CURRENT == 3 )) && [[ $words[2] == "run" ]] || [[ $words[2] == "pub" ]]; then
_alternative "arguments:entries:($keys_list)"
elif (( CURRENT >= 3 )) && $(echo $keys_list | grep $words[2] > /dev/null); then
shift 2 words
(( CURRENT = CURRENT - 2 ))
_normal -p $service
elif (( CURRENT >= 4 )) && [[ $words[2] == "run" ]]; then
shift 3 words
(( CURRENT = CURRENT - 3 ))
_normal -p $service
fi
}
compdef _complete_passk passk
'
run_with_ssh_agent() {
key=$1
# generate a custom ssh-agent
agent_env="$(ssh-agent)"
agent_sock=$(eval "$agent_env echo \$SSH_AUTH_SOCK" | tail -n 1)
agent_pid=$(eval "$agent_env echo \$SSH_AGENT_PID" | tail -n 1)
pass_show "$key" | SSH_AUTH_SOCK=$agent_sock SSH_AGENT_PID=$agent_pid ssh-add - > /dev/null 2>&1
SSH_AUTH_SOCK=$agent_sock SSH_AGENT_PID=$agent_pid ${@:2}
exit_code=$?
SSH_AUTH_SOCK=$agent_sock SSH_AGENT_PID=$agent_pid ssh-agent -k > /dev/null
return $exit_code
}
case $command in
list)
pass_list | grep -E "ssh|key"
;;
pub)
key=$2
pass_show "$key" | ssh-keygen -y -f /dev/stdin
;;
run)
run_with_ssh_agent ${@:2}
exit $?
;;
gen)
echo "Provide some pass entry"
read entry
pass_find "$entry" && (echo "Entry already exists"; exit 42;)
echo "Provide recipent/comment"
read recipient
temp="$(mktemp)"
rm -f "$temp" && ssh-keygen -a 100 -t ed25519 -f "$temp" -N "" -C "$recipient"
cat "$temp" | pass_insert "$entry"
rm -f "$temp" "${temp}.pub"
;;
completion-zsh)
echo "${zsh_completion}"
;;
*)
if [ -n "$1" ] && $(passk list | grep $1 > /dev/null); then
run_with_ssh_agent $@
else
echo "USAGE: passk command [OPTIONS]"
echo ""
echo "passk list"
echo " list all gopass entries which contain 'ssh' or 'key'"
echo "passk pub <entry>"
echo " display public key generated from the private one stored in pass entry"
echo "passk [run] <entry> (...)"
echo " run the following command with a new ssh-agent containing the entry."
echo " agent will be killed at the end of the command"
echo "passk gen"
echo " generate private key and store it into an entry (interactive)"
exit
fi
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment