From e2a5e778204f2dd10459b25c627c81d4fa656c4e Mon Sep 17 00:00:00 2001 From: MaineK00n Date: Fri, 14 Jul 2023 03:28:26 +0900 Subject: [PATCH] fix(fetcher/redhat): fetch oval v1 --- commands/fetch-redhat.go | 2 +- fetcher/redhat/redhat.go | 70 +++++++++++++++++++++++++++++++++++----- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/commands/fetch-redhat.go b/commands/fetch-redhat.go index 0a32d096..79fd4183 100644 --- a/commands/fetch-redhat.go +++ b/commands/fetch-redhat.go @@ -85,7 +85,7 @@ func fetchRedHat(_ *cobra.Command, args []string) (err error) { } roots := make([]redhat.Root, 0, len(m)) - for _, k := range []string{fmt.Sprintf("rhel-%s.oval.xml.bz2", v), fmt.Sprintf("com.redhat.rhsa-RHEL%s.xml.bz2", v)} { + for _, k := range []string{fmt.Sprintf("rhel-%s.oval.xml.bz2", v), fmt.Sprintf("com.redhat.rhsa-RHEL%s.xml", v)} { roots = append(roots, m[k]) } diff --git a/fetcher/redhat/redhat.go b/fetcher/redhat/redhat.go index a8321733..51822179 100644 --- a/fetcher/redhat/redhat.go +++ b/fetcher/redhat/redhat.go @@ -1,10 +1,16 @@ package redhat import ( + "archive/tar" + "compress/gzip" "fmt" + "io" + "net/http" "strconv" + "strings" "github.com/inconshreveable/log15" + "golang.org/x/exp/slices" "golang.org/x/xerrors" "github.com/vulsio/goval-dictionary/fetcher/util" @@ -13,6 +19,7 @@ import ( // FetchFiles fetch OVAL from RedHat func FetchFiles(versions []string) (map[string][]util.FetchResult, error) { results := map[string][]util.FetchResult{} + vs := make([]string, 0, len(versions)) for _, v := range versions { n, err := strconv.Atoi(v) if err != nil { @@ -25,25 +32,72 @@ func FetchFiles(versions []string) (map[string][]util.FetchResult, error) { continue } - reqs := []util.FetchRequest{{ - Target: v, - URL: fmt.Sprintf("https://www.redhat.com/security/data/oval/com.redhat.rhsa-RHEL%s.xml.bz2", v), - MIMEType: util.MIMETypeBzip2, - }} - if n != 5 { + vs = append(vs, v) + } + if len(vs) == 0 { + return nil, xerrors.New("There are no versions to fetch") + } + + log15.Info("Fetching... ", "URL", "https://access.redhat.com/security/data/archive/oval_v1_20230706.tar.gz") + resp, err := http.Get("https://access.redhat.com/security/data/archive/oval_v1_20230706.tar.gz") + if err != nil { + return nil, xerrors.Errorf("Failed to get oval v1. err: %w", err) + } + if resp.StatusCode != http.StatusOK { + return nil, xerrors.Errorf("Failed to get oval v1. err: bad status %d", resp.StatusCode) + } + defer resp.Body.Close() + + gr, err := gzip.NewReader(resp.Body) + if err != nil { + return nil, xerrors.Errorf("Failed to create gzip reader. err: %w", err) + } + defer gr.Close() + + tr := tar.NewReader(gr) + for { + hdr, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return nil, xerrors.Errorf("Failed to next tar reader. err: %w", err) + } + + v := strings.TrimSuffix(strings.TrimPrefix(hdr.Name, "com.redhat.rhsa-RHEL"), ".xml") + if slices.Contains(vs, v) { + bs, err := io.ReadAll(tr) + if err != nil { + return nil, xerrors.Errorf("Failed to read all com.redhat.rhsa-RHEL%s.xml. err: %w", v, err) + } + results[v] = append(results[v], util.FetchResult{ + Target: v, + URL: fmt.Sprintf("https://access.redhat.com/security/data/archive/oval_v1_20230706.tar.gz/com.redhat.rhsa-RHEL%s.xml", v), + Body: bs, + }) + } + } + + reqs := make([]util.FetchRequest, 0, len(vs)) + for _, v := range vs { + if v != "5" { reqs = append(reqs, util.FetchRequest{ Target: v, URL: fmt.Sprintf("https://access.redhat.com/security/data/oval/v2/RHEL%s/rhel-%s.oval.xml.bz2", v, v), MIMEType: util.MIMETypeBzip2, }) } - + } + if len(reqs) > 0 { rs, err := util.FetchFeedFiles(reqs) if err != nil { return nil, xerrors.Errorf("Failed to fetch. err: %w", err) } - results[v] = append(results[v], rs...) + for _, r := range rs { + results[r.Target] = append(results[r.Target], r) + } } + if len(results) == 0 { return nil, xerrors.New("There are no versions to fetch") }