add xml-report

add struct tag for encoding/xml

update README

update glide.lock
This commit is contained in:
gleentea
2016-11-01 16:06:02 +09:00
parent f014f8fd59
commit ce2daf2493
6 changed files with 92 additions and 23 deletions

View File

@@ -157,7 +157,7 @@ $ sudo chmod 700 /var/log/vuls
$
$ mkdir -p $GOPATH/src/github.com/kotakanbe
$ cd $GOPATH/src/github.com/kotakanbe
$ git https://github.com/kotakanbe/go-cve-dictionary.git
$ git clone https://github.com/kotakanbe/go-cve-dictionary.git
$ cd go-cve-dictionary
$ make install
```
@@ -620,6 +620,7 @@ scan:
[-report-s3]
[-report-slack]
[-report-text]
[-report-xml]
[-http-proxy=http://192.168.0.1:8080]
[-ask-key-password]
[-debug]
@@ -681,6 +682,8 @@ scan:
Send report via Slack
-report-text
Write report to text files ($PWD/results/current)
-report-xml
Write report to XML files ($PWDresults/current)
-results-dir string
/path/to/results (default "$PWD/results")
-ssh-external
@@ -708,11 +711,10 @@ Defaults:vuls !requiretty
| empty password | - | |
| with password | required | or use ssh-agent |
## -report-json , -report-text option
## -report-json , -report-text , -report-xml option
結果をファイルに出力したい場合に指定する。出力先は、`$PWD/result/current/`
`all.(json|txt)`には、サーバのスキャン結果が出力される。
`servername.(json|txt)`には、サーバごとのスキャン結果が出力される。
`servername.(json|txt|xml)`には、サーバごとのスキャン結果が出力される。
## Example: Scan all servers defined in config file
```

View File

@@ -627,6 +627,7 @@ scan:
[-report-s3]
[-report-slack]
[-report-text]
[-report-xml]
[-http-proxy=http://192.168.0.1:8080]
[-ask-key-password]
[-debug]
@@ -688,6 +689,8 @@ scan:
Send report via Slack
-report-text
Write report to text files ($PWD/results/current)
-report-xml
Write report to XML files ($PWDresults/current)
-results-dir string
/path/to/results (default "$PWD/results")
-ssh-external
@@ -716,10 +719,10 @@ Defaults:vuls !requiretty
| empty password | - | |
| with password | required | or use ssh-agent |
## -report-json , -report-text option
## -report-json , -report-text , -report-xml option
At the end of the scan, scan results will be available in the `$PWD/result/current/` directory.
`all.(json|txt)` includes the scan results of all servers and `servername.(json|txt)` includes the scan result of the server.
`servername.(json|txt|xml)` includes the scan result of the server.
## Example: Scan all servers defined in config file
```

View File

@@ -67,6 +67,7 @@ type ScanCmd struct {
reportText bool
reportS3 bool
reportAzureBlob bool
reportXML bool
awsProfile string
awsS3Bucket string
@@ -106,6 +107,7 @@ func (*ScanCmd) Usage() string {
[-report-s3]
[-report-slack]
[-report-text]
[-report-xml]
[-http-proxy=http://192.168.0.1:8080]
[-ask-key-password]
[-debug]
@@ -204,6 +206,11 @@ func (p *ScanCmd) SetFlags(f *flag.FlagSet) {
false,
fmt.Sprintf("Write report to text files (%s/results/current)", wd),
)
f.BoolVar(&p.reportXML,
"report-xml",
false,
fmt.Sprintf("Write report to XML files (%s/results/current)", wd),
)
f.BoolVar(&p.reportS3,
"report-s3",
@@ -333,6 +340,9 @@ func (p *ScanCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
if p.reportText {
reports = append(reports, report.TextFileWriter{ScannedAt: scannedAt})
}
if p.reportXML {
reports = append(reports, report.XMLWriter{ScannedAt: scannedAt})
}
if p.reportS3 {
c.Conf.AwsRegion = p.awsRegion
c.Conf.AwsProfile = p.awsProfile

2
glide.lock generated
View File

@@ -69,7 +69,7 @@ imports:
- name: github.com/k0kubun/pp
version: f5dce6ed0ccf6c350f1679964ff6b61f3d6d2033
- name: github.com/kotakanbe/go-cve-dictionary
version: d0d8b0d3eee8022395d37edd95e88af7f5f970ad
version: 70989b6709c3102924ad8c8483e9bdc99bcb598b
subpackages:
- config
- db

View File

@@ -72,8 +72,8 @@ func (s ScanResults) FilterByCvssOver() (filtered ScanResults) {
// ScanResult has the result of scanned CVE information.
type ScanResult struct {
gorm.Model `json:"-"`
ScanHistoryID uint `json:"-"`
gorm.Model `json:"-" xml:"-"`
ScanHistoryID uint `json:"-" xml:"-"`
ScannedAt time.Time
ServerName string // TOML Section key
@@ -167,8 +167,8 @@ func (r ScanResult) CveSummary() string {
// NWLink has network link information.
type NWLink struct {
gorm.Model `json:"-"`
ScanResultID uint `json:"-"`
gorm.Model `json:"-" xml:"-"`
ScanResultID uint `json:"-" xml:"-"`
IPAddress string
Netmask string
@@ -197,8 +197,8 @@ func (c CveInfos) Less(i, j int) bool {
// CveInfo has Cve Information.
type CveInfo struct {
gorm.Model `json:"-"`
ScanResultID uint `json:"-"`
gorm.Model `json:"-" xml:"-"`
ScanResultID uint `json:"-" xml:"-"`
CveDetail cve.CveDetail
Packages []PackageInfo
@@ -208,8 +208,8 @@ type CveInfo struct {
// CpeName has CPE name
type CpeName struct {
gorm.Model `json:"-"`
CveInfoID uint `json:"-"`
gorm.Model `json:"-" xml:"-"`
CveInfoID uint `json:"-" xml:"-"`
Name string
}
@@ -274,8 +274,8 @@ func (ps PackageInfoList) FindByName(name string) (result PackageInfo, found boo
// PackageInfo has installed packages.
type PackageInfo struct {
gorm.Model `json:"-"`
CveInfoID uint `json:"-"`
gorm.Model `json:"-" xml:"-"`
CveInfoID uint `json:"-" xml:"-"`
Name string
Version string
@@ -311,8 +311,8 @@ func (p PackageInfo) ToStringNewVersion() string {
// DistroAdvisory has Amazon Linux, RHEL, FreeBSD Security Advisory information.
type DistroAdvisory struct {
gorm.Model `json:"-"`
CveInfoID uint `json:"-"`
gorm.Model `json:"-" xml:"-"`
CveInfoID uint `json:"-" xml:"-"`
AdvisoryID string
Severity string
@@ -322,8 +322,8 @@ type DistroAdvisory struct {
// Container has Container information
type Container struct {
gorm.Model `json:"-"`
ScanResultID uint `json:"-"`
gorm.Model `json:"-" xml:"-"`
ScanResultID uint `json:"-" xml:"-"`
ContainerID string
Name string
@@ -331,8 +331,8 @@ type Container struct {
// Platform has platform information
type Platform struct {
gorm.Model `json:"-"`
ScanResultID uint `json:"-"`
gorm.Model `json:"-" xml:"-"`
ScanResultID uint `json:"-" xml:"-"`
Name string // aws or azure or gcp or other...
InstanceID string

54
report/xml.go Normal file
View File

@@ -0,0 +1,54 @@
package report
import (
"bytes"
"encoding/xml"
"fmt"
"io/ioutil"
"path/filepath"
"time"
"github.com/future-architect/vuls/models"
)
const (
vulsOpenTag = "<vulsreport>"
vulsCloseTag = "</vulsreport>"
)
// XMLWriter writes results to file.
type XMLWriter struct {
ScannedAt time.Time
}
func (w XMLWriter) Write(scanResults []models.ScanResult) (err error) {
var path string
if path, err = ensureResultDir(w.ScannedAt); err != nil {
return fmt.Errorf("Failed to make direcotory/symlink : %s", err)
}
for _, scanResult := range scanResults {
scanResult.ScannedAt = w.ScannedAt
}
var xmlBytes []byte
for _, r := range scanResults {
xmlPath := ""
if len(r.Container.ContainerID) == 0 {
xmlPath = filepath.Join(path, fmt.Sprintf("%s.xml", r.ServerName))
} else {
xmlPath = filepath.Join(path,
fmt.Sprintf("%s_%s.xml", r.ServerName, r.Container.Name))
}
if xmlBytes, err = xml.Marshal(r); err != nil {
return fmt.Errorf("Failed to Marshal to XML: %s", err)
}
allBytes := bytes.Join([][]byte{[]byte(xml.Header + vulsOpenTag), xmlBytes, []byte(vulsCloseTag)}, []byte{})
if err := ioutil.WriteFile(xmlPath, allBytes, 0600); err != nil {
return fmt.Errorf("Failed to write XML. path: %s, err: %s", xmlPath, err)
}
}
return nil
}