models.CveContents.Cpes   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
dl 0
loc 13
rs 9.95
c 0
b 0
f 0
nop 1
1
/* Vuls - Vulnerability Scanner
2
Copyright (C) 2016  Future Corporation , 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 models
19
20
import (
21
	"time"
22
)
23
24
// CveContents has CveContent
25
type CveContents map[CveContentType]CveContent
26
27
// NewCveContents create CveContents
28
func NewCveContents(conts ...CveContent) CveContents {
29
	m := CveContents{}
30
	for _, cont := range conts {
31
		m[cont.Type] = cont
32
	}
33
	return m
34
}
35
36
// CveContentStr has CveContentType and Value
37
type CveContentStr struct {
38
	Type  CveContentType
39
	Value string
40
}
41
42
// Except returns CveContents except given keys for enumeration
43
func (v CveContents) Except(exceptCtypes ...CveContentType) (values CveContents) {
44
	values = CveContents{}
45
	for ctype, content := range v {
46
		found := false
47
		for _, exceptCtype := range exceptCtypes {
48
			if ctype == exceptCtype {
49
				found = true
50
				break
51
			}
52
		}
53
		if !found {
54
			values[ctype] = content
55
		}
56
	}
57
	return
58
}
59
60
// SourceLinks returns link of source
61
func (v CveContents) SourceLinks(lang, myFamily, cveID string) (values []CveContentStr) {
62
	if lang == "ja" {
63
		if cont, found := v[Jvn]; found && 0 < len(cont.SourceLink) {
64
			values = append(values, CveContentStr{Jvn, cont.SourceLink})
65
		}
66
	}
67
68
	order := CveContentTypes{Nvd, NvdXML, NewCveContentType(myFamily)}
69
	for _, ctype := range order {
70
		if cont, found := v[ctype]; found {
71
			values = append(values, CveContentStr{ctype, cont.SourceLink})
72
		}
73
	}
74
75
	if len(values) == 0 {
76
		return []CveContentStr{{
77
			Type:  Nvd,
78
			Value: "https://nvd.nist.gov/vuln/detail/" + cveID,
79
		}}
80
	}
81
	return values
82
}
83
84
/*
85
// Severities returns Severities
86
func (v CveContents) Severities(myFamily string) (values []CveContentStr) {
87
	order := CveContentTypes{NVD, NewCveContentType(myFamily)}
88
	order = append(order, AllCveContetTypes.Except(append(order)...)...)
89
90
	for _, ctype := range order {
91
		if cont, found := v[ctype]; found && 0 < len(cont.Severity) {
92
			values = append(values, CveContentStr{
93
				Type:  ctype,
94
				Value: cont.Severity,
95
			})
96
		}
97
	}
98
	return
99
}
100
*/
101
102
// CveContentCpes has CveContentType and Value
103
type CveContentCpes struct {
104
	Type  CveContentType
105
	Value []Cpe
106
}
107
108
// Cpes returns affected CPEs of this Vulnerability
109
func (v CveContents) Cpes(myFamily string) (values []CveContentCpes) {
110
	order := CveContentTypes{NewCveContentType(myFamily)}
111
	order = append(order, AllCveContetTypes.Except(order...)...)
112
113
	for _, ctype := range order {
114
		if cont, found := v[ctype]; found && 0 < len(cont.Cpes) {
115
			values = append(values, CveContentCpes{
116
				Type:  ctype,
117
				Value: cont.Cpes,
118
			})
119
		}
120
	}
121
	return
122
}
123
124
// CveContentRefs has CveContentType and Cpes
125
type CveContentRefs struct {
126
	Type  CveContentType
127
	Value []Reference
128
}
129
130
// References returns References
131
func (v CveContents) References(myFamily string) (values []CveContentRefs) {
132
	order := CveContentTypes{NewCveContentType(myFamily)}
133
	order = append(order, AllCveContetTypes.Except(order...)...)
134
135
	for _, ctype := range order {
136
		if cont, found := v[ctype]; found && 0 < len(cont.References) {
137
			values = append(values, CveContentRefs{
138
				Type:  ctype,
139
				Value: cont.References,
140
			})
141
		}
142
	}
143
144
	return
145
}
146
147
// CweIDs returns related CweIDs of the vulnerability
148
func (v CveContents) CweIDs(myFamily string) (values []CveContentStr) {
149
	order := CveContentTypes{NewCveContentType(myFamily)}
150
	order = append(order, AllCveContetTypes.Except(order...)...)
151
	for _, ctype := range order {
152
		if cont, found := v[ctype]; found && 0 < len(cont.CweIDs) {
153
			for _, cweID := range cont.CweIDs {
154
				for _, val := range values {
155
					if val.Value == cweID {
156
						continue
157
					}
158
				}
159
				values = append(values, CveContentStr{
160
					Type:  ctype,
161
					Value: cweID,
162
				})
163
			}
164
		}
165
	}
166
	return
167
}
168
169
// UniqCweIDs returns Uniq CweIDs
170
func (v CveContents) UniqCweIDs(myFamily string) (values []CveContentStr) {
171
	uniq := map[string]CveContentStr{}
172
	for _, cwes := range v.CweIDs(myFamily) {
173
		uniq[cwes.Value] = cwes
174
	}
175
	for _, cwe := range uniq {
176
		values = append(values, cwe)
177
	}
178
	return values
179
}
180
181
// CveContent has abstraction of various vulnerability information
182
type CveContent struct {
183
	Type          CveContentType    `json:"type"`
184
	CveID         string            `json:"cveID"`
185
	Title         string            `json:"title"`
186
	Summary       string            `json:"summary"`
187
	Cvss2Score    float64           `json:"cvss2Score"`
188
	Cvss2Vector   string            `json:"cvss2Vector"`
189
	Cvss2Severity string            `json:"cvss2Severity"`
190
	Cvss3Score    float64           `json:"cvss3Score"`
191
	Cvss3Vector   string            `json:"cvss3Vector"`
192
	Cvss3Severity string            `json:"cvss3Severity"`
193
	SourceLink    string            `json:"sourceLink"`
194
	Cpes          []Cpe             `json:"cpes,omitempty"`
195
	References    References        `json:"references,omitempty"`
196
	CweIDs        []string          `json:"cweIDs,omitempty"`
197
	Published     time.Time         `json:"published"`
198
	LastModified  time.Time         `json:"lastModified"`
199
	Mitigation    string            `json:"mitigation"` // RedHat API
200
	Optional      map[string]string `json:"optional,omitempty"`
201
}
202
203
// Empty checks the content is empty
204
func (c CveContent) Empty() bool {
205
	return c.Summary == ""
206
}
207
208
// CveContentType is a source of CVE information
209
type CveContentType string
210
211
// NewCveContentType create CveContentType
212
func NewCveContentType(name string) CveContentType {
213
	switch name {
214
	case "nvdxml":
215
		return NvdXML
216
	case "nvd":
217
		return Nvd
218
	case "jvn":
219
		return Jvn
220
	case "redhat", "centos":
221
		return RedHat
222
	case "oracle":
223
		return Oracle
224
	case "ubuntu":
225
		return Ubuntu
226
	case "debian":
227
		return Debian
228
	case "redhat_api":
229
		return RedHatAPI
230
	case "debian_security_tracker":
231
		return DebianSecurityTracker
232
	case "microsoft":
233
		return Microsoft
234
	case "wordpress":
235
		return WPVulnDB
236
	default:
237
		return Unknown
238
	}
239
}
240
241
const (
242
	// NvdXML is NvdXML
243
	NvdXML CveContentType = "nvdxml"
244
245
	// Nvd is Nvd
246
	Nvd CveContentType = "nvd"
247
248
	// Jvn is Jvn
249
	Jvn CveContentType = "jvn"
250
251
	// RedHat is RedHat
252
	RedHat CveContentType = "redhat"
253
254
	// RedHatAPI is RedHat
255
	RedHatAPI CveContentType = "redhat_api"
256
257
	// DebianSecurityTracker is Debian Secury tracker
258
	DebianSecurityTracker CveContentType = "debian_security_tracker"
259
260
	// Debian is Debian
261
	Debian CveContentType = "debian"
262
263
	// Ubuntu is Ubuntu
264
	Ubuntu CveContentType = "ubuntu"
265
266
	// Oracle is Oracle Linux
267
	Oracle CveContentType = "oracle"
268
269
	// SUSE is SUSE Linux
270
	SUSE CveContentType = "suse"
271
272
	// Microsoft is Microsoft
273
	Microsoft CveContentType = "microsoft"
274
275
	// WPVulnDB is WordPress
276
	WPVulnDB CveContentType = "wpvulndb"
277
278
	// Unknown is Unknown
279
	Unknown CveContentType = "unknown"
280
)
281
282
// CveContentTypes has slide of CveContentType
283
type CveContentTypes []CveContentType
284
285
// AllCveContetTypes has all of CveContentTypes
286
var AllCveContetTypes = CveContentTypes{
287
	Nvd,
288
	NvdXML,
289
	Jvn,
290
	RedHat,
291
	Debian,
292
	Ubuntu,
293
	RedHatAPI,
294
	DebianSecurityTracker,
295
	WPVulnDB,
296
}
297
298
// Except returns CveContentTypes except for given args
299
func (c CveContentTypes) Except(excepts ...CveContentType) (excepted CveContentTypes) {
300
	for _, ctype := range c {
301
		found := false
302
		for _, except := range excepts {
303
			if ctype == except {
304
				found = true
305
				break
306
			}
307
		}
308
		if !found {
309
			excepted = append(excepted, ctype)
310
		}
311
	}
312
	return
313
}
314
315
// Cpe is Common Platform Enumeration
316
type Cpe struct {
317
	URI             string `json:"uri"`
318
	FormattedString string `json:"formattedString"`
319
}
320
321
// References is a slice of Reference
322
type References []Reference
323
324
// Reference has a related link of the CVE
325
type Reference struct {
326
	Source string `json:"source"`
327
	Link   string `json:"link"`
328
	RefID  string `json:"refID"`
329
}
330