diff --git a/cmd/csaf_downloader/config.go b/cmd/csaf_downloader/config.go index ddb0ac36..3bfea979 100644 --- a/cmd/csaf_downloader/config.go +++ b/cmd/csaf_downloader/config.go @@ -10,6 +10,7 @@ package main import ( "crypto/tls" + "fmt" "net/http" "github.com/csaf-poc/csaf_distribution/v2/internal/certs" @@ -19,9 +20,17 @@ import ( ) const ( - defaultWorker = 2 - defaultPreset = "mandatory" - defaultForwardQueue = 5 + defaultWorker = 2 + defaultPreset = "mandatory" + defaultForwardQueue = 5 + defaultValidationMode = validationStrict +) + +type validationMode string + +const ( + validationStrict = validationMode("strict") + validationUnsafe = validationMode("unsafe") ) type config struct { @@ -45,6 +54,9 @@ type config struct { RemoteValidatorCache string `long:"validatorcache" description:"FILE to cache remote validations" value-name:"FILE" toml:"validatorcache"` RemoteValidatorPresets []string `long:"validatorpreset" description:"One or more PRESETS to validate remotely" value-name:"PRESETS" toml:"validatorpreset"` + //lint:ignore SA5008 We are using choice twice: strict, unsafe. + ValidationMode validationMode `long:"validationmode" short:"m" choice:"strict" choice:"unsafe" value-name:"MODE" description:"MODE how strict the validation is" toml:"validation_mode"` + ForwardURL string `long:"forwardurl" description:"URL of HTTP endpoint to forward downloads to" value-name:"URL" toml:"forward_url"` ForwardHeader http.Header `long:"forwardheader" description:"One or more extra HTTP header fields used by forwarding" toml:"forward_header"` ForwardQueue int `long:"forwardqueue" description:"Maximal queue LENGTH before forwarder" value-name:"LENGTH" toml:"forward_queue"` @@ -73,6 +85,8 @@ func parseArgsConfig() ([]string, *config, error) { SetDefaults: func(cfg *config) { cfg.Worker = defaultWorker cfg.RemoteValidatorPresets = []string{defaultPreset} + cfg.ValidationMode = defaultValidationMode + cfg.ForwardQueue = defaultForwardQueue }, // Re-establish default values if not set. EnsureDefaults: func(cfg *config) { @@ -82,11 +96,27 @@ func parseArgsConfig() ([]string, *config, error) { if cfg.RemoteValidatorPresets == nil { cfg.RemoteValidatorPresets = []string{defaultPreset} } + switch cfg.ValidationMode { + case validationStrict, validationUnsafe: + default: + cfg.ValidationMode = validationStrict + } }, } return p.Parse() } +// UnmarshalText implements [encoding/text.TextUnmarshaler]. +func (vm *validationMode) UnmarshalText(text []byte) error { + switch m := validationMode(text); m { + case validationStrict, validationUnsafe: + *vm = m + default: + return fmt.Errorf(`invalid value %q (expected "strict" or "unsafe"`, m) + } + return nil +} + // ignoreFile returns true if the given URL should not be downloaded. func (cfg *config) ignoreURL(u string) bool { return cfg.ignorePattern.Matches(u) diff --git a/cmd/csaf_downloader/downloader.go b/cmd/csaf_downloader/downloader.go index a3e5e2ce..68bf837d 100644 --- a/cmd/csaf_downloader/downloader.go +++ b/cmd/csaf_downloader/downloader.go @@ -456,7 +456,6 @@ nextAdvisory: if sign != nil { if err := d.checkSignature(data.Bytes(), sign); err != nil { if !d.cfg.IgnoreSignatureCheck { - // TODO: strict mode check return fmt.Errorf("cannot verify signature for %s: %v", file.URL(), err) } } @@ -513,8 +512,9 @@ nextAdvisory: // TODO: Improve logging. log.Printf("check failed: %v\n", err) valStatus.update(invalidValidationStatus) - // TODO strict mode check - continue nextAdvisory + if d.cfg.ValidationMode == validationStrict { + continue nextAdvisory + } } } valStatus.update(validValidationStatus) diff --git a/docs/csaf_downloader.md b/docs/csaf_downloader.md index 5be48fa3..e858cffa 100644 --- a/docs/csaf_downloader.md +++ b/docs/csaf_downloader.md @@ -7,28 +7,34 @@ A tool to download CSAF documents from CSAF providers. csaf_downloader [OPTIONS] domain... Application Options: - -d, --directory=DIR DIRectory to store the downloaded files in - --insecure Do not check TLS certificates from provider - --ignoresigcheck Ignore signature check results, just warn on mismatch - --client-cert=CERT-FILE TLS client certificate file (PEM encoded data) - --client-key=KEY-FILE TLS client private key file (PEM encoded data) - --client-passphrase=PASSPHRASE Optional passphrase for the client cert (limited, experimental, see doc) - --version Display version of the binary - -v, --verbose Verbose output - -r, --rate= The average upper limit of https operations per second (defaults to - unlimited) - -w, --worker=NUM NUMber of concurrent downloads (default: 2) - -t, --timerange=RANGE RANGE of time from which advisories to download - -f, --folder=FOLDER Download into a given subFOLDER - -i, --ignorepattern=PATTERN Do not download files if their URLs match any of the given PATTERNs - -H, --header= One or more extra HTTP header fields - --validator=URL URL to validate documents remotely - --validatorcache=FILE FILE to cache remote validations - --validatorpreset=PRESETS One or more PRESETS to validate remotely (default: [mandatory]) - -c, --config=TOML-FILE Path to config TOML file + -d, --directory=DIR DIRectory to store the downloaded files in + --insecure Do not check TLS certificates from provider + --ignoresigcheck Ignore signature check results, just warn on mismatch + --client-cert=CERT-FILE TLS client certificate file (PEM encoded data) + --client-key=KEY-FILE TLS client private key file (PEM encoded data) + --client-passphrase=PASSPHRASE Optional passphrase for the client cert (limited, experimental, see doc) + --version Display version of the binary + -v, --verbose Verbose output + -n, --nostore Do not store files + -r, --rate= The average upper limit of https operations per second (defaults to + unlimited) + -w, --worker=NUM NUMber of concurrent downloads (default: 2) + -t, --timerange=RANGE RANGE of time from which advisories to download + -f, --folder=FOLDER Download into a given subFOLDER + -i, --ignorepattern=PATTERN Do not download files if their URLs match any of the given PATTERNs + -H, --header= One or more extra HTTP header fields + --validator=URL URL to validate documents remotely + --validatorcache=FILE FILE to cache remote validations + --validatorpreset=PRESETS One or more PRESETS to validate remotely (default: [mandatory]) + -m, --validationmode=MODE[strict|unsafe] MODE how strict the validation is (default: strict) + --forwardurl=URL URL of HTTP endpoint to forward downloads to + --forwardheader= One or more extra HTTP header fields used by forwarding + --forwardqueue=LENGTH Maximal queue LENGTH before forwarder + --forwardinsecure Do not check TLS certificates from forward endpoint + -c, --config=TOML-FILE Path to config TOML file Help Options: - -h, --help Show this help message + -h, --help Show this help message ``` Will download all CSAF documents for the given _domains_, by trying each as a CSAF provider. @@ -67,6 +73,11 @@ worker = 2 # validator # not set by default # validatorcache # not set by default validatorpreset = ["mandatory"] +validation_mode = "strict" +# forward_url # not set by default +# forward_header # not set by default +forward_queue = 5 +forward_insecure = false ``` The `timerange` parameter enables downloading advisories which last changes falls