1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/bin/sh
# https://git.christoph-polcin.com/keyring/
# Simplified BSD License
set -e
if [ -z "${SSH_AUTH_SOCK}" ] || [ ! -S "${SSH_AUTH_SOCK}" ]
then
SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"
export SSH_AUTH_SOCK
gpgconf --launch gpg-agent
sleep 1
fi
if [ "$1" = '--eval' ] || [ "$1" = '-e' ] || [ "$1" = 'eval' ]; then
shift
printf "SSH_AUTH_SOCK=%s\nexport SSH_AUTH_SOCK;\n" "$SSH_AUTH_SOCK"
fi
case "${1}" in
-a|--add|add)
shift
printf "keyring +\n" >&2
SSH_ASKPASS="${0}" ssh-add "${@:?'need argument: ~/.ssh/KEY...'}" </dev/null >&2
;;
-c|--clear|clear)
shift
[ "${1:-}" = "--force" ] && force="${1}" || force=""
while IFS= read -r kid
do
[ -z "${kid}" ] && continue
gpg-connect-agent "DELETE_KEY ${force} ${kid}" /bye || :
done <<EOF
$(
gpg-connect-agent 'KEYINFO --ssh-list' /bye \
| cut -s -d' ' -f3
)
EOF
;;
-k|--kill|kill)
gpg-connect-agent 'KILLAGENT' /bye
;;
-d|--del|del|--delete|delete)
shift
for key in "${@:?KEY... to delete from agent}"
do
[ ! -e "${key}" ] && continue
fp="$(ssh-keygen -l -E sha256 -f "${key}" | cut -d' ' -f2 | cut -d: -f2)"
kid="$(gpg-connect-agent 'KEYINFO --ssh-list --ssh-fpr=sha256' /bye | grep -- "${fp}" | cut -s -d' ' -f3)"
[ -z "${kid}" ] && printf 'key not in keyring: %s\n' "${fp}" && continue
gpg-connect-agent "DELETE_KEY --force ${kid}" /bye
done
;;
-l|--list|list|ls)
ssh-add -l >&2
;;
-h|--help|help)
cmd="$(basename "$0")"
cat <<EOF
usage: ${cmd} [ --eval ] --add ~/.ssh/KEY... | --clear [--force] | --kill | --list
${cmd} -e|--eval [ARGS] Prints the SSH_AUTH_SOCK to stdout.
${cmd} -a|--add ~/.ssh/KEY... Adds identities.
${cmd} -c|--clear [--force] Removes all identities.
${cmd} -k|--kill Kills the current agent.
${cmd} -d|--del ~/.ssh/KEY... Removes identities.
${cmd} -l|--list Lists all identities.
PASS_KEY_PREFIX: ${PASS_KEY_PREFIX:-keyring}
EOF
;;
*)
# retrieves passphrase from pass via SSH_ASKPASS
KEY="$(printf "%s" "$*" | sed -n 's/^.*[ \/]\([^\/].*\):\s*$/\1/p')"
if [ -n "${KEY}" ]
then
pass show "${PASS_KEY_PREFIX:-keyring}/${KEY}"
else
exit 1
fi
;;
esac