Ejemplo n.º 1
0
    def type_request(self, user, item):
        temperate = {
            'type': T_RESPONSE,
            'cmd': item['cmd'],
            'data': None,
            'time': time.time(),
            'uuid': item['uuid']}
        allow_list = list()
        deny_list = list()
        ack_list = list()

        if item['cmd'] == ClientCmd.PING_PONG:
            temperate['data'] = {
                'ping': item['data'],
                'pong': time.time()}
            allow_list.append(user)

        elif item['cmd'] == ClientCmd.BROADCAST:
            if item['uuid'] in self.__broadcast_uuid:
                return  # already get broadcast data
            elif self.__waiting_result.include(item['uuid']):
                return  # I'm broadcaster, get from ack
            elif not self.broadcast_check(item['data']):
                user.warn += 1
                self.__broadcast_uuid.append(item['uuid'])
                return  # not allowed broadcast data
            else:
                self.__broadcast_uuid.append(item['uuid'])
                self.broadcast_que.broadcast(item['data'])
                deny_list.append(user)
                allow_list = None
                # send ACK
                ack_list.append(user)
                # send Response
                temperate['type'] = T_REQUEST
                temperate['data'] = item['data']

        elif item['cmd'] == ClientCmd.GET_PEER_INFO:
            # [[(host,port), header],..]
            temperate['data'] = self.peers.data
            allow_list.append(user)

        elif item['cmd'] == ClientCmd.GET_NEARS:
            temperate['data'] = {user.get_host_port(): user.serialize() for user in self.p2p.user}
            allow_list.append(user)

        elif item['cmd'] == ClientCmd.CHECK_REACHABLE:
            try:
                port = item['data']['port']
            except:
                port = user.p2p_port
            temperate['data'] = is_reachable(host=user.host_port[0], port=port)
            allow_list.append(user)

        elif item['cmd'] == ClientCmd.FILE_CHECK:
            # {'hash': hash, 'uuid': uuid}
            file_hash = item['data']['hash']
            file_path = os.path.join(V.TMP_PATH, 'file.' + file_hash + '.dat')
            f_existence = os.path.exists(file_path)
            if 'uuid' in item['data']:
                f_asked = self.__user2user_route.include(item['data']['uuid'])
            else:
                f_asked = False
            temperate['data'] = {'have': f_existence, 'asked': f_asked}
            allow_list.append(user)

        elif item['cmd'] == ClientCmd.FILE_GET:
            def asking():
                # ファイル要求元のNodeに近いNode群を無視する
                nears_name = set(user_.name for user_ in self.p2p.user)
                best_name = list(nears_name - already_asked_user)
                random.shuffle(best_name)
                nears_name = list(nears_name)
                random.shuffle(nears_name)
                # nearを最後に探索するように並び替え
                try_to_ask_name = best_name + nears_name

                # ファイル所持Nodeを見つけたら即コマンド送る、それ以外は候補をリスト化
                candidates = list()
                for ask_name in try_to_ask_name:
                    try:
                        ask_user = self.p2p.name2user(ask_name)
                        if ask_user is None:
                            continue
                        send_data = {'hash': file_hash, 'uuid': item['uuid']}
                        dummy, data = self.send_command(cmd=ClientCmd.FILE_CHECK, user=ask_user,
                                                        data=send_data, timeout=2)
                    except Exception as e:
                        logging.debug("Check file existence one by one, %s", e)
                        continue
                    if data['have']:
                        # ファイル所持Nodeを発見したのでGETを即送信
                        hopeful = ask_user
                        break
                    elif not data['asked']:
                        candidates.append(ask_user)
                    else:
                        pass
                else:
                    # 候補がいなければここで探索終了
                    if len(candidates) == 0:
                        temperate['type'] = T_RESPONSE
                        self._send_msg(item=temperate, allows=[user], denys=list())
                        logging.debug("Asking, stop asking file.")
                        return
                    else:
                        hopeful = random.choice(candidates)  # 一番新しいのを候補

                logging.debug("Asking, Candidate={}, ask=>{}".format(len(candidates), hopeful.name))
                try:
                    data = {'hash': file_hash, 'asked': nears_name}
                    self.__user2user_route.put(uuid=item['uuid'], item=(user, hopeful))
                    from_client, data = self.send_command(ClientCmd.FILE_GET, data,
                                                          item['uuid'], user=hopeful, timeout=5)
                    temperate['data'] = data
                    if data is None:
                        logging.debug("Asking failed from {} {}".format(hopeful.name, file_hash))
                    else:
                        logging.debug("Asking success {} {}".format(hopeful.name, file_hash))
                except Exception as e:
                    logging.debug("Asking raised {} {} {}".format(hopeful.name, file_hash, e))
                    temperate['data'] = None
                temperate['type'] = T_RESPONSE
                count = self._send_msg(item=temperate, allows=[user], denys=list())
                logging.debug("Response file to {} {}({})".format(user.name, count, file_hash))
                return

            def sending():
                with open(file_path, mode='br') as f:
                    raw = f.read()
                temperate['type'] = T_RESPONSE
                temperate['data'] = raw
                self.__user2user_route.put(uuid=item['uuid'], item=(user, user))
                if 0 < self._send_msg(item=temperate, allows=[user], denys=list()):
                    logging.debug("Send file to {} {}".format(user.name, file_hash))
                else:
                    logging.debug("Failed send file to {} {}".format(user.name, file_hash))

            if self.__user2user_route.include(item['uuid']):
                return
            logging.debug("Asked file get by {}".format(user.name))
            file_hash = item['data']['hash']
            already_asked_user = set(item['data']['asked'])
            file_path = os.path.join(V.TMP_PATH, 'file.' + file_hash + '.dat')
            # When you have file, sending. When you don't have file, asking
            if os.path.exists(file_path):
                Thread(target=sending, name='Sending', daemon=True).start()
            elif V.F_FILE_CONTINUE_ASKING:
                # Default disable
                Thread(target=asking, name='Asking', daemon=True).start()

        elif item['cmd'] == ClientCmd.FILE_DELETE:
            item_ = item['data']
            file_hash = item_['hash']
            signer_pk = item_['signer']
            sign = item_['sign']
            cert_sign = item_['cert']['sign']
            master_pk = item_['cert']['master']
            cert_start = item_['cert']['start']
            cert_stop = item_['cert']['stop']

            if not(cert_start < int(time.time()) < cert_stop):
                return  # old signature
            elif master_pk not in C.MASTER_KEYS:
                return
            elif item['uuid'] in self.__broadcast_uuid:
                return  # already get broadcast data
            elif self.__waiting_result.include(item['uuid']):
                return  # I'm broadcaster, get from ack

            self.__broadcast_uuid.append(item['uuid'])
            cert_raw = bjson.dumps((master_pk, signer_pk, cert_start, cert_stop), compress=False)
            sign_raw = bjson.dumps((file_hash, item['uuid']), compress=False)
            deny_list.append(user)
            allow_list = None
            # send ACK
            ack_list.append(user)
            # send Response
            temperate['type'] = T_REQUEST
            temperate['data'] = item['data']
            # delete file check
            try:
                logging.debug("1:Delete request {}".format(file_hash))
                ecc = Encryption()
                ecc.pk = master_pk  # 署名者の署名者チェック
                ecc.verify(msg=cert_raw, signature=cert_sign)
                ecc.pk = signer_pk  # 署名者チェック
                ecc.verify(msg=sign_raw, signature=sign)
                if self.remove_file(file_hash):
                    logging.info("2:Delete request accepted!")
            except ValueError:
                allow_list = list()  # No sending

        elif item['cmd'] == ClientCmd.DIRECT_CMD:
            def direct_cmd():
                data = item['data']
                temperate['data'] = self.event.work(cmd=data['cmd'], data=data['data'])
                self._send_msg(item=temperate, allows=[user])
            if 'cmd' in item['data'] and item['data']['cmd'] in self.event:
                Thread(target=direct_cmd, name='DirectCmd', daemon=True).start()
        else:
            pass

        # send message
        send_count = self._send_msg(item=temperate, allows=allow_list, denys=deny_list)
        # send ack
        ack_count = 0
        if len(ack_list) > 0:
            temperate['type'] = T_ACK
            temperate['data'] = send_count
            ack_count = self._send_msg(item=temperate, allows=ack_list)
        # debug
        if Debug.P_RECEIVE_MSG_INFO:
            logging.debug("Reply to request {} All={}, Send={}, Ack={}"
                          .format(temperate['cmd'], len(self.p2p.user), send_count, ack_count))
Ejemplo n.º 2
0
from nem_ed25519.base import Encryption

ecc = Encryption()

print("sk", ecc.secret_key())
print("pk", ecc.public_key())
print("ck", ecc.get_address())

msg = b'hello world nice day.'
signature = ecc.sign(msg, encode='base64')
print("sign", signature)
ecc.verify(msg, signature)

enc = ecc.encrypt(ecc.pk, msg, encode='base64')
print(enc)
print(ecc.decrypt(ecc.pk, enc))