providers/redhat/feed.go (56 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package redhat import ( "encoding/json" "fmt" "io" "os" "github.com/facebookincubator/nvdtools/providers/redhat/check" "github.com/facebookincubator/nvdtools/providers/redhat/schema" "github.com/facebookincubator/nvdtools/rpm" "github.com/facebookincubator/nvdtools/wfn" ) // Feed is a collection of CVEs from RedHat. type Feed struct { // Data is map of CVEs as returned by the redhat API, keyed by CVE names. Data map[string]*schema.CVE // pkgCVE is a package -> CVE map produced from data and cached. pkg2CVE packageFeed // rpm.Checker for this feed, cached. checker rpm.Checker } // LoadFeed loads a Feed from a JSON file. func LoadFeed(path string) (*Feed, error) { f, err := os.Open(path) if err != nil { return nil, fmt.Errorf("can't open file %q: %v", path, err) } defer f.Close() return loadFeed(f) } func loadFeed(r io.Reader) (*Feed, error) { var feed Feed if err := json.NewDecoder(r).Decode(&feed.Data); err != nil { return nil, fmt.Errorf("can't decode feed: %v", err) } return &feed, nil } // Checker returns an rpm.Checker that uses the Feed. func (feed *Feed) Checker() (rpm.Checker, error) { if feed.checker != nil { return feed.checker, nil } mc := make(mapChecker, len(feed.Data)) var err error for cveid, cve := range feed.Data { if mc[cveid], err = check.CVEChecker(cve); err != nil { if err == check.ErrCheckers { // no checkers could be created, just skip it delete(mc, cveid) continue } return nil, fmt.Errorf("can't create a checker for %q: %v", cveid, err) } } feed.checker = mc return mc, nil } // cve -> checker type mapChecker map[string]rpm.Checker // Check is part of the rpm.Check interface func (c mapChecker) Check(pkg *rpm.Package, distro *wfn.Attributes, cve string) bool { if chk, ok := c[cve]; ok { return chk.Check(pkg, distro, cve) } return false }