github.com/khulnasoft-lab/tunnel-db@v0.0.0-20231117205118-74e1113bd007/pkg/vulnsrc/arch-linux/archlinux.go (about)

     1  package archlinux
     2  
     3  import (
     4  	"encoding/json"
     5  	"io"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	bolt "go.etcd.io/bbolt"
    10  	"golang.org/x/xerrors"
    11  
    12  	"github.com/khulnasoft-lab/tunnel-db/pkg/db"
    13  	"github.com/khulnasoft-lab/tunnel-db/pkg/types"
    14  	"github.com/khulnasoft-lab/tunnel-db/pkg/utils"
    15  	"github.com/khulnasoft-lab/tunnel-db/pkg/vulnsrc/vulnerability"
    16  )
    17  
    18  const (
    19  	archLinuxDir = "arch-linux"
    20  	platformName = "archlinux"
    21  )
    22  
    23  var (
    24  	source = types.DataSource{
    25  		ID:   vulnerability.ArchLinux,
    26  		Name: "Arch Linux Vulnerable issues",
    27  		URL:  "https://security.archlinux.org/",
    28  	}
    29  )
    30  
    31  type VulnSrc struct {
    32  	dbc db.Operation
    33  }
    34  
    35  func NewVulnSrc() VulnSrc {
    36  	return VulnSrc{
    37  		dbc: db.Config{},
    38  	}
    39  }
    40  
    41  func (vs VulnSrc) Name() types.SourceID {
    42  	return source.ID
    43  }
    44  
    45  func (vs VulnSrc) Update(dir string) error {
    46  	rootDir := filepath.Join(dir, "vuln-list", archLinuxDir)
    47  
    48  	var avgs []ArchVulnGroup
    49  
    50  	err := utils.FileWalk(rootDir, func(r io.Reader, path string) error {
    51  		var avg ArchVulnGroup
    52  		if err := json.NewDecoder(r).Decode(&avg); err != nil {
    53  			return xerrors.Errorf("failed to decode arch linux json (%s): %w", path, err)
    54  		}
    55  		avgs = append(avgs, avg)
    56  		return nil
    57  	})
    58  	if err != nil {
    59  		return xerrors.Errorf("error in arch linux walk: %w", err)
    60  	}
    61  
    62  	if err = vs.save(avgs); err != nil {
    63  		return xerrors.Errorf("error in arch linux save: %w", err)
    64  	}
    65  
    66  	return nil
    67  }
    68  
    69  func (vs VulnSrc) save(avgs []ArchVulnGroup) error {
    70  	err := vs.dbc.BatchUpdate(func(tx *bolt.Tx) error {
    71  		if err := vs.dbc.PutDataSource(tx, platformName, source); err != nil {
    72  			return xerrors.Errorf("failed to put data source: %w", err)
    73  		}
    74  		if err := vs.commit(tx, avgs); err != nil {
    75  			return xerrors.Errorf("commit error: %w", err)
    76  		}
    77  		return nil
    78  	})
    79  	if err != nil {
    80  		return xerrors.Errorf("error in batch update: %w", err)
    81  	}
    82  	return nil
    83  }
    84  
    85  func (vs VulnSrc) commit(tx *bolt.Tx, avgs []ArchVulnGroup) error {
    86  	for _, avg := range avgs {
    87  		for _, cveId := range avg.Issues {
    88  			advisory := types.Advisory{
    89  				FixedVersion:    avg.Fixed,
    90  				AffectedVersion: avg.Affected,
    91  			}
    92  
    93  			for _, pkg := range avg.Packages {
    94  				if err := vs.dbc.PutAdvisoryDetail(tx, cveId, pkg, []string{platformName}, advisory); err != nil {
    95  					return xerrors.Errorf("failed to save arch linux advisory: %w", err)
    96  				}
    97  
    98  				vuln := types.VulnerabilityDetail{
    99  					Severity: convertSeverity(avg.Severity),
   100  				}
   101  				if err := vs.dbc.PutVulnerabilityDetail(tx, cveId, source.ID, vuln); err != nil {
   102  					return xerrors.Errorf("failed to save arch linux vulnerability: %w", err)
   103  				}
   104  
   105  				// for optimization
   106  				if err := vs.dbc.PutVulnerabilityID(tx, cveId); err != nil {
   107  					return xerrors.Errorf("failed to save the vulnerability ID: %w", err)
   108  				}
   109  			}
   110  
   111  		}
   112  	}
   113  	return nil
   114  }
   115  
   116  func (vs VulnSrc) Get(pkgName string) ([]types.Advisory, error) {
   117  	advisories, err := vs.dbc.GetAdvisories(platformName, pkgName)
   118  	if err != nil {
   119  		return nil, xerrors.Errorf("failed to get Arch Linux advisories: %w", err)
   120  	}
   121  	return advisories, nil
   122  }
   123  
   124  func convertSeverity(sev string) types.Severity {
   125  	severity, _ := types.NewSeverity(strings.ToUpper(sev))
   126  	return severity
   127  }