Fix alpine tests

This commit is contained in:
knqyf263 2019-10-10 18:45:17 +03:00
parent 573a7b3b5a
commit 3e42145b06
30 changed files with 616 additions and 197 deletions

View File

@ -32,26 +32,28 @@ var (
malformedVerReplacer = strings.NewReplacer("_p", "-p", ".-", "-", ".r", "-r", "_alpha", "-alpha", "_rc", "-rc")
)
func Update(gc git.Operations) (err error) {
type Config struct {
GitClient git.Operations
CacheDir string
VulnListDir string
}
func (c Config) Update() (err error) {
log.Println("Fetching Alpine data...")
repoDir = filepath.Join(utils.CacheDir(), "aports")
if _, err = gc.CloneOrPull(repoURL, repoDir); err != nil {
repoDir = filepath.Join(c.CacheDir, "aports")
if _, err = c.GitClient.CloneOrPull(repoURL, repoDir); err != nil {
return xerrors.Errorf("failed to clone alpine repository: %w", err)
}
// Extract secfixes in all APKBUILD
log.Println("Extracting Alpine secfixes...")
branches, err := gc.RemoteBranch(repoDir)
branches, err := c.GitClient.RemoteBranch(repoDir)
if err != nil {
return xerrors.Errorf("failed to show branches: %w", err)
}
defer func() {
// restore branch
if err = gc.Checkout(repoDir, "master"); err != nil {
err = xerrors.Errorf("error in git checkout: %w", err)
}
}()
// restore branch
defer c.GitClient.Checkout(repoDir, "master")
for _, branch := range branches {
branch = strings.TrimSpace(branch)
@ -64,18 +66,18 @@ func Update(gc git.Operations) (err error) {
}
release := strings.TrimSuffix(s[1], "-stable")
if err = gc.Checkout(repoDir, branch); err != nil {
return xerrors.Errorf("failed to git checkout: %w", err)
if err = c.GitClient.Checkout(repoDir, branch); err != nil {
return xerrors.Errorf("git failed to checkout branch: %w", err)
}
advisories, err := walkApkBuild(repoDir, release)
advisories, err := c.walkApkBuild(repoDir, release)
if err != nil {
return xerrors.Errorf("failed to walk APKBUILD: %w", err)
}
log.Printf("Saving secfixes: %s\n", release)
for _, advisory := range advisories {
filePath, err := constructFilePath(advisory.Release, advisory.Repository, advisory.Package, advisory.VulnerabilityID)
filePath, err := c.constructFilePath(advisory.Release, advisory.Repository, advisory.Package, advisory.VulnerabilityID)
if err != nil {
return xerrors.Errorf("failed to construct file path: %w", err)
}
@ -83,7 +85,7 @@ func Update(gc git.Operations) (err error) {
ok, err := utils.Exists(filePath)
if err != nil {
return xerrors.Errorf("error in file existence check: %w", err)
} else if ok && !shouldOverwrite(filePath, advisory.FixedVersion) {
} else if ok && !c.shouldOverwrite(filePath, advisory.FixedVersion) {
continue
}
@ -96,7 +98,7 @@ func Update(gc git.Operations) (err error) {
return nil
}
func shouldOverwrite(filePath string, currentVersion string) bool {
func (c Config) shouldOverwrite(filePath string, currentVersion string) bool {
f, err := os.Open(filePath)
if err != nil {
return false
@ -107,6 +109,10 @@ func shouldOverwrite(filePath string, currentVersion string) bool {
if err = json.NewDecoder(f).Decode(&advisory); err != nil {
return true
}
if advisory.Package == "" || advisory.FixedVersion == "" {
return true
}
// advisory with Subject is more accurate and should not be overwritten
if advisory.Subject != "" {
return false
}
@ -126,9 +132,12 @@ func shouldOverwrite(filePath string, currentVersion string) bool {
return current.LessThan(prev)
}
func walkApkBuild(repoDir, release string) ([]Advisory, error) {
func (c Config) walkApkBuild(repoDir, release string) ([]Advisory, error) {
var advisories []Advisory
err := filepath.Walk(repoDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return xerrors.Errorf("file walk error: %w", err)
}
if info.IsDir() {
return nil
}
@ -144,14 +153,14 @@ func walkApkBuild(repoDir, release string) ([]Advisory, error) {
return xerrors.Errorf("file read error: %w", err)
}
secFixes, err := parseSecFixes(string(content))
secFixes, err := c.parseSecFixes(string(content))
if err != nil {
return err
} else if secFixes == nil {
return nil
}
advisories = buildAdvisories(secFixes, release, pkg, repo)
advisories = append(advisories, c.buildAdvisories(secFixes, release, pkg, repo)...)
return nil
})
@ -161,7 +170,7 @@ func walkApkBuild(repoDir, release string) ([]Advisory, error) {
return advisories, nil
}
func buildAdvisories(secFixes map[string][]string, release string, pkg string, repo string) []Advisory {
func (c Config) buildAdvisories(secFixes map[string][]string, release string, pkg string, repo string) []Advisory {
var advisories []Advisory
for ver, vulnIDs := range secFixes {
for _, vulnID := range vulnIDs {
@ -191,8 +200,8 @@ func buildAdvisories(secFixes map[string][]string, release string, pkg string, r
return advisories
}
func constructFilePath(release, repository, pkg, cveID string) (string, error) {
dir := filepath.Join(utils.VulnListDir(), alpineDir, release, repository, pkg)
func (c Config) constructFilePath(release, repository, pkg, cveID string) (string, error) {
dir := filepath.Join(c.VulnListDir, alpineDir, release, repository, pkg)
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return "", xerrors.Errorf("failed to create directory: %w", err)
}
@ -207,7 +216,7 @@ func splitPath(filePath string) (string, string, string) {
return filepath.Clean(repo), pkg, base
}
func parsePkgVerRel(content string) (pkgVer string, pkgRel string, err error) {
func (c Config) parsePkgVerRel(content string) (pkgVer string, pkgRel string, err error) {
lines := strings.Split(content, "\n")
for i := 0; i < len(lines); i++ {
@ -231,7 +240,7 @@ func parsePkgVerRel(content string) (pkgVer string, pkgRel string, err error) {
return pkgVer, pkgRel, nil
}
func parseSecFixes(content string) (secFixes map[string][]string, err error) {
func (c Config) parseSecFixes(content string) (secFixes map[string][]string, err error) {
lines := strings.Split(content, "\n")
for i := 0; i < len(lines); i++ {
line := strings.TrimSpace(lines[i])

View File

@ -1,43 +1,42 @@
package alpine
package alpine_test
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"reflect"
"strings"
"testing"
"golang.org/x/xerrors"
"github.com/aquasecurity/vuln-list-update/alpine"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
type MockGitConfig struct {
cloneorpull func(string, string) (map[string]struct{}, error)
remotebranch func(string) ([]string, error)
checkout func(string, string) error
mock.Mock
}
func (mgc MockGitConfig) CloneOrPull(a string, b string) (map[string]struct{}, error) {
if mgc.cloneorpull != nil {
return mgc.cloneorpull(a, b)
}
return map[string]struct{}{}, nil
args := mgc.Called(a, b)
return args.Get(0).(map[string]struct{}), args.Error(1)
}
func (mgc MockGitConfig) RemoteBranch(a string) ([]string, error) {
if mgc.remotebranch != nil {
return mgc.remotebranch(a)
}
return []string{}, nil
args := mgc.Called(a)
return args.Get(0).([]string), args.Error(1)
}
func (mgc MockGitConfig) Checkout(a string, b string) error {
if mgc.checkout != nil {
return mgc.checkout(a, b)
}
return nil
args := mgc.Called(a, b)
return args.Error(0)
}
func TestParsePkgVerRel(t *testing.T) {
@ -48,12 +47,12 @@ func TestParsePkgVerRel(t *testing.T) {
secFixes map[string][]string
}{
{
file: "testdata/APKBUILD_plain",
file: "testdata/aports/main/freeradius/APKBUILD",
pkgVer: "3.0.19",
pkgRel: "0",
},
{
file: "testdata/APKBUILD_multicves",
file: "testdata/aports/main/wireshark/APKBUILD",
pkgVer: "2.6.8",
pkgRel: "1",
},
@ -66,7 +65,7 @@ func TestParsePkgVerRel(t *testing.T) {
t.Fatalf("ReadAll() error: %v", err)
}
pkgVer, pkgRel, err := parsePkgVerRel(string(content))
pkgVer, pkgRel, err := alpine.ParsePkgVerRel(&alpine.Config{}, string(content))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -90,7 +89,7 @@ func TestParseSecFixes(t *testing.T) {
secFixes map[string][]string
}{
{
file: "testdata/APKBUILD_plain",
file: "testdata/aports/main/freeradius/APKBUILD",
pkgVer: "3.0.19",
pkgRel: "0",
secFixes: map[string][]string{
@ -98,7 +97,7 @@ func TestParseSecFixes(t *testing.T) {
},
},
{
file: "testdata/APKBUILD_multicves",
file: "testdata/aports/main/wireshark/APKBUILD",
pkgVer: "2.6.8",
pkgRel: "1",
secFixes: map[string][]string{
@ -116,7 +115,7 @@ func TestParseSecFixes(t *testing.T) {
t.Fatalf("ReadAll() error: %v", err)
}
secFixes, err := parseSecFixes(string(content))
secFixes, err := alpine.ParseSecFixes(&alpine.Config{}, string(content))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
@ -129,175 +128,257 @@ func TestParseSecFixes(t *testing.T) {
}
func TestShouldOverwrite(t *testing.T) {
t.Run("happy and sad paths with valid versions", func(t *testing.T) {
issuedAdvisory := Advisory{
IssueID: 100,
VulnerabilityID: "CVE-2100-0001",
Release: "1.0",
Package: "testpackage",
Repository: "main",
//Subject: "test advisory",
Description: "for testing only",
}
testCases := []struct {
name string
currentVersion string
fixedVersion string
expctedOverwrite bool
}{
{
name: "issued advisory should overwrite existing one",
currentVersion: "1.0.0",
fixedVersion: "1.2.0",
expctedOverwrite: true,
testCases := []struct {
name string
currentVersion string
issuedAdvisory interface{}
expctedOverwrite bool
}{
{
name: "issued advisory should overwrite existing one with valid version",
currentVersion: "1.0.0",
issuedAdvisory: alpine.Advisory{
IssueID: 0,
VulnerabilityID: "CVE-2100-0001",
Release: "1.0",
Package: "testpackage",
Repository: "main",
FixedVersion: "1.2.0",
Description: "for testing only",
},
{
name: "issued advisory should NOT overwrite existing one",
currentVersion: "1.0.0",
fixedVersion: "0.9.0",
expctedOverwrite: false,
expctedOverwrite: true,
},
{
name: "issued advisory should NOT overwrite existing one with valid version",
currentVersion: "1.0.0",
issuedAdvisory: alpine.Advisory{
IssueID: 0,
VulnerabilityID: "CVE-2100-0001",
Release: "1.0",
Package: "testpackage",
Repository: "main",
FixedVersion: "0.9.0",
Description: "for testing only",
},
}
expctedOverwrite: false,
},
{
name: "invalid advisory json",
currentVersion: "1.0.0",
issuedAdvisory: []byte(`badjsonhere`),
expctedOverwrite: true,
},
{
name: "empty fixed version",
currentVersion: "1.0.0",
issuedAdvisory: alpine.Advisory{
Subject: "non empty subject",
},
expctedOverwrite: true,
},
{
name: "invalid old advisory version",
currentVersion: "1.0.0",
issuedAdvisory: alpine.Advisory{
Subject: "non empty subject",
Package: "test",
FixedVersion: "invalid",
},
expctedOverwrite: false,
},
{
name: "invalid current advisory version",
currentVersion: "invalid",
issuedAdvisory: alpine.Advisory{
Subject: "non empty subject",
Package: "test",
FixedVersion: "1.0.0",
},
expctedOverwrite: false,
},
}
for _, tc := range testCases {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
f, _ := ioutil.TempFile("", "TestShouldOverwrite_happy_sad")
issuedAdvisory.FixedVersion = tc.fixedVersion
b, _ := json.Marshal(&issuedAdvisory)
defer os.Remove(f.Name())
b, _ := json.Marshal(tc.issuedAdvisory)
_, _ = f.Write(b)
defer f.Close()
assert.Equal(t, tc.expctedOverwrite, shouldOverwrite(f.Name(), tc.currentVersion), tc.name)
}
})
t.Run("invalid advisory json", func(t *testing.T) {
f, _ := ioutil.TempFile("", "TestShouldOverwrite_invalid_json")
_, _ = f.Write([]byte(`badjsonhere`))
defer f.Close()
assert.Equal(t, true, shouldOverwrite(f.Name(), "doesnt matter"), "invalid advisory json")
})
// TODO: Why should this not overwrite with a subject in advisory json?
t.Run("non empty subject advisory", func(t *testing.T) {
f, _ := ioutil.TempFile("", "TestShouldOverwrite_subject_advisory_json")
b, _ := json.Marshal(&Advisory{
Subject: "non empty subject",
assert.Equal(t, tc.expctedOverwrite, alpine.ShouldOverwrite(&alpine.Config{}, f.Name(), tc.currentVersion), tc.name)
assert.NoError(t, f.Close())
})
_, _ = f.Write(b)
defer f.Close()
assert.True(t, shouldOverwrite(f.Name(), "doesnt matter"), "subject advisory json")
})
t.Run("invalid new advisory version", func(t *testing.T) {
f, _ := ioutil.TempFile("", "TestShouldOverwrite_invalid_version_json_new")
b, _ := json.Marshal(&Advisory{
FixedVersion: "badversionhere",
})
_, _ = f.Write(b)
defer f.Close()
assert.False(t, shouldOverwrite(f.Name(), "doesnt matter"), "invalid new advisory version")
})
t.Run("invalid current advisory version", func(t *testing.T) {
f, _ := ioutil.TempFile("", "TestShouldOverwrite_invalid_version_json_current")
b, _ := json.Marshal(&Advisory{
FixedVersion: "1.0.0",
})
_, _ = f.Write(b)
defer f.Close()
assert.False(t, shouldOverwrite(f.Name(), "badversionhere"), "invalid current advisory version")
})
}
}
func TestWalkApkBuild(t *testing.T) {
advisories, err := walkApkBuild("testdata", "1.0.0")
advisories, err := alpine.WalkApkBuild(&alpine.Config{}, "testdata/aports", "1.0.0")
assert.NoError(t, err)
assert.Equal(t, []Advisory{
{IssueID: 0, VulnerabilityID: "CVE-2019-7572", Release: "1.0.0", Package: "testdata", Repository: ".", FixedVersion: "1.2.15-r11", Subject: "", Description: ""},
{IssueID: 0, VulnerabilityID: "CVE-2019-7574", Release: "1.0.0", Package: "testdata", Repository: ".", FixedVersion: "1.2.15-r11", Subject: "", Description: ""}}, advisories)
assert.ElementsMatch(t, []alpine.Advisory{
{FixedVersion: "1.2.15-r11", VulnerabilityID: "CVE-2019-7572", Release: "1.0.0", Package: "sdl", Repository: "main"},
{FixedVersion: "1.2.15-r11", VulnerabilityID: "CVE-2019-7574", Release: "1.0.0", Package: "sdl", Repository: "main"},
{FixedVersion: "2.6.8-r0", VulnerabilityID: "CVE-2019-10894", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.8-r0", VulnerabilityID: "CVE-2019-10895", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.8-r0", VulnerabilityID: "CVE-2019-10896", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.8-r0", VulnerabilityID: "CVE-2019-10899", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.8-r0", VulnerabilityID: "CVE-2019-10901", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.8-r0", VulnerabilityID: "CVE-2019-10903", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.7-r0", VulnerabilityID: "CVE-2019-9208", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.7-r0", VulnerabilityID: "CVE-2019-9209", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.7-r0", VulnerabilityID: "CVE-2019-9214", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.6-r0", VulnerabilityID: "CVE-2019-5717", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.6-r0", VulnerabilityID: "CVE-2019-5718", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.6-r0", VulnerabilityID: "CVE-2019-5719", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "2.6.6-r0", VulnerabilityID: "CVE-2019-5721", Release: "1.0.0", Package: "wireshark", Repository: "main"},
{FixedVersion: "3.0.19-r0", VulnerabilityID: "CVE-2019-11234", Release: "1.0.0", Package: "freeradius", Repository: "main"},
{FixedVersion: "3.0.19-r0", VulnerabilityID: "CVE-2019-11235", Release: "1.0.0", Package: "freeradius", Repository: "main"},
{FixedVersion: "1.7.3-r0", VulnerabilityID: "CVE-2019-9917", Release: "1.0.0", Package: "znc", Repository: "community"},
{FixedVersion: "1.7.1-r0", VulnerabilityID: "CVE-2018-14055", Release: "1.0.0", Package: "znc", Repository: "community"},
{FixedVersion: "1.7.1-r0", VulnerabilityID: "CVE-2018-14056", Release: "1.0.0", Package: "znc", Repository: "community"},
},
advisories)
}
func TestBuildAdvisories(t *testing.T) {
secFixes := map[string][]string{
"2.6.8-r0": {"CVE-2019-10894"},
"2.6.7-r1": {"CVE_2019-2426 XSA-201"}, // typo
"2.6.5-r0": {"CVE_2019-5910 (+ some extra in parens)"},
}
assert.Equal(t, []Advisory{
assert.ElementsMatch(t, []alpine.Advisory{
{IssueID: 0, VulnerabilityID: "CVE-2019-10894", Release: "1.0.0", Package: "testpkg", Repository: "testrepo", FixedVersion: "2.6.8-r0", Subject: "", Description: ""},
{IssueID: 0, VulnerabilityID: "CVE-2019-2426", Release: "1.0.0", Package: "testpkg", Repository: "testrepo", FixedVersion: "2.6.7-r1", Subject: "", Description: ""},
{IssueID: 0, VulnerabilityID: "XSA-201", Release: "1.0.0", Package: "testpkg", Repository: "testrepo", FixedVersion: "2.6.7-r1", Subject: "", Description: ""},
{IssueID: 0, VulnerabilityID: "CVE-2019-5910", Release: "1.0.0", Package: "testpkg", Repository: "testrepo", FixedVersion: "2.6.5-r0", Subject: "", Description: ""}},
buildAdvisories(secFixes, "1.0.0", "testpkg", "testrepo"))
alpine.BuildAdvisories(&alpine.Config{}, secFixes, "1.0.0", "testpkg", "testrepo"))
}
func TestUpdate(t *testing.T) {
t.Run("happy path", func(t *testing.T) {
assert.NoError(t, Update(MockGitConfig{
remotebranch: func(s string) (strings []string, e error) {
return []string{"origin/branch1-stable", "origin/branch2", "origin/branch3"}, nil
},
}))
})
func TestConfig_Update(t *testing.T) {
type cloneOrPull struct {
returnArg map[string]struct{}
err error
}
type remoteBranch struct {
returnArg []string
err error
}
t.Run("invalid branch name", func(t *testing.T) {
assert.NoError(t, Update(MockGitConfig{
remotebranch: func(s string) (strings []string, e error) {
return []string{"badbranch-stable"}, nil
testCases := []struct {
name string
remoteBranch remoteBranch // mock value
cloneOrPull cloneOrPull // mock value
checkout map[string]error // mock value
wantErr error
}{
{
name: "happy path",
remoteBranch: remoteBranch{
returnArg: []string{"origin/branch1-stable", "origin/branch2", "origin/branch3"},
},
}))
})
checkout: map[string]error{mock.Anything: nil},
wantErr: nil,
},
{
name: "invalid branch name",
remoteBranch: remoteBranch{returnArg: []string{"badbranch-stable"}},
checkout: map[string]error{mock.Anything: nil},
wantErr: nil,
},
{
name: "git fails to show remote branches",
remoteBranch: remoteBranch{
returnArg: nil, err: errors.New("failed to show remote branch"),
},
checkout: map[string]error{mock.Anything: nil},
wantErr: xerrors.Errorf("failed to show branches: %w", errors.New("failed to show remote branch")),
},
{
name: "git clone fails",
cloneOrPull: cloneOrPull{
returnArg: nil, err: errors.New("failed clone operation"),
},
checkout: map[string]error{mock.Anything: nil},
wantErr: xerrors.Errorf("failed to clone alpine repository: %w", errors.New("failed clone operation")),
},
{
name: "git fails to checkout branch",
remoteBranch: remoteBranch{
returnArg: []string{"origin/branch1-stable", "origin/branch2", "origin/branch3"},
},
checkout: map[string]error{mock.Anything: errors.New("failed to checkout branch")},
wantErr: xerrors.Errorf("git failed to checkout branch: %w", errors.New("failed to checkout branch")),
},
{
name: "git checkout of a particular branch fails",
remoteBranch: remoteBranch{
returnArg: []string{"origin/branch1-stable", "origin/branch2", "origin/branch3"},
},
checkout: map[string]error{
"master": errors.New("failed to checkout master"),
"origin/branch1-stable": errors.New("failed to checkout branch1-stable"),
},
wantErr: xerrors.Errorf("git failed to checkout branch: %w", errors.New("failed to checkout branch1-stable")),
},
}
t.Run("git clone fails", func(t *testing.T) {
assert.Equal(t, xerrors.Errorf("failed to clone alpine repository: %w", errors.New("failed clone operation")).Error(),
Update(MockGitConfig{
cloneorpull: func(s string, s2 string) (i map[string]struct{}, e error) {
return nil, errors.New("failed clone operation")
},
}).Error(),
)
})
t.Run("git fails to show remote branches", func(t *testing.T) {
assert.Equal(t, xerrors.Errorf("failed to show branches: %w", errors.New("failed to show remote branch")).Error(),
Update(MockGitConfig{
remotebranch: func(s string) (strings []string, e error) {
return []string{}, errors.New("failed to show remote branch")
},
}).Error(),
)
})
t.Run("git fails to checkout branch", func(t *testing.T) {
assert.Equal(t, xerrors.Errorf("error in git checkout: %w", errors.New("failed to checkout branch")).Error(),
Update(MockGitConfig{
checkout: func(s string, s2 string) error {
return errors.New("failed to checkout branch")
},
}).Error(),
)
})
cacheDir := "testdata"
repoDir := filepath.Join(cacheDir, "aports")
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
vulnListDir, err := ioutil.TempDir("", "TestUpdate")
assert.NoError(t, err)
defer os.RemoveAll(vulnListDir)
t.Run("git checkout of a particular branch fails", func(t *testing.T) {
assert.Equal(t, "error in git checkout: failed to checkout branch", Update(MockGitConfig{
remotebranch: func(s string) (strings []string, e error) {
return []string{"origin/branch1-stable", "origin/branch2", "origin/branch3"}, nil
},
checkout: func(s string, branch string) error {
switch branch {
case "master":
return errors.New("failed to checkout branch")
case "origin/branch1-stable":
return errors.New("failed to checkout branch")
}
return nil
},
}).Error())
})
mockGitConfig := new(MockGitConfig)
// setup expectations with a placeholder in the argument list
mockGitConfig.On("RemoteBranch", repoDir).Return(
tc.remoteBranch.returnArg, tc.remoteBranch.err)
mockGitConfig.On("CloneOrPull", mock.Anything, repoDir).Return(
tc.cloneOrPull.returnArg, tc.cloneOrPull.err)
for arg, returnErr := range tc.checkout {
mockGitConfig.On("Checkout", repoDir, arg).Return(returnErr)
}
ac := alpine.Config{
GitClient: mockGitConfig,
CacheDir: cacheDir,
VulnListDir: vulnListDir,
}
fmt.Println(vulnListDir)
err = ac.Update()
if tc.wantErr != nil {
assert.EqualError(t, err, tc.wantErr.Error())
} else {
assert.NoError(t, err)
err = filepath.Walk(vulnListDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
paths := strings.Split(path, string(os.PathSeparator))
assert.True(t, len(paths) > 3)
golden := filepath.Join("testdata", "goldens",
paths[len(paths)-3], paths[len(paths)-2], paths[len(paths)-1],
)
got, _ := ioutil.ReadFile(path)
want, _ := ioutil.ReadFile(golden + ".golden")
assert.Equal(t, string(want), string(got), "Alpine result json")
return nil
})
assert.NoError(t, err)
}
})
}
}

9
alpine/export_test.go Normal file
View File

@ -0,0 +1,9 @@
package alpine
var (
ShouldOverwrite = (*Config).shouldOverwrite
ParsePkgVerRel = (*Config).parsePkgVerRel
ParseSecFixes = (*Config).parseSecFixes
WalkApkBuild = (*Config).walkApkBuild
BuildAdvisories = (*Config).buildAdvisories
)

View File

@ -0,0 +1,111 @@
# Contributor: Natanael Copa <ncopa@alpinelinux.org>
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=znc
pkgver=1.7.4
pkgrel=0
pkgdesc="Advanced IRC bouncer"
url="https://wiki.znc.in/ZNC"
arch="all"
license="Apache-2.0"
makedepends="perl-dev openssl-dev cyrus-sasl-dev python2-dev c-ares-dev swig
gettext-dev tcl-dev autoconf automake python3-dev icu-dev"
pkgusers="$pkgname"
pkggroups="$pkgusers"
install="$pkgname.pre-install"
subpackages="$pkgname-dev $pkgname-doc $pkgname-extra $pkgname-modtcl
$pkgname-modperl $pkgname-modpython $pkgname-openrc"
source="http://znc.in/releases/znc-$pkgver.tar.gz
$pkgname.initd
$pkgname.confd"
# secfixes:
# 1.7.3-r0:
# - CVE-2019-9917
# 1.7.1-r0:
# - CVE-2018-14055
# - CVE-2018-14056
build() {
export CFLAGS="$CFLAGS -D_GNU_SOURCE"
./configure \
--build=$CBUILD \
--host=$CHOST \
--prefix=/usr \
--sysconfdir=/etc \
--mandir=/usr/share/man \
--infodir=/usr/share/info \
--localstatedir=/var \
--enable-perl \
--enable-tcl \
--enable-python
make
}
package() {
make DESTDIR="$pkgdir" install
install -D -m755 "$srcdir"/$pkgname.initd "$pkgdir"/etc/init.d/$pkgname
install -D -m644 "$srcdir"/$pkgname.confd "$pkgdir"/etc/conf.d/$pkgname
install -d -m750 -o $pkgusers -g $pkggroups "$pkgdir"/var/lib/znc
}
dev() {
default_dev
_mv_to_sub usr/bin/znc-buildmod
}
extra() {
pkgdesc="Extra modules for ZNC"
_mv_mod \
autovoice.so \
block_motd.so \
clearbufferonmsg.so \
ctcpflood.so \
flooddetach.so \
imapauth.so \
listsockets.so \
log.so \
notify_connect.so \
send_raw.so \
shell.so
}
modtcl() {
pkgdesc="TCL module for ZNC"
depends="znc"
_mv_mod modtcl.so
_mv_to_sub usr/share/znc/modtcl
}
modperl() {
pkgdesc="Perl module for ZNC"
depends="znc"
_mv_mod modperl modperl.so
}
modpython() {
pkgdesc="Python modules for ZNC"
depends="znc"
_mv_mod modpython modpython.so
}
_mv_mod() {
local i; for i in "$@"; do
_mv_to_sub usr/lib/znc/$i
done
}
_mv_to_sub() {
local i; for i in "$@"; do
mkdir -p "$subpkgdir"/${i%/*}
mv "$pkgdir"/$i "$subpkgdir"/$i
done
}
sha512sums="ea559ee9e06bfbc51c03ef08e145bc39ee7402638cc153fab7dc1dcedae01548fa0743d726304f9e4631a66241eb96c03940b76093954093a35f69641133b2ae znc-1.7.4.tar.gz
47f9bd00f07861e195333d2cda5b1c7386e2324a1842b890837a7936a94b65b7a269f7fee656a522ec86b58a94bd451a2a3629bd6465578681b8d0733c2c77dc znc.initd
00360f9b487ed5a9d50c85ce597e65c89cf869cabb893c294d0bc7fcd88f9610ecb63ba6df7af1ba1dd977b6d5b05da625a3ee799a46d381f17ac04b976a1f29 znc.confd"

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2018-14055",
"Release": "branch1",
"Package": "znc",
"Repository": "community",
"FixedVersion": "1.7.1-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2018-14056",
"Release": "branch1",
"Package": "znc",
"Repository": "community",
"FixedVersion": "1.7.1-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-9917",
"Release": "branch1",
"Package": "znc",
"Repository": "community",
"FixedVersion": "1.7.3-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-11234",
"Release": "branch1",
"Package": "freeradius",
"Repository": "main",
"FixedVersion": "3.0.19-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-11235",
"Release": "branch1",
"Package": "freeradius",
"Repository": "main",
"FixedVersion": "3.0.19-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-7572",
"Release": "branch1",
"Package": "sdl",
"Repository": "main",
"FixedVersion": "1.2.15-r11",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-7574",
"Release": "branch1",
"Package": "sdl",
"Repository": "main",
"FixedVersion": "1.2.15-r11",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-10894",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.8-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-10895",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.8-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-10896",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.8-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-10899",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.8-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-10901",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.8-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-10903",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.8-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-5717",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.6-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-5718",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.6-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-5719",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.6-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-5721",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.6-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-9208",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.7-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-9209",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.7-r0",
"Subject": "",
"Description": ""
}

View File

@ -0,0 +1,10 @@
{
"IssueID": 0,
"VulnerabilityID": "CVE-2019-9214",
"Release": "branch1",
"Package": "wireshark",
"Repository": "main",
"FixedVersion": "2.6.7-r0",
"Subject": "",
"Description": ""
}

5
go.mod
View File

@ -4,7 +4,6 @@ go 1.13
require (
github.com/araddon/dateparse v0.0.0-20190426192744-0d74ffceef83
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f // indirect
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect
github.com/fatih/color v1.7.0 // indirect
@ -17,10 +16,10 @@ require (
github.com/moul/http2curl v1.0.0 // indirect
github.com/parnurzeal/gorequest v0.2.15
github.com/pkg/errors v0.8.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/simplereach/timeutils v1.2.0 // indirect
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
github.com/stretchr/testify v1.2.2 // indirect
github.com/stretchr/objx v0.2.0 // indirect
github.com/stretchr/testify v1.3.0
golang.org/x/sys v0.0.0-20190412213103-97732733099d // indirect
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect

8
go.sum
View File

@ -1,5 +1,6 @@
github.com/araddon/dateparse v0.0.0-20190426192744-0d74ffceef83 h1:ukTLOeMC0aVxbJWVg6hOsVJ0VPIo8w++PbNsze/pqF8=
github.com/araddon/dateparse v0.0.0-20190426192744-0d74ffceef83/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f h1:8GDPb0tCY8LQ+OJ3dbHb5sA6YZWXFORQYZx5sdsTlMs=
@ -44,8 +45,11 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=

10
main.go
View File

@ -42,7 +42,8 @@ func main() {
func run() error {
flag.Parse()
now := time.Now().UTC()
gc := git.Config{}
gc := &git.Config{}
vulnListDir := utils.VulnListDir()
repoOwner := utils.LookupEnv("VULNLIST_REPOSITORY_OWNER", defaultRepoOwner)
repoName := utils.LookupEnv("VULNLIST_REPOSITORY_NAME", defaultRepoName)
@ -96,7 +97,12 @@ func run() error {
}
commitMsg = "Ubuntu CVE Tracker"
case "alpine":
if err := alpine.Update(gc); err != nil {
ac := alpine.Config{
GitClient: gc,
CacheDir: utils.CacheDir(),
VulnListDir: vulnListDir,
}
if err := ac.Update(); err != nil {
return xerrors.Errorf("error in Alpine update: %w", err)
}
commitMsg = "Alpine Issue Tracker"