Skip to content

Commit

Permalink
chore(fedora): add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MaineK00n committed Jan 21, 2022
1 parent 61b00e9 commit 8146632
Show file tree
Hide file tree
Showing 28 changed files with 3,393 additions and 51 deletions.
76 changes: 25 additions & 51 deletions fedora/fedora.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"regexp"
"strconv"
"strings"
"time"

"github.com/aquasecurity/vuln-list-update/utils"
"github.com/cheggaaa/pb/v3"
Expand All @@ -34,10 +33,12 @@ const (
)

var (
URIForamt = map[string]string{
"fedora": "https://dl.fedoraproject.org/pub/fedora/linux/updates/%s/%s/%s/",
"epel7": "https://dl.fedoraproject.org/pub/epel/%s/%s/",
"epel": "https://dl.fedoraproject.org/pub/epel/%s/%s/%s/",
urlFormat = map[string]string{
"fedora": "https://dl.fedoraproject.org/pub/fedora/linux/updates/%s/%s/%s/",
"epel7": "https://dl.fedoraproject.org/pub/epel/%s/%s/",
"epel": "https://dl.fedoraproject.org/pub/epel/%s/%s/%s/",
"bugzilla": "https://bugzilla.redhat.com/show_bug.cgi?ctype=xml&id=%s",
"moduleinfo": "https://kojipkgs.fedoraproject.org/packages/%s/%s/%d.%s/files/module/modulemd.%s.txt",
}

defaultReleases = map[string][]string{
Expand All @@ -53,8 +54,6 @@ var (
}

cveIDPattern = regexp.MustCompile(`(CVE-\d{4}-\d{4,})`)
bugzillaURL = "https://bugzilla.redhat.com/show_bug.cgi?ctype=xml&id=%s"
moduleURL = "https://kojipkgs.fedoraproject.org//packages/%s/%s/%d.%s/files/module/modulemd.%s.txt"
)

// RepoMd has repomd data
Expand Down Expand Up @@ -139,36 +138,17 @@ type options struct {

type option func(*options)

func WithURLs(urls map[string]string) option {
return func(opts *options) { opts.urls = urls }
}

func WithDir(dir string) option {
return func(opts *options) { opts.dir = dir }
}

func WithConcurrency(concurrency int) option {
return func(opts *options) { opts.concurrency = concurrency }
}

func WithWait(wait int) option {
return func(opts *options) { opts.wait = wait }
}

func WithRetry(retry int) option {
return func(opts *options) { opts.retry = retry }
}

func WithReleases(releases map[string][]string) option {
return func(opts *options) { opts.releases = releases }
}

func WithRepos(repos []string) option {
return func(opts *options) { opts.repos = repos }
}

func WithArches(arches []string) option {
return func(opts *options) { opts.arches = arches }
func With(urls map[string]string, dir string, concurrency, wait, retry int, releases map[string][]string, repos, arches []string) option {
return func(opts *options) {
opts.urls = urls
opts.dir = dir
opts.concurrency = concurrency
opts.wait = wait
opts.retry = retry
opts.releases = releases
opts.repos = repos
opts.arches = arches
}
}

type Config struct {
Expand All @@ -177,7 +157,7 @@ type Config struct {

func NewConfig(opts ...option) Config {
o := &options{
urls: URIForamt,
urls: urlFormat,
dir: filepath.Join(utils.VulnListDir(), fedoraDir),
concurrency: defaultConcurrency,
wait: defaultWait,
Expand Down Expand Up @@ -251,11 +231,8 @@ func (c Config) update(mode, release, repo, arch string) error {

fsalistByYear := map[string][]FSA{}
for _, fsa := range vulns.FSAList {
t, err := time.Parse(dateFormat, fsa.Issued.Date)
if err != nil {
return xerrors.Errorf("failed to parse issued date: %w", err)
}
y := fmt.Sprintf("%d", t.Year())
ss := strings.Split(fsa.ID, "-")
y := ss[len(ss)-2]
fsalistByYear[y] = append(fsalistByYear[y], fsa)
}

Expand Down Expand Up @@ -485,7 +462,7 @@ type Bugzilla struct {
func (c Config) fetchCVEIDsfromBugzilla(bugzillaID string) ([]string, error) {
log.Printf("Fetching CVE-IDs using Bugzilla API. Root Bugzilla ID: %s\n", bugzillaID)

url := fmt.Sprintf(bugzillaURL, bugzillaID)
url := fmt.Sprintf(c.urls["bugzilla"], bugzillaID)
res, err := utils.FetchURL(url, "", c.retry)
if err != nil {
return nil, xerrors.Errorf("failed to fetch bugzilla xml: %w", err)
Expand All @@ -502,7 +479,7 @@ func (c Config) fetchCVEIDsfromBugzilla(bugzillaID string) ([]string, error) {

urls := []string{}
for _, blocked := range root.Bug.Blocked {
urls = append(urls, fmt.Sprintf(bugzillaURL, blocked))
urls = append(urls, fmt.Sprintf(c.urls["bugzilla"], blocked))
}
xmlBytes, err := utils.FetchConcurrently(urls, c.concurrency, c.wait, c.retry)
if err != nil {
Expand Down Expand Up @@ -530,7 +507,7 @@ func (c Config) fetchModules(uinfo *UpdateInfo, arch string) (map[string]ModuleI
if err != nil {
return nil, xerrors.Errorf("failed to parse moduleinfo: %w", err)
}
moduleURLs = append(moduleURLs, fmt.Sprintf(moduleURL, module.Name, module.Stream, module.Version, module.Context, arch))
moduleURLs = append(moduleURLs, fmt.Sprintf(c.urls["moduleinfo"], module.Name, module.Stream, module.Version, module.Context, arch))
}
if len(moduleURLs) == 0 {
return map[string]ModuleInfo{}, nil
Expand Down Expand Up @@ -559,9 +536,7 @@ func (c Config) fetchModules(uinfo *UpdateInfo, arch string) (map[string]ModuleI
if err := yaml.NewDecoder(strings.NewReader(strings.Join(contents, "\n"))).Decode(&module); err != nil {
return nil, xerrors.Errorf("failed to decode module info: %w", err)
}
if module.Version == 2 {
modules[module.convertToUpdateInfoTitle()] = module
}
modules[module.convertToUpdateInfoTitle()] = module
}
default:
{
Expand Down Expand Up @@ -593,8 +568,7 @@ func parseModuleFromAdvisoryTitle(title string) (Module, error) {
}

type ModuleInfo struct {
Version int `yaml:"version"`
Data struct {
Data struct {
Name string `yaml:"name"`
Stream string `yaml:"stream"`
Version int64 `yaml:"version"`
Expand Down
123 changes: 123 additions & 0 deletions fedora/fedora_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package fedora_test

import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"reflect"
"testing"

"github.com/aquasecurity/vuln-list-update/fedora"
"github.com/kylelemons/godebug/pretty"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Test_Update(t *testing.T) {
type args struct {
mode string
uinfoURLPath string
release []string
repos []string
arches []string
}
tests := []struct {
name string
rootDir string
args args
expectedError error
}{
{
name: "fedora 35",
rootDir: "testdata/fixtures/fedora35",
args: args{
mode: "fedora",
uinfoURLPath: "/pub/fedora/linux/updates/%s/%s/%s/",
release: []string{"35"},
repos: []string{"Everything", "Modular"},
arches: []string{"x86_64"},
},
expectedError: nil,
},
{
name: "epel 7",
rootDir: "testdata/fixtures/epel7",
args: args{
mode: "epel",
uinfoURLPath: "/pub/epel/%s/%s/",
release: []string{"7"},
repos: []string{},
arches: []string{"x86_64"},
},
expectedError: nil,
},
{
name: "epel 8",
rootDir: "testdata/fixtures/epel8",
args: args{
mode: "epel",
uinfoURLPath: "/pub/epel/%s/%s/%s/",
release: []string{"8"},
repos: []string{"Everything"},
arches: []string{"x86_64"},
},
expectedError: nil,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mux := http.NewServeMux()
mux.Handle("/pub/", http.FileServer(http.Dir(tt.rootDir)))
mux.Handle("/packages/", http.FileServer(http.Dir(tt.rootDir)))
mux.HandleFunc("/show_bug.cgi", func(rw http.ResponseWriter, r *http.Request) {
bugzillaID := r.URL.Query().Get("id")
r.URL.Path = fmt.Sprintf("%s.xml", bugzillaID)
r.URL.RawQuery = ""
http.FileServer(http.Dir(filepath.Join(tt.rootDir, "bugzilla"))).ServeHTTP(rw, r)
})
tsServerURL := httptest.NewServer(mux)
defer tsServerURL.Close()

dir := t.TempDir()
fd := fedora.NewConfig(fedora.With(map[string]string{tt.args.mode: tsServerURL.URL + tt.args.uinfoURLPath, "bugzilla": tsServerURL.URL + "/show_bug.cgi?ctype=xml&id=%s", "moduleinfo": tsServerURL.URL + "/packages/%s/%s/%d.%s/files/module/modulemd.%s.txt"}, dir, 1, 0, 0, map[string][]string{tt.args.mode: tt.args.release}, tt.args.repos, tt.args.arches))
if err := fd.Update(); tt.expectedError != nil {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.expectedError.Error())
return
}

err := filepath.Walk(dir, func(path string, info os.FileInfo, errfp error) error {
if errfp != nil {
return errfp
}
if info.IsDir() {
return nil
}

dir, file := filepath.Split(path)
b, err := os.ReadFile(filepath.Join("testdata", "golden", filepath.Base(dir), file))
assert.NoError(t, err, "failed to open the golden file")
var want fedora.FSA
err = json.Unmarshal(b, &want)
assert.NoError(t, err, "failed to unmarshal json")

b, err = os.ReadFile(path)
assert.NoError(t, err, "failed to open the result file")
var got fedora.FSA
err = json.Unmarshal(b, &got)
assert.NoError(t, err, "failed to unmarshal json")

if !reflect.DeepEqual(got, want) {
t.Errorf("[%s]\n diff: %s", tt.name, pretty.Compare(got, want))
}

return nil
})
assert.Nil(t, err, "filepath walk error")
})
}
}
120 changes: 120 additions & 0 deletions fedora/testdata/fixtures/epel7/bugzilla/1684012.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE bugzilla SYSTEM "https://bugzilla.redhat.com/page.cgi?id=bugzilla.dtd">
<bugzilla version="5.0.4.rh65" urlbase="https://bugzilla.redhat.com/" maintainer="[email protected]">

<bug>
<bug_id>1684012</bug_id>
<alias>CVE-2019-9027</alias>
<creation_ts>2019-02-28 09:34:35 +0000</creation_ts>
<short_desc>CVE-2019-9027 matio: heap-based buffer overflow in function ReadNextCell() in mat5.c</short_desc>
<delta_ts>2019-11-28 13:39:35 +0000</delta_ts>
<reporter_accessible>1</reporter_accessible>
<cclist_accessible>1</cclist_accessible>
<classification_id>3</classification_id>
<classification>Other</classification>
<product>Security Response</product>
<component>vulnerability</component>
<version>unspecified</version>
<rep_platform>All</rep_platform>
<op_sys>Linux</op_sys>
<bug_status>CLOSED</bug_status>
<resolution>UPSTREAM</resolution>


<bug_file_loc/>
<status_whiteboard/>
<keywords>Security</keywords>
<priority>low</priority>
<bug_severity>low</bug_severity>
<target_milestone>---</target_milestone>
<dependson>1684013</dependson>


<dependson>1684014</dependson>

<everconfirmed>1</everconfirmed>
<reporter name="Dhananjay Arunesh">darunesh</reporter>
<assigned_to name="Red Hat Product Security">security-response-team</assigned_to>
<cc>c.david86</cc>


<cc>kwizart</cc>


<cc>lupinix.fedora</cc>



<cf_fixed_in/>
<cf_doc_type>If docs needed, set a value</cf_doc_type>
<cf_release_notes/>
<cf_story_points>---</cf_story_points>

<cf_environment/>
<cf_last_closed>2019-06-10 10:49:24</cf_last_closed>
<cf_type>---</cf_type>
<cf_regression_status>---</cf_regression_status>
<cf_mount_type>---</cf_mount_type>
<cf_documentation_action>---</cf_documentation_action>
<cf_crm/>
<cf_verified_branch/>
<cf_category>---</cf_category>
<cf_ovirt_team>---</cf_ovirt_team>

<cf_cloudforms_team>---</cf_cloudforms_team>
<cf_target_upstream_version/>





<target_release>---</target_release>

<votes>0</votes>







<comment_sort_order>oldest_to_newest</comment_sort_order>
<long_desc isprivate="0">
<commentid>12500308</commentid>
<comment_count>0</comment_count>
<who name="Dhananjay Arunesh">darunesh</who>
<bug_when>2019-02-28 09:34:35 +0000</bug_when>
<thetext>An issue was discovered in libmatio.a in matio (aka MAT File I/O Library) 1.5.13. There is a heap-based buffer overflow problem in the function ReadNextCell() in mat5.c.

References:
https://github.com/tbeu/matio/issues/103
https://github.com/TeamSeri0us/pocs/tree/master/matio</thetext>
</long_desc><long_desc isprivate="0">
<commentid>12500313</commentid>
<comment_count>1</comment_count>
<who name="Dhananjay Arunesh">darunesh</who>
<bug_when>2019-02-28 09:34:56 +0000</bug_when>
<thetext>Created matio tracking bugs for this issue:

Affects: fedora-all [bug 1684013]</thetext>
</long_desc><long_desc isprivate="0">
<commentid>12500317</commentid>
<comment_count>2</comment_count>
<who name="Dhananjay Arunesh">darunesh</who>
<bug_when>2019-02-28 09:35:18 +0000</bug_when>
<thetext>Created matio tracking bugs for this issue:

Affects: epel-all [bug 1684014]</thetext>
</long_desc><long_desc isprivate="0">
<commentid>12825865</commentid>
<comment_count>3</comment_count>
<who name="Product Security DevOps Team">prodsec-dev</who>
<bug_when>2019-06-10 10:49:24 +0000</bug_when>
<thetext>This CVE Bugzilla entry is for community support informational purposes only as it does not affect a package in a commercially supported Red Hat product. Refer to the dependent bugs for status of those individual community products.</thetext>
</long_desc>



</bug>

</bugzilla>
Loading

0 comments on commit 8146632

Please sign in to comment.