1package amazon
2
3import (
4	"strings"
5
6	version "github.com/knqyf263/go-deb-version"
7	"go.uber.org/zap"
8	"golang.org/x/xerrors"
9
10	ftypes "github.com/aquasecurity/fanal/types"
11	dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
12	"github.com/aquasecurity/trivy-db/pkg/vulnsrc/amazon"
13	"github.com/aquasecurity/trivy/pkg/log"
14	"github.com/aquasecurity/trivy/pkg/scanner/utils"
15	"github.com/aquasecurity/trivy/pkg/types"
16)
17
18type Scanner struct {
19	l  *zap.SugaredLogger
20	ac dbTypes.VulnSrc
21}
22
23func NewScanner() *Scanner {
24	return &Scanner{
25		l:  log.Logger,
26		ac: amazon.NewVulnSrc(),
27	}
28}
29
30func (s *Scanner) Detect(osVer string, pkgs []ftypes.Package) ([]types.DetectedVulnerability, error) {
31	log.Logger.Info("Detecting Amazon Linux vulnerabilities...")
32
33	osVer = strings.Fields(osVer)[0]
34	if osVer != "2" {
35		osVer = "1"
36	}
37	log.Logger.Debugf("amazon: os version: %s", osVer)
38	log.Logger.Debugf("amazon: the number of packages: %d", len(pkgs))
39
40	var vulns []types.DetectedVulnerability
41	for _, pkg := range pkgs {
42		advisories, err := s.ac.Get(osVer, pkg.Name)
43		if err != nil {
44			return nil, xerrors.Errorf("failed to get amazon advisories: %w", err)
45		}
46
47		installed := utils.FormatVersion(pkg)
48		if installed == "" {
49			continue
50		}
51
52		installedVersion, err := version.NewVersion(installed)
53		if err != nil {
54			log.Logger.Debugf("failed to parse Amazon Linux installed package version: %s", err)
55			continue
56		}
57
58		for _, adv := range advisories {
59			fixedVersion, err := version.NewVersion(adv.FixedVersion)
60			if err != nil {
61				log.Logger.Debugf("failed to parse Amazon Linux package version: %s", err)
62				continue
63			}
64
65			if installedVersion.LessThan(fixedVersion) {
66				vuln := types.DetectedVulnerability{
67					VulnerabilityID:  adv.VulnerabilityID,
68					PkgName:          pkg.Name,
69					InstalledVersion: installed,
70					FixedVersion:     adv.FixedVersion,
71					Layer:            pkg.Layer,
72				}
73				vulns = append(vulns, vuln)
74			}
75		}
76	}
77	return vulns, nil
78}
79
80func (s *Scanner) IsSupportedVersion(osFamily, osVer string) bool {
81	return true
82}
83