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 }