class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): """ Each player connecting over telnet (ie using most traditional mud clients) gets a telnet protocol instance assigned to them. All communication between game and player goes through here. """ def connectionMade(self): """ This is called when the connection is first established. """ # initialize the session self.iaw_mode = False self.handshakes = 4 # ttype, mccp, mssp, msdp client_address = self.transport.client self.init_session("telnet", client_address, self.factory.sessionhandler) # negotiate ttype (client info) # Obs: mudlet ttype does not seem to work if we start mccp before ttype. /Griatch self.ttype = ttype.Ttype(self) # negotiate mccp (data compression) - turn this off for wireshark analysis self.mccp = Mccp(self) # negotiate mssp (crawler communication) self.mssp = mssp.Mssp(self) # msdp self.msdp = msdp.Msdp(self) # add this new connection to sessionhandler so # the Server becomes aware of it. self.sessionhandler.connect(self) # timeout the handshakes in case the client doesn't reply at all from src.utils.utils import delay delay(2, callback=self.handshake_done, retval=True) def handshake_done(self, force=False): """ This is called by all telnet extensions once they are finished. When all have reported, a sync with the server is performed. The system will force-call this sync after a small time to handle clients that don't reply to handshakes at all. info - debug text from the protocol calling """ if self.handshakes > 0: if force: self.sessionhandler.sync(self) return self.handshakes -= 1 if self.handshakes <= 0: # do the sync self.sessionhandler.sync(self) def enableRemote(self, option): """ This sets up the remote-activated options we allow for this protocol. """ return (option == LINEMODE or option == ttype.TTYPE or option == MCCP or option == mssp.MSSP) def enableLocal(self, option): """ Call to allow the activation of options for this protocol """ return option == MCCP def disableLocal(self, option): """ Disable a given option """ if option == MCCP: self.mccp.no_mccp(option) return True else: return super(TelnetProtocol, self).disableLocal(option) def connectionLost(self, reason): """ this is executed when the connection is lost for whatever reason. it can also be called directly, from the disconnect method """ self.sessionhandler.disconnect(self) self.transport.loseConnection() def dataReceived(self, data): """ This method will split the incoming data depending on if it starts with IAC (a telnet command) or not. All other data will be handled in line mode. Some clients also sends an erroneous line break after IAC, which we must watch out for. OOB protocols (MSDP etc) already intercept subnegotiations on their own, never entering this method. They will relay their parsed data directly to self.data_in. """ if data and data[0] == IAC or self.iaw_mode: try: #print "IAC mode" super(TelnetProtocol, self).dataReceived(data) if len(data) == 1: self.iaw_mode = True else: self.iaw_mode = False return except Exception, err1: conv = "" try: for b in data: conv += " " + repr(ord(b)) except Exception, err2: conv = str(err2) + ":", str(data) out = "Telnet Error (%s): %s (%s)" % (err1, data, conv) logger.log_trace(out) return
class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): """ Each player connecting over telnet (ie using most traditional mud clients) gets a telnet protocol instance assigned to them. All communication between game and player goes through here. """ def connectionMade(self): """ This is called when the connection is first established. """ # initialize the session self.iaw_mode = False client_address = self.transport.client # this number is counted down for every handshake that completes. # when it reaches 0 the portal/server syncs their data self.handshakes = 5 # naws, ttype, mccp, mssp, msdp self.init_session("telnet", client_address, self.factory.sessionhandler) # negotiate client size self.naws = naws.Naws(self) # negotiate ttype (client info) # Obs: mudlet ttype does not seem to work if we start mccp before ttype. /Griatch self.ttype = ttype.Ttype(self) # negotiate mccp (data compression) - turn this off for wireshark analysis self.mccp = Mccp(self) # negotiate mssp (crawler communication) self.mssp = mssp.Mssp(self) # msdp self.msdp = msdp.Msdp(self) # add this new connection to sessionhandler so # the Server becomes aware of it. self.sessionhandler.connect(self) # timeout the handshakes in case the client doesn't reply at all from src.utils.utils import delay delay(2, callback=self.handshake_done, retval=True) def handshake_done(self, force=False): """ This is called by all telnet extensions once they are finished. When all have reported, a sync with the server is performed. The system will force-call this sync after a small time to handle clients that don't reply to handshakes at all. info - debug text from the protocol calling """ if self.handshakes > 0: if force: self.sessionhandler.sync(self) return self.handshakes -= 1 if self.handshakes <= 0: # do the sync self.sessionhandler.sync(self) def enableRemote(self, option): """ This sets up the remote-activated options we allow for this protocol. """ pass return (option == LINEMODE or option == ttype.TTYPE or option == naws.NAWS or option == MCCP or option == mssp.MSSP) def enableLocal(self, option): """ Call to allow the activation of options for this protocol """ return (option == MCCP or option == ECHO) def disableLocal(self, option): """ Disable a given option """ if option == ECHO: return True if option == MCCP: self.mccp.no_mccp(option) return True else: return super(TelnetProtocol, self).disableLocal(option) def connectionLost(self, reason): """ this is executed when the connection is lost for whatever reason. it can also be called directly, from the disconnect method """ self.sessionhandler.disconnect(self) self.transport.loseConnection() def dataReceived(self, data): """ This method will split the incoming data depending on if it starts with IAC (a telnet command) or not. All other data will be handled in line mode. Some clients also sends an erroneous line break after IAC, which we must watch out for. OOB protocols (MSDP etc) already intercept subnegotiations on their own, never entering this method. They will relay their parsed data directly to self.data_in. """ if data and data[0] == IAC or self.iaw_mode: try: #print "IAC mode" super(TelnetProtocol, self).dataReceived(data) if len(data) == 1: self.iaw_mode = True else: self.iaw_mode = False return except Exception, err1: conv = "" try: for b in data: conv += " " + repr(ord(b)) except Exception, err2: conv = str(err2) + ":", str(data) out = "Telnet Error (%s): %s (%s)" % (err1, data, conv) logger.log_trace(out) return
class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): """ Each player connecting over telnet (ie using most traditional mud clients) gets a telnet protocol instance assigned to them. All communication between game and player goes through here. """ def connectionMade(self): """ This is called when the connection is first established. """ # initialize the session self.iaw_mode = False client_address = self.transport.client self.init_session("telnet", client_address, self.factory.sessionhandler) # negotiate mccp (data compression) self.mccp = Mccp(self) # negotiate ttype (client info) self.ttype = ttype.Ttype(self) # negotiate mssp (crawler communication) self.mssp = mssp.Mssp(self) # msdp self.msdp = msdp.Msdp(self) # add this new connection to sessionhandler so # the Server becomes aware of it. # This is a fix to make sure the connection does not # continue until the handshakes are done. This is a # dumb delay of 1 second. This solution is not ideal (and # potentially buggy for slow connections?) but # adding a callback chain to all protocols (and notably # to their handshakes, which in some cases are multi-part) # is not trivial. Without it, the protocol will default # to their defaults since sessionhandler.connect will sync # before the handshakes have had time to finish. Keeping this patch # until coming up with a more elegant solution /Griatch from src.utils.utils import delay delay(1, callback=self.sessionhandler.connect, retval=self) #self.sessionhandler.connect(self) def enableRemote(self, option): """ This sets up the remote-activated options we allow for this protocol. """ return (option == LINEMODE or option == ttype.TTYPE or option == MCCP or option == mssp.MSSP) def enableLocal(self, option): """ Call to allow the activation of options for this protocol """ return option == MCCP def disableLocal(self, option): """ Disable a given option """ if option == MCCP: self.mccp.no_mccp(option) return True else: return super(TelnetProtocol, self).disableLocal(option) def connectionLost(self, reason): """ this is executed when the connection is lost for whatever reason. it can also be called directly, from the disconnect method """ self.sessionhandler.disconnect(self) self.transport.loseConnection() def dataReceived(self, data): """ This method will split the incoming data depending on if it starts with IAC (a telnet command) or not. All other data will be handled in line mode. Some clients also sends an erroneous line break after IAC, which we must watch out for. OOB protocols (MSDP etc) already intercept subnegotiations on their own, never entering this method. They will relay their parsed data directly to self.data_in. """ if data and data[0] == IAC or self.iaw_mode: try: #print "IAC mode" super(TelnetProtocol, self).dataReceived(data) if len(data) == 1: self.iaw_mode = True else: self.iaw_mode = False return except Exception, err1: conv = "" try: for b in data: conv += " " + repr(ord(b)) except Exception, err2: conv = str(err2) + ":", str(data) out = "Telnet Error (%s): %s (%s)" % (err1, data, conv) logger.log_trace(out) return
class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session): """ Each player connecting over telnet (ie using most traditional mud clients) gets a telnet protocol instance assigned to them. All communication between game and player goes through here. """ def connectionMade(self): """ This is called when the connection is first established. """ # initialize the session self.iaw_mode = False client_address = self.transport.client self.init_session("telnet", client_address, self.factory.sessionhandler) # negotiate ttype (client info) # Obs: mudlet ttype does not seem to work if we start mccp before ttype. /Griatch self.ttype = ttype.Ttype(self) # negotiate mccp (data compression) - turn this off for wireshark analysis self.mccp = Mccp(self) # negotiate mssp (crawler communication) self.mssp = mssp.Mssp(self) # msdp self.msdp = msdp.Msdp(self) # add this new connection to sessionhandler so # the Server becomes aware of it. # This is a fix to make sure the connection does not # continue until the handshakes are done. This is a # dumb delay of 1 second. This solution is not ideal (and # potentially buggy for slow connections?) but # adding a callback chain to all protocols (and notably # to their handshakes, which in some cases are multi-part) # is not trivial. Without it, the protocol will default # to their defaults since sessionhandler.connect will sync # before the handshakes have had time to finish. Keeping this patch # until coming up with a more elegant solution /Griatch from src.utils.utils import delay delay(1, callback=self.sessionhandler.connect, retval=self) #self.sessionhandler.connect(self) def enableRemote(self, option): """ This sets up the remote-activated options we allow for this protocol. """ return (option == LINEMODE or option == ttype.TTYPE or option == MCCP or option == mssp.MSSP) def enableLocal(self, option): """ Call to allow the activation of options for this protocol """ return option == MCCP def disableLocal(self, option): """ Disable a given option """ if option == MCCP: self.mccp.no_mccp(option) return True else: return super(TelnetProtocol, self).disableLocal(option) def connectionLost(self, reason): """ this is executed when the connection is lost for whatever reason. it can also be called directly, from the disconnect method """ self.sessionhandler.disconnect(self) self.transport.loseConnection() def dataReceived(self, data): """ This method will split the incoming data depending on if it starts with IAC (a telnet command) or not. All other data will be handled in line mode. Some clients also sends an erroneous line break after IAC, which we must watch out for. OOB protocols (MSDP etc) already intercept subnegotiations on their own, never entering this method. They will relay their parsed data directly to self.data_in. """ if data and data[0] == IAC or self.iaw_mode: try: #print "IAC mode" super(TelnetProtocol, self).dataReceived(data) if len(data) == 1: self.iaw_mode = True else: self.iaw_mode = False return except Exception, err1: conv = "" try: for b in data: conv += " " + repr(ord(b)) except Exception, err2: conv = str(err2) + ":", str(data) out = "Telnet Error (%s): %s (%s)" % (err1, data, conv) logger.log_trace(out) return