diff --git a/shrc/zshrc b/shrc/zshrc index d8f107f..621e7a6 100755 --- a/shrc/zshrc +++ b/shrc/zshrc @@ -32,6 +32,7 @@ zstyle :compinstall filename '/home/salt/.zshrc' autoload -Uz compinit compinit compdef _git dot +compdef _ssh ssht # The prompt autoload -Uz promptinit diff --git a/ssht b/ssht new file mode 100755 index 0000000..95fbbd2 --- /dev/null +++ b/ssht @@ -0,0 +1,90 @@ +#! /usr/bin/env bash +# +# ssht +# Copyright (C) 2018 salt +# +# Distributed under terms of the MIT license. +# + +name="$(basename $0 .sh)" + +# $1: Message +function log() { + [ -z ${1+x} ] && return 1 + printf "\e[94m$name\e[0m: $*\n" +} + +# $1: Binary in $PATH +function check_program_exists() { + if ! which $1 > /dev/null 2>&1; then + return 1 + fi + return 0 +} + +function get_tor_port() { + for port in 9050 9051 9150 9151; do + if netstat -ntl | grep 127.0.0.1:"$port" > /dev/null 2>&1; then + export return="$port" + return 0 + fi + done + return 1 +} + +# $1: Tor Port +# $2: Host +# $*: Command +function ssh_through_tor() { + [ -z ${3+x} ] && return 1 + ssh -o ProxyCommand="nc -x 127.0.0.1:$1 \%h \%p" $2 ${*:3} +} + +# $1: Tor Port +# $2: Host +function get_ssh_ip() { + # Yes, this is bad and you could totally run it through an SSH tunnel + # to avoid the curl requirement on the remote host + # Yes, that would avoid an extraneous connection + # TODO: That, also add curl to the list of critical requirements + log "Checking if host $2 has curl" + if ssh_through_tor "$1" "$2" which curl > /dev/null 2>&1; then + log "Finding out host's IP through curl" + export return="$(ssh_through_tor $1 $2 curl -s http://whatismyip.akamai.com)" + return 0 + fi + # TODO: Add more identification methods + return 1 +} + +# $1: Host +# $*: Arguments to ssh +function main() { + if ! [[ "$1" == *.onion ]]; then + log "First argument must be a .onion address" + exit 1 + fi + for dep in ssh tor netstat nc; do + if ! check_program_exists "$dep"; then + log "Could not find critical dependency \"$dep\"" + exit 50 + fi + done + if ! get_tor_port; then + log "Tor is not running" + exit 51 + fi + torport="$return" + log "Found Tor listening on local port $torport" + if ! get_ssh_ip $torport $1; then + log "Failed to determine target's public IP" + exit 52 + fi + ssh_ip="$return" + log "Found public IP: $ssh_ip" + unset return torport + exec ssh $ssh_ip ${*:2} +} + +main "$@" +