Beispiel #1
0
    def scan(self, image, scan_args):
        '''
        Wrapper function for basic security scans using
        openscap
        '''

        mnt_dir = self._ensure_mnt_dir()

        # Mount the temporary image/container to the dir
        DM = DockerMount(mnt_dir, mnt_mkdir=True)
        try:
            _tmp_mnt_dir = DM.mount(image)
        except MountError as e:
            sys.stderr.write(str(e) + "\n")
            return None

        # Remeber actual mounted fs in 'rootfs'
        chroot = os.path.join(_tmp_mnt_dir, 'rootfs')

        # Scan the chroot
        sys.stdout.write(self.helper._scan(chroot, scan_args))

        # Clean up
        self.helper._cleanup_by_path(_tmp_mnt_dir)
        self._remove_mnt_dir(mnt_dir)
    def scan(self, image, scan_args):
        '''
        Wrapper function for basic security scans using
        openscap
        '''

        mnt_dir = self._ensure_mnt_dir()

        # Mount the temporary image/container to the dir
        DM = DockerMount(mnt_dir, mnt_mkdir=True)
        try:
            _tmp_mnt_dir = DM.mount(image)
        except MountError as e:
            sys.stderr.write(str(e) + "\n")
            return None

        # Remeber actual mounted fs in 'rootfs'
        chroot = os.path.join(_tmp_mnt_dir, 'rootfs')

        # Scan the chroot
        sys.stdout.write(self.helper._scan(chroot, scan_args))

        # Clean up
        self.helper._cleanup_by_path(_tmp_mnt_dir)
        self._remove_mnt_dir(mnt_dir)
    def scan(self, image, scan_args):
        '''
        Wrapper function for basic security scans using
        openscap
        '''

        mnt_dir = self._ensure_mnt_dir()

        # Mount the temporary image/container to the dir
        DM = DockerMount(mnt_dir, mnt_mkdir=True)
        try:
            _tmp_mnt_dir = DM.mount(image)
        except MountError as e:
            sys.stderr.write(str(e) + "\n")
            return None

        try:
            chroot = self._find_chroot_path(_tmp_mnt_dir)

            # Scan the chroot
            scan_result = self.helper._scan(chroot, image, scan_args)
            print(scan_result.stdout)
            print(scan_result.stderr, file=sys.stderr)

        finally:
            # Clean up
            self.helper._cleanup_by_path(_tmp_mnt_dir, DM)
            self._remove_mnt_dir(mnt_dir)

        return scan_result.returncode
Beispiel #4
0
    def scan_cve(self, image, scan_args):
        '''
        Wrapper function for scanning a container or image
        '''
        # Mount the temporary image/container to the dir
        DM = DockerMount(self.mnt_dir, mnt_mkdir=True)
        _tmp_mnt_dir = DM.mount(image)

        # Remeber actual mounted fs in 'rootfs'
        chroot = os.path.join(_tmp_mnt_dir, 'rootfs')

        # Figure out which RHEL dist is in the chroot
        dist = self.helper._get_dist(chroot)

        # Fetch the CVE input data for the dist
        fetch = getInputCVE(self.tmp_dir)

        # TODO
        # This should probably be in a try/except
        fetch._fetch_single(dist)

        # Scan the chroot
        sys.stdout.write(self.helper._scan_cve(chroot, dist, scan_args))

        # Clean up
        self.helper._cleanup_by_path(_tmp_mnt_dir)
    def scan(self, image, scan_args):
        '''
        Wrapper function for basic security scans using
        openscap
        '''

        mnt_dir = self._ensure_mnt_dir()

        # Mount the temporary image/container to the dir
        DM = DockerMount(mnt_dir, mnt_mkdir=True)
        try:
            _tmp_mnt_dir = DM.mount(image)
        except MountError as e:
            sys.stderr.write(str(e) + "\n")
            return None

        try:
            chroot = self._find_chroot_path(_tmp_mnt_dir)

            # Scan the chroot
            sys.stdout.write(self.helper._scan(chroot, image, scan_args))

        finally:
            # Clean up
            self.helper._cleanup_by_path(_tmp_mnt_dir, DM)
            self._remove_mnt_dir(mnt_dir)
Beispiel #6
0
    def scan_cve(self, image, scan_args):
        '''
        Wrapper function for scanning a container or image
        '''
        # Mount the temporary image/container to the dir
        DM = DockerMount(self.mnt_dir, mnt_mkdir=True)
        _tmp_mnt_dir = DM.mount(image)

        # Remeber actual mounted fs in 'rootfs'
        chroot = os.path.join(_tmp_mnt_dir, 'rootfs')

        # Figure out which RHEL dist is in the chroot
        dist = self.helper._get_dist(chroot)

        # Fetch the CVE input data for the dist
        fetch = getInputCVE(self.tmp_dir)

        # TODO
        # This should probably be in a try/except
        fetch._fetch_single(dist)

        # Scan the chroot
        sys.stdout.write(self.helper._scan_cve(chroot, dist, scan_args))

        # Clean up
        self.helper._cleanup_by_path(_tmp_mnt_dir)
Beispiel #7
0
def build_rpm_for_docker_backend(image, name, temp_dir, labels):
    """
    build rpm package for specified docker image

    :param image, instance of Atomic.objects.image.Image
    :param name, str, name of the associated container
    :param temp_dir: str, directory where all the data will be processed
    :param labels: dict, these labels come from container image
    :return: instance of StandaloneContainerInstallation
    """
    from Atomic.mount import DockerMount, MountContextManager
    mount_path = os.path.join(temp_dir, "mountpoint")
    destination = os.path.join(temp_dir, "system_rpm")
    os.makedirs(destination)
    os.makedirs(mount_path)
    dm = DockerMount(mount_path)
    cm = MountContextManager(dm, image.id)
    with cm:
        # if we are on devicemapper, the path to container is <mount_point>/hostfs/
        dm_candidate_path = os.path.join(cm.mnt_path, "rootfs")
        if os.path.exists(dm_candidate_path):
            exports_dir = os.path.join(dm_candidate_path, "exports")
        else:
            exports_dir = os.path.join(cm.mnt_path, "exports")
        r = RPMHostInstall.generate_rpm(
            name, image.id, labels, exports_dir, destination)
        return ContainerInstallation(r[0], r[1], r[2])
Beispiel #8
0
    def scan(self, image, scan_args):
        '''
        Wrapper function for basic security scans using
        openscap
        '''
        # Mount the temporary image/container to the dir
        DM = DockerMount(self.mnt_dir, mnt_mkdir=True)
        _tmp_mnt_dir = DM.mount(image)

        # Remeber actual mounted fs in 'rootfs'
        chroot = os.path.join(_tmp_mnt_dir, 'rootfs')

        # Scan the chroot
        sys.stdout.write(self.helper._scan(chroot, scan_args))

        # Clean up
        self.helper._cleanup_by_path(_tmp_mnt_dir)
Beispiel #9
0
    def scan(self, image, scan_args):
        '''
        Wrapper function for basic security scans using
        openscap
        '''
        # Mount the temporary image/container to the dir
        DM = DockerMount(self.mnt_dir, mnt_mkdir=True)
        _tmp_mnt_dir = DM.mount(image)

        # Remeber actual mounted fs in 'rootfs'
        chroot = os.path.join(_tmp_mnt_dir, 'rootfs')

        # Scan the chroot
        sys.stdout.write(self.helper._scan(chroot, scan_args))

        # Clean up
        self.helper._cleanup_by_path(_tmp_mnt_dir)
Beispiel #10
0
    def _cleanup_by_path(self, path):
        '''
        Cleans up the mounted chroot by umounting it and
        removing the temporary directory
        '''
        # Sometimes when this def is called, path will have 'rootfs'
        # appended.  If it does, strip it and proceed

        _no_rootfs = os.path.dirname(path) if os.path.basename(path) == \
            'rootfs' else path

        DM = DockerMount("/tmp")
        # umount chroot
        DM.unmount_path(_no_rootfs)

        # clean up temporary container
        DM._clean_temp_container_by_path(_no_rootfs)
        os.rmdir(_no_rootfs)
    def scan_cve(self, image, scan_args):
        '''
        Wrapper function for scanning a container or image
        '''

        mnt_dir = self._ensure_mnt_dir()

        # Mount the temporary image/container to the dir
        DM = DockerMount(mnt_dir, mnt_mkdir=True)
        try:
            _tmp_mnt_dir = DM.mount(image)
        except MountError as e:
            sys.stderr.write(str(e) + "\n")
            return None

        try:
            chroot = self._find_chroot_path(_tmp_mnt_dir)

            # Figure out which RHEL dist is in the chroot
            name, conf = self.helper._get_target_name_and_config(image)
            dist = get_dist(chroot, self.helper.oscap_binary,
                            conf.get("Env", []) or [])

            if dist is None:
                sys.stderr.write("{0} is not based on RHEL\n".format(image))
                return None

            # Fetch the CVE input data for the dist
            fetch = getInputCVE(self.tmp_dir)
            fetch._fetch_single(dist)

            # Scan the chroot
            scan_result = self.helper._scan_cve(chroot, image, dist, scan_args)
            print(scan_result.stdout)
            print(scan_result.stderr, file=sys.stderr)

        finally:
            # Clean up
            self.helper._cleanup_by_path(_tmp_mnt_dir, DM)
            self._remove_mnt_dir(mnt_dir)

        return scan_result.returncode
Beispiel #12
0
    def __init__(self, image_uuid, con_uuids, output, appc):
        self.image_name = image_uuid
        self.ac = appc
        self.CVEs = collections.namedtuple(
            'CVEs', 'title, severity,'
            'cve_ref_id, cve_ref_url,'
            'rhsa_ref_id, rhsa_ref_url')

        self.list_of_CVEs = []
        self.con_uuids = con_uuids
        self.output = output
        self.report_dir = os.path.join(self.ac.workdir, "reports")
        if not os.path.exists(self.report_dir):
            os.mkdir(self.report_dir)

        start = time.time()
        self.DM = DockerMount("/tmp", mnt_mkdir=True)
        self.dm_results = self.DM.mount(image_uuid)
        logging.debug("Created scanning chroot in {0}"
                      " seconds".format(time.time() - start))
        self.dest = self.dm_results
Beispiel #13
0
    def scan_cve(self, image, scan_args):
        '''
        Wrapper function for scanning a container or image
        '''

        mnt_dir = self._ensure_mnt_dir()

        # Mount the temporary image/container to the dir
        DM = DockerMount(mnt_dir, mnt_mkdir=True)
        try:
            _tmp_mnt_dir = DM.mount(image)
        except MountError as e:
            sys.stderr.write(str(e) + "\n")
            return None

        # Remeber actual mounted fs in 'rootfs'
        chroot = os.path.join(_tmp_mnt_dir, 'rootfs')


        try:
            # Figure out which RHEL dist is in the chroot
            dist = self.helper._get_dist(chroot)

            if dist is None:
                sys.stderr.write("{0} is not based on RHEL\n".format(image))
                return None

            # Fetch the CVE input data for the dist
            fetch = getInputCVE(self.tmp_dir)
            fetch._fetch_single(dist)

            # Scan the chroot
            sys.stdout.write(self.helper._scan_cve(chroot, dist, scan_args))

        finally:
            # Clean up
            self.helper._cleanup_by_path(_tmp_mnt_dir)
            self._remove_mnt_dir(mnt_dir)
    def scan_cve(self, image, scan_args):
        '''
        Wrapper function for scanning a container or image
        '''

        mnt_dir = self._ensure_mnt_dir()

        # Mount the temporary image/container to the dir
        DM = DockerMount(mnt_dir, mnt_mkdir=True)
        try:
            _tmp_mnt_dir = DM.mount(image)
        except MountError as e:
            sys.stderr.write(str(e) + "\n")
            return None

        # Remeber actual mounted fs in 'rootfs'
        chroot = os.path.join(_tmp_mnt_dir, 'rootfs')


        try:
            # Figure out which RHEL dist is in the chroot
            dist = self.helper._get_dist(chroot)

            if dist is None:
                sys.stderr.write("{0} is not based on RHEL\n".format(image))
                return None

            # Fetch the CVE input data for the dist
            fetch = getInputCVE(self.tmp_dir)
            fetch._fetch_single(dist)

            # Scan the chroot
            sys.stdout.write(self.helper._scan_cve(chroot, dist, scan_args))

        finally:
            # Clean up
            self.helper._cleanup_by_path(_tmp_mnt_dir)
            self._remove_mnt_dir(mnt_dir)
Beispiel #15
0
    def __init__(self, image_uuid, con_uuids, output, appc):
        self.image_name = image_uuid
        self.ac = appc
        self.CVEs = collections.namedtuple('CVEs', 'title, severity,'
                                           'cve_ref_id, cve_ref_url,'
                                           'rhsa_ref_id, rhsa_ref_url')

        self.list_of_CVEs = []
        self.con_uuids = con_uuids
        self.output = output
        self.report_dir = os.path.join(self.ac.workdir, "reports")
        if not os.path.exists(self.report_dir):
            os.mkdir(self.report_dir)

        start = time.time()
        self.DM = DockerMount("/tmp", mnt_mkdir=True)
        self.dm_results = self.DM.mount(image_uuid)
        logging.debug("Created scanning chroot in {0}"
                      " seconds".format(time.time() - start))
        self.dest = self.dm_results
Beispiel #16
0
    def _cleanup_by_path(self, path):
        '''
        Cleans up the mounted chroot by umounting it and
        removing the temporary directory
        '''
        # Sometimes when this def is called, path will have 'rootfs'
        # appended.  If it does, strip it and proceed

        _no_rootfs = os.path.dirname(path) if os.path.basename(path) == \
            'rootfs' else path

        DM = DockerMount("/tmp")
        # umount chroot
        DM.unmount_path(_no_rootfs)

        # clean up temporary container
        DM._clean_temp_container_by_path(_no_rootfs)
        os.rmdir(_no_rootfs)
Beispiel #17
0
class Scan(object):

    # Fix race-condition in atomic mount/unmount
    # We don't want to do mount and unmount simultaneously
    _mount_lock = Lock()

    def __init__(self, image_uuid, con_uuids, output, appc):
        self.image_name = image_uuid
        self.ac = appc
        self.CVEs = collections.namedtuple('CVEs', 'title, severity,'
                                           'cve_ref_id, cve_ref_url,'
                                           'rhsa_ref_id, rhsa_ref_url')

        self.list_of_CVEs = []
        self.con_uuids = con_uuids
        self.output = output
        self.report_dir = os.path.join(self.ac.workdir, "reports")
        if not os.path.exists(self.report_dir):
            os.mkdir(self.report_dir)
        start = time.time()
        from Atomic.mount import DockerMount
        self.DM = DockerMount("/tmp", mnt_mkdir=True)
        with Scan._mount_lock:
            self.dm_results = self.DM.mount(image_uuid)
        logging.debug("Created scanning chroot in {0}"
                      " seconds".format(time.time() - start))
        self.dest = self.dm_results


    def get_release(self):
        etc_release_path = os.path.join(self.dest, "rootfs",
                                        "etc/redhat-release")

        if not os.path.exists(etc_release_path):
            logging.info("{0} is not RHEL based".format(self.image_name))
            return False

        self.os_release = open(etc_release_path).read()

        rhel = 'Red Hat Enterprise Linux'

        if rhel in self.os_release:
            logging.debug("{0} is {1}".format(self.image_name,
                                              self.os_release.rstrip()))
            return True
        else:
            logging.info("{0} is {1}".format(self.image_name,
                                             self.os_release.rstrip()))
            return False

    def scan(self):
        logging.debug("Scanning chroot {0}".format(self.image_name))
        hostname = open("/etc/hostname").read().rstrip()
        os.environ["OSCAP_PROBE_ARCHITECTURE"] = platform.processor()
        os.environ["OSCAP_PROBE_ROOT"] = os.path.join(self.dest, "rootfs")
        os.environ["OSCAP_PROBE_OS_NAME"] = platform.system()
        os.environ["OSCAP_PROBE_OS_VERSION"] = platform.release()
        os.environ["OSCAP_PROBE_"
                   "PRIMARY_HOST_NAME"] = "{0}:{1}".format(hostname,
                                                           self.image_name)

        from oscap_docker_python.get_cve_input import getInputCVE
        # We only support RHEL 6|7 in containers right now
        osc = getInputCVE("/tmp")
        if "Red Hat Enterprise Linux" in self.os_release:
            if "7." in self.os_release:
                self.chroot_cve_file = os.path.join(
                    self.ac.workdir, osc.dist_cve_name.format("7"))
            if "6." in self.os_release:
                self.chroot_cve_file = os.path.join(
                    self.ac.workdir, osc.dist_cve_name.format("6"))
        cmd = ['oscap', 'oval', 'eval', '--report',
               os.path.join(self.report_dir,
                            self.image_name + '.html'),
               '--results',
               os.path.join(self.report_dir,
                            self.image_name + '.xml'), self.chroot_cve_file]

        logging.debug(
            "Starting evaluation with command '%s'.",
        " ".join(cmd))

        try:
            self.result = subprocess.check_output(cmd).decode("utf-8")
        except Exception:
            pass
    # def capture_run(self, cmd):
    #     '''
    #     Subprocess command that captures and returns the output and
    #     return code.
    #     '''

    #     r = subprocess.Popen(cmd, stdout=subprocess.PIPE,
    #                          stderr=subprocess.PIPE)
    #     return r.communicate(), r.returncode

    def get_cons(self, fcons, short_iid):
        cons = []
        for image in fcons:
            if image.startswith(short_iid):
                for con in fcons[image]:
                    cons.append(con['uuid'][:12])
        return cons

    def report_results(self):
        if not os.path.exists(self.chroot_cve_file):
            from openscap_daemon.cve_scanner.scanner_error import ImageScannerClientError
            raise ImageScannerClientError("Unable to find {0}"
                                          .format(self.chroot_cve_file))
            return False
        cve_tree = ET.parse(bz2.BZ2File(self.chroot_cve_file))
        self.cve_root = cve_tree.getroot()

        for line in self.result.splitlines():
            split_line = line.split(':')
            # Not in love with how I did this
            # Should find a better marked to know if it is a line
            # a parsable line.
            if (len(split_line) == 5) and ('true' in split_line[4]):
                self._return_xml_values(line.split()[1][:-1])

        sev_dict = {}
        sum_log = StringIO()
        sum_log.write("Image: {0} ({1})".format(self.image_name,
                                                self.os_release))
        cons = self.get_cons(self.ac.fcons, self.image_name)
        sum_log.write("\nContainers based on this image ({0}): {1}\n"
                      .format(len(cons), ", ".join(cons)))
        for sev in ['Critical', 'Important', 'Moderate', 'Low']:
            sev_counter = 0
            for cve in self.list_of_CVEs:
                if cve.severity == sev:
                    sev_counter += 1
                    sum_log.write("\n")
                    fields = list(self.CVEs._fields)
                    fields.remove('title')
                    sum_log.write("{0}{1}: {2}\n"
                                  .format(" " * 5, "Title",
                                          getattr(cve, "title")))

                    for field in fields:
                        sum_log.write("{0}{1}: {2}\n"
                                      .format(" " * 10, field.title(),
                                              getattr(cve, field)))
            sev_dict[sev] = sev_counter
        self.output.list_of_outputs.append(
            self.output.output(iid=self.image_name, cid=self.con_uuids,
                               os=self.os_release, sevs=sev_dict,
                               log=sum_log.getvalue(), msg=None))
        sum_log.close()

    def _report_not_rhel(self, image):
        msg = "{0} is not based on RHEL".format(image[:8])
        self.output.list_of_outputs.append(
            self.output.output(iid=image, cid=None,
                               os=None, sevs=None,
                               log=None, msg=msg))

    def _return_xml_values(self, cve):
        cve_string = ("{http://oval.mitre.org/XMLSchema/oval-definitions-5}"
                      "definitions/*[@id='%s']" % cve)
        cve_xml = self.cve_root.find(cve_string)
        title = cve_xml.find("{http://oval.mitre.org/XMLSchema/oval-"
                             "definitions-5}metadata/"
                             "{http://oval.mitre.org/XMLSchema/"
                             "oval-definitions-5}title")
        cve_id = cve_xml.find("{http://oval.mitre.org/XMLSchema/"
                              "oval-definitions-5}metadata/{http://oval.mitre."
                              "org/XMLSchema/oval-definitions-5}reference"
                              "[@source='CVE']")
        sev = (cve_xml.find("{http://oval.mitre.org/XMLSchema/oval-definitions"
                            "-5}metadata/{http://oval.mitre.org/XMLSchema/oval"
                            "-definitions-5}advisory/")).text

        if cve_id is not None:
            cve_ref_id = cve_id.attrib['ref_id']
            cve_ref_url = cve_id.attrib['ref_url']
        else:
            cve_ref_id = None
            cve_ref_url = None

        rhsa_id = cve_xml.find("{http://oval.mitre.org/XMLSchema/oval-"
                               "definitions-5}metadata/{http://oval.mitre.org"
                               "/XMLSchema/oval-definitions-5}reference"
                               "[@source='RHSA']")

        if rhsa_id is not None:
            rhsa_ref_id = rhsa_id.attrib['ref_id']
            rhsa_ref_url = rhsa_id.attrib['ref_url']
        else:
            rhsa_ref_id = None
            rhsa_ref_url = None

        self.list_of_CVEs.append(
            self.CVEs(title=title.text, cve_ref_id=cve_ref_id,
                      cve_ref_url=cve_ref_url, rhsa_ref_id=rhsa_ref_id,
                      rhsa_ref_url=rhsa_ref_url, severity=sev))

    def _get_rpms(self):
        # TODO: External dep!
        import rpm

        chroot_os = os.path.join(self.dest, "rootfs")
        ts = rpm.TransactionSet(chroot_os)
        ts.setVSFlags((rpm._RPMVSF_NOSIGNATURES | rpm._RPMVSF_NODIGESTS))
        image_rpms = []
        for hdr in ts.dbMatch():  # No sorting
            if hdr['name'] == 'gpg-pubkey':
                continue
            else:
                foo = "{0}-{1}-{2}-{3}-{4}".format(hdr['name'],
                                                   hdr['epochnum'],
                                                   hdr['version'],
                                                   hdr['release'],
                                                   hdr['arch'])
                image_rpms.append(foo)
        return image_rpms

    def unmount(self):
        with Scan._mount_lock:
            self.DM.unmount_path(self.dest)
            self.DM._clean_temp_container_by_path(self.dest)
Beispiel #18
0
class Scan(object):

    # Fix race-condition in atomic mount/unmount
    # We don't want to do mount and unmount simultaneously
    _mount_lock = Lock()

    def __init__(self, image_uuid, con_uuids, output, appc):
        self.image_name = image_uuid
        self.ac = appc
        self.CVEs = collections.namedtuple(
            'CVEs', 'title, severity,'
            'cve_ref_id, cve_ref_url,'
            'rhsa_ref_id, rhsa_ref_url')

        self.list_of_CVEs = []
        self.con_uuids = con_uuids
        self.output = output
        self.report_dir = os.path.join(self.ac.workdir, "reports")
        if not os.path.exists(self.report_dir):
            os.mkdir(self.report_dir)
        start = time.time()
        from Atomic.mount import DockerMount
        self.DM = DockerMount("/tmp", mnt_mkdir=True)
        with Scan._mount_lock:
            self.dm_results = self.DM.mount(image_uuid)
        logging.debug("Created scanning chroot in {0}"
                      " seconds".format(time.time() - start))
        self.dest = self.dm_results

    def get_release(self):
        etc_release_path = os.path.join(self.dest, "rootfs",
                                        "etc/redhat-release")

        if not os.path.exists(etc_release_path):
            logging.info("{0} is not RHEL based".format(self.image_name))
            return False

        self.os_release = open(etc_release_path).read()

        rhel = 'Red Hat Enterprise Linux'

        if rhel in self.os_release:
            logging.debug("{0} is {1}".format(self.image_name,
                                              self.os_release.rstrip()))
            return True
        else:
            logging.info("{0} is {1}".format(self.image_name,
                                             self.os_release.rstrip()))
            return False

    def scan(self):
        logging.debug("Scanning chroot {0}".format(self.image_name))
        hostname = open("/etc/hostname").read().rstrip()
        os.environ["OSCAP_PROBE_ARCHITECTURE"] = platform.processor()
        os.environ["OSCAP_PROBE_ROOT"] = os.path.join(self.dest, "rootfs")
        os.environ["OSCAP_PROBE_OS_NAME"] = platform.system()
        os.environ["OSCAP_PROBE_OS_VERSION"] = platform.release()
        os.environ["OSCAP_PROBE_"
                   "PRIMARY_HOST_NAME"] = "{0}:{1}".format(
                       hostname, self.image_name)

        from oscap_docker_python.get_cve_input import getInputCVE
        # We only support RHEL 6|7 in containers right now
        osc = getInputCVE("/tmp")
        if "Red Hat Enterprise Linux" in self.os_release:
            if "7." in self.os_release:
                self.chroot_cve_file = os.path.join(
                    self.ac.workdir, osc.dist_cve_name.format("7"))
            if "6." in self.os_release:
                self.chroot_cve_file = os.path.join(
                    self.ac.workdir, osc.dist_cve_name.format("6"))
        cmd = [
            'oscap', 'oval', 'eval', '--report',
            os.path.join(self.report_dir,
                         self.image_name + '.html'), '--results',
            os.path.join(self.report_dir, self.image_name + '.xml'),
            self.chroot_cve_file
        ]

        logging.debug("Starting evaluation with command '%s'.", " ".join(cmd))

        try:
            self.result = subprocess.check_output(cmd).decode("utf-8")
        except Exception:
            pass

    # def capture_run(self, cmd):
    #     '''
    #     Subprocess command that captures and returns the output and
    #     return code.
    #     '''

    #     r = subprocess.Popen(cmd, stdout=subprocess.PIPE,
    #                          stderr=subprocess.PIPE)
    #     return r.communicate(), r.returncode

    def get_cons(self, fcons, short_iid):
        cons = []
        for image in fcons:
            if image.startswith(short_iid):
                for con in fcons[image]:
                    cons.append(con['uuid'][:12])
        return cons

    def report_results(self):
        if not os.path.exists(self.chroot_cve_file):
            from openscap_daemon.cve_scanner.scanner_error import ImageScannerClientError
            raise ImageScannerClientError("Unable to find {0}".format(
                self.chroot_cve_file))
            return False
        cve_tree = ET.parse(bz2.BZ2File(self.chroot_cve_file))
        self.cve_root = cve_tree.getroot()

        for line in self.result.splitlines():
            split_line = line.split(':')
            # Not in love with how I did this
            # Should find a better marked to know if it is a line
            # a parsable line.
            if (len(split_line) == 5) and ('true' in split_line[4]):
                self._return_xml_values(line.split()[1][:-1])

        sev_dict = {}
        sum_log = StringIO()
        sum_log.write("Image: {0} ({1})".format(self.image_name,
                                                self.os_release))
        cons = self.get_cons(self.ac.fcons, self.image_name)
        sum_log.write("\nContainers based on this image ({0}): {1}\n".format(
            len(cons), ", ".join(cons)))
        for sev in ['Critical', 'Important', 'Moderate', 'Low']:
            sev_counter = 0
            for cve in self.list_of_CVEs:
                if cve.severity == sev:
                    sev_counter += 1
                    sum_log.write("\n")
                    fields = list(self.CVEs._fields)
                    fields.remove('title')
                    sum_log.write("{0}{1}: {2}\n".format(
                        " " * 5, "Title", getattr(cve, "title")))

                    for field in fields:
                        sum_log.write("{0}{1}: {2}\n".format(
                            " " * 10, field.title(), getattr(cve, field)))
            sev_dict[sev] = sev_counter
        self.output.list_of_outputs.append(
            self.output.output(iid=self.image_name,
                               cid=self.con_uuids,
                               os=self.os_release,
                               sevs=sev_dict,
                               log=sum_log.getvalue(),
                               msg=None))
        sum_log.close()

    def _report_not_rhel(self, image):
        msg = "{0} is not based on RHEL".format(image[:8])
        self.output.list_of_outputs.append(
            self.output.output(iid=image,
                               cid=None,
                               os=None,
                               sevs=None,
                               log=None,
                               msg=msg))

    def _return_xml_values(self, cve):
        cve_string = ("{http://oval.mitre.org/XMLSchema/oval-definitions-5}"
                      "definitions/*[@id='%s']" % cve)
        cve_xml = self.cve_root.find(cve_string)
        title = cve_xml.find("{http://oval.mitre.org/XMLSchema/oval-"
                             "definitions-5}metadata/"
                             "{http://oval.mitre.org/XMLSchema/"
                             "oval-definitions-5}title")
        cve_id = cve_xml.find("{http://oval.mitre.org/XMLSchema/"
                              "oval-definitions-5}metadata/{http://oval.mitre."
                              "org/XMLSchema/oval-definitions-5}reference"
                              "[@source='CVE']")
        sev = (cve_xml.find("{http://oval.mitre.org/XMLSchema/oval-definitions"
                            "-5}metadata/{http://oval.mitre.org/XMLSchema/oval"
                            "-definitions-5}advisory/")).text

        if cve_id is not None:
            cve_ref_id = cve_id.attrib['ref_id']
            cve_ref_url = cve_id.attrib['ref_url']
        else:
            cve_ref_id = None
            cve_ref_url = None

        rhsa_id = cve_xml.find("{http://oval.mitre.org/XMLSchema/oval-"
                               "definitions-5}metadata/{http://oval.mitre.org"
                               "/XMLSchema/oval-definitions-5}reference"
                               "[@source='RHSA']")

        if rhsa_id is not None:
            rhsa_ref_id = rhsa_id.attrib['ref_id']
            rhsa_ref_url = rhsa_id.attrib['ref_url']
        else:
            rhsa_ref_id = None
            rhsa_ref_url = None

        self.list_of_CVEs.append(
            self.CVEs(title=title.text,
                      cve_ref_id=cve_ref_id,
                      cve_ref_url=cve_ref_url,
                      rhsa_ref_id=rhsa_ref_id,
                      rhsa_ref_url=rhsa_ref_url,
                      severity=sev))

    def _get_rpms(self):
        # TODO: External dep!
        import rpm

        chroot_os = os.path.join(self.dest, "rootfs")
        ts = rpm.TransactionSet(chroot_os)
        ts.setVSFlags((rpm._RPMVSF_NOSIGNATURES | rpm._RPMVSF_NODIGESTS))
        image_rpms = []
        for hdr in ts.dbMatch():  # No sorting
            if hdr['name'] == 'gpg-pubkey':
                continue
            else:
                foo = "{0}-{1}-{2}-{3}-{4}".format(hdr['name'],
                                                   hdr['epochnum'],
                                                   hdr['version'],
                                                   hdr['release'], hdr['arch'])
                image_rpms.append(foo)
        return image_rpms

    def unmount(self):
        with Scan._mount_lock:
            self.DM.unmount_path(self.dest)
            self.DM._clean_temp_container_by_path(self.dest)