Skip to content

Commit

Permalink
feat(sles): prefer bz2 files where available and account for addition…
Browse files Browse the repository at this point in the history
…al severity mappings (#625)

Signed-off-by: Weston Steimel <[email protected]>
  • Loading branch information
westonsteimel authored Jul 11, 2024
1 parent 3ae59c4 commit a931ec3
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
13 changes: 11 additions & 2 deletions src/vunnel/providers/sles/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from decimal import Decimal, DecimalException
from typing import TYPE_CHECKING

import requests
from cvss import CVSS3
from cvss.exceptions import CVSS3MalformedError

Expand Down Expand Up @@ -39,15 +40,17 @@
severity_map={
"low": "Low",
"moderate": "Medium",
"medium": "Medium",
"high": "High",
"important": "High",
"critical": "Critical",
},
)


class Parser:
__oval_url__ = "https://ftp.suse.com/pub/projects/security/oval/suse.linux.enterprise.server.{}.xml.gz"
__oval_file_name__ = "suse-linux-enterprise-server-{}.xml.gz"
__oval_url__ = "https://ftp.suse.com/pub/projects/security/oval/suse.linux.enterprise.server.{}.xml.bz2"
__oval_file_name__ = "suse-linux-enterprise-server-{}.xml.bz2"
__oval_dir_path__ = "oval"
__source_dir_path__ = "source"

Expand Down Expand Up @@ -79,6 +82,12 @@ def _download(self, major_version: str) -> str:

oval_file_path = os.path.join(self.oval_dir_path, self.__oval_file_name__.format(major_version))
download_url = self.__oval_url__.format(major_version)

# We should prefer the .bz2 files going forward, but fall back to .gz if unavailable for a particular release
if requests.head(download_url, timeout=self.download_timeout).status_code == 404:
download_url = download_url.removesuffix(".bz2") + ".gz"
oval_file_path = oval_file_path.removesuffix(".bz2") + ".gz"

self.urls.append(download_url)

self.logger.info(
Expand Down
15 changes: 11 additions & 4 deletions src/vunnel/utils/oval_parser.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from __future__ import annotations

import bz2
import copy
import gzip
import logging
import os
import re
from typing import Callable

import defusedxml.ElementTree as ET

Expand Down Expand Up @@ -48,6 +50,14 @@ class Config:
ns_format = None


def get_opener(filename: str) -> Callable:
if filename.endswith(".gz"):
return gzip.open
if filename.endswith(".bz2"):
return bz2.open
return open


def parse(dest_file: str, config: Config, vuln_dict: dict | None = None): # noqa: C901, PLR0912
"""
Parse the oval file and return a dictionary with tuple (ID, namespace) as the key
Expand All @@ -67,10 +77,7 @@ def parse(dest_file: str, config: Config, vuln_dict: dict | None = None): # noq

if os.path.exists(dest_file):
processing = False
opener = open

if dest_file.endswith(".gz"):
opener = gzip.open
opener = get_opener(dest_file)

with opener(dest_file, "rb") as f: # noqa: F841
for event, element in ET.iterparse(dest_file, events=("start", "end")):
Expand Down
15 changes: 11 additions & 4 deletions src/vunnel/utils/oval_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from __future__ import annotations

import bz2
import enum
import gzip
import logging
Expand All @@ -15,6 +16,7 @@
from abc import ABC, abstractmethod
from collections import defaultdict
from dataclasses import dataclass
from typing import Callable

from defusedxml.ElementTree import iterparse

Expand Down Expand Up @@ -399,6 +401,14 @@ def get_oval_element(self, xml_element: ET.Element, config: OVALParserConfig) ->
return result


def get_opener(filename: str) -> Callable:
if filename.endswith(".gz"):
return gzip.open
if filename.endswith(".bz2"):
return bz2.open
return open


def iter_parse_vulnerability_file(
oval_file_path: str,
parser_config: OVALParserConfig,
Expand All @@ -417,10 +427,7 @@ def iter_parse_vulnerability_file(

if os.path.exists(oval_file_path):
ingress = False
opener = open

if oval_file_path.endswith(".gz"):
opener = gzip.open
opener = get_opener(oval_file_path)

with opener(oval_file_path, "rb") as f:
for event, xml_element in iterparse(f, events=("start", "end")):
Expand Down

0 comments on commit a931ec3

Please sign in to comment.