1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#!/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"
for _ in {1..20}; do
sleep 1
[ -e "/etc/cron.d/usage_stats" ] && break
done
[ -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
|