#!/bin/bash

RDP_NAME="$1" ; shift 1
RDP_USER="$USER"
#RDP_PASSWORD=""
RDP_APP=""
#RDP_DOMAIN=""
RDP_DEBUG=""
RDP_USE_FILE=""

RDP_USER_PROMPT=""

DO_PRERESOLVE_HOST="y"

OPTION_PASSWORD=""
OPTION_APP=""
OPTION_DOMAIN=""
OPTION_SEC=""
OPTION_SIZE="" #"/dynamic-resolution"
OPTION_GUI="--gui"
OPTION_GUI_APPNAME=""
OPTION_PROMPT_PASS=""
OPTION_USERNAME=""
OPTION_CERT="/cert:auto"
OPTION_BPP="/bpp:15"
OPTION_AUTO_RECONNECT=""
OPTION_AUTO_RECONNECT_RETRIES=""
OPTION_ALLOW_NLA_REQUEST=""
OPTION_TLS_SECLEVEL=""
OPTION_RETRY_WITH_TOFU=""
OPTIONS_DRIVE=()

print_help() {
cat <<EOF
foxde-rdp is a wrapper around xfreerdp making it easier to work with in .desktop files and to bring remote, not always cooperating applications to your local linux desktop. Most options have a direct xfreerdp equivalent.

Usage: foxde-rdp [<user>@]<servername> <<options>>

RDP Options:

--user <user>
	Set the username for the connection, defaults to \$USER {/u:…}
	
--domain <domain>
	The domain to use for login {/d:…}

--app <application>
	Sometimes applications can be exported without any desktop {/app:||…}

--shell <shell>
	While deprected, this works quite well at exporting less cooperative applications. {/shell:||…}

--size <width>x<height>
	The viewport size in pixels to use for the connection {/size:…}
	if left unset and no --app or --shell is specified {/dynamic-resolution} will be set
	if set to dynamic the {/dynamic-resolution} flag will always be set

--bpp <bits>
	Sets the color depth {/bpp:…}, default 15

--auto-reconnect <n>
	Will attempt to automatically reconnect up to n times.
	{+auto-reconnect /auto-reconnect-max-retries:…}

--drive <name> <path>
	Pass a filepath on to the remote {/drive:…,…}
	
Security Options:

--sec <sec>
	Which security protocol to use {/sec:…}
	
--sec-no-nla
	Disables nla using the {-sec-nla} for getting a unauthenticated
	session, i.e. for password resets.
	Incompatible with the --sec option.

--cert <mode>
	Which method to use for validating the certificate, default is tofu {/cert:…}
	Use the value ca to indicate that the default validation by trusted CAs should happen

--old-tls
	Makes you able to connect to very old TLS setups, this is not secure.
	{/tls-seclevel:0}
	         
--pass <password>
	Set the password for the rdp connection {/p:…}
	WARNING: If you set the password this way is will be visible to other processes!
	         Do not use unless you know what you are doing!

Wrapper Options:

--user-prompt
	Spawn a kdialog to ask the user for their username, prefilled with whatever is given using --user or \$USER

--pass-prompt
	Spawn a kdialog asking the user for their password.

--allow-nla-request
	If the server requests an unauthenticated connection
	(i.e. for resetting a password) ask the user.

--no-preresolve
	Do not attempt to get the full hotname through DNS-Resolution before connecting.
	(Enabled by default to help with recognizing certificates)

Options:

--debug
	Currently only waits 10 Seconds before exiting to get the chance to at least take a screenshot of an autoclosing terminal.

--help
	Displays this helptext.


EOF
}

case "$RDP_NAME" in
	--help)
		print_help
		exit 0 ;;
	"")
		print_help
		exit 1 ;;
	*@*)
		RDP_USER="$( printf "%s" "$RDP_NAME" | cut -d@ -f 1)"
		RDP_NAME="$( printf "%s" "$RDP_NAME" | cut -d@ -f 2)"
		;;
esac

set -e

while [ "$#" -gt 0 ]; do
  case "$1" in
    --user) RDP_USER="$2"; OPTION_USERNAME="/u:$2"; shift 2;;
    --pass)
	    #RDP_PASSWORD="$2";
	    OPTION_PASSWORD="/p:$2"
		OPTION_PROMPT_PASS="--no-pass-prompt"
	    shift 2;;
    --app) RDP_APP="$2"; OPTION_APP="/app:||'$2'"; shift 2;;
    --shell) RDP_APP="$2"; OPTION_APP="/shell:||'$2'"; shift 2;;
    --domain)
	    #RDP_DOMAIN="$2";
	    OPTION_DOMAIN="/d:$2";
	    shift 2;;
    --sec) OPTION_SEC="/sec:$2"; shift 2;;
    --sec-no-nla) OPTION_SEC="-sec-nla"; shift 1;;
    --cert) OPTION_CERT="/cert:$2"; shift 2;;
    --debug) RDP_DEBUG="y"; shift 1;;
    --is-rdp-file) RDP_USE_FILE="y"; shift 1;;
    --pass-prompt) OPTION_PROMPT_PASS=""; shift 1;;
    --no-pass-prompt) OPTION_PROMPT_PASS="--no-pass-prompt"; shift 1;;
    --user-prompt) RDP_USER_PROMPT="yes"; shift 1;;
    --allow-nla-request) OPTION_ALLOW_NLA_REQUEST="--allow-nla-request"; shift 1;;
    --size) OPTION_SIZE="/size:$2"; shift 2;;
    --bpp) OPTION_BPP="/bpp:$2"; shift 2;;
    --auto-reconnect)
	    OPTION_AUTO_RECONNECT="+auto-reconnect";
	    OPTION_AUTO_RECONNECT_RETRIES="/auto-reconnect-max-retries:$2";
	    shift 2;;
	--old-tls) OPTION_TLS_SECLEVEL="/tls-seclevel:0"; shift 1;;
	--no-preresolve) DO_PRERESOLVE_HOST=""; shift 1;;
	--drive)
		OPTIONS_DRIVE+=("/drive:$2,$3")
		shift 3;;
    --help) print_help; exit 0;;

    *) printf "Unknown option: %s\nUse --help to see what this script can do.\n" "$1" >&2; exit 1;;
  esac
done

set +e

if [ -n "$DO_PRERESOLVE_HOST" ] ; then
	OLD_NAME="$RDP_NAME"
	RDP_NAME="$(host "$RDP_NAME" | grep " has address " | cut -d' ' -f1)"
	if [ -z "$RDP_NAME" ] ; then
		echo "Warning: Pre-DNS-Resolving the hostname »$OLD_NAME« failed." >&2
		echo "Host is likely to be unreachable or certificate checks may fail." >&2
		echo "Use --no-preresolve to turn preresolution off." >&2
		RDP_NAME="$OLD_NAME"
	fi
	unset OLD_NAME
fi

case "$OPTION_CERT" in
	/cert:auto)
		if awk -v"host=$RDP_NAME" 'BEGIN { n=1 } $1==host { n=0; exit } END { exit n }' < ~/.config/freerdp/known_hosts2 ; then
			# Use tofu if in known hosts
			OPTION_CERT="/cert:tofu"
		else
			# Use ca auth by default and fall back to tofu otherwise
			OPTION_CERT=""
			OPTION_RETRY_WITH_TOFU="--retry-with-tofu"
		fi
		;;
	/cert:ca)
		OPTION_CERT=""
		;;
esac

if [ "$USER" = "$RDP_USER" ] && grep -iq autologin <<< "$RDP_USER" ; then
	RDP_USER_PROMPT=yes
fi

if [ -z "$RDP_APP" ] && [ -z "$OPTION_SIZE" ] || [ "_$OPTION_SIZE" = "_/size:dynamic" ]; then
	OPTION_SIZE="/dynamic-resolution"
fi

if [ -n "$RDP_USER_PROMPT" ] ; then
	RDP_USER="$(kdialog --title "Remotedesktopverbindung" --inputbox "Nutzername für $RDP_NAME:" "$RDP_USER")"
	if [ -z "$RDP_USER" ] ; then
		exit 130
	fi
	OPTION_USERNAME="/u:$RDP_USER"
fi

if [[ -n "$OPTION_GUI" ]] ; then
	OPTION_GUI_APPNAME="$RDP_USER@$RDP_NAME"
fi

function push_arg() {
	if [ -n "$1" ] ; then
		arguments+=("$1")
	fi
}

function connect() {
	arguments=()
	push_arg "$OPTION_GUI"
	push_arg "$OPTION_GUI_APPNAME"
	push_arg "$OPTION_PROMPT_PASS"

	if [ -z "$RDP_USE_FILE" ] ; then
		push_arg "$OPTION_ALLOW_NLA_REQUEST"
		push_arg "$OPTION_RETRY_WITH_TOFU"
		push_arg "--"
		push_arg "$OPTION_CERT"
		push_arg "$OPTION_AUTO_RECONNECT"
		push_arg "$OPTION_AUTO_RECONNECT_RETRIES"
		push_arg "+clipboard"
		push_arg "$OPTION_BPP"
		push_arg "/compression"
		push_arg "$OPTION_SIZE"
		push_arg "$OPTION_SEC"
		push_arg "$OPTION_TLS_SECLEVEL"
		push_arg "$OPTION_PASSWORD"
		push_arg "$OPTION_APP"
		push_arg "$OPTION_DOMAIN"
		push_arg "/u:$RDP_USER"
		push_arg "/v:$RDP_NAME"
		arguments+=("${OPTIONS_DRIVE[@]}")
	else
		push_arg "--"
		push_arg "/usr/share/rdp/$RDP_NAME.rdp"
		push_arg "$OPTION_USERNAME"
	fi
	echo "calling foxde-xfreerdp-gui" "${arguments[@]}"
	foxde-xfreerdp-gui "${arguments[@]}"
	ECODE=$?
}

connect

echo "Helper exited with code: $ECODE"

case "$ECODE" in
	101)
		# NLA reequest + password expired
		if [ -n "$OPTION_ALLOW_NLA_REQUEST" ] ; then
			if kdialog --title "(RDP) Passwort abgelaufen" --warningcontinuecancel "Dein Passwort ist abgelaufen. Der Server bietet eine Sitzung an mit der sich das Passwort neu setzen lassen sollte.<br><br>Wenn das nicht funktioniert oder du das nicht erwartet hast kontaktiere bitte die IT-Abteilung." --continue-label "Trotzdem verbinden" --cancel-label "Ich melde mich bei der IT" ; then
				OPTION_SEC="-sec-nla"
				OPTION_ALLOW_NLA_REQUEST=""
				OPTION_PROMPT_PASS="--no-pass-prompt"
				connect
			fi
		fi
	;;
	102)
		# No NLA request
		if [ -n "$OPTION_ALLOW_NLA_REQUEST" ] ; then
			if kdialog --title "(RDP) No-NLA Request" --warningcontinuecancel "Der Server hat deine Logindaten nicht angenommen." --continue-label "Trotzdem verbinden" --cancel-label "Ich melde mich bei der IT" ; then
				OPTION_SEC="-sec-nla"
				OPTION_ALLOW_NLA_REQUEST=""
				OPTION_PROMPT_PASS="--no-pass-prompt"
				connect
			fi
		fi
	;;
	103)
		# Enable NLA request
		if [ -n "$OPTION_ALLOW_NLA_REQUEST" ] ; then
			if kdialog --title "(RDP) Enable NLA Request" --warningcontinuecancel "Der Server möchte das NLA Protokoll für die Verbindung verwenden (das ist gut!) aber es wurde '${OPTION_SEC:-Standardeinstellung}' konfiguriert.<br><br>Bitte leite diese Information an die IT-Abteilung weiter." --continue-label "Mit NLA verbinden" --cancel-label "Abbrechen" ; then
				OPTION_SEC="/sec:nla"
				OPTION_ALLOW_NLA_REQUEST=""
				connect
			fi
		fi
	;;
esac

[ -n "$RDP_DEBUG" ] && sleep 10
