github.com/quay/claircore@v1.5.28/debian/parser.go (about)

     1  package debian
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  
     9  	"github.com/quay/zlog"
    10  
    11  	"github.com/quay/claircore"
    12  )
    13  
    14  const linkPrefix = `https://security-tracker.debian.org/tracker/`
    15  
    16  // JSONData maps source package -> related vulnerabilities
    17  type JSONData map[string]Vulnerabilities
    18  
    19  // Vulnerabilities maps vulnerability ID (CVE) -> related data
    20  type Vulnerabilities map[string]*Vulnerability
    21  
    22  // Vulnerability is data related to a vulnerability
    23  type Vulnerability struct {
    24  	Description string                 `json:"description"`
    25  	Releases    map[string]ReleaseData `json:"releases"`
    26  }
    27  
    28  // ReleaseData is data related to releases related to a vulnerability
    29  type ReleaseData struct {
    30  	Status       string `json:"status"`
    31  	FixedVersion string `json:"fixed_version"`
    32  	Urgency      string `json:"urgency"`
    33  }
    34  
    35  // Parse implements [driver.Parser].
    36  func (u *updater) Parse(ctx context.Context, r io.ReadCloser) ([]*claircore.Vulnerability, error) {
    37  	ctx = zlog.ContextWithValues(ctx, "component", "debian/Updater.Parse")
    38  	zlog.Info(ctx).Msg("starting parse")
    39  	defer r.Close()
    40  
    41  	var vulnsJSON JSONData
    42  	err := json.NewDecoder(r).Decode(&vulnsJSON)
    43  	if err != nil {
    44  		return nil, fmt.Errorf("unable to parse JSON vulnerability feed: %w", err)
    45  	}
    46  
    47  	var vs []*claircore.Vulnerability
    48  	for src, vulns := range vulnsJSON {
    49  		for id, vulnData := range vulns {
    50  			for release, releaseData := range vulnData.Releases {
    51  				d, err := getDist(release)
    52  				if err != nil {
    53  					// Don't log here to ensure logs aren't blown up with
    54  					// entries referring to sid or an unreleased Debian version.
    55  					continue
    56  				}
    57  
    58  				v := claircore.Vulnerability{
    59  					Updater:            u.Name(),
    60  					Name:               id,
    61  					Description:        vulnData.Description,
    62  					Links:              linkPrefix + id,
    63  					Severity:           releaseData.Urgency,
    64  					NormalizedSeverity: normalizeSeverity(releaseData.Urgency),
    65  					Dist:               d,
    66  					FixedInVersion:     releaseData.FixedVersion,
    67  					Package: &claircore.Package{
    68  						Name: src,
    69  						Kind: claircore.SOURCE,
    70  					},
    71  				}
    72  				vs = append(vs, &v)
    73  			}
    74  		}
    75  	}
    76  
    77  	return vs, nil
    78  }