summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Williams <codehelp@debian.org>2021-12-20 10:46:25 +0000
committerNeil Williams <codehelp@debian.org>2022-01-27 09:08:15 +0000
commit576d2502fe6150b84c55d78b9337518e8d453a86 (patch)
treec024e8734a092a0146fb9c62164978ae1081c4c8
parent89e67eba224135aea7a133f54b25dd77f881a2ce (diff)
Add support for --input accepting email text on STDIN
-rwxr-xr-xbin/grab-cve-in-fix105
1 files changed, 78 insertions, 27 deletions
diff --git a/bin/grab-cve-in-fix b/bin/grab-cve-in-fix
index 11fd986786..cabda5584a 100755
--- a/bin/grab-cve-in-fix
+++ b/bin/grab-cve-in-fix
@@ -32,12 +32,13 @@ grab-cve-in-fix - #1001451
# pylint: disable=too-few-public-methods
# Examples:
-# --email https://lists.debian.org/debian-devel-changes/2021/12/msg01280.html
+# --archive https://lists.debian.org/debian-devel-changes/2021/12/msg01280.html
# --tracker https://tracker.debian.org/news/1285227/accepted-freerdp2-241dfsg1-1-source-into-unstable/
import argparse
import os
import glob
+import logging
import re
import sys
import requests
@@ -65,6 +66,14 @@ class ParseChanges:
self.bugs = {}
self.parsed = []
self.unstable_version = None
+ self.logger = logging.getLogger("grab-cve-in-fix")
+ self.logger.setLevel(logging.DEBUG)
+ # console logging
+ ch = logging.StreamHandler()
+ ch.setLevel(logging.DEBUG)
+ formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s")
+ ch.setFormatter(formatter)
+ self.logger.addHandler(ch)
def _read_cvelist(self):
os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
@@ -73,6 +82,12 @@ class ParseChanges:
for bug in data:
if bug.header.name == cve:
self.bugs[cve] = bug
+ if not self.cves:
+ self.logger.warning(
+ "no CVEs found in the changes output " "for %s %s",
+ self.source_package,
+ self.unstable_version,
+ )
def parse(self):
"""Parser-specific code to pick out the DEB822 content"""
@@ -84,7 +99,7 @@ class ParseChanges:
rel = Changes(self.parsed)
changes = rel.get("Changes")
if not changes:
- sys.stderr.write("ERROR:%s %s\n" % (rel, self.parsed))
+ self.logger.error("%s %s\n", rel, self.parsed)
return
self.source_package = rel.get("Source")
self.unstable_version = rel.get("Version")
@@ -113,9 +128,11 @@ class ParseChanges:
if line.package != self.source_package:
continue # allow for removed, old or alternate pkg names
if line.version:
- print(
- f"{cve} already has annotation for "
- f"- {self.source_package} {line.version}"
+ self.logger.info(
+ "%s already has annotation for - %s %s",
+ cve,
+ self.source_package,
+ line.version,
)
else:
mod_line = line._replace(version=self.unstable_version)
@@ -129,12 +146,16 @@ class ParseChanges:
if not modified:
return
if os.path.exists(cve_file):
- raise OSError("%s already exists" % cve_file)
+ self.logger.critical("%s already exists", cve_file)
+ return -1
mods = []
for cve in modified:
- print(
- f"Writing to ./{cve_file} with update for {cve.header.name} "
- f"- {self.source_package} {self.unstable_version}"
+ self.logger.info(
+ "Writing to ./%s with update for %s - %s %s",
+ cve_file,
+ cve.header.name,
+ self.source_package,
+ self.unstable_version,
)
with open(cve_file, "a") as snippet:
writecvelist(modified, snippet)
@@ -144,11 +165,9 @@ class ParseSources(ParseChanges):
"""Read latest version in unstable from updated local Sources files"""
def parse(self):
- print("Retrieving data from local packages data...")
+ self.logger.info("Retrieving data from local packages data...")
if not self.source_package or not self.cves:
- sys.stderr.write(
- "ERROR: for offline use, specify both --src and --cves options\n"
- )
+ self.logger.error("for offline use, specify both --src and --cves options")
return 1
# self.url contains pkgdir which needs to contain Sources files
os.chdir(self.url)
@@ -170,17 +189,19 @@ class ParseTrackerAccepted(ParseChanges):
e.g. https://tracker.debian.org/news/1285227/accepted-freerdp2-241dfsg1-1-source-into-unstable/
"""
+ MARKER = '<div class="email-news-body">'
+
def parse(self):
- print("Retrieving data from distro-tracker...")
+ self.logger.info("Retrieving data from distro-tracker...")
req = requests.get(self.url)
if req.status_code != requests.codes.ok: # pylint: disable=no-member
return 2
self.parsed = []
for line in req.text.splitlines():
- if not self.parsed and not line.startswith('<div class="email-news-body">'):
+ if not self.parsed and not line.startswith(self.MARKER):
continue
- if '<div class="email-news-body">' in line:
- line = line.replace('<div class="email-news-body">', "")
+ if self.MARKER in line:
+ line = line.replace(self.MARKER, "")
if "<pre>" in line:
line = line.replace("<pre>", "")
if line.startswith("\t"):
@@ -202,7 +223,7 @@ class ParseDDChanges(ParseChanges):
"""
def parse(self):
- print("Retrieving data from debian-devel-changes archive...")
+ self.logger.info("Retrieving data from debian-devel-changes archive...")
req = requests.get(self.url)
if req.status_code != requests.codes.ok: # pylint: disable=no-member
return 3
@@ -219,11 +240,33 @@ class ParseDDChanges(ParseChanges):
return 0
+class ParseDDStdIn(ParseChanges):
+ """
+ Parse an email originating from debian-devel-changes passed
+ on STDIN
+ """
+
+ MARKER = "-----BEGIN PGP SIGNED MESSAGE-----"
+
+ def parse(self):
+ self.logger.info("Retrieving data from debian-devel-changes archive...")
+ content = sys.stdin.read()
+ for line in content.splitlines():
+ if not self.parsed and not line.startswith(self.MARKER):
+ continue
+ self.parsed.append(line)
+ self._read_changes()
+ self._read_cvelist()
+ self.add_unstable_version()
+ return 0
+
+
def main():
"""
1: Provide an option to parse the email from debian-devel-changes
2: Provide an option to lookup the information using tracker.d.o
- 3: Fallback to lookup the information in the local apt-cache
+ 3: Provide an option to read an email from debian-devel-changes on stdin
+ 4: Fallback to lookup the information in the local apt-cache
data populated by 'make update-packages'
data/packages/sid__main_Sources
data/packages/sid__contrib_Sources
@@ -231,17 +274,22 @@ def main():
"""
parser = argparse.ArgumentParser(
description="Grab CVE data from a package upload for manual review",
- usage="%(prog)s [-h] [[--email EMAIL] | [--tracker TRACKER]] | "
+ usage="%(prog)s [-h] [[--input] | [--archive URL] | [--tracker TRACKER]] | "
"[[--src SRC] & [--cves [CVES ...]]]",
epilog="Data is written to a new <source_package>.list "
"file which can be used with './bin/merge-cve-files'",
)
online = parser.add_argument_group(
- "Online - query either the "
- "distro-tracker or debian-devel-changes mail archive"
+ "Online - query one of distro-tracker or "
+ "debian-devel-changes mail archive or debian-devel-changes email"
+ )
+ online.add_argument(
+ "--input",
+ action="store_true",
+ help="Read from a debian-devel-changes email on STDIN",
)
online.add_argument(
- "--email",
+ "--archive",
help="URL of debian-devel-changes " "announcement in the list archive",
)
online.add_argument(
@@ -258,8 +306,11 @@ def main():
"--cves", nargs="*", help="CVE ID tag with version from local packages files"
)
args = parser.parse_args()
- if args.email:
- data = ParseDDChanges(args.email)
+ if args.input:
+ data = ParseDDStdIn(args.input)
+ return data.parse()
+ if args.archive:
+ data = ParseDDChanges(args.archive)
return data.parse()
if args.tracker:
data = ParseTrackerAccepted(args.tracker)
@@ -270,8 +321,8 @@ def main():
data.source_package = args.src
data.cves = args.cves
return data.parse()
- sys.stderr.write("Unable to parse local package data!\n")
- sys.stderr.write("Try running 'make update-packages'\n")
+ self.logger.error("Unable to parse local package data!")
+ self.logger.error("Try running 'make update-packages'")
return -1

© 2014-2024 Faster IT GmbH | imprint | privacy policy