feat(contrib/fvuls) Add commands to obtained CPE information of network devices by executing snmp2cpe and upload to Fvuls server (#1721)
* add: README.md * add: commands(discover,add-server,add-cpe) * add: implements(discover,add-server,add-cpe) * fix: changed os.Exit(1) in main.go to return an error * fix: lint error * delete: trivy-to-vuls stdIn * fix: Incomprehesible error logs * fix: according to review * add: function converts old config to latest one * delete: add-server * fix: lint error * fix * fix: remote scan error in Windows * fix: lint error * fix * fix: lint error * fix: lint error * fix: lint error * add: scanner/scanner.go test normalizeHomeDirForWindows() * fix * fix * fix * fix * fix * fix * fix: lint error * fix: error log * fix * refactor(fvuls) * Refactor (#2) refactor --------- Co-authored-by: 和田皓翔 <wadahiroka@192.168.0.6> * Refactor (#3) fix --------- Co-authored-by: Sadayuki Matsuno <sadayuki.matsuno@gmail.com> Co-authored-by: 和田皓翔 <wadahiroka@192.168.0.6> * fix * fix: lint error * fix --------- Co-authored-by: 和田皓翔 <wadahiroka@192.168.0.4> Co-authored-by: 和田皓翔 <wadahiroka@192.168.0.10> Co-authored-by: 和田皓翔 <wadahiroka@192.168.0.6> Co-authored-by: Sadayuki Matsuno <sadayuki.matsuno@gmail.com>
This commit is contained in:
23
contrib/future-vuls/pkg/config/config.go
Normal file
23
contrib/future-vuls/pkg/config/config.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Package config ...
|
||||
package config
|
||||
|
||||
const (
|
||||
DiscoverTomlFileName = "discover_list.toml"
|
||||
SnmpVersion = "v2c"
|
||||
FvulsDomain = "vuls.biz"
|
||||
DiscoverTomlTimeStampFormat = "20060102150405"
|
||||
)
|
||||
|
||||
// DiscoverToml ...
|
||||
type DiscoverToml map[string]ServerSetting
|
||||
|
||||
// ServerSetting ...
|
||||
type ServerSetting struct {
|
||||
IP string `toml:"ip"`
|
||||
ServerName string `toml:"server_name"`
|
||||
UUID string `toml:"uuid"`
|
||||
CpeURIs []string `toml:"cpe_uris"`
|
||||
FvulsSync bool `toml:"fvuls_sync"`
|
||||
// use internal
|
||||
NewCpeURIs []string `toml:"-"`
|
||||
}
|
||||
186
contrib/future-vuls/pkg/cpe/cpe.go
Normal file
186
contrib/future-vuls/pkg/cpe/cpe.go
Normal file
@@ -0,0 +1,186 @@
|
||||
// Package cpe ...
|
||||
package cpe
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/future-architect/vuls/contrib/future-vuls/pkg/config"
|
||||
"github.com/future-architect/vuls/contrib/future-vuls/pkg/fvuls"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// AddCpeConfig ...
|
||||
type AddCpeConfig struct {
|
||||
Token string
|
||||
Proxy string
|
||||
DiscoverTomlPath string
|
||||
OriginalDiscoverToml config.DiscoverToml
|
||||
}
|
||||
|
||||
// AddCpe ...
|
||||
func AddCpe(token, outputFile, proxy string) (err error) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
cpeConfig := &AddCpeConfig{
|
||||
Token: token,
|
||||
Proxy: proxy,
|
||||
DiscoverTomlPath: outputFile,
|
||||
}
|
||||
|
||||
var needAddServers, needAddCpes config.DiscoverToml
|
||||
if needAddServers, needAddCpes, err = cpeConfig.LoadAndCheckTomlFile(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if 0 < len(needAddServers) {
|
||||
addedServers := cpeConfig.AddServerToFvuls(ctx, needAddServers)
|
||||
if 0 < len(addedServers) {
|
||||
for name, server := range addedServers {
|
||||
needAddCpes[name] = server
|
||||
}
|
||||
}
|
||||
|
||||
// update discover toml
|
||||
for name, server := range needAddCpes {
|
||||
cpeConfig.OriginalDiscoverToml[name] = server
|
||||
}
|
||||
if err = cpeConfig.WriteDiscoverToml(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if 0 < len(needAddCpes) {
|
||||
var addedCpes config.DiscoverToml
|
||||
if addedCpes, err = cpeConfig.AddCpeToFvuls(ctx, needAddCpes); err != nil {
|
||||
return err
|
||||
}
|
||||
for name, server := range addedCpes {
|
||||
cpeConfig.OriginalDiscoverToml[name] = server
|
||||
}
|
||||
if err = cpeConfig.WriteDiscoverToml(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadAndCheckTomlFile ...
|
||||
func (c *AddCpeConfig) LoadAndCheckTomlFile(ctx context.Context) (needAddServers, needAddCpes config.DiscoverToml, err error) {
|
||||
var discoverToml config.DiscoverToml
|
||||
if _, err = toml.DecodeFile(c.DiscoverTomlPath, &discoverToml); err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to read discover toml: %s", c.DiscoverTomlPath)
|
||||
}
|
||||
c.OriginalDiscoverToml = discoverToml
|
||||
|
||||
needAddServers = make(map[string]config.ServerSetting)
|
||||
needAddCpes = make(map[string]config.ServerSetting)
|
||||
for name, setting := range discoverToml {
|
||||
if !setting.FvulsSync {
|
||||
continue
|
||||
}
|
||||
|
||||
if setting.UUID == "" {
|
||||
setting.NewCpeURIs = setting.CpeURIs
|
||||
needAddServers[name] = setting
|
||||
} else if 0 < len(setting.CpeURIs) {
|
||||
fvulsClient := fvuls.NewClient(c.Token, c.Proxy)
|
||||
var serverDetail fvuls.ServerDetailOutput
|
||||
if serverDetail, err = fvulsClient.GetServerByUUID(ctx, setting.UUID); err != nil {
|
||||
fmt.Printf("%s: Failed to Fetch serverID. err: %v\n", name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// update server name
|
||||
server := c.OriginalDiscoverToml[name]
|
||||
server.ServerName = serverDetail.ServerName
|
||||
c.OriginalDiscoverToml[name] = server
|
||||
|
||||
var uploadedCpes []string
|
||||
if uploadedCpes, err = fvulsClient.ListUploadedCPE(ctx, serverDetail.ServerID); err != nil {
|
||||
fmt.Printf("%s: Failed to Fetch uploaded CPE. err: %v\n", name, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// check if there are any CPEs that are not uploaded
|
||||
var newCpes []string
|
||||
for _, cpeURI := range setting.CpeURIs {
|
||||
if !slices.Contains(uploadedCpes, cpeURI) {
|
||||
newCpes = append(newCpes, cpeURI)
|
||||
}
|
||||
}
|
||||
if 0 < len(newCpes) {
|
||||
setting.NewCpeURIs = newCpes
|
||||
needAddCpes[name] = setting
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(needAddServers)+len(needAddCpes) == 0 {
|
||||
fmt.Printf("There are no hosts to add to Fvuls\n")
|
||||
return nil, nil, nil
|
||||
}
|
||||
return needAddServers, needAddCpes, nil
|
||||
}
|
||||
|
||||
// AddServerToFvuls ...
|
||||
func (c *AddCpeConfig) AddServerToFvuls(ctx context.Context, needAddServers map[string]config.ServerSetting) (addedServers config.DiscoverToml) {
|
||||
fmt.Printf("Creating %d pseudo server...\n", len(needAddServers))
|
||||
fvulsClient := fvuls.NewClient(c.Token, c.Proxy)
|
||||
addedServers = make(map[string]config.ServerSetting)
|
||||
for name, server := range needAddServers {
|
||||
var serverDetail fvuls.ServerDetailOutput
|
||||
serverDetail, err := fvulsClient.CreatePseudoServer(ctx, server.ServerName)
|
||||
if err != nil {
|
||||
fmt.Printf("%s: Failed to add to Fvuls server. err: %v\n", server.ServerName, err)
|
||||
continue
|
||||
}
|
||||
server.UUID = serverDetail.ServerUUID
|
||||
server.ServerName = serverDetail.ServerName
|
||||
addedServers[name] = server
|
||||
fmt.Printf("%s: Created FutureVuls pseudo server %s\n", server.ServerName, server.UUID)
|
||||
}
|
||||
return addedServers
|
||||
}
|
||||
|
||||
// AddCpeToFvuls ...
|
||||
func (c *AddCpeConfig) AddCpeToFvuls(ctx context.Context, needAddCpes config.DiscoverToml) (config.DiscoverToml, error) {
|
||||
fmt.Printf("Uploading %d server's CPE...\n", len(needAddCpes))
|
||||
fvulsClient := fvuls.NewClient(c.Token, c.Proxy)
|
||||
for name, server := range needAddCpes {
|
||||
serverDetail, err := fvulsClient.GetServerByUUID(ctx, server.UUID)
|
||||
server.ServerName = serverDetail.ServerName
|
||||
if err != nil {
|
||||
fmt.Printf("%s: Failed to Fetch serverID. err: %v\n", server.ServerName, err)
|
||||
continue
|
||||
}
|
||||
for _, cpeURI := range server.NewCpeURIs {
|
||||
if err = fvulsClient.UploadCPE(ctx, cpeURI, serverDetail.ServerID); err != nil {
|
||||
fmt.Printf("%s: Failed to upload CPE %s. err: %v\n", server.ServerName, cpeURI, err)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("%s: Uploaded CPE %s\n", server.ServerName, cpeURI)
|
||||
}
|
||||
needAddCpes[name] = server
|
||||
}
|
||||
return needAddCpes, nil
|
||||
}
|
||||
|
||||
// WriteDiscoverToml ...
|
||||
func (c *AddCpeConfig) WriteDiscoverToml() error {
|
||||
f, err := os.OpenFile(c.DiscoverTomlPath, os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open toml file. err: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
encoder := toml.NewEncoder(f)
|
||||
if err := encoder.Encode(c.OriginalDiscoverToml); err != nil {
|
||||
return fmt.Errorf("failed to write to %s. err: %v", c.DiscoverTomlPath, err)
|
||||
}
|
||||
fmt.Printf("wrote to %s\n\n", c.DiscoverTomlPath)
|
||||
return nil
|
||||
}
|
||||
127
contrib/future-vuls/pkg/discover/discover.go
Normal file
127
contrib/future-vuls/pkg/discover/discover.go
Normal file
@@ -0,0 +1,127 @@
|
||||
// Package discover ...
|
||||
package discover
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/future-architect/vuls/contrib/future-vuls/pkg/config"
|
||||
"github.com/kotakanbe/go-pingscanner"
|
||||
)
|
||||
|
||||
// ActiveHosts ...
|
||||
func ActiveHosts(cidr string, outputFile string, snmpVersion string) error {
|
||||
scanner := pingscanner.PingScanner{
|
||||
CIDR: cidr,
|
||||
PingOptions: []string{
|
||||
"-c1",
|
||||
},
|
||||
NumOfConcurrency: 100,
|
||||
}
|
||||
fmt.Printf("Discovering %s...\n", cidr)
|
||||
activeHosts, err := scanner.Scan()
|
||||
if err != nil {
|
||||
return fmt.Errorf("host Discovery failed. err: %v", err)
|
||||
}
|
||||
if len(activeHosts) == 0 {
|
||||
return fmt.Errorf("active hosts not found in %s", cidr)
|
||||
}
|
||||
|
||||
discoverToml := config.DiscoverToml{}
|
||||
if _, err := os.Stat(outputFile); err == nil {
|
||||
fmt.Printf("%s is found.\n", outputFile)
|
||||
if _, err = toml.DecodeFile(outputFile, &discoverToml); err != nil {
|
||||
return fmt.Errorf("failed to read discover toml: %s", outputFile)
|
||||
}
|
||||
}
|
||||
|
||||
servers := make(config.DiscoverToml)
|
||||
for _, activeHost := range activeHosts {
|
||||
cpes, err := executeSnmp2cpe(activeHost, snmpVersion)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to execute snmp2cpe. err: %v\n", err)
|
||||
continue
|
||||
}
|
||||
|
||||
fvulsSync := false
|
||||
serverUUID := ""
|
||||
serverName := activeHost
|
||||
if server, ok := discoverToml[activeHost]; ok {
|
||||
fvulsSync = server.FvulsSync
|
||||
serverUUID = server.UUID
|
||||
serverName = server.ServerName
|
||||
} else {
|
||||
fmt.Printf("New network device found %s\n", activeHost)
|
||||
}
|
||||
|
||||
servers[activeHost] = config.ServerSetting{
|
||||
IP: activeHost,
|
||||
ServerName: serverName,
|
||||
UUID: serverUUID,
|
||||
FvulsSync: fvulsSync,
|
||||
CpeURIs: cpes[activeHost],
|
||||
}
|
||||
}
|
||||
|
||||
for ip, setting := range discoverToml {
|
||||
if _, ok := servers[ip]; !ok {
|
||||
fmt.Printf("%s(%s) has been removed as there was no response.\n", setting.ServerName, setting.IP)
|
||||
}
|
||||
}
|
||||
if len(servers) == 0 {
|
||||
return fmt.Errorf("new network devices could not be found")
|
||||
}
|
||||
|
||||
if 0 < len(discoverToml) {
|
||||
fmt.Printf("Creating new %s and saving the old file under different name...\n", outputFile)
|
||||
timestamp := time.Now().Format(config.DiscoverTomlTimeStampFormat)
|
||||
oldDiscoverFile := fmt.Sprintf("%s_%s", timestamp, outputFile)
|
||||
if err := os.Rename(outputFile, oldDiscoverFile); err != nil {
|
||||
return fmt.Errorf("failed to rename exist toml file. err: %v", err)
|
||||
}
|
||||
fmt.Printf("You can check the difference from the previous DISCOVER with the following command.\n diff %s %s\n", outputFile, oldDiscoverFile)
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(outputFile, os.O_RDWR|os.O_CREATE, 0666)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open toml file. err: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
encoder := toml.NewEncoder(f)
|
||||
if err = encoder.Encode(servers); err != nil {
|
||||
return fmt.Errorf("failed to write to %s. err: %v", outputFile, err)
|
||||
}
|
||||
fmt.Printf("wrote to %s\n", outputFile)
|
||||
return nil
|
||||
}
|
||||
|
||||
func executeSnmp2cpe(addr string, snmpVersion string) (cpes map[string][]string, err error) {
|
||||
fmt.Printf("%s: Execute snmp2cpe...\n", addr)
|
||||
result, err := exec.Command("./snmp2cpe", snmpVersion, addr, "public").CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to execute snmp2cpe. err: %v", err)
|
||||
}
|
||||
cmd := exec.Command("./snmp2cpe", "convert")
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert snmp2cpe result. err: %v", err)
|
||||
}
|
||||
if _, err := io.WriteString(stdin, string(result)); err != nil {
|
||||
return nil, fmt.Errorf("failed to write to stdIn. err: %v", err)
|
||||
}
|
||||
stdin.Close()
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert snmp2cpe result. err: %v", err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(output, &cpes); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal snmp2cpe output. err: %v", err)
|
||||
}
|
||||
return cpes, nil
|
||||
}
|
||||
192
contrib/future-vuls/pkg/fvuls/fvuls.go
Normal file
192
contrib/future-vuls/pkg/fvuls/fvuls.go
Normal file
@@ -0,0 +1,192 @@
|
||||
// Package fvuls ...
|
||||
package fvuls
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/future-architect/vuls/config"
|
||||
"github.com/future-architect/vuls/models"
|
||||
"github.com/future-architect/vuls/saas"
|
||||
"github.com/future-architect/vuls/util"
|
||||
)
|
||||
|
||||
// Client ...
|
||||
type Client struct {
|
||||
Token string
|
||||
Proxy string
|
||||
FvulsScanEndpoint string
|
||||
FvulsRestEndpoint string
|
||||
}
|
||||
|
||||
// NewClient ...
|
||||
func NewClient(token string, proxy string) *Client {
|
||||
fvulsDomain := "vuls.biz"
|
||||
if domain := os.Getenv("VULS_DOMAIN"); 0 < len(domain) {
|
||||
fvulsDomain = domain
|
||||
}
|
||||
return &Client{
|
||||
Token: token,
|
||||
Proxy: proxy,
|
||||
FvulsScanEndpoint: fmt.Sprintf("https://auth.%s/one-time-auth", fvulsDomain),
|
||||
FvulsRestEndpoint: fmt.Sprintf("https://rest.%s/v1", fvulsDomain),
|
||||
}
|
||||
}
|
||||
|
||||
// UploadToFvuls ...
|
||||
func (f Client) UploadToFvuls(serverUUID string, groupID int64, tags []string, scanResultJSON []byte) error {
|
||||
var scanResult models.ScanResult
|
||||
if err := json.Unmarshal(scanResultJSON, &scanResult); err != nil {
|
||||
fmt.Printf("failed to parse json. err: %v\nPerhaps scan has failed. Please check following scan results.\nResult: %s", err, fmt.Sprintf("%s", scanResultJSON))
|
||||
return err
|
||||
}
|
||||
scanResult.ServerUUID = serverUUID
|
||||
if 0 < len(tags) {
|
||||
if scanResult.Optional == nil {
|
||||
scanResult.Optional = map[string]interface{}{}
|
||||
}
|
||||
scanResult.Optional["VULS_TAGS"] = tags
|
||||
}
|
||||
|
||||
config.Conf.Saas.GroupID = groupID
|
||||
config.Conf.Saas.Token = f.Token
|
||||
config.Conf.Saas.URL = f.FvulsScanEndpoint
|
||||
if err := (saas.Writer{}).Write(scanResult); err != nil {
|
||||
return fmt.Errorf("%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetServerByUUID ...
|
||||
func (f Client) GetServerByUUID(ctx context.Context, uuid string) (server ServerDetailOutput, err error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/server/uuid/%s", f.FvulsRestEndpoint, uuid), nil)
|
||||
if err != nil {
|
||||
return ServerDetailOutput{}, fmt.Errorf("failed to create request. err: %v", err)
|
||||
}
|
||||
t, err := f.sendHTTPRequest(req)
|
||||
if err != nil {
|
||||
return ServerDetailOutput{}, err
|
||||
}
|
||||
var serverDetail ServerDetailOutput
|
||||
if err := json.Unmarshal(t, &serverDetail); err != nil {
|
||||
if err.Error() == "invalid character 'A' looking for beginning of value" {
|
||||
return ServerDetailOutput{}, fmt.Errorf("invalid token")
|
||||
}
|
||||
return ServerDetailOutput{}, fmt.Errorf("failed to unmarshal serverDetail. err: %v", err)
|
||||
}
|
||||
return serverDetail, nil
|
||||
}
|
||||
|
||||
// CreatePseudoServer ...
|
||||
func (f Client) CreatePseudoServer(ctx context.Context, name string) (serverDetail ServerDetailOutput, err error) {
|
||||
payload := CreatePseudoServerInput{
|
||||
ServerName: name,
|
||||
}
|
||||
body, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return ServerDetailOutput{}, fmt.Errorf("failed to Marshal to JSON: %v", err)
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/server/pseudo", f.FvulsRestEndpoint), bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return ServerDetailOutput{}, fmt.Errorf("failed to create request: %v", err)
|
||||
}
|
||||
t, err := f.sendHTTPRequest(req)
|
||||
if err != nil {
|
||||
return ServerDetailOutput{}, err
|
||||
}
|
||||
if err := json.Unmarshal(t, &serverDetail); err != nil {
|
||||
if err.Error() == "invalid character 'A' looking for beginning of value" {
|
||||
return ServerDetailOutput{}, fmt.Errorf("invalid token")
|
||||
}
|
||||
return ServerDetailOutput{}, fmt.Errorf("failed to unmarshal serverDetail. err: %v", err)
|
||||
}
|
||||
return serverDetail, nil
|
||||
}
|
||||
|
||||
// UploadCPE ...
|
||||
func (f Client) UploadCPE(ctx context.Context, cpeURI string, serverID int64) (err error) {
|
||||
payload := AddCpeInput{
|
||||
ServerID: serverID,
|
||||
CpeName: cpeURI,
|
||||
IsURI: false,
|
||||
}
|
||||
body, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal JSON: %v", err)
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf("%s/pkgCpe/cpe", f.FvulsRestEndpoint), bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create request. err: %v", err)
|
||||
}
|
||||
t, err := f.sendHTTPRequest(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var cpeDetail AddCpeOutput
|
||||
if err := json.Unmarshal(t, &cpeDetail); err != nil {
|
||||
if err.Error() == "invalid character 'A' looking for beginning of value" {
|
||||
return fmt.Errorf("invalid token")
|
||||
}
|
||||
return fmt.Errorf("failed to unmarshal serverDetail. err: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListUploadedCPE ...
|
||||
func (f Client) ListUploadedCPE(ctx context.Context, serverID int64) (uploadedCPEs []string, err error) {
|
||||
page := 1
|
||||
for {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/pkgCpes?page=%d&limit=%d&filterServerID=%d", f.FvulsRestEndpoint, page, 200, serverID), nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request. err: %v", err)
|
||||
}
|
||||
t, err := f.sendHTTPRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var pkgCpes ListCpesOutput
|
||||
if err := json.Unmarshal(t, &pkgCpes); err != nil {
|
||||
if err.Error() == "invalid character 'A' looking for beginning of value" {
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
}
|
||||
return nil, fmt.Errorf("failed to unmarshal listCpesOutput. err: %v", err)
|
||||
}
|
||||
for _, pkgCpe := range pkgCpes.PkgCpes {
|
||||
uploadedCPEs = append(uploadedCPEs, pkgCpe.CpeFS)
|
||||
}
|
||||
|
||||
if pkgCpes.Paging.TotalPage <= page {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
return uploadedCPEs, nil
|
||||
}
|
||||
|
||||
func (f Client) sendHTTPRequest(req *http.Request) ([]byte, error) {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("Authorization", f.Token)
|
||||
client, err := util.GetHTTPClient(f.Proxy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v", err)
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to sent request. err: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("error response: %v", resp.StatusCode)
|
||||
}
|
||||
t, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response data. err: %v", err)
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
56
contrib/future-vuls/pkg/fvuls/model.go
Normal file
56
contrib/future-vuls/pkg/fvuls/model.go
Normal file
@@ -0,0 +1,56 @@
|
||||
// Package fvuls ...
|
||||
package fvuls
|
||||
|
||||
// CreatePseudoServerInput ...
|
||||
type CreatePseudoServerInput struct {
|
||||
ServerName string `json:"serverName"`
|
||||
}
|
||||
|
||||
// AddCpeInput ...
|
||||
type AddCpeInput struct {
|
||||
ServerID int64 `json:"serverID"`
|
||||
CpeName string `json:"cpeName"`
|
||||
IsURI bool `json:"isURI"`
|
||||
}
|
||||
|
||||
// AddCpeOutput ...
|
||||
type AddCpeOutput struct {
|
||||
Server ServerChild `json:"server"`
|
||||
}
|
||||
|
||||
// ListCpesInput ...
|
||||
type ListCpesInput struct {
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
ServerID int64 `json:"filterServerID"`
|
||||
}
|
||||
|
||||
// ListCpesOutput ...
|
||||
type ListCpesOutput struct {
|
||||
Paging Paging `json:"paging"`
|
||||
PkgCpes []PkgCpes `json:"pkgCpes"`
|
||||
}
|
||||
|
||||
// Paging ...
|
||||
type Paging struct {
|
||||
Page int `json:"page"`
|
||||
Limit int `json:"limit"`
|
||||
TotalPage int `json:"totalPage"`
|
||||
}
|
||||
|
||||
// PkgCpes ...
|
||||
type PkgCpes struct {
|
||||
CpeFS string `json:"cpeFS"`
|
||||
}
|
||||
|
||||
// ServerChild ...
|
||||
type ServerChild struct {
|
||||
ServerName string `json:"serverName"`
|
||||
}
|
||||
|
||||
// ServerDetailOutput ...
|
||||
type ServerDetailOutput struct {
|
||||
ServerID int64 `json:"id"`
|
||||
ServerName string `json:"serverName"`
|
||||
ServerUUID string `json:"serverUuid"`
|
||||
}
|
||||
Reference in New Issue
Block a user