#!/bin/sh sourced [ -z "$SLX_KCL_SERVERS" ] && . /opt/openslx/config [ "$DISPLAY" = :0 ] && [ -n "$SLX_REMOTE_VNC" ] && bash <<"BLUBB" & . /opt/openslx/config # TODO If we support multiple parallel sessions in the future, we need dedicated # ports for each session for both, the VNC and the RPC port. vnc_port="${SLX_REMOTE_VNC_PORT:-5900}" if ! [ "$vnc_port" -gt 0 ] || ! [ "$vnc_port" -lt 65535 ]; then vnc_port=5900 fi srchost="$SLX_REMOTE_HOST_ACCESS" if [ -n "$srchost" ]; then # IPTABLES rule="/opt/openslx/iptables/rules.d/80-remote-access" if ! [ -e "$rule" ]; then ( echo "#!/bin/sh" echo "iptables -A INPUT -s "'"'"$srchost"'"'" -p tcp --dport $vnc_port -j ACCEPT" echo "iptables -A INPUT -s "'"'"$srchost"'"'" -p tcp --dport 7551 -j ACCEPT" echo "iptables -A INPUT -p tcp --dport $vnc_port -j DROP" echo "iptables -A INPUT -p tcp --dport 7551 -j DROP" ) > "$rule" chmod +x "$rule" fi fi #set -x #exec &> /tmp/fooooooooooooo # dd since busybox head doesn't know -c passwd="$( < /dev/urandom tr -c -d 'a-zA-Z0-9#&/=()[]{}' | dd bs=8 count=1 status=none )" printf "%s" "$passwd" > "/tmp/vnc-passwd" ( # Make a copy of xauth, so if the xserver restarts, we'll use the old one and fail to connect if [ -n "$XAUTHORITY" ]; then copy="$( mktemp )" cat "$XAUTHORITY" > "$copy" export XAUTHORITY="$copy" trap 'exit 1' INT TERM trap 'rm -f -- "$copy"' EXIT fi fails=0 while true; do s="$( date +%s )" # skip keycode stuff fixes altgr for vmware x11vnc -rfbport "$vnc_port" -shared -forever -noxrecord -xkb -capslock -skip_keycodes 92,187,188 -remap DEAD=gac,U20AC-EuroSign -passwd "$passwd" e="$( date +%s )" d="$(( e - s ))" if [ "$d" -gt 5 ]; then fails=0 else fails="$(( fails + 1 ))" [ "$fails" -gt 10 ] && break [ "$fails" -gt 3 ] && usleep 333333 fi done ) &> "/tmp/x11vnc-log-$$" & vncpid=$! # Delay this a bit until x11vnc is ready, and since we might potentially have had a race # with the ~poweron event, which would reset the password in the database. ( url="http://${SLX_PXE_SERVER_IP}/slx-admin/api.php?do=remoteaccess" sleep 6 [ -d "/proc/${vncpid}" ] || exit 1 # Something is wrong, bail curl -s -S -L --retry 4 --retry-connrefused --max-time 3 --retry-max-time 10 \ --data-urlencode "password=$passwd" \ --data-urlencode "vncport=$vnc_port" \ "$url" > /dev/null ) & gotone=false vmvnc=false idle=0 stepcount=0 # In case of stale entry # TODO: This sucks anyways performance-wise for VMware, maybe remove? iptables -t nat -D PREROUTING -p tcp --dport "$vnc_port" -j REDIRECT --to-ports 5901 while [ -d "/proc/${vncpid}" ]; do sleep 5 if netstat -tn | awk 'BEGIN{ e=1 } { if ($4 ~ /:590[0123]$/) e=0 } END{ exit e }'; then gotone=true idle=0 else idle=$(( idle + 1 )) fi if $gotone; then # As soon as someone is connected, "blank" the screen by setting brightness to zero. # This doesn't seem to affect the framebuffer, luckily # Let's see how well this works in practice. :-( if (( stepcount == 0 )); then declare -a args args=() for o in $( xrandr | grep -E '^[A-Z0-9-]+ connected.*[0-9]+x[0-9]+' | awk '{print $1}' ); do args+=( "--output" "$o" "--brightness" "0" ) done xrandr "${args[@]}" fi if (( stepcount++ > 3 )); then stepcount=0 fi fi if $gotone && [ "$idle" -gt 120 ]; then # 120 * 5 = 10 mins kill "$vncpid" break fi # In case we access vmplayer via x11vnc; vmplayer won't leave the keymap alone >:( # TODO: Currently everything needs to be set to DE for this to work - X11 and # the OS in the VM. #setxkbmap -query | grep -q '^layout:\s*de$' || \ # NO, always reports 'de' setxkbmap de # Check if we should redirect to vmware if netstat -tnl | awk 'BEGIN{ e=1 } { if ($4 ~ /:5901$/) e=0 } END{ exit e }'; then #enable if ! $vmvnc; then killall x11vnc usleep 10000 iptables -t nat -I PREROUTING 1 -p tcp --dport "$vnc_port" -j REDIRECT --to-ports 5901 fi vmvnc=true else # disable if $vmvnc; then iptables -t nat -D PREROUTING -p tcp --dport "$vnc_port" -j REDIRECT --to-ports 5901 fi vmvnc=false fi done systemctl restart lightdm BLUBB