#! /usr/bin/env bash
#
# ssht
# Copyright (C) 2018 salt <salt@lap-th-e560-0>
#
# 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 "$@"