def run(self): event = threading.Event() while not self.server.wantshutdown: if __debug__ and TRACE: print self.getName() + ": About to call accept" try: transport = None event.clear() # blocking wait for new connection to come in sock, peeraddr = self.listen.accept() # ask if we allow this connection msg = Server.Message(Server.Message.CMD_NEW_ACCEPT_REQUEST, self.responsequeue, peeraddr) self.requestqueue.put(msg) resp = self.responsequeue.get() assert resp.cmd == resp.CMD_NEW_ACCEPT_RESPONSE ok = resp.data if not ok: self.log("Connection from " + ` peeraddr ` + " not accepted") sock.close() continue # startup ssh stuff self.log("Connection from " + ` peeraddr ` + " accepted") transport = paramiko.Transport(sock) transport.add_server_key(self.server.ssh_server_key) transport.setDaemon(True) srvr = myServer(peeraddr, self) transport.start_server(event, srvr) except: if __debug__ and TRACE: print self.getName() + ": Exception in accept block\n" + guihelper.formatexception() self.logexception("Exception in accept", sys.exc_info()) if transport is not None: del transport sock.close() continue # wait for it to become an SSH connection event.wait() if not event.isSet() or not transport.is_active(): self.log("Connection from " + ` peeraddr ` + " didn't do SSH negotiation") transport.close() sock.close() continue if __debug__ and TRACE: print self.getName() + ": SSH connection from " + ` peeraddr ` self.log("SSH negotiated from " + ` peeraddr `) chan = None try: chan = transport.accept() serverchan = ServerChannel(chan, peeraddr, srvr.bf_auth_username) serverchan.XMLRPCLoop(self) except: self.logexception("Exception in XMLRPCLoop", sys.exc_info()) if chan is not None: chan.close() del chan if transport is not None: transport.close() del transport msg = Server.Message(Server.Message.CMD_CONNECTION_CLOSE, None, peeraddr) self.requestqueue.put(msg) self.log("Connection from " + ` peeraddr ` + " closed")
def logexception(self, str, excinfo): if __debug__ and TRACE: print "exception %s\n%s" % (str, guihelper.formatexception(excinfo)) self.log(str) msg = Server.Message(Server.Message.CMD_LOG_EXCEPTION, data=excinfo) self.requestqueue.put(msg)
def run(self): event=threading.Event() while not self.server.wantshutdown: if __debug__ and TRACE: print self.getName()+": About to call accept" try: transport=None event.clear() # blocking wait for new connection to come in sock, peeraddr = self.listen.accept() # ask if we allow this connection msg=Server.Message(Server.Message.CMD_NEW_ACCEPT_REQUEST, self.responsequeue, peeraddr) self.requestqueue.put(msg) resp=self.responsequeue.get() assert resp.cmd==resp.CMD_NEW_ACCEPT_RESPONSE ok=resp.data if not ok: self.log("Connection from "+`peeraddr`+" not accepted") sock.close() continue # startup ssh stuff self.log("Connection from "+`peeraddr`+" accepted") transport=paramiko.Transport(sock) transport.add_server_key(self.server.ssh_server_key) transport.setDaemon(True) srvr=myServer(peeraddr, self) transport.start_server(event,srvr) except: if __debug__ and TRACE: print self.getName()+": Exception in accept block\n"+guihelper.formatexception() self.logexception("Exception in accept", sys.exc_info()) if transport is not None: del transport sock.close() continue # wait for it to become an SSH connection event.wait() if not event.isSet() or not transport.is_active(): self.log("Connection from "+`peeraddr`+" didn't do SSH negotiation") transport.close() sock.close() continue if __debug__ and TRACE: print self.getName()+": SSH connection from "+`peeraddr` self.log("SSH negotiated from "+`peeraddr`) chan=None try: chan=transport.accept() serverchan=ServerChannel(chan,peeraddr,srvr.bf_auth_username) serverchan.XMLRPCLoop(self) except: self.logexception("Exception in XMLRPCLoop", sys.exc_info()) if chan is not None: chan.close() del chan if transport is not None: transport.close() del transport msg=Server.Message(Server.Message.CMD_CONNECTION_CLOSE, None, peeraddr) self.requestqueue.put(msg) self.log("Connection from "+`peeraddr`+" closed")
def __init__(self, chanid, peeraddr, username): self.chan=chanid self.peeraddr=peeraddr self.username=username paramiko.Channel.__init__(self, chanid) def readall(self, amount): result="" while amount: l=self.chan.recv(amount) if len(l)==0: return result result+=l amount-=len(l) return result def XMLRPCLoop(self, conn): """Main loop that deals with the XML-RPC data @param conn: The connectionthread object we are working for """ while True: try: length=int(self.readall(8)) except ValueError: return xml=self.readall(length) response=conn.processxmlrpcrequest(xml, self.peeraddr, self.username) self.chan.sendall( ("%08d" % (len(response),))+response) class myServer (paramiko.ServerInterface) : def __init__(self, peeraddr, onbehalfof): self.event = threading.Event() self.peeraddr=peeraddr self.onbehalfof=onbehalfof def get_allowed_auths(self, username): return "password" def check_auth_password(self, username, password): self.bf_auth_username="******" conn=self.onbehalfof conn.log("Checking authentication for user "+`username`) msg=Server.Message(Server.Message.CMD_NEW_USER_REQUEST, conn.responsequeue, self.peeraddr, data=(username,password)) conn.requestqueue.put(msg) resp=conn.responsequeue.get() assert resp.cmd==resp.CMD_NEW_USER_RESPONSE if hasattr(resp, 'exception'): conn.logexception("Exception while checking authentication",resp.exception) return paramiko.AUTH_FAILED if resp.data: conn.log("Credentials ok for user "+`username`) self.bf_auth_username=username return paramiko.AUTH_SUCCESSFUL conn.log("Credentials not accepted for user "+`username`) return paramiko.AUTH_FAILED def check_channel_request(self, kind, chanid): if kind == 'bitfling': return paramiko.OPEN_SUCCEEDED return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED class Server (threading.Thread) : class Message : """A message between a connection thread and the server object, or vice versa""" CMD_LOG=0 CMD_LOG_EXCEPTION=1 CMD_NEW_ACCEPT_REQUEST=2 CMD_NEW_ACCEPT_RESPONSE=3 CMD_NEW_USER_REQUEST=4 CMD_NEW_USER_RESPONSE=5 CMD_XMLRPC_REQUEST=6 CMD_XMLRPC_RESPONSE=7 CMD_CONNECTION_CLOSE=8 def __init__(self, cmd, respondqueue=None, clientaddr=None, data=None): self.cmd=cmd self.respondqueue=respondqueue self.clientaddr=clientaddr self.data=data def __repr__(self): d=`self.data` if len(d)>40: d=d[:40] str=`self.cmd` for i in dir(self): if i.startswith("CMD_") and getattr(self, i)==self.cmd: str=i break return "Message: cmd=%s data=%s" % (str, d) """A message between a connection thread and the server object, or vice versa""" class ConnectionThread (threading.Thread) : def __init__(self, server, listen, queue, name): """Constructor @param server: reference to server object @param listen: socket object that is in listening state @param queue: the queue object to send messages to @param name: name of this thread""" threading.Thread.__init__(self) self.setDaemon(True) self.setName(name) self.responsequeue=Queue.Queue() self.server=server self.requestqueue=queue self.listen=listen def log(self, str): now=time.time() t=time.localtime(now) timestr="&%d:%02d:%02d.%03d" % ( t[3], t[4], t[5], int((now-int(now))*1000)) msg=Server.Message(Server.Message.CMD_LOG, data="%s: %s: %s" % (timestr, self.getName(), str)) self.requestqueue.put(msg) def logexception(self, str, excinfo): if __debug__ and TRACE: print "exception %s\n%s" % (str, guihelper.formatexception(excinfo)) self.log(str) msg=Server.Message(Server.Message.CMD_LOG_EXCEPTION, data=excinfo) self.requestqueue.put(msg) def run(self):
def logexception(self, str, excinfo): if __debug__ and TRACE: print "exception %s\n%s" % (str, guihelper.formatexception(excinfo)) self.log(str) msg=Server.Message(Server.Message.CMD_LOG_EXCEPTION, data=excinfo) self.requestqueue.put(msg)