From e004939abf508228d4e5ffd3ea518b26cd23f327 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Wed, 25 Jan 2023 10:27:44 +0100 Subject: [PATCH] Implement remote validation in checker. --- cmd/csaf_checker/main.go | 19 +++++++++++++++--- cmd/csaf_checker/processor.go | 38 ++++++++++++++++++++++++++++++++++- docs/csaf_checker.md | 3 +++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/cmd/csaf_checker/main.go b/cmd/csaf_checker/main.go index 78f58b6..316f4c4 100644 --- a/cmd/csaf_checker/main.go +++ b/cmd/csaf_checker/main.go @@ -39,6 +39,10 @@ type options struct { Rate *float64 `long:"rate" short:"r" description:"The average upper limit of https operations per second"` Years *uint `long:"years" short:"y" description:"Number of years to look back from now" value-name:"YEARS"` + RemoteValidator string `long:"validator" description:"URL to validate documents remotely" value-name:"URL"` + RemoteValidatorCache string `long:"validatorcache" description:"FILE to cache remote validations" value-name:"FILE"` + RemoteValidatorPresets []string `long:"validatorpreset" description:"One or more presets to validate remotely"` + clientCerts []tls.Certificate } @@ -154,6 +158,17 @@ func buildReporters() []reporter { } } +// run uses a processor to check all the given domains +// and generates a report. +func run(opts *options, domains []string) (*Report, error) { + p, err := newProcessor(opts) + if err != nil { + return nil, err + } + defer p.close() + return p.run(buildReporters(), domains) +} + func main() { opts := new(options) @@ -172,9 +187,7 @@ func main() { return } - p := newProcessor(opts) - - report, err := p.run(buildReporters(), domains) + report, err := run(opts, domains) errCheck(err) errCheck(writeReport(report, opts)) diff --git a/cmd/csaf_checker/processor.go b/cmd/csaf_checker/processor.go index 32eb991..b1895f0 100644 --- a/cmd/csaf_checker/processor.go +++ b/cmd/csaf_checker/processor.go @@ -41,6 +41,7 @@ type topicMessages []Message type processor struct { opts *options + validator csaf.RemoteValidator client util.Client ageAccept func(time.Time) bool @@ -146,12 +147,37 @@ func (m *topicMessages) used() bool { return *m != nil } // newProcessor returns a processor structure after assigning the given options to the opts attribute // and initializing the "alreadyChecked" and "expr" fields. -func newProcessor(opts *options) *processor { +func newProcessor(opts *options) (*processor, error) { + + var validator csaf.RemoteValidator + + if opts.RemoteValidator != "" { + validatorOptions := csaf.RemoteValidatorOptions{ + URL: opts.RemoteValidator, + Presets: opts.RemoteValidatorPresets, + Cache: opts.RemoteValidatorCache, + } + var err error + if validator, err = validatorOptions.Open(); err != nil { + return nil, fmt.Errorf( + "preparing remote validator failed: %w", err) + } + } + return &processor{ opts: opts, alreadyChecked: map[string]whereType{}, expr: util.NewPathEval(), ageAccept: ageAccept(opts), + validator: validator, + }, nil +} + +// close closes external ressources of the processor. +func (p *processor) close() { + if p.validator != nil { + p.validator.Close() + p.validator = nil } } @@ -451,6 +477,7 @@ func (p *processor) integrity( continue } + // Validate against JSON schema. errors, err := csaf.ValidateCSAF(doc) if err != nil { lg(ErrorType, "Failed to validate %s: %v", u, err) @@ -460,6 +487,15 @@ func (p *processor) integrity( lg(ErrorType, "CSAF file %s has %d validation errors.", u, len(errors)) } + // Validate against remote validator. + if p.validator != nil { + if ok, err := p.validator.Validate(doc); err != nil { + lg(ErrorType, "Calling remote validator on %s failed: %v", u, err) + } else if !ok { + lg(ErrorType, "Remote validation of %s failed.", u) + } + } + // Check if file is in the right folder. p.badFolders.use() diff --git a/docs/csaf_checker.md b/docs/csaf_checker.md index 39c265d..f279d4c 100644 --- a/docs/csaf_checker.md +++ b/docs/csaf_checker.md @@ -15,6 +15,9 @@ Application Options: -v, --verbose Verbose output -r, --rate= The average upper limit of https operations per second -y, --years=YEARS Number of years to look back from now + --validator=URL URL to validate documents remotely + --validatorcache=FILE FILE to cache remote validations + --validatorpreset= One or more presets to validate remotely Help Options: -h, --help Show this help message