cmd/cvetriage,internal: add initial command
An initial layout for cvetriage is added, which reads data from
triaged-cve-list and prints it out. Logic for triaging actual CVEs from
CVE list will be added in the next few CLs.
Change-Id: Ibc2e3a7e78e9ee8310f0717b14cbdfafca9c2eb9
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/356390
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
diff --git a/cmd/cvetriage/main.go b/cmd/cvetriage/main.go
new file mode 100644
index 0000000..f06d851
--- /dev/null
+++ b/cmd/cvetriage/main.go
@@ -0,0 +1,80 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Command cvetriage is used to manage the processing and triaging of CVE data
+// from the github.com/CVEProject/cvelist git repository. It is intended to be
+// run by a third-party scheduler, such as Cloud Run, at some predefined interval.
+//
+// Running this tool will do the following: run the tool does the following things:
+// 1. Reads each CVE JSON file, filtering them based on possible indicators
+// that the CVE is related to a Go project.
+// 2. Reads a list of already processed CVEs (currently stored at
+// triaged-cve-list, but will likely be moved to a database in the future), skipping
+// any CVEs from the previous step that have already been processed.
+// 3. For each unprocessed CVE, a preliminary YAML vulnerability report will be generated, and a
+// GitHub issue will be created.
+package main
+
+import (
+ "fmt"
+ "log"
+ "strings"
+
+ "golang.org/x/vulndb/internal"
+)
+
+func main() {
+ if err := run(); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func run() error {
+ triaged, err := readTriagedCVEList()
+ if err != nil {
+ return err
+ }
+ // TODO: implement CVE list triage logic and replace this print.
+ for k := range triaged {
+ fmt.Println(k)
+ }
+ return nil
+}
+
+const (
+ triagedCVEList = "triaged-cve-list"
+ statusFalsePositive = "false-positive"
+ statusTriaged = "triaged"
+)
+
+func readTriagedCVEList() (map[string]bool, error) {
+ triaged := map[string]bool{}
+ lines, err := internal.ReadFileLines(triagedCVEList)
+ if err != nil {
+ return nil, err
+ }
+ for _, l := range lines {
+ vuln := strings.Fields(l)
+ if len(vuln) < 2 {
+ return nil, fmt.Errorf("unexpected syntax: %q", l)
+ }
+ var (
+ cveID = vuln[0]
+ status = vuln[1]
+ )
+ if status != statusFalsePositive && status != statusTriaged {
+ return nil, fmt.Errorf("unexpected syntax: %q", l)
+ }
+ if status == statusTriaged {
+ if len(vuln) != 3 {
+ return nil, fmt.Errorf("unexpected syntax: %q", l)
+ }
+ triaged[cveID] = true
+ }
+ if status == statusFalsePositive {
+ triaged[cveID] = true
+ }
+ }
+ return triaged, nil
+}
diff --git a/internal/internal.go b/internal/internal.go
new file mode 100644
index 0000000..d8055b5
--- /dev/null
+++ b/internal/internal.go
@@ -0,0 +1,36 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package internal contains functionality for x/vulndb.
+package internal
+
+import (
+ "bufio"
+ "os"
+ "strings"
+)
+
+// Readfilelines reads and returns the lines from a file.
+// Whitespace on each line is trimmed.
+// Blank lines and lines beginning with '#' are ignored.
+func ReadFileLines(filename string) (lines []string, err error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ s := bufio.NewScanner(f)
+ for s.Scan() {
+ line := strings.TrimSpace(s.Text())
+ if line == "" || strings.HasPrefix(line, "#") {
+ continue
+ }
+ lines = append(lines, line)
+ }
+ if s.Err() != nil {
+ return nil, s.Err()
+ }
+ return lines, nil
+}