Skip to content

Commit

Permalink
Merge pull request #240 from gleentea/feature/report-xml
Browse files Browse the repository at this point in the history
Add the XML output
  • Loading branch information
kotakanbe authored Nov 7, 2016
2 parents f014f8f + ce2daf2 commit 159f261
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 23 deletions.
10 changes: 6 additions & 4 deletions README.ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
```
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
```
Expand Down
10 changes: 10 additions & 0 deletions commands/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type ScanCmd struct {
reportText bool
reportS3 bool
reportAzureBlob bool
reportXML bool

awsProfile string
awsS3Bucket string
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 16 additions & 16 deletions models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -322,17 +322,17 @@ 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
}

// 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
Expand Down
54 changes: 54 additions & 0 deletions report/xml.go
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 159f261

Please sign in to comment.