gost.Debian.FillWithGost   F
last analyzed

Complexity

Conditions 23

Size

Total Lines 118
Code Lines 81

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 23
eloc 81
dl 0
loc 118
rs 0
c 0
b 0
f 0
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like gost.Debian.FillWithGost often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/* Vuls - Vulnerability Scanner
2
Copyright (C) 2016  Future Architect, Inc. Japan.
3
4
This program is free software: you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation, either version 3 of the License, or
7
(at your option) any later version.
8
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
GNU General Public License for more details.
13
14
You should have received a copy of the GNU General Public License
15
along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
18
package gost
19
20
import (
21
	"encoding/json"
22
23
	"github.com/future-architect/vuls/config"
24
	"github.com/future-architect/vuls/models"
25
	"github.com/future-architect/vuls/util"
26
	"github.com/knqyf263/gost/db"
27
	gostmodels "github.com/knqyf263/gost/models"
28
)
29
30
// Debian is Gost client for Debian GNU/Linux
31
type Debian struct {
32
	Base
33
}
34
35
type packCves struct {
36
	packName  string
37
	isSrcPack bool
38
	cves      []models.CveContent
39
}
40
41
// FillWithGost fills cve information that has in Gost
42
func (deb Debian) FillWithGost(driver db.DB, r *models.ScanResult) (nCVEs int, err error) {
43
	linuxImage := "linux-image-" + r.RunningKernel.Release
44
	// Add linux and set the version of running kernel to search OVAL.
45
	if r.Container.ContainerID == "" {
46
		newVer := ""
47
		if p, ok := r.Packages[linuxImage]; ok {
48
			newVer = p.NewVersion
49
		}
50
		r.Packages["linux"] = models.Package{
51
			Name:       "linux",
52
			Version:    r.RunningKernel.Version,
53
			NewVersion: newVer,
54
		}
55
	}
56
57
	packCvesList := []packCves{}
58
	if config.Conf.Gost.IsFetchViaHTTP() {
59
		url, _ := util.URLPathJoin(config.Conf.Gost.URL, "debian", major(r.Release), "pkgs")
60
		responses, err := getAllUnfixedCvesViaHTTP(r, url)
61
		if err != nil {
62
			return 0, err
63
		}
64
65
		for _, res := range responses {
66
			debCves := map[string]gostmodels.DebianCVE{}
67
			if err := json.Unmarshal([]byte(res.json), &debCves); err != nil {
68
				return 0, err
69
			}
70
			cves := []models.CveContent{}
71
			for _, debcve := range debCves {
72
				cves = append(cves, *deb.ConvertToModel(&debcve))
73
			}
74
			packCvesList = append(packCvesList, packCves{
75
				packName:  res.request.packName,
76
				isSrcPack: res.request.isSrcPack,
77
				cves:      cves,
78
			})
79
		}
80
	} else {
81
		if driver == nil {
82
			return 0, nil
83
		}
84
		for _, pack := range r.Packages {
85
			cveDebs := driver.GetUnfixedCvesDebian(major(r.Release), pack.Name)
86
			cves := []models.CveContent{}
87
			for _, cveDeb := range cveDebs {
88
				cves = append(cves, *deb.ConvertToModel(&cveDeb))
89
			}
90
			packCvesList = append(packCvesList, packCves{
91
				packName:  pack.Name,
92
				isSrcPack: false,
93
				cves:      cves,
94
			})
95
		}
96
97
		// SrcPack
98
		for _, pack := range r.SrcPackages {
99
			cveDebs := driver.GetUnfixedCvesDebian(major(r.Release), pack.Name)
100
			cves := []models.CveContent{}
101
			for _, cveDeb := range cveDebs {
102
				cves = append(cves, *deb.ConvertToModel(&cveDeb))
103
			}
104
			packCvesList = append(packCvesList, packCves{
105
				packName:  pack.Name,
106
				isSrcPack: true,
107
				cves:      cves,
108
			})
109
		}
110
	}
111
112
	delete(r.Packages, "linux")
113
114
	for _, p := range packCvesList {
115
		for _, cve := range p.cves {
116
			v, ok := r.ScannedCves[cve.CveID]
117
			if ok {
118
				if v.CveContents == nil {
119
					v.CveContents = models.NewCveContents(cve)
120
				} else {
121
					v.CveContents[models.DebianSecurityTracker] = cve
122
				}
123
			} else {
124
				v = models.VulnInfo{
125
					CveID:       cve.CveID,
126
					CveContents: models.NewCveContents(cve),
127
					Confidences: models.Confidences{models.DebianSecurityTrackerMatch},
128
				}
129
				nCVEs++
130
			}
131
132
			names := []string{}
133
			if p.isSrcPack {
134
				if srcPack, ok := r.SrcPackages[p.packName]; ok {
135
					for _, binName := range srcPack.BinaryNames {
136
						if _, ok := r.Packages[binName]; ok {
137
							names = append(names, binName)
138
						}
139
					}
140
				}
141
			} else {
142
				if p.packName == "linux" {
143
					names = append(names, linuxImage)
144
				} else {
145
					names = append(names, p.packName)
146
				}
147
			}
148
149
			for _, name := range names {
150
				v.AffectedPackages = v.AffectedPackages.Store(models.PackageFixStatus{
151
					Name:        name,
152
					FixState:    "open",
153
					NotFixedYet: true,
154
				})
155
			}
156
			r.ScannedCves[cve.CveID] = v
157
		}
158
	}
159
	return nCVEs, nil
160
}
161
162
// ConvertToModel converts gost model to vuls model
163
func (deb Debian) ConvertToModel(cve *gostmodels.DebianCVE) *models.CveContent {
164
	severity := ""
165
	for _, p := range cve.Package {
166
		for _, r := range p.Release {
167
			severity = r.Urgency
168
			break
169
		}
170
	}
171
	return &models.CveContent{
172
		Type:          models.DebianSecurityTracker,
173
		CveID:         cve.CveID,
174
		Summary:       cve.Description,
175
		Cvss2Severity: severity,
176
		Cvss3Severity: severity,
177
		SourceLink:    "https://security-tracker.debian.org/tracker/" + cve.CveID,
178
		Optional: map[string]string{
179
			"attack range": cve.Scope,
180
		},
181
	}
182
}
183