github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/analyzer/os/release/release.go (about)

     1  package release
     2  
     3  import (
     4  	"bufio"
     5  	"context"
     6  	"os"
     7  	"strings"
     8  
     9  	"golang.org/x/exp/slices"
    10  
    11  	"github.com/devseccon/trivy/pkg/fanal/analyzer"
    12  	"github.com/devseccon/trivy/pkg/fanal/types"
    13  )
    14  
    15  func init() {
    16  	analyzer.RegisterAnalyzer(&osReleaseAnalyzer{})
    17  }
    18  
    19  const version = 1
    20  
    21  var requiredFiles = []string{
    22  	"etc/os-release",
    23  	"usr/lib/os-release",
    24  }
    25  
    26  type osReleaseAnalyzer struct{}
    27  
    28  func (a osReleaseAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
    29  	var id, versionID string
    30  	scanner := bufio.NewScanner(input.Content)
    31  	for scanner.Scan() {
    32  		line := scanner.Text()
    33  
    34  		ss := strings.SplitN(line, "=", 2)
    35  		if len(ss) != 2 {
    36  			continue
    37  		}
    38  		key, value := strings.TrimSpace(ss[0]), strings.TrimSpace(ss[1])
    39  
    40  		switch key {
    41  		case "ID":
    42  			id = strings.Trim(value, `"'`)
    43  		case "VERSION_ID":
    44  			versionID = strings.Trim(value, `"'`)
    45  		default:
    46  			continue
    47  		}
    48  
    49  		var family types.OSType
    50  		switch id {
    51  		case "alpine":
    52  			family = types.Alpine
    53  		case "opensuse-tumbleweed":
    54  			family = types.OpenSUSETumbleweed
    55  		case "opensuse-leap", "opensuse": // opensuse for leap:42, opensuse-leap for leap:15
    56  			family = types.OpenSUSELeap
    57  		case "sles":
    58  			family = types.SLES
    59  		case "photon":
    60  			family = types.Photon
    61  		case "wolfi":
    62  			family = types.Wolfi
    63  		case "chainguard":
    64  			family = types.Chainguard
    65  		}
    66  
    67  		if family != "" && versionID != "" {
    68  			return &analyzer.AnalysisResult{
    69  				OS: types.OS{
    70  					Family: family,
    71  					Name:   versionID,
    72  				},
    73  			}, nil
    74  		}
    75  	}
    76  
    77  	return nil, nil
    78  }
    79  
    80  func (a osReleaseAnalyzer) Required(filePath string, _ os.FileInfo) bool {
    81  	return slices.Contains(requiredFiles, filePath)
    82  }
    83  
    84  func (a osReleaseAnalyzer) Type() analyzer.Type {
    85  	return analyzer.TypeOSRelease
    86  }
    87  
    88  func (a osReleaseAnalyzer) Version() int {
    89  	return version
    90  }