def status(cfg: UAConfig, show_beta: bool = False) -> Dict[str, Any]:
    """Return status as a dict, using a cache for non-root users

    When unattached, get available resources from the contract service
    to report detailed availability of different resources for this
    machine.

    Write the status-cache when called by root.
    """
    if os.getuid() != 0:
        response = cast("Dict[str, Any]", cfg.read_cache("status-cache"))
        if not response:
            response = _unattached_status(cfg)
    elif not cfg.is_attached:
        response = _unattached_status(cfg)
    else:
        response = _attached_status(cfg)

    response.update(_get_config_status(cfg))

    if os.getuid() == 0:
        cfg.write_cache("status-cache", response)

        # Try to remove fix reboot notices if not applicable
        if not util.should_reboot():
            cfg.remove_notice(
                "",
                messages.ENABLE_REBOOT_REQUIRED_TMPL.format(
                    operation="fix operation"
                ),
            )

    response = _handle_beta_resources(cfg, show_beta, response)

    return response
示例#2
0
 def _check_for_reboot(self) -> bool:
     """Check if system needs to be rebooted."""
     reboot_required = util.should_reboot(
         installed_pkgs=set(self.packages),
         installed_pkgs_regex=set(["linux-.*-realtime"]),
     )
     event.needs_reboot(reboot_required)
     return reboot_required
示例#3
0
    def check_for_reboot_msg(self, operation: str) -> None:
        """Check if user should be alerted that a reboot must be performed.

        @param operation: The operation being executed.
        """
        if util.should_reboot():
            print(
                status.MESSAGE_ENABLE_REBOOT_REQUIRED_TMPL.format(
                    operation=operation
                )
            )
    def application_status(
        self,
    ) -> Tuple[ApplicationStatus, Optional[messages.NamedMessage]]:
        super_status, super_msg = super().application_status()

        if util.is_container() and not util.should_reboot():
            self.cfg.remove_notice(
                "", messages.FIPS_SYSTEM_REBOOT_REQUIRED.msg
            )
            return super_status, super_msg

        if os.path.exists(self.FIPS_PROC_FILE):
            self.cfg.remove_notice(
                "", messages.FIPS_SYSTEM_REBOOT_REQUIRED.msg
            )
            self.cfg.remove_notice("", messages.FIPS_REBOOT_REQUIRED_MSG)
            if util.load_file(self.FIPS_PROC_FILE).strip() == "1":
                self.cfg.remove_notice(
                    "", messages.NOTICE_FIPS_MANUAL_DISABLE_URL
                )
                return super_status, super_msg
            else:
                self.cfg.remove_notice(
                    "", messages.FIPS_DISABLE_REBOOT_REQUIRED
                )
                self.cfg.add_notice(
                    "", messages.NOTICE_FIPS_MANUAL_DISABLE_URL
                )
                return (
                    ApplicationStatus.DISABLED,
                    messages.FIPS_PROC_FILE_ERROR.format(
                        file_name=self.FIPS_PROC_FILE
                    ),
                )
        else:
            self.cfg.remove_notice("", messages.FIPS_DISABLE_REBOOT_REQUIRED)

        if super_status != ApplicationStatus.ENABLED:
            return super_status, super_msg
        return (
            ApplicationStatus.ENABLED,
            messages.FIPS_REBOOT_REQUIRED,
        )
示例#5
0
    def _get_config_status(self) -> "Dict[str, str]":
        """Return a dict with configStatus and configStatusDetails keys.

            Values for configStatus will be one of UserFacingConfigStatus enum:
                inactive, active, reboot-required
            configStatusDescription will provide more details about that state.
        """
        userStatus = status.UserFacingConfigStatus
        status_val = userStatus.INACTIVE.value
        status_desc = status.MESSAGE_NO_ACTIVE_OPERATIONS
        (lock_pid, lock_holder) = util.check_lock_info(self.data_path("lock"))
        if lock_pid > 0:
            status_val = userStatus.ACTIVE.value
            status_desc = status.MESSAGE_LOCK_HELD.format(
                pid=lock_pid, lock_holder=lock_holder)
        elif util.should_reboot():
            status_val = userStatus.REBOOTREQUIRED.value
            status_desc = status.MESSAGE_ENABLE_REBOOT_REQUIRED_TMPL.format(
                operation="configuration changes")
        return {"configStatus": status_val, "configStatusDetails": status_desc}
    def _check_for_reboot_msg(
        self, operation: str, silent: bool = False
    ) -> None:
        """Check if user should be alerted that a reboot must be performed.

        @param operation: The operation being executed.
        @param silent: Boolean set True to silence print/log of messages
        """
        reboot_required = util.should_reboot()
        event.needs_reboot(reboot_required)
        if reboot_required:
            if not silent:
                event.info(
                    messages.ENABLE_REBOOT_REQUIRED_TMPL.format(
                        operation=operation
                    )
                )
            if operation == "install":
                self.cfg.add_notice(
                    "", messages.FIPS_SYSTEM_REBOOT_REQUIRED.msg
                )
            elif operation == "disable operation":
                self.cfg.add_notice("", messages.FIPS_DISABLE_REBOOT_REQUIRED)
示例#7
0
 def _check_for_reboot(self) -> bool:
     """Check if system needs to be rebooted."""
     return util.should_reboot()
示例#8
0
 def _check_for_reboot(self) -> bool:
     """Check if system needs to be rebooted."""
     reboot_required = util.should_reboot(installed_pkgs=set(self.packages))
     event.needs_reboot(reboot_required)
     return reboot_required
示例#9
0
def prompt_for_affected_packages(
    cfg: UAConfig,
    issue_id: str,
    affected_pkg_status: Dict[str, CVEPackageStatus],
    installed_packages: Dict[str, Dict[str, str]],
    usn_released_pkgs: Dict[str, Dict[str, Dict[str, str]]],
    dry_run: bool,
) -> FixStatus:
    """Process security CVE dict returning a CVEStatus object.

    Since CVEs point to a USN if active, get_notice may be called to fill in
    CVE title details.

    :returns: An FixStatus enum value corresponding to the system state
              after processing the affected packages
    """
    count = len(affected_pkg_status)
    print_affected_packages_header(issue_id, affected_pkg_status)
    if count == 0:
        return FixStatus.SYSTEM_NON_VULNERABLE
    fix_message = messages.SECURITY_ISSUE_RESOLVED.format(issue=issue_id)
    src_pocket_pkgs = defaultdict(list)
    binary_pocket_pkgs = defaultdict(list)
    pkg_index = 0

    pkg_status_groups = group_by_usn_package_status(
        affected_pkg_status, usn_released_pkgs
    )

    unfixed_pkgs = []
    for status_value, pkg_status_group in sorted(pkg_status_groups.items()):
        if status_value != "released":
            fix_message = messages.SECURITY_ISSUE_NOT_RESOLVED.format(
                issue=issue_id
            )
            print(
                _format_packages_message(
                    pkg_status_list=pkg_status_group,
                    pkg_index=pkg_index,
                    num_pkgs=count,
                )
            )
            pkg_index += len(pkg_status_group)
            unfixed_pkgs += [src_pkg for src_pkg, _ in pkg_status_group]
        else:
            for src_pkg, pkg_status in pkg_status_group:
                src_pocket_pkgs[pkg_status.pocket_source].append(
                    (src_pkg, pkg_status)
                )
                for binary_pkg, version in installed_packages[src_pkg].items():
                    usn_released_src = usn_released_pkgs.get(src_pkg, {})
                    if binary_pkg not in usn_released_src:
                        unfixed_pkgs += [
                            src_pkg for src_pkg, _ in pkg_status_group
                        ]
                        msg = (
                            "{issue} metadata defines no fixed version for"
                            " {pkg}.\n".format(pkg=binary_pkg, issue=issue_id)
                        )

                        msg += _format_unfixed_packages_msg(unfixed_pkgs)
                        raise exceptions.SecurityAPIMetadataError(
                            msg, issue_id
                        )
                    fixed_pkg = usn_released_src[binary_pkg]
                    fixed_version = fixed_pkg["version"]  # type: ignore
                    if not version_cmp_le(fixed_version, version):
                        binary_pocket_pkgs[pkg_status.pocket_source].append(
                            binary_pkg
                        )

    released_pkgs_install_result = _handle_released_package_fixes(
        cfg=cfg,
        src_pocket_pkgs=src_pocket_pkgs,
        binary_pocket_pkgs=binary_pocket_pkgs,
        pkg_index=pkg_index,
        num_pkgs=count,
        dry_run=dry_run,
    )

    unfixed_pkgs += released_pkgs_install_result.unfixed_pkgs

    if unfixed_pkgs:
        print(_format_unfixed_packages_msg(unfixed_pkgs))

    if released_pkgs_install_result.fix_status:
        # fix_status is True if either:
        #  (1) we successfully installed all the packages we needed to
        #  (2) we didn't need to install any packages
        # In case (2), then all_already_installed is also True
        if released_pkgs_install_result.all_already_installed:
            # we didn't install any packages, so we're good
            print(util.handle_unicode_characters(fix_message))
            return (
                FixStatus.SYSTEM_STILL_VULNERABLE
                if unfixed_pkgs
                else FixStatus.SYSTEM_NON_VULNERABLE
            )
        elif util.should_reboot(
            installed_pkgs=released_pkgs_install_result.installed_pkgs
        ):
            # we successfully installed some packages, but
            # system reboot-required. This might be because
            # or our installations.
            reboot_msg = messages.ENABLE_REBOOT_REQUIRED_TMPL.format(
                operation="fix operation"
            )
            print(reboot_msg)
            cfg.add_notice("", reboot_msg)
            print(
                util.handle_unicode_characters(
                    messages.SECURITY_ISSUE_NOT_RESOLVED.format(issue=issue_id)
                )
            )
            return FixStatus.SYSTEM_VULNERABLE_UNTIL_REBOOT
        else:
            # we successfully installed some packages, and the system
            # reboot-required flag is not set, so we're good
            print(util.handle_unicode_characters(fix_message))
            return (
                FixStatus.SYSTEM_STILL_VULNERABLE
                if unfixed_pkgs
                else FixStatus.SYSTEM_NON_VULNERABLE
            )
    else:
        print(
            util.handle_unicode_characters(
                messages.SECURITY_ISSUE_NOT_RESOLVED.format(issue=issue_id)
            )
        )
        return FixStatus.SYSTEM_STILL_VULNERABLE