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))
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))