Fix -to-email
This commit is contained in:
		@@ -231,14 +231,12 @@ func cvss3ScoreToSeverity(score float64) string {
 | 
			
		||||
 | 
			
		||||
// Cvss3Scores returns CVSS V3 Score
 | 
			
		||||
func (v CveContents) Cvss3Scores() (values []CveContentCvss3) {
 | 
			
		||||
	// TODO implement NVD
 | 
			
		||||
	order := []CveContentType{RedHat}
 | 
			
		||||
	for _, ctype := range order {
 | 
			
		||||
		if cont, found := v[ctype]; found && 0 < cont.Cvss3Score {
 | 
			
		||||
			// https://nvd.nist.gov/vuln-metrics/cvss
 | 
			
		||||
			sev := cont.Severity
 | 
			
		||||
			if ctype == NVD {
 | 
			
		||||
				sev = cvss3ScoreToSeverity(cont.Cvss2Score)
 | 
			
		||||
			}
 | 
			
		||||
			values = append(values, CveContentCvss3{
 | 
			
		||||
				Type: ctype,
 | 
			
		||||
				Value: Cvss3{
 | 
			
		||||
@@ -254,6 +252,7 @@ func (v CveContents) Cvss3Scores() (values []CveContentCvss3) {
 | 
			
		||||
 | 
			
		||||
// MaxCvss3Score returns Max CVSS V3 Score
 | 
			
		||||
func (v CveContents) MaxCvss3Score() CveContentCvss3 {
 | 
			
		||||
	// TODO implement NVD
 | 
			
		||||
	order := []CveContentType{RedHat}
 | 
			
		||||
	max := 0.0
 | 
			
		||||
	value := CveContentCvss3{
 | 
			
		||||
@@ -264,9 +263,6 @@ func (v CveContents) MaxCvss3Score() CveContentCvss3 {
 | 
			
		||||
		if cont, found := v[ctype]; found && max < cont.Cvss3Score {
 | 
			
		||||
			// https://nvd.nist.gov/vuln-metrics/cvss
 | 
			
		||||
			sev := cont.Severity
 | 
			
		||||
			if ctype == NVD {
 | 
			
		||||
				sev = cvss3ScoreToSeverity(cont.Cvss2Score)
 | 
			
		||||
			}
 | 
			
		||||
			value = CveContentCvss3{
 | 
			
		||||
				Type: ctype,
 | 
			
		||||
				Value: Cvss3{
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,6 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	cvedict "github.com/kotakanbe/go-cve-dictionary/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -215,34 +214,6 @@ func (r ScanResult) FormatServerName() string {
 | 
			
		||||
		r.Container.Name, r.ServerName)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CveSummary summarize the number of CVEs group by CVSSv2 Severity
 | 
			
		||||
func (r ScanResult) CveSummary() string {
 | 
			
		||||
	var high, medium, low, unknown int
 | 
			
		||||
	for _, vInfo := range r.ScannedCves {
 | 
			
		||||
		score := vInfo.CveContents.MaxCvss2Score().Value.Score
 | 
			
		||||
		if score < 0.1 {
 | 
			
		||||
			score = vInfo.CveContents.MaxCvss3Score().Value.Score
 | 
			
		||||
		}
 | 
			
		||||
		switch {
 | 
			
		||||
		case 7.0 <= score:
 | 
			
		||||
			high++
 | 
			
		||||
		case 4.0 <= score:
 | 
			
		||||
			medium++
 | 
			
		||||
		case 0 < score:
 | 
			
		||||
			low++
 | 
			
		||||
		default:
 | 
			
		||||
			unknown++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if config.Conf.IgnoreUnscoredCves {
 | 
			
		||||
		return fmt.Sprintf("Total: %d (High:%d Medium:%d Low:%d)",
 | 
			
		||||
			high+medium+low, high, medium, low)
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("Total: %d (High:%d Medium:%d Low:%d ?:%d)",
 | 
			
		||||
		high+medium+low+unknown, high, medium, low, unknown)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatTextReportHeadedr returns header of text report
 | 
			
		||||
func (r ScanResult) FormatTextReportHeadedr() string {
 | 
			
		||||
	serverInfo := r.ServerInfo()
 | 
			
		||||
@@ -253,7 +224,7 @@ func (r ScanResult) FormatTextReportHeadedr() string {
 | 
			
		||||
	return fmt.Sprintf("%s\n%s\n%s\t%s\n",
 | 
			
		||||
		r.ServerInfo(),
 | 
			
		||||
		buf.String(),
 | 
			
		||||
		r.CveSummary(),
 | 
			
		||||
		r.ScannedCves.FormatCveSummary(),
 | 
			
		||||
		r.Packages.FormatUpdatablePacksSummary(),
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,8 @@ import (
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// VulnInfos is VulnInfo list, getter/setter, sortable methods.
 | 
			
		||||
@@ -65,7 +67,42 @@ func (v VulnInfos) ToSortedSlice() (sorted []VulnInfo) {
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VulnInfo holds a vulnerability information and unsecure packages
 | 
			
		||||
// CountGroupBySeverity summarize the number of CVEs group by CVSSv2 Severity
 | 
			
		||||
func (v VulnInfos) CountGroupBySeverity() map[string]int {
 | 
			
		||||
	m := map[string]int{}
 | 
			
		||||
	for _, vInfo := range v {
 | 
			
		||||
		score := vInfo.CveContents.MaxCvss2Score().Value.Score
 | 
			
		||||
		if score < 0.1 {
 | 
			
		||||
			score = vInfo.CveContents.MaxCvss3Score().Value.Score
 | 
			
		||||
		}
 | 
			
		||||
		switch {
 | 
			
		||||
		case 7.0 <= score:
 | 
			
		||||
			m["High"]++
 | 
			
		||||
		case 4.0 <= score:
 | 
			
		||||
			m["Medium"]++
 | 
			
		||||
		case 0 < score:
 | 
			
		||||
			m["Low"]++
 | 
			
		||||
		default:
 | 
			
		||||
			m["Unknown"]++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FormatCveSummary summarize the number of CVEs group by CVSSv2 Severity
 | 
			
		||||
func (v VulnInfos) FormatCveSummary() string {
 | 
			
		||||
	m := v.CountGroupBySeverity()
 | 
			
		||||
 | 
			
		||||
	if config.Conf.IgnoreUnscoredCves {
 | 
			
		||||
		return fmt.Sprintf("Total: %d (High:%d Medium:%d Low:%d)",
 | 
			
		||||
			m["High"]+m["Medium"]+m["Low"], m["High"], m["Medium"], m["Low"])
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("Total: %d (High:%d Medium:%d Low:%d ?:%d)",
 | 
			
		||||
		m["High"]+m["Medium"]+m["Low"]+m["Unknown"],
 | 
			
		||||
		m["High"], m["Medium"], m["Low"], m["Unknown"])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// VulnInfo has a vulnerability information and unsecure packages
 | 
			
		||||
type VulnInfo struct {
 | 
			
		||||
	CveID            string
 | 
			
		||||
	Confidence       Confidence
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,67 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestCountGroupBySeverity(t *testing.T) {
 | 
			
		||||
	var tests = []struct {
 | 
			
		||||
		in  VulnInfos
 | 
			
		||||
		out map[string]int
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			in: VulnInfos{
 | 
			
		||||
				"CVE-2017-0002": {
 | 
			
		||||
					CveID: "CVE-2017-0002",
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss2Score: 6.0,
 | 
			
		||||
						},
 | 
			
		||||
						RedHat: {
 | 
			
		||||
							Type:       RedHat,
 | 
			
		||||
							Cvss2Score: 7.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				"CVE-2017-0003": {
 | 
			
		||||
					CveID: "CVE-2017-0003",
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss2Score: 2.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				"CVE-2017-0004": {
 | 
			
		||||
					CveID: "CVE-2017-0004",
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss2Score: 5.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				"CVE-2017-0005": {
 | 
			
		||||
					CveID: "CVE-2017-0005",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			out: map[string]int{
 | 
			
		||||
				"High":    1,
 | 
			
		||||
				"Medium":  1,
 | 
			
		||||
				"Low":     1,
 | 
			
		||||
				"Unknown": 1,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		actual := tt.in.CountGroupBySeverity()
 | 
			
		||||
		for k := range tt.out {
 | 
			
		||||
			if tt.out[k] != actual[k] {
 | 
			
		||||
				t.Errorf("\nexpected %s: %d\n  actual %d\n",
 | 
			
		||||
					k, tt.out[k], actual[k])
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestToSortedSlice(t *testing.T) {
 | 
			
		||||
	var tests = []struct {
 | 
			
		||||
		in  VulnInfos
 | 
			
		||||
@@ -33,11 +94,11 @@ func TestToSortedSlice(t *testing.T) {
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss3Score: 6.0,
 | 
			
		||||
							Cvss2Score: 6.0,
 | 
			
		||||
						},
 | 
			
		||||
						RedHat: {
 | 
			
		||||
							Type:       RedHat,
 | 
			
		||||
							Cvss2Score: 7.0,
 | 
			
		||||
							Cvss3Score: 7.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
@@ -46,11 +107,11 @@ func TestToSortedSlice(t *testing.T) {
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss3Score: 7.0,
 | 
			
		||||
							Cvss2Score: 7.0,
 | 
			
		||||
						},
 | 
			
		||||
						RedHat: {
 | 
			
		||||
							Type:       RedHat,
 | 
			
		||||
							Cvss2Score: 8.0,
 | 
			
		||||
							Cvss3Score: 8.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
@@ -61,11 +122,11 @@ func TestToSortedSlice(t *testing.T) {
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss3Score: 7.0,
 | 
			
		||||
							Cvss2Score: 7.0,
 | 
			
		||||
						},
 | 
			
		||||
						RedHat: {
 | 
			
		||||
							Type:       RedHat,
 | 
			
		||||
							Cvss2Score: 8.0,
 | 
			
		||||
							Cvss3Score: 8.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
@@ -74,11 +135,11 @@ func TestToSortedSlice(t *testing.T) {
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss3Score: 6.0,
 | 
			
		||||
							Cvss2Score: 6.0,
 | 
			
		||||
						},
 | 
			
		||||
						RedHat: {
 | 
			
		||||
							Type:       RedHat,
 | 
			
		||||
							Cvss2Score: 7.0,
 | 
			
		||||
							Cvss3Score: 7.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
@@ -92,11 +153,11 @@ func TestToSortedSlice(t *testing.T) {
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss3Score: 6.0,
 | 
			
		||||
							Cvss2Score: 6.0,
 | 
			
		||||
						},
 | 
			
		||||
						RedHat: {
 | 
			
		||||
							Type:       RedHat,
 | 
			
		||||
							Cvss2Score: 7.0,
 | 
			
		||||
							Cvss3Score: 7.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
@@ -125,11 +186,11 @@ func TestToSortedSlice(t *testing.T) {
 | 
			
		||||
					CveContents: CveContents{
 | 
			
		||||
						NVD: {
 | 
			
		||||
							Type:       NVD,
 | 
			
		||||
							Cvss3Score: 6.0,
 | 
			
		||||
							Cvss2Score: 6.0,
 | 
			
		||||
						},
 | 
			
		||||
						RedHat: {
 | 
			
		||||
							Type:       RedHat,
 | 
			
		||||
							Cvss2Score: 7.0,
 | 
			
		||||
							Cvss3Score: 7.0,
 | 
			
		||||
						},
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user