2022-04-03 18:51:56 +00:00
|
|
|
package updater
|
|
|
|
|
|
|
|
import (
|
|
|
|
"archive/tar"
|
|
|
|
"archive/zip"
|
|
|
|
"bytes"
|
|
|
|
"compress/gzip"
|
|
|
|
"encoding/json"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"runtime"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/go-errors/errors"
|
|
|
|
"github.com/jpillora/overseer/fetcher"
|
|
|
|
|
2023-02-14 23:00:07 +00:00
|
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
|
2022-04-03 18:51:56 +00:00
|
|
|
"github.com/trufflesecurity/trufflehog/v3/pkg/version"
|
|
|
|
)
|
|
|
|
|
2024-08-13 15:50:36 +00:00
|
|
|
func Fetcher(cmd string, tui bool) fetcher.Interface {
|
|
|
|
return &OSS{Cmd: cmd, TUI: tui}
|
2022-04-03 18:51:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type OSS struct {
|
2024-06-05 17:07:50 +00:00
|
|
|
Interval time.Duration
|
2024-08-13 15:50:36 +00:00
|
|
|
Cmd string
|
2024-06-05 17:07:50 +00:00
|
|
|
TUI bool
|
|
|
|
Updated bool
|
2022-04-03 18:51:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Init validates the provided config
|
|
|
|
func (g *OSS) Init() error {
|
2022-08-30 16:41:12 +00:00
|
|
|
// initiate OSS connection
|
2022-04-03 18:51:56 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
const url = "https://oss.trufflehog.org/updates"
|
|
|
|
|
|
|
|
type FormData struct {
|
|
|
|
OS string
|
|
|
|
Arch string
|
|
|
|
CurrentVersion string
|
2024-08-13 15:50:36 +00:00
|
|
|
Cmd string
|
2024-06-05 17:07:50 +00:00
|
|
|
TUI bool
|
2022-04-03 18:51:56 +00:00
|
|
|
Timezone string
|
|
|
|
Binary string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fetch binary from URL via OSS client
|
|
|
|
func (g *OSS) Fetch() (io.Reader, error) {
|
2022-04-04 04:13:39 +00:00
|
|
|
if g.Updated {
|
|
|
|
select {} // block until exit
|
|
|
|
}
|
|
|
|
g.Updated = true
|
2022-04-03 18:51:56 +00:00
|
|
|
|
|
|
|
zone, _ := time.Now().Zone()
|
|
|
|
data := &FormData{
|
|
|
|
OS: runtime.GOOS,
|
|
|
|
Arch: runtime.GOARCH,
|
|
|
|
CurrentVersion: version.BuildVersion,
|
2024-08-13 15:50:36 +00:00
|
|
|
Cmd: g.Cmd,
|
2024-06-05 17:07:50 +00:00
|
|
|
TUI: g.TUI,
|
2022-04-03 18:51:56 +00:00
|
|
|
Timezone: zone,
|
|
|
|
Binary: "trufflehog",
|
|
|
|
}
|
|
|
|
|
|
|
|
dataByte, err := json.Marshal(data)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
reader := bytes.NewReader(dataByte)
|
|
|
|
resp, err := http.Post(url, "application/json", reader)
|
|
|
|
if err != nil || resp == nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
2022-04-04 04:13:39 +00:00
|
|
|
if resp.StatusCode == http.StatusNoContent {
|
2022-04-04 05:48:43 +00:00
|
|
|
return nil, errors.New("already up to date")
|
2022-04-04 04:13:39 +00:00
|
|
|
}
|
|
|
|
|
2023-02-14 23:00:07 +00:00
|
|
|
context.Background().Logger().V(2).Info("fetching trufflehog update")
|
2022-04-04 04:13:39 +00:00
|
|
|
|
2022-08-30 16:41:12 +00:00
|
|
|
newBinBytes, err := io.ReadAll(resp.Body)
|
2022-04-03 18:51:56 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer := bytes.NewReader(newBinBytes)
|
|
|
|
switch runtime.GOOS {
|
|
|
|
case "windows":
|
|
|
|
zipReader, err := zip.NewReader(buffer, int64(len(newBinBytes)))
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Errorf("Failed to read zip archive: %s", err)
|
|
|
|
}
|
|
|
|
for _, f := range zipReader.File {
|
|
|
|
if strings.HasPrefix(f.Name, "trufflehog") {
|
|
|
|
return f.Open()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
gzipReader, err := gzip.NewReader(buffer)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Errorf("Failed to read gzip archive: %s", err)
|
|
|
|
}
|
|
|
|
defer gzipReader.Close()
|
|
|
|
tarReader := tar.NewReader(gzipReader)
|
|
|
|
for {
|
|
|
|
header, err := tarReader.Next()
|
|
|
|
if err == io.EOF {
|
|
|
|
return nil, errors.New("unable to get update")
|
|
|
|
}
|
|
|
|
|
|
|
|
if header.Typeflag == tar.TypeReg {
|
|
|
|
if strings.HasPrefix(header.Name, "trufflehog") {
|
|
|
|
return tarReader, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, errors.New("unable to get update")
|
|
|
|
}
|