Last active
January 13, 2017 09:21
-
-
Save mochipon/6a67bb5e4108ab1f27a545350ccfa4d9 to your computer and use it in GitHub Desktop.
The traditional method of automating telnet sessions meets macOS Keychain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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