Skip to content

Instantly share code, notes, and snippets.

@mochipon
Last active January 13, 2017 09:21
Show Gist options
  • Save mochipon/6a67bb5e4108ab1f27a545350ccfa4d9 to your computer and use it in GitHub Desktop.
Save mochipon/6a67bb5e4108ab1f27a545350ccfa4d9 to your computer and use it in GitHub Desktop.
The traditional method of automating telnet sessions meets macOS Keychain
#!/bin/sh
#### This script enables automated telnet login using macOS Keychain.
#### In addition, automatically entering privilege EXEC mode is available.
####
#### Copyright (c) 2017 Masaki Tagawa
#### Released under the MIT license
#### http://opensource.org/licenses/mit-license.php
set -ef -o pipefail
PROGNAME=$(basename $0)
function usage() {
echo "Usage: ${PROGNAME} [OPTIONS] [user@]host [port]"
echo
echo "Options:"
echo " -h, --help"
echo " -k, --disable-keychain Disable Keychain integration"
echo " -l user"
echo " -u, --update Update Username and Password on Keychain"
}
function get_passwords() {
# First, check whether the enable password is stored.
if security find-generic-password -s ${host}:${port} -a enable 1>/dev/null 2>&1; then
enablepass=`security find-generic-password -s ${host}:${port} -a enable -w`
fi
if [ ! -z ${username} ]; then
# Check whether the login password is stored for specific user.
if security find-generic-password -s ${host}:${port} -a ${username} 1>/dev/null 2>&1; then
loginpass=`security find-generic-password -s ${host}:${port} -a ${username} -w`
else
echo "${PROGNAME}: the login password is not stored in Keychain." 1>&2
fi
else
if security find-generic-password -s ${host}:${port} -a login 1>/dev/null 2>&1; then
loginpass=`security find-generic-password -s ${host}:${port} -a login -w`
fi
fi
return 0
}
function connect_telnet() {
# We cannot use heredoc.
# ref. http://stackoverflow.com/questions/33026478/keeping-alive-a-ssh-session-with-a-script-bash-expect
expect -c "
set timeout 30
spawn telnet ${host} ${port}
expect {
timeout { send_user \"\nTimeout Exceeded - Check Host\n\"; exit 1 }
eof { send_user \"\nSSH Connection To ${host} Failed\n\"; exit 1 }
\"*sername\" {
if { \"${flag_disable_keychain}\" != \"true\" } {
if { \"${flag_update}\" == \"true\" || \"${username}\" == \"\" } {
expect_user -re \"(.*)\n\"
set username \$expect_out(1,string)
send -- \"\$username\r\"
exp_continue
} else {
send -- \"${username}\r\"; exp_continue
}
}
}
\"*assword\" {
if { \"${flag_disable_keychain}\" != \"true\" } {
if { \"${flag_update}\" == \"true\" || \"${loginpass}\" == \"\" } {
stty -echo
expect_user -re \"(.*)\n\"
set loginpass \$expect_out(1,string)
if { \$username == \"\" } { set username \"${username}\" }
if { \$username == \"\" } { set username login }
catch {exec security delete-generic-password -s ${host}:${port} -a \$username}
catch {exec security add-generic-password -s ${host}:${port} -a \$username -w \$loginpass}
send -- \"\$loginpass\r\"
stty echo
exp_continue
} else {
send -- \"${loginpass}\r\"; exp_continue
}
}
}
\"*>\" {
if { \"${flag_disable_keychain}\" != \"true\" } {
send \"enable\n\"
expect \"*assword\"
if { \"${flag_update}\" == \"true\" || \"${enablepass}\" == \"\" } {
stty -echo
expect_user -re \"(.*)\n\"
set enablepass \$expect_out(1,string)
catch {exec security delete-generic-password -s ${host}:${port} -a enable}
catch {exec security add-generic-password -s ${host}:${port} -a enable -w \$enablepass}
send -- \"\$enablepass\r\"
stty echo
exp_continue
} else {
send -- \"${enablepass}\r\"
}
}
}
\"*#\" { }
}
interact
"
}
# Default
flag_disable_keychain=false
flag_update=false
for OPT in "$@"
do
case "$OPT" in
'-h'|'--help' )
usage
exit 1
;;
'-l' )
if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]; then
echo "$PROGNAME: option requires an argument -- $1" 1>&2
exit 1 fi
username="$2"
shift 2
;;
'-k'|'--disable-keychain' )
flag_disable_keychain=true
shift 1
;;
'-u'|'--update' )
flag_update=true
shift 1
;;
'--'|'-' )
shift 1
param+=( "$@" )
break
;;
-*)
echo "${PROGNAME}: illegal option -- '$(echo $1 | sed 's/^-*//')'" 1>&2
exit 1
;;
*)
if [[ ! -z "$1" ]] && [[ ! "$1" =~ ^-+ ]]; then
param+=( "$1" )
host=${param[0]:-}
port=${param[1]:-}
# Perse "username@host"
if [[ "${host}" = *"@"* ]]; then
username=`echo ${host} | cut -d'@' -f1`
host=`echo ${host} | cut -d'@' -f2`
fi
# Default port is 23
if [ -z ${port} ]; then port=23; fi
shift 1
fi
;;
esac
done
if [ -z $param ]; then
echo "${PROGNAME}: too few arguments" 1>&2
echo "Try '${PROGNAME} --help' for more information." 1>&2
exit 1
fi
# Keychain Integration
if [ "${flag_disable_keychain}" != "true" ]; then
get_passwords
fi
# Start telnet with expect
connect_telnet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment