add xml-report
add struct tag for encoding/xml update README update glide.lock
This commit is contained in:
10
README.ja.md
10
README.ja.md
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
2
glide.lock
generated
@@ -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
|
||||
|
||||
@@ -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
54
report/xml.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user