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

Check if hash present, before sending a request

This commit is contained in:
koplas 2024-09-27 15:20:36 +02:00
parent 37c9eaf346
commit c0de0c2b6d

View file

@ -84,10 +84,8 @@ type reporter interface {
report(*processor, *Domain) report(*processor, *Domain)
} }
var ( // errContinue indicates that the current check should continue.
// errContinue indicates that the current check should continue. var errContinue = errors.New("continue")
errContinue = errors.New("continue")
)
type whereType byte type whereType byte
@ -167,7 +165,6 @@ func (m *topicMessages) hasErrors() bool {
// newProcessor returns an initialized processor. // newProcessor returns an initialized processor.
func newProcessor(cfg *config) (*processor, error) { func newProcessor(cfg *config) (*processor, error) {
var validator csaf.RemoteValidator var validator csaf.RemoteValidator
if cfg.RemoteValidator != "" { if cfg.RemoteValidator != "" {
@ -240,7 +237,6 @@ func (p *processor) reset() {
// Then it calls the report method on each report from the given "reporters" parameter for each domain. // Then it calls the report method on each report from the given "reporters" parameter for each domain.
// It returns a pointer to the report and nil, otherwise an error. // It returns a pointer to the report and nil, otherwise an error.
func (p *processor) run(domains []string) (*Report, error) { func (p *processor) run(domains []string) (*Report, error) {
report := Report{ report := Report{
Date: ReportTime{Time: time.Now().UTC()}, Date: ReportTime{Time: time.Now().UTC()},
Version: util.SemVersion, Version: util.SemVersion,
@ -297,7 +293,6 @@ func (p *processor) run(domains []string) (*Report, error) {
// fillMeta fills the report with extra informations from provider metadata. // fillMeta fills the report with extra informations from provider metadata.
func (p *processor) fillMeta(domain *Domain) error { func (p *processor) fillMeta(domain *Domain) error {
if p.pmd == nil { if p.pmd == nil {
return nil return nil
} }
@ -323,7 +318,6 @@ func (p *processor) fillMeta(domain *Domain) error {
// domainChecks compiles a list of checks which should be performed // domainChecks compiles a list of checks which should be performed
// for a given domain. // for a given domain.
func (p *processor) domainChecks(domain string) []func(*processor, string) error { func (p *processor) domainChecks(domain string) []func(*processor, string) error {
// If we have a direct domain url we dont need to // If we have a direct domain url we dont need to
// perform certain checks. // perform certain checks.
direct := strings.HasPrefix(domain, "https://") direct := strings.HasPrefix(domain, "https://")
@ -393,7 +387,6 @@ func (p *processor) markChecked(s string, mask whereType) bool {
} }
func (p *processor) checkRedirect(r *http.Request, via []*http.Request) error { func (p *processor) checkRedirect(r *http.Request, via []*http.Request) error {
url := r.URL.String() url := r.URL.String()
p.checkTLS(url) p.checkTLS(url)
if p.redirects == nil { if p.redirects == nil {
@ -495,7 +488,6 @@ func (p *processor) usedAuthorizedClient() bool {
// rolieFeedEntries loads the references to the advisory files for a given feed. // rolieFeedEntries loads the references to the advisory files for a given feed.
func (p *processor) rolieFeedEntries(feed string) ([]csaf.AdvisoryFile, error) { func (p *processor) rolieFeedEntries(feed string) ([]csaf.AdvisoryFile, error) {
client := p.httpClient() client := p.httpClient()
res, err := client.Get(feed) res, err := client.Get(feed)
p.badDirListings.use() p.badDirListings.use()
@ -546,7 +538,6 @@ func (p *processor) rolieFeedEntries(feed string) ([]csaf.AdvisoryFile, error) {
var files []csaf.AdvisoryFile var files []csaf.AdvisoryFile
rfeed.Entries(func(entry *csaf.Entry) { rfeed.Entries(func(entry *csaf.Entry) {
// Filter if we have date checking. // Filter if we have date checking.
if accept := p.cfg.Range; accept != nil { if accept := p.cfg.Range; accept != nil {
if t := time.Time(entry.Updated); !t.IsZero() && !accept.Contains(t) { if t := time.Time(entry.Updated); !t.IsZero() && !accept.Contains(t) {
@ -759,14 +750,20 @@ func (p *processor) integrity(
// Check hashes // Check hashes
p.badIntegrities.use() p.badIntegrities.use()
for _, x := range []struct { type hash struct {
ext string ext string
url func() string url func() string
hash []byte hash []byte
}{ }
{"SHA256", f.SHA256URL, s256.Sum(nil)}, hashes := []hash{}
{"SHA512", f.SHA512URL, s512.Sum(nil)}, if f.SHA256URL() != "" {
} { hashes = append(hashes, hash{"SHA256", f.SHA256URL, s256.Sum(nil)})
}
if f.SHA512URL() != "" {
hashes = append(hashes, hash{"SHA512", f.SHA512URL, s512.Sum(nil)})
}
for _, x := range hashes {
hu, err := url.Parse(x.url()) hu, err := url.Parse(x.url())
if err != nil { if err != nil {
lg(ErrorType, "Bad URL %s: %v", x.url(), err) lg(ErrorType, "Bad URL %s: %v", x.url(), err)
@ -918,7 +915,6 @@ func (p *processor) checkIndex(base string, mask whereType) error {
// of the fields' values and if they are sorted properly. Then it passes the files to the // of the fields' values and if they are sorted properly. Then it passes the files to the
// "integrity" functions. It returns error if some test fails, otherwise nil. // "integrity" functions. It returns error if some test fails, otherwise nil.
func (p *processor) checkChanges(base string, mask whereType) error { func (p *processor) checkChanges(base string, mask whereType) error {
bu, err := url.Parse(base) bu, err := url.Parse(base)
if err != nil { if err != nil {
return err return err
@ -978,8 +974,7 @@ func (p *processor) checkChanges(base string, mask whereType) error {
} }
path := r[pathColumn] path := r[pathColumn]
times, files = times, files = append(times, t),
append(times, t),
append(files, csaf.DirectoryAdvisoryFile{Path: path}) append(files, csaf.DirectoryAdvisoryFile{Path: path})
} }
return times, files, nil return times, files, nil
@ -1152,7 +1147,6 @@ func (p *processor) checkMissing(string) error {
// checkInvalid goes over all found adivisories URLs and checks // checkInvalid goes over all found adivisories URLs and checks
// if file name conforms to standard. // if file name conforms to standard.
func (p *processor) checkInvalid(string) error { func (p *processor) checkInvalid(string) error {
p.badDirListings.use() p.badDirListings.use()
var invalids []string var invalids []string
@ -1174,7 +1168,6 @@ func (p *processor) checkInvalid(string) error {
// checkListing goes over all found adivisories URLs and checks // checkListing goes over all found adivisories URLs and checks
// if their parent directory is listable. // if their parent directory is listable.
func (p *processor) checkListing(string) error { func (p *processor) checkListing(string) error {
p.badDirListings.use() p.badDirListings.use()
pgs := pages{} pgs := pages{}
@ -1209,7 +1202,6 @@ func (p *processor) checkListing(string) error {
// checkWhitePermissions checks if the TLP:WHITE advisories are // checkWhitePermissions checks if the TLP:WHITE advisories are
// available with unprotected access. // available with unprotected access.
func (p *processor) checkWhitePermissions(string) error { func (p *processor) checkWhitePermissions(string) error {
var ids []string var ids []string
for id, open := range p.labelChecker.whiteAdvisories { for id, open := range p.labelChecker.whiteAdvisories {
if !open { if !open {
@ -1235,7 +1227,6 @@ func (p *processor) checkWhitePermissions(string) error {
// According to the result, the respective error messages added to // According to the result, the respective error messages added to
// badProviderMetadata. // badProviderMetadata.
func (p *processor) checkProviderMetadata(domain string) bool { func (p *processor) checkProviderMetadata(domain string) bool {
p.badProviderMetadata.use() p.badProviderMetadata.use()
client := p.httpClient() client := p.httpClient()
@ -1282,7 +1273,6 @@ func (p *processor) checkSecurity(domain string, legacy bool) (int, string) {
// checkSecurityFolder checks the security.txt in a given folder. // checkSecurityFolder checks the security.txt in a given folder.
func (p *processor) checkSecurityFolder(folder string) string { func (p *processor) checkSecurityFolder(folder string) string {
client := p.httpClient() client := p.httpClient()
path := folder + "security.txt" path := folder + "security.txt"
res, err := client.Get(path) res, err := client.Get(path)
@ -1349,7 +1339,6 @@ func (p *processor) checkSecurityFolder(folder string) string {
// and serves the "provider-metadata.json". // and serves the "provider-metadata.json".
// It returns an empty string if all checks are passed, otherwise the errormessage. // It returns an empty string if all checks are passed, otherwise the errormessage.
func (p *processor) checkDNS(domain string) string { func (p *processor) checkDNS(domain string) string {
client := p.httpClient() client := p.httpClient()
path := "https://csaf.data.security." + domain path := "https://csaf.data.security." + domain
res, err := client.Get(path) res, err := client.Get(path)
@ -1359,7 +1348,6 @@ func (p *processor) checkDNS(domain string) string {
if res.StatusCode != http.StatusOK { if res.StatusCode != http.StatusOK {
return fmt.Sprintf("Fetching %s failed. Status code %d (%s)", return fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status) path, res.StatusCode, res.Status)
} }
hash := sha256.New() hash := sha256.New()
defer res.Body.Close() defer res.Body.Close()
@ -1378,7 +1366,6 @@ func (p *processor) checkDNS(domain string) string {
// available under the /.well-known/csaf/ directory. Returns the errormessage if // available under the /.well-known/csaf/ directory. Returns the errormessage if
// an error was encountered, or an empty string otherwise // an error was encountered, or an empty string otherwise
func (p *processor) checkWellknown(domain string) string { func (p *processor) checkWellknown(domain string) string {
client := p.httpClient() client := p.httpClient()
path := "https://" + domain + "/.well-known/csaf/provider-metadata.json" path := "https://" + domain + "/.well-known/csaf/provider-metadata.json"
@ -1408,7 +1395,6 @@ func (p *processor) checkWellknown(domain string) string {
// The function returns nil, unless errors outside the checks were found. // The function returns nil, unless errors outside the checks were found.
// In that case, errors are returned. // In that case, errors are returned.
func (p *processor) checkWellknownSecurityDNS(domain string) error { func (p *processor) checkWellknownSecurityDNS(domain string) error {
warningsW := p.checkWellknown(domain) warningsW := p.checkWellknown(domain)
// Security check for well known (default) and legacy location // Security check for well known (default) and legacy location
warningsS, sDMessage := p.checkSecurity(domain, false) warningsS, sDMessage := p.checkSecurity(domain, false)
@ -1461,7 +1447,6 @@ func (p *processor) checkWellknownSecurityDNS(domain string) error {
// As a result of these a respective error messages are passed to badPGP method // As a result of these a respective error messages are passed to badPGP method
// in case of errors. It returns nil if all checks are passed. // in case of errors. It returns nil if all checks are passed.
func (p *processor) checkPGPKeys(_ string) error { func (p *processor) checkPGPKeys(_ string) error {
p.badPGPs.use() p.badPGPs.use()
src, err := p.expr.Eval("$.public_openpgp_keys", p.pmd) src, err := p.expr.Eval("$.public_openpgp_keys", p.pmd)
@ -1520,7 +1505,6 @@ func (p *processor) checkPGPKeys(_ string) error {
defer res.Body.Close() defer res.Body.Close()
return crypto.NewKeyFromArmoredReader(res.Body) return crypto.NewKeyFromArmoredReader(res.Body)
}() }()
if err != nil { if err != nil {
p.badPGPs.error("Reading public OpenPGP key %s failed: %v", u, err) p.badPGPs.error("Reading public OpenPGP key %s failed: %v", u, err)
continue continue