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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// utility functions
package util
import (
"compress/gzip"
"encoding/json"
"encoding/xml"
"github.com/pablotron/cvez/cisa"
"github.com/pablotron/cvez/cpedict"
"github.com/pablotron/cvez/cpematch"
"github.com/pablotron/cvez/nvdmirror"
nvd_feed "github.com/pablotron/cvez/feed"
"os"
"path/filepath"
)
// read gzipped file, pass reader to callback.
func gzOpen(path string, fn func(*gzip.Reader) error) error {
f, err := os.Open(path)
if err != nil {
return err
}
defer f.Close()
// create gzip reader
r, err := gzip.NewReader(f)
if err != nil {
return err
}
// call func, return result
return fn(r)
}
// read gzipped json, pass decoder to callback
func jsonGzOpen(path string, fn func(*json.Decoder) error) error {
return gzOpen(path, func(r *gzip.Reader) error {
return fn(json.NewDecoder(r))
})
}
// read gzipped xml, pass decoder to callback
func xmlGzOpen(path string, fn func(*xml.Decoder) error) error {
return gzOpen(path, func(r *gzip.Reader) error {
return fn(xml.NewDecoder(r))
})
}
type getFeedResult struct {
feed nvd_feed.Feed
err error
}
// Read feed from file.
func getFeed(path string) getFeedResult {
var feed nvd_feed.Feed
err := jsonGzOpen(path, func(d *json.Decoder) error {
return d.Decode(&feed)
})
return getFeedResult { feed, err }
}
// Load CVE feeds in parallel.
func GetFeeds(cacheDir string, updates []nvdmirror.Update) ([]nvd_feed.Feed, error) {
numFeeds := 0
// load feeds in parallel
ch := make(chan getFeedResult)
for _, row := range(updates) {
if row.Type == nvdmirror.UpdateCveYear {
numFeeds += 1
go func(path string) {
ch <- getFeed(path)
}(filepath.Join(cacheDir, row.Path))
}
}
// collect feeds
feeds := make([]nvd_feed.Feed, numFeeds)
for i := 0; i < numFeeds; i++ {
if r := <-ch; r.err != nil {
return feeds, r.err
} else {
feeds[i] = r.feed
}
}
return feeds, nil
}
// Read cpe matches from file.
func GetCpeMatches(path string) (cpematch.Matches, error) {
var matches cpematch.Matches
return matches, jsonGzOpen(path, func(d *json.Decoder) error {
return d.Decode(&matches)
})
}
// Read cpe dictionary from file.
func GetCpeDict(path string) (cpedict.Dictionary, error) {
var dict cpedict.Dictionary
return dict, xmlGzOpen(path, func(d *xml.Decoder) error {
return d.Decode(&dict)
})
}
// Read cisa catalog from file.
func GetCisaCatalog(path string) (cisa.Catalog, error) {
var cat cisa.Catalog
f, err := os.Open(path)
if err != nil {
return cat, err
}
defer f.Close()
// decode/return catalog
d := json.NewDecoder(f)
return cat, d.Decode(&cat)
}
|