github.com/khulnasoft-lab/tunnel-db@v0.0.0-20231117205118-74e1113bd007/pkg/vulnsrc/photon/photon.go (about) 1 package photon 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "log" 8 "path/filepath" 9 10 bolt "go.etcd.io/bbolt" 11 "golang.org/x/xerrors" 12 13 "github.com/khulnasoft-lab/tunnel-db/pkg/db" 14 "github.com/khulnasoft-lab/tunnel-db/pkg/types" 15 "github.com/khulnasoft-lab/tunnel-db/pkg/utils" 16 "github.com/khulnasoft-lab/tunnel-db/pkg/vulnsrc/vulnerability" 17 ) 18 19 const ( 20 photonDir = "photon" 21 platformFormat = "Photon OS %s" 22 ) 23 24 var source = types.DataSource{ 25 ID: vulnerability.Photon, 26 Name: "Photon OS CVE metadata", 27 URL: "https://packages.vmware.com/photon/photon_cve_metadata/", 28 } 29 30 type VulnSrc struct { 31 dbc db.Operation 32 } 33 34 func NewVulnSrc() VulnSrc { 35 return VulnSrc{ 36 dbc: db.Config{}, 37 } 38 } 39 40 func (vs VulnSrc) Name() types.SourceID { 41 return source.ID 42 } 43 44 func (vs VulnSrc) Update(dir string) error { 45 rootDir := filepath.Join(dir, "vuln-list", photonDir) 46 47 var cves []PhotonCVE 48 err := utils.FileWalk(rootDir, func(r io.Reader, path string) error { 49 var cve PhotonCVE 50 if err := json.NewDecoder(r).Decode(&cve); err != nil { 51 return xerrors.Errorf("failed to decode Photon JSON: %w", err) 52 } 53 cves = append(cves, cve) 54 55 return nil 56 }) 57 if err != nil { 58 return xerrors.Errorf("error in Photon walk: %w", err) 59 } 60 61 if err = vs.save(cves); err != nil { 62 return xerrors.Errorf("unable to save Photon advisories: %w", err) 63 } 64 65 return nil 66 } 67 68 func (vs VulnSrc) save(cves []PhotonCVE) error { 69 log.Println("Saving Photon DB") 70 err := vs.dbc.BatchUpdate(func(tx *bolt.Tx) error { 71 return vs.commit(tx, cves) 72 }) 73 if err != nil { 74 return xerrors.Errorf("error in batch update: %w", err) 75 } 76 77 return nil 78 } 79 80 func (vs VulnSrc) commit(tx *bolt.Tx, cves []PhotonCVE) error { 81 for _, cve := range cves { 82 platformName := fmt.Sprintf(platformFormat, cve.OSVersion) 83 if err := vs.dbc.PutDataSource(tx, platformName, source); err != nil { 84 return xerrors.Errorf("failed to put data source: %w", err) 85 } 86 87 advisory := types.Advisory{ 88 FixedVersion: cve.ResVer, 89 } 90 if err := vs.dbc.PutAdvisoryDetail(tx, cve.CveID, cve.Pkg, []string{platformName}, advisory); err != nil { 91 return xerrors.Errorf("failed to save Photon advisory: %w", err) 92 } 93 94 vuln := types.VulnerabilityDetail{ 95 // Photon uses CVSS Version 3.X 96 CvssScoreV3: cve.CveScore, 97 } 98 if err := vs.dbc.PutVulnerabilityDetail(tx, cve.CveID, source.ID, vuln); err != nil { 99 return xerrors.Errorf("failed to save Photon vulnerability detail: %w", err) 100 } 101 102 // for optimization 103 if err := vs.dbc.PutVulnerabilityID(tx, cve.CveID); err != nil { 104 return xerrors.Errorf("failed to save the vulnerability ID: %w", err) 105 } 106 } 107 return nil 108 } 109 110 func (vs VulnSrc) Get(release string, pkgName string) ([]types.Advisory, error) { 111 bucket := fmt.Sprintf(platformFormat, release) 112 advisories, err := vs.dbc.GetAdvisories(bucket, pkgName) 113 if err != nil { 114 return nil, xerrors.Errorf("failed to get Photon advisories: %w", err) 115 } 116 return advisories, nil 117 }