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

     1  package ubuntu
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"os"
     7  
     8  	"golang.org/x/exp/slices"
     9  	"golang.org/x/xerrors"
    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(&ubuntuESMAnalyzer{})
    17  }
    18  
    19  const (
    20  	ESMAnalyzerVersion = 1
    21  	esmConfFilePath    = "var/lib/ubuntu-advantage/status.json"
    22  	esmServiceName     = "esm-infra"
    23  	esmStatusEnabled   = "enabled"
    24  )
    25  
    26  var ESMRequiredFiles = []string{
    27  	esmConfFilePath,
    28  }
    29  
    30  type ubuntuESMAnalyzer struct{}
    31  
    32  func (a ubuntuESMAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
    33  	st := status{}
    34  	err := json.NewDecoder(input.Content).Decode(&st)
    35  	if err != nil {
    36  		return nil, xerrors.Errorf("ubuntu ESM analyze error: %w", err)
    37  	}
    38  	if esmEnabled(st) {
    39  		return &analyzer.AnalysisResult{
    40  			OS: types.OS{
    41  				Family:   types.Ubuntu,
    42  				Extended: true,
    43  			},
    44  		}, nil
    45  	}
    46  	// if ESM is disabled - return nil to reduce the amount of logic in the OS.Merge function
    47  	return nil, nil
    48  }
    49  
    50  func (a ubuntuESMAnalyzer) Required(filePath string, _ os.FileInfo) bool {
    51  	return slices.Contains(ESMRequiredFiles, filePath)
    52  }
    53  
    54  func (a ubuntuESMAnalyzer) Type() analyzer.Type {
    55  	return analyzer.TypeUbuntuESM
    56  }
    57  
    58  func (a ubuntuESMAnalyzer) Version() int {
    59  	return ESMAnalyzerVersion
    60  }
    61  
    62  // structs to parse ESM status
    63  type status struct {
    64  	Services []service `json:"services"`
    65  }
    66  
    67  type service struct {
    68  	Name   string `json:"name"`
    69  	Status string `json:"status"`
    70  }
    71  
    72  func esmEnabled(st status) bool {
    73  	for _, s := range st.Services { // Find ESM Service
    74  		if s.Name == esmServiceName && s.Status == esmStatusEnabled {
    75  			return true
    76  		}
    77  	}
    78  	return false
    79  }