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  }