Exemple #1
0
    def __handle_privmsg(self, source, target, message):
        nick = get_irc_nick(source)
        if target == self.nick:
            if message[0] == '\x01':
                endindex = message[1:].find('\x01')
                if endindex == -1:
                    return
                ctcp = message[1:endindex + 1]
                if ctcp.upper() == 'VERSION':
                    self.send_raw('PRIVMSG ' + nick +
                                  ' :\x01VERSION xchat 2.8.8 Ubuntu\x01')
                    return

            if nick not in self.built_privmsg:
                if message[0] != COMMAND_PREFIX:
                    log.debug('message not a cmd')
                    return
                # new message starting
                cmd_string = message[1:].split(' ')[0]
                if cmd_string not in plaintext_commands + encrypted_commands:
                    log.debug('cmd not in cmd_list, line="' + message + '"')
                    return
                self.built_privmsg[nick] = [cmd_string, message[:-2]]
            else:
                self.built_privmsg[nick][1] += message[:-2]
            box, encrypt = self.__get_encryption_box(
                self.built_privmsg[nick][0], nick)
            if message[-1] == ';':
                self.waiting[nick] = True
            elif message[-1] == '~':
                self.waiting[nick] = False
                if encrypt:
                    if not box:
                        log.debug('error, dont have encryption box object for '
                                  + nick + ', dropping message')
                        return
                    # need to decrypt everything after the command string
                    to_decrypt = ''.join(self.built_privmsg[nick][1].split(' ')[
                        1])
                    try:
                        decrypted = decode_decrypt(to_decrypt, box)
                    except ValueError as e:
                        log.debug('valueerror when decrypting, skipping: ' +
                                  repr(e))
                        return
                    parsed = self.built_privmsg[nick][1].split(' ')[
                        0] + ' ' + decrypted
                else:
                    parsed = self.built_privmsg[nick][1]
                # wipe the message buffer waiting for the next one
                del self.built_privmsg[nick]
                log.debug("<<privmsg nick=%s message=%s" % (nick, parsed))
                self.__on_privmsg(nick, parsed)
            else:
                # drop the bad nick
                del self.built_privmsg[nick]
        elif target == self.channel:
            log.debug("<<pubmsg nick=%s message=%s" % (nick, message))
            self.__on_pubmsg(nick, message)
        else:
            log.debug('what is this? privmsg src=%s target=%s message=%s;' %
                      (source, target, message))
Exemple #2
0
    def on_privmsg(self, nick, message):
        """handles the case when a private message is received"""
        #Aberrant short messages should be handled by subclasses
        #in _privmsg, but this constitutes a sanity check. Note that
        #messages which use an encrypted_command but present no
        #ciphertext will be rejected with the ValueError on decryption.
        #Other ill formatted messages will be caught in the try block.
        if len(message) < 2:
            return

        if message[0] != COMMAND_PREFIX:
            log.debug('message not a cmd')
            return
        cmd_string = message[1:].split(' ')[0]
        if cmd_string not in plaintext_commands + encrypted_commands:
            log.debug('cmd not in cmd_list, line="' + message + '"')
            return
        #Verify nick ownership
        sig = message[1:].split(' ')[-2:]
        #reconstruct original message without cmd
        rawmessage = ' '.join(message[1:].split(' ')[1:-2])
        #sanity check that the sig was appended properly
        if len(sig) != 2 or len(rawmessage) == 0:
            log.debug("Sig not properly appended to privmsg, ignoring")
            return
        if not self.verify_nick(nick, sig, rawmessage):
            #This is an impostor; just ignore
            log.debug("Message received from unverified counterparty; ignoring")
            return

        #Marks the nick as active on this channel; note *only* if verified.
        #Otherwise squatter/attacker can persuade us to send privmsgs to him.
        if self.on_privmsg_trigger:
            self.on_privmsg_trigger(nick, self)
        #strip sig from message for processing, having verified
        message = " ".join(message[1:].split(" ")[:-2])
        for command in message.split(COMMAND_PREFIX):
            _chunks = command.split(" ")

            #Decrypt if necessary
            if _chunks[0] in encrypted_commands:
                box, encrypt = self.get_encryption_box(_chunks[0], nick)
                if encrypt:
                    if not box:
                        log.debug('error, dont have encryption box object for '
                                  + nick + ', dropping message')
                        return
                    # need to decrypt everything after the command string
                    to_decrypt = ''.join(_chunks[1:])
                    try:
                        decrypted = decode_decrypt(to_decrypt, box)
                    except ValueError as e:
                        log.debug('valueerror when decrypting, skipping: ' +
                                  repr(e))
                        return
                    #rebuild the chunks array as if it had been plaintext
                    _chunks = [_chunks[0]] + decrypted.split(" ")

            # looks like a very similar pattern for all of these
            # check for a command name, parse arguments, call a function
            # maybe we need some eval() trickery to do it better

            try:
                # orderbook watch commands
                if self.check_for_orders(nick, _chunks):
                    pass
                # taker commands
                elif _chunks[0] == 'pubkey':
                    maker_pk = _chunks[1]
                    if self.on_pubkey:
                        self.on_pubkey(nick, maker_pk)
                elif _chunks[0] == 'ioauth':
                    utxo_list = _chunks[1].split(',')
                    auth_pub = _chunks[2]
                    cj_addr = _chunks[3]
                    change_addr = _chunks[4]
                    btc_sig = _chunks[5]
                    if self.on_ioauth:
                        self.on_ioauth(nick, utxo_list, auth_pub, cj_addr,
                                       change_addr, btc_sig)
                elif _chunks[0] == 'sig':
                    sig = _chunks[1]
                    if self.on_sig:
                        self.on_sig(nick, sig)

                # maker commands
                if self.check_for_commitments(nick, _chunks, private=True):
                    pass
                if _chunks[0] == 'fill':
                    try:
                        oid = int(_chunks[1])
                        amount = int(_chunks[2])
                        taker_pk = _chunks[3]
                        if len(_chunks) > 4:
                            commit = _chunks[4]
                        else:
                            commit = None
                    except (ValueError, IndexError) as e:
                        self.send_error(nick, str(e))
                    if self.on_order_fill:
                        self.on_order_fill(nick, oid, amount, taker_pk, commit)
                elif _chunks[0] == 'auth':
                    try:
                        cr = _chunks[1]
                    except (ValueError, IndexError) as e:
                        self.send_error(nick, str(e))
                    if self.on_seen_auth:
                        self.on_seen_auth(nick, cr)
                elif _chunks[0] == 'tx':
                    b64tx = _chunks[1]
                    try:
                        txhex = base64.b64decode(b64tx).encode('hex')
                    except TypeError as e:
                        self.send_error(nick, 'bad base64 tx. ' + repr(e))
                    if self.on_seen_tx:
                        self.on_seen_tx(nick, txhex)
                elif _chunks[0] == 'push':
                    b64tx = _chunks[1]
                    try:
                        txhex = base64.b64decode(b64tx).encode('hex')
                    except TypeError as e:
                        self.send_error(nick, 'bad base64 tx. ' + repr(e))
                    if self.on_push_tx:
                        self.on_push_tx(nick, txhex)
            except CJPeerError:
                # TODO proper error handling
                log.debug('cj peer error TODO handle')
                continue
Exemple #3
0
    def __handle_privmsg(self, source, target, message):
        nick = get_irc_nick(source)
        if target == self.nick:
            if message[0] == '\x01':
                endindex = message[1:].find('\x01')
                if endindex == -1:
                    return
                ctcp = message[1:endindex + 1]
                if ctcp.upper() == 'VERSION':
                    self.send_raw('PRIVMSG ' + nick +
                                  ' :\x01VERSION xchat 2.8.8 Ubuntu\x01')
                    return

            if nick not in self.built_privmsg:
                if message[0] != COMMAND_PREFIX:
                    log.debug('message not a cmd')
                    return
                # new message starting
                cmd_string = message[1:].split(' ')[0]
                if cmd_string not in plaintext_commands + encrypted_commands:
                    log.debug('cmd not in cmd_list, line="' + message + '"')
                    return
                self.built_privmsg[nick] = [cmd_string, message[:-2]]
            else:
                self.built_privmsg[nick][1] += message[:-2]
            box, encrypt = self.__get_encryption_box(
                self.built_privmsg[nick][0], nick)
            if message[-1] == ';':
                self.waiting[nick] = True
            elif message[-1] == '~':
                self.waiting[nick] = False
                if encrypt:
                    if not box:
                        log.debug(
                            'error, dont have encryption box object for ' +
                            nick + ', dropping message')
                        return
                    # need to decrypt everything after the command string
                    to_decrypt = ''.join(
                        self.built_privmsg[nick][1].split(' ')[1])
                    try:
                        decrypted = decode_decrypt(to_decrypt, box)
                    except ValueError as e:
                        log.debug('valueerror when decrypting, skipping: ' +
                                  repr(e))
                        return
                    parsed = self.built_privmsg[nick][1].split(
                        ' ')[0] + ' ' + decrypted
                else:
                    parsed = self.built_privmsg[nick][1]
                # wipe the message buffer waiting for the next one
                del self.built_privmsg[nick]
                log.debug("<<privmsg nick=%s message=%s" % (nick, parsed))
                self.__on_privmsg(nick, parsed)
            else:
                # drop the bad nick
                del self.built_privmsg[nick]
        elif target == self.channel:
            log.debug("<<pubmsg nick=%s message=%s" % (nick, message))
            self.__on_pubmsg(nick, message)
        else:
            log.debug('what is this? privmsg src=%s target=%s message=%s;' %
                      (source, target, message))
Exemple #4
0
    def on_privmsg(self, nick, message):
        """handles the case when a private message is received"""
        if message[0] != COMMAND_PREFIX:
            log.debug('message not a cmd')
            return
        cmd_string = message[1:].split(' ')[0]
        if cmd_string not in plaintext_commands + encrypted_commands:
            log.debug('cmd not in cmd_list, line="' + message + '"')
            return
        for command in message[1:].split(COMMAND_PREFIX):
            _chunks = command.split(" ")

            #Decrypt if necessary
            if _chunks[0] in encrypted_commands:
                box, encrypt = self.get_encryption_box(_chunks[0], nick)
                if encrypt:
                    if not box:
                        log.debug('error, dont have encryption box object for '
                                  + nick + ', dropping message')
                        return
                    # need to decrypt everything after the command string
                    to_decrypt = ''.join(_chunks[1:])
                    try:
                        decrypted = decode_decrypt(to_decrypt, box)
                    except ValueError as e:
                        log.debug('valueerror when decrypting, skipping: ' +
                                  repr(e))
                        return
                    #rebuild the chunks array as if it had been plaintext
                    _chunks = [_chunks[0]] + decrypted.split(" ")

            # looks like a very similar pattern for all of these
            # check for a command name, parse arguments, call a function
            # maybe we need some eval() trickery to do it better

            try:
                # orderbook watch commands
                if self.check_for_orders(nick, _chunks):
                    pass

                # taker commands
                elif _chunks[0] == 'pubkey':
                    maker_pk = _chunks[1]
                    if self.on_pubkey:
                        self.on_pubkey(nick, maker_pk)
                elif _chunks[0] == 'ioauth':
                    utxo_list = _chunks[1].split(',')
                    cj_pub = _chunks[2]
                    change_addr = _chunks[3]
                    btc_sig = _chunks[4]
                    if self.on_ioauth:
                        self.on_ioauth(nick, utxo_list, cj_pub, change_addr,
                                       btc_sig)
                elif _chunks[0] == 'sig':
                    sig = _chunks[1]
                    if self.on_sig:
                        self.on_sig(nick, sig)

                # maker commands
                if _chunks[0] == 'fill':
                    try:
                        oid = int(_chunks[1])
                        amount = int(_chunks[2])
                        taker_pk = _chunks[3]
                    except (ValueError, IndexError) as e:
                        self.send_error(nick, str(e))
                    if self.on_order_fill:
                        self.on_order_fill(nick, oid, amount, taker_pk)
                elif _chunks[0] == 'auth':
                    try:
                        i_utxo_pubkey = _chunks[1]
                        btc_sig = _chunks[2]
                    except (ValueError, IndexError) as e:
                        self.send_error(nick, str(e))
                    if self.on_seen_auth:
                        self.on_seen_auth(nick, i_utxo_pubkey, btc_sig)
                elif _chunks[0] == 'tx':
                    b64tx = _chunks[1]
                    try:
                        txhex = base64.b64decode(b64tx).encode('hex')
                    except TypeError as e:
                        self.send_error(nick, 'bad base64 tx. ' + repr(e))
                    if self.on_seen_tx:
                        self.on_seen_tx(nick, txhex)
                elif _chunks[0] == 'push':
                    b64tx = _chunks[1]
                    try:
                        txhex = base64.b64decode(b64tx).encode('hex')
                    except TypeError as e:
                        self.send_error(nick, 'bad base64 tx. ' + repr(e))
                    if self.on_push_tx:
                        self.on_push_tx(nick, txhex)
            except CJPeerError:
                # TODO proper error handling
                log.debug('cj peer error TODO handle')
                continue