mirror of
https://github.com/ssb22/bits-and-bobs.git
synced 2023-06-08 10:22:44 +00:00
92 lines
3.2 KiB
Bash
92 lines
3.2 KiB
Bash
#!/usr/bin/env expect --
|
|
# -*- mode: shell-script -*-
|
|
|
|
# Mac and Linux script to SSH to a host via Android adb
|
|
# with SOCKS port-forwarding and decent terminal settings
|
|
# (Linux users: remove the '--' on the first line above)
|
|
|
|
# Silas S. Brown 2014-2015, 2019, public domain, no warranty
|
|
|
|
# Where to find history:
|
|
# on GitHub at https://github.com/ssb22/bits-and-bobs
|
|
# and on GitLab at https://gitlab.com/ssb22/bits-and-bobs
|
|
# and on BitBucket https://bitbucket.org/ssb22/bits-and-bobs
|
|
# and at https://gitlab.developers.cam.ac.uk/ssb22/bits-and-bobs
|
|
# and in China: https://gitee.com/ssb22/bits-and-bobs
|
|
|
|
# Assumes ~/.ssh/known_hosts already has the host you're
|
|
# trying to connect to. (If it doesn't, you might need to
|
|
# add code to recognise the fingerprint and answer yes.)
|
|
|
|
# You'll need to set the following:
|
|
# The path to your adb binary:
|
|
set ADB_PATH /usr/local/adt-bundle/sdk/platform-tools/adb
|
|
# The port number of the local SOCKS port to set up
|
|
# (10080 is the default port number for dsocks, which
|
|
# might be useful)
|
|
set SOCKS_PORT 10080
|
|
|
|
# --------------------------------------------------------
|
|
|
|
if {$argc == 0} {
|
|
send_user "Syntax: $argv0 \[-l user\] host\n"
|
|
send_user "(do not add a command)\n"
|
|
exit 1
|
|
}
|
|
|
|
set timeout -1
|
|
|
|
# Read the user ID from 'whoami' for -l option. If the
|
|
# user supplies a -l option as well, it'll override this.
|
|
spawn /usr/bin/whoami
|
|
expect -re "(.*)\r"
|
|
set USER "$expect_out(1,string)"
|
|
|
|
# Now start the ADB stuff:
|
|
send_user "Getting an ADB shell...\n"
|
|
spawn "$ADB_PATH" -d shell
|
|
expect {
|
|
"device not found" {exit 1}
|
|
"$ "
|
|
}
|
|
send_user "Sending known_hosts to Android...\n"
|
|
system "$ADB_PATH" -d push ~/.ssh/known_hosts /storage/emulated/legacy/known_hosts
|
|
send_user "Starting SSH...\n"
|
|
send "ssh -D $SOCKS_PORT -C -o UserKnownHostsFile=/storage/emulated/legacy/known_hosts -l $USER $argv \"/bin/bash -c 'echo waiting...;read'\"\r"
|
|
# (we do a 'read' rather than just have the prompt so that
|
|
# (1) it doesn't matter what the prompt is, (2) the local
|
|
# user is not confused by this non-interactive prompt)
|
|
expect assword:
|
|
stty -echo
|
|
expect_user -re "(.*)\n"
|
|
stty echo
|
|
set the_password "$expect_out(1,string)"
|
|
send_user "\nRemoving known_hosts from Android...\n"
|
|
system "$ADB_PATH" -d shell rm -f /storage/emulated/legacy/known_hosts
|
|
send_user "Sending password...\n"
|
|
send "$the_password\r"
|
|
expect "waiting..."
|
|
send_user "Completing the port forwarding...\n"
|
|
system "$ADB_PATH" -d forward tcp:$SOCKS_PORT tcp:$SOCKS_PORT
|
|
send_user "Spawning a local ssh...\n"
|
|
set old_id $spawn_id
|
|
spawn /bin/bash -c "ssh -o IdentityFile=/not/exist -o ProxyCommand='`which nc` -x localhost:$SOCKS_PORT %h %p' $argv"
|
|
# (using IdentityFile=/not/exist to force password so the following 'expect assword:' always works; could also use expect { ... } with some other string e.g. "Last login" as an alternative)
|
|
trap {
|
|
set rows [stty rows]
|
|
set cols [stty columns]
|
|
stty rows $rows columns $cols < $spawn_out(slave,name)
|
|
} WINCH
|
|
expect assword:
|
|
send_user "(sending password)\n"
|
|
send_user "SOCKS port is localhost:$SOCKS_PORT; will be closed when this session exits"
|
|
send "$the_password\r"
|
|
interact
|
|
set spawn_id $old_id
|
|
send_user "Shutting down Android SSH connection...\n"
|
|
send "exit\r"
|
|
expect "$ "
|
|
system "$ADB_PATH" -d forward --remove tcp:$SOCKS_PORT
|
|
send "exit\r"
|
|
send_user "Finished\n"
|