-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
107 lines (88 loc) · 2.43 KB
/
main.go
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"context"
"fmt"
"os"
"strings"
"github.com/dememorized/forsikt/auditfile"
"github.com/dememorized/forsikt/graph"
"golang.org/x/mod/semver"
)
func main() {
mods, err := graph.GraphModule(context.Background())
if err != nil {
panic(err)
}
filename := "go.audit"
bytes, err := os.ReadFile(filename)
if err != nil {
panic(err)
}
af, err := auditfile.Parse(filename, bytes)
if err != nil {
panic(err)
}
trusts := map[string]map[string]string{}
for _, t := range af.Trust {
if t == nil {
continue
}
if _, exists := trusts[t.Mod.Path]; !exists {
trusts[t.Mod.Path] = make(map[string]string)
}
trusts[t.Mod.Path][t.Mod.High] = t.Mod.Low
}
violations := map[string]map[string]string{}
for _, t := range af.Violation {
if t == nil {
continue
}
if _, exists := violations[t.Mod.Path]; !exists {
violations[t.Mod.Path] = make(map[string]string)
}
violations[t.Mod.Path][t.Mod.High] = t.Mod.Low
}
resNotFounds := []string{}
resVersionMismatch := []string{}
resViolations := []string{}
for _, mod := range mods.Versions {
p, v := mod.Path, mod.Version
if _, exists := violations[p]; exists {
if versionInRanges(v, violations[p]) {
resViolations = append(resViolations, mod.String())
continue
}
}
if _, exists := trusts[p]; exists {
if versionInRanges(v, trusts[p]) {
continue
}
resVersionMismatch = append(resVersionMismatch, mod.String())
} else {
resNotFounds = append(resNotFounds, mod.String())
}
}
if len(resNotFounds) == 0 && len(resVersionMismatch) == 0 && len(resViolations) == 0 {
// all good!
return
}
fmt.Printf("modules missing from '%s':\n\t%s\n\n", filename, strings.Join(resNotFounds, "\n\t"))
fmt.Printf("modules with wrong versions from '%s':\n\t%s\n\n", filename, strings.Join(resVersionMismatch, "\n\t"))
fmt.Printf("policy violations from '%s':\n\t%s\n\n", filename, strings.Join(resViolations, "\n\t"))
fmt.Printf("### audit failed ###\n%d missing modules, %d version mismatches, %d policy violations\n",
len(resNotFounds), len(resVersionMismatch), len(resViolations))
os.Exit(1)
}
func versionInRanges(v string, ranges map[string]string) bool {
// catch-all '*'
if _, catchall := ranges[""]; catchall {
return true
}
if lower, ok := ranges[v]; ok {
if semver.Compare(v, lower) == 0 {
return true
}
return versionInRanges(lower, ranges)
}
return false
}