Last active
May 11, 2023 08:13
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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