clair: mv updater clair and mv severity to db

pull/305/head
Jimmy Zelinskie 7 years ago
parent 6e8e6ad26b
commit 9c63a63944

@ -24,7 +24,6 @@ import (
"github.com/coreos/pkg/capnslog"
"github.com/fernet/fernet-go"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
)
@ -109,7 +108,7 @@ type Vulnerability struct {
}
func (v Vulnerability) DatabaseModel() (database.Vulnerability, error) {
severity, err := clair.NewSeverity(v.Severity)
severity, err := database.NewSeverity(v.Severity)
if err != nil {
return database.Vulnerability{}, err
}

@ -27,13 +27,13 @@ import (
"github.com/coreos/pkg/capnslog"
"github.com/coreos/clair"
"github.com/coreos/clair/api"
"github.com/coreos/clair/api/context"
"github.com/coreos/clair/config"
"github.com/coreos/clair/database"
"github.com/coreos/clair/notifier"
"github.com/coreos/clair/pkg/stopper"
"github.com/coreos/clair/updater"
// Register database driver.
_ "github.com/coreos/clair/database/pgsql"
@ -112,7 +112,7 @@ func Boot(config *config.Config) {
// Start updater
st.Begin()
go updater.Run(config.Updater, db, st)
go clair.RunUpdater(config.Updater, db, st)
// Wait for interruption and shutdown gracefully.
waitForSignals(syscall.SIGINT, syscall.SIGTERM)

@ -12,7 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Package database defines the Clair's models and a common interface for database implementations.
// Package database defines the Clair's models and a common interface for
// database implementations.
package database
import (
@ -144,7 +145,8 @@ type Datastore interface {
// Vulnerability in the database. It can be used to store the fact that a
// Vulnerability no longer affects the given Feature in any Version.
//
// It has has to create a Notification that will contain the old and the updated Vulnerability.
// It has has to create a Notification that will contain the old and the
// updated Vulnerability.
DeleteVulnerabilityFix(vulnerabilityNamespace, vulnerabilityName, featureName string) error
// GetAvailableNotification returns the Name, Created, Notified and Deleted

@ -18,8 +18,6 @@ import (
"database/sql/driver"
"encoding/json"
"time"
"github.com/coreos/clair"
)
// ID is only meant to be used by database implementations and should never be used for anything else.
@ -70,7 +68,7 @@ type Vulnerability struct {
Description string
Link string
Severity clair.Severity
Severity Severity
Metadata MetadataMap

@ -26,7 +26,6 @@ import (
"github.com/pborman/uuid"
"github.com/stretchr/testify/assert"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt/dpkg"
)
@ -92,7 +91,7 @@ func TestRaceAffects(t *testing.T) {
Version: strconv.Itoa(version),
},
},
Severity: clair.Unknown,
Severity: database.UnknownSeverity,
}
vulnerabilities[version] = append(vulnerabilities[version], vulnerability)

@ -20,7 +20,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt/dpkg"
"github.com/coreos/clair/pkg/commonerr"
@ -91,7 +90,7 @@ func TestFindLayer(t *testing.T) {
if assert.Len(t, featureVersion.AffectedBy, 1) {
assert.Equal(t, "debian:7", featureVersion.AffectedBy[0].Namespace.Name)
assert.Equal(t, "CVE-OPENSSL-1-DEB7", featureVersion.AffectedBy[0].Name)
assert.Equal(t, clair.High, featureVersion.AffectedBy[0].Severity)
assert.Equal(t, database.HighSeverity, featureVersion.AffectedBy[0].Severity)
assert.Equal(t, "A vulnerability affecting OpenSSL < 2.0 on Debian 7.0", featureVersion.AffectedBy[0].Description)
assert.Equal(t, "http://google.com/#q=CVE-OPENSSL-1-DEB7", featureVersion.AffectedBy[0].Link)
assert.Equal(t, "2.0", featureVersion.AffectedBy[0].FixedBy)

@ -20,7 +20,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
"github.com/coreos/clair/ext/versionfmt/dpkg"
@ -169,7 +168,7 @@ func TestNotification(t *testing.T) {
// Update a vulnerability and ensure that the old/new vulnerabilities are correct.
v1b := v1
v1b.Severity = clair.High
v1b.Severity = database.HighSeverity
v1b.FixedIn = []database.FeatureVersion{
{
Feature: f1,

@ -20,7 +20,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
"github.com/coreos/clair/ext/versionfmt/dpkg"
@ -44,7 +43,7 @@ func TestFindVulnerability(t *testing.T) {
Name: "CVE-OPENSSL-1-DEB7",
Description: "A vulnerability affecting OpenSSL < 2.0 on Debian 7.0",
Link: "http://google.com/#q=CVE-OPENSSL-1-DEB7",
Severity: clair.High,
Severity: database.HighSeverity,
Namespace: database.Namespace{
Name: "debian:7",
VersionFormat: dpkg.ParserName,
@ -74,7 +73,7 @@ func TestFindVulnerability(t *testing.T) {
Name: "debian:7",
VersionFormat: dpkg.ParserName,
},
Severity: clair.Unknown,
Severity: database.UnknownSeverity,
}
v2f, err := datastore.FindVulnerability("debian:7", "CVE-NOPE")
@ -180,13 +179,13 @@ func TestInsertVulnerability(t *testing.T) {
Name: "",
Namespace: n1,
FixedIn: []database.FeatureVersion{f1},
Severity: clair.Unknown,
Severity: database.UnknownSeverity,
},
{
Name: "TestInsertVulnerability0",
Namespace: database.Namespace{},
FixedIn: []database.FeatureVersion{f1},
Severity: clair.Unknown,
Severity: database.UnknownSeverity,
},
{
Name: "TestInsertVulnerability0-",
@ -197,7 +196,7 @@ func TestInsertVulnerability(t *testing.T) {
Name: "TestInsertVulnerability0",
Namespace: n1,
FixedIn: []database.FeatureVersion{f2},
Severity: clair.Unknown,
Severity: database.UnknownSeverity,
},
} {
err := datastore.InsertVulnerabilities([]database.Vulnerability{vulnerability}, true)
@ -217,7 +216,7 @@ func TestInsertVulnerability(t *testing.T) {
Name: "TestInsertVulnerability1",
Namespace: n1,
FixedIn: []database.FeatureVersion{f1, f3, f6, f7},
Severity: clair.Low,
Severity: database.LowSeverity,
Description: "TestInsertVulnerabilityDescription1",
Link: "TestInsertVulnerabilityLink1",
Metadata: v1meta,
@ -233,7 +232,7 @@ func TestInsertVulnerability(t *testing.T) {
// Update vulnerability.
v1.Description = "TestInsertVulnerabilityLink2"
v1.Link = "TestInsertVulnerabilityLink2"
v1.Severity = clair.High
v1.Severity = database.HighSeverity
// Update f3 in f4, add fixed in f5, add fixed in f6 which already exists,
// removes fixed in f7 by adding f8 which is f7 but with MinVersion, and
// add fixed by f5 a second time (duplicated).

@ -0,0 +1,134 @@
// Copyright 2017 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 database
import (
"database/sql/driver"
"errors"
"strings"
)
// ErrFailedToParseSeverity is the error returned when a severity could not
// be parsed from a string.
var ErrFailedToParseSeverity = errors.New("failed to parse Severity from input")
// Severity defines a standard scale for measuring the severity of a
// vulnerability.
type Severity string
const (
// UnknownSeverity is either a security problem that has not been assigned to
// a priority yet or a priority that our system did not recognize.
UnknownSeverity Severity = "Unknown"
// NegligibleSeverity is technically a security problem, but is only
// theoretical in nature, requires a very special situation, has almost no
// install base, or does no real damage. These tend not to get backport from
// upstreams, and will likely not be included in security updates unless
// there is an easy fix and some other issue causes an update.
NegligibleSeverity Severity = "Negligible"
// LowSeverity is a security problem, but is hard to exploit due to
// environment, requires a user-assisted attack, a small install base, or
// does very little damage. These tend to be included in security updates
// only when higher priority issues require an update, or if many low
// priority issues have built up.
LowSeverity Severity = "Low"
// MediumSeverity is a real security problem, and is exploitable for many
// people. Includes network daemon denial of service attacks, cross-site
// scripting, and gaining user privileges. Updates should be made soon for
// this priority of issue.
MediumSeverity Severity = "Medium"
// HighSeverity is a real problem, exploitable for many people in a default
// installation. Includes serious remote denial of services, local root
// privilege escalations, or data loss.
HighSeverity Severity = "High"
// CriticalSeverity is a world-burning problem, exploitable for nearly all
// people in a default installation of Linux. Includes remote root privilege
// escalations, or massive data loss.
CriticalSeverity Severity = "Critical"
// Defcon1Severity is a Critical problem which has been manually highlighted
// by the team. It requires an immediate attention.
Defcon1Severity Severity = "Defcon1"
)
// Severities lists all known severities, ordered from lowest to highest.
var Severities = []Severity{
UnknownSeverity,
NegligibleSeverity,
LowSeverity,
MediumSeverity,
HighSeverity,
CriticalSeverity,
Defcon1Severity,
}
// NewSeverity attempts to parse a string into a standard Severity value.
func NewSeverity(s string) (Severity, error) {
for _, ss := range Severities {
if strings.EqualFold(s, string(ss)) {
return ss, nil
}
}
return UnknownSeverity, ErrFailedToParseSeverity
}
// Compare determines the equality of two severities.
//
// If the severities are equal, returns 0.
// If the receiever is less, returns -1.
// If the receiver is greater, returns 1.
func (s Severity) Compare(s2 Severity) int {
var i1, i2 int
for i1 = 0; i1 < len(Severities); i1 = i1 + 1 {
if s == Severities[i1] {
break
}
}
for i2 = 0; i2 < len(Severities); i2 = i2 + 1 {
if s2 == Severities[i2] {
break
}
}
return i1 - i2
}
// Scan implements the database/sql.Scanner interface.
func (s *Severity) Scan(value interface{}) error {
val, ok := value.([]byte)
if !ok {
return errors.New("could not scan a Severity from a non-string input")
}
var err error
*s, err = NewSeverity(string(val))
if err != nil {
return err
}
return nil
}
// Value implements the database/sql/driver.Valuer interface.
func (s Severity) Value() (driver.Value, error) {
return string(s), nil
}

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package clair
package database
import (
"testing"
@ -21,9 +21,9 @@ import (
)
func TestCompareSeverity(t *testing.T) {
assert.Equal(t, Medium.Compare(Medium), 0, "Severity comparison failed")
assert.True(t, Medium.Compare(High) < 0, "Severity comparison failed")
assert.True(t, Critical.Compare(Low) > 0, "Severity comparison failed")
assert.Equal(t, MediumSeverity.Compare(MediumSeverity), 0, "Severity comparison failed")
assert.True(t, MediumSeverity.Compare(HighSeverity) < 0, "Severity comparison failed")
assert.True(t, CriticalSeverity.Compare(LowSeverity) > 0, "Severity comparison failed")
}
func TestParseSeverity(t *testing.T) {

@ -19,7 +19,6 @@ package vulnmdsrc
import (
"sync"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
)
@ -29,7 +28,7 @@ var (
)
// AppendFunc is the type of a callback provided to an Appender.
type AppendFunc func(metadataKey string, metadata interface{}, severity clair.Severity)
type AppendFunc func(metadataKey string, metadata interface{}, severity database.Severity)
// Appender represents anything that can fetch vulnerability metadata and
// append it to a Vulnerability.

@ -32,7 +32,6 @@ import (
"github.com/coreos/pkg/capnslog"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/vulnmdsrc"
"github.com/coreos/clair/pkg/commonerr"
@ -218,23 +217,25 @@ func getHashFromMetaURL(metaURL string) (string, error) {
return "", errors.New("invalid .meta file format")
}
// SeverityFromCVSS converts the CVSS Score (0.0 - 10.0) into a clair.Severity
// following the qualitative rating scale available in the CVSS v3.0
// specification (https://www.first.org/cvss/specification-document), Table 14.
// SeverityFromCVSS converts the CVSS Score (0.0 - 10.0) into a
// database.Severity following the qualitative rating scale available in the
// CVSS v3.0 specification (https://www.first.org/cvss/specification-document),
// Table 14.
//
// The Negligible level is set for CVSS scores between [0, 1), replacing the
// specified None level, originally used for a score of 0.
func SeverityFromCVSS(score float64) clair.Severity {
func SeverityFromCVSS(score float64) database.Severity {
switch {
case score < 1.0:
return clair.Negligible
return database.NegligibleSeverity
case score < 3.9:
return clair.Low
return database.LowSeverity
case score < 6.9:
return clair.Medium
return database.MediumSeverity
case score < 8.9:
return clair.High
return database.HighSeverity
case score <= 10:
return clair.Critical
return database.CriticalSeverity
}
return clair.Unknown
return database.UnknownSeverity
}

@ -28,7 +28,6 @@ import (
"github.com/coreos/pkg/capnslog"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
"github.com/coreos/clair/ext/versionfmt/dpkg"
@ -43,9 +42,7 @@ const (
nvdURLPrefix = "https://cve.mitre.org/cgi-bin/cvename.cgi?name="
)
var (
log = capnslog.NewPackageLogger("github.com/coreos/clair", "ext/vulnsrc/alpine")
)
var log = capnslog.NewPackageLogger("github.com/coreos/clair", "ext/vulnsrc/alpine")
func init() {
vulnsrc.RegisterUpdater("alpine", &updater{})
@ -230,7 +227,7 @@ func parse33YAML(r io.Reader) (vulns []database.Vulnerability, err error) {
vulns = append(vulns, database.Vulnerability{
Name: fix,
Severity: clair.Unknown,
Severity: database.UnknownSeverity,
Link: nvdURLPrefix + fix,
FixedIn: []database.FeatureVersion{
{
@ -284,7 +281,7 @@ func parse34YAML(r io.Reader) (vulns []database.Vulnerability, err error) {
for _, vulnStr := range vulnStrs {
var vuln database.Vulnerability
vuln.Severity = clair.Unknown
vuln.Severity = database.UnknownSeverity
vuln.Name = vulnStr
vuln.Link = nvdURLPrefix + vulnStr
vuln.FixedIn = []database.FeatureVersion{

@ -27,7 +27,6 @@ import (
"github.com/coreos/pkg/capnslog"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
"github.com/coreos/clair/ext/versionfmt/dpkg"
@ -158,7 +157,7 @@ func parseDebianJSON(data *jsonData) (vulnerabilities []database.Vulnerability,
vulnerability = &database.Vulnerability{
Name: vulnName,
Link: strings.Join([]string{cveURLPrefix, "/", vulnName}, ""),
Severity: clair.Unknown,
Severity: database.UnknownSeverity,
Description: vulnNode.Description,
}
}
@ -220,40 +219,40 @@ func parseDebianJSON(data *jsonData) (vulnerabilities []database.Vulnerability,
}
// SeverityFromUrgency converts the urgency scale used by the Debian Security
// Bug Tracker into a clair.Severity.
func SeverityFromUrgency(urgency string) clair.Severity {
// Bug Tracker into a database.Severity.
func SeverityFromUrgency(urgency string) database.Severity {
switch urgency {
case "not yet assigned":
return clair.Unknown
return database.UnknownSeverity
case "end-of-life":
fallthrough
case "unimportant":
return clair.Negligible
return database.NegligibleSeverity
case "low":
fallthrough
case "low*":
fallthrough
case "low**":
return clair.Low
return database.LowSeverity
case "medium":
fallthrough
case "medium*":
fallthrough
case "medium**":
return clair.Medium
return database.MediumSeverity
case "high":
fallthrough
case "high*":
fallthrough
case "high**":
return clair.High
return database.HighSeverity
default:
log.Warningf("could not determine vulnerability severity from: %s", urgency)
return clair.Unknown
return database.UnknownSeverity
}
}

@ -20,7 +20,6 @@ import (
"runtime"
"testing"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
"github.com/coreos/clair/ext/versionfmt/dpkg"
@ -37,7 +36,7 @@ func TestDebianParser(t *testing.T) {
for _, vulnerability := range response.Vulnerabilities {
if vulnerability.Name == "CVE-2015-1323" {
assert.Equal(t, "https://security-tracker.debian.org/tracker/CVE-2015-1323", vulnerability.Link)
assert.Equal(t, clair.Low, vulnerability.Severity)
assert.Equal(t, database.LowSeverity, vulnerability.Severity)
assert.Equal(t, "This vulnerability is not very dangerous.", vulnerability.Description)
expectedFeatureVersions := []database.FeatureVersion{
@ -68,7 +67,7 @@ func TestDebianParser(t *testing.T) {
}
} else if vulnerability.Name == "CVE-2003-0779" {
assert.Equal(t, "https://security-tracker.debian.org/tracker/CVE-2003-0779", vulnerability.Link)
assert.Equal(t, clair.High, vulnerability.Severity)
assert.Equal(t, database.HighSeverity, vulnerability.Severity)
assert.Equal(t, "But this one is very dangerous.", vulnerability.Description)
expectedFeatureVersions := []database.FeatureVersion{
@ -109,7 +108,7 @@ func TestDebianParser(t *testing.T) {
}
} else if vulnerability.Name == "CVE-2013-2685" {
assert.Equal(t, "https://security-tracker.debian.org/tracker/CVE-2013-2685", vulnerability.Link)
assert.Equal(t, clair.Negligible, vulnerability.Severity)
assert.Equal(t, database.NegligibleSeverity, vulnerability.Severity)
assert.Equal(t, "Un-affected packages.", vulnerability.Description)
expectedFeatureVersions := []database.FeatureVersion{

@ -27,7 +27,6 @@ import (
"github.com/coreos/pkg/capnslog"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
"github.com/coreos/clair/ext/versionfmt/rpm"
@ -337,20 +336,20 @@ func link(def definition) (link string) {
return
}
func severity(def definition) clair.Severity {
func severity(def definition) database.Severity {
switch strings.ToLower(def.Severity) {
case "n/a":
return clair.Negligible
return database.NegligibleSeverity
case "low":
return clair.Low
return database.LowSeverity
case "moderate":
return clair.Medium
return database.MediumSeverity
case "important":
return clair.High
return database.HighSeverity
case "critical":
return clair.Critical
return database.CriticalSeverity
default:
log.Warningf("could not determine vulnerability severity from: %s.", def.Severity)
return clair.Unknown
return database.UnknownSeverity
}
}

@ -20,7 +20,6 @@ import (
"runtime"
"testing"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt/rpm"
"github.com/stretchr/testify/assert"
@ -38,7 +37,7 @@ func TestOracleParser(t *testing.T) {
if assert.Nil(t, err) && assert.Len(t, vulnerabilities, 1) {
assert.Equal(t, "ELSA-2015-1193", vulnerabilities[0].Name)
assert.Equal(t, "http://linux.oracle.com/errata/ELSA-2015-1193.html", vulnerabilities[0].Link)
assert.Equal(t, clair.Medium, vulnerabilities[0].Severity)
assert.Equal(t, database.MediumSeverity, vulnerabilities[0].Severity)
assert.Equal(t, ` [3.1.1-7] Resolves: rhbz#1217104 CVE-2015-0252 `, vulnerabilities[0].Description)
expectedFeatureVersions := []database.FeatureVersion{
@ -86,7 +85,7 @@ func TestOracleParser(t *testing.T) {
if assert.Nil(t, err) && assert.Len(t, vulnerabilities, 1) {
assert.Equal(t, "ELSA-2015-1207", vulnerabilities[0].Name)
assert.Equal(t, "http://linux.oracle.com/errata/ELSA-2015-1207.html", vulnerabilities[0].Link)
assert.Equal(t, clair.Critical, vulnerabilities[0].Severity)
assert.Equal(t, database.CriticalSeverity, vulnerabilities[0].Severity)
assert.Equal(t, ` [38.1.0-1.0.1.el7_1] - Add firefox-oracle-default-prefs.js and remove the corresponding Red Hat file [38.1.0-1] - Update to 38.1.0 ESR [38.0.1-2] - Fixed rhbz#1222807 by removing preun section `, vulnerabilities[0].Description)
expectedFeatureVersions := []database.FeatureVersion{
{

@ -27,7 +27,6 @@ import (
"github.com/coreos/pkg/capnslog"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
"github.com/coreos/clair/ext/versionfmt/rpm"
@ -344,18 +343,18 @@ func link(def definition) (link string) {
return
}
func severity(def definition) clair.Severity {
func severity(def definition) database.Severity {
switch strings.TrimSpace(def.Title[strings.LastIndex(def.Title, "(")+1 : len(def.Title)-1]) {
case "Low":
return clair.Low
return database.LowSeverity
case "Moderate":
return clair.Medium
return database.MediumSeverity
case "Important":
return clair.High
return database.HighSeverity
case "Critical":
return clair.Critical
return database.CriticalSeverity
default:
log.Warning("could not determine vulnerability severity from: %s.", def.Title)
return clair.Unknown
return database.UnknownSeverity
}
}

@ -20,7 +20,6 @@ import (
"runtime"
"testing"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt/rpm"
"github.com/stretchr/testify/assert"
@ -36,7 +35,7 @@ func TestRHELParser(t *testing.T) {
if assert.Nil(t, err) && assert.Len(t, vulnerabilities, 1) {
assert.Equal(t, "RHSA-2015:1193", vulnerabilities[0].Name)
assert.Equal(t, "https://rhn.redhat.com/errata/RHSA-2015-1193.html", vulnerabilities[0].Link)
assert.Equal(t, clair.Medium, vulnerabilities[0].Severity)
assert.Equal(t, database.MediumSeverity, vulnerabilities[0].Severity)
assert.Equal(t, `Xerces-C is a validating XML parser written in a portable subset of C++. A flaw was found in the way the Xerces-C XML parser processed certain XML documents. A remote attacker could provide specially crafted XML input that, when parsed by an application using Xerces-C, would cause that application to crash.`, vulnerabilities[0].Description)
expectedFeatureVersions := []database.FeatureVersion{
@ -83,7 +82,7 @@ func TestRHELParser(t *testing.T) {
if assert.Nil(t, err) && assert.Len(t, vulnerabilities, 1) {
assert.Equal(t, "RHSA-2015:1207", vulnerabilities[0].Name)
assert.Equal(t, "https://rhn.redhat.com/errata/RHSA-2015-1207.html", vulnerabilities[0].Link)
assert.Equal(t, clair.Critical, vulnerabilities[0].Severity)
assert.Equal(t, database.CriticalSeverity, vulnerabilities[0].Severity)
assert.Equal(t, `Mozilla Firefox is an open source web browser. XULRunner provides the XUL Runtime environment for Mozilla Firefox. Several flaws were found in the processing of malformed web content. A web page containing malicious content could cause Firefox to crash or, potentially, execute arbitrary code with the privileges of the user running Firefox.`, vulnerabilities[0].Description)
expectedFeatureVersions := []database.FeatureVersion{

@ -30,7 +30,6 @@ import (
"github.com/coreos/pkg/capnslog"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
"github.com/coreos/clair/ext/versionfmt/dpkg"
@ -398,30 +397,30 @@ func parseUbuntuCVE(fileContent io.Reader) (vulnerability database.Vulnerability
// If no priority has been provided (CVE-2007-0667 for instance), set the priority to Unknown
if vulnerability.Severity == "" {
vulnerability.Severity = clair.Unknown
vulnerability.Severity = database.UnknownSeverity
}
return
}
// SeverityFromPriority converts an priority from the Ubuntu CVE Tracker into
// a clair.Severity.
func SeverityFromPriority(priority string) clair.Severity {
// a database.Severity.
func SeverityFromPriority(priority string) database.Severity {
switch priority {
case "untriaged":
return clair.Unknown
return database.UnknownSeverity
case "negligible":
return clair.Negligible
return database.NegligibleSeverity
case "low":
return clair.Low
return database.LowSeverity
case "medium":
return clair.Medium
return database.MediumSeverity
case "high":
return clair.High
return database.HighSeverity
case "critical":
return clair.Critical
return database.CriticalSeverity
default:
log.Warning("could not determine a vulnerability severity from: %s", priority)
return clair.Unknown
return database.UnknownSeverity
}
}

@ -22,7 +22,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/coreos/clair"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/versionfmt"
)
@ -37,7 +36,7 @@ func TestUbuntuParser(t *testing.T) {
vulnerability, unknownReleases, err := parseUbuntuCVE(testData)
if assert.Nil(t, err) {
assert.Equal(t, "CVE-2015-4471", vulnerability.Name)
assert.Equal(t, clair.Medium, vulnerability.Severity)
assert.Equal(t, database.MediumSeverity, vulnerability.Severity)
assert.Equal(t, "Off-by-one error in the lzxd_decompress function in lzxd.c in libmspack before 0.5 allows remote attackers to cause a denial of service (buffer under-read and application crash) via a crafted CAB archive.", vulnerability.Description)
// Unknown release (line 28)

@ -1,139 +0,0 @@
// Copyright 2017 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 clair
import (
"database/sql/driver"
"errors"
"strings"
)
var (
// ErrFailedToParseSeverity is the error returned when a severity could not
// be parsed from a string.
ErrFailedToParseSeverity = errors.New("failed to parse Severity from input")
)
// Severity defines a standard scale for measuring the severity of a
// vulnerability.
type Severity string
const (
// Unknown is either a security problem that has not been
// assigned to a priority yet or a priority that our system
// did not recognize.
Unknown Severity = "Unknown"
// Negligible is technically a security problem, but is
// only theoretical in nature, requires a very special
// situation, has almost no install base, or does no real
// damage. These tend not to get backport from upstreams,
// and will likely not be included in security updates unless
// there is an easy fix and some other issue causes an update.
Negligible Severity = "Negligible"
// Low is a security problem, but is hard to
// exploit due to environment, requires a user-assisted
// attack, a small install base, or does very little damage.
// These tend to be included in security updates only when
// higher priority issues require an update, or if many
// low priority issues have built up.
Low Severity = "Low"
// Medium is a real security problem, and is exploitable
// for many people. Includes network daemon denial of service
// attacks, cross-site scripting, and gaining user privileges.
// Updates should be made soon for this priority of issue.
Medium Severity = "Medium"
// High is a real problem, exploitable for many people in a default
// installation. Includes serious remote denial of services,
// local root privilege escalations, or data loss.
High Severity = "High"
// Critical is a world-burning problem, exploitable for nearly all people
// in a default installation of Linux. Includes remote root
// privilege escalations, or massive data loss.
Critical Severity = "Critical"
// Defcon1 is a Critical problem which has been manually highlighted by
// the team. It requires an immediate attention.
Defcon1 Severity = "Defcon1"
)
// Severities lists all known severities, ordered from lowest to highest.
var Severities = []Severity{
Unknown,
Negligible,
Low,
Medium,
High,
Critical,
Defcon1,
}
// NewSeverity attempts to parse a string into a standard Severity value.
func NewSeverity(s string) (Severity, error) {
for _, ss := range Severities {
if strings.EqualFold(s, string(ss)) {
return ss, nil
}
}
return Unknown, ErrFailedToParseSeverity
}
// Compare determines the equality of two severities.
//
// If the severities are equal, returns 0.
// If the receiever is less, returns -1.
// If the receiver is greater, returns 1.
func (s Severity) Compare(s2 Severity) int {
var i1, i2 int
for i1 = 0; i1 < len(Severities); i1 = i1 + 1 {
if s == Severities[i1] {
break
}
}
for i2 = 0; i2 < len(Severities); i2 = i2 + 1 {
if s2 == Severities[i2] {
break
}
}
return i1 - i2
}
// Scan implements the database/sql.Scanner interface.
func (s *Severity) Scan(value interface{}) error {
val, ok := value.([]byte)
if !ok {
return errors.New("could not scan a Severity from a non-string input")
}
var err error
*s, err = NewSeverity(string(val))
if err != nil {
return err
}
return nil
}
// Value implements the database/sql/driver.Valuer interface.
func (s Severity) Value() (driver.Value, error) {
return string(s), nil
}

@ -12,10 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// Package updater updates the vulnerability database periodically using the
// registered vulnerability source updaters and vulnerability metadata
// appenders.
package updater
package clair
import (
"math/rand"
@ -27,7 +24,6 @@ import (
"github.com/pborman/uuid"
"github.com/prometheus/client_golang/prometheus"
"github.com/coreos/clair"
"github.com/coreos/clair/config"
"github.com/coreos/clair/database"
"github.com/coreos/clair/ext/vulnmdsrc"
@ -36,16 +32,14 @@ import (
)
const (
flagName = "updater/last"
notesFlagName = "updater/notes"
lockName = "updater"
lockDuration = refreshLockDuration + time.Minute*2
refreshLockDuration = time.Minute * 8
updaterLastFlagName = "updater/last"
updaterLockName = "updater"
updaterLockDuration = updaterLockRefreshDuration + time.Minute*2
updaterLockRefreshDuration = time.Minute * 8
)
var (
log = capnslog.NewPackageLogger("github.com/coreos/clair", "updater")
log = capnslog.NewPackageLogger("github.com/coreos/clair", "clair")
promUpdaterErrorsTotal = prometheus.NewCounter(prometheus.CounterOpts{
Name: "clair_updater_errors_total",
@ -69,8 +63,9 @@ func init() {
prometheus.MustRegister(promUpdaterNotesTotal)
}
// Run updates the vulnerability database at regular intervals.
func Run(config *config.UpdaterConfig, datastore database.Datastore, st *stopper.Stopper) {
// RunUpdater begins a process that updates the vulnerability database at
// regular intervals.
func RunUpdater(config *config.UpdaterConfig, datastore database.Datastore, st *stopper.Stopper) {
defer st.End()
// Do not run the updater if there is no config or if the interval is 0.
@ -100,12 +95,12 @@ func Run(config *config.UpdaterConfig, datastore database.Datastore, st *stopper
if nextUpdate.Before(time.Now().UTC()) {
// Attempt to get a lock on the the update.
log.Debug("attempting to obtain update lock")
hasLock, hasLockUntil := datastore.Lock(lockName, whoAmI, lockDuration, false)
hasLock, hasLockUntil := datastore.Lock(updaterLockName, whoAmI, updaterLockDuration, false)
if hasLock {
// Launch update in a new go routine.
doneC := make(chan bool, 1)
go func() {
Update(datastore, firstUpdate)
update(datastore, firstUpdate)
doneC <- true
}()
@ -113,23 +108,23 @@ func Run(config *config.UpdaterConfig, datastore database.Datastore, st *stopper
select {
case <-doneC:
done = true
case <-time.After(refreshLockDuration):
case <-time.After(updaterLockRefreshDuration):
// Refresh the lock until the update is done.
datastore.Lock(lockName, whoAmI, lockDuration, true)
datastore.Lock(updaterLockName, whoAmI, updaterLockDuration, true)
case <-st.Chan():
stop = true
}
}
// Unlock the update.
datastore.Unlock(lockName, whoAmI)
datastore.Unlock(updaterLockName, whoAmI)
if stop {
break
}
continue
} else {
lockOwner, lockExpiration, err := datastore.FindLock(lockName)
lockOwner, lockExpiration, err := datastore.FindLock(updaterLockName)
if err != nil {
log.Debug("update lock is already taken")
nextUpdate = hasLockUntil
@ -162,9 +157,9 @@ func Run(config *config.UpdaterConfig, datastore database.Datastore, st *stopper
log.Info("updater service stopped")
}
// Update fetches all the vulnerabilities from the registered fetchers, upserts
// update fetches all the vulnerabilities from the registered fetchers, upserts
// them into the database and then sends notifications.
func Update(datastore database.Datastore, firstUpdate bool) {
func update(datastore database.Datastore, firstUpdate bool) {
defer setUpdaterDuration(time.Now())
log.Info("updating vulnerabilities")
@ -195,7 +190,7 @@ func Update(datastore database.Datastore, firstUpdate bool) {
// Update last successful update if every fetchers worked properly.
if status {
datastore.InsertKeyValue(flagName, strconv.FormatInt(time.Now().UTC().Unix(), 10))
datastore.InsertKeyValue(updaterLastFlagName, strconv.FormatInt(time.Now().UTC().Unix(), 10))
}
log.Info("update finished")
@ -293,7 +288,7 @@ func addMetadata(datastore database.Datastore, vulnerabilities []database.Vulner
}
func getLastUpdate(datastore database.Datastore) (time.Time, bool, error) {
lastUpdateTSS, err := datastore.GetKeyValue(flagName)
lastUpdateTSS, err := datastore.GetKeyValue(updaterLastFlagName)
if err != nil {
return time.Time{}, false, err
}
@ -316,7 +311,7 @@ type lockableVulnerability struct {
sync.Mutex
}
func (lv *lockableVulnerability) appendFunc(metadataKey string, metadata interface{}, severity clair.Severity) {
func (lv *lockableVulnerability) appendFunc(metadataKey string, metadata interface{}, severity database.Severity) {
lv.Lock()
defer lv.Unlock()
@ -329,7 +324,7 @@ func (lv *lockableVulnerability) appendFunc(metadataKey string, metadata interfa
lv.Metadata[metadataKey] = metadata
// If necessary, provide a severity for the vulnerability.
if lv.Severity == clair.Unknown {
if lv.Severity == database.UnknownSeverity {
lv.Severity = severity
}
}

@ -1,4 +1,4 @@
// Copyright 2016 clair authors
// Copyright 2017 clair authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package updater
package clair
import (
"fmt"
Loading…
Cancel
Save