#! /bin/bash
# SSH identifyer: This file has been generated automatically by SSH version  29 july 2020-rev 0 on mercredi 29 juillet 2020, 19:14:12 (UTC+0200) on vreferee
# SSH is available at http://download.sisalp.net/scripts/SSH
# license gpl V3
# Author Dominique Chabord SISalp https://sisalp.fr
# dominique.chabord@sisalp.org
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#==========================================
# specific values
CreationDate="mercredi 29 juillet 2020, 19:14:12 (UTC+0200)"
Generator="SSH version  29 july 2020-rev 0"
ScriptConf=" /usr/local/etc/SSH/backup.conf"
if [ ! -d /usr/local/etc/SSH ] ; then
	echo "$LINENO Configuration directory  /usr/local/etc/SSH is not found"
	case `whoami` in
	root)
		mkdir /usr/local/etc/SSH
		echo "$LINENO Configuration directory  /usr/local/etc/SSH is created"
		;;
	esac	
fi
if [ -f  $ScriptConf ] ; then
	.  $ScriptConf
else
	echo "$LINENO Configuration file  $ScriptConf is not found"
	case `whoami` in
	root)
		cd /usr/local/etc/SSH
		if wget -q http://download.sisalp.net/scripts/backup.conf ; then
			echo "$LINENO Configuration file  $ScriptConf is downloaded"
		else
			echo "$LINENO Configuration file  $ScriptConf could not be downloaded"
		fi
		;;
	esac
	exit $LINENO
fi
#-------------------------------------------------------------------------
CHECK_GET_NOT_EMPTY ()
#-------------------------------------------------------------------------
{
QUESTION="$1"
shift
RESULT="$*"
if [ -z "$RESULT" ] ; then
	echo -n "$QUESTION : "
	read RESULT
	if [ -z "$RESULT" ] ; then
		echo "$LINENO $QUESTION is mandatory"
		exit $LINENO
	fi
fi
}
#-------------------------------------------------------------------------
CHECK_GET_DEFAULT ()
#-------------------------------------------------------------------------
{
QUESTION="$1"
shift
RESULT="$1"
shift
if [ "${RESULT}" = ":" ] ; then
	RESULT=""
else
	shift
fi
default_result="$*"
if [ -z "$RESULT" ] ; then
	echo -n "$LINENO| $QUESTION, default is <$default_result> : "
	read RESULT
fi
case "$RESULT" in
Y|y|o|O)
	echo "$LINENO| $QUESTION is set to default value $default_result"
	RESULT="$default_result"
	;;
esac
if [ -z "$RESULT" ] ; then
	echo -cv "$LINENO| $QUESTION is set to default value $default_result"
	RESULT="$default_result"
fi
}
#-------------------------------------------------------------------------
CHECK_LAN_OR_WAN ()
#-------------------------------------------------------------------------
{
remote_server="$RemoteHost"
remote_port="$RemotePort"
case "$RemoteFqdn" in
-)
	;;
*)
	echo -n "Checking local availability of $RemoteHost ..."
	if ! ping -c 1 $RemoteHost > /dev/null 2>&1 ; then
		remote_server="$RemoteFqdn"
		remote_port="$RemoteFqdnPort"
		echo "........Not responding"
		echo -n "Connect to $RemoteUser@$RemoteFqdn -p $RemoteFqdnPort is tried instead ..."
		if ! ping -c 1 $RemoteFqdn > /dev/null 2>&1 ; then
			echo "........Not responding either"
			return 1
		else
			echo "..OK"
		fi
	else
		echo "..OK"
	fi
esac
}
#-------------------------------------------------------------------------
CHECK_LOCAL_IP ()
#-------------------------------------------------------------------------
{
case "$RemoteIp" in
-)
	;;
[0-9]*)
	if ! cat /etc/hosts | grep -v "^#" | grep -qw "$RemoteHost" ; then
		case `whoami` in
		root)
			echo "$RemoteIp $RemoteHost" >> /etc/hosts
			echo "$RemoteIp $RemoteHost has been added to /etc/hosts"
			;;
		*)
			echo "$RemoteIp $RemoteHost is not found in to /etc/hosts, consider $0 --help as root to add it"
			exit $LINENO
			;;
		esac
	fi
	;;
esac
}
#-------------------------------------------------------------------------
CHECK_LOCAL_IP
RemoteCommand="$*"
COMMAND="$1"
shift
case "$COMMAND" in
-h|help|--help)
	$MyScriptName --version
	echo "Syntax of $MyScriptName command
Missing parameters are prompted

$MyScriptName -h|help|--help
	Print this documentation

$MyScriptName
	Connect to ssh $RemoteUser@$RemoteHost -p $RemotePort

$MyScriptName command
	Execute command to ssh $RemoteUser@$RemoteHost -p $RemotePort command
"
	case "$RemoteFqdn" in
	-)
		;;
	*)
		echo "If $RemoteHost doesn't respond to ping, $RemoteUser@$RemoteFqdn -p $RemoteFqdnPort will be tried instead"
		;;
	esac
	echo "
Other options:
--------------
$MyScriptName -c|check|--check
	Check password-less connection effectiveness, print ok or failure

$MyScriptName -cv|check_verbose|--check_verbose
	Check password-less connection effectiveness, configuration and print messages

$MyScriptName -cvv|check_very_verbose|--check_very_verbose
	Check password-less connection effectiveness, configuration and print debug messages

$MyScriptName -d|delete|--delete
	Delete $MyScriptName if remote server is not reachable

$MyScriptName -df|delete-force|--delete-force
	Delete $MyScriptName

$MyScriptName -k|keys|--keys
	Exchange keys for password-less connection to $RemoteUser account

$MyScriptName -kr|keys-root|--keys-root
	Exchange keys for password-less connection to root account

$MyScriptName -p|purge|--purge
	Delete $MyScriptName and its SSH generator data if remote server is not reachable

$MyScriptName -pf|purge-force|--purge-force
	Delete $MyScriptName and its SSH generator data

$MyScriptName -r|root|--root
	Connect to ssh root@$RemoteHost -p $RemotePort or alternate remote target

$MyScriptName -t|tunnel|--tunnel local_port [remote_port [remote_ip]]
	Create a tunnel from port local_port to remote_ip:remote_port on connection $RemoteUser@$RemoteHost port $RemotePort

$MyScriptName -u|update|--update http://download_url
	Update $MyScriptName from download_url

$MyScriptName -v|version|--version
	Print version of $MyScriptName command


==============================================="
	echo ""
	;;
-c|check|--check)
	CHECK_LAN_OR_WAN	> /dev/null
	if ssh $RemoteUser@$remote_server -p $remote_port ls > /dev/null ; then
		echo "ok"
		exit 0
	else
		echo "failure"
		exit $LINENO
	fi
	;;
-cv|check_verbose|--check_verbose)
	echo "connection parameters in  $ScriptConf"
	cat  $ScriptConf
	echo "$MyScriptName version $CreationDate on $HostName generated by $Generator"
	CHECK_LAN_OR_WAN
	echo "Connect to ssh $RemoteUser@$remote_server -p $remote_port and list home directory"
	if ssh $RemoteUser@$remote_server -p $remote_port ls ; then
		echo "ssh return code :	ok"
		echo "Closed connection to ssh $RemoteUser@$remote_server -p $remote_port"
		exit 0
	else
		echo "ssh return code :	failure"
		echo "Closed connection to ssh $RemoteUser@$remote_server -p $remote_port"
		exit $LINENO
	fi
	;;
-cvv|check_very_verbose|--check_very_verbose)
	echo "connection parameters"
	cat  $ScriptConf
	echo "$MyScriptName version $CreationDate on $HostName generated by $Generator"
	CHECK_LAN_OR_WAN
	echo "Connect to ssh $RemoteUser@$remote_server -p $remote_port and list home directory"
	if ssh -vvv $RemoteUser@$remote_server -p $remote_port ls ; then
		echo "ssh return code :	ok"
		echo "Closed connection to ssh $RemoteUser@$remote_server -p $remote_port"
		exit 0
	else
		echo "ssh return code :	failure"
		echo "Closed connection to ssh $RemoteUser@$remote_server -p $remote_port"
		exit $LINENO
	fi
	;;
-d|delete|--delete|-p|purge|--purge|-df|delete-force|--delete-force|-pf|purge-force|--purge-force)
DELETE ()
{
case `whoami` in
root)
	echo "Failed to reach remote server, $0 is deleted"
	echo "rm $0"
	rm $0
	echo "rm -f /usr/local/etc/SSH/$MyScriptName.conf"
	rm -f /usr/local/etc/SSH/$MyScriptName.conf
	case "$COMMAND" in
	-p|purge|--purge|-pf|purge-force|--purge-force)
		echo "Remove also SSH generator data"
		SSH --forget $MyScriptName
		;;
	esac
	;;
*)
	echo "Failed to delete $0, you must be root"
	;;
esac
}
	case "$COMMAND" in
	-df|-pf|*-force)
		DELETE
		;;
	*)
		if ! CHECK_LAN_OR_WAN ; then
			DELETE
		else
			echo "Succeeded in reaching remote server, $0 is not deleted"
		fi
		;;
	esac
	;;

-k|keys|--keys|-kr|keys-root|--keys-root)
	echo "Command keys $COMMAND"
	if ! expect -v > /dev/null 2>&1 ; then
		echo "programme expect must be installed : apt-get install expect; nothing done"
		exit $LINENO
	fi
	echo "$MyScriptName version $CreationDate on $HostName generated by $Generator"
	case "$COMMAND" in
	-kr|keys-root|--keys-root)
		remote_user="root"
		;;
	*)
		remote_user="$RemoteUser"
		;;
	esac
	if [ ! -f $HOME/.ssh/id_rsa.pub ]
	then
		echo "SSH configuration"
		ssh-keygen -t rsa -N "" -f $HOME/.ssh/id_rsa
		echo "Generation of the key done"
	fi
	CHECK_LAN_OR_WAN
	echo -n "Provide once $remote_user@$remote_server -p $remote_port password : "
	read -s remote_password
	echo "controle de l existence du repertoire .ssh sur la cible"
expect -c "set timeout -1;\
spawn ssh $remote_user@$remote_server -p $remote_port \"mkdir .ssh > /dev/null 2>&1\";\
expect *password:*;\
send -- $remote_password\r;\
interact;"
	#ssh $remote_user@$remote_server -p $remote_port "mkdir .ssh > /dev/null 2>&1"
	echo "scp -P $remote_port $HOME/.ssh/id_rsa.pub $remote_user@$remote_server:/tmp/SSH.$RemoteUser.$HostName.key.pub"
expect -c "set timeout -1;\
spawn scp -P $remote_port $HOME/.ssh/id_rsa.pub $remote_user@$remote_server:/tmp/SSH.$remote_user.$HostName.key.pub;expect *password:*;\
send -- $remote_password\r;\
interact;"
	#scp -P $remote_port $HOME/.ssh/id_rsa.pub $remote_user@$remote_server:/tmp/SSH.$remote_user.$HostName.key.pub
	echo "ssh $remote_user@$remote_server -p $remote_port cat /tmp/SSH.$remote_user.$HostName.key.pub >> .ssh/authorized_keys"

expect -c "set timeout -1;\
spawn ssh $remote_user@$remote_server -p $remote_port \"cat /tmp/SSH.$remote_user.$HostName.key.pub >> .ssh/authorized_keys\";expect *password:*;\
send -- $remote_password\r;\
interact;"
	#ssh $remote_user@$remote_server -p $remote_port \"cat /tmp/SSH.$remote_user.$HostName.key.pub >> .ssh/authorized_keys\"
	echo "`whoami` can connect now to $remote_user @ $remote_server without password"
	;;
-r|root|--root)
	echo "$MyScriptName version $CreationDate on $HostName generated by $Generator"
	CHECK_LAN_OR_WAN

	echo "Connect to ssh root@$remote_server -p $remote_port"
	ssh root@$remote_server -p $remote_port
	;;
-t|tunnel|--tunnel)
	echo "$MyScriptName version $CreationDate on $HostName generated by $Generator"
	CHECK_LAN_OR_WAN
	CHECK_GET_NOT_EMPTY "Local port" $1
	LOCAL_PORT="$RESULT"
	CHECK_GET_DEFAULT "Remote port" $2 : $LOCAL_PORT
	REMOTE_PORT="$RESULT"
	CHECK_GET_DEFAULT "Remote ip" $3 : localhost
	REMOTE_IP="$RESULT"
	echo "Create a tunnel from port $LOCAL_PORT to :$REMOTE_IP:$REMOTE_PORT on connection $RemoteUser@$remote_server port $remote_port"
	ssh -L $LOCAL_PORT:$REMOTE_IP:$REMOTE_PORT $RemoteUser@$remote_server -p $remote_port
	echo "Closed tunnel from port $LOCAL_PORT to :$REMOTE_IP:$REMOTE_PORT on connection $RemoteUser@$remote_server port $remote_port"
	;;
-u|update|--update)
	case `whoami` in
	root)
		cd /usr/local/bin
		mv $0 $0.previous_version
		if wget -q $DownloadUrl ; then
			diff $0.previous_version $0
			chmod 755 $0
			$0 --version
		else
			echo "Failure why downloading wget -q $DownloadUrl "
			mv $0.previous_version $0
			
		fi
		;;
	*)
		echo "You must be root to update"
		;;
	esac
	;;
-v|version|--version)
	echo "$MyScriptName version $CreationDate on $HostName generated by $Generator"
	;;
*)
	echo "$MyScriptName version $CreationDate on $HostName generated by $Generator"
	CHECK_LAN_OR_WAN
	echo "Connect to ssh $RemoteUser@$remote_server -p $remote_port $RemoteCommand"
	ssh $RemoteUser@$remote_server -p $remote_port $RemoteCommand
	echo "Closed connection to ssh $RemoteUser@$remote_server -p $remote_port"
	;;
esac
exit 0
