From a5549fb50064303ad663e43f6072271179536155 Mon Sep 17 00:00:00 2001 From: hirokazu yamada Date: Tue, 31 May 2016 01:05:02 +0900 Subject: [PATCH] Add option for it get cve detail from cve.sqlite3. It is an error in go-cve-dictionary API when result of scan is many. --- commands/scan.go | 5 +++++ config/config.go | 8 ++++++++ cveapi/cve_client.go | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/commands/scan.go b/commands/scan.go index 08f949be..6c75b101 100644 --- a/commands/scan.go +++ b/commands/scan.go @@ -43,6 +43,7 @@ type ScanCmd struct { configPath string dbpath string + cvedbpath string cveDictionaryURL string cvssScoreOver float64 @@ -76,6 +77,7 @@ func (*ScanCmd) Usage() string { [-lang=en|ja] [-config=/path/to/config.toml] [-dbpath=/path/to/vuls.sqlite3] + [-cvedbpath=/path/to/cve.sqlite3] [-cve-dictionary-url=http://127.0.0.1:1323] [-cvss-over=7] [-ignore-unscored-cves] @@ -105,6 +107,8 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) { defaultDBPath := filepath.Join(wd, "vuls.sqlite3") f.StringVar(&p.dbpath, "dbpath", defaultDBPath, "/path/to/sqlite3") + f.StringVar(&p.cvedbpath, "cvedbpath", "", "/path/to/sqlite3 (For get cve detail from cve.sqlite3)") + defaultURL := "http://127.0.0.1:1323" f.StringVar( &p.cveDictionaryURL, @@ -245,6 +249,7 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) } c.Conf.DBPath = p.dbpath + c.Conf.CveDBPath = p.cvedbpath c.Conf.CveDictionaryURL = p.cveDictionaryURL c.Conf.CvssScoreOver = p.cvssScoreOver c.Conf.IgnoreUnscoredCves = p.ignoreUnscoredCves diff --git a/config/config.go b/config/config.go index 6f956294..c481c700 100644 --- a/config/config.go +++ b/config/config.go @@ -46,6 +46,7 @@ type Config struct { HTTPProxy string `valid:"url"` DBPath string + CveDBPath string // CpeNames []string // SummaryMode bool UseYumPluginSecurity bool @@ -63,6 +64,13 @@ func (c Config) Validate() bool { } } + if len(c.CveDBPath) != 0 { + if ok, _ := valid.IsFilePath(c.CveDBPath); !ok { + errs = append(errs, fmt.Errorf( + "SQLite3 DB(Cve Doctionary) path must be a *Absolute* file path. dbpath: %s", c.CveDBPath)) + } + } + _, err := valid.ValidateStruct(c) if err != nil { errs = append(errs, err) diff --git a/cveapi/cve_client.go b/cveapi/cve_client.go index 991bf635..76031a13 100644 --- a/cveapi/cve_client.go +++ b/cveapi/cve_client.go @@ -30,6 +30,8 @@ import ( log "github.com/Sirupsen/logrus" "github.com/future-architect/vuls/config" "github.com/future-architect/vuls/util" + cveconfig "github.com/kotakanbe/go-cve-dictionary/config" + cvedb "github.com/kotakanbe/go-cve-dictionary/db" cve "github.com/kotakanbe/go-cve-dictionary/models" ) @@ -46,6 +48,11 @@ func (api *cvedictClient) initialize() { } func (api cvedictClient) CheckHealth() (ok bool, err error) { + if config.Conf.CveDBPath != "" { + log.Debugf("get cve-dictionary from sqlite3") + return true, nil + } + api.initialize() url := fmt.Sprintf("%s/health", api.baseURL) var errs []error @@ -67,6 +74,10 @@ type response struct { } func (api cvedictClient) FetchCveDetails(cveIDs []string) (cveDetails cve.CveDetails, err error) { + if config.Conf.CveDBPath != "" { + return api.FetchCveDetailsFromCveDB(cveIDs) + } + api.baseURL = config.Conf.CveDictionaryURL reqChan := make(chan string, len(cveIDs)) resChan := make(chan response, len(cveIDs)) @@ -126,6 +137,32 @@ func (api cvedictClient) FetchCveDetails(cveIDs []string) (cveDetails cve.CveDet return } +func (api cvedictClient) FetchCveDetailsFromCveDB(cveIDs []string) (cveDetails cve.CveDetails, err error) { + + cveconfig.Conf.DBPath = config.Conf.CveDBPath + + log.Debugf("open cve-dictionary db") + if err := cvedb.OpenDB(); err != nil { + return []cve.CveDetail{}, + fmt.Errorf("go-cve-dictionary:OpenDB Error: %v", err) + } + for _, cveID := range cveIDs { + cveDetail := cvedb.Get(cveID) + if len(cveDetail.CveID) == 0 { + cveDetails = append(cveDetails, cve.CveDetail{ + CveID: cveID, + }) + } else { + cveDetails = append(cveDetails, cveDetail) + } + } + + // order by CVE ID desc + sort.Sort(cveDetails) + return + +} + func (api cvedictClient) httpGet(key, url string, resChan chan<- response, errChan chan<- error) { var body string var errs []error