github.com/quay/claircore@v1.5.28/oracle/parser.go (about) 1 package oracle 2 3 import ( 4 "context" 5 "encoding/xml" 6 "fmt" 7 "io" 8 9 "github.com/quay/goval-parser/oval" 10 "github.com/quay/zlog" 11 12 "github.com/quay/claircore" 13 "github.com/quay/claircore/internal/xmlutil" 14 "github.com/quay/claircore/libvuln/driver" 15 "github.com/quay/claircore/pkg/ovalutil" 16 ) 17 18 const ( 19 oracleLinux5Platform = "Oracle Linux 5" 20 oracleLinux6Platform = "Oracle Linux 6" 21 oracleLinux7Platform = "Oracle Linux 7" 22 oracleLinux8Platform = "Oracle Linux 8" 23 oracleLinux9Platform = "Oracle Linux 9" 24 ) 25 26 // a mapping between oval platform string to claircore distribution 27 var platformToDist = map[string]*claircore.Distribution{ 28 oracleLinux5Platform: fiveDist, 29 oracleLinux6Platform: sixDist, 30 oracleLinux7Platform: sevenDist, 31 oracleLinux8Platform: eightDist, 32 oracleLinux9Platform: nineDist, 33 } 34 35 var _ driver.Parser = (*Updater)(nil) 36 37 func (u *Updater) Parse(ctx context.Context, r io.ReadCloser) ([]*claircore.Vulnerability, error) { 38 ctx = zlog.ContextWithValues(ctx, "component", "oracle/Updater.Parse") 39 zlog.Info(ctx).Msg("starting parse") 40 defer r.Close() 41 root := oval.Root{} 42 dec := xml.NewDecoder(r) 43 dec.CharsetReader = xmlutil.CharsetReader 44 if err := dec.Decode(&root); err != nil { 45 return nil, fmt.Errorf("oracle: unable to decode OVAL document: %w", err) 46 } 47 zlog.Debug(ctx).Msg("xml decoded") 48 protoVulns := func(def oval.Definition) ([]*claircore.Vulnerability, error) { 49 // In all oracle databases tested a single 50 // and correct platform string can be found inside a definition 51 // search is for good measure 52 proto := claircore.Vulnerability{ 53 Updater: u.Name(), 54 Name: def.Title, 55 Description: def.Description, 56 Issued: def.Advisory.Issued.Date, 57 Links: ovalutil.Links(def), 58 Severity: def.Advisory.Severity, 59 NormalizedSeverity: NormalizeSeverity(def.Advisory.Severity), 60 } 61 vs := []*claircore.Vulnerability{} 62 for _, affected := range def.Affecteds { 63 for _, platform := range affected.Platforms { 64 if d, ok := platformToDist[platform]; ok { 65 v := proto 66 v.Dist = d 67 vs = append(vs, &v) 68 } 69 } 70 } 71 if len(vs) == 0 { 72 return nil, fmt.Errorf("could not determine dist") 73 } 74 return vs, nil 75 } 76 vulns, err := ovalutil.RPMDefsToVulns(ctx, &root, protoVulns) 77 if err != nil { 78 return nil, err 79 } 80 return vulns, err 81 }