Source code for varats.provider.cve.cve_provider

"""Module for the :class:`CVEProvider`."""
import typing as tp

from benchbuild.project import Project

from varats.project.project_util import get_local_project_git_path
from varats.provider.cve.cve import CVE, find_all_cve, find_cve, find_cwe
from varats.provider.cve.cve_map import generate_cve_map
from varats.provider.provider import Provider


[docs]class CVEProviderHook(): """ Gives the :class:`CVEProvider` the necessary information how to find CVEs and CWEs for a project. This class should be inherited by projects. """
[docs] @classmethod def get_cve_product_info(cls) -> tp.List[tp.Tuple[str, str]]: """ Get information on how to find CVEs for a project. Returns: a tuple ``(vendor, product)`` """ raise NotImplementedError("Must be overridden by the project.")
[docs]class CVEProvider(Provider): """Provides CVE and CWE information for a project.""" def __init__(self, project: tp.Type[Project]) -> None: super().__init__(project) if hasattr(project, "get_cve_product_info"): self.__cve_map = generate_cve_map( get_local_project_git_path(project.NAME), project.get_cve_product_info() ) else: raise ValueError( f"Project {project} does not implement " f"CVEProviderHook." )
[docs] @classmethod def create_provider_for_project( cls, project: tp.Type[Project] ) -> tp.Optional['CVEProvider']: if hasattr(project, "get_cve_product_info"): return CVEProvider(project) return None
[docs] @classmethod def create_default_provider( cls, project: tp.Type[Project] ) -> 'CVEProvider': return CVEDefaultProvider(project)
[docs] def get_revision_cve_tuples( self ) -> tp.Set[tp.Tuple[str, tp.FrozenSet[CVE]]]: """ Get all CVEs associated with this provider's project along with the fixing commits/versions. Return: a set of tuples of commit hash and cves """ return {(k, frozenset(tp.cast(tp.Set[CVE], v["cve"]))) for k, v in self.__cve_map.items()}
[docs]class CVEDefaultProvider(CVEProvider): """Default implementation of the :class:`CVE provider` for projects that do not (yet) support CVEs.""" def __init__(self, project: tp.Type[Project]) -> None: # pylint: disable=E1003 super(CVEProvider, self).__init__(project)
[docs] def get_revision_cve_tuples( self ) -> tp.Set[tp.Tuple[str, tp.FrozenSet[CVE]]]: return set()
# TODO: remove below functions once we remove the cve driver
[docs]def list_cve_for_projects( vendor: str, product: str, verbose: bool = False ) -> None: """ List all CVE's for the given vendor/product combination. Call via vara-sec list-cve <vendor> <product>. """ print(f"Listing CVE's for {vendor}/{product}:") try: for cve in find_all_cve(vendor=vendor, product=product): if verbose: print(cve, end='\n\n') else: print(f'{cve.cve_id:20} [{cve.url}]') except ValueError: print('No entries found.')
[docs]def info(search: str, verbose: bool = False) -> None: """Search for matching CVE/CWE and print its data.""" print(f"Fetching information for {search}:") if search.lower().startswith('cve-'): cve = find_cve(cve_id=search) if verbose: print(cve) else: print(f'{cve.cve_id:20} [{cve.url}]') elif search.lower().startswith('cwe-'): cwe = find_cwe(cwe_id=search) if verbose: print(cwe) else: print(f'{cwe.cwe_id:20} [{cwe.url}]') else: print( f'Could not parse input. Did you mean CVE-{search} or CWE-{search}?' )