All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] cve-check: add option to format reports as comma seperated values
@ 2020-05-12  8:17 timon.ulrich
  2020-05-12 14:56 ` [OE-core] " Ross Burton
  0 siblings, 1 reply; 2+ messages in thread
From: timon.ulrich @ 2020-05-12  8:17 UTC (permalink / raw)
  To: openembedded-core; +Cc: Timon Ulrich

From: Timon Ulrich <t.ulrich@anapur.de>

cve-check will check if CVE_CHECK_FORMAT_CSV is set and format the outputs
(manifest etc.) as CSV for use in spreadsheets.

Signed-off-by: Timon Ulrich <t.ulrich@anapur.de>
---
 meta/classes/cve-check.bbclass | 52 ++++++++++++++++++++++++++--------
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/meta/classes/cve-check.bbclass b/meta/classes/cve-check.bbclass
index 2a530a0489..3933a78552 100644
--- a/meta/classes/cve-check.bbclass
+++ b/meta/classes/cve-check.bbclass
@@ -35,6 +35,7 @@ CVE_CHECK_DIR ??= "${DEPLOY_DIR}/cve"
 CVE_CHECK_MANIFEST ?= "${DEPLOY_DIR_IMAGE}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.cve"
 CVE_CHECK_COPY_FILES ??= "1"
 CVE_CHECK_CREATE_MANIFEST ??= "1"
+CVE_CHECK_FORMAT_CSV ??= "0"
 
 # Whitelist for packages (PN)
 CVE_CHECK_PN_WHITELIST ?= ""
@@ -98,10 +99,24 @@ python cve_check_write_rootfs_manifest () {
         manifest_name = d.getVar("CVE_CHECK_MANIFEST")
         cve_tmp_file = d.getVar("CVE_CHECK_TMP_FILE")
 
+        if d.getVar("CVE_CHECK_FORMAT_CSV") == "1":
+            manifest_name += ".csv"
+            
+            with open(cve_tmp_file, "r") as f:
+                db_update_timestamp = f.readline()
+                orig_tmp_file = f.readlines()[1:]
+            with open(cve_tmp_file, "w") as f:
+                f.write(db_update_timestamp+'\n')
+                f.write("PACKAGE NAME;PACKAGE VERSION;CVE;CVE STATUS;"
+                       "CVE SUMMARY;CVSS v2 BASE SCORE;CVSS v3 BASE SCORE;"
+                       "VECTOR;MORE INFORMATION\n")
+            with open(cve_tmp_file, "a") as f:
+                f.writelines(orig_tmp_file)
+
         shutil.copyfile(cve_tmp_file, manifest_name)
 
         if manifest_name and os.path.exists(manifest_name):
-            manifest_link = os.path.join(deploy_dir, "%s.cve" % link_name)
+            manifest_link = os.path.join(deploy_dir, "%s.cve%s" % (link_name, ".csv" if d.getVar("CVE_CHECK_FORMAT_CSV") == "1" else ""))
             # If we already have another manifest, update symlinks
             if os.path.exists(os.path.realpath(manifest_link)):
                 os.remove(manifest_link)
@@ -295,26 +310,35 @@ def cve_write_data(d, patched, unpatched, whitelisted, cve_data):
 
     cve_file = d.getVar("CVE_CHECK_LOG")
     nvd_link = "https://web.nvd.nist.gov/view/vuln/detail?vulnId="
+    eol_char = '\n' if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else ';'
     write_string = ""
     unpatched_cves = []
     bb.utils.mkdirhier(os.path.dirname(cve_file))
 
     for cve in sorted(cve_data):
-        write_string += "PACKAGE NAME: %s\n" % d.getVar("PN")
-        write_string += "PACKAGE VERSION: %s\n" % d.getVar("PV")
-        write_string += "CVE: %s\n" % cve
+        write_string += "%s%s%c" % ("PACKAGE NAME: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", d.getVar("PN"), eol_char)
+        write_string += "%s%s%c" % ("PACKAGE VERSION: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", d.getVar("PV"), eol_char)
+        write_string += "%s%s%c" % ("CVE: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", cve, eol_char)
+        if d.getVar("CVE_CHECK_FORMAT_CSV") != "1":
+            write_string += "CVE STATUS: "
         if cve in whitelisted:
-            write_string += "CVE STATUS: Whitelisted\n"
+            write_string += "Whitelisted"
         elif cve in patched:
-            write_string += "CVE STATUS: Patched\n"
+            write_string += "Patched"
         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)
+            write_string += "Unpatched"
+        write_string += eol_char
+        if d.getVar("CVE_CHECK_FORMAT_CSV") == "1":
+            write_string += "\"%s\"%c" % (cve_data[cve]["summary"].replace("\"","\'"), eol_char)
+        else:
+            write_string += "CVE SUMMARY: %s%c" % (cve_data[cve]["summary"], eol_char)
+        write_string += "%s%s%c" % ("CVSS v2 BASE SCORE: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", cve_data[cve]["scorev2"], eol_char)
+        write_string += "%s%s%c" % ("CVSS v3 BASE SCORE: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", cve_data[cve]["scorev3"], eol_char)
+        write_string += "%s%s%c" % ("VECTOR: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", cve_data[cve]["vector"], eol_char)
+        write_string += "%s%s%s\n" % ("MORE INFORMATION: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", nvd_link, cve)
+        if d.getVar("CVE_CHECK_FORMAT_CSV") != "1":
+            write_string += '\n'
 
     if unpatched_cves:
         bb.warn("Found unpatched CVE (%s), for more information check %s" % (" ".join(unpatched_cves),cve_file))
@@ -328,6 +352,10 @@ def cve_write_data(d, patched, unpatched, whitelisted, cve_data):
         bb.utils.mkdirhier(cve_dir)
         deploy_file = os.path.join(cve_dir, d.getVar("PN"))
         with open(deploy_file, "w") as f:
+            if d.getVar("CVE_CHECK_FORMAT_CSV") == "1":
+                f.write("PACKAGE NAME;PACKAGE VERSION;CVE;CVE STATUS;"
+                       "CVE SUMMARY;CVSS v2 BASE SCORE;CVSS v3 BASE SCORE;"
+                       "VECTOR;MORE INFORMATION\n")
             f.write(write_string)
 
     if d.getVar("CVE_CHECK_CREATE_MANIFEST") == "1":
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [OE-core] [PATCH v2] cve-check: add option to format reports as comma seperated values
  2020-05-12  8:17 [PATCH v2] cve-check: add option to format reports as comma seperated values timon.ulrich
@ 2020-05-12 14:56 ` Ross Burton
  0 siblings, 0 replies; 2+ messages in thread
From: Ross Burton @ 2020-05-12 14:56 UTC (permalink / raw)
  To: timon.ulrich; +Cc: OE-core, Timon Ulrich

On Tue, 12 May 2020 at 09:17, <timon.ulrich@kabelmail.de> wrote:
> +        if d.getVar("CVE_CHECK_FORMAT_CSV") == "1":
> +            manifest_name += ".csv"
> +
> +            with open(cve_tmp_file, "r") as f:
> +                db_update_timestamp = f.readline()
> +                orig_tmp_file = f.readlines()[1:]
> +            with open(cve_tmp_file, "w") as f:
> +                f.write(db_update_timestamp+'\n')
> +                f.write("PACKAGE NAME;PACKAGE VERSION;CVE;CVE STATUS;"
> +                       "CVE SUMMARY;CVSS v2 BASE SCORE;CVSS v3 BASE SCORE;"
> +                       "VECTOR;MORE INFORMATION\n")

If writing a CSV file, it's really best to use the built-in csv writer
classes as they handle quoting and so on for you.

> +        write_string += "%s%s%c" % ("PACKAGE NAME: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", d.getVar("PN"), eol_char)
> +        write_string += "%s%s%c" % ("PACKAGE VERSION: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", d.getVar("PV"), eol_char)
> +        write_string += "%s%s%c" % ("CVE: " if d.getVar("CVE_CHECK_FORMAT_CSV") != "1" else "", cve, eol_char)

This is getting unreadable.

How about having a report class and separate implementations for each
type, instead of trying to support both forms in the same code path?

Ross

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-05-12 14:57 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-12  8:17 [PATCH v2] cve-check: add option to format reports as comma seperated values timon.ulrich
2020-05-12 14:56 ` [OE-core] " Ross Burton

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.