#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

# This class is used to check recipes against public CVEs.
#
# In order to use this class just inherit the class in the
# local.conf file and it will add the cve_check task for
# every recipe. The task can be used per recipe, per image,
# or using the special cases "world" and "universe". The
# cve_check task will print a warning for every unpatched
# CVE found and generate a file in the recipe WORKDIR/cve
# directory. If an image is build it will generate a report
# in DEPLOY_DIR_IMAGE for all the packages used.
#
# Example:
#   bitbake -c cve_check openssl
#   bitbake core-image-sato
#   bitbake -k -c cve_check universe
#
# DISCLAIMER
#
# This class/tool is meant to be used as support and not
# the only method to check against CVEs. Running this tool
# doesn't guarantee your packages are free of CVEs.

# The product name that the CVE database uses defaults to BPN, but may need to
# be overriden per recipe (for example tiff.bb sets CVE_PRODUCT=libtiff).
CVE_PRODUCT ??= "${BPN}"
CVE_VERSION ??= "${PV}"

CVE_CHECK_DB_DIR ?= "${DL_DIR}/CVE_CHECK"
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvdcve_2.db"
CVE_CHECK_DB_FILE_LOCK ?= "${CVE_CHECK_DB_FILE}.lock"

CVE_CHECK_LOG ?= "${T}/cve.log"
CVE_CHECK_TMP_FILE ?= "${TMPDIR}/cve_check"
CVE_CHECK_SUMMARY_DIR ?= "${LOG_DIR}/cve"
CVE_CHECK_SUMMARY_FILE_NAME ?= "cve-summary"
CVE_CHECK_SUMMARY_FILE ?= "${CVE_CHECK_SUMMARY_DIR}/${CVE_CHECK_SUMMARY_FILE_NAME}"
CVE_CHECK_SUMMARY_FILE_NAME_JSON = "cve-summary.json"
CVE_CHECK_SUMMARY_INDEX_PATH = "${CVE_CHECK_SUMMARY_DIR}/cve-summary-index.txt"

CVE_CHECK_LOG_JSON ?= "${T}/cve.json"

CVE_CHECK_DIR ??= "${DEPLOY_DIR}/cve"
CVE_CHECK_RECIPE_FILE ?= "${CVE_CHECK_DIR}/${PN}"
CVE_CHECK_RECIPE_FILE_JSON ?= "${CVE_CHECK_DIR}/${PN}_cve.json"
CVE_CHECK_MANIFEST ?= "${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.cve"
CVE_CHECK_MANIFEST_JSON ?= "${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.json"
CVE_CHECK_COPY_FILES ??= "1"
CVE_CHECK_CREATE_MANIFEST ??= "1"

# Report Patched or Ignored CVEs
CVE_CHECK_REPORT_PATCHED ??= "1"

CVE_CHECK_SHOW_WARNINGS ??= "1"

# Provide text output
CVE_CHECK_FORMAT_TEXT ??= "1"

# Provide JSON output
CVE_CHECK_FORMAT_JSON ??= "1"

# Check for packages without CVEs (no issues or missing product name)
CVE_CHECK_COVERAGE ??= "1"

# Skip CVE Check for packages (PN)
CVE_CHECK_SKIP_RECIPE ?= ""

# Ingore the check for a given list of CVEs. If a CVE is found,
# then it is considered patched. The value is a string containing
# space separated CVE values:
#
# CVE_CHECK_IGNORE = 'CVE-2014-2524 CVE-2018-1234'
#
CVE_CHECK_IGNORE ?= ""

# Layers to be excluded
CVE_CHECK_LAYER_EXCLUDELIST ??= ""

# Layers to be included
CVE_CHECK_LAYER_INCLUDELIST ??= ""


# set to "alphabetical" for version using single alphabetical character as increment release
CVE_VERSION_SUFFIX ??= ""

def generate_json_report(d, out_path, link_path):
    if os.path.exists(d.getVar("CVE_CHECK_SUMMARY_INDEX_PATH")):
        import json
        from oe.cve_check import cve_check_merge_jsons, update_symlinks

        bb.note("Generating JSON CVE summary")
        index_file = d.getVar("CVE_CHECK_SUMMARY_INDEX_PATH")
        summary = {"version":"1", "package": []}
        with open(index_file) as f:
            filename = f.readline()
            while filename:
                with open(filename.rstrip()) as j:
                    data = json.load(j)
                    cve_check_merge_jsons(summary, data)
                filename = f.readline()

        with open(out_path, "w") as f:
            json.dump(summary, f, indent=2)

        update_symlinks(out_path, link_path)

python cve_save_summary_handler () {
    import shutil
    import datetime
    from oe.cve_check import update_symlinks

    cve_tmp_file = d.getVar("CVE_CHECK_TMP_FILE")

    cve_summary_name = d.getVar("CVE_CHECK_SUMMARY_FILE_NAME")
    cvelogpath = d.getVar("CVE_CHECK_SUMMARY_DIR")
    bb.utils.mkdirhier(cvelogpath)

    timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
    cve_summary_file = os.path.join(cvelogpath, "%s-%s.txt" % (cve_summary_name, timestamp))

    if os.path.exists(cve_tmp_file):
        shutil.copyfile(cve_tmp_file, cve_summary_file)
        cvefile_link = os.path.join(cvelogpath, cve_summary_name)
        update_symlinks(cve_summary_file, cvefile_link)
        bb.plain("Complete CVE report summary created at: %s" % cvefile_link)

    if d.getVar("CVE_CHECK_FORMAT_JSON") == "1":
        json_summary_link_name = os.path.join(cvelogpath, d.getVar("CVE_CHECK_SUMMARY_FILE_NAME_JSON"))
        json_summary_name = os.path.join(cvelogpath, "%s-%s.json" % (cve_summary_name, timestamp))
        generate_json_report(d, json_summary_name, json_summary_link_name)
        bb.plain("Complete CVE JSON report summary created at: %s" % json_summary_link_name)
}

addhandler cve_save_summary_handler
cve_save_summary_handler[eventmask] = "bb.event.BuildCompleted"

python do_cve_check () {
    """
    Check recipe for patched and unpatched CVEs
    """
    from oe.cve_check import get_patched_cves

    with bb.utils.fileslocked([d.getVar("CVE_CHECK_DB_FILE_LOCK")], shared=True):
        if os.path.exists(d.getVar("CVE_CHECK_DB_FILE")):
            try:
                patched_cves = get_patched_cves(d)
            except FileNotFoundError:
                bb.fatal("Failure in searching patches")
            ignored, patched, unpatched, status = check_cves(d, patched_cves)
            if patched or unpatched or (d.getVar("CVE_CHECK_COVERAGE") == "1" and status):
                cve_data = get_cve_info(d, patched + unpatched + ignored)
                cve_write_data(d, patched, unpatched, ignored, cve_data, status)
        else:
            bb.note("No CVE database found, skipping CVE check")

}

addtask cve_check before do_build
do_cve_check[depends] = "cve-update-nvd2-native:do_fetch"
do_cve_check[nostamp] = "1"

python cve_check_cleanup () {
    """
    Delete the file used to gather all the CVE information.
    """
    bb.utils.remove(e.data.getVar("CVE_CHECK_TMP_FILE"))
    bb.utils.remove(e.data.getVar("CVE_CHECK_SUMMARY_INDEX_PATH"))
}

addhandler cve_check_cleanup
cve_check_cleanup[eventmask] = "bb.event.BuildCompleted"

python cve_check_write_rootfs_manifest () {
    """
    Create CVE manifest when building an image
    """

    import shutil
    import json
    from oe.rootfs import image_list_installed_packages
    from oe.cve_check import cve_check_merge_jsons, update_symlinks

    if d.getVar("CVE_CHECK_COPY_FILES") == "1":
        deploy_file = d.getVar("CVE_CHECK_RECIPE_FILE")
        if os.path.exists(deploy_file):
            bb.utils.remove(deploy_file)
        deploy_file_json = d.getVar("CVE_CHECK_RECIPE_FILE_JSON")
        if os.path.exists(deploy_file_json):
            bb.utils.remove(deploy_file_json)

    # Create a list of relevant recipies
    recipies = set()
    for pkg in list(image_list_installed_packages(d)):
        pkg_info = os.path.join(d.getVar('PKGDATA_DIR'),
                                'runtime-reverse', pkg)
        pkg_data = oe.packagedata.read_pkgdatafile(pkg_info)
        recipies.add(pkg_data["PN"])

    bb.note("Writing rootfs CVE manifest")
    deploy_dir = d.getVar("IMGDEPLOYDIR")
    link_name = d.getVar("IMAGE_LINK_NAME")

    json_data = {"version":"1", "package": []}
    text_data = ""
    enable_json = d.getVar("CVE_CHECK_FORMAT_JSON") == "1"
    enable_text = d.getVar("CVE_CHECK_FORMAT_TEXT") == "1"

    save_pn = d.getVar("PN")

    for pkg in recipies:
        # To be able to use the CVE_CHECK_RECIPE_FILE variable we have to evaluate
        # it with the different PN names set each time.
        d.setVar("PN", pkg)
        if enable_text:
            pkgfilepath = d.getVar("CVE_CHECK_RECIPE_FILE")
            if os.path.exists(pkgfilepath):
                with open(pkgfilepath) as pfile:
                    text_data += pfile.read()

        if enable_json:
            pkgfilepath = d.getVar("CVE_CHECK_RECIPE_FILE_JSON")
            if os.path.exists(pkgfilepath):
                with open(pkgfilepath) as j:
                    data = json.load(j)
                    cve_check_merge_jsons(json_data, data)

    d.setVar("PN", save_pn)

    if enable_text:
        link_path = os.path.join(deploy_dir, "%s.cve" % link_name)
        manifest_name = d.getVar("CVE_CHECK_MANIFEST")

        with open(manifest_name, "w") as f:
            f.write(text_data)

        update_symlinks(manifest_name, link_path)
        bb.plain("Image CVE report stored in: %s" % manifest_name)

    if enable_json:
        link_path = os.path.join(deploy_dir, "%s.json" % link_name)
        manifest_name = d.getVar("CVE_CHECK_MANIFEST_JSON")

        with open(manifest_name, "w") as f:
            json.dump(json_data, f, indent=2)

        update_symlinks(manifest_name, link_path)
        bb.plain("Image CVE JSON report stored in: %s" % manifest_name)
}

ROOTFS_POSTPROCESS_COMMAND:prepend = "${@'cve_check_write_rootfs_manifest; ' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}"
do_rootfs[recrdeptask] += "${@'do_cve_check' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}"
do_populate_sdk[recrdeptask] += "${@'do_cve_check' if d.getVar('CVE_CHECK_CREATE_MANIFEST') == '1' else ''}"

def check_cves(d, patched_cves):
    """
    Connect to the NVD database and find unpatched cves.
    """
    from oe.cve_check import Version, convert_cve_version

    pn = d.getVar("PN")
    real_pv = d.getVar("PV")
    suffix = d.getVar("CVE_VERSION_SUFFIX")

    cves_unpatched = []
    cves_ignored = []
    cves_status = []
    cves_in_recipe = False
    # CVE_PRODUCT can contain more than one product (eg. curl/libcurl)
    products = d.getVar("CVE_PRODUCT").split()
    # If this has been unset then we're not scanning for CVEs here (for example, image recipes)
    if not products:
        return ([], [], [], [])
    pv = d.getVar("CVE_VERSION").split("+git")[0]

    # If the recipe has been skipped/ignored we return empty lists
    if pn in d.getVar("CVE_CHECK_SKIP_RECIPE").split():
        bb.note("Recipe has been skipped by cve-check")
        return ([], [], [], [])

    cve_ignore = d.getVar("CVE_CHECK_IGNORE").split()

    import sqlite3
    db_file = d.expand("file:${CVE_CHECK_DB_FILE}?mode=ro")
    conn = sqlite3.connect(db_file, uri=True)

    # For each of the known product names (e.g. curl has CPEs using curl and libcurl)...
    for product in products:
        cves_in_product = False
        if ":" in product:
            vendor, product = product.split(":", 1)
        else:
            vendor = "%"

        # Find all relevant CVE IDs.
        cve_cursor = conn.execute("SELECT DISTINCT ID FROM PRODUCTS WHERE PRODUCT IS ? AND VENDOR LIKE ?", (product, vendor))
        for cverow in cve_cursor:
            cve = cverow[0]

            if cve in cve_ignore:
                bb.note("%s-%s ignores %s" % (product, pv, cve))
                cves_ignored.append(cve)
                continue
            elif cve in patched_cves:
                bb.note("%s has been patched" % (cve))
                continue
            # Write status once only for each product
            if not cves_in_product:
                cves_status.append([product, True])
                cves_in_product = True
                cves_in_recipe = True

            vulnerable = False
            ignored = False

            product_cursor = conn.execute("SELECT * FROM PRODUCTS WHERE ID IS ? AND PRODUCT IS ? AND VENDOR LIKE ?", (cve, product, vendor))
            for row in product_cursor:
                (_, _, _, version_start, operator_start, version_end, operator_end) = row
                #bb.debug(2, "Evaluating row " + str(row))
                if cve in cve_ignore:
                    ignored = True

                version_start = convert_cve_version(version_start)
                version_end = convert_cve_version(version_end)

                if (operator_start == '=' and pv == version_start) or version_start == '-':
                    vulnerable = True
                else:
                    if operator_start:
                        try:
                            vulnerable_start =  (operator_start == '>=' and Version(pv,suffix) >= Version(version_start,suffix))
                            vulnerable_start |= (operator_start == '>' and Version(pv,suffix) > Version(version_start,suffix))
                        except:
                            bb.warn("%s: Failed to compare %s %s %s for %s" %
                                    (product, pv, operator_start, version_start, cve))
                            vulnerable_start = False
                    else:
                        vulnerable_start = False

                    if operator_end:
                        try:
                            vulnerable_end  = (operator_end == '<=' and Version(pv,suffix) <= Version(version_end,suffix) )
                            vulnerable_end |= (operator_end == '<' and Version(pv,suffix) < Version(version_end,suffix) )
                        except:
                            bb.warn("%s: Failed to compare %s %s %s for %s" %
                                    (product, pv, operator_end, version_end, cve))
                            vulnerable_end = False
                    else:
                        vulnerable_end = False

                    if operator_start and operator_end:
                        vulnerable = vulnerable_start and vulnerable_end
                    else:
                        vulnerable = vulnerable_start or vulnerable_end

                if vulnerable:
                    if ignored:
                        bb.note("%s is ignored in %s-%s" % (cve, pn, real_pv))
                        cves_ignored.append(cve)
                    else:
                        bb.note("%s-%s is vulnerable to %s" % (pn, real_pv, cve))
                        cves_unpatched.append(cve)
                    break
            product_cursor.close()

            if not vulnerable:
                bb.note("%s-%s is not vulnerable to %s" % (pn, real_pv, cve))
                patched_cves.add(cve)
        cve_cursor.close()

        if not cves_in_product:
            bb.note("No CVE records found for product %s, pn %s" % (product, pn))
            cves_status.append([product, False])

    conn.close()

    if not cves_in_recipe:
        bb.note("No CVE records for products in recipe %s" % (pn))

    return (list(cves_ignored), list(patched_cves), cves_unpatched, cves_status)

def get_cve_info(d, cves):
    """
    Get CVE information from the database.
    """

    import sqlite3

    cve_data = {}
    db_file = d.expand("file:${CVE_CHECK_DB_FILE}?mode=ro")
    conn = sqlite3.connect(db_file, uri=True)

    for cve in cves:
        cursor = conn.execute("SELECT * FROM NVD WHERE ID IS ?", (cve,))
        for row in cursor:
            cve_data[row[0]] = {}
            cve_data[row[0]]["summary"] = row[1]
            cve_data[row[0]]["scorev2"] = row[2]
            cve_data[row[0]]["scorev3"] = row[3]
            cve_data[row[0]]["modified"] = row[4]
            cve_data[row[0]]["vector"] = row[5]
        cursor.close()
    conn.close()
    return cve_data

def cve_write_data_text(d, patched, unpatched, ignored, cve_data):
    """
    Write CVE information in WORKDIR; and to CVE_CHECK_DIR, and
    CVE manifest if enabled.
    """

    cve_file = d.getVar("CVE_CHECK_LOG")
    fdir_name  = d.getVar("FILE_DIRNAME")
    layer = fdir_name.split("/")[-3]

    include_layers = d.getVar("CVE_CHECK_LAYER_INCLUDELIST").split()
    exclude_layers = d.getVar("CVE_CHECK_LAYER_EXCLUDELIST").split()

    report_all = d.getVar("CVE_CHECK_REPORT_PATCHED") == "1"

    if exclude_layers and layer in exclude_layers:
        return

    if include_layers and layer not in include_layers:
        return

    # Early exit, the text format does not report packages without CVEs
    if not patched+unpatched+ignored:
        return

    nvd_link = "https://nvd.nist.gov/vuln/detail/"
    write_string = ""
    unpatched_cves = []
    bb.utils.mkdirhier(os.path.dirname(cve_file))

    for cve in sorted(cve_data):
        is_patched = cve in patched
        is_ignored = cve in ignored

        if (is_patched or is_ignored) and not report_all:
            continue

        write_string += "LAYER: %s\n" % layer
        write_string += "PACKAGE NAME: %s\n" % d.getVar("PN")
        write_string += "PACKAGE VERSION: %s%s\n" % (d.getVar("EXTENDPE"), d.getVar("PV"))
        write_string += "CVE: %s\n" % cve
        if is_ignored:
            write_string += "CVE STATUS: Ignored\n"
        elif is_patched:
            write_string += "CVE STATUS: Patched\n"
        else:
            unpatched_cves.append(cve)
            write_string += "CVE STATUS: Unpatched\n"
        write_string += "CVE SUMMARY: %s\n" % cve_data[cve]["summary"]
        write_string += "CVSS v2 BASE SCORE: %s\n" % cve_data[cve]["scorev2"]
        write_string += "CVSS v3 BASE SCORE: %s\n" % cve_data[cve]["scorev3"]
        write_string += "VECTOR: %s\n" % cve_data[cve]["vector"]
        write_string += "MORE INFORMATION: %s%s\n\n" % (nvd_link, cve)

    if unpatched_cves and d.getVar("CVE_CHECK_SHOW_WARNINGS") == "1":
        bb.warn("Found unpatched CVE (%s), for more information check %s" % (" ".join(unpatched_cves),cve_file))

    with open(cve_file, "w") as f:
        bb.note("Writing file %s with CVE information" % cve_file)
        f.write(write_string)

    if d.getVar("CVE_CHECK_COPY_FILES") == "1":
        deploy_file = d.getVar("CVE_CHECK_RECIPE_FILE")
        bb.utils.mkdirhier(os.path.dirname(deploy_file))
        with open(deploy_file, "w") as f:
            f.write(write_string)

    if d.getVar("CVE_CHECK_CREATE_MANIFEST") == "1":
        cvelogpath = d.getVar("CVE_CHECK_SUMMARY_DIR")
        bb.utils.mkdirhier(cvelogpath)

        with open(d.getVar("CVE_CHECK_TMP_FILE"), "a") as f:
            f.write("%s" % write_string)

def cve_check_write_json_output(d, output, direct_file, deploy_file, manifest_file):
    """
    Write CVE information in the JSON format: to WORKDIR; and to
    CVE_CHECK_DIR, if CVE manifest if enabled, write fragment
    files that will be assembled at the end in cve_check_write_rootfs_manifest.
    """

    import json

    write_string = json.dumps(output, indent=2)
    with open(direct_file, "w") as f:
        bb.note("Writing file %s with CVE information" % direct_file)
        f.write(write_string)

    if d.getVar("CVE_CHECK_COPY_FILES") == "1":
        bb.utils.mkdirhier(os.path.dirname(deploy_file))
        with open(deploy_file, "w") as f:
            f.write(write_string)

    if d.getVar("CVE_CHECK_CREATE_MANIFEST") == "1":
        cvelogpath = d.getVar("CVE_CHECK_SUMMARY_DIR")
        index_path = d.getVar("CVE_CHECK_SUMMARY_INDEX_PATH")
        bb.utils.mkdirhier(cvelogpath)
        fragment_file = os.path.basename(deploy_file)
        fragment_path = os.path.join(cvelogpath, fragment_file)
        with open(fragment_path, "w") as f:
            f.write(write_string)
        with open(index_path, "a+") as f:
            f.write("%s\n" % fragment_path)

def cve_write_data_json(d, patched, unpatched, ignored, cve_data, cve_status):
    """
    Prepare CVE data for the JSON format, then write it.
    """

    output = {"version":"1", "package": []}
    nvd_link = "https://nvd.nist.gov/vuln/detail/"

    fdir_name  = d.getVar("FILE_DIRNAME")
    layer = fdir_name.split("/")[-3]

    include_layers = d.getVar("CVE_CHECK_LAYER_INCLUDELIST").split()
    exclude_layers = d.getVar("CVE_CHECK_LAYER_EXCLUDELIST").split()

    report_all = d.getVar("CVE_CHECK_REPORT_PATCHED") == "1"

    if exclude_layers and layer in exclude_layers:
        return

    if include_layers and layer not in include_layers:
        return

    unpatched_cves = []

    product_data = []
    for s in cve_status:
        p = {"product": s[0], "cvesInRecord": "Yes"}
        if s[1] == False:
            p["cvesInRecord"] = "No"
        product_data.append(p)

    package_version = "%s%s" % (d.getVar("EXTENDPE"), d.getVar("PV"))
    package_data = {
        "name" : d.getVar("PN"),
        "layer" : layer,
        "version" : package_version,
        "products": product_data
    }
    cve_list = []

    for cve in sorted(cve_data):
        is_patched = cve in patched
        is_ignored = cve in ignored
        status = "Unpatched"
        if (is_patched or is_ignored) and not report_all:
            continue
        if is_ignored:
            status = "Ignored"
        elif is_patched:
            status = "Patched"
        else:
            # default value of status is Unpatched
            unpatched_cves.append(cve)

        issue_link = "%s%s" % (nvd_link, cve)

        cve_item = {
            "id" : cve,
            "summary" : cve_data[cve]["summary"],
            "scorev2" : cve_data[cve]["scorev2"],
            "scorev3" : cve_data[cve]["scorev3"],
            "vector" : cve_data[cve]["vector"],
            "status" : status,
            "link": issue_link
        }
        cve_list.append(cve_item)

    package_data["issue"] = cve_list
    output["package"].append(package_data)

    direct_file = d.getVar("CVE_CHECK_LOG_JSON")
    deploy_file = d.getVar("CVE_CHECK_RECIPE_FILE_JSON")
    manifest_file = d.getVar("CVE_CHECK_SUMMARY_FILE_NAME_JSON")

    cve_check_write_json_output(d, output, direct_file, deploy_file, manifest_file)

def cve_write_data(d, patched, unpatched, ignored, cve_data, status):
    """
    Write CVE data in each enabled format.
    """

    if d.getVar("CVE_CHECK_FORMAT_TEXT") == "1":
        cve_write_data_text(d, patched, unpatched, ignored, cve_data)
    if d.getVar("CVE_CHECK_FORMAT_JSON") == "1":
        cve_write_data_json(d, patched, unpatched, ignored, cve_data, status)
