def delete_key(self, pkfp, is_private=False): log.debug("Deleting key %s" % pkfp) base_path = self.user_keys_path if is_private else self.trusted_keys_path key_path = os.path.join(base_path, pkfp) if not os.path.exists(key_path): log.exception("Key not found! Path: %s\n%s " % (key_path, get_stack())) raise FileNotFoundError("Key not found") shutil.rmtree(key_path) log.debug("Key has been removed successfully!")
def get_torrent_info(self, infohash): """ Loads torrent info into dictionary and returns it :param infohash: string :return: torrent info string """ t_info_path = os.path.join(self.torrent_metadata_path, ("%s.json" % infohash)) if not os.path.exists(t_info_path): msg = "Torrent info file not found \n%s" % get_stack() log.exception(msg) raise FileNotFoundError(msg) with open(t_info_path, "r") as fp: return json.load(fp)
def resume_torrent(self, infohash): log.debug("Pausing torrent %s" % infohash) info = self.get_torrent_info(infohash) lt_info = lt.parse_magnet_uri(info["magnet"]) handle = self.session.find_torrent(lt_info.info_hash) if handle.is_valid(): handle.resume() ti = TorrentInfo.from_dict(self.get_torrent_info(infohash)) ti["status"] = "active" self._write_torrent_info_data( self._get_torrent_info_path(infohash), ti.dump()) else: log.exception("Error pausing torrent: handle is invalid! %s " % get_stack())
def proc_metadata_received(self, alert): t_handle = alert.handle if not t_handle.is_valid(): log.exception( "%s\n%s" % ("Error saving metadata. Handle is invalid.", get_stack())) return log.debug("Metadata received! Saving metadata...") t_info = t_handle.torrent_file() c_torrent = lt.create_torrent(t_info) entry = c_torrent.generate() infohash = t_info.info_hash() with open( os.path.join(self.torrent_metadata_path, "%s.torrent" % str(infohash)), "wb") as fp: fp.write(lt.bencode(entry))
def configure_vm(self): log.debug("Configureing imported image") try: self.message("Image imported. Configuring...") log.debug("Image imported. Configuring...") self.setup_host_only_adapter() log.debug("Network configured..") self.message("Network configured..") self.island_manager.set_new_datafolder(self.data_path) log.debug("Data folder set up... Launching VM") self.message("Data folder set up... Launching VM") log.info("Setup completed. Restarting Islands...") self.message("Setup completed. Restarting Islands...") sleep(1) self.message("Cleaning up...") self.cleanup() self.message("Cleanup completed") sleep(1) self.complete(True) except CmdExecutionError as e: self.emergency_wipe() error_message = "CmdExecutionError.\nReturn code: {retcode}" \ "\nstderr: {stderr}" \ "\nstdout: {stdout}".format(retcode=e.args[0], stderr=e.args[1], stdout=e.args[2]) log.error("%s\n%s" % (error_message, get_stack())) self.error(msg=error_message, size=16) self.complete(False, error_message) except IslandsImageNotFound as e: self.emergency_wipe() error_message = "Islands image was not found. Please restart setup." log.error(error_message) log.exception(e) self.complete(False, error_message) except Exception as e: self.emergency_wipe() error_message = "Islands VM installation error: \n{msg}".format(msg=str(e)) log.error(error_message) log.exception(e) self.complete(False, error_message)
def _process_alerts(self): while True: if self.exiting: return self.session.post_session_stats() time.sleep(.5) alerts = self.session.pop_alerts() start = time.time() while len(alerts) == 0 and time.time() - start < 1: alerts = self.session.pop_alerts() time.sleep(.1) for alert in alerts: if type(alert) in self._alert_processors: try: # log.debug("Received lt alert %s. Processing..." % str(type(alert))) self._alert_processors[type(alert)](alert) except Exception as e: log.error("Error processing alert %s: %s\n%s" % (str(type(alert)), str(e), get_stack())) log.exception(e) else: # other alerts pass time.sleep(1)
def create_torrent(self, path_to_payload, add_to_session=True): log.debug("Creating torrent for %s" % path_to_payload) if not os.path.exists(path_to_payload): raise FileNotFoundError("Path to data is invalid") storage = lt.file_storage() lt.add_files(storage, path_to_payload) ct = lt.create_torrent(storage) ct.add_node("127.0.0.1", 6881) lt.set_piece_hashes(ct, os.path.dirname(path_to_payload)) entry = ct.generate() if entry is None: log.exception( "%s\n%s" % ("Torrent create failed: bencode entry is undefined.", get_stack())) raise TorrentCreateError t_info = lt.torrent_info(entry) #t_info.save_path = path_to_payload magnet = lt.make_magnet_uri(t_info) atp = lt.add_torrent_params() atp.ti = t_info infohash = str(t_info.info_hash()) atp.info_hash = t_info.info_hash() atp.save_path = os.path.dirname(path_to_payload) atp.name = entry[b"info"][b"name"] if add_to_session: log.debug("Adding new torrent to session") handle = self._add_torrent(atp) handle.force_recheck() self.save_torrent_info(atp, magnet, "active", path_to_payload) with open( os.path.join(self.torrent_metadata_path, "%s.torrent" % str(infohash)), "wb") as fp: fp.write(lt.bencode(entry)) log.debug("Torrent created successfully")
def verify_image(self, temp_dir): """ Given the path to temporary directory where image data has been unpacked scans the structure of the image data and verifies hashes and signatures Also checks if public key is trusted :param temp_dir: temporary directory where content of zip archive was unpacked it should be a folder with 3 files in it :return: list of found errors. List will be empty if no errors found Errors come from ImageVerificationError enum """ errors = [] image_dir = os.path.join(temp_dir, self.config["image_dirname"]) try: path_to_image, path_to_info, path_to_signature = self._get_paths(image_dir) except InvalidImageContent as e: log.info("Invalid image content.") errors.append(ImageVerificationError.IMAGE_DATA_INVALID) return errors except Exception as e: log.exception(e) raise e info, info_sign = None, None ic = ICrypto() # load info with open(path_to_info, "r") as info_fp, \ open(path_to_signature, "rb") as sign_fp: info = json.load(info_fp) info_sign = sign_fp.read() # checking protocol if "authoring_protocol" not in info or info["authoring_protocol"] != self.authoring_protocol: log.exception("Authoring protocol don't match! \n%s" % get_stack()) errors.append(ImageVerificationError.AUTHORING_PROTOCOL_MISMATCH) ic.hash_file("image_hash", path_to_image) image_hash = ic["image_hash"] if bytes(info["hash"], "utf8") != image_hash: log.error("Image hash does not match with hash specified in the info: \n%s\n%s" % (str(image_hash), str(info["hash"]))) errors.append(ImageVerificationError.HASH_MISMATCH) try: ic.hash_file("infohash", path_to_info) \ .add_blob("sign", info_sign) \ .load_pem_public_key("pub", bytes(info["public_key"], "utf8")) \ .public_key_verify("res_infohash", "infohash", "pub", "sign") \ .get_public_key_fingerprint("pkfp", "pub") \ .add_blob("image_hash", image_hash) \ .add_blob("image_sign", bytes(info["sign"], "utf8")) \ .public_key_verify("res_image", "image_hash", "pub", "image_sign") except Exception as e: errors.append(ImageVerificationError.CRYPTO_ERROR) return errors if ic["res_infohash"] is False: log.error("Info signature is invalid") errors.append(ImageVerificationError.INFO_SIGNATURE_INVAILD) if ic["res_image"] is False: log.error("Image signature is invalid") errors.append(ImageVerificationError.IMAGE_SIGNATURE_INVALID) if ic["pkfp"] != bytes(info["pkfp"], "utf8"): msg = "Pkfp does not match" log.error("Pkfp does not match") errors.append(msg) log.info("Checking if pkfp is in trusted keys...") if not self.key_manager.is_key_trusted(str(ic["pkfp"], "utf8")): log.error("Key is not trusted") errors.append(ImageVerificationError.KEY_NOT_TRUSTED) return errors