Coverage for org_fedora_oscap/ks/oscap.py : 60%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# # Copyright (C) 2013 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. You should have received a copy of the # GNU General Public License along with this program; if not, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # # Red Hat Author(s): Vratislav Podzimek <vpodzime@redhat.com> #
# export OSCAPdata class to prevent Anaconda's collect method from taking # AddonData class instead of the OSCAPdata class # @see: pyanaconda.kickstart.AnacondaKSHandler.__init__
"scap-security-guide", )
# LABEL:?, hdaX:?, )
"""Exception for reporting misconfiguration."""
""" Class parsing and storing data for the OSCAP addon.
:see: pyanaconda.addons.AddonData
"""
""" :param name: name of the addon :type name: str
"""
# do not call the parent's __init__ more than once
# values specifying the content
# additional values
# certificate to verify HTTPS connection or signed data
# internal values
""" What should end up in the resulting kickstart file, i.e. string representation of the stored data.
"""
# the addon was run in the dry run mode, omit it from the kickstart return ""
self.tailoring_path)
ret += "\n%s" % key_value_pair("fingerprint", self.fingerprint)
ret += "\n%s" % key_value_pair("certificates", self.certificates)
else: msg = "Unsupported content type '%s' in the %s addon" % (value, self.name) raise KickstartValueError(msg)
for prefix in SUPPORTED_URL_PREFIXES): else: msg = "Unsupported url '%s' in the %s addon" % (value, self.name) raise KickstartValueError(msg)
# need to be checked?
# need to be checked?
# need to be checked?
# need to be checked?
# need to be checked?
# need to be checked?
self.certificates = value
""" The handle_line method that is called with every line from this addon's %addon section of the kickstart file.
:param line: a single line from the %addon section :type line: str
"""
"content-url": self._parse_content_url, "content-path": self._parse_content_path, "datastream-id": self._parse_datastream_id, "profile": self._parse_profile_id, "xccdf-id": self._parse_xccdf_id, "xccdf-path": self._parse_content_path, "cpe-path": self._parse_cpe_path, "tailoring-path": self._parse_tailoring_path, "fingerprint": self._parse_fingerprint, "certificates": self._parse_certificates, }
msg = "Unknown item '%s' for %s addon" % (line, self.name) raise KickstartParseError(msg)
""" The finalize method that is called when the end of the %addon section (the %end line) is reached. It means no more kickstart data will come.
"""
# check provided data
"or archive is used"
msg = "Content type set to RPM, but the content URL doesn't end "\ "with '.rpm'" raise KickstartValueError(msg)
for arch_type in SUPPORTED_ARCHIVES) "file '%s'" % self.content_url
# do some initialization magic in case of SSG if not common.ssg_available(): msg = "SCAP Security Guide not found on the system" raise KickstartValueError(msg)
self.content_path = common.SSG_DIR + common.SSG_CONTENT
def content_defined(self): return self.content_url or self.content_type == "scap-security-guide"
def content_name(self): raise ValueError("Using scap-security-guide, no single content file")
msg = "Unsupported url '%s' in the %s addon" % (self.content_url, self.name) raise KickstartValueError(msg)
def raw_preinst_content_path(self): """Path to the raw (unextracted, ...) pre-installation content file"""
self.content_name)
def raw_postinst_content_path(self): """Path to the raw (unextracted, ...) post-installation content file"""
self.content_name)
def preinst_content_path(self): """Path to the pre-installation content file"""
self.content_name) # SSG is not copied to the standard place return self.content_path else: self.content_path)
def postinst_content_path(self): """Path to the post-installation content file"""
self.content_name) # no path magic in case of RPM (SSG is installed as an RPM) else: return utils.join_paths(common.TARGET_CONTENT_DIR, self.content_path)
def preinst_tailoring_path(self): """Path to the pre-installation tailoring file (if any)"""
return ""
self.tailoring_path)
def postinst_tailoring_path(self): """Path to the post-installation tailoring file (if any)"""
return ""
# no path magic in case of RPM return self.tailoring_path
self.tailoring_path)
"""Fetch content and initialize from it"""
data_fetch.fetch_data(self.content_url, self.raw_preinst_content_path, self.certificates) # RPM is an archive at this phase if self.content_type in ("archive", "rpm"): # extract the content common.extract_data(self.raw_preinst_content_path, common.INSTALLATION_CONTENT_DIR, [self.content_path])
rules = common.get_fix_rules_pre(self.profile_id, self.preinst_content_path, self.datastream_id, self.xccdf_id, self.preinst_tailoring_path)
# parse and store rules with a clean RuleData instance self.rule_data = rule_handling.RuleData() for rule in rules.splitlines(): self.rule_data.new_rule(rule)
""" 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)
""" The execute method that should make changes to the installed system. It is called only once in the post-install setup phase.
:see: setup :param users: information about created users :type users: pyanaconda.users.Users 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
target_content_dir = utils.join_paths(getSysroot(), common.TARGET_CONTENT_DIR) utils.ensure_dir_exists(target_content_dir)
if self.content_type == "datastream": shutil.copy2(self.preinst_content_path, target_content_dir) elif self.content_type == "rpm": # copy the RPM to the target system shutil.copy2(self.raw_preinst_content_path, target_content_dir)
# and install it with yum ret = util.execInSysroot("yum", ["-y", "--nogpg", "install", self.raw_postinst_content_path]) if ret != 0: raise common.ExtractionError("Failed to install content " "RPM to the target system") elif self.content_type == "scap-security-guide": # nothing needed pass else: utils.universal_copy(utils.join_paths(common.INSTALLATION_CONTENT_DIR, "*"), target_content_dir) if os.path.exists(self.preinst_tailoring_path): shutil.copy2(self.preinst_tailoring_path, target_content_dir)
common.run_oscap_remediate(self.profile_id, self.postinst_content_path, self.datastream_id, self.xccdf_id, self.postinst_tailoring_path, chroot=getSysroot())
"""Clear all the stored values."""
self.__init__(self.name, just_clear=True) |