Ejemplo n.º 1
0
class Handler:
    "Command parser, where all player commands go."

    def unknown(self, session, cmd):
        session.push(tpl.UNKNOWN_CMD % str(cmd))

    def handle(self, session, line):
        #Time of last command executed. Will be used for external timeout cleanup.
        Update.setLastAction(time.time(), session.p_id)

        if not line.strip(): session.push("> ")

        # Filter the telnet commands
        self.tiac = TelnetTalk()
        self.ndata = self.tiac.listen(line)
        line = self.ndata[0]

        session.push(self.ndata[1]) # Reply accordingly

        parts = line.split(' ', 1)
        cmd = parts[0]
        if not cmd: pass

        # Easier to do it here, as EndSession is defined outside of action.py
        elif (cmd == "logout") or (cmd == "quit"):
            raise EndSession

        else:
            try: line = parts[1].strip()
            except IndexError: line = ''
            meth = getattr(Actions, 'do_'+cmd, None) # Normal commands, actions.py

            if cmd.find('@') == 0 :
                methadm = getattr(Admincmd, 'do_'+cmd.strip('@'), None) # Admin commands, admin.py
                if session.pname in self.coders and callable(methadm):
                    methadm(session, line)
                    session.push("> ")
                else:
                    self.unknown(session, cmd)
                    session.push("> ")

            elif callable(meth): # Normal command
                meth(session, line)
                session.push("> ")
            else:
                self.unknown(session, cmd)
                session.push("> ")
Ejemplo n.º 2
0
class FirstLogin:
    """Class to manage state while logging in user"""

    def __init__(self, server, addr):
        self.server = server
        self.ipaddr = addr
        self.line = None
        self.plname = None
        self.email = None
        self.ansi = None
        self.step = 1
        self.check = 0
        self.nak = []
        self.enc_pass = ''

    def echo_off(self, session):
        #session.push("\033[8m\xff\373\001") # ECHO OFF
        session.push("\xff\373\001") # ECHO OFF

    def echo_on(self, session):
        #session.push("\033[8m\xff\374\001") # ECHO ON
        session.push("\xff\374\001") # ECHO ON

    def generate_salt(self):
        salt = ""
        possible = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.;,=+!:?$%@-_"

        while len(salt) < 64:
            char = possible[randrange(len(possible))]
            if salt.find(char) == -1:
                salt += char

        return salt

    def encpass(self, ppass, salt):
        ma = sha.new()
        ma.update(salt)
        ma.update(ppass)
        return ma.hexdigest()

    def check_password(self, passtest):
        self.cchk = Select.getPassword(self.plname)

        self.test = self.encpass(passtest, self.cchk[1])
        if self.test == self.cchk[0]: return 0
        else: return -1
        
    def check_ban(self, uname):
        self.bchk = Select.getBan(uname)

        if self.bchk[0] == 1: return 1
        else: return 0

    def handle(self, session, cmd):
        """ This is ugly. asynchat doesn't implement interactive sessions so we have
            to simulate a dialog using a counter that is incremented at every step."""

        if not cmd: cmd = " "

        # Filter the telnet commands
        self.tiac = TelnetTalk()
        self.ndata = self.tiac.listen(cmd)
        self.cmd = self.ndata[0]

        session.push(self.ndata[1]) # Reply accordingly

        if self.step == 1:
            self.plname = self.cmd.lower().strip()
            if not self.plname:
                session.push(tpl.NAME_NO + tpl.NAME_INPUT)
                return
            if not self.plname.isalpha():
                session.push(tpl.NAME_ALPHA + tpl.NAME_INPUT)
                return

            wrongname = False
            badnames = open('badnames', 'r')
            for naughtyword in badnames:
                if naughtyword.strip() in self.plname:
                    wrongname = True
                    break
            badnames.close()

            if wrongname:
                session.push(tpl.NAME_BAD + tpl.NAME_INPUT)
                return

            try:
                self.nak = Select.getPlayerByName(self.plname)
                session.push(str(tpl.WELCOME % self.nak[1].capitalize()))
                session.push(tpl.PASSWORD)
                self.echo_off(session)
                self.step = 5 # Existing user
            except: 
                session.push(tpl.WELCOME_NEW)
                self.plname = str(self.plname)
                session.push(tpl.NAME_IS % self.plname.capitalize())
                session.push(tpl.PASSWORD)
                self.echo_off(session)
                self.step = 2 # New user

        elif self.step == 2:
            #self.echo_on(session)
            self.fpass = self.cmd
            if not self.fpass:
                session.push(tpl.PASSWORD)
                self.echo_off(session)
                return
            else:
                session.push(tpl.PASSWORD_CONFIRM)
                self.echo_off(session)
                self.step = 3

        elif self.step == 3:
            self.spass = self.cmd
            if self.fpass == self.spass:
                self.echo_on(session)
                session.push(tpl.ANSI)
                self.step = 6
            else:
                session.push(tpl.PASSWORD_MISMATCH)
                session.push(tpl.PASSWORD)
                self.echo_off(session)
                self.step = 2

        elif self.step == 5:
            self.echo_on(session)

            if not self.cmd:
                session.push(tpl.PASSWORD)
                self.echo_off(session)
                return

            if self.check_password(self.cmd) == 0:
                # Check if the user is banned.
                if self.check_ban(self.plname) == 1:
                    session.push(tpl.BANNED)
                    session.close()
                else:
                    session.push(tpl.LOGIN + tpl.PRESS_ENTER)
                    self.step = 8
            else:
                session.push(tpl.PASSWORD_WRONG)
                session.push(tpl.PASSWORD)
                self.echo_off(session)

        elif self.step == 6:
            self.echo_on(session)
            self.colors = cmd.lower()
            if (self.colors == "y") or (self.colors == "yes"):
                self.ansi = 'on'
            else:
                self.ansi = 'off'
            session.push(tpl.EMAIL)
            self.step = 7

        elif self.step == 7: # CHANGE
            #self.echo_on(session)
            emailreg = re.compile('^[0-9a-z_.+\-]+@[0-9a-z_.\-]+\.[a-z]{2,4}', re.IGNORECASE)
            if emailreg.match(self.cmd) != None:
                self.email = self.cmd
                self.step = 8
                self.createUser(session, self.plname, self.fpass)
            else:
                session.push(tpl.EMAIL_BAD)
                session.push(tpl.EMAIL)
                self.step = 7

        elif self.step == 8:
            self.nak = Select.getIP(self.plname)

            if self.nak[1] != None and self.nak[1] != "127.0.0.1":
                session.push(tpl.LOGIN_ALREADY_IN)
                session.close()
            else:
                # Store some basic info into the socket object.
                session.p_id = self.nak[0]
                session.pname = str(self.plname.capitalize())

                session.push("> ")
                session.enter(self.server.enterg)

        else:
            session.push(tpl.ERROR_CRITICAL)

    def createUser(self, session, pname, ppass):
        self.salty = self.generate_salt()
        self.truepass = self.encpass(ppass, self.salty)

        self.test = (pname, self.email, self.truepass, self.salty, self.ansi)
        Insert.newPlayer(self.test)

        session.push(tpl.NEW_PLAYER + tpl.PRESS_ENTER)

    def add(self, session):
        # First session reference
        self.session = session
        session.push(motd)
Ejemplo n.º 3
0
class SecondServSock(async_chat):
    #The chat server, instanced for all users

    def __init__(self, server, sock, addr):
        async_chat.__init__(self, sock)
        self.server = server
        self.ipaddr = addr
        self.set_terminator("\n")
        self.name = None
        self.data = []
        self.sock = sock
        self.enter(FirstLogin(server, addr[0])) #Call the login procedure before anything.

    def collect_incoming_data(self, data):
        self.data.append(data)
    def found_terminator(self):
        line = (''.join(self.data))
        line = line.strip('\r')
        self.tiac = TelnetTalk()
        self.ndata = self.tiac.listen(line)
        line = self.ndata[0]
        self.data = []

        try: 
            self.room.handle(self, line)
        except EndSession:
            self.handle_close()

    def handle_close(self):
        self.ival = ipsessions.items()
        for i in self.ival:
            self.test = str(sessions[i[0]])
            self.tesb = str(self.sock)
            try:
                if (self.ipaddr[0] == i[1]) & (self.test == self.tesb):
                    self.leaver = Select.getPlayerByID(i[0])
                    self.leaver = self.leaver[1].capitalize()
                    #In any case, if the player exits, remove him.
                    Update.LogoutPlayer(i[0])
                    Log("%s disconnected from %s" % (self.leaver, self.ipaddr[0]))
                    print "%s logged out." % self.leaver

                    del sessions[i[0]]
                    del ipsessions[i[0]]

                    self.locali = Select.getAllPlayersWithIP()
                    
                    for j in self.locali:
                        self.tmpsec = sessions[j[0]]
                        if self.tmpsec == None: # Shouldn't happen, do some cleaning
                            Update.LogoutPlayer(j[0])
                        else:
                            self.tmpsec.push(tpl.LEAVE_GAME % (self.leaver,))

                    async_chat.handle_close(self)
                else: raise
            except: raise

    def enter(self, room):
        self.room = room
        room.add(self)