def Setup(self, service, connectionID, echo=False):
        Connection.Setup(self, service, connectionID)

        self.suppressEcho = False

        self.echo = echo
        self.consoleColumns = 80
        self.consoleRows = 24
        self.terminalType = None
        self.terminalTypes = []

        self.clientName = None
        self.optionEcho = False
        self.optionLineMode = True
        self.readlineBuffer = ""

        self.telneg = TelnetNegotiation(self.TelnetNegotiationSend,
                                        self.TelnetSubnegotiation,
                                        self.TelnetCommand)
        self.telneg_terminaltype_cb = None

        if False:
            self.user = None
            self.preLoginBuffer = StringIO.StringIO()
            stackless.tasklet(self._ManageConnectionPreLogin)()

        self.user = User(self, "login")
        self.user.SetupInputStack()

        self.loopTasklet = None
        self.loopIsReading = True
        self.RestartLoop()
Exemple #2
0
class WebSocketHandler(tornado.websocket.WebSocketHandler):

    def open(self):
        '''
        Assign user class
        '''
        print("open")
        self.user= User(self.send_reply)

    def on_close(self):
        print("close")

    def on_message(self, message):
        parsed = tornado.escape.json_decode(message)

        # TODO: may need to be async, offload message, seperate response
        msg_body = parsed["body"]

        self.user.handle_input(msg_body)

    def send_reply(self, string):

        # TODO: various fields so can have multi window in client
        msg = {
            "id": str(uuid.uuid4()),
            "body": string,
            }
        msg["html"] = tornado.escape.to_basestring(self.render_string("message.html", message=msg))

        self.write_message(msg)
class TelnetConnection(Connection):
    def Setup(self, service, connectionID, echo=False):
        Connection.Setup(self, service, connectionID)

        self.suppressEcho = False

        self.echo = echo
        self.consoleColumns = 80
        self.consoleRows = 24
        self.terminalType = None
        self.terminalTypes = []

        self.clientName = None
        self.optionEcho = False
        self.optionLineMode = True
        self.readlineBuffer = ""

        self.telneg = TelnetNegotiation(self.TelnetNegotiationSend,
                                        self.TelnetSubnegotiation,
                                        self.TelnetCommand)
        self.telneg_terminaltype_cb = None

        if False:
            self.user = None
            self.preLoginBuffer = StringIO.StringIO()
            stackless.tasklet(self._ManageConnectionPreLogin)()

        self.user = User(self, "login")
        self.user.SetupInputStack()

        self.loopTasklet = None
        self.loopIsReading = True
        self.RestartLoop()

    def SetClientName(self, clientName):
        self.clientName = clientName

    def SetPasswordMode(self, flag):
        if flag:
            self.suppressEcho = True
            # self.telneg.will_echo()
        else:
            self.suppressEcho = False
            # self.telneg.wont_echo()

    def SetLineMode(self, flag):
        oldValue = self.user.connection.optionLineMode
        self.user.connection.optionLineMode = flag
        if oldValue != flag:
            self.RestartLoop(onlyIfReading=True)
        return oldValue

    def TelnetNegotiationSend(self, data):
        self.service and self.service.LogDebug("SEND(%s)%s%s", self.user.name,
                                               self.clientAddress,
                                               [ord(c) for c in data])
        self.send(data)

    def TelnetCommand(self, command, option):
        # print "TELNET COMMAND", command, option
        if command == "DO":
            if option == "ECHO":
                self.echo = True

    def TelnetSubnegotiation(self, result):
        if result.command == NAWS:
            self.service.LogDebug("TERMINAL SIZE %s (%s)%s", result.parameters,
                                  self.user.name, self.clientAddress)
            self.consoleColumns, self.consoleRows = result.parameters

            self.user.inputstack.OnTerminalSizeChanged(*result.parameters)
        elif result.command == TTYPE:
            if self.terminalType and result.parameters == [self.terminalType]:
                self.service.LogDebug("TERMINAL TYPE %s (%s)%s",
                                      self.terminalType, self.user.name,
                                      self.clientAddress)
                return

            self.service.LogDebug("TERMINAL TYPES %s (%s)%s",
                                  result.parameters, self.user.name,
                                  self.clientAddress)
            self.terminalTypes = result.parameters

            # Select the first one the client offered.
            self.terminalType = result.parameters[0]
            self.telneg.do_ttype(self.terminalType)
            if self.telneg_terminaltype_cb:
                self.telneg_terminaltype_cb(self.terminalType)
        elif result.command == NEW_ENVIRON:
            self.service.LogDebug("ENVIRONMENT VARIABLES %s (%s)%s",
                                  result.parameters, self.user.name,
                                  self.clientAddress)
            for k, v in result.parameters:
                if k == "SYSTEMTYPE" and v == "WIN32":
                    self.telneg.will_echo()
                    break
        else:
            raise Exception("Unhandled subnegotiation", result)

    def RestartLoop(self, onlyIfReading=False):
        if onlyIfReading and not self.loopIsReading:
            return
        if self.loopTasklet is not None:
            t = self.loopTasklet()
            if t is not None:
                t.kill()
        t = stackless.tasklet(self.ManageConnection)()
        self.loopTasklet = weakref.ref(t)

    def ManageConnection(self):
        while not self.released:
            if not self._ManageConnection():
                break

    def _ManageConnection(self):
        self.loopIsReading = True
        try:
            if self.optionLineMode:
                input = self.readline()
            else:
                if self.readlineBuffer:
                    input = self.readlineBuffer
                    self.readlineBuffer = ""
                else:
                    input = self.read(65536)
                # We may recieve an empty string if there was only negotiation.
                if input == "":
                    return True
        finally:
            self.loopIsReading = False

        if input is None:
            return False

        try:
            self.user.ReceiveInput(input)
        except Exception:
            self.service.LogException("Error dispatching input")
        return True

    def _ManageConnectionPreLogin(self):
        dataQueue = []

        def CollectIncomingData():
            data = ""
            while not self.released and data is not None:
                data = self.read(65536)
                dataQueue.append(data)

        workerTasklet = stackless.tasklet(CollectIncomingData)()

        self.send("\x1b[0c")
        self.send("MUD\r\n")

        slept = 0
        while not self.released:
            for data in dataQueue:
                if data is None:
                    return
                # print "RECEIVED AFTER", slept, "DATA", data
            del dataQueue[:]

            tasklet_sleep(0.01)
            slept += 0.01

    def OnDisconnection(self):
        super(TelnetConnection, self).OnDisconnection()

        # Notify the service of the disconnection.
        if self.user:
            self.user.OnTelnetDisconnection()
            self.user = None

        self.service.OnTelnetDisconnection(self)

    def read(self, bytes):
        s = self.recv(65536)
        #print "INPUT-CHARS", [ ord(c) for c in s ], s
        if s == "":
            return None

        buf = ""
        for s in self.telneg.feed(s):
            buf += s
        return buf

    # -----------------------------------------------------------------------
    # readline
    # -----------------------------------------------------------------------
    def readline(self):
        buf = self.readlineBuffer

        while True:
            # We need to handle all the different line endings which clients may send:
            #   \r  \r\n  \n
            ret = ""
            rIdx = buf.find('\r')
            if rIdx == -1:
                rIdx = buf.find('\n')
                if rIdx > -1:
                    ret = buf[:rIdx]
                    self.readlineBuffer = buf[rIdx + 1:]
            else:
                ret = buf[:rIdx]
                if len(buf) > rIdx + 1 and buf[rIdx + 1] == '\n':
                    self.readlineBuffer = buf[rIdx + 2:]
                else:
                    self.readlineBuffer = buf[rIdx + 1:]

            if len(ret) or rIdx == 0:
                i = ret.find('\x08')
                while i > -1:
                    if i == 0:
                        ret = ret[1:]
                    else:
                        ret = ret[:i - 1] + ret[i + 1:]
                    i = ret.find('\x08')

                # print "INPUT-LINE", [ ord(c) for c in ret ], ret
                return ret

            s = self.recv(65536)
            if s == "":
                return None
            #print "INPUT-RECEIVED", [ ord(c) for c in s ]
            #if s[0] == "\x1b":
            #    print "ESCAPE-SEQUENCE-PENDING", s

            for s2 in self.telneg.feed(s):
                # This is so not optimal yet, but it is correct which is good for now.
                for i, c in enumerate(s2):
                    if self.echo and not self.suppressEcho:
                        # print "ECHO", c
                        if c == '\x08':
                            self.send(c + " ")
                        elif c == '\r' and i == len(s2) - 1:
                            # \r and \n are expected to come in pairs.
                            # If \r is the final character, no \n was sent.
                            self.send('\n')
                        self.send(c)
                    buf += c
Exemple #4
0
 def open(self):
     '''
     Assign user class
     '''
     print("open")
     self.user= User(self.send_reply)