X-Git-Url: http://xvm.mit.edu/gitweb/invirt/packages/invirt-vnc-server.git/blobdiff_plain/8ebae0c0aed6651c6f73b9a8ac52d2f2596f6357..14cf46b2e06a403c4238b415b2d762e747840d35:/vncexternalauth.py diff --git a/vncexternalauth.py b/vncexternalauth.py deleted file mode 100644 index 9f0edec..0000000 --- a/vncexternalauth.py +++ /dev/null @@ -1,215 +0,0 @@ -""" -Wrapper for sipb-xen VNC proxying -""" - -# twisted imports -from twisted.internet import reactor, protocol, defer -from twisted.python import log - -# python imports -import sys -import struct -import string -import cPickle -# Python 2.5: -#import hashlib -import sha -import hmac -import base64 -import socket -import time -import get_port - -TOKEN_KEY = "0M6W0U1IXexThi5idy8mnkqPKEq1LtEnlK/pZSn0cDrN" - -def getPort(name, auth_data): - if (auth_data["machine"] == name): - port = get_port.findPort(name) - if port is None: - return 0 - return int(port.split(':')[1]) - else: - return None - -class VNCAuthOutgoing(protocol.Protocol): - - def __init__(self,socks): - self.socks=socks - - def connectionMade(self): - peer = self.transport.getPeer() - self.socks.makeReply(200) - self.socks.otherConn=self - - def connectionLost(self, reason): - self.socks.transport.loseConnection() - - def dataReceived(self,data): - self.socks.write(data) - - def write(self,data): - #self.socks.log(self,data) - self.transport.write(data) - - -class VNCAuth(protocol.Protocol): - - def __init__(self,logging=None,server="localhost"): - self.logging=logging - self.server=server - self.auth=None - - def connectionMade(self): - self.buf="" - self.otherConn=None - - def validateToken(self, token): - global TOKEN_KEY - try: - token = base64.urlsafe_b64decode(token) - token = cPickle.loads(token) - m = hmac.new(TOKEN_KEY, digestmod=sha) - m.update(token['data']) - self.auth_error = "Invalid token" - if (m.digest() == token['digest']): - data = cPickle.loads(token['data']) - expires = data["expires"] - if (time.time() < expires): - self.auth = data["user"] - self.auth_error = None - self.auth_machine = data["machine"] - self.auth_data = data - else: - self.auth_error = "Token has expired; please try logging in again" - except: - self.auth = None - print sys.exc_info() - - def dataReceived(self,data): - if self.otherConn: - self.otherConn.write(data) - return - self.buf=self.buf+data - if ('\r\n\r\n' in self.buf) or ('\n\n' in self.buf) or ('\r\r' in self.buf): - lines = self.buf.splitlines() - args = lines.pop(0).split() - command = args.pop(0) - headers = {} - for line in lines: - try: - (header, data) = line.split(": ", 1) - headers[header] = data - except: - pass - - if command == "AUTHTOKEN": - user = args[0] - token = headers["Auth-token"] - if token == "1": #FIXME - self.auth = user - self.makeReply(200, "Authentication successful") - else: - self.makeReply(401) - elif command == "CONNECTVNC": - vmname = args[0] - if ("Auth-token" in headers): - token = headers["Auth-token"] - try: - self.validateToken(token) - finally: - if self.auth is not None: - port = getPort(vmname, self.auth_data) - if port is not None: # FIXME - if port is not 0: - d = self.connectClass(self.server, port, VNCAuthOutgoing, self) - d.addErrback(lambda result, self=self: self.makeReply(404, result.getErrorMessage())) - else: - self.makeReply(404, "Unable to find VNC for VM "+vmname) - else: - self.makeReply(401, "Unauthorized to connect to VM "+vmname) - else: - if self.auth_error: - self.makeReply(401, self.auth_error) - else: - self.makeReply(401, "Invalid token") - else: - self.makeReply(401, "Login first") - else: - self.makeReply(501, "unknown method "+command) - self.buf='' - if False and '\000' in self.buf[8:]: - head,self.buf=self.buf[:8],self.buf[8:] - try: - version,code,port=struct.unpack("!BBH",head[:4]) - except struct.error: - raise RuntimeError, "struct error with head='%s' and buf='%s'"%(repr(head),repr(self.buf)) - user,self.buf=string.split(self.buf,"\000",1) - if head[4:7]=="\000\000\000": # domain is after - server,self.buf=string.split(self.buf,'\000',1) - #server=gethostbyname(server) - else: - server=socket.inet_ntoa(head[4:8]) - assert version==4, "Bad version code: %s"%version - if not self.authorize(code,server,port,user): - self.makeReply(91) - return - if code==1: # CONNECT - d = self.connectClass(server, port, SOCKSv4Outgoing, self) - d.addErrback(lambda result, self=self: self.makeReply(91)) - else: - raise RuntimeError, "Bad Connect Code: %s" % code - assert self.buf=="","hmm, still stuff in buffer... %s" % repr(self.buf) - - def connectionLost(self, reason): - if self.otherConn: - self.otherConn.transport.loseConnection() - - def authorize(self,code,server,port,user): - log.msg("code %s connection to %s:%s (user %s) authorized" % (code,server,port,user)) - return 1 - - def connectClass(self, host, port, klass, *args): - return protocol.ClientCreator(reactor, klass, *args).connectTCP(host,port) - - def makeReply(self,reply,message=""): - self.transport.write("VNCProxy/1.0 %d %s\r\n\r\n" % (reply, message)) - if int(reply / 100)!=2: self.transport.loseConnection() - - def write(self,data): - #self.log(self,data) - self.transport.write(data) - - def log(self,proto,data): - if not self.logging: return - peer = self.transport.getPeer() - their_peer = self.otherConn.transport.getPeer() - f=open(self.logging,"a") - f.write("%s\t%s:%d %s %s:%d\n"%(time.ctime(), - peer.host,peer.port, - ((proto==self and '<') or '>'), - their_peer.host,their_peer.port)) - while data: - p,data=data[:16],data[16:] - f.write(string.join(map(lambda x:'%02X'%ord(x),p),' ')+' ') - f.write((16-len(p))*3*' ') - for c in p: - if len(repr(c))>3: f.write('.') - else: f.write(c) - f.write('\n') - f.write('\n') - f.close() - - -class VNCAuthFactory(protocol.Factory): - """A factory for a VNC auth proxy. - - Constructor accepts one argument, a log file name. - """ - - def __init__(self, log, server): - self.logging = log - self.server = server - - def buildProtocol(self, addr): - return VNCAuth(self.logging, self.server) -