blob: 892bcf2a915b1a0778a5a00996fcc2e8012c64f2 (
plain) (
blame)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
#!/bin/bash
t="/tmp/remote-access-$DISPLAY"
mkdir -p "$t"
modmap="$t/modmap.want"
tmpmap="$t/modmap.have"
(
sleep 1
setxkbmap de
xmodmap -e "keycode 92 ="
xmodmap -e "keycode 187 ="
xmodmap -e "keycode 188 ="
xmodmap -e "keycode 26 = e E e E U20AC U20AC U20AC"
xmodmap -pke > "$modmap"
) &
. /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" > "$t/vnc-passwd"
[ "$SLX_REMOTE_VNC" = "x11vnc" ] && chmod 0600 "$t/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
< "$t/vnc-passwd" tigervncpasswd -f > "$t/tigervnc-passwd"
fails=0
while true; do
s="$( date +%s )"
x0vncserver -fg -SecurityTypes VncAuth,TLSvnc -rfbauth "$t/tigervnc-passwd" -rfbport "$vnc_port" -localhost no -Log "*:stdout:100" \
-AlwaysShared=true -DisconnectClients=false -MaxConnectionTime=0 -MaxDisconnectionTime=0 -MaxIdleTime=0
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
) &> "$t/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.
(
if [ -n "$SLX_REMOTE_LOG" ]; then
url="${SLX_REMOTE_LOG//=clientlog/=remoteaccess}"
elif [ -n "$SLX_PVS_CONFIG_URL" ]; then
url="${SLX_PVS_CONFIG_URL//=roomplanner/=remoteaccess}"
else
url="http://${SLX_PXE_SERVER_IP}/slx-admin/api.php?do=remoteaccess"
fi
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 ~ /:('"$vnc_port"'|5901)$/) 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 >:(
xmodmap -pke > "$tmpmap"
if ! cmp -s "$tmpmap" "$modmap"; then
echo "$( date ) Reloading modmap" >> "$t/reload-log"
xmodmap "$modmap"
fi
# Check if we should redirect to vmware
if [ "$SLX_REMOTE_VNC" != 'x11vnc' ]; then
if netstat -tnl | awk 'BEGIN{ e=1 } { if ($4 ~ /:5901$/) e=0 } END{ exit e }'; then
#enable
if ! $vmvnc; then
killall x0vncserver
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
fi
done
systemctl restart lightdm
|