def test_hash(): file_hash = '87fcda7d9e7a22412e95779e2f8e70f929106c7b27a94f5f8510553ebf4624a6' hash_obj = utils.get_hashing_algorithm(file_hash) assert hash_obj.name == "sha256" filepath = os.path.join(os.path.dirname(__file__), 'data', 'file') computed_hash = utils.get_file_fingerprint(filepath, hash_obj) assert file_hash == computed_hash
def setup(self, storage, ksdata, instclass): """ The setup method that should make changes to the runtime environment according to the data stored in this object. :param storage: object storing storage-related information (disks, partitioning, bootloader, etc.) :type storage: blivet.Blivet instance :param ksdata: data parsed from the kickstart file and set in the installation process :type ksdata: pykickstart.base.BaseHandler instance :param instclass: distribution-specific information :type instclass: pyanaconda.installclass.BaseInstallClass """ # check fingerprint if given if self.fingerprint: hash_obj = utils.get_hashing_algorithm(self.fingerprint) digest = utils.get_file_fingerprint(self.raw_preinst_content_path, hash_obj) if digest != self.fingerprint: msg = "Integrity check of the content failed!" raise ContentCheckError(msg) if self.dry_run: # nothing more to be done in the dry-run mode return # evaluate rules, do automatic fixes and stop if something that cannot # be fixed automatically is wrong messages = self.rule_data.eval_rules(ksdata, storage) if any(message.type == common.MESSAGE_TYPE_FATAL for message in messages): raise MisconfigurationError("Wrong configuration detected!") # add packages needed on the target system to the list of packages # that are requested to be installed pkgs_to_install = list(REQUIRED_PACKAGES) if self.content_type == "scap-security-guide": pkgs_to_install.append("scap-security-guide") for pkg in pkgs_to_install: if pkg not in ksdata.packages.packageList: ksdata.packages.packageList.append(pkg)
def _verify_fingerprint(self, dest_filename, fingerprint=""): if not fingerprint: log.info( "OSCAP Addon: No fingerprint provided, skipping integrity check" ) return hash_obj = utils.get_hashing_algorithm(fingerprint) digest = utils.get_file_fingerprint(dest_filename, hash_obj) if digest != fingerprint: log.error( "OSCAP Addon: " f"File {dest_filename} failed integrity check - assumed a " f"{hash_obj.name} hash and '{fingerprint}', got '{digest}'") msg = _( f"OSCAP Addon: Integrity check of the content failed - {hash_obj.name} hash didn't match" ) raise content_handling.ContentCheckError(msg) log.info(f"Integrity check passed using {hash_obj.name} hash")
def _init_after_data_fetch(self, wait_for): """ Waits for data fetching to be finished, extracts it (if needed), populates the stores and evaluates pre-installation fixes from the content and marks the spoke as ready in the end. :param wait_for: name of the thread to wait for (if any) :type wait_for: str or None """ try: threadMgr.wait(wait_for) except data_fetch.DataFetchError: self._data_fetch_failed() with self._fetch_flag_lock: self._fetching = False return finally: # stop the spinner in any case fire_gtk_action(self._progress_spinner.stop) if self._addon_data.fingerprint: hash_obj = utils.get_hashing_algorithm( self._addon_data.fingerprint) digest = utils.get_file_fingerprint( self._addon_data.raw_preinst_content_path, hash_obj) if digest != self._addon_data.fingerprint: self._integrity_check_failed() # fetching done with self._fetch_flag_lock: self._fetching = False return # RPM is an archive at this phase if self._addon_data.content_type in ("archive", "rpm"): # extract the content try: fpaths = common.extract_data( self._addon_data.raw_preinst_content_path, common.INSTALLATION_CONTENT_DIR, [self._addon_data.content_path]) except common.ExtractionError as err: self._extraction_failed(err.message) # fetching done with self._fetch_flag_lock: self._fetching = False return # and populate missing fields self._content_handling_cls, files = content_handling.explore_content_files( fpaths) files = common.strip_content_dir(files) # pylint: disable-msg=E1103 self._addon_data.content_path = self._addon_data.content_path or files.xccdf self._addon_data.cpe_path = self._addon_data.cpe_path or files.cpe self._addon_data.tailoring_path = (self._addon_data.tailoring_path or files.tailoring) elif self._addon_data.content_type == "datastream": self._content_handling_cls = content_handling.DataStreamHandler elif self._addon_data.content_type == "scap-security-guide": self._content_handling_cls = content_handling.BenchmarkHandler else: raise common.OSCAPaddonError("Unsupported content type") try: self._content_handler = self._content_handling_cls( self._addon_data.preinst_content_path, self._addon_data.preinst_tailoring_path) except content_handling.ContentHandlingError: self._invalid_content() # fetching done with self._fetch_flag_lock: self._fetching = False return if self._using_ds: # populate the stores from items from the content self._ds_checklists = self._content_handler.get_data_streams_checklists( ) add_ds_ids = GtkActionList() add_ds_ids.add_action(self._ds_store.clear) for dstream in self._ds_checklists.keys(): add_ds_ids.add_action(self._add_ds_id, dstream) add_ds_ids.fire() self._update_ids_visibility() # refresh UI elements self.refresh() # let all initialization and configuration happen before we evaluate # the setup if not self._anaconda_spokes_initialized.is_set(): # only wait (and log the messages) if the event is not set yet log.debug( "OSCAP addon: waiting for all Anaconda spokes to be initialized" ) self._anaconda_spokes_initialized.wait() log.debug( "OSCAP addon: all Anaconda spokes have been initialized - continuing" ) # try to switch to the chosen profile (if any) selected = self._switch_profile() if self._addon_data.profile_id and not selected: # profile ID given, but it was impossible to select it -> invalid # profile ID given self._invalid_profile_id() return # initialize the self._addon_data.rule_data self._addon_data.rule_data = self._rule_data # update the message store with the messages self._update_message_store() # all initialized, we can now let user set parameters fire_gtk_action(self._main_notebook.set_current_page, SET_PARAMS_PAGE) # and use control buttons fire_gtk_action(really_show, self._control_buttons) # fetching done with self._fetch_flag_lock: self._fetching = False # no error self._set_error(None)
def setup(self, storage, ksdata, instclass, payload): """ The setup method that should make changes to the runtime environment according to the data stored in this object. :param storage: object storing storage-related information (disks, partitioning, bootloader, etc.) :type storage: blivet.Blivet instance :param ksdata: data parsed from the kickstart file and set in the installation process :type ksdata: pykickstart.base.BaseHandler instance :param instclass: distribution-specific information :type instclass: pyanaconda.installclass.BaseInstallClass """ if self.dry_run or not self.profile_id: # nothing more to be done in the dry-run mode or if no profile is # selected return if not os.path.exists(self.preinst_content_path) and not os.path.exists(self.raw_preinst_content_path): # content not available/fetched yet try: self._fetch_content_and_initialize() except (common.OSCAPaddonError, data_fetch.DataFetchError) as e: log.error("Failed to fetch and initialize SCAP content!") msg = _("There was an error fetching and loading the security content:\n" + "%s\n" + "The installation should be aborted. Do you wish to continue anyway?") % e if flags.flags.automatedInstall and not flags.flags.ksprompt: # cannot have ask in a non-interactive kickstart # installation raise errors.CmdlineError(msg) answ = errors.errorHandler.ui.showYesNoQuestion(msg) if answ == errors.ERROR_CONTINUE: # prevent any futher actions here by switching to the dry # run mode and let things go on self.dry_run = True return else: # Let's sleep forever to prevent any further actions and # wait for the main thread to quit the process. progressQ.send_quit(1) while True: time.sleep(100000) # check fingerprint if given if self.fingerprint: hash_obj = utils.get_hashing_algorithm(self.fingerprint) digest = utils.get_file_fingerprint(self.raw_preinst_content_path, hash_obj) if digest != self.fingerprint: log.error("Failed to fetch and initialize SCAP content!") msg = _("The integrity check of the security content failed.\n" + "The installation should be aborted. Do you wish to continue anyway?") if flags.flags.automatedInstall and not flags.flags.ksprompt: # cannot have ask in a non-interactive kickstart # installation raise errors.CmdlineError(msg) answ = errors.errorHandler.ui.showYesNoQuestion(msg) if answ == errors.ERROR_CONTINUE: # prevent any futher actions here by switching to the dry # run mode and let things go on self.dry_run = True return else: # Let's sleep forever to prevent any further actions and # wait for the main thread to quit the process. progressQ.send_quit(1) while True: time.sleep(100000) # evaluate rules, do automatic fixes and stop if something that cannot # be fixed automatically is wrong fatal_messages = [message for message in self.rule_data.eval_rules(ksdata, storage) if message.type == common.MESSAGE_TYPE_FATAL] if any(fatal_messages): msg = "Wrong configuration detected!\n" msg += "\n".join(message.text for message in fatal_messages) msg += "\nThe installation should be aborted. Do you wish to continue anyway?" if flags.flags.automatedInstall and not flags.flags.ksprompt: # cannot have ask in a non-interactive kickstart installation raise errors.CmdlineError(msg) answ = errors.errorHandler.ui.showYesNoQuestion(msg) if answ == errors.ERROR_CONTINUE: # prevent any futher actions here by switching to the dry # run mode and let things go on self.dry_run = True return else: # Let's sleep forever to prevent any further actions and wait # for the main thread to quit the process. progressQ.send_quit(1) while True: time.sleep(100000) # add packages needed on the target system to the list of packages # that are requested to be installed pkgs_to_install = list(REQUIRED_PACKAGES) if self.content_type == "scap-security-guide": pkgs_to_install.append("scap-security-guide") for pkg in pkgs_to_install: if pkg not in ksdata.packages.packageList: ksdata.packages.packageList.append(pkg)
def _init_after_data_fetch(self, wait_for): """ Waits for data fetching to be finished, extracts it (if needed), populates the stores and evaluates pre-installation fixes from the content and marks the spoke as ready in the end. :param wait_for: name of the thread to wait for (if any) :type wait_for: str or None """ try: threadMgr.wait(wait_for) except data_fetch.DataFetchError: self._data_fetch_failed() with self._fetch_flag_lock: self._fetching = False return finally: # stop the spinner in any case fire_gtk_action(self._progress_spinner.stop) if self._addon_data.fingerprint: hash_obj = utils.get_hashing_algorithm(self._addon_data.fingerprint) digest = utils.get_file_fingerprint(self._addon_data.raw_preinst_content_path, hash_obj) if digest != self._addon_data.fingerprint: self._integrity_check_failed() # fetching done with self._fetch_flag_lock: self._fetching = False return # RPM is an archive at this phase if self._addon_data.content_type in ("archive", "rpm"): # extract the content try: fpaths = common.extract_data(self._addon_data.raw_preinst_content_path, common.INSTALLATION_CONTENT_DIR, [self._addon_data.content_path]) except common.ExtractionError as err: self._extraction_failed(str(err)) # fetching done with self._fetch_flag_lock: self._fetching = False return # and populate missing fields self._content_handling_cls, files = content_handling.explore_content_files(fpaths) files = common.strip_content_dir(files) # pylint: disable-msg=E1103 self._addon_data.content_path = self._addon_data.content_path or files.xccdf self._addon_data.cpe_path = self._addon_data.cpe_path or files.cpe self._addon_data.tailoring_path = (self._addon_data.tailoring_path or files.tailoring) elif self._addon_data.content_type == "datastream": self._content_handling_cls = content_handling.DataStreamHandler elif self._addon_data.content_type == "scap-security-guide": self._content_handling_cls = content_handling.BenchmarkHandler else: raise common.OSCAPaddonError("Unsupported content type") try: self._content_handler = self._content_handling_cls(self._addon_data.preinst_content_path, self._addon_data.preinst_tailoring_path) except content_handling.ContentHandlingError: self._invalid_content() # fetching done with self._fetch_flag_lock: self._fetching = False return if self._using_ds: # populate the stores from items from the content self._ds_checklists = self._content_handler.get_data_streams_checklists() add_ds_ids = GtkActionList() add_ds_ids.add_action(self._ds_store.clear) for dstream in self._ds_checklists.keys(): add_ds_ids.add_action(self._add_ds_id, dstream) add_ds_ids.fire() self._update_ids_visibility() # refresh UI elements self.refresh() # let all initialization and configuration happen before we evaluate # the setup if not self._anaconda_spokes_initialized.is_set(): # only wait (and log the messages) if the event is not set yet log.debug("OSCAP addon: waiting for all Anaconda spokes to be initialized") self._anaconda_spokes_initialized.wait() log.debug("OSCAP addon: all Anaconda spokes have been initialized - continuing") # try to switch to the chosen profile (if any) selected = self._switch_profile() if self._addon_data.profile_id and not selected: # profile ID given, but it was impossible to select it -> invalid # profile ID given self._invalid_profile_id() return # initialize the self._addon_data.rule_data self._addon_data.rule_data = self._rule_data # update the message store with the messages self._update_message_store() # all initialized, we can now let user set parameters fire_gtk_action(self._main_notebook.set_current_page, SET_PARAMS_PAGE) # and use control buttons fire_gtk_action(really_show, self._control_buttons) # fetching done with self._fetch_flag_lock: self._fetching = False # no error self._set_error(None)
def setup(self, storage, ksdata, payload): """ The setup method that should make changes to the runtime environment according to the data stored in this object. :param storage: object storing storage-related information (disks, partitioning, bootloader, etc.) :type storage: blivet.Blivet instance :param ksdata: data parsed from the kickstart file and set in the installation process :type ksdata: pykickstart.base.BaseHandler instance """ if self.dry_run or not self.profile_id: # nothing more to be done in the dry-run mode or if no profile is # selected return if not os.path.exists(self.preinst_content_path) and not os.path.exists(self.raw_preinst_content_path): # content not available/fetched yet try: self._fetch_content_and_initialize() except (common.OSCAPaddonError, data_fetch.DataFetchError) as e: log.error("Failed to fetch and initialize SCAP content!") msg = _("There was an error fetching and loading the security content:\n" + "%s\n" + "The installation should be aborted. Do you wish to continue anyway?") % e if flags.flags.automatedInstall and not flags.flags.ksprompt: # cannot have ask in a non-interactive kickstart # installation raise errors.CmdlineError(msg) answ = errors.errorHandler.ui.showYesNoQuestion(msg) if answ == errors.ERROR_CONTINUE: # prevent any futher actions here by switching to the dry # run mode and let things go on self.dry_run = True return else: # Let's sleep forever to prevent any further actions and # wait for the main thread to quit the process. progressQ.send_quit(1) while True: time.sleep(100000) # check fingerprint if given if self.fingerprint: hash_obj = utils.get_hashing_algorithm(self.fingerprint) digest = utils.get_file_fingerprint(self.raw_preinst_content_path, hash_obj) if digest != self.fingerprint: log.error("Failed to fetch and initialize SCAP content!") msg = _("The integrity check of the security content failed.\n" + "The installation should be aborted. Do you wish to continue anyway?") if flags.flags.automatedInstall and not flags.flags.ksprompt: # cannot have ask in a non-interactive kickstart # installation raise errors.CmdlineError(msg) answ = errors.errorHandler.ui.showYesNoQuestion(msg) if answ == errors.ERROR_CONTINUE: # prevent any futher actions here by switching to the dry # run mode and let things go on self.dry_run = True return else: # Let's sleep forever to prevent any further actions and # wait for the main thread to quit the process. progressQ.send_quit(1) while True: time.sleep(100000) # evaluate rules, do automatic fixes and stop if something that cannot # be fixed automatically is wrong fatal_messages = [message for message in self.rule_data.eval_rules(ksdata, storage) if message.type == common.MESSAGE_TYPE_FATAL] if any(fatal_messages): msg = "Wrong configuration detected!\n" msg += "\n".join(message.text for message in fatal_messages) msg += "\nThe installation should be aborted. Do you wish to continue anyway?" if flags.flags.automatedInstall and not flags.flags.ksprompt: # cannot have ask in a non-interactive kickstart installation raise errors.CmdlineError(msg) answ = errors.errorHandler.ui.showYesNoQuestion(msg) if answ == errors.ERROR_CONTINUE: # prevent any futher actions here by switching to the dry # run mode and let things go on self.dry_run = True return else: # Let's sleep forever to prevent any further actions and wait # for the main thread to quit the process. progressQ.send_quit(1) while True: time.sleep(100000) # add packages needed on the target system to the list of packages # that are requested to be installed pkgs_to_install = list(REQUIRED_PACKAGES) if self.content_type == "scap-security-guide": pkgs_to_install.append("scap-security-guide") for pkg in pkgs_to_install: if pkg not in ksdata.packages.packageList: ksdata.packages.packageList.append(pkg)
def _init_after_data_fetch(self, wait_for): """ Waits for data fetching to be finished, extracts it (if needed), populates the stores and evaluates pre-installation fixes from the content and marks the spoke as ready in the end. :param wait_for: name of the thread to wait for (if any) :type wait_for: str or None """ try: threadMgr.wait(wait_for) except data_fetch.DataFetchError: self._data_fetch_failed() with self._fetch_flag_lock: self._fetching = False return finally: # stop the spinner in any case fire_gtk_action(self._progress_spinner.stop) if self._addon_data.fingerprint: hash_obj = utils.get_hashing_algorithm(self._addon_data.fingerprint) digest = utils.get_file_fingerprint(\ self._addon_data.raw_preinst_content_path, hash_obj) if digest != self._addon_data.fingerprint: msg = _("Integrity check failed") raise content_handling.ContentCheckError(msg) # RPM is an archive at this phase if self._addon_data.content_type in ("archive", "rpm"): # extract the content try: fpaths = common.extract_data(\ self._addon_data.raw_preinst_content_path, common.INSTALLATION_CONTENT_DIR, [self._addon_data.xccdf_path]) except common.ExtractionError as err: self._extraction_failed(err.message) # fetching done with self._fetch_flag_lock: self._fetching = False return # and populate missing fields self._content_handling_cls, files = \ content_handling.explore_content_files(fpaths) files = common.strip_content_dir(files) # pylint: disable-msg=E1103 self._addon_data.xccdf_path = self._addon_data.xccdf_path or files.xccdf self._addon_data.cpe_path = self._addon_data.cpe_path or files.cpe self._addon_data.tailoring_path = (self._addon_data.tailoring_path or files.tailoring) elif self._addon_data.content_type == "datastream": self._content_handling_cls = content_handling.DataStreamHandler elif self._addon_data.content_type == "scap-security-guide": self._content_handling_cls = content_handling.BenchmarkHandler else: raise common.OSCAPaddonError("Unsupported content type") try: self._content_handler = self._content_handling_cls(\ self._addon_data.preinst_content_path, self._addon_data.preinst_tailoring_path) except content_handling.ContentHandlingError: self._invalid_content() # fetching done with self._fetch_flag_lock: self._fetching = False return if self._using_ds: # populate the stores from items from the content self._ds_checklists = self._content_handler.get_data_streams_checklists() for dstream in self._ds_checklists.iterkeys(): self._add_ds_id(dstream) else: # hide the labels and comboboxes for datastream-id and xccdf-id # selection fire_gtk_action(really_hide, self._ids_box) # refresh UI elements self.refresh() # try to switch to the chosen profile (if any) self._switch_profile() # initialize the self._addon_data.rule_data self._addon_data.rule_data = self._rule_data # update the message store with the messages self._update_message_store() # no more being unitialized self._unitialized_status = None self._ready = True # all initialized, we can now let user set parameters self._main_notebook.set_current_page(SET_PARAMS_PAGE) # and use control buttons really_show(self._control_buttons) # pylint: disable-msg=E1101 hubQ.send_ready(self.__class__.__name__, True) hubQ.send_message(self.__class__.__name__, self.status) # fetching done with self._fetch_flag_lock: self._fetching = False