Skip to content

Instantly share code, notes, and snippets.

@nekwebdev
Last active August 21, 2022 22:23
Show Gist options
  • Save nekwebdev/eeb070f88344ce24506b0ceafabaeb4c to your computer and use it in GitHub Desktop.
Save nekwebdev/eeb070f88344ce24506b0ceafabaeb4c to your computer and use it in GitHub Desktop.
#!/bin/bash
############################################################################
## ██╗ ██████╗ █████╗ ███████╗███████╗ ███████╗███████╗██╗ ██╗ ##
## ██║ ██╔══██╗██╔══██╗██╔════╝██╔════╝ ██╔════╝██╔════╝██║ ██║ ##
## ██║ ██████╔╝███████║███████╗███████╗█████╗███████╗███████╗███████║ ##
## ██║ ██╔═══╝ ██╔══██║╚════██║╚════██║╚════╝╚════██║╚════██║██╔══██║ ##
## ███████╗██║ ██║ ██║███████║███████║ ███████║███████║██║ ██║ ##
## ╚══════╝╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚══════╝╚══════╝╚═╝ ╚═╝ ##
############################################################################
## Preparation:
## Create a secure SSH note in LastPass named: 'SSH: <key name>'
## Make sure the Passphrase and Private Key fields are correct
## Extra: Set LPASS_USER environment variable to your LastPass username
##
## You can also copy this script to the secure SSH note "notes" field
## Then use this command to download this script and run it
##
## Added the time option set to 8h in this example
##
## bash <(lpass show 'SSH: <key name>' --notes) <key name> -t 8
##
## Useful function for this command: lpass-ssh <key name> <time> (optional)
##
## lpass-ssh() {
## if [ -z ${2} ]; then 2=8 fi
## bash (lpass show 'SSH: $1' --notes) $1 -t $2
## }
##
## Fish shell version
##
## bash (lpass show 'SSH: <key name>' --notes | psub) <key name> -t 8
##
## Useful function for this command: lpass-ssh <key name> <time> (optional)
##
## function lpass-ssh --argument-names key_name time
## if test -z $time
## set time 8
## end
## bash (lpass show "SSH: $key_name" --notes | psub) $key_name -t $time
## end
##
############################################################################
# Display help screen
_display_help() {
echo " Preparation:"
echo " Create a secure SSH note in LastPass named: 'SSH: <key name>'."
echo " Make sure the Passphrase and Private Key fields are correct."
echo
echo " Usage:"
echo " lpass-ssh [-u | --user <username>] [-t | --time <hours>] (<key name>)"
echo " lpass-ssh [-h | --help]"
echo
echo " Options:"
echo " -h --help Show this screen."
echo " -u --user <username> Optional LastPass username."
echo " Will use LPASS_USER environment variable or prompt for it."
echo " -t --time <hours> Optional, defaults to 8 hours."
echo " Hours the ssh key will remain in the agent."
echo " <key name> LastPass will look for a secure note named SSH: <key name>."
echo
echo " The ssh key will be download and added to the agent for a set duration."
echo
echo " Once added the key is deleted from the drive."
echo
}
# ###########################################################################
# # Terminal output helpers
# ###########################################################################
# _echo_equals() outputs a line with =
# seq does not exist under OpenBSD
_echo_equals() {
COUNTER=0
while [ $COUNTER -lt "$1" ]; do
printf '='
(( COUNTER=COUNTER+1 ))
done
}
# _echo_title() outputs a title padded by =, in yellow.
_echo_title() {
TITLE=$1
NCOLS=$(tput cols)
NEQUALS=$(((NCOLS-${#TITLE})/2-1))
tput setaf 3 # 3 = yellow
_echo_equals "$NEQUALS"
printf " %s " "$TITLE"
_echo_equals "$NEQUALS"
tput sgr 0 0 # reset terminal
echo
}
# _echo_step() outputs a step collored in cyan, without outputing a newline.
_echo_step() {
tput setaf 6 # 6 = cyan
echo -n "$1"
tput sgr 0 0 # reset terminal
}
# _echo_step_info() outputs additional step info in cyan, without a newline.
_echo_step_info() {
tput setaf 6 # 6 = cyan
echo -n " ($1)"
tput sgr 0 0 # reset terminal
}
# _echo_right() outputs a string at the rightmost side of the screen.
_echo_right() {
TEXT=$1
echo
tput cuu1
tput cuf "$(tput cols)"
tput cub ${#TEXT}
echo "$TEXT"
}
# _echo_failure() outputs [ FAILED ] in red, at the rightmost side of the screen.
_echo_failure() {
tput setaf 1 # 1 = red
_echo_right "[ FAILED ]"
tput sgr 0 0 # reset terminal
}
# _echo_success() outputs [ OK ] in green, at the rightmost side of the screen.
_echo_success() {
tput setaf 2 # 2 = green
_echo_right "[ OK ]"
tput sgr 0 0 # reset terminal
}
# _echo_warning() outputs a message and [ WARNING ] in yellow, at the rightmost side of the screen.
_echo_warning() {
tput setaf 3 # 3 = yellow
_echo_right "[ WARNING ]"
tput sgr 0 0 # reset terminal
echo " ($1)"
}
# _exit_with_message() outputs and logs a message before exiting the script.
_exit_with_message() {
echo
echo "$1"
echo
exit 1
}
# _exit_with_failure() calls _echo_failure() and _exit_with_message().
_exit_with_failure() {
_echo_failure
_exit_with_message "FAILURE: $1" 1
}
# ################################################################################################
# # Main script
# ################################################################################################
# Parse the command arguments
ssh_key=""
while (( "$#" )); do
case "$1" in
-h|--help)
_display_help
exit 0
shift
;;
-u|--user)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
lpass_user=$2
shift 2
fi
;;
-k|--key)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
ssh_key=$2
shift 2
else
echo "Error: Argument for $1 is missing" >&2
exit 1
fi
;;
-t|--time)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
valid_for=$2
shift 2
fi
;;
-*|--*=) # unsupported flags
echo "Error: Unsupported flag $1" >&2
exit 1
;;
*) # preserve positional arguments
ssh_key="$ssh_key $1"
shift
;;
esac
done
# Require the key name argument
if [ -z "${ssh_key}" ]; then
_exit_with_failure "You need to specify a key name. lpass-ssh <key name>"
fi
# If this key is already in the agent we don't need to do anything
if ( ssh-add -l | grep -q "${ssh_key}" ); then
_exit_with_failure "Key already present."
fi
# Ensure we are logged into LastPass
_echo_step "LastPass login"
status=$(lpass status)
if [ $? -ne 0 ]
then
if [ "$status" = 'Not logged in.' ]
then
# Check for username argument
if [ -z "${lpass_user}" ]; then
# Check the environment variable
lpass_user=$LPASS_USER
if [ -z "${lpass_user}" ]; then
echo
_echo_step_info "Please enter your LastPass username:"
read lpass_user
fi
fi
# Make sure DISPLAY is set for some reason and log into lastpass
echo
_echo_step_info "Logging into LastPass as ${lpass_user}..."; echo
DISPLAY=${DISPLAY:-:0} lpass login "${lpass_user}" 1>&2
else
_exit_with_failure "Lastpass error: $status" 1>&2
fi
fi
_echo_success
# Check for time argument
if [ -z "${valid_for}" ]; then
valid_for=4
fi
# Set our environment variables
export DISPLAY=${DISPLAY:-:0}
export SSH_ASKPASS="/tmp/lpass-ssh-askpass"
lastpass_key="SSH: $(basename ${ssh_key})"
# Write our pass agent to disk
cat > /tmp/lpass-ssh-askpass <<EOF
#!/bin/sh
lpass show --field Passphrase "${lastpass_key}"
EOF
chmod +x /tmp/lpass-ssh-askpass
_echo_step "Adding Private Key '${ssh_key}' for ${valid_for}h";echo
# Fetch and add our pruvate key to the agent.
lpass show "${lastpass_key}" --field="Private Key" | setsid ssh-add -t "${valid_for}h" /dev/stdin
if ! [ $? -eq 0 ]; then
_exit_with_failure "Unable to get ssh key."
fi
_echo_success
# Clean up
rm -rf /tmp/lpass-ssh-askpass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment