commands/tui.go   A
last analyzed

Size/Duplication

Total Lines 231
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 22
eloc 139
dl 0
loc 231
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A commands.*TuiCmd.Name 0 1 1
A commands.*TuiCmd.Synopsis 0 1 1
A commands.*TuiCmd.Usage 0 2 1
B commands.*TuiCmd.SetFlags 0 56 1
F commands.*TuiCmd.Execute 0 105 18
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 commands
19
20
import (
21
	"context"
22
	"flag"
23
	"os"
24
	"path/filepath"
25
26
	c "github.com/future-architect/vuls/config"
27
	"github.com/future-architect/vuls/exploit"
28
	"github.com/future-architect/vuls/gost"
29
	"github.com/future-architect/vuls/models"
30
	"github.com/future-architect/vuls/oval"
31
	"github.com/future-architect/vuls/report"
32
	"github.com/future-architect/vuls/util"
33
	"github.com/google/subcommands"
34
	cvelog "github.com/kotakanbe/go-cve-dictionary/log"
35
)
36
37
// TuiCmd is Subcommand of host discovery mode
38
type TuiCmd struct {
39
	configPath  string
40
	cveDict     c.GoCveDictConf
41
	ovalDict    c.GovalDictConf
42
	gostConf    c.GostConf
43
	exploitConf c.ExploitConf
44
}
45
46
// Name return subcommand name
47
func (*TuiCmd) Name() string { return "tui" }
48
49
// Synopsis return synopsis
50
func (*TuiCmd) Synopsis() string { return "Run Tui view to analyze vulnerabilities" }
51
52
// Usage return usage
53
func (*TuiCmd) Usage() string {
54
	return `tui:
55
	tui
56
		[-refresh-cve]
57
		[-config=/path/to/config.toml]
58
		[-cvss-over=7]
59
		[-diff]
60
		[-ignore-unscored-cves]
61
		[-ignore-unfixed]
62
		[-results-dir=/path/to/results]
63
		[-log-dir=/path/to/log]
64
		[-debug]
65
		[-debug-sql]
66
		[-pipe]
67
		[-cvedb-type=sqlite3|mysql|postgres|redis|http]
68
		[-cvedb-sqlite3-path=/path/to/cve.sqlite3]
69
		[-cvedb-url=http://127.0.0.1:1323 or DB connection string]
70
		[-ovaldb-type=sqlite3|mysql|redis|http]
71
		[-ovaldb-sqlite3-path=/path/to/oval.sqlite3]
72
		[-ovaldb-url=http://127.0.0.1:1324 or DB connection string]
73
		[-gostdb-type=sqlite3|mysql|redis|http]
74
		[-gostdb-sqlite3-path=/path/to/gost.sqlite3]
75
		[-gostdb-url=http://127.0.0.1:1325 or DB connection string]
76
		[-exploitdb-type=sqlite3|mysql|redis|http]
77
		[-exploitdb-sqlite3-path=/path/to/exploitdb.sqlite3]
78
		[-exploitdb-url=http://127.0.0.1:1326 or DB connection string]
79
80
`
81
}
82
83
// SetFlags set flag
84
func (p *TuiCmd) SetFlags(f *flag.FlagSet) {
85
	//  f.StringVar(&p.lang, "lang", "en", "[en|ja]")
86
	f.BoolVar(&c.Conf.DebugSQL, "debug-sql", false, "debug SQL")
87
	f.BoolVar(&c.Conf.Debug, "debug", false, "debug mode")
88
89
	defaultLogDir := util.GetDefaultLogDir()
90
	f.StringVar(&c.Conf.LogDir, "log-dir", defaultLogDir, "/path/to/log")
91
92
	wd, _ := os.Getwd()
93
	defaultResultsDir := filepath.Join(wd, "results")
94
	f.StringVar(&c.Conf.ResultsDir, "results-dir", defaultResultsDir, "/path/to/results")
95
96
	defaultConfPath := filepath.Join(wd, "config.toml")
97
	f.StringVar(&p.configPath, "config", defaultConfPath, "/path/to/toml")
98
99
	f.BoolVar(&c.Conf.RefreshCve, "refresh-cve", false,
100
		"Refresh CVE information in JSON file under results dir")
101
102
	f.Float64Var(&c.Conf.CvssScoreOver, "cvss-over", 0,
103
		"-cvss-over=6.5 means reporting CVSS Score 6.5 and over (default: 0 (means report all))")
104
105
	f.BoolVar(&c.Conf.Diff, "diff", false,
106
		"Difference between previous result and current result ")
107
108
	f.BoolVar(
109
		&c.Conf.IgnoreUnscoredCves, "ignore-unscored-cves", false,
110
		"Don't report the unscored CVEs")
111
112
	f.BoolVar(&c.Conf.IgnoreUnfixed, "ignore-unfixed", false,
113
		"Don't report the unfixed CVEs")
114
115
	f.BoolVar(&c.Conf.Pipe, "pipe", false, "Use stdin via PIPE")
116
117
	f.StringVar(&p.cveDict.Type, "cvedb-type", "",
118
		"DB type of go-cve-dictionary (sqlite3, mysql, postgres or redis)")
119
	f.StringVar(&p.cveDict.SQLite3Path, "cvedb-path", "", "/path/to/sqlite3")
120
	f.StringVar(&p.cveDict.URL, "cvedb-url", "",
121
		"http://go-cve-dictionary.com:1323 or DB connection string")
122
123
	f.StringVar(&p.ovalDict.Type, "ovaldb-type", "",
124
		"DB type of goval-dictionary (sqlite3, mysql, postgres or redis)")
125
	f.StringVar(&p.ovalDict.SQLite3Path, "ovaldb-path", "", "/path/to/sqlite3")
126
	f.StringVar(&p.ovalDict.URL, "ovaldb-url", "",
127
		"http://goval-dictionary.com:1324 or DB connection string")
128
129
	f.StringVar(&p.gostConf.Type, "gostdb-type", "",
130
		"DB type of gost (sqlite3, mysql, postgres or redis)")
131
	f.StringVar(&p.gostConf.SQLite3Path, "gostdb-path", "", "/path/to/sqlite3")
132
	f.StringVar(&p.gostConf.URL, "gostdb-url", "",
133
		"http://gost.com:1325 or DB connection string")
134
135
	f.StringVar(&p.exploitConf.Type, "exploitdb-type", "",
136
		"DB type of exploit (sqlite3, mysql, postgres, redis or http)")
137
	f.StringVar(&p.exploitConf.SQLite3Path, "exploitdb-sqlite3-path", "", "/path/to/sqlite3")
138
	f.StringVar(&p.exploitConf.URL, "exploitdb-url", "",
139
		"http://exploit.com:1326 or DB connection string")
140
141
}
142
143
// Execute execute
144
func (p *TuiCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
145
	c.Conf.Lang = "en"
146
147
	// Setup Logger
148
	util.Log = util.NewCustomLogger(c.ServerInfo{})
149
	cvelog.SetLogger(c.Conf.LogDir, false, c.Conf.Debug, false)
150
151
	if err := c.Load(p.configPath, ""); err != nil {
152
		util.Log.Errorf("Error loading %s, err: %+v", p.configPath, err)
153
		return subcommands.ExitUsageError
154
	}
155
156
	c.Conf.CveDict.Overwrite(p.cveDict)
157
	c.Conf.OvalDict.Overwrite(p.ovalDict)
158
	c.Conf.Gost.Overwrite(p.gostConf)
159
	c.Conf.Exploit.Overwrite(p.exploitConf)
160
161
	var dir string
162
	var err error
163
	if c.Conf.Diff {
164
		dir, err = report.JSONDir([]string{})
165
	} else {
166
		dir, err = report.JSONDir(f.Args())
167
	}
168
	if err != nil {
169
		util.Log.Errorf("Failed to read from JSON. err: %+v", err)
170
		return subcommands.ExitFailure
171
	}
172
173
	util.Log.Info("Validating config...")
174
	if !c.Conf.ValidateOnTui() {
175
		return subcommands.ExitUsageError
176
	}
177
178
	var res models.ScanResults
179
	if res, err = report.LoadScanResults(dir); err != nil {
180
		util.Log.Error(err)
181
		return subcommands.ExitFailure
182
	}
183
	util.Log.Infof("Loaded: %s", dir)
184
185
	util.Log.Info("Validating db config...")
186
	if !c.Conf.ValidateOnReportDB() {
187
		return subcommands.ExitUsageError
188
	}
189
190
	if c.Conf.CveDict.URL != "" {
191
		if err := report.CveClient.CheckHealth(); err != nil {
192
			util.Log.Errorf("CVE HTTP server is not running. err: %+v", err)
193
			util.Log.Errorf("Run go-cve-dictionary as server mode before reporting or run with `-cvedb-type=sqlite3 -cvedb-sqlite3-path` option instead of -cvedb-url")
194
			return subcommands.ExitFailure
195
		}
196
	}
197
198
	if c.Conf.OvalDict.URL != "" {
199
		err := oval.Base{}.CheckHTTPHealth()
200
		if err != nil {
201
			util.Log.Errorf("OVAL HTTP server is not running. err: %+v", err)
202
			util.Log.Errorf("Run goval-dictionary as server mode before reporting or run with `-ovaldb-type=sqlite3 -ovaldb-sqlite3-path` option instead of -ovaldb-url")
203
			return subcommands.ExitFailure
204
		}
205
	}
206
207
	if c.Conf.Gost.URL != "" {
208
		util.Log.Infof("gost: %s", c.Conf.Gost.URL)
209
		err := gost.Base{}.CheckHTTPHealth()
210
		if err != nil {
211
			util.Log.Errorf("gost HTTP server is not running. err: %+v", err)
212
			util.Log.Errorf("Run gost as server mode before reporting or run with `-gostdb-type=sqlite3 -gostdb-sqlite3-path` option instead of -gostdb-url")
213
			return subcommands.ExitFailure
214
		}
215
	}
216
217
	if c.Conf.Exploit.URL != "" {
218
		err := exploit.CheckHTTPHealth()
219
		if err != nil {
220
			util.Log.Errorf("exploit HTTP server is not running. err: %+v", err)
221
			util.Log.Errorf("Run go-exploitdb as server mode before reporting")
222
			return subcommands.ExitFailure
223
		}
224
	}
225
	dbclient, locked, err := report.NewDBClient(report.DBClientConf{
226
		CveDictCnf:  c.Conf.CveDict,
227
		OvalDictCnf: c.Conf.OvalDict,
228
		GostCnf:     c.Conf.Gost,
229
		ExploitCnf:  c.Conf.Exploit,
230
		DebugSQL:    c.Conf.DebugSQL,
231
	})
232
	if locked {
233
		util.Log.Errorf("SQLite3 is locked. Close other DB connections and try again: %+v", err)
234
		return subcommands.ExitFailure
235
	}
236
237
	if err != nil {
238
		util.Log.Errorf("Failed to init DB Clients. err: %+v", err)
239
		return subcommands.ExitFailure
240
	}
241
242
	defer dbclient.CloseDB()
243
244
	if res, err = report.FillCveInfos(*dbclient, res, dir); err != nil {
245
		util.Log.Error(err)
246
		return subcommands.ExitFailure
247
	}
248
	return report.RunTui(res)
249
}
250