aboutsummaryrefslogtreecommitdiff
path: root/brew_vulns.go
blob: 7816e477f60bedf411ca783d64f9dfd60be8575b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package app

import (
	"bytes"
	"encoding/json"
	"fmt"
	"os/exec"
)

// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse and unparse this JSON data, add this code to your project and do:
//
//    brewVulns, err := UnmarshalBrewVulns(bytes)
//    bytes, err = brewVulns.Marshal()

func UnmarshalBrewVulns(data []byte) (BrewVulns, error) {
	var r BrewVulns
	err := json.Unmarshal(data, &r)
	return r, err
}

func (r *BrewVulns) Marshal() ([]byte, error) {
	return json.Marshal(r)
}

type BrewVulns struct {
	Findings        []Finding `json:"findings"`
	SkippedFormulae []string  `json:"skipped_formulae"`
}

type Finding struct {
	Formula         string    `json:"formula"`
	Version         string    `json:"version"`
	Tag             string    `json:"tag"`
	RepoURL         string    `json:"repo_url"`
	Vulnerabilities []Patched `json:"vulnerabilities"`
	Patched         []Patched `json:"patched"`
}

type Patched struct {
	ID            string   `json:"id"`
	Severity      Severity `json:"severity"`
	Summary       *string  `json:"summary"`
	Aliases       []string `json:"aliases"`
	FixedVersions []string `json:"fixed_versions"`
}

type Severity string

const (
	High    Severity = "HIGH"
	Low     Severity = "LOW"
	Medium  Severity = "MEDIUM"
	Unknown Severity = "UNKNOWN"
)

// runBrewVulns executes `brew vulns --json` and decodes the findings.
func runBrewVulns() (BrewVulns, error) {
	cmd := exec.Command("brew", "vulns", "--json")
	var out, errBuf bytes.Buffer
	cmd.Stdout = &out
	cmd.Stderr = &errBuf

	if err := cmd.Run(); err != nil && out.Len() == 0 {
		msg := errBuf.String()
		if msg == "" {
			msg = err.Error()
		}
		return BrewVulns{}, fmt.Errorf("brew vulns: %v: %s", err, msg)
	}

	r, err := UnmarshalBrewVulns(out.Bytes())
	if err != nil {
		if msg := errBuf.String(); msg != "" {
			return BrewVulns{}, fmt.Errorf("decode brew vulns output: %v: %s", err, msg)
		}
		return BrewVulns{}, fmt.Errorf("decode brew vulns output: %w", err)
	}

	return r, nil
}