X-Git-Url: http://xvm.mit.edu/gitweb/invirt/scripts/vnc-client.git/blobdiff_plain/ce2a43eb31a263484f225e70c89d3d826a88f16e..8aac8dd8db9bcdbe40f6dc6c6bb45930c824e400:/invirt-vnc-client diff --git a/invirt-vnc-client b/invirt-vnc-client index a4a9570..63d3999 100755 --- a/invirt-vnc-client +++ b/invirt-vnc-client @@ -1,8 +1,8 @@ #!/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 @@ -10,7 +10,8 @@ def usage(): 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) @@ -19,10 +20,13 @@ def usage(): 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): @@ -59,16 +63,18 @@ class ProxyClient(Proxy): 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 @@ -136,8 +142,9 @@ def main(): 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: @@ -152,12 +159,12 @@ def main(): 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: @@ -182,11 +189,21 @@ def main(): 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()