#!/usr/bin/python
-from twisted.internet import reactor, ssl, protocol
+from twisted.internet import reactor, ssl, protocol, error
from OpenSSL import SSL
import base64, pickle
-import getopt, sys
+import getopt, sys, os, time
verbose = False
print """%s [-v] [-l [HOST:]PORT] {-a AUTHTOKEN|VMNAME}
-l, --listen [HOST:]PORT port (and optionally host) to listen on for
connections (default is 127.0.0.1 and a randomly
- chosen port)
+ chosen port). Use an empty HOST to listen on all
+ interfaces (INSECURE!)
-a, --authtoken AUTHTOKEN Authentication token for connecting to the VNC server
VMNAME VM name to connect to (automatically fetches an
authentication token using remctl)
class ClientContextFactory(ssl.ClientContextFactory):
def _verify(self, connection, x509, errnum, errdepth, ok):
- print '_verify (ok=%d):' % ok
- print ' subject:', x509.get_subject()
- print ' issuer:', x509.get_issuer()
- print ' errnum %s, errdepth %d' % (errnum, errdepth)
+ if verbose:
+ print '_verify (ok=%d):' % ok
+ print ' subject:', x509.get_subject()
+ print ' issuer:', x509.get_issuer()
+ print ' errnum %s, errdepth %d' % (errnum, errdepth)
+ if errnum == 10:
+ print 'The VNC server certificate has expired. Please contact xvm@mit.edu.'
return ok
def getContext(self):
self.transport.write(data)
if verbose: print "ProxyClient: connection made"
def dataReceived(self, data):
- if not ready:
+ if not self.ready:
if verbose: print 'ProxyClient: received data "%s"' % data
if data.startswith("VNCProxy/1.0 200 "):
- ready = True
+ self.ready = True
if "\n" in data:
- self.peer.transport.write(data[data.find("\n")+1:])
+ self.peer.transport.write(data[data.find("\n")+3:])
self.peer.transport.resumeProducing() # Allow reading
else:
print "Failed to connect: %s" % data
self.transport.loseConnection()
+ else:
+ self.peer.transport.write(data)
class ProxyClientFactory(protocol.ClientFactory):
protocol = ProxyClient
elif o in ("-l", "--listen"):
if ":" in a:
listen = a.split(":", 2)
+ listen[1] = int(listen[1])
else:
- listen[1] = a
+ listen[1] = int(a)
elif o in ("-a", "--authtoken"):
authtoken = a
else:
sys.exit(2)
from subprocess import PIPE, Popen
try:
- p = Popen(["remctl", "remote", "control", args[0], "vnctoken"],
+ p = Popen(["remctl", "xvm-remote.mit.edu", "control", args[0], "vnctoken"],
stdout=PIPE)
except OSError:
if verbose: print "remctl not found in path. Trying remctl locker."
p = Popen(["athrun", "remctl", "remctl",
- "remote", "control", args[0], "vnctoken"],
+ "xvm-remote.mit.edu", "control", args[0], "vnctoken"],
stdout=PIPE)
authtoken = p.communicate()[0]
if p.returncode != 0:
sys.exit(1)
if verbose: print "Will connect to %s:%s" % (connect_host, connect_port)
+ if listen[1] is None:
+ listen[1] = 5900
+ ready = False
+ while not ready and listen[1] < 6000:
+ try:
+ reactor.listenTCP(listen[1], ProxyFactory(connect_host, connect_port, authtoken, machine), interface=listen[0])
+ ready = True
+ except error.CannotListenError:
+ listen[1] += 1
+ else:
+ reactor.listenTCP(listen[1], ProxyFactory(connect_host, connect_port, authtoken, machine))
- listen[1] = 10003
- reactor.listenTCP(listen[1], ProxyFactory(connect_host, connect_port, authtoken, machine))
-
- print "Ready to connect. Connect to %s:%s now with your VNC client. The password is 'moocow'." % (listen[0], listen[1])
+ print "Ready to connect. Connect to %s:%s (display %d) now with your VNC client. The password is 'moocow'." % (listen[0], listen[1], listen[1]-5900)
+ print "You must connect before your authentication token expires at %s." % \
+ (time.ctime(token_expires))
reactor.run()