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.
112 lines
2.6 KiB
112 lines
2.6 KiB
10 years ago
|
#!/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
|
||
|
}
|
||
|
|