Completed
Push — master ( 76037c...7585f9 )
by kota
09:11 queued 01:58
created

report/db_client.go   A

Size/Duplication

Total Lines 185
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 36
eloc 124
dl 0
loc 185
rs 9.52
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
B report.NewExploitDB 0 23 6
A report.DBClient.CloseDB 0 9 5
B report.NewGostDB 0 23 6
B report.NewOvalDB 0 24 6
C report.NewDBClient 0 42 9
A report.NewCveDB 0 17 4
1
package report
2
3
import (
4
	"fmt"
5
	"os"
6
7
	"github.com/future-architect/vuls/config"
8
	"github.com/future-architect/vuls/util"
9
	gostdb "github.com/knqyf263/gost/db"
10
	cvedb "github.com/kotakanbe/go-cve-dictionary/db"
11
	ovaldb "github.com/kotakanbe/goval-dictionary/db"
12
	exploitdb "github.com/mozqnet/go-exploitdb/db"
13
)
14
15
// DBClient is a dictionarie's db client for reporting
16
type DBClient struct {
17
	CveDB     cvedb.DB
18
	OvalDB    ovaldb.DB
19
	GostDB    gostdb.DB
20
	ExploitDB exploitdb.DB
21
}
22
23
// DBClientConf has a configuration of Vulnerability DBs
24
type DBClientConf struct {
25
	CveDictCnf  config.GoCveDictConf
26
	OvalDictCnf config.GovalDictConf
27
	GostCnf     config.GostConf
28
	ExploitCnf  config.ExploitConf
29
	DebugSQL    bool
30
}
31
32
// NewDBClient returns db clients
33
func NewDBClient(cnf DBClientConf) (dbclient *DBClient, locked bool, err error) {
34
	cveDriver, locked, err := NewCveDB(cnf)
35
	if locked {
36
		return nil, true, fmt.Errorf("CveDB is locked: %s",
37
			cnf.OvalDictCnf.SQLite3Path)
38
	} else if err != nil {
39
		return nil, locked, err
40
	}
41
42
	ovaldb, locked, err := NewOvalDB(cnf)
43
	if locked {
44
		return nil, true, fmt.Errorf("OvalDB is locked: %s",
45
			cnf.OvalDictCnf.SQLite3Path)
46
	} else if err != nil {
47
		util.Log.Warnf("Unable to use OvalDB: %s, err: %s",
48
			cnf.OvalDictCnf.SQLite3Path, err)
49
	}
50
51
	gostdb, locked, err := NewGostDB(cnf)
52
	if locked {
53
		return nil, true, fmt.Errorf("gostDB is locked: %s",
54
			cnf.GostCnf.SQLite3Path)
55
	} else if err != nil {
56
		util.Log.Warnf("Unable to use gostDB: %s, err: %s",
57
			cnf.GostCnf.SQLite3Path, err)
58
	}
59
60
	exploitdb, locked, err := NewExploitDB(cnf)
61
	if locked {
62
		return nil, true, fmt.Errorf("exploitDB is locked: %s",
63
			cnf.ExploitCnf.SQLite3Path)
64
	} else if err != nil {
65
		util.Log.Warnf("Unable to use exploitDB: %s, err: %s",
66
			cnf.ExploitCnf.SQLite3Path, err)
67
	}
68
69
	return &DBClient{
70
		CveDB:     cveDriver,
71
		OvalDB:    ovaldb,
72
		GostDB:    gostdb,
73
		ExploitDB: exploitdb,
74
	}, false, nil
75
}
76
77
// NewCveDB returns cve db client
78
func NewCveDB(cnf DBClientConf) (driver cvedb.DB, locked bool, err error) {
79
	if config.Conf.CveDict.IsFetchViaHTTP() {
80
		return nil, false, nil
81
	}
82
	util.Log.Debugf("open cve-dictionary db (%s)", cnf.CveDictCnf.Type)
83
	path := cnf.CveDictCnf.URL
84
	if cnf.CveDictCnf.Type == "sqlite3" {
85
		path = cnf.CveDictCnf.SQLite3Path
86
	}
87
88
	util.Log.Debugf("Open cve-dictionary db (%s): %s", cnf.CveDictCnf.Type, path)
89
	driver, locked, err = cvedb.NewDB(cnf.CveDictCnf.Type, path, cnf.DebugSQL)
90
	if err != nil {
91
		err = fmt.Errorf("Failed to init CVE DB. err: %s, path: %s", err, path)
92
		return nil, locked, err
93
	}
94
	return driver, false, nil
95
}
96
97
// NewOvalDB returns oval db client
98
func NewOvalDB(cnf DBClientConf) (driver ovaldb.DB, locked bool, err error) {
99
	if config.Conf.OvalDict.IsFetchViaHTTP() {
100
		return nil, false, nil
101
	}
102
	path := cnf.OvalDictCnf.URL
103
	if cnf.OvalDictCnf.Type == "sqlite3" {
104
		path = cnf.OvalDictCnf.SQLite3Path
105
106
		if _, err := os.Stat(path); os.IsNotExist(err) {
107
			util.Log.Warnf("--ovaldb-path=%s is not found. It's recommended to use OVAL to improve scanning accuracy. For details, see https://github.com/kotakanbe/goval-dictionary#usage", path)
108
			return nil, false, nil
109
		}
110
	}
111
112
	util.Log.Debugf("Open oval-dictionary db (%s): %s", cnf.OvalDictCnf.Type, path)
113
	driver, locked, err = ovaldb.NewDB("", cnf.OvalDictCnf.Type, path, cnf.DebugSQL)
114
	if err != nil {
115
		err = fmt.Errorf("Failed to new OVAL DB. err: %s", err)
116
		if locked {
117
			return nil, true, err
118
		}
119
		return nil, false, err
120
	}
121
	return driver, false, nil
122
}
123
124
// NewGostDB returns db client for Gost
125
func NewGostDB(cnf DBClientConf) (driver gostdb.DB, locked bool, err error) {
126
	if config.Conf.Gost.IsFetchViaHTTP() {
127
		return nil, false, nil
128
	}
129
	path := cnf.GostCnf.URL
130
	if cnf.GostCnf.Type == "sqlite3" {
131
		path = cnf.GostCnf.SQLite3Path
132
133
		if _, err := os.Stat(path); os.IsNotExist(err) {
134
			util.Log.Warnf("--gostdb-path=%s is not found. If the scan target server is Debian, RHEL or CentOS, it's recommended to use gost to improve scanning accuracy. To use gost database, see https://github.com/knqyf263/gost#fetch-redhat", path)
135
			return nil, false, nil
136
		}
137
	}
138
139
	util.Log.Debugf("Open gost db (%s): %s", cnf.GostCnf.Type, path)
140
	if driver, locked, err = gostdb.NewDB(cnf.GostCnf.Type, path, cnf.DebugSQL); err != nil {
141
		if locked {
142
			util.Log.Errorf("gostDB is locked: %s", err)
143
			return nil, true, err
144
		}
145
		return nil, false, err
146
	}
147
	return driver, false, nil
148
}
149
150
// NewExploitDB returns db client for Exploit
151
func NewExploitDB(cnf DBClientConf) (driver exploitdb.DB, locked bool, err error) {
152
	if config.Conf.Exploit.IsFetchViaHTTP() {
153
		return nil, false, nil
154
	}
155
	path := cnf.ExploitCnf.URL
156
	if cnf.ExploitCnf.Type == "sqlite3" {
157
		path = cnf.ExploitCnf.SQLite3Path
158
159
		if _, err := os.Stat(path); os.IsNotExist(err) {
160
			util.Log.Warnf("--exploitdb-path=%s is not found. It's recommended to use exploit to improve scanning accuracy. To use exploit db database, see https://github.com/mozqnet/go-exploitdb", path)
161
			return nil, false, nil
162
		}
163
	}
164
165
	util.Log.Debugf("Open exploit db (%s): %s", cnf.ExploitCnf.Type, path)
166
	if driver, locked, err = exploitdb.NewDB(cnf.ExploitCnf.Type, path, cnf.DebugSQL); err != nil {
167
		if locked {
168
			util.Log.Errorf("exploitDB is locked: %s", err)
169
			return nil, true, err
170
		}
171
		return nil, false, err
172
	}
173
	return driver, false, nil
174
}
175
176
// CloseDB close dbs
177
func (d DBClient) CloseDB() {
178
	if d.CveDB != nil {
179
		if err := d.CveDB.CloseDB(); err != nil {
180
			util.Log.Errorf("Failed to close DB: %s", err)
181
		}
182
	}
183
	if d.OvalDB != nil {
184
		if err := d.OvalDB.CloseDB(); err != nil {
185
			util.Log.Errorf("Failed to close DB: %s", err)
186
		}
187
	}
188
}
189