1
0
Fork 0
mirror of https://github.com/gocsaf/csaf.git synced 2025-12-22 05:40:11 +01:00

Downloader: Add forwarding to HTTP endpoint (#442)

* started with forwarding support in downloader

* Add missing files.

* Add missing files.

* Raise needed Go version

* More Go version bumping.

* Fix forwarding

* Go 1.21+ needed

* Make terminating forwarder more robust.

* Better var naming

* Remove dead code. Improve commentary.

* Prepare validation status adjustment.

* Move validations to functions to make them executable in a loop.

* Introduce validation mode flag (strict, unsafe)
This commit is contained in:
Sascha L. Teichmann 2023-08-25 10:31:27 +02:00 committed by GitHub
parent 7d3c3a68df
commit e0475791ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 398 additions and 63 deletions

View file

@ -42,6 +42,7 @@ type downloader struct {
keys *crypto.KeyRing
eval *util.PathEval
validator csaf.RemoteValidator
forwarder *forwarder
mkdirMu sync.Mutex
}
@ -424,18 +425,26 @@ nextAdvisory:
}
// Compare the checksums.
if s256 != nil && !bytes.Equal(s256.Sum(nil), remoteSHA256) {
log.Printf("SHA256 checksum of %s does not match.\n", file.URL())
continue
s256Check := func() error {
if s256 != nil && !bytes.Equal(s256.Sum(nil), remoteSHA256) {
return fmt.Errorf("SHA256 checksum of %s does not match", file.URL())
}
return nil
}
if s512 != nil && !bytes.Equal(s512.Sum(nil), remoteSHA512) {
log.Printf("SHA512 checksum of %s does not match.\n", file.URL())
continue
s512Check := func() error {
if s512 != nil && !bytes.Equal(s512.Sum(nil), remoteSHA512) {
return fmt.Errorf("SHA512 checksum of %s does not match", file.URL())
}
return nil
}
// Only check signature if we have loaded keys.
if d.keys != nil {
// Validate OpenPGG signature.
keysCheck := func() error {
// Only check signature if we have loaded keys.
if d.keys == nil {
return nil
}
var sign *crypto.PGPSignature
sign, signData, err = loadSignature(client, file.SignURL())
if err != nil {
@ -446,37 +455,82 @@ nextAdvisory:
}
if sign != nil {
if err := d.checkSignature(data.Bytes(), sign); err != nil {
log.Printf("Cannot verify signature for %s: %v\n", file.URL(), err)
if !d.cfg.IgnoreSignatureCheck {
continue
return fmt.Errorf("cannot verify signature for %s: %v", file.URL(), err)
}
}
}
return nil
}
// Validate against CSAF schema.
if errors, err := csaf.ValidateCSAF(doc); err != nil || len(errors) > 0 {
d.logValidationIssues(file.URL(), errors, err)
continue
schemaCheck := func() error {
if errors, err := csaf.ValidateCSAF(doc); err != nil || len(errors) > 0 {
d.logValidationIssues(file.URL(), errors, err)
return fmt.Errorf("schema validation for %q failed", file.URL())
}
return nil
}
if err := util.IDMatchesFilename(d.eval, doc, filename); err != nil {
log.Printf("Ignoring %s: %s.\n", file.URL(), err)
continue
// Validate if filename is conforming.
filenameCheck := func() error {
if err := util.IDMatchesFilename(d.eval, doc, filename); err != nil {
return fmt.Errorf("filename not conforming %s: %s", file.URL(), err)
}
return nil
}
// Validate against remote validator
if d.validator != nil {
// Validate against remote validator.
remoteValidatorCheck := func() error {
if d.validator == nil {
return nil
}
rvr, err := d.validator.Validate(doc)
if err != nil {
errorCh <- fmt.Errorf(
"calling remote validator on %q failed: %w",
file.URL(), err)
continue
return nil
}
if !rvr.Valid {
log.Printf("Remote validation of %q failed\n", file.URL())
return fmt.Errorf("remote validation of %q failed", file.URL())
}
return nil
}
// Run all the validations.
valStatus := notValidatedValidationStatus
for _, check := range []func() error{
s256Check,
s512Check,
keysCheck,
schemaCheck,
filenameCheck,
remoteValidatorCheck,
} {
if err := check(); err != nil {
// TODO: Improve logging.
log.Printf("check failed: %v\n", err)
valStatus.update(invalidValidationStatus)
if d.cfg.ValidationMode == validationStrict {
continue nextAdvisory
}
}
}
valStatus.update(validValidationStatus)
// Send to forwarder
if d.forwarder != nil {
d.forwarder.forward(
filename, data.String(),
valStatus,
string(s256Data),
string(s512Data))
}
if d.cfg.NoStore {
// Do not write locally.
continue
}
if err := d.eval.Extract(`$.document.tracking.initial_release_date`, dateExtract, false, doc); err != nil {