diff --git a/cmd/clair/main.go b/cmd/clair/main.go
index df3d0ba2be..4c07ea0d8a 100644
--- a/cmd/clair/main.go
+++ b/cmd/clair/main.go
@@ -29,6 +29,7 @@ import (
_ "github.com/coreos/clair/notifier/notifiers"
_ "github.com/coreos/clair/updater/fetchers/debian"
+ _ "github.com/coreos/clair/updater/fetchers/opensuse"
_ "github.com/coreos/clair/updater/fetchers/rhel"
_ "github.com/coreos/clair/updater/fetchers/ubuntu"
_ "github.com/coreos/clair/updater/metadata_fetchers/nvd"
diff --git a/updater/fetchers/opensuse/opensuse.go b/updater/fetchers/opensuse/opensuse.go
new file mode 100644
index 0000000000..a4b57f989c
--- /dev/null
+++ b/updater/fetchers/opensuse/opensuse.go
@@ -0,0 +1,101 @@
+// Copyright 2015 clair authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package opensuse
+
+import (
+ "fmt"
+ "regexp"
+ "strconv"
+
+ "github.com/coreos/clair/updater"
+ "github.com/coreos/clair/updater/fetchers/oval"
+ "github.com/coreos/pkg/capnslog"
+)
+
+var log = capnslog.NewPackageLogger("github.com/coreos/clair", "updater/fetchers/sle")
+
+func init() {
+ opensuse_info := &OpenSUSE_Info{}
+
+ updater.RegisterFetcher(opensuse_info.DistName(),
+ &oval.OvalFetcher{Os_info: opensuse_info})
+}
+
+type OpenSUSE_Info struct {
+}
+
+func (f *OpenSUSE_Info) CritSystem() *regexp.Regexp {
+ return regexp.MustCompile(`openSUSE [^0-9]*(\d+\.\d+)[^0-9]* is installed`)
+}
+
+func (f *OpenSUSE_Info) CritPackage() *regexp.Regexp {
+ return regexp.MustCompile(`(.*)-(.*\-[\d\.]+) is installed`)
+}
+
+func (f *OpenSUSE_Info) DistRegexp() *regexp.Regexp {
+ return regexp.MustCompile(`opensuse.[^0-9]*(\d+\.\d+).xml`)
+}
+
+func (f *OpenSUSE_Info) OvalURI() string {
+ return "http://ftp.suse.com/pub/projects/security/oval/"
+}
+
+func (f *OpenSUSE_Info) UpdaterFlag() string {
+ return "opensuseUpdater"
+}
+
+func (f *OpenSUSE_Info) DistMinVersion() float64 {
+ return 13.1
+}
+
+func (f *OpenSUSE_Info) DistName() string {
+ return "opensuse"
+}
+
+func (f *OpenSUSE_Info) ParseOsVersion(comment string) string {
+ systemMatch := f.CritSystem().FindStringSubmatch(comment)
+ if len(systemMatch) < 2 {
+ return ""
+ }
+ osVersion := systemMatch[1]
+ if len(systemMatch) == 4 && systemMatch[3] != "" {
+ sp := systemMatch[3]
+ osVersion = fmt.Sprintf("%s.%s", osVersion, sp)
+ }
+
+ // log.Infof("got %s as system version from: %s", osVersion, c.Comment)
+ return osVersion
+
+}
+
+func (f *OpenSUSE_Info) ParsePackageNameVersion(comment string) (string, string) {
+ packageMatch := f.CritPackage().FindStringSubmatch(comment)
+
+ if len(packageMatch) != 3 {
+ return "", ""
+ }
+ name := packageMatch[1]
+ version := packageMatch[2]
+ return name, version
+}
+
+func (f *OpenSUSE_Info) ParseFilenameDistVersion(line string) (string, float64) {
+ r := f.DistRegexp().FindStringSubmatch(line)
+ if len(r) == 2 {
+ distVersion, _ := strconv.ParseFloat(r[1], 32)
+ return r[0], distVersion
+ }
+ return "", 0
+}
diff --git a/updater/fetchers/opensuse/opensuse_test.go b/updater/fetchers/opensuse/opensuse_test.go
new file mode 100644
index 0000000000..eb2d2f6e40
--- /dev/null
+++ b/updater/fetchers/opensuse/opensuse_test.go
@@ -0,0 +1,66 @@
+// Copyright 2015 clair authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package opensuse
+
+import (
+ "os"
+ "path/filepath"
+ "runtime"
+ "testing"
+
+ "github.com/coreos/clair/database"
+ "github.com/coreos/clair/updater/fetchers/oval"
+ "github.com/coreos/clair/utils/types"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestOpenSUSEParser(t *testing.T) {
+ _, filename, _, _ := runtime.Caller(0)
+ path := filepath.Join(filepath.Dir(filename))
+
+ // Test parsing testdata/fetcher_opensuse_test.1.xml
+ testFile, _ := os.Open(path + "/testdata/fetcher_opensuse_test.1.xml")
+ ov := &oval.OvalFetcher{Os_info: &OpenSUSE_Info{}}
+ vulnerabilities, err := ov.ParseOval(testFile)
+ if assert.Nil(t, err) && assert.Len(t, vulnerabilities, 1) {
+ assert.Equal(t, "CVE-2012-2150", vulnerabilities[0].Name)
+ assert.Equal(t, "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-2150", vulnerabilities[0].Link)
+ // Severity is not defined for openSUSE
+ assert.Equal(t, types.Unknown, vulnerabilities[0].Severity)
+ assert.Equal(t, `xfs_metadump in xfsprogs before 3.2.4 does not properly obfuscate file data, which allows remote attackers to obtain sensitive information by reading a generated image.`, vulnerabilities[0].Description)
+
+ expectedFeatureVersions := []database.FeatureVersion{
+ {
+ Feature: database.Feature{
+ Namespace: database.Namespace{Name: "opensuse:42.1"},
+ Name: "xfsprogs",
+ },
+ Version: types.NewVersionUnsafe("3.2.1-5.1"),
+ },
+ {
+ Feature: database.Feature{
+ Namespace: database.Namespace{Name: "opensuse:42.1"},
+ Name: "xfsprogs-devel",
+ },
+ Version: types.NewVersionUnsafe("3.2.1-5.1"),
+ },
+ }
+
+ for _, expectedFeatureVersion := range expectedFeatureVersions {
+ assert.Contains(t, vulnerabilities[0].FixedIn, expectedFeatureVersion)
+ }
+ }
+
+}
diff --git a/updater/fetchers/opensuse/testdata/fetcher_opensuse_test.1.xml b/updater/fetchers/opensuse/testdata/fetcher_opensuse_test.1.xml
new file mode 100644
index 0000000000..258f8254e7
--- /dev/null
+++ b/updater/fetchers/opensuse/testdata/fetcher_opensuse_test.1.xml
@@ -0,0 +1,66 @@
+
+
+
+
+ Marcus Updateinfo to OVAL Converter
+ 5.5
+ 2016-06-27T04:04:46
+
+
+
+
+ CVE-2012-2150
+
+ openSUSE Leap 42.1
+
+
+ xfs_metadump in xfsprogs before 3.2.4 does not properly obfuscate file data, which allows remote attackers to obtain sensitive information by reading a generated image.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ xfsprogs-devel
+
+
+ openSUSE-release
+
+
+ xfsprogs
+
+
+
+
+ 0:3.2.1-5.1
+
+
+ 42.1
+
+
+
diff --git a/updater/fetchers/oval/oval.go b/updater/fetchers/oval/oval.go
new file mode 100644
index 0000000000..e9275e79e6
--- /dev/null
+++ b/updater/fetchers/oval/oval.go
@@ -0,0 +1,306 @@
+// Copyright 2015 clair authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package oval
+
+import (
+ "bufio"
+ "encoding/xml"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+
+ "github.com/coreos/clair/database"
+ "github.com/coreos/clair/updater"
+ cerrors "github.com/coreos/clair/utils/errors"
+ "github.com/coreos/clair/utils/types"
+ "github.com/coreos/pkg/capnslog"
+)
+
+type oval struct {
+ Definitions []definition `xml:"definitions>definition"`
+}
+
+type definition struct {
+ Title string `xml:"metadata>title"`
+ Description string `xml:"metadata>description"`
+ References []reference `xml:"metadata>reference"`
+ Criteria criteria `xml:"criteria"`
+}
+
+type reference struct {
+ Source string `xml:"source,attr"`
+ URI string `xml:"ref_url,attr"`
+}
+
+type criteria struct {
+ Operator string `xml:"operator,attr"`
+ Criterias []*criteria `xml:"criteria"`
+ Criterions []criterion `xml:"criterion"`
+}
+
+type criterion struct {
+ Comment string `xml:"comment,attr"`
+}
+
+// OvalFetcher implements updater.Fetcher.
+type OvalFetcher struct {
+ Os_info OSInfo
+}
+
+type OSInfo interface {
+ ParsePackageNameVersion(string) (string, string)
+ ParseOsVersion(string) string
+ ParseFilenameDistVersion(string) (string, float64)
+ OvalURI() string
+ UpdaterFlag() string
+ DistMinVersion() float64
+ DistName() string
+}
+
+var (
+ log = capnslog.NewPackageLogger("github.com/coreos/clair", "updater/fetchers/sle")
+)
+
+// FetchUpdate gets vulnerability updates from the OVAL definitions.
+func (f *OvalFetcher) FetchUpdate(datastore database.Datastore) (resp updater.FetcherResponse, err error) {
+ log.Info("fetching %s vulnerabilities", f.Os_info.DistName())
+
+ // TODO: Skip already loaded records
+
+ // flagValue, err := datastore.KeyValue(f.Os_info.UpdaterFlag)
+
+ // if err != nil {
+ // return resp, err
+ // }
+
+ r, err := http.Get(f.Os_info.OvalURI())
+
+ if err != nil {
+ log.Errorf("could not download %s's update list: %s", f.Os_info.DistName(), err)
+ return resp, cerrors.ErrCouldNotDownload
+ }
+
+ var distList []string
+ scanner := bufio.NewScanner(r.Body)
+
+ for scanner.Scan() {
+ line := scanner.Text()
+ filename, distVersion := f.Os_info.ParseFilenameDistVersion(line)
+ if distVersion >= f.Os_info.DistMinVersion() {
+ distList = append(distList, filename)
+ }
+ }
+
+ for _, distFile := range distList {
+ r, err := http.Get(f.Os_info.OvalURI() + distFile)
+
+ if err != nil {
+ log.Errorf("could not download %s's update file: %s", f.Os_info.DistName(), err)
+ return resp, cerrors.ErrCouldNotDownload
+ }
+
+ vs, err := f.ParseOval(r.Body)
+
+ if err != nil {
+ return resp, err
+ }
+
+ for _, v := range vs {
+ resp.Vulnerabilities = append(resp.Vulnerabilities, v)
+ }
+ }
+
+ return resp, nil
+}
+
+// Clean deletes any allocated resources.
+func (f *OvalFetcher) Clean() {}
+
+func (f *OvalFetcher) ToFeatureVersions(possibilities [][]criterion) []database.FeatureVersion {
+ featureVersionParameters := make(map[string]database.FeatureVersion)
+
+ for _, criterions := range possibilities {
+ var (
+ featureVersion database.FeatureVersion
+ osVersion string
+ )
+
+ for _, c := range criterions {
+ tmp_v := f.Os_info.ParseOsVersion(c.Comment)
+ if tmp_v != "" {
+ osVersion = tmp_v
+ continue
+ }
+
+ tmp_p_name, tmp_p_version := f.Os_info.ParsePackageNameVersion(c.Comment)
+ if tmp_p_version != "" && tmp_p_name != "" {
+ featureVersion.Feature.Name = tmp_p_name
+ featureVersion.Version, _ = types.NewVersion(tmp_p_version)
+ continue
+ }
+
+ log.Warningf("could not parse criteria: '%s'.", c.Comment)
+ }
+
+ if osVersion == "" {
+ log.Warning(criterions)
+ }
+
+ featureVersion.Feature.Namespace.Name = fmt.Sprintf("%s:%s", f.Os_info.DistName(), osVersion)
+
+ if featureVersion.Feature.Name != "" && featureVersion.Version.String() != "" {
+ featureVersionParameters[featureVersion.Feature.Namespace.Name+":"+featureVersion.Feature.Name] = featureVersion
+ } else {
+ log.Warningf("could not determine a valid package from criterions: %v", criterions)
+ }
+ }
+
+ var featureVersionParametersArray []database.FeatureVersion
+
+ for _, fv := range featureVersionParameters {
+ featureVersionParametersArray = append(featureVersionParametersArray, fv)
+ }
+
+ return featureVersionParametersArray
+}
+func (f *OvalFetcher) ParseOval(ovalReader io.Reader) (vulnerabilities []database.Vulnerability, err error) {
+ var ov oval
+ err = xml.NewDecoder(ovalReader).Decode(&ov)
+
+ if err != nil {
+ log.Errorf("could not decode %s's XML: %s", f.Os_info.DistName(), err)
+ return vulnerabilities, cerrors.ErrCouldNotParse
+ }
+
+ for _, definition := range ov.Definitions {
+ pkgs := f.ToFeatureVersions(getPossibilities(definition.Criteria))
+
+ if len(pkgs) > 0 {
+ vulnerability := database.Vulnerability{
+ Name: name(definition),
+ Link: link(definition),
+ Severity: priority(definition),
+ Description: description(definition),
+ }
+
+ for _, p := range pkgs {
+ vulnerability.FixedIn = append(vulnerability.FixedIn, p)
+ }
+
+ vulnerabilities = append(vulnerabilities, vulnerability)
+ }
+ }
+
+ return
+}
+
+func description(def definition) (desc string) {
+ desc = strings.Replace(def.Description, "\n\n\n", " ", -1)
+ desc = strings.Replace(desc, "\n\n", " ", -1)
+ desc = strings.Replace(desc, "\n", " ", -1)
+
+ return
+}
+
+func name(def definition) string {
+ return strings.TrimSpace(def.Title)
+}
+
+func link(def definition) (link string) {
+ for _, reference := range def.References {
+ if reference.Source == "CVE" {
+ link = reference.URI
+ break
+ }
+ }
+
+ return
+}
+
+func priority(def definition) types.Priority {
+ // The OVAL files provided by SUSE doesn't include any priority/severity yet.
+ return types.Unknown
+}
+
+func getCriterions(node criteria) [][]criterion {
+ var criterions []criterion
+
+ for _, c := range node.Criterions {
+ criterions = append(criterions, c)
+ }
+
+ if node.Operator == "AND" {
+ return [][]criterion{criterions}
+ } else if node.Operator == "OR" {
+ var possibilities [][]criterion
+
+ for _, c := range criterions {
+ possibilities = append(possibilities, []criterion{c})
+ }
+
+ return possibilities
+ }
+
+ return [][]criterion{}
+}
+
+func getPossibilities(node criteria) [][]criterion {
+ if len(node.Criterias) == 0 {
+ return getCriterions(node)
+ }
+
+ var possibilitiesToCompose [][][]criterion
+
+ for _, criteria := range node.Criterias {
+ possibilitiesToCompose = append(possibilitiesToCompose, getPossibilities(*criteria))
+ }
+
+ if len(node.Criterions) > 0 {
+ possibilitiesToCompose = append(possibilitiesToCompose, getCriterions(node))
+ }
+
+ var possibilities [][]criterion
+
+ if node.Operator == "AND" {
+ for _, possibility := range possibilitiesToCompose[0] {
+ possibilities = append(possibilities, possibility)
+ }
+
+ for _, possibilityGroup := range possibilitiesToCompose[1:] {
+ var newPossibilities [][]criterion
+
+ for _, possibility := range possibilities {
+ for _, possibilityInGroup := range possibilityGroup {
+ var p []criterion
+
+ p = append(p, possibility...)
+ p = append(p, possibilityInGroup...)
+
+ newPossibilities = append(newPossibilities, p)
+ }
+ }
+
+ possibilities = newPossibilities
+ }
+ } else if node.Operator == "OR" {
+ for _, possibilityGroup := range possibilitiesToCompose {
+ for _, possibility := range possibilityGroup {
+ possibilities = append(possibilities, possibility)
+ }
+ }
+ }
+ return possibilities
+}
diff --git a/updater/fetchers/sle/sle.go b/updater/fetchers/sle/sle.go
new file mode 100644
index 0000000000..b7addcd2ad
--- /dev/null
+++ b/updater/fetchers/sle/sle.go
@@ -0,0 +1,101 @@
+// Copyright 2015 clair authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sle
+
+import (
+ "fmt"
+ "regexp"
+ "strconv"
+
+ "github.com/coreos/clair/updater"
+ "github.com/coreos/clair/updater/fetchers/oval"
+ "github.com/coreos/pkg/capnslog"
+)
+
+var log = capnslog.NewPackageLogger("github.com/coreos/clair", "updater/fetchers/sle")
+
+func init() {
+ sle_info := &SLE_Info{}
+
+ updater.RegisterFetcher(sle_info.DistName(),
+ &oval.OvalFetcher{Os_info: sle_info})
+}
+
+type SLE_Info struct {
+}
+
+func (f *SLE_Info) CritSystem() *regexp.Regexp {
+ return regexp.MustCompile(`SUSE Linux Enterprise Server [^0-9]*(\d+)\s*(SP(\d+)|) is installed`)
+}
+
+func (f *SLE_Info) CritPackage() *regexp.Regexp {
+ return regexp.MustCompile(`(.*)-(.*\-[\d\.]+) is installed`)
+}
+
+func (f *SLE_Info) DistRegexp() *regexp.Regexp {
+ return regexp.MustCompile(`suse.linux.enterprise.(\d+).xml`)
+}
+
+func (f *SLE_Info) OvalURI() string {
+ return "http://ftp.suse.com/pub/projects/security/oval/"
+}
+
+func (f *SLE_Info) UpdaterFlag() string {
+ return "sleUpdater"
+}
+
+func (f *SLE_Info) DistMinVersion() float64 {
+ return 11.4
+}
+
+func (f *SLE_Info) DistName() string {
+ return "sle"
+}
+
+func (f *SLE_Info) ParseOsVersion(comment string) string {
+ systemMatch := f.CritSystem().FindStringSubmatch(comment)
+ if len(systemMatch) < 2 {
+ return ""
+ }
+ osVersion := systemMatch[1]
+ if len(systemMatch) == 4 && systemMatch[3] != "" {
+ sp := systemMatch[3]
+ osVersion = fmt.Sprintf("%s.%s", osVersion, sp)
+ }
+
+ // log.Infof("got %s as system version from: %s", osVersion, c.Comment)
+ return osVersion
+
+}
+
+func (f *SLE_Info) ParsePackageNameVersion(comment string) (string, string) {
+ packageMatch := f.CritPackage().FindStringSubmatch(comment)
+
+ if len(packageMatch) != 3 {
+ return "", ""
+ }
+ name := packageMatch[1]
+ version := packageMatch[2]
+ return name, version
+}
+
+func (f *SLE_Info) ParseFilenameDistVersion(line string) (string, float64) {
+ r := f.DistRegexp().FindStringSubmatch(line)
+ if len(r) == 2 {
+ distVersion, _ := strconv.ParseFloat(r[1], 32)
+ return r[0], distVersion
+ }
+ return "", 0
+}
diff --git a/updater/fetchers/sle/sle_test.go b/updater/fetchers/sle/sle_test.go
new file mode 100644
index 0000000000..394ed3dcc6
--- /dev/null
+++ b/updater/fetchers/sle/sle_test.go
@@ -0,0 +1,67 @@
+// Copyright 2015 clair authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sle
+
+import (
+ "os"
+ "path/filepath"
+ "runtime"
+ "testing"
+
+ "github.com/coreos/clair/database"
+ "github.com/coreos/clair/updater/fetchers/oval"
+ "github.com/coreos/clair/utils/types"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestSLEParser(t *testing.T) {
+ _, filename, _, _ := runtime.Caller(0)
+ path := filepath.Join(filepath.Dir(filename))
+
+ // Test parsing testdata/fetcher_sle_test.1.xml
+ testFile, _ := os.Open(path + "/testdata/fetcher_sle_test.1.xml")
+ ov := &oval.OvalFetcher{Os_info: &SLE_Info{}}
+ vulnerabilities, err := ov.ParseOval(testFile)
+ if assert.Nil(t, err) && assert.Len(t, vulnerabilities, 1) {
+ assert.Equal(t, "CVE-2012-2150", vulnerabilities[0].Name)
+ assert.Equal(t, "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-2150", vulnerabilities[0].Link)
+ // Severity is not defined for SLE
+ assert.Equal(t, types.Unknown, vulnerabilities[0].Severity)
+ assert.Equal(t, `xfs_metadump in xfsprogs before 3.2.4 does not properly obfuscate file data, which allows remote attackers to obtain sensitive information by reading a generated image.`, vulnerabilities[0].Description)
+
+ expectedFeatureVersions := []database.FeatureVersion{
+ {
+ Feature: database.Feature{
+ Namespace: database.Namespace{Name: "sle:12"},
+ Name: "xfsprogs",
+ },
+ Version: types.NewVersionUnsafe("3.2.1-3.5"),
+ },
+ {
+ Feature: database.Feature{
+ Namespace: database.Namespace{Name: "sle:12.1"},
+ Name: "xfsprogs",
+ },
+ Version: types.NewVersionUnsafe("3.2.1-3.5"),
+ },
+ }
+
+ for _, expectedFeatureVersion := range expectedFeatureVersions {
+ assert.Contains(t, vulnerabilities[0].FixedIn, expectedFeatureVersion)
+ }
+
+ }
+
+}
diff --git a/updater/fetchers/sle/testdata/fetcher_sle_test.1.xml b/updater/fetchers/sle/testdata/fetcher_sle_test.1.xml
new file mode 100644
index 0000000000..e718def9de
--- /dev/null
+++ b/updater/fetchers/sle/testdata/fetcher_sle_test.1.xml
@@ -0,0 +1,69 @@
+
+
+
+
+ Marcus Updateinfo to OVAL Converter
+ 5.5
+ 2016-06-27T04:04:46
+
+
+
+
+ CVE-2012-2150
+
+ SUSE Linux Enterprise Server 12
+
+
+ xfs_metadump in xfsprogs before 3.2.4 does not properly obfuscate file data, which allows remote attackers to obtain sensitive information by reading a generated image.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sles-release
+
+
+ xfsprogs
+
+
+
+
+ 0:3.2.1-3.5
+
+
+ 12
+
+
+ 12.1
+
+
+