Skip to content

Commit 5f7e4bc

Browse files
committed
Add -to-http option to report
1 parent ef2b523 commit 5f7e4bc

File tree

5 files changed

+53
-8
lines changed

5 files changed

+53
-8
lines changed

commands/report.go

+14
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type ReportCmd struct {
6767
toLocalFile bool
6868
toS3 bool
6969
toAzureBlob bool
70+
toHTTP string
7071

7172
formatJSON bool
7273
formatXML bool
@@ -118,6 +119,7 @@ func (*ReportCmd) Usage() string {
118119
[-ignore-unscored-cves]
119120
[-ignore-unfixed]
120121
[-to-email]
122+
[-to-http]
121123
[-to-slack]
122124
[-to-stride]
123125
[-to-hipchat]
@@ -287,6 +289,11 @@ func (p *ReportCmd) SetFlags(f *flag.FlagSet) {
287289
"to-s3",
288290
false,
289291
"Write report to S3 (bucket/yyyyMMdd_HHmm/servername.json/xml/txt)")
292+
f.StringVar(&p.toHTTP,
293+
"to-http",
294+
"",
295+
"http://vuls-server (default: empty)")
296+
290297
f.StringVar(&p.awsProfile, "aws-profile", "default", "AWS profile to use")
291298
f.StringVar(&p.awsRegion, "aws-region", "us-east-1", "AWS region to use")
292299
f.StringVar(&p.awsS3Bucket, "aws-s3-bucket", "", "S3 bucket name")
@@ -348,6 +355,7 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
348355
c.Conf.ToHipChat = p.toHipChat
349356
c.Conf.ToChatWork = p.toChatWork
350357
c.Conf.ToEmail = p.toEMail
358+
c.Conf.ToHTTP = p.toHTTP
351359
c.Conf.ToSyslog = p.toSyslog
352360
c.Conf.ToLocalFile = p.toLocalFile
353361
c.Conf.ToS3 = p.toS3
@@ -406,6 +414,12 @@ func (p *ReportCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}
406414
reports = append(reports, report.SyslogWriter{})
407415
}
408416

417+
if p.toHTTP != "" {
418+
reports = append(reports, report.HTTPRequestWriter{
419+
URL: p.toHTTP,
420+
})
421+
}
422+
409423
if p.toLocalFile {
410424
reports = append(reports, report.LocalFileWriter{
411425
CurrentDir: dir,

config/config.go

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ type Config struct {
144144
ToLocalFile bool
145145
ToS3 bool
146146
ToAzureBlob bool
147+
ToHTTP string
147148

148149
FormatXML bool
149150
FormatJSON bool

report/http.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,39 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
package report
1919

2020
import (
21+
"bytes"
2122
"encoding/json"
2223
"net/http"
2324

2425
"github.com/future-architect/vuls/models"
2526
"github.com/pkg/errors"
2627
)
2728

28-
// HTTPWriter writes results to S3
29-
type HTTPWriter struct {
29+
// HTTPRequestWriter writes results to HTTP request
30+
type HTTPRequestWriter struct {
31+
URL string
32+
}
33+
34+
// Write sends results as HTTP response
35+
func (w HTTPRequestWriter) Write(rs ...models.ScanResult) (err error) {
36+
for _, r := range rs {
37+
b := new(bytes.Buffer)
38+
json.NewEncoder(b).Encode(r)
39+
_, err = http.Post(w.URL, "application/json; charset=utf-8", b)
40+
if err != nil {
41+
return err
42+
}
43+
}
44+
return nil
45+
}
46+
47+
// HTTPResponseWriter writes results to HTTP response
48+
type HTTPResponseWriter struct {
3049
Writer http.ResponseWriter
3150
}
3251

3352
// Write sends results as HTTP response
34-
func (w HTTPWriter) Write(rs ...models.ScanResult) (err error) {
53+
func (w HTTPResponseWriter) Write(rs ...models.ScanResult) (err error) {
3554
res, err := json.Marshal(rs)
3655
if err != nil {
3756
return errors.Wrap(err, "Failed to marshal scah results")

scan/debian.go

-1
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@ func (o *debian) parseInstalledPackages(stdout string) (models.Packages, models.
375375
// openssh-server,ii ,1:6.7p1-5+deb8u3,openssh,1:6.7p1-5+deb8u3
376376
// tar,ii ,1.27.1-2+b1,tar (1.27.1-2),1.27.1-2
377377
lines := strings.Split(stdout, "\n")
378-
fmt.Println(lines)
379378
for _, line := range lines {
380379
if trimmed := strings.TrimSpace(line); len(trimmed) != 0 {
381380
name, status, version, srcName, srcVersion, err := o.parseScannedPackagesLine(trimmed)

server/server.go

+16-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"encoding/json"
2323
"fmt"
2424
"io"
25+
"mime"
2526
"net/http"
2627
"time"
2728

@@ -42,13 +43,20 @@ func (h VulsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
4243
result := models.ScanResult{ScannedCves: models.VulnInfos{}}
4344

4445
contentType := r.Header.Get("Content-Type")
45-
if contentType == "application/json" {
46+
mediatype, _, err := mime.ParseMediaType(contentType)
47+
if err != nil {
48+
util.Log.Error(err)
49+
http.Error(w, err.Error(), http.StatusBadRequest)
50+
return
51+
}
52+
53+
if mediatype == "application/json" {
4654
if err = json.NewDecoder(r.Body).Decode(&result); err != nil {
4755
util.Log.Error(err)
4856
http.Error(w, "Invalid JSON", http.StatusBadRequest)
4957
return
5058
}
51-
} else if contentType == "text/plain" {
59+
} else if mediatype == "text/plain" {
5260
buf := new(bytes.Buffer)
5361
io.Copy(buf, r.Body)
5462
if result, err = scan.ViaHTTP(r.Header, buf.String()); err != nil {
@@ -57,6 +65,7 @@ func (h VulsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
5765
return
5866
}
5967
} else {
68+
util.Log.Error(mediatype)
6069
http.Error(w, fmt.Sprintf("Invalid Content-Type: %s", contentType), http.StatusUnsupportedMediaType)
6170
return
6271
}
@@ -69,10 +78,13 @@ func (h VulsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
6978

7079
// report
7180
reports := []report.ResultWriter{
72-
report.HTTPWriter{Writer: w},
81+
report.HTTPResponseWriter{Writer: w},
7382
}
7483
if c.Conf.ToLocalFile {
75-
scannedAt := time.Now().Truncate(1 * time.Hour)
84+
scannedAt := result.ScannedAt
85+
if scannedAt.IsZero() {
86+
scannedAt = time.Now().Truncate(1 * time.Hour)
87+
}
7688
dir, err := scan.EnsureResultDir(scannedAt)
7789
if err != nil {
7890
util.Log.Errorf("Failed to ensure the result directory: %s", err)

0 commit comments

Comments
 (0)