diff --git a/dev-tools/mage/crossbuild.go b/dev-tools/mage/crossbuild.go index 22b0ae574df8..4340c7fdb4ea 100644 --- a/dev-tools/mage/crossbuild.go +++ b/dev-tools/mage/crossbuild.go @@ -267,6 +267,7 @@ func (b GolangCrossBuilder) Build() error { "--env", "MAGEFILE_VERBOSE="+verbose, "--env", "MAGEFILE_TIMEOUT="+EnvOr("MAGEFILE_TIMEOUT", ""), "--env", fmt.Sprintf("SNAPSHOT=%v", Snapshot), + "--env", fmt.Sprintf("DEV=%v", DevBuild), "-v", repoInfo.RootDir+":"+mountPoint, "-w", workDir, image, diff --git a/dev-tools/mage/settings.go b/dev-tools/mage/settings.go index 08a619c3df34..037d4838d035 100644 --- a/dev-tools/mage/settings.go +++ b/dev-tools/mage/settings.go @@ -77,6 +77,7 @@ var ( BeatProjectType ProjectType Snapshot bool + DevBuild bool versionQualified bool versionQualifier string @@ -117,6 +118,11 @@ func init() { panic(errors.Wrap(err, "failed to parse SNAPSHOT env value")) } + DevBuild, err = strconv.ParseBool(EnvOr("DEV", "false")) + if err != nil { + panic(errors.Wrap(err, "failed to parse DEV env value")) + } + versionQualifier, versionQualified = os.LookupEnv("VERSION_QUALIFIER") } @@ -165,6 +171,7 @@ func varMap(args ...map[string]interface{}) map[string]interface{} { "BeatURL": BeatURL, "BeatUser": BeatUser, "Snapshot": Snapshot, + "DEV": DevBuild, "Qualifier": versionQualifier, } diff --git a/x-pack/elastic-agent/GPG-KEY-elasticsearch b/x-pack/elastic-agent/GPG-KEY-elasticsearch new file mode 100644 index 000000000000..1b50dcca799a --- /dev/null +++ b/x-pack/elastic-agent/GPG-KEY-elasticsearch @@ -0,0 +1,31 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.14 (GNU/Linux) + +mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD +A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9 +CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ +j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd +1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD +2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg +KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy +Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC +F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75 +nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/ +7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm +TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe +8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/ +eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl +zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT +RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+ +1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+ +Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt +KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww +EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0 +c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J +TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j +6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7 +vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM +cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/ +qPDlGRlOgVTd9xUfHFkzB52c70E= +=92oX +-----END PGP PUBLIC KEY BLOCK----- diff --git a/x-pack/elastic-agent/dev-tools/cmd/buildpgp/build_pgp.go b/x-pack/elastic-agent/dev-tools/cmd/buildpgp/build_pgp.go new file mode 100644 index 000000000000..55bb33f1fc0d --- /dev/null +++ b/x-pack/elastic-agent/dev-tools/cmd/buildpgp/build_pgp.go @@ -0,0 +1,113 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +package main + +import ( + "bytes" + "flag" + "fmt" + "go/format" + "io/ioutil" + "os" + "text/template" + + "github.com/elastic/beats/v7/licenses" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/packer" +) + +var ( + input string + output string + license string +) + +func init() { + flag.StringVar(&input, "in", "", "Source of input. \"-\" means reading from stdin") + flag.StringVar(&output, "out", "-", "Output path. \"-\" means writing to stdout") + flag.StringVar(&license, "license", "Elastic", "License header for generated file.") +} + +var tmplPgp = template.Must(template.New("pgp").Parse(` +{{ .License }} +// Code generated by x-pack/dev-tools/cmd/buildspec/buildPgp.go - DO NOT EDIT. + +package release + +import ( + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/packer" +) + +// pgp bytes is a packed in public gpg key +var pgpBytes []byte + +func init() { + // Packed Files + {{ range $i, $f := .Files -}} + // {{ $f }} + {{ end -}} + pgpBytes = packer.MustUnpack("{{ .Pack }}")["GPG-KEY-elasticsearch"] +} + +// PGP return pgpbytes and a flag describing whether or not no pgp is valid. +func PGP() (bool, []byte) { + return allowEmptyPgp == "true", pgpBytes +} +`)) + +func main() { + flag.Parse() + + if len(input) == 0 { + fmt.Fprintln(os.Stderr, "Invalid input source") + os.Exit(1) + } + + l, err := licenses.Find(license) + if err != nil { + fmt.Fprintf(os.Stderr, "problem to retrieve the license, error: %+v", err) + os.Exit(1) + return + } + + data, err := gen(input, l) + if err != nil { + fmt.Fprintf(os.Stderr, "Error while generating the file, err: %+v\n", err) + os.Exit(1) + } + + if output == "-" { + os.Stdout.Write(data) + return + } else { + ioutil.WriteFile(output, data, 0640) + } + + return +} + +func gen(path string, l string) ([]byte, error) { + pack, files, err := packer.Pack(input) + if err != nil { + return nil, err + } + + var buf bytes.Buffer + tmplPgp.Execute(&buf, struct { + Pack string + Files []string + License string + }{ + Pack: pack, + Files: files, + License: l, + }) + + formatted, err := format.Source(buf.Bytes()) + if err != nil { + return nil, err + } + + return formatted, nil +} diff --git a/x-pack/elastic-agent/magefile.go b/x-pack/elastic-agent/magefile.go index 499e1d251a22..ec6e76a0995a 100644 --- a/x-pack/elastic-agent/magefile.go +++ b/x-pack/elastic-agent/magefile.go @@ -14,6 +14,7 @@ import ( "os/exec" "path/filepath" "runtime" + "strconv" "strings" "time" @@ -40,6 +41,7 @@ const ( buildDir = "build" metaDir = "_meta" snapshotEnv = "SNAPSHOT" + devEnv = "DEV" configFile = "elastic-agent.yml" agentDropPath = "AGENT_DROP_PATH" ) @@ -345,7 +347,7 @@ func commitID() string { // Update is an alias for executing control protocol, configs, and specs. func Update() { - mg.SerialDeps(Config, BuildSpec, BuildFleetCfg) + mg.SerialDeps(Config, BuildSpec, BuildPGP, BuildFleetCfg) } // CrossBuild cross-builds the beat for all target platforms. @@ -370,7 +372,7 @@ func ControlProto() error { // BuildSpec make sure that all the suppported program spec are built into the binary. func BuildSpec() error { - // go run x-pack/agent/dev-tools/cmd/buildspec/buildspec.go --in x-pack/agent/spec/*.yml --out x-pack/agent/pkg/agent/program/supported.go + // go run x-pack/elastic-agent/dev-tools/cmd/buildspec/buildspec.go --in x-pack/agent/spec/*.yml --out x-pack/elastic-agent/pkg/agent/program/supported.go goF := filepath.Join("dev-tools", "cmd", "buildspec", "buildspec.go") in := filepath.Join("spec", "*.yml") out := filepath.Join("pkg", "agent", "program", "supported.go") @@ -379,6 +381,16 @@ func BuildSpec() error { return RunGo("run", goF, "--in", in, "--out", out) } +func BuildPGP() error { + // go run x-pack/elastic-agent/dev-tools/cmd/buildpgp/build_pgp.go --in x-pack/agent/spec/GPG-KEY-elasticsearch --out x-pack/elastic-agent/pkg/release/pgp.go + goF := filepath.Join("dev-tools", "cmd", "buildpgp", "build_pgp.go") + in := "GPG-KEY-elasticsearch" + out := filepath.Join("pkg", "release", "pgp.go") + + fmt.Printf(">> BuildPGP from %s to %s\n", in, out) + return RunGo("run", goF, "--in", in, "--out", out) +} + func configYML() error { return devtools.Config(devtools.AllConfigTypes, ConfigFileParams(), ".") } @@ -620,6 +632,12 @@ func buildVars() map[string]string { isSnapshot, _ := os.LookupEnv(snapshotEnv) vars["github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/release.snapshot"] = isSnapshot + if isDevFlag, devFound := os.LookupEnv(devEnv); devFound { + if isDev, err := strconv.ParseBool(isDevFlag); err == nil && isDev { + vars["github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/release.allowEmptyPgp"] = "true" + } + } + return vars } diff --git a/x-pack/elastic-agent/pkg/agent/application/stream.go b/x-pack/elastic-agent/pkg/agent/application/stream.go index ee2b1f2d0197..41999fcb8329 100644 --- a/x-pack/elastic-agent/pkg/agent/application/stream.go +++ b/x-pack/elastic-agent/pkg/agent/application/stream.go @@ -19,6 +19,7 @@ import ( "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/monitoring" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/server" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/core/state" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/release" ) type operatorStream struct { @@ -56,7 +57,8 @@ func streamFactory(ctx context.Context, cfg *configuration.SettingsConfig, srv * func newOperator(ctx context.Context, log *logger.Logger, id routingKey, config *configuration.SettingsConfig, srv *server.Server, r state.Reporter, m monitoring.Monitor) (*operation.Operator, error) { fetcher := downloader.NewDownloader(log, config.DownloadConfig) - verifier, err := downloader.NewVerifier(log, config.DownloadConfig) + allowEmptyPgp, pgp := release.PGP() + verifier, err := downloader.NewVerifier(log, config.DownloadConfig, allowEmptyPgp, pgp) if err != nil { return nil, errors.New(err, "initiating verifier") } diff --git a/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go b/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go index 9bcb941d7e99..28e93949fbf4 100644 --- a/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go +++ b/x-pack/elastic-agent/pkg/agent/application/upgrade/step_download.go @@ -9,6 +9,7 @@ import ( "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" downloader "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact/download/localremote" + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/release" ) func (u *Upgrader) downloadArtifact(ctx context.Context, version, sourceURI string) (string, error) { @@ -18,7 +19,8 @@ func (u *Upgrader) downloadArtifact(ctx context.Context, version, sourceURI stri settings.SourceURI = sourceURI } - verifier, err := downloader.NewVerifier(u.log, &settings) + allowEmptyPgp, pgp := release.PGP() + verifier, err := downloader.NewVerifier(u.log, &settings, allowEmptyPgp, pgp) if err != nil { return "", errors.New(err, "initiating verifier") } diff --git a/x-pack/elastic-agent/pkg/artifact/config.go b/x-pack/elastic-agent/pkg/artifact/config.go index 6faa9861710b..5b0766cb2574 100644 --- a/x-pack/elastic-agent/pkg/artifact/config.go +++ b/x-pack/elastic-agent/pkg/artifact/config.go @@ -30,10 +30,6 @@ type Config struct { // Timeout: timeout for downloading package Timeout time.Duration `json:"timeout" config:"timeout"` - // PgpFile: filepath to a public key used for verifying downloaded artifacts - // if not file is present elastic-agent will try to load public key from elastic.co website. - PgpFile string `json:"pgpfile" config:"pgpfile"` - // InstallPath: path to the directory containing installed packages InstallPath string `yaml:"installPath" config:"install_path"` @@ -48,12 +44,10 @@ type Config struct { // DefaultConfig creates a config with pre-set default values. func DefaultConfig() *Config { homePath := paths.Home() - dataPath := paths.Data() return &Config{ SourceURI: "https://artifacts.elastic.co/downloads/", TargetDirectory: filepath.Join(homePath, "downloads"), Timeout: 30 * time.Second, - PgpFile: filepath.Join(dataPath, "elastic.pgp"), InstallPath: filepath.Join(homePath, "install"), } } diff --git a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier.go index 20bff381a394..d934b20faefb 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier.go @@ -14,11 +14,9 @@ import ( "os" "path/filepath" "strings" - "sync" "golang.org/x/crypto/openpgp" - "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/application/paths" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/agent/errors" "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/artifact" ) @@ -30,15 +28,22 @@ const ( // Verifier verifies a downloaded package by comparing with public ASC // file from elastic.co website. type Verifier struct { - config *artifact.Config - pgpBytes []byte + config *artifact.Config + pgpBytes []byte + allowEmptyPgp bool } // NewVerifier create a verifier checking downloaded package on preconfigured // location agains a key stored on elastic.co website. -func NewVerifier(config *artifact.Config) (*Verifier, error) { +func NewVerifier(config *artifact.Config, allowEmptyPgp bool, pgp []byte) (*Verifier, error) { + if len(pgp) == 0 && !allowEmptyPgp { + return nil, errors.New("expecting PGP but retrieved none", errors.TypeSecurity) + } + v := &Verifier{ - config: config, + config: config, + allowEmptyPgp: allowEmptyPgp, + pgpBytes: pgp, } return v, nil @@ -59,9 +64,11 @@ func (v *Verifier) Verify(programName, version string) (bool, error) { // remove bits so they can be redownloaded os.Remove(fullPath) os.Remove(fullPath + ".sha512") + os.Remove(fullPath + ".asc") + return isMatch, err } - return isMatch, err + return v.verifyAsc(filename, fullPath) } func (v *Verifier) verifyHash(filename, fullPath string) (bool, error) { @@ -87,7 +94,7 @@ func (v *Verifier) verifyHash(filename, fullPath string) (bool, error) { } if expectedHash == "" { - return false, fmt.Errorf("hash for '%s' not found", filename) + return false, fmt.Errorf("hash for '%s' not found in '%s'", filename, hashFilePath) } // compute file hash @@ -107,19 +114,16 @@ func (v *Verifier) verifyHash(filename, fullPath string) (bool, error) { } func (v *Verifier) verifyAsc(filename, fullPath string) (bool, error) { - var err error - var pgpBytesLoader sync.Once - - pgpBytesLoader.Do(func() { - err = v.loadPGP(v.config.PgpFile) - }) - - if err != nil { - return false, errors.New(err, "loading PGP") + if len(v.pgpBytes) == 0 { + // no pgp available skip verification process + return true, nil } - ascBytes, err := v.getPublicAsc(filename) - if err != nil { + ascBytes, err := v.getPublicAsc(fullPath) + if err != nil && v.allowEmptyPgp { + // asc not available but we allow empty for dev use-case + return true, nil + } else if err != nil { return false, err } @@ -143,10 +147,8 @@ func (v *Verifier) verifyAsc(filename, fullPath string) (bool, error) { return true, nil } -func (v *Verifier) getPublicAsc(filename string) ([]byte, error) { - ascFile := fmt.Sprintf("%s%s", filename, ascSuffix) - fullPath := filepath.Join(paths.Home(), "downloads", ascFile) - +func (v *Verifier) getPublicAsc(fullPath string) ([]byte, error) { + fullPath = fmt.Sprintf("%s%s", fullPath, ascSuffix) b, err := ioutil.ReadFile(fullPath) if err != nil { return nil, errors.New(err, fmt.Sprintf("fetching asc file from '%s'", fullPath), errors.TypeFilesystem, errors.M(errors.MetaKeyPath, fullPath)) @@ -154,18 +156,3 @@ func (v *Verifier) getPublicAsc(filename string) ([]byte, error) { return b, nil } - -func (v *Verifier) loadPGP(file string) error { - var err error - - if file == "" { - return errors.New("pgp file not specified for verifier", errors.TypeConfig) - } - - v.pgpBytes, err = ioutil.ReadFile(file) - if err != nil { - return errors.New(err, errors.TypeFilesystem) - } - - return nil -} diff --git a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go index 4787656d8b0a..4fd845482c5d 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go +++ b/x-pack/elastic-agent/pkg/artifact/download/fs/verifier_test.go @@ -59,7 +59,7 @@ func TestFetchVerify(t *testing.T) { assert.NoError(t, err) downloader := NewDownloader(config) - verifier, err := NewVerifier(config) + verifier, err := NewVerifier(config, true, nil) assert.NoError(t, err) // first download verify should fail: @@ -157,7 +157,7 @@ func TestVerify(t *testing.T) { t.Fatal(err) } - testVerifier, err := NewVerifier(config) + testVerifier, err := NewVerifier(config, true, nil) if err != nil { t.Fatal(err) } diff --git a/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go b/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go index a1e1ced0b662..0edb979a320e 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go +++ b/x-pack/elastic-agent/pkg/artifact/download/http/elastic_test.go @@ -105,7 +105,7 @@ func TestVerify(t *testing.T) { t.Fatal(err) } - testVerifier, err := NewVerifier(config) + testVerifier, err := NewVerifier(config, true, nil) if err != nil { t.Fatal(err) } diff --git a/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go index 171b3363aecc..9f2eacd93959 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/http/verifier.go @@ -16,7 +16,6 @@ import ( "os" "path" "strings" - "sync" "golang.org/x/crypto/openpgp" @@ -32,20 +31,27 @@ const ( // Verifier verifies a downloaded package by comparing with public ASC // file from elastic.co website. type Verifier struct { - config *artifact.Config - client http.Client - pgpBytes []byte + config *artifact.Config + client http.Client + pgpBytes []byte + allowEmptyPgp bool } // NewVerifier create a verifier checking downloaded package on preconfigured // location agains a key stored on elastic.co website. -func NewVerifier(config *artifact.Config) (*Verifier, error) { +func NewVerifier(config *artifact.Config, allowEmptyPgp bool, pgp []byte) (*Verifier, error) { + if len(pgp) == 0 && !allowEmptyPgp { + return nil, errors.New("expecting PGP but retrieved none", errors.TypeSecurity) + } + client := http.Client{Timeout: config.Timeout} rtt := withHeaders(client.Transport, headers) client.Transport = rtt v := &Verifier{ - config: config, - client: client, + config: config, + client: client, + allowEmptyPgp: allowEmptyPgp, + pgpBytes: pgp, } return v, nil @@ -71,9 +77,11 @@ func (v *Verifier) Verify(programName, version string) (bool, error) { // remove bits so they can be redownloaded os.Remove(fullPath) os.Remove(fullPath + ".sha512") + os.Remove(fullPath + ".asc") + return isMatch, err } - return isMatch, err + return v.verifyAsc(programName, version) } func (v *Verifier) verifyHash(filename, fullPath string) (bool, error) { @@ -120,15 +128,9 @@ func (v *Verifier) verifyHash(filename, fullPath string) (bool, error) { } func (v *Verifier) verifyAsc(programName, version string) (bool, error) { - var err error - var pgpBytesLoader sync.Once - - pgpBytesLoader.Do(func() { - err = v.loadPGP(v.config.PgpFile) - }) - - if err != nil { - return false, errors.New(err, "loading PGP") + if len(v.pgpBytes) == 0 { + // no pgp available skip verification process + return true, nil } filename, err := artifact.GetArtifactName(programName, version, v.config.OS(), v.config.Arch()) @@ -147,7 +149,10 @@ func (v *Verifier) verifyAsc(programName, version string) (bool, error) { } ascBytes, err := v.getPublicAsc(ascURI) - if err != nil { + if err != nil && v.allowEmptyPgp { + // asc not available but we allow empty for dev use-case + return true, nil + } else if err != nil { return false, errors.New(err, fmt.Sprintf("fetching asc file from %s", ascURI), errors.TypeNetwork, errors.M(errors.MetaKeyURI, ascURI)) } @@ -202,33 +207,3 @@ func (v *Verifier) getPublicAsc(sourceURI string) ([]byte, error) { return ioutil.ReadAll(resp.Body) } - -func (v *Verifier) loadPGP(file string) error { - var err error - - if file == "" { - v.pgpBytes, err = v.loadPGPFromWeb() - return err - } - - v.pgpBytes, err = ioutil.ReadFile(file) - if err != nil { - return errors.New(err, errors.TypeFilesystem, errors.M(errors.MetaKeyPath, file)) - } - - return nil -} - -func (v *Verifier) loadPGPFromWeb() ([]byte, error) { - resp, err := v.client.Get(publicKeyURI) - if err != nil { - return nil, errors.New(err, "failed loading public key", errors.TypeNetwork, errors.M(errors.MetaKeyURI, publicKeyURI)) - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - return nil, errors.New(fmt.Sprintf("call to '%s' returned unsuccessful status code: %d", publicKeyURI, resp.StatusCode), errors.TypeNetwork, errors.M(errors.MetaKeyURI, publicKeyURI)) - } - - return ioutil.ReadAll(resp.Body) -} diff --git a/x-pack/elastic-agent/pkg/artifact/download/localremote/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/localremote/verifier.go index 34863270679b..4f33cbbdb8e2 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/localremote/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/localremote/verifier.go @@ -17,10 +17,10 @@ import ( // NewVerifier creates a downloader which first checks local directory // and then fallbacks to remote if configured. -func NewVerifier(log *logger.Logger, config *artifact.Config) (download.Verifier, error) { +func NewVerifier(log *logger.Logger, config *artifact.Config, allowEmptyPgp bool, pgp []byte) (download.Verifier, error) { verifiers := make([]download.Verifier, 0, 3) - fsVer, err := fs.NewVerifier(config) + fsVer, err := fs.NewVerifier(config, allowEmptyPgp, pgp) if err != nil { return nil, err } @@ -28,7 +28,7 @@ func NewVerifier(log *logger.Logger, config *artifact.Config) (download.Verifier // try snapshot repo before official if release.Snapshot() { - snapshotVerifier, err := snapshot.NewVerifier(config) + snapshotVerifier, err := snapshot.NewVerifier(config, allowEmptyPgp, pgp) if err != nil { log.Error(err) } else { @@ -36,7 +36,7 @@ func NewVerifier(log *logger.Logger, config *artifact.Config) (download.Verifier } } - remoteVer, err := http.NewVerifier(config) + remoteVer, err := http.NewVerifier(config, allowEmptyPgp, pgp) if err != nil { return nil, err } diff --git a/x-pack/elastic-agent/pkg/artifact/download/snapshot/downloader.go b/x-pack/elastic-agent/pkg/artifact/download/snapshot/downloader.go index f45a38d3f973..6f28ad8d9269 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/snapshot/downloader.go +++ b/x-pack/elastic-agent/pkg/artifact/download/snapshot/downloader.go @@ -38,7 +38,6 @@ func snapshotConfig(config *artifact.Config) (*artifact.Config, error) { SourceURI: snapshotURI, TargetDirectory: config.TargetDirectory, Timeout: config.Timeout, - PgpFile: config.PgpFile, InstallPath: config.InstallPath, DropPath: config.DropPath, }, nil diff --git a/x-pack/elastic-agent/pkg/artifact/download/snapshot/verifier.go b/x-pack/elastic-agent/pkg/artifact/download/snapshot/verifier.go index 91626a6b55b0..e9d8bbd4dc14 100644 --- a/x-pack/elastic-agent/pkg/artifact/download/snapshot/verifier.go +++ b/x-pack/elastic-agent/pkg/artifact/download/snapshot/verifier.go @@ -12,10 +12,10 @@ import ( // NewVerifier creates a downloader which first checks local directory // and then fallbacks to remote if configured. -func NewVerifier(config *artifact.Config, downloaders ...download.Downloader) (download.Verifier, error) { +func NewVerifier(config *artifact.Config, allowEmptyPgp bool, pgp []byte) (download.Verifier, error) { cfg, err := snapshotConfig(config) if err != nil { return nil, err } - return http.NewVerifier(cfg) + return http.NewVerifier(cfg, allowEmptyPgp, pgp) } diff --git a/x-pack/elastic-agent/pkg/release/pgp.go b/x-pack/elastic-agent/pkg/release/pgp.go new file mode 100644 index 000000000000..00ca6add25a3 --- /dev/null +++ b/x-pack/elastic-agent/pkg/release/pgp.go @@ -0,0 +1,25 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. + +// Code generated by x-pack/dev-tools/cmd/buildspec/buildPgp.go - DO NOT EDIT. + +package release + +import ( + "github.com/elastic/beats/v7/x-pack/elastic-agent/pkg/packer" +) + +// pgp bytes is a packed in public gpg key +var pgpBytes []byte + +func init() { + // Packed Files + // GPG-KEY-elasticsearch + pgpBytes = packer.MustUnpack("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")["GPG-KEY-elasticsearch"] +} + +// PGP return pgpbytes and a flag describing whether or not no pgp is valid. +func PGP() (bool, []byte) { + return allowEmptyPgp == "true", pgpBytes +} diff --git a/x-pack/elastic-agent/pkg/release/version.go b/x-pack/elastic-agent/pkg/release/version.go index 542ea8294177..37579ac86de5 100644 --- a/x-pack/elastic-agent/pkg/release/version.go +++ b/x-pack/elastic-agent/pkg/release/version.go @@ -15,6 +15,10 @@ import ( // snapshot is a flag marking build as a snapshot. var snapshot = "" +// allowEmptyPgp is used as a debug flag and allows working +// without valid pgp +var allowEmptyPgp string + // Commit returns the current build hash or unknown if it was not injected in the build process. func Commit() string { return libbeatVersion.Commit() @@ -54,7 +58,7 @@ func Info() VersionInfo { } } -// String returns the string format for the version informaiton. +// String returns the string format for the version information. func (v *VersionInfo) String() string { var sb strings.Builder