From b107414fef5fc16546c50104f2a76370fd429e97 Mon Sep 17 00:00:00 2001 From: Joonas Bergius Date: Tue, 27 Aug 2024 21:47:36 -0500 Subject: [PATCH] refactor: break --insecure into --http-only and --tls-skip-verify Fixes #2860 Signed-off-by: Joonas Bergius --- .../docs/tutorials/6-publish-and-deploy.mdx | 2 +- src/cmd/common/viper.go | 18 +++++++----- src/cmd/initialize.go | 1 + src/cmd/package.go | 28 ++++++++++++++++++ src/cmd/root.go | 9 ++++++ src/config/lang/english.go | 29 ++++++++++--------- src/internal/packager/helm/chart.go | 2 +- src/internal/packager/helm/repo.go | 2 +- src/internal/packager/images/common.go | 6 ++-- src/pkg/packager/creator/normal.go | 15 ++++++---- src/pkg/packager/sources/new_test.go | 2 +- src/pkg/packager/sources/oci.go | 18 +++++++----- src/pkg/packager/sources/tarball.go | 18 +++++++----- src/pkg/packager/sources/url.go | 4 +-- src/pkg/packager/sources/validate.go | 8 +---- src/pkg/zoci/common.go | 4 +-- src/test/e2e/11_oci_pull_inspect_test.go | 4 +-- src/test/e2e/14_oci_compose_test.go | 24 +++++++-------- .../e2e/31_checksum_and_signature_test.go | 2 +- src/test/e2e/34_custom_init_package_test.go | 2 +- src/test/e2e/50_oci_publish_deploy_test.go | 20 ++++++------- src/types/runtime.go | 6 ++++ 22 files changed, 139 insertions(+), 85 deletions(-) diff --git a/site/src/content/docs/tutorials/6-publish-and-deploy.mdx b/site/src/content/docs/tutorials/6-publish-and-deploy.mdx index a03b0ec392..5787bfd673 100644 --- a/site/src/content/docs/tutorials/6-publish-and-deploy.mdx +++ b/site/src/content/docs/tutorials/6-publish-and-deploy.mdx @@ -142,7 +142,7 @@ You attempted to publish a package with no version metadata. You attempted to publish a package to an insecure registry, using http instead of https. -1. Use the `--insecure` flag. Note that this is not suitable for production workloads. +1. Use the `--plain-http` flag. Note that this is not suitable for production workloads. ::: diff --git a/src/cmd/common/viper.go b/src/cmd/common/viper.go index e161c22d00..d8a95339f6 100644 --- a/src/cmd/common/viper.go +++ b/src/cmd/common/viper.go @@ -20,14 +20,16 @@ const ( // Root config keys - VLogLevel = "log_level" - VArchitecture = "architecture" - VNoLogFile = "no_log_file" - VNoProgress = "no_progress" - VNoColor = "no_color" - VZarfCache = "zarf_cache" - VTmpDir = "tmp_dir" - VInsecure = "insecure" + VLogLevel = "log_level" + VArchitecture = "architecture" + VNoLogFile = "no_log_file" + VNoProgress = "no_progress" + VNoColor = "no_color" + VZarfCache = "zarf_cache" + VTmpDir = "tmp_dir" + VInsecure = "insecure" + VPlainHTTP = "plain_http" + VInsecureSkipTLSVerify = "insecure_skip_tls_verify" // Init config keys diff --git a/src/cmd/initialize.go b/src/cmd/initialize.go index 4d1c61363b..376db85da9 100644 --- a/src/cmd/initialize.go +++ b/src/cmd/initialize.go @@ -223,6 +223,7 @@ func init() { initCmd.Flags().IntVar(&pkgConfig.PkgOpts.Retries, "retries", v.GetInt(common.VPkgRetries), lang.CmdPackageFlagRetries) initCmd.Flags().StringVarP(&pkgConfig.PkgOpts.PublicKeyPath, "key", "k", v.GetString(common.VPkgPublicKey), lang.CmdPackageFlagFlagPublicKey) + initCmd.Flags().BoolVar(&pkgConfig.PkgOpts.SkipSignatureValidation, "skip-signature-validation", false, lang.CmdPackageFlagSkipSignatureValidation) initCmd.Flags().SortFlags = true } diff --git a/src/cmd/package.go b/src/cmd/package.go index 8b1405e25c..97f040b393 100644 --- a/src/cmd/package.go +++ b/src/cmd/package.go @@ -73,6 +73,12 @@ var packageDeployCmd = &cobra.Command{ Short: lang.CmdPackageDeployShort, Long: lang.CmdPackageDeployLong, Args: cobra.MaximumNArgs(1), + PreRun: func(_ *cobra.Command, _ []string) { + // If --insecure was provided, set --skip-signature-validation to match + if config.CommonOptions.Insecure { + pkgConfig.PkgOpts.SkipSignatureValidation = true + } + }, RunE: func(cmd *cobra.Command, args []string) error { packageSource, err := choosePackage(args) if err != nil { @@ -130,6 +136,12 @@ var packageInspectCmd = &cobra.Command{ Short: lang.CmdPackageInspectShort, Long: lang.CmdPackageInspectLong, Args: cobra.MaximumNArgs(1), + PreRun: func(_ *cobra.Command, _ []string) { + // If --insecure was provided, set --skip-signature-validation to match + if config.CommonOptions.Insecure { + pkgConfig.PkgOpts.SkipSignatureValidation = true + } + }, RunE: func(cmd *cobra.Command, args []string) error { packageSource, err := choosePackage(args) if err != nil { @@ -202,6 +214,12 @@ var packageRemoveCmd = &cobra.Command{ Aliases: []string{"u", "rm"}, Args: cobra.MaximumNArgs(1), Short: lang.CmdPackageRemoveShort, + PreRun: func(_ *cobra.Command, _ []string) { + // If --insecure was provided, set --skip-signature-validation to match + if config.CommonOptions.Insecure { + pkgConfig.PkgOpts.SkipSignatureValidation = true + } + }, RunE: func(cmd *cobra.Command, args []string) error { packageSource, err := choosePackage(args) if err != nil { @@ -230,6 +248,12 @@ var packagePublishCmd = &cobra.Command{ Short: lang.CmdPackagePublishShort, Example: lang.CmdPackagePublishExample, Args: cobra.ExactArgs(2), + PreRun: func(_ *cobra.Command, _ []string) { + // If --insecure was provided, set --skip-signature-validation to match + if config.CommonOptions.Insecure { + pkgConfig.PkgOpts.SkipSignatureValidation = true + } + }, RunE: func(cmd *cobra.Command, args []string) error { pkgConfig.PkgOpts.PackageSource = args[0] @@ -424,6 +448,7 @@ func bindDeployFlags(v *viper.Viper) { deployFlags.StringVar(&pkgConfig.PkgOpts.OptionalComponents, "components", v.GetString(common.VPkgDeployComponents), lang.CmdPackageDeployFlagComponents) deployFlags.StringVar(&pkgConfig.PkgOpts.Shasum, "shasum", v.GetString(common.VPkgDeployShasum), lang.CmdPackageDeployFlagShasum) deployFlags.StringVar(&pkgConfig.PkgOpts.SGetKeyPath, "sget", v.GetString(common.VPkgDeploySget), lang.CmdPackageDeployFlagSget) + deployFlags.BoolVar(&pkgConfig.PkgOpts.SkipSignatureValidation, "skip-signature-validation", false, lang.CmdPackageFlagSkipSignatureValidation) deployFlags.MarkHidden("sget") } @@ -460,12 +485,14 @@ func bindInspectFlags(_ *viper.Viper) { inspectFlags.BoolVarP(&pkgConfig.InspectOpts.ViewSBOM, "sbom", "s", false, lang.CmdPackageInspectFlagSbom) inspectFlags.StringVar(&pkgConfig.InspectOpts.SBOMOutputDir, "sbom-out", "", lang.CmdPackageInspectFlagSbomOut) inspectFlags.BoolVar(&pkgConfig.InspectOpts.ListImages, "list-images", false, lang.CmdPackageInspectFlagListImages) + inspectFlags.BoolVar(&pkgConfig.PkgOpts.SkipSignatureValidation, "skip-signature-validation", false, lang.CmdPackageFlagSkipSignatureValidation) } func bindRemoveFlags(v *viper.Viper) { removeFlags := packageRemoveCmd.Flags() removeFlags.BoolVar(&config.CommonOptions.Confirm, "confirm", false, lang.CmdPackageRemoveFlagConfirm) removeFlags.StringVar(&pkgConfig.PkgOpts.OptionalComponents, "components", v.GetString(common.VPkgDeployComponents), lang.CmdPackageRemoveFlagComponents) + removeFlags.BoolVar(&pkgConfig.PkgOpts.SkipSignatureValidation, "skip-signature-validation", false, lang.CmdPackageFlagSkipSignatureValidation) _ = packageRemoveCmd.MarkFlagRequired("confirm") } @@ -473,6 +500,7 @@ func bindPublishFlags(v *viper.Viper) { publishFlags := packagePublishCmd.Flags() publishFlags.StringVar(&pkgConfig.PublishOpts.SigningKeyPath, "signing-key", v.GetString(common.VPkgPublishSigningKey), lang.CmdPackagePublishFlagSigningKey) publishFlags.StringVar(&pkgConfig.PublishOpts.SigningKeyPassword, "signing-key-pass", v.GetString(common.VPkgPublishSigningKeyPassword), lang.CmdPackagePublishFlagSigningKeyPassword) + publishFlags.BoolVar(&pkgConfig.PkgOpts.SkipSignatureValidation, "skip-signature-validation", false, lang.CmdPackageFlagSkipSignatureValidation) } func bindPullFlags(v *viper.Viper) { diff --git a/src/cmd/root.go b/src/cmd/root.go index 62e0582c8e..188f91e8cc 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -37,6 +37,12 @@ var ( var rootCmd = &cobra.Command{ Use: "zarf COMMAND", PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { + // If --insecure was provided, set --insecure-skip-tls-verify and --plain-http to match + if config.CommonOptions.Insecure { + config.CommonOptions.InsecureSkipTLSVerify = true + config.CommonOptions.PlainHTTP = true + } + // Skip for vendor only commands if common.CheckVendorOnlyFromPath(cmd) { return nil @@ -121,4 +127,7 @@ func init() { rootCmd.PersistentFlags().StringVar(&config.CommonOptions.CachePath, "zarf-cache", v.GetString(common.VZarfCache), lang.RootCmdFlagCachePath) rootCmd.PersistentFlags().StringVar(&config.CommonOptions.TempDirectory, "tmpdir", v.GetString(common.VTmpDir), lang.RootCmdFlagTempDir) rootCmd.PersistentFlags().BoolVar(&config.CommonOptions.Insecure, "insecure", v.GetBool(common.VInsecure), lang.RootCmdFlagInsecure) + rootCmd.PersistentFlags().MarkDeprecated("insecure", "please use --plain-http, --insecure-skip-tls-verify, or --skip-signature-validation instead.") + rootCmd.PersistentFlags().BoolVar(&config.CommonOptions.PlainHTTP, "plain-http", v.GetBool(common.VPlainHTTP), lang.RootCmdFlagPlainHTTP) + rootCmd.PersistentFlags().BoolVar(&config.CommonOptions.InsecureSkipTLSVerify, "insecure-skip-tls-verify", v.GetBool(common.VInsecureSkipTLSVerify), lang.RootCmdFlagInsecureSkipTLSVerify) } diff --git a/src/config/lang/english.go b/src/config/lang/english.go index 50ce790c44..6f7ff8e3f5 100644 --- a/src/config/lang/english.go +++ b/src/config/lang/english.go @@ -45,14 +45,16 @@ const ( RootCmdLong = "Zarf eliminates the complexity of air gap software delivery for Kubernetes clusters and cloud native workloads\n" + "using a declarative packaging strategy to support DevSecOps in offline and semi-connected environments." - RootCmdFlagLogLevel = "Log level when running Zarf. Valid options are: warn, info, debug, trace" - RootCmdFlagArch = "Architecture for OCI images and Zarf packages" - RootCmdFlagSkipLogFile = "Disable log file creation" - RootCmdFlagNoProgress = "Disable fancy UI progress bars, spinners, logos, etc" - RootCmdFlagNoColor = "Disable colors in output" - RootCmdFlagCachePath = "Specify the location of the Zarf cache directory" - RootCmdFlagTempDir = "Specify the temporary directory to use for intermediate files" - RootCmdFlagInsecure = "Allow access to insecure registries and disable other recommended security enforcements such as package checksum and signature validation. This flag should only be used if you have a specific reason and accept the reduced security posture." + RootCmdFlagLogLevel = "Log level when running Zarf. Valid options are: warn, info, debug, trace" + RootCmdFlagArch = "Architecture for OCI images and Zarf packages" + RootCmdFlagSkipLogFile = "Disable log file creation" + RootCmdFlagNoProgress = "Disable fancy UI progress bars, spinners, logos, etc" + RootCmdFlagNoColor = "Disable colors in output" + RootCmdFlagCachePath = "Specify the location of the Zarf cache directory" + RootCmdFlagTempDir = "Specify the temporary directory to use for intermediate files" + RootCmdFlagInsecure = "Allow access to insecure registries and disable other recommended security enforcements such as package checksum and signature validation. This flag should only be used if you have a specific reason and accept the reduced security posture." + RootCmdFlagPlainHTTP = "Force the connections over HTTP instead of HTTPS. This flag should only be used if you have a specific reason and accept the reduced security posture." + RootCmdFlagInsecureSkipTLSVerify = "Skip checking server's certificate for validity. This flag should only be used if you have a specific reason and accept the reduced security posture." RootCmdDeprecatedDeploy = "Deprecated: Please use \"zarf package deploy %s\" to deploy this package. This warning will be removed in Zarf v1.0.0." RootCmdDeprecatedCreate = "Deprecated: Please use \"zarf package create\" to create this package. This warning will be removed in Zarf v1.0.0." @@ -210,10 +212,11 @@ $ zarf init --artifact-push-password={PASSWORD} --artifact-push-username={USERNA CmdInternalCrc32Short = "Generates a decimal CRC32 for the given text" // zarf package - CmdPackageShort = "Zarf package commands for creating, deploying, and inspecting packages" - CmdPackageFlagConcurrency = "Number of concurrent layer operations to perform when interacting with a remote package." - CmdPackageFlagFlagPublicKey = "Path to public key file for validating signed packages" - CmdPackageFlagRetries = "Number of retries to perform for Zarf deploy operations like git/image pushes or Helm installs" + CmdPackageShort = "Zarf package commands for creating, deploying, and inspecting packages" + CmdPackageFlagConcurrency = "Number of concurrent layer operations to perform when interacting with a remote package." + CmdPackageFlagFlagPublicKey = "Path to public key file for validating signed packages" + CmdPackageFlagSkipSignatureValidation = "Skip validating the signature of the Zarf package" + CmdPackageFlagRetries = "Number of retries to perform for Zarf deploy operations like git/image pushes or Helm installs" CmdPackageCreateShort = "Creates a Zarf package from a given directory or the current directory" CmdPackageCreateLong = "Builds an archive of resources and dependencies defined by the 'zarf.yaml' in the specified directory.\n" + @@ -273,7 +276,7 @@ $ zarf package mirror-resources \ CmdPackageDeployFlagAdoptExistingResources = "Adopts any pre-existing K8s resources into the Helm charts managed by Zarf. ONLY use when you have existing deployments you want Zarf to takeover." CmdPackageDeployFlagSet = "Specify deployment variables to set on the command line (KEY=value)" CmdPackageDeployFlagComponents = "Comma-separated list of components to deploy. Adding this flag will skip the prompts for selected components. Globbing component names with '*' and deselecting 'default' components with a leading '-' are also supported." - CmdPackageDeployFlagShasum = "Shasum of the package to deploy. Required if deploying a remote package and \"--insecure\" is not provided" + CmdPackageDeployFlagShasum = "Shasum of the package to deploy. Required if deploying a remote package." CmdPackageDeployFlagSget = "[Deprecated] Path to public sget key file for remote packages signed via cosign. This flag will be removed in v1.0.0 please use the --key flag instead." CmdPackageDeployFlagSkipWebhooks = "[alpha] Skip waiting for external webhooks to execute as each package component is deployed" CmdPackageDeployFlagTimeout = "Timeout for Helm operations such as installs and rollbacks" diff --git a/src/internal/packager/helm/chart.go b/src/internal/packager/helm/chart.go index daf59902e5..656b5560b5 100644 --- a/src/internal/packager/helm/chart.go +++ b/src/internal/packager/helm/chart.go @@ -143,7 +143,7 @@ func (h *Helm) TemplateChart(ctx context.Context) (manifest string, chartValues client.IncludeCRDs = true // TODO: Further research this with regular/OCI charts client.Verify = false - client.InsecureSkipTLSverify = config.CommonOptions.Insecure + client.InsecureSkipTLSverify = config.CommonOptions.InsecureSkipTLSVerify if h.kubeVersion != "" { parsedKubeVersion, err := chartutil.ParseKubeVersion(h.kubeVersion) if err != nil { diff --git a/src/internal/packager/helm/repo.go b/src/internal/packager/helm/repo.go index 24f3a7f4b0..c9744c148d 100644 --- a/src/internal/packager/helm/repo.go +++ b/src/internal/packager/helm/repo.go @@ -197,7 +197,7 @@ func (h *Helm) DownloadPublishedChart(ctx context.Context, cosignKeyPath string) Verify: downloader.VerifyNever, Getters: getter.All(pull.Settings), Options: []getter.Option{ - getter.WithInsecureSkipVerifyTLS(config.CommonOptions.Insecure), + getter.WithInsecureSkipVerifyTLS(config.CommonOptions.InsecureSkipTLSVerify), getter.WithBasicAuth(username, password), }, } diff --git a/src/internal/packager/images/common.go b/src/internal/packager/images/common.go index 3e2ad406ff..285c541edb 100644 --- a/src/internal/packager/images/common.go +++ b/src/internal/packager/images/common.go @@ -50,9 +50,9 @@ type PushConfig struct { func NoopOpt(*crane.Options) {} // WithGlobalInsecureFlag returns an option for crane that configures insecure -// based upon Zarf's global --insecure flag. +// based upon Zarf's global --insecure-skip-tls-verify (and --insecure) flags. func WithGlobalInsecureFlag() []crane.Option { - if config.CommonOptions.Insecure { + if config.CommonOptions.InsecureSkipTLSVerify { return []crane.Option{crane.Insecure} } // passing a nil option will cause panic @@ -103,7 +103,7 @@ func createPushOpts(cfg PushConfig, pb *message.ProgressBar) []crane.Option { opts = append(opts, WithPushAuth(cfg.RegInfo)) transport := http.DefaultTransport.(*http.Transport).Clone() - transport.TLSClientConfig.InsecureSkipVerify = config.CommonOptions.Insecure + transport.TLSClientConfig.InsecureSkipVerify = config.CommonOptions.InsecureSkipTLSVerify // TODO (@WSTARR) This is set to match the TLSHandshakeTimeout to potentially mitigate effects of https://github.com/zarf-dev/zarf/issues/1444 transport.ResponseHeaderTimeout = 10 * time.Second diff --git a/src/pkg/packager/creator/normal.go b/src/pkg/packager/creator/normal.go index 847a22003e..8766bfb8d3 100644 --- a/src/pkg/packager/creator/normal.go +++ b/src/pkg/packager/creator/normal.go @@ -281,14 +281,17 @@ func (pc *PackageCreator) Output(ctx context.Context, dst *layout.PackagePaths, return fmt.Errorf("unable to publish package: %w", err) } message.HorizontalRule() - flags := "" - if config.CommonOptions.Insecure { - flags = "--insecure" + flags := []string{} + if config.CommonOptions.PlainHTTP { + flags = append(flags, "--plain-http") + } + if config.CommonOptions.InsecureSkipTLSVerify { + flags = append(flags, "--insecure-skip-tls-verify") } message.Title("To inspect/deploy/pull:", "") - message.ZarfCommand("package inspect %s %s", helpers.OCIURLPrefix+remote.Repo().Reference.String(), flags) - message.ZarfCommand("package deploy %s %s", helpers.OCIURLPrefix+remote.Repo().Reference.String(), flags) - message.ZarfCommand("package pull %s %s", helpers.OCIURLPrefix+remote.Repo().Reference.String(), flags) + message.ZarfCommand("package inspect %s %s", helpers.OCIURLPrefix+remote.Repo().Reference.String(), strings.Join(flags, " ")) + message.ZarfCommand("package deploy %s %s", helpers.OCIURLPrefix+remote.Repo().Reference.String(), strings.Join(flags, " ")) + message.ZarfCommand("package pull %s %s", helpers.OCIURLPrefix+remote.Repo().Reference.String(), strings.Join(flags, " ")) } else { // Use the output path if the user specified it. packageName := fmt.Sprintf("%s%s", sources.NameFromMetadata(pkg, pc.createOpts.IsSkeleton), sources.PkgSuffix(pkg.Metadata.Uncompressed)) diff --git a/src/pkg/packager/sources/new_test.go b/src/pkg/packager/sources/new_test.go index 9ae3147168..17d1481192 100644 --- a/src/pkg/packager/sources/new_test.go +++ b/src/pkg/packager/sources/new_test.go @@ -155,7 +155,7 @@ func TestPackageSource(t *testing.T) { { name: "http-insecure", src: fmt.Sprintf("%s/zarf-package-wordpress-amd64-16.0.4.tar.zst", ts.URL), - expectedErr: "remote package provided without a shasum, use --insecure to ignore, or provide one w/ --shasum", + expectedErr: "remote package provided without a shasum, please provide one with --shasum", }, } for _, tt := range tests { diff --git a/src/pkg/packager/sources/oci.go b/src/pkg/packager/sources/oci.go index 8bf6d6d1a6..b86d3797d3 100644 --- a/src/pkg/packager/sources/oci.go +++ b/src/pkg/packager/sources/oci.go @@ -79,8 +79,10 @@ func (s *OCISource) LoadPackage(ctx context.Context, dst *layout.PackagePaths, f spinner.Success() - if err := ValidatePackageSignature(ctx, dst, s.PublicKeyPath); err != nil { - return pkg, nil, err + if !s.SkipSignatureValidation { + if err := ValidatePackageSignature(ctx, dst, s.PublicKeyPath); err != nil { + return pkg, nil, err + } } } @@ -141,11 +143,13 @@ func (s *OCISource) LoadPackageMetadata(ctx context.Context, dst *layout.Package spinner.Success() } - if err := ValidatePackageSignature(ctx, dst, s.PublicKeyPath); err != nil { - if errors.Is(err, ErrPkgSigButNoKey) && skipValidation { - message.Warn("The package was signed but no public key was provided, skipping signature validation") - } else { - return pkg, nil, err + if !s.SkipSignatureValidation { + if err := ValidatePackageSignature(ctx, dst, s.PublicKeyPath); err != nil { + if errors.Is(err, ErrPkgSigButNoKey) && skipValidation { + message.Warn("The package was signed but no public key was provided, skipping signature validation") + } else { + return pkg, nil, err + } } } } diff --git a/src/pkg/packager/sources/tarball.go b/src/pkg/packager/sources/tarball.go index db1b2ed01a..5b556f78e1 100644 --- a/src/pkg/packager/sources/tarball.go +++ b/src/pkg/packager/sources/tarball.go @@ -107,8 +107,10 @@ func (s *TarballSource) LoadPackage(ctx context.Context, dst *layout.PackagePath spinner.Success() - if err := ValidatePackageSignature(ctx, dst, s.PublicKeyPath); err != nil { - return pkg, nil, err + if !s.SkipSignatureValidation { + if err := ValidatePackageSignature(ctx, dst, s.PublicKeyPath); err != nil { + return pkg, nil, err + } } } @@ -185,11 +187,13 @@ func (s *TarballSource) LoadPackageMetadata(ctx context.Context, dst *layout.Pac spinner.Success() } - if err := ValidatePackageSignature(ctx, dst, s.PublicKeyPath); err != nil { - if errors.Is(err, ErrPkgSigButNoKey) && skipValidation { - message.Warn("The package was signed but no public key was provided, skipping signature validation") - } else { - return pkg, nil, err + if !s.SkipSignatureValidation { + if err := ValidatePackageSignature(ctx, dst, s.PublicKeyPath); err != nil { + if errors.Is(err, ErrPkgSigButNoKey) && skipValidation { + message.Warn("The package was signed but no public key was provided, skipping signature validation") + } else { + return pkg, nil, err + } } } } diff --git a/src/pkg/packager/sources/url.go b/src/pkg/packager/sources/url.go index dd4aa05ff5..3e51aa611e 100644 --- a/src/pkg/packager/sources/url.go +++ b/src/pkg/packager/sources/url.go @@ -32,8 +32,8 @@ type URLSource struct { // Collect downloads a package from the source URL. func (s *URLSource) Collect(ctx context.Context, dir string) (string, error) { - if !config.CommonOptions.Insecure && s.Shasum == "" && !strings.HasPrefix(s.PackageSource, helpers.SGETURLPrefix) { - return "", fmt.Errorf("remote package provided without a shasum, use --insecure to ignore, or provide one w/ --shasum") + if s.Shasum == "" && !strings.HasPrefix(s.PackageSource, helpers.SGETURLPrefix) { + return "", fmt.Errorf("remote package provided without a shasum, please provide one with --shasum") } var packageURL string if s.Shasum != "" { diff --git a/src/pkg/packager/sources/validate.go b/src/pkg/packager/sources/validate.go index 1c7914ea69..baf958a699 100644 --- a/src/pkg/packager/sources/validate.go +++ b/src/pkg/packager/sources/validate.go @@ -15,7 +15,6 @@ import ( "strings" "github.com/defenseunicorns/pkg/helpers/v2" - "github.com/zarf-dev/zarf/src/config" "github.com/zarf-dev/zarf/src/pkg/layout" "github.com/zarf-dev/zarf/src/pkg/message" "github.com/zarf-dev/zarf/src/pkg/utils" @@ -25,16 +24,11 @@ var ( // ErrPkgKeyButNoSig is returned when a key was provided but the package is not signed ErrPkgKeyButNoSig = errors.New("a key was provided but the package is not signed - the package may be corrupted or the --key flag was erroneously specified") // ErrPkgSigButNoKey is returned when a package is signed but no key was provided - ErrPkgSigButNoKey = errors.New("package is signed but no key was provided - add a key with the --key flag or use the --insecure flag and run the command again") + ErrPkgSigButNoKey = errors.New("package is signed but no key was provided - add a key with the --key flag or use the --skip-signature-validation flag and run the command again") ) // ValidatePackageSignature validates the signature of a package func ValidatePackageSignature(ctx context.Context, paths *layout.PackagePaths, publicKeyPath string) error { - // If the insecure flag was provided ignore the signature validation - if config.CommonOptions.Insecure { - return nil - } - if publicKeyPath != "" { message.Debugf("Using public key %q for signature validation", publicKeyPath) } diff --git a/src/pkg/zoci/common.go b/src/pkg/zoci/common.go index 41cf415d1b..29e9f34564 100644 --- a/src/pkg/zoci/common.go +++ b/src/pkg/zoci/common.go @@ -32,8 +32,8 @@ type Remote struct { func NewRemote(url string, platform ocispec.Platform, mods ...oci.Modifier) (*Remote, error) { logger := slog.New(message.ZarfHandler{}) modifiers := append([]oci.Modifier{ - oci.WithPlainHTTP(config.CommonOptions.Insecure), - oci.WithInsecureSkipVerify(config.CommonOptions.Insecure), + oci.WithPlainHTTP(config.CommonOptions.PlainHTTP), + oci.WithInsecureSkipVerify(config.CommonOptions.InsecureSkipTLSVerify), oci.WithLogger(logger), oci.WithUserAgent("zarf/" + config.CLIVersion), }, mods...) diff --git a/src/test/e2e/11_oci_pull_inspect_test.go b/src/test/e2e/11_oci_pull_inspect_test.go index cd045ae0a6..764948b883 100644 --- a/src/test/e2e/11_oci_pull_inspect_test.go +++ b/src/test/e2e/11_oci_pull_inspect_test.go @@ -61,7 +61,7 @@ func (suite *PullInspectTestSuite) Test_0_Pull() { suite.Contains(stdErr, "Package signature validated!") // Test pull w/ bad ref. - stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+badPullInspectRef.String(), "--insecure") + stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+badPullInspectRef.String(), "--plain-http", "--insecure-skip-tls-verify") suite.Error(err, stdOut, stdErr) } @@ -69,7 +69,7 @@ func (suite *PullInspectTestSuite) Test_1_Remote_Inspect() { suite.T().Log("E2E: Package Inspect oci://") // Test inspect w/ bad ref. - _, stdErr, err := e2e.Zarf(suite.T(), "package", "inspect", "oci://"+badPullInspectRef.String(), "--insecure") + _, stdErr, err := e2e.Zarf(suite.T(), "package", "inspect", "oci://"+badPullInspectRef.String(), "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation") suite.Error(err, stdErr) // Test inspect on a public package. diff --git a/src/test/e2e/14_oci_compose_test.go b/src/test/e2e/14_oci_compose_test.go index ef060af819..e701f824a9 100644 --- a/src/test/e2e/14_oci_compose_test.go +++ b/src/test/e2e/14_oci_compose_test.go @@ -65,47 +65,47 @@ func (suite *PublishCopySkeletonSuite) Test_0_Publish_Skeletons() { ref := suite.Reference.String() helmCharts := filepath.Join("examples", "helm-charts") - _, stdErr, err := e2e.Zarf(suite.T(), "package", "publish", helmCharts, "oci://"+ref, "--insecure") + _, stdErr, err := e2e.Zarf(suite.T(), "package", "publish", helmCharts, "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify") suite.NoError(err) suite.Contains(stdErr, "Published "+ref) bigBang := filepath.Join("src", "test", "packages", "14-import-everything", "big-bang-min") - _, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", bigBang, "oci://"+ref, "--insecure") + _, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", bigBang, "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify") suite.NoError(err) suite.Contains(stdErr, "Published "+ref) composable := filepath.Join("src", "test", "packages", "09-composable-packages") - _, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", composable, "oci://"+ref, "--insecure") + _, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", composable, "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify") suite.NoError(err) suite.Contains(stdErr, "Published "+ref) - _, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", importEverything, "oci://"+ref, "--insecure") + _, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", importEverything, "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify") suite.NoError(err) suite.Contains(stdErr, "Published "+ref) - _, _, err = e2e.Zarf(suite.T(), "package", "inspect", "oci://"+ref+"/import-everything:0.0.1", "--insecure", "-a", "skeleton") + _, _, err = e2e.Zarf(suite.T(), "package", "inspect", "oci://"+ref+"/import-everything:0.0.1", "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation", "-a", "skeleton") suite.NoError(err) - _, _, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/import-everything:0.0.1", "-o", "build", "--insecure", "-a", "skeleton") + _, _, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/import-everything:0.0.1", "-o", "build", "--plain-http", "--insecure-skip-tls-verify", "-a", "skeleton") suite.NoError(err) - _, _, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/helm-charts:0.0.1", "-o", "build", "--insecure", "-a", "skeleton") + _, _, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/helm-charts:0.0.1", "-o", "build", "--plain-http", "--insecure-skip-tls-verify", "-a", "skeleton") suite.NoError(err) - _, _, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/big-bang-min:2.10.0", "-o", "build", "--insecure", "-a", "skeleton") + _, _, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/big-bang-min:2.10.0", "-o", "build", "--plain-http", "--insecure-skip-tls-verify", "-a", "skeleton") suite.NoError(err) - _, _, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/test-compose-package:0.0.1", "-o", "build", "--insecure", "-a", "skeleton") + _, _, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/test-compose-package:0.0.1", "-o", "build", "--plain-http", "--insecure-skip-tls-verify", "-a", "skeleton") suite.NoError(err) } func (suite *PublishCopySkeletonSuite) Test_1_Compose_Everything_Inception() { suite.T().Log("E2E: Skeleton Package Compose oci://") - _, _, err := e2e.Zarf(suite.T(), "package", "create", importEverything, "-o", "build", "--insecure", "--confirm") + _, _, err := e2e.Zarf(suite.T(), "package", "create", importEverything, "-o", "build", "--plain-http", "--insecure-skip-tls-verify", "--confirm") suite.NoError(err) - _, _, err = e2e.Zarf(suite.T(), "package", "create", importception, "-o", "build", "--insecure", "--confirm") + _, _, err = e2e.Zarf(suite.T(), "package", "create", importception, "-o", "build", "--plain-http", "--insecure-skip-tls-verify", "--confirm") suite.NoError(err) _, stdErr, err := e2e.Zarf(suite.T(), "package", "inspect", importEverythingPath) @@ -183,7 +183,7 @@ func (suite *PublishCopySkeletonSuite) Test_3_Copy() { t := suite.T() example := filepath.Join("build", fmt.Sprintf("zarf-package-helm-charts-%s-0.0.1.tar.zst", e2e.Arch)) - stdOut, stdErr, err := e2e.Zarf(t, "package", "publish", example, "oci://"+suite.Reference.Registry, "--insecure") + stdOut, stdErr, err := e2e.Zarf(t, "package", "publish", example, "oci://"+suite.Reference.Registry, "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation") suite.NoError(err, stdOut, stdErr) suite.Reference.Repository = "helm-charts" diff --git a/src/test/e2e/31_checksum_and_signature_test.go b/src/test/e2e/31_checksum_and_signature_test.go index c83888fe00..0c50817099 100644 --- a/src/test/e2e/31_checksum_and_signature_test.go +++ b/src/test/e2e/31_checksum_and_signature_test.go @@ -37,7 +37,7 @@ func TestChecksumAndSignature(t *testing.T) { // Test that we get an error when trying to deploy a package without providing the public key stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", pkgName, "--confirm") require.Error(t, err, stdOut, stdErr) - require.Contains(t, e2e.StripMessageFormatting(stdErr), "failed to deploy package: unable to load the package: package is signed but no key was provided - add a key with the --key flag or use the --insecure flag and run the command again") + require.Contains(t, e2e.StripMessageFormatting(stdErr), "failed to deploy package: unable to load the package: package is signed but no key was provided - add a key with the --key flag or use the --skip-signature-validation flag and run the command again") // Test that we don't get an error when we remember to provide the public key stdOut, stdErr, err = e2e.Zarf(t, "package", "deploy", pkgName, publicKeyFlag, "--confirm") diff --git a/src/test/e2e/34_custom_init_package_test.go b/src/test/e2e/34_custom_init_package_test.go index e4d3307fc4..d63226a9c8 100644 --- a/src/test/e2e/34_custom_init_package_test.go +++ b/src/test/e2e/34_custom_init_package_test.go @@ -38,7 +38,7 @@ func TestCustomInit(t *testing.T) { // Test that we get an error when trying to deploy a package without providing the public key stdOut, stdErr, err = e2e.Zarf(t, "init", "--confirm") require.Error(t, err, stdOut, stdErr) - require.Contains(t, e2e.StripMessageFormatting(stdErr), "unable to load the package: package is signed but no key was provided - add a key with the --key flag or use the --insecure flag and run the command again") + require.Contains(t, e2e.StripMessageFormatting(stdErr), "unable to load the package: package is signed but no key was provided - add a key with the --key flag or use the --skip-signature-validation flag and run the command again") /* Test operations during package deploy */ // Test that we can deploy the package with the public key diff --git a/src/test/e2e/50_oci_publish_deploy_test.go b/src/test/e2e/50_oci_publish_deploy_test.go index 75f5937179..1f7ce4f3c9 100644 --- a/src/test/e2e/50_oci_publish_deploy_test.go +++ b/src/test/e2e/50_oci_publish_deploy_test.go @@ -46,35 +46,35 @@ func (suite *PublishDeploySuiteTestSuite) Test_0_Publish() { // Publish package. example := filepath.Join(suite.PackagesDir, fmt.Sprintf("zarf-package-helm-charts-%s-0.0.1.tar.zst", e2e.Arch)) ref := suite.Reference.String() - stdOut, stdErr, err := e2e.Zarf(suite.T(), "package", "publish", example, "oci://"+ref, "--insecure") + stdOut, stdErr, err := e2e.Zarf(suite.T(), "package", "publish", example, "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation") suite.NoError(err, stdOut, stdErr) suite.Contains(stdErr, "Published "+ref) // Pull the package via OCI. - stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/helm-charts:0.0.1", "--insecure") + stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "pull", "oci://"+ref+"/helm-charts:0.0.1", "--plain-http", "--insecure-skip-tls-verify") suite.NoError(err, stdOut, stdErr) // Publish w/ package missing `metadata.version` field. example = filepath.Join(suite.PackagesDir, fmt.Sprintf("zarf-package-component-actions-%s.tar.zst", e2e.Arch)) - _, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", example, "oci://"+ref, "--insecure") + _, stdErr, err = e2e.Zarf(suite.T(), "package", "publish", example, "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation") suite.Error(err, stdErr) // Inline publish package. dir := filepath.Join("examples", "helm-charts") - stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "create", dir, "-o", "oci://"+ref, "--insecure", "--oci-concurrency=5", "--confirm") + stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "create", dir, "-o", "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify", "--oci-concurrency=5", "--confirm") suite.NoError(err, stdOut, stdErr) // Inline publish flavor. dir = filepath.Join("examples", "package-flavors") - stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "create", dir, "-o", "oci://"+ref, "--flavor", "oracle-cookie-crunch", "--insecure", "--confirm") + stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "create", dir, "-o", "oci://"+ref, "--flavor", "oracle-cookie-crunch", "--plain-http", "--insecure-skip-tls-verify", "--confirm") suite.NoError(err, stdOut, stdErr) // Inspect published flavor. - stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "inspect", "oci://"+ref+"/package-flavors:1.0.0-oracle-cookie-crunch", "--insecure") + stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "inspect", "oci://"+ref+"/package-flavors:1.0.0-oracle-cookie-crunch", "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation") suite.NoError(err, stdOut, stdErr) // Inspect the published package. - stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "inspect", "oci://"+ref+"/helm-charts:0.0.1", "--insecure") + stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "inspect", "oci://"+ref+"/helm-charts:0.0.1", "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation") suite.NoError(err, stdOut, stdErr) } @@ -87,15 +87,15 @@ func (suite *PublishDeploySuiteTestSuite) Test_1_Deploy() { ref := suite.Reference.String() // Deploy the package via OCI. - stdOut, stdErr, err := e2e.Zarf(suite.T(), "package", "deploy", "oci://"+ref, "--insecure", "--confirm") + stdOut, stdErr, err := e2e.Zarf(suite.T(), "package", "deploy", "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation", "--confirm") suite.NoError(err, stdOut, stdErr) // Remove the package via OCI. - stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "remove", "oci://"+ref, "--insecure", "--confirm") + stdOut, stdErr, err = e2e.Zarf(suite.T(), "package", "remove", "oci://"+ref, "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation", "--confirm") suite.NoError(err, stdOut, stdErr) // Test deploy w/ bad ref. - _, stdErr, err = e2e.Zarf(suite.T(), "package", "deploy", "oci://"+badDeployRef.String(), "--insecure", "--confirm") + _, stdErr, err = e2e.Zarf(suite.T(), "package", "deploy", "oci://"+badDeployRef.String(), "--plain-http", "--insecure-skip-tls-verify", "--skip-signature-validation", "--confirm") suite.Error(err, stdErr) } diff --git a/src/types/runtime.go b/src/types/runtime.go index 0faed8c9e6..8f9ef51996 100644 --- a/src/types/runtime.go +++ b/src/types/runtime.go @@ -14,6 +14,10 @@ type ZarfCommonOptions struct { Confirm bool // Allow insecure connections for remote packages Insecure bool + // Disable checking the server TLS certificate for validity + InsecureSkipTLSVerify bool + // Force connections to be over http instead of https + PlainHTTP bool // Path to use to cache images and git repos on package create CachePath string // Location Zarf should use as a staging ground when managing files and images for package creation and deployment @@ -38,6 +42,8 @@ type ZarfPackageOptions struct { PublicKeyPath string // The number of retries to perform for Zarf deploy operations like image pushes or Helm installs Retries int + // Skip validating the signature of the Zarf package + SkipSignatureValidation bool } // ZarfInspectOptions tracks the user-defined preferences during a package inspection.