refactor: don't use global Config in private func (#1197)
* refactor: cve_client.go * refactor: don't use global Config in private func * remove import alias for config * refactor: dbclient * refactor: resultDir * refactor: resultsDir * refactor * refactor: gost * refactor: db client * refactor: cveDB * refactor: cvedb * refactor: exploitDB * refactor: remove detector/dbclient.go * refactor: writer * refactor: syslog writer * refactor: ips * refactor: ensureResultDir * refactor: proxy * fix(db): call CloseDB * add integration test * feat(report): sort array in json * sort func for json diff * add build-int to makefile * add int-rds-redis to makefile * fix: test case, makefile * fix makefile * show cve count after diff * make diff * diff -c * sort exploits in json for diff * sort metasploit, exploit
This commit is contained in:
		@@ -9,7 +9,7 @@ import (
 | 
			
		||||
	storage "github.com/Azure/azure-sdk-for-go/storage"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
 | 
			
		||||
	c "github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -21,7 +21,7 @@ type AzureBlobWriter struct {
 | 
			
		||||
	FormatList        bool
 | 
			
		||||
	Gzip              bool
 | 
			
		||||
 | 
			
		||||
	c.AzureConf
 | 
			
		||||
	config.AzureConf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write results to Azure Blob storage
 | 
			
		||||
 
 | 
			
		||||
@@ -15,14 +15,16 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ChatWorkWriter send report to ChatWork
 | 
			
		||||
type ChatWorkWriter struct{}
 | 
			
		||||
type ChatWorkWriter struct {
 | 
			
		||||
	Cnf   config.ChatWorkConf
 | 
			
		||||
	Proxy string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w ChatWorkWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
	conf := config.Conf.ChatWork
 | 
			
		||||
 | 
			
		||||
	for _, r := range rs {
 | 
			
		||||
		serverInfo := fmt.Sprintf("%s", r.ServerInfo())
 | 
			
		||||
		if err = chatWorkpostMessage(conf.Room, conf.APIToken, serverInfo); err != nil {
 | 
			
		||||
		if err = w.chatWorkpostMessage(serverInfo); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -40,7 +42,7 @@ func (w ChatWorkWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
				severity,
 | 
			
		||||
				vinfo.Summaries(r.Lang, r.Family)[0].Value)
 | 
			
		||||
 | 
			
		||||
			if err = chatWorkpostMessage(conf.Room, conf.APIToken, message); err != nil {
 | 
			
		||||
			if err = w.chatWorkpostMessage(message); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -49,8 +51,8 @@ func (w ChatWorkWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func chatWorkpostMessage(room, token, message string) error {
 | 
			
		||||
	uri := fmt.Sprintf("https://api.chatwork.com/v2/rooms/%s/messages=%s", room, token)
 | 
			
		||||
func (w ChatWorkWriter) chatWorkpostMessage(message string) error {
 | 
			
		||||
	uri := fmt.Sprintf("https://api.chatwork.com/v2/rooms/%s/messages=%s", w.Cnf.Room, w.Cnf.APIToken)
 | 
			
		||||
	payload := url.Values{"body": {message}}
 | 
			
		||||
 | 
			
		||||
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 | 
			
		||||
@@ -59,10 +61,9 @@ func chatWorkpostMessage(room, token, message string) error {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	req.Header.Add("X-ChatWorkToken", token)
 | 
			
		||||
	req.Header.Add("X-ChatWorkToken", w.Cnf.APIToken)
 | 
			
		||||
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
 | 
			
		||||
 | 
			
		||||
	client, err := util.GetHTTPClient(config.Conf.HTTPProxy)
 | 
			
		||||
	client, err := util.GetHTTPClient(w.Proxy)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,12 +20,12 @@ type EMailWriter struct {
 | 
			
		||||
	FormatOneEMail    bool
 | 
			
		||||
	FormatOneLineText bool
 | 
			
		||||
	FormatList        bool
 | 
			
		||||
	Cnf               config.SMTPConf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w EMailWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
	conf := config.Conf
 | 
			
		||||
	var message string
 | 
			
		||||
	sender := NewEMailSender()
 | 
			
		||||
	sender := NewEMailSender(w.Cnf)
 | 
			
		||||
	m := map[string]int{}
 | 
			
		||||
	for _, r := range rs {
 | 
			
		||||
		if w.FormatOneEMail {
 | 
			
		||||
@@ -39,10 +39,10 @@ func (w EMailWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
			var subject string
 | 
			
		||||
			if len(r.Errors) != 0 {
 | 
			
		||||
				subject = fmt.Sprintf("%s%s An error occurred while scanning",
 | 
			
		||||
					conf.EMail.SubjectPrefix, r.ServerInfo())
 | 
			
		||||
					w.Cnf.SubjectPrefix, r.ServerInfo())
 | 
			
		||||
			} else {
 | 
			
		||||
				subject = fmt.Sprintf("%s%s %s",
 | 
			
		||||
					conf.EMail.SubjectPrefix,
 | 
			
		||||
					w.Cnf.SubjectPrefix,
 | 
			
		||||
					r.ServerInfo(),
 | 
			
		||||
					r.ScannedCves.FormatCveSummary())
 | 
			
		||||
			}
 | 
			
		||||
@@ -72,7 +72,7 @@ func (w EMailWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		subject := fmt.Sprintf("%s %s",
 | 
			
		||||
			conf.EMail.SubjectPrefix, summary)
 | 
			
		||||
			w.Cnf.SubjectPrefix, summary)
 | 
			
		||||
		return sender.Send(subject, message)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
@@ -196,8 +196,8 @@ func (e *emailSender) Send(subject, body string) (err error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewEMailSender creates emailSender
 | 
			
		||||
func NewEMailSender() EMailSender {
 | 
			
		||||
	return &emailSender{config.Conf.EMail}
 | 
			
		||||
func NewEMailSender(cnf config.SMTPConf) EMailSender {
 | 
			
		||||
	return &emailSender{cnf}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *emailSender) newSaslClient(authList []string) sasl.Client {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,13 +5,14 @@ import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// HTTPRequestWriter writes results to HTTP request
 | 
			
		||||
type HTTPRequestWriter struct{}
 | 
			
		||||
type HTTPRequestWriter struct {
 | 
			
		||||
	Proxy string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write sends results as HTTP response
 | 
			
		||||
func (w HTTPRequestWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
@@ -20,7 +21,7 @@ func (w HTTPRequestWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
		if err := json.NewEncoder(b).Encode(r); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		_, err = http.Post(config.Conf.HTTP.URL, "application/json; charset=utf-8", b)
 | 
			
		||||
		_, err = http.Post(w.Proxy, "application/json; charset=utf-8", b)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,8 +35,9 @@ func (w LocalFileWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, r := range rs {
 | 
			
		||||
		path := filepath.Join(w.CurrentDir, r.ReportFileName())
 | 
			
		||||
		r.SortForJSONOutput()
 | 
			
		||||
 | 
			
		||||
		path := filepath.Join(w.CurrentDir, r.ReportFileName())
 | 
			
		||||
		if w.FormatJSON {
 | 
			
		||||
			p := path + ".json"
 | 
			
		||||
			if w.DiffPlus || w.DiffMinus {
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ import (
 | 
			
		||||
	"github.com/aws/aws-sdk-go/service/s3"
 | 
			
		||||
	"golang.org/x/xerrors"
 | 
			
		||||
 | 
			
		||||
	c "github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/config"
 | 
			
		||||
	"github.com/future-architect/vuls/models"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -27,7 +27,7 @@ type S3Writer struct {
 | 
			
		||||
	FormatList        bool
 | 
			
		||||
	Gzip              bool
 | 
			
		||||
 | 
			
		||||
	c.AWSConf
 | 
			
		||||
	config.AWSConf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w S3Writer) getS3() (*s3.S3, error) {
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,8 @@ type SlackWriter struct {
 | 
			
		||||
	FormatOneLineText bool
 | 
			
		||||
	lang              string
 | 
			
		||||
	osFamily          string
 | 
			
		||||
	Cnf               config.SlackConf
 | 
			
		||||
	Proxy             string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type message struct {
 | 
			
		||||
@@ -32,10 +34,8 @@ type message struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w SlackWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
	conf := config.Conf.Slack
 | 
			
		||||
	channel := conf.Channel
 | 
			
		||||
	token := conf.LegacyToken
 | 
			
		||||
 | 
			
		||||
	channel := w.Cnf.Channel
 | 
			
		||||
	for _, r := range rs {
 | 
			
		||||
		w.lang, w.osFamily = r.Lang, r.Family
 | 
			
		||||
		if channel == "${servername}" {
 | 
			
		||||
@@ -57,15 +57,15 @@ func (w SlackWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
		sort.Ints(chunkKeys)
 | 
			
		||||
 | 
			
		||||
		summary := fmt.Sprintf("%s\n%s",
 | 
			
		||||
			w.getNotifyUsers(config.Conf.Slack.NotifyUsers),
 | 
			
		||||
			w.getNotifyUsers(w.Cnf.NotifyUsers),
 | 
			
		||||
			formatOneLineSummary(r))
 | 
			
		||||
 | 
			
		||||
		// Send slack by API
 | 
			
		||||
		if 0 < len(token) {
 | 
			
		||||
			api := slack.New(token)
 | 
			
		||||
		if 0 < len(w.Cnf.LegacyToken) {
 | 
			
		||||
			api := slack.New(w.Cnf.LegacyToken)
 | 
			
		||||
			msgPrms := slack.PostMessageParameters{
 | 
			
		||||
				Username:  conf.AuthUser,
 | 
			
		||||
				IconEmoji: conf.IconEmoji,
 | 
			
		||||
				Username:  w.Cnf.AuthUser,
 | 
			
		||||
				IconEmoji: w.Cnf.IconEmoji,
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var ts string
 | 
			
		||||
@@ -83,8 +83,8 @@ func (w SlackWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
 | 
			
		||||
			for _, k := range chunkKeys {
 | 
			
		||||
				params := slack.PostMessageParameters{
 | 
			
		||||
					Username:        conf.AuthUser,
 | 
			
		||||
					IconEmoji:       conf.IconEmoji,
 | 
			
		||||
					Username:        w.Cnf.AuthUser,
 | 
			
		||||
					IconEmoji:       w.Cnf.IconEmoji,
 | 
			
		||||
					ThreadTimestamp: ts,
 | 
			
		||||
				}
 | 
			
		||||
				if _, _, err = api.PostMessage(
 | 
			
		||||
@@ -99,8 +99,8 @@ func (w SlackWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
		} else {
 | 
			
		||||
			msg := message{
 | 
			
		||||
				Text:      summary,
 | 
			
		||||
				Username:  conf.AuthUser,
 | 
			
		||||
				IconEmoji: conf.IconEmoji,
 | 
			
		||||
				Username:  w.Cnf.AuthUser,
 | 
			
		||||
				IconEmoji: w.Cnf.IconEmoji,
 | 
			
		||||
				Channel:   channel,
 | 
			
		||||
			}
 | 
			
		||||
			if err := w.send(msg); err != nil {
 | 
			
		||||
@@ -119,8 +119,8 @@ func (w SlackWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
 | 
			
		||||
				msg := message{
 | 
			
		||||
					Text:        txt,
 | 
			
		||||
					Username:    conf.AuthUser,
 | 
			
		||||
					IconEmoji:   conf.IconEmoji,
 | 
			
		||||
					Username:    w.Cnf.AuthUser,
 | 
			
		||||
					IconEmoji:   w.Cnf.IconEmoji,
 | 
			
		||||
					Channel:     channel,
 | 
			
		||||
					Attachments: m[k],
 | 
			
		||||
				}
 | 
			
		||||
@@ -134,14 +134,13 @@ func (w SlackWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w SlackWriter) send(msg message) error {
 | 
			
		||||
	conf := config.Conf.Slack
 | 
			
		||||
	count, retryMax := 0, 10
 | 
			
		||||
 | 
			
		||||
	count, retryMax := 0, 10
 | 
			
		||||
	bytes, _ := json.Marshal(msg)
 | 
			
		||||
	jsonBody := string(bytes)
 | 
			
		||||
 | 
			
		||||
	f := func() (err error) {
 | 
			
		||||
		resp, body, errs := gorequest.New().Timeout(10 * time.Second).Proxy(config.Conf.HTTPProxy).Post(conf.HookURL).Send(string(jsonBody)).End()
 | 
			
		||||
		resp, body, errs := gorequest.New().Timeout(10 * time.Second).Proxy(w.Proxy).Post(w.Cnf.HookURL).Send(string(jsonBody)).End()
 | 
			
		||||
		if 0 < len(errs) || resp == nil || resp.StatusCode != 200 {
 | 
			
		||||
			count++
 | 
			
		||||
			if count == retryMax {
 | 
			
		||||
@@ -149,7 +148,7 @@ func (w SlackWriter) send(msg message) error {
 | 
			
		||||
			}
 | 
			
		||||
			return xerrors.Errorf(
 | 
			
		||||
				"HTTP POST error. url: %s, resp: %v, body: %s, err: %+v",
 | 
			
		||||
				conf.HookURL, resp, body, errs)
 | 
			
		||||
				w.Cnf.HookURL, resp, body, errs)
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,15 +12,16 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SyslogWriter send report to syslog
 | 
			
		||||
type SyslogWriter struct{}
 | 
			
		||||
type SyslogWriter struct {
 | 
			
		||||
	Cnf config.SyslogConf
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w SyslogWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
	conf := config.Conf.Syslog
 | 
			
		||||
	facility, _ := conf.GetFacility()
 | 
			
		||||
	severity, _ := conf.GetSeverity()
 | 
			
		||||
	raddr := fmt.Sprintf("%s:%s", conf.Host, conf.Port)
 | 
			
		||||
	facility, _ := w.Cnf.GetFacility()
 | 
			
		||||
	severity, _ := w.Cnf.GetSeverity()
 | 
			
		||||
	raddr := fmt.Sprintf("%s:%s", w.Cnf.Host, w.Cnf.Port)
 | 
			
		||||
 | 
			
		||||
	sysLog, err := syslog.Dial(conf.Protocol, raddr, severity|facility, conf.Tag)
 | 
			
		||||
	sysLog, err := syslog.Dial(w.Cnf.Protocol, raddr, severity|facility, w.Cnf.Tag)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return xerrors.Errorf("Failed to initialize syslog client: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -72,7 +73,7 @@ func (w SyslogWriter) encodeSyslog(result models.ScanResult) (messages []string)
 | 
			
		||||
		if content, ok := vinfo.CveContents[models.Nvd]; ok {
 | 
			
		||||
			cwes := strings.Join(content.CweIDs, ",")
 | 
			
		||||
			kvPairs = append(kvPairs, fmt.Sprintf(`cwe_ids="%s"`, cwes))
 | 
			
		||||
			if config.Conf.Syslog.Verbose {
 | 
			
		||||
			if w.Cnf.Verbose {
 | 
			
		||||
				kvPairs = append(kvPairs, fmt.Sprintf(`source_link="%s"`, content.SourceLink))
 | 
			
		||||
				kvPairs = append(kvPairs, fmt.Sprintf(`summary="%s"`, content.Summary))
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,10 +16,12 @@ import (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TelegramWriter sends report to Telegram
 | 
			
		||||
type TelegramWriter struct{}
 | 
			
		||||
type TelegramWriter struct {
 | 
			
		||||
	Cnf   config.TelegramConf
 | 
			
		||||
	Proxy string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w TelegramWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
	conf := config.Conf.Telegram
 | 
			
		||||
	for _, r := range rs {
 | 
			
		||||
		msgs := []string{fmt.Sprintf("*%s*\n%s\n%s\n%s",
 | 
			
		||||
			r.ServerInfo(),
 | 
			
		||||
@@ -40,14 +42,14 @@ func (w TelegramWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
				maxCvss.Value.Vector,
 | 
			
		||||
				vinfo.Summaries(r.Lang, r.Family)[0].Value))
 | 
			
		||||
			if len(msgs) == 5 {
 | 
			
		||||
				if err = sendMessage(conf.ChatID, conf.Token, strings.Join(msgs, "\n\n")); err != nil {
 | 
			
		||||
				if err = w.sendMessage(w.Cnf.ChatID, w.Cnf.Token, strings.Join(msgs, "\n\n")); err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				msgs = []string{}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if len(msgs) != 0 {
 | 
			
		||||
			if err = sendMessage(conf.ChatID, conf.Token, strings.Join(msgs, "\n\n")); err != nil {
 | 
			
		||||
			if err = w.sendMessage(w.Cnf.ChatID, w.Cnf.Token, strings.Join(msgs, "\n\n")); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
@@ -55,7 +57,7 @@ func (w TelegramWriter) Write(rs ...models.ScanResult) (err error) {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sendMessage(chatID, token, message string) error {
 | 
			
		||||
func (w TelegramWriter) sendMessage(chatID, token, message string) error {
 | 
			
		||||
	uri := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", token)
 | 
			
		||||
	payload := `{"text": "` + strings.Replace(message, `"`, `\"`, -1) + `", "chat_id": "` + chatID + `", "parse_mode": "Markdown" }`
 | 
			
		||||
 | 
			
		||||
@@ -67,7 +69,7 @@ func sendMessage(chatID, token, message string) error {
 | 
			
		||||
	}
 | 
			
		||||
	req.Header.Add("Content-Type", "application/json")
 | 
			
		||||
 | 
			
		||||
	client, err := util.GetHTTPClient(config.Conf.HTTPProxy)
 | 
			
		||||
	client, err := util.GetHTTPClient(w.Proxy)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -85,16 +85,15 @@ var jsonDirPattern = regexp.MustCompile(
 | 
			
		||||
 | 
			
		||||
// ListValidJSONDirs returns valid json directory as array
 | 
			
		||||
// Returned array is sorted so that recent directories are at the head
 | 
			
		||||
func ListValidJSONDirs() (dirs []string, err error) {
 | 
			
		||||
func ListValidJSONDirs(resultsDir string) (dirs []string, err error) {
 | 
			
		||||
	var dirInfo []os.FileInfo
 | 
			
		||||
	if dirInfo, err = ioutil.ReadDir(config.Conf.ResultsDir); err != nil {
 | 
			
		||||
		err = xerrors.Errorf("Failed to read %s: %w",
 | 
			
		||||
			config.Conf.ResultsDir, err)
 | 
			
		||||
	if dirInfo, err = ioutil.ReadDir(resultsDir); err != nil {
 | 
			
		||||
		err = xerrors.Errorf("Failed to read %s: %w", resultsDir, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	for _, d := range dirInfo {
 | 
			
		||||
		if d.IsDir() && jsonDirPattern.MatchString(d.Name()) {
 | 
			
		||||
			jsonDir := filepath.Join(config.Conf.ResultsDir, d.Name())
 | 
			
		||||
			jsonDir := filepath.Join(resultsDir, d.Name())
 | 
			
		||||
			dirs = append(dirs, jsonDir)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -105,19 +104,17 @@ func ListValidJSONDirs() (dirs []string, err error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// JSONDir returns
 | 
			
		||||
// If there is an arg, check if it is a valid format and return the corresponding path under results.
 | 
			
		||||
// If there is args, check if it is a valid format and return the corresponding path under results.
 | 
			
		||||
// If arg passed via PIPE (such as history subcommand), return that path.
 | 
			
		||||
// Otherwise, returns the path of the latest directory
 | 
			
		||||
func JSONDir(args []string) (string, error) {
 | 
			
		||||
	var err error
 | 
			
		||||
func JSONDir(resultsDir string, args []string) (path string, err error) {
 | 
			
		||||
	var dirs []string
 | 
			
		||||
 | 
			
		||||
	if 0 < len(args) {
 | 
			
		||||
		if dirs, err = ListValidJSONDirs(); err != nil {
 | 
			
		||||
		if dirs, err = ListValidJSONDirs(resultsDir); err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		path := filepath.Join(config.Conf.ResultsDir, args[0])
 | 
			
		||||
		path = filepath.Join(resultsDir, args[0])
 | 
			
		||||
		for _, d := range dirs {
 | 
			
		||||
			ss := strings.Split(d, string(os.PathSeparator))
 | 
			
		||||
			timedir := ss[len(ss)-1]
 | 
			
		||||
@@ -125,11 +122,10 @@ func JSONDir(args []string) (string, error) {
 | 
			
		||||
				return path, nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return "", xerrors.Errorf("Invalid path: %s", path)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// PIPE
 | 
			
		||||
	// TODO remove Pipe flag
 | 
			
		||||
	if config.Conf.Pipe {
 | 
			
		||||
		bytes, err := ioutil.ReadAll(os.Stdin)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
@@ -137,18 +133,17 @@ func JSONDir(args []string) (string, error) {
 | 
			
		||||
		}
 | 
			
		||||
		fields := strings.Fields(string(bytes))
 | 
			
		||||
		if 0 < len(fields) {
 | 
			
		||||
			return filepath.Join(config.Conf.ResultsDir, fields[0]), nil
 | 
			
		||||
			return filepath.Join(resultsDir, fields[0]), nil
 | 
			
		||||
		}
 | 
			
		||||
		return "", xerrors.Errorf("Stdin is invalid: %s", string(bytes))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// returns latest dir when no args or no PIPE
 | 
			
		||||
	if dirs, err = ListValidJSONDirs(); err != nil {
 | 
			
		||||
	if dirs, err = ListValidJSONDirs(resultsDir); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	if len(dirs) == 0 {
 | 
			
		||||
		return "", xerrors.Errorf("No results under %s",
 | 
			
		||||
			config.Conf.ResultsDir)
 | 
			
		||||
		return "", xerrors.Errorf("No results under %s", resultsDir)
 | 
			
		||||
	}
 | 
			
		||||
	return dirs[0], nil
 | 
			
		||||
}
 | 
			
		||||
@@ -224,6 +219,7 @@ func formatOneLineSummary(rs ...models.ScanResult) string {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// We don't want warning message to the summary file
 | 
			
		||||
	// TODO Don't use global variable
 | 
			
		||||
	if config.Conf.Quiet {
 | 
			
		||||
		return fmt.Sprintf("%s\n", table)
 | 
			
		||||
	}
 | 
			
		||||
@@ -483,7 +479,7 @@ No CVE-IDs are found in updatable packages.
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, alert := range vuln.AlertDict.En {
 | 
			
		||||
			data = append(data, []string{"USCERT Alert", alert.URL})
 | 
			
		||||
			data = append(data, []string{"US-CERT Alert", alert.URL})
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// for _, rr := range vuln.CveContents.References(r.Family) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user