You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.6 KiB
111 lines
2.6 KiB
#!/bin/bash |
|
# libssh-agent 0.1 |
|
# (c) 2013-2014 Orochimarufan |
|
# |
|
# Managing SSH keys and agents |
|
|
|
LSA_VERSION=0.1 |
|
|
|
# === Tools === |
|
# Echo colored text to STDERR |
|
echocolor() { |
|
# (int color, string... text) |
|
local COLOR=$1 && shift |
|
echo -e "\e[${COLOR}m$*\e[0m" >&2 |
|
} |
|
|
|
# Look for keys in ssh argv |
|
ssh_keys_from_argv() { |
|
# (string... argv) -> global "KEYS" |
|
local EX=false |
|
declare -ga KEYS |
|
|
|
for arg in "$@"; do |
|
if $EX; then |
|
KEYS=("${KEYS[@]}" "$arg") |
|
EX=false |
|
else |
|
[ "$arg" = "-i" ] && EX=true |
|
fi |
|
done |
|
} |
|
|
|
# === Private Functions === |
|
# Private SSH Agent instance management |
|
PRIVATE_SSH_AGENT=false |
|
|
|
private_ssh_agent_start() { |
|
echocolor 35 "Starting private SSH Agent." |
|
PRIVATE_SSH_AGENT_P_PID=$SSH_AGENT_PID |
|
PRIVATE_SSH_AGENT_P_SOCK=$SSH_AUTH_SOCK |
|
# We don't want the PID printed. |
|
eval `ssh-agent -s` >/dev/null |
|
PRIVATE_SSH_AGENT=true |
|
} |
|
|
|
private_ssh_agent_stop() { |
|
echocolor 35 "Stopping private SSH Agent." |
|
# We don't need the output. |
|
eval `ssh-agent -ks` >/dev/null |
|
PRIVATE_SSH_AGENT=false |
|
export SSH_AGENT_PID=$PRIVATE_SSH_AGENT_P_PID |
|
export SSH_AUTH_SOCK=$PRIVATE_SSH_AGENT_P_SOCK |
|
} |
|
|
|
gnome_keyring_ssh_agent_ckeck() { |
|
# the GNOME Keyring agent doesn't support ecdsa keys. |
|
local PID=$1; shift |
|
|
|
# FIXME: Linux specific! |
|
# FIXME: is this reliable? |
|
CMDLINE="/proc/$PID/cmdline" |
|
if grep -qi gnome-session "$CMDLINE" 2>/dev/null; then |
|
echocolor 33 "Warning: Detected GNOME Keyring, lacking ECDSA support." |
|
for key in "$@"; do |
|
if grep -q "BEGIN EC PRIVATE KEY" "$key"; then |
|
echocolor 31 "Found ECDSA Identity: $key" |
|
echocolor 31 "Identities contain ECDSA key(s). Forcing creation of a private OpenSSH agent." |
|
return 1 |
|
fi |
|
done |
|
fi |
|
return 0 |
|
} |
|
|
|
# === Public API === |
|
# Check for running agent or start a new one |
|
# Keys will be added if they don't exist. |
|
# Setting start to false will basically do a dry run. |
|
# You should use the aliases below. |
|
ssh_agent() { |
|
# (bool start, string... keys) |
|
local START=$1 && shift |
|
|
|
local KEYS="`ssh-add -l 2>/dev/null`" |
|
{ [ $? -eq 2 ] || ! gnome_keyring_ssh_agent_ckeck $SSH_AGENT_PID "$@" || $START && test -n "$LSA_FORCE_AGENT"; } && \ |
|
{ $START && private_ssh_agent_start || return 2; } |
|
|
|
local RT=0 |
|
for key in "$@"; do |
|
echo "$KEYS" | grep -q "$key" \ |
|
|| { $START && ssh-add "$key"; } \ |
|
|| { RT=1; echocolor 34 "SSH Agent is missing a key: $key"; } |
|
done |
|
return $RT |
|
} |
|
|
|
ssh_agent_dry() { |
|
# (string... keys) |
|
ssh_agent false "$@" |
|
} |
|
|
|
ssh_agent_begin() { |
|
# (string... keys) |
|
ssh_agent true "$@" |
|
} |
|
|
|
ssh_agent_end() { |
|
# (void) |
|
$PRIVATE_SSH_AGENT && private_ssh_agent_stop |
|
} |
|
|
|
|