#!/usr/bin/env bash
#
# Author: Dmitry Razumov <asmeron@ublinux.com>
# Copyright (c) 2021-2025 UBLinux <support@ublinux.com>
#

ENABLED=yes
[[ ${ENABLED} == yes ]] || exit 0
DEBUGMODE=no

SOURCE=/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null  || exit 0
SOURCE=/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null  || exit 0
debug_mode "$0" "$@"

SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/desktop; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null

FILE_ROOT_USERS="${SYSCONF}/.users_credential"
SOURCE=${FILE_ROOT_USERS}; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null

## Сервис удалённого управления рабочим столом X11 и TTY
## Поддерживает Multiseat по номеру порта display:0=port:5900 display:1=port:5901 display:2=port:5902
## X11VNC[password]=<hash_password>
##   <hash_password><--># Пароль кодировать в base64: echo 'ublinux' | base64
##			# Пароль для VNC сервиса x11vnc-ublinux:*.service. Настроен на работу только по паролю для всех рабочих мест.
##			# Создаёт шифрованный пароль в файле /root/.vnc/.passwd
## X11VNC[password]=dWJsaW51eAo=

## Дополнительные опции к автоматическому соединению https://manpages.ubuntu.com/manpages/lunar/en/man1/x11vnc.1.html
## X11VNC[options]="<options> <options> <options>"
##   <options>		# Дополнительные опции перечисленные через пробел
##     -noipv6		#
##     -ultrafilexfer	# Включите расширение передачи файлов UltraVNC
##     -tightfilexfer	# Включите расширение передачи файлов TightVNC
##     -xkb		# Если копирование и вставка не работают должным образом с буфером обмена
##     -ssl [pem]
##       [pem]=file_pem
##       [pem]=SAVE
##       [pem]=ANON	# Аноним Диффи-Хеллмана используется метод обмена ключами, без SSL
##       [pem]=TMP
##     -unixpw		# Чтобы работало, должна быть установлена переменная UNIXPW_DISABLE_SSL=1
##     -users unixpw=
##     -xdummy
##     -avahi		# Используйте протокол Avahi/mDNS ZeroConf для объявления этого VNC-сервера на локальном компьютере в сеть

## VNC для управления TTY
## X11VNC[tty1]="-noipv6"

## Пользовательская настройка запуска, new_1..new_2..new_n
## X11VNC[new1]="-no6 -rfbauth /root/.vnc/.passwd -rawfb vt2"

## Отключить автоматическое создание X11VNC для всех дисплеев
## X11VNC[display]=disable || X11VNC[nodisplay]=1 || X11VNC[disable]=1
exec_x11vnc(){
    systemctl --quiet --wait is-system-running
    if [[ -n ${X11VNC[@]} ]]; then
	OPTION_GLOBAL="-many -shared -no6"
#	OPTION_GLOBAL="-many -shared -no6 -forever -dontdisconnect -noxdamage -xkb -rfbport 590%i "
	if [[ -n ${X11VNC[password]} ]]; then
	    # Добавить параметр в ${FILE_ROOT_USERS}=".users_credential" и удалить параметр X11VNC[password] из '/etc/ublinux/desktop
	    if [[ -f ${FILE_ROOT_USERS} ]]; then
		sed "/X11VNC\[password\]=/d" -i "${FILE_ROOT_USERS}"
		[[ -n ${X11VNC[password]} ]] && echo "X11VNC[password]='${X11VNC[password]}'" >> ${FILE_ROOT_USERS}
	    fi
	    [[ -f "${SYSCONF}/desktop" ]] && sed -E "s/(X11VNC\[password\])=.*/\1=secret/g" -i "${SYSCONF}/desktop"
	    [[ -d /root/.vnc ]] || mkdir -p /root/.vnc
	    /usr/bin/x11vnc -quiet -storepasswd "$(base64 -d <<< "${X11VNC[password]}")" /root/.vnc/.passwd &>/dev/null
	    chmod 600 /root/.vnc/.passwd
	    ## Show obscured password
	    #/usr/bin/x11vnc -showrfbauth /root/.vnc/passwd
	fi
	[[ -f /root/.vnc/.passwd ]] && OPTION_RFBAUTH_PASSWD="-rfbauth /root/.vnc/.passwd"
	# Создать сервис x11vnc для дисплейного менеджера
	if systemctl --quiet is-enabled lightdm.service &>/dev/null || systemctl --quiet is-enabled lightdm-plymouth.service &>/dev/null; then
	    #$(cd /tmp/.X11-unix && for x in X*; do echo ":${x#X}"; done)
	    for ID_DISPLAY in /var/run/lightdm/root/:*; do
		FILE_X11VNC_SERVICE="/usr/lib/systemd/system/x11vnc-ublinux:${ID_DISPLAY##*:}.service"
		OPTION_DISPLAY="-display WAIT:${ID_DISPLAY##*:} -auth /var/run/lightdm/root/:${ID_DISPLAY##*:}"
		OPTION_LOG="-o /var/log/x11vnc-ublinux:${ID_DISPLAY##*:}.log"
		OPTION_PORT="-autoport 590${ID_DISPLAY##*:}"
    		mkdir -p "${FILE_X11VNC_SERVICE%/*}"
		cat << EOF > "${FILE_X11VNC_SERVICE}"
[Unit]
Description=VNC Server for X11:${ID_DISPLAY##*:}
Requires=graphical.target
After=graphical.target

[Service]
#ExecStartPre=/bin/sh -c 'while ! pgrep -U "root" Xorg; do sleep 2; done'
ExecStart=
ExecStart=/usr/bin/x11vnc ${X11VNC[options]} ${OPTION_PORT} ${OPTION_DISPLAY} ${OPTION_RFBAUTH_PASSWD} ${OPTION_LOG} ${OPTION_GLOBAL}
Restart=always
RestartSec=5
SuccessExitStatus=2

[Install]
WantedBy=graphical.target
EOF
		systemctl daemon-reload &>/dev/null
		[[ -f ${FILE_X11VNC_SERVICE} ]] && systemctl --quiet  enable ${FILE_X11VNC_SERVICE##*/} &>/dev/null && systemctl --quiet  restart ${FILE_X11VNC_SERVICE##*/} &>/dev/null
	    done
	elif systemctl --quiet is-enabled gdm.service &>/dev/null || systemctl --quiet is-enabled gdm-plymouth.service &>/dev/null; then
	    true
	elif systemctl --quiet is-enabled lxdm.service &>/dev/null || systemctl --quiet is-enabled lxdm-plymouth.service &>/dev/null; then
	    true
	elif systemctl --quiet is-enabled sddm.service &>/dev/null || systemctl --quiet is-enabled sddm-plymouth.service &>/dev/null; then
	    true
	elif systemctl --quiet is-enabled slim.service &>/dev/null || systemctl --quiet is-enabled slim-plymouth.service &>/dev/null; then
	    true
	fi
	## Создаём сервисы пользовательские
	for X11VNC_NEW in "${!X11VNC[@]}"; do
	    if  [[ ${X11VNC_NEW} =~ ^new[0-9]{1,2}$ || ${X11VNC_NEW} =~ ^tty[0-9]{1,2}$ ]]; then
		## Настройка VNC для TTY
		if [[ ${X11VNC_NEW} =~ ^tty[0-9]{1,2}$ ]]; then
		    NUM_TTY=$(sed "s/tty//" <<< ${X11VNC_NEW})
		    X11VNC[${X11VNC_NEW}]="${OPTION_GLOBAL} -rfbauth /root/.vnc/.passwd -rawfb vt${NUM_TTY} ${X11VNC[${X11VNC_NEW}]}"
		fi
		FILE_X11VNC_SERVICE="/usr/lib/systemd/system/x11vnc-ublinux-${X11VNC_NEW}.service"
		OPTION_LOG="-o /var/log/x11vnc-ublinux-${X11VNC_NEW}.log"
		OPTION_PORT="-autoport 5900"
		if NUM_TTY=$(grep -E --only-matching -- "-rawfb vt[0-9]{1,2}" <<< ${X11VNC[${X11VNC_NEW}]} | head -1 | sed "s/-rawfb vt//") && [[ -n ${NUM_TTY} ]]; then
		    systemctl start getty@tty${NUM_TTY}.service
		fi
		if grep --quiet -- "-display" <<< ${X11VNC[${X11VNC_NEW}]}; then
		    SERVICE_UNIT="[Unit]
Description=VNC Server ${X11VNC_NEW}
Requires=graphical.target
After=graphical.target"
		    SERVICE_INSTALL="[Install]
WantedBy=graphical.target"
		else
		    SERVICE_UNIT="[Unit]
Description=VNC Server - ${X11VNC_NEW}"
		    SERVICE_INSTALL="[Install]
WantedBy=multi-user.target"
		fi
		mkdir -p "${FILE_X11VNC_SERVICE%/*}"
		cat << EOF > "${FILE_X11VNC_SERVICE}"
${SERVICE_UNIT}

[Service]
ExecStart=
ExecStart=/usr/bin/x11vnc ${OPTION_PORT} ${OPTION_LOG} ${X11VNC[${X11VNC_NEW}]}
Restart=always
RestartSec=5
SuccessExitStatus=2

${SERVICE_INSTALL}
EOF
		systemctl daemon-reload &>/dev/null
		[[ -f ${FILE_X11VNC_SERVICE} ]] && systemctl --quiet enable ${FILE_X11VNC_SERVICE##*/} &>/dev/null && systemctl --quiet restart ${FILE_X11VNC_SERVICE##*/} &>/dev/null
	    fi
	done
    else
    ## Если в режиме полного сохранения настройку убрали, то отключаем
	local DAEMON_RELOAD=
        [[ -f ${FILE_ROOT_USERS} ]] && sed "/X11VNC\[password\]=/d" -i "${FILE_ROOT_USERS}"
	[[ -f "${SYSCONF}/desktop" ]] && sed "/X11VNC\[password\]=/d" -i "${SYSCONF}/desktop"
	rm -f /root/.vnc/.passwd
	for FILE_X11VNC_SERVICE in /usr/lib/systemd/system/x11vnc-ublinux*.service; do
	    if [[ -e ${FILE_X11VNC_SERVICE} ]]; then
		systemctl --quiet disable ${FILE_X11VNC_SERVICE##*/} &>/dev/null
		systemctl --quiet stop ${FILE_X11VNC_SERVICE##*/} &>/dev/null
		rm -f ${FILE_X11VNC_SERVICE}
		DAEMON_RELOAD=yes
	    fi
	done
	[[ -z ${DAEMON_RELOAD} ]] || systemctl daemon-reload &>/dev/null
    fi
}

################
##### MAIN #####
################

    # Если файл подключен как ресурс с функциями, то выйти
    return 0 2>/dev/null && return 0

    exec_x11vnc $@
