コード例 #1
0
ファイル: network.py プロジェクト: ringmaster/sigma-mud
class ClientSocket(asynchat.async_chat):
    def __init__(self, connection):
        asynchat.async_chat.__init__(self, connection)

        # Holds all pending text (awaiting a newline from client).
        self.buffer = ''

        self.set_terminator('\n')

        # Retains the player class tied to this socket.
        self.parent = Player(self)

    def collect_incoming_data(self, data):
        for char in data:
            if char == '\b' and len(self.buffer) > 0:
                self.buffer = self.buffer[:-1]
            elif char == '\b' or char == '\r':
                pass
            elif char in string.printable:
                self.buffer += char
                if self.parent.state == STATE_PASSWORD:
                    self.parent.send('\b \b')

    def found_terminator(self):
        data = self.buffer
        self.buffer = ''
        command.accept_command(self.parent, data)

    def handle_close(self):
        # Shunt output to parent (avoids recursion in simultaneous logouts)
        self.parent.send = lambda s: None

        if self.parent.location:
            libsigma.report(libsigma.ROOM, "$actor has left the game.",
                            self.parent)
            self.parent.location.characters.remove(self.parent)

        w = World()
        if self.parent in w.players:
            a = Archive()
            a.save(self.parent)
            w.players.remove(self.parent)

        log("NETWORK", "Client at %s closed connection" % self.addr[0])
        self.parent.socket = None
        self.close()

    def handle_accept(self):
        pass
コード例 #2
0
ファイル: network.py プロジェクト: ringmaster/sigma-mud
class ClientSocket(asynchat.async_chat):
    def __init__(self, connection):
        asynchat.async_chat.__init__(self, connection)

        # Holds all pending text (awaiting a newline from client).
        self.buffer = ''

        self.set_terminator('\n')

        # Retains the player class tied to this socket.
        self.parent = Player(self)

    def collect_incoming_data(self, data):
        for char in data:
            if char == '\b' and len(self.buffer) > 0:
                self.buffer = self.buffer[:-1]
            elif char == '\b' or char == '\r': pass
            elif char in string.printable:
                self.buffer += char
                if self.parent.state == STATE_PASSWORD:
                    self.parent.send('\b \b')

    def found_terminator(self):
        data = self.buffer
        self.buffer = ''
        command.accept_command(self.parent, data)

    def handle_close(self):
        # Shunt output to parent (avoids recursion in simultaneous logouts)
        self.parent.send = lambda s: None

        if self.parent.location:
            libsigma.report(libsigma.ROOM, "$actor has left the game.", self.parent)
            self.parent.location.characters.remove(self.parent)

        w = World()
        if self.parent in w.players:
            a = Archive()
            a.save(self.parent)
            w.players.remove(self.parent)

        log("NETWORK", "Client at %s closed connection" % self.addr[0])
        self.parent.socket = None
        self.close()

    def handle_accept(self):
        pass
コード例 #3
0
def register_thread(c, addr):

    session_key = None
    pub_key = None
    while True:
        rec = b''
        while True:
            part = c.recv(1024)
            rec += part
            if len(part) < 1024:
                break
        try:
            data = json.loads(rec.decode('ascii'))
            mac = crypto.encrypt(
                hashlib.sha256(data['message'].encode('ascii')).digest(),
                session_key) if session_key is not None else None
            if (mac.hex() if mac is not None else mac) != data['mac']:
                print("Ignored message with erroneous MAC")
                continue
            data = json.loads(data['message'])

            if data['type'] == messages.CONNECTION_REQUEST and pub_key is None:
                pub_key = serialization.load_pem_public_key(
                    bytes.fromhex(data['key']), default_backend())
                a = crypto.dh_get_private()
                A = crypto.dh_get_public(a)
                c.send(
                    json.dumps({
                        'message':
                        json.dumps({
                            'type':
                            messages.CONNECTION_REPLY,
                            'iv':
                            crypto.get_string(shuffle.iv),
                            'param':
                            A,
                            'sig':
                            rsa_priv_key.sign(
                                hashlib.sha256(
                                    str(A).encode('ascii')).digest(),
                                padding.PSS(
                                    mgf=padding.MGF1(hashes.SHA256()),
                                    salt_length=padding.PSS.MAX_LENGTH),
                                hashes.SHA256()).hex()
                        }),
                        'mac':
                        None
                    }).encode('ascii'))

            elif data['type'] == messages.CONNECTION_REPLY:
                pub_key.verify(
                    bytes.fromhex(data['sig']),
                    hashlib.sha256(str(
                        data['param']).encode('ascii')).digest(),
                    padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
                                salt_length=padding.PSS.MAX_LENGTH),
                    hashes.SHA256())
                B = data['param']
                dh_sig = data['sig']
                session_key = crypto.dh_get_shared(a, B)

            elif data[
                    'type'] == messages.REGISTER_REQUEST and session_key is not None:
                p = Player(data['name'], bytes.fromhex(data['sig']), c,
                           session_key, pub_key, B, dh_sig)
                accepted = p.name not in pseudo_db

                if accepted:
                    new_player_lock.acquire()
                    if len(players) < players_num:
                        players[c] = p
                        pseudo_players[data['name']] = p
                        print('[socket]', addr[0], ':', addr[1], '-',
                              'Registered, pseudonym:', data['name'])
                        pseudo_db.append(data['name'])
                        ok.add(p.name)
                    else:
                        c.close()
                        new_player_lock.release()
                        return
                    new_player_lock.release()

                p.send({'type': messages.REGISTER_REPLY, 'accepted': accepted})

                if accepted:
                    return

        except:
            c.close()
            return