forked from pool/tigervnc
f3919e3250
- Updated to tigervnc 1.5.0. - Dropped no longer needed patches: * tigervnc-sf3495623.patch * u_syslog.patch * u_tigervnc-build-with-xserver-1.17.patch - Use encryption everywhere. (fate#318936) - Work with fltk 1.3.2. * N_tigervnc_revert_fltk_1_3_3_requirements.patch OBS-URL: https://build.opensuse.org/request/show/316948 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/tigervnc?expand=0&rev=58
115 lines
3.5 KiB
Python
115 lines
3.5 KiB
Python
#!/usr/bin/env python
|
|
|
|
# This is simple stupid WWW server intended to serve VNC java applet.
|
|
# It is made to be called by xinetd.
|
|
# It handles both HTTP and HTTPS on the same port. If HTTPS is allowed, any HTTP requests is responded with redirect to HTTPS.
|
|
|
|
import re
|
|
import sys
|
|
import socket
|
|
import time
|
|
|
|
from OpenSSL import SSL, crypto
|
|
|
|
TLS_KEY = "/etc/vnc/tls.key"
|
|
TLS_CERT = "/etc/vnc/tls.cert"
|
|
JAR_FILE = "/usr/share/vnc/classes/VncViewer.jar"
|
|
TIMEOUT = 10
|
|
|
|
WIDTH = int(sys.argv[1])
|
|
HEIGHT = int(sys.argv[2])
|
|
VNC_PORT = int(sys.argv[3])
|
|
USE_HTTPS = not (len(sys.argv) >= 5 and sys.argv[4] == "NoHTTPS")
|
|
|
|
|
|
# Take the stdin as our input socket (given from xinetd)
|
|
conn = sock = socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
# If we are supposed to use HTTPS, load certificate and replace conn with SSL connection.
|
|
if USE_HTTPS:
|
|
cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(TLS_CERT, 'r').read())
|
|
|
|
context = SSL.Context(SSL.SSLv23_METHOD)
|
|
context.use_privatekey_file(TLS_KEY)
|
|
context.use_certificate(cert)
|
|
|
|
conn = SSL.Connection(context, sock)
|
|
conn.set_accept_state()
|
|
|
|
# Send normal response
|
|
def send_response(connection, ctype, response):
|
|
connection.sendall(
|
|
"HTTP/1.0 200 OK\n" +
|
|
"Content-Type: " + ctype + "\n" +
|
|
"Content-Length: " + str(len(response)) + "\n" +
|
|
"Connection: close\n" +
|
|
"\n" +
|
|
response
|
|
)
|
|
|
|
# Send redirect
|
|
def send_redirect(connection, ctype, response, location):
|
|
connection.sendall(
|
|
"HTTP/1.0 301 Moved Permanently\n" +
|
|
"Location: " + location + "\n" +
|
|
"Content-Type: " + ctype + "\n" +
|
|
"Content-Length: " + str(len(response)) + "\n" +
|
|
"Connection: close\n" +
|
|
"\n" +
|
|
response
|
|
)
|
|
|
|
|
|
# Try to read and parse HTTP request
|
|
try:
|
|
start_time = time.time()
|
|
buffer = ''
|
|
while True:
|
|
buffer += conn.recv(1024)
|
|
|
|
if buffer.endswith("\r\n\r\n") or start_time + TIMEOUT < time.time():
|
|
break
|
|
|
|
method, url = buffer.split(" ", 2)[0:2]
|
|
|
|
if url == '/VncViewer.jar':
|
|
with open(JAR_FILE, 'r') as file:
|
|
send_response(conn, "application/octet-stream", file.read())
|
|
else:
|
|
response = \
|
|
"""<html>
|
|
<head>
|
|
<title>Remote Desktop</title>
|
|
</head>
|
|
<body>
|
|
<embed type="application/x-java-applet;version=1.6" code="com.tigervnc.vncviewer.VncViewer" archive="VncViewer.jar" width="%d" height="%d"
|
|
Port="%d"
|
|
Embed="true"
|
|
AlwaysShowServerDialog="false"
|
|
SecurityTypes="%s"
|
|
x509autoaccept="%s"
|
|
>
|
|
</body>
|
|
</html>
|
|
"""%(WIDTH, HEIGHT, VNC_PORT, 'X509None' if USE_HTTPS else 'TLSNone', cert.digest('SHA1') if USE_HTTPS else '')
|
|
|
|
send_response(conn, "text/html", response)
|
|
|
|
except SSL.Error:
|
|
# If SSL failed, it is most probably because the browser is actually trying to do normal HTTP request.
|
|
|
|
# We have now a partially consumed HTTP request in sock, let's try if we can get Host header out of it
|
|
partial_request = sock.recv(8000) # Arbitrary big number, if the request is longer than this, we will just skip the rest.
|
|
|
|
host = None
|
|
match = re.search(r"\r\nHost: ([^\r]+)\r\n", partial_request)
|
|
if match:
|
|
host = match.group(1)
|
|
|
|
if host:
|
|
# If we got host header, we can redirect nicely with HTTP 301.
|
|
send_redirect(sock, "text.html", "<html><body>Use https.</body></html>", "https://" + host)
|
|
else:
|
|
# If we don't know the host header, redirect using javascript.
|
|
send_response(sock, "text.html", "<html><head><script>document.location.protocol = 'https';</script></head><body>Use https.</body></html>")
|