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

Merge branch 'main' into sha-handling

This commit is contained in:
koplas 2025-03-05 09:41:29 +01:00
commit 1d1c5698da
No known key found for this signature in database
16 changed files with 308 additions and 72 deletions

View file

@ -423,6 +423,7 @@ func (p *processor) fullClient() util.Client {
hClient.Transport = &http.Transport{
TLSClientConfig: &tlsConfig,
Proxy: http.ProxyFromEnvironment,
}
client := util.Client(&hClient)
@ -453,6 +454,7 @@ func (p *processor) basicClient() *http.Client {
if p.cfg.Insecure {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
Proxy: http.ProxyFromEnvironment,
}
return &http.Client{Transport: tr}
}
@ -1352,47 +1354,52 @@ func (p *processor) checkSecurityFolder(folder string) string {
// checkDNS checks if the "csaf.data.security.domain.tld" DNS record is available
// and serves the "provider-metadata.json".
// 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) {
p.badDNSPath.use()
client := p.httpClient()
path := "https://csaf.data.security." + domain
res, err := client.Get(path)
if err != nil {
return fmt.Sprintf("Fetching %s failed: %v", path, err)
p.badDNSPath.add(ErrorType,
fmt.Sprintf("Fetching %s failed: %v", path, err))
return
}
if res.StatusCode != http.StatusOK {
return fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status)
p.badDNSPath.add(ErrorType, fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status))
}
hash := sha256.New()
defer res.Body.Close()
content, err := io.ReadAll(res.Body)
if err != nil {
return fmt.Sprintf("Error while reading the response from %s", path)
p.badDNSPath.add(ErrorType,
fmt.Sprintf("Error while reading the response from %s", path))
}
hash.Write(content)
if !bytes.Equal(hash.Sum(nil), p.pmd256) {
return fmt.Sprintf("%s does not serve the same provider-metadata.json as previously found", path)
p.badDNSPath.add(ErrorType,
fmt.Sprintf("%s does not serve the same provider-metadata.json as previously found",
path))
}
return ""
}
// checkWellknownMetadataReporter checks if the provider-metadata.json file is
// available under the /.well-known/csaf/ directory. Returns the errormessage if
// an error was encountered, or an empty string otherwise
func (p *processor) checkWellknown(domain string) string {
// checkWellknown checks if the provider-metadata.json file is
// available under the /.well-known/csaf/ directory.
func (p *processor) checkWellknown(domain string) {
p.badWellknownMetadata.use()
client := p.httpClient()
path := "https://" + domain + "/.well-known/csaf/provider-metadata.json"
res, err := client.Get(path)
if err != nil {
return fmt.Sprintf("Fetching %s failed: %v", path, err)
p.badWellknownMetadata.add(ErrorType,
fmt.Sprintf("Fetching %s failed: %v", path, err))
}
if res.StatusCode != http.StatusOK {
return fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status)
p.badWellknownMetadata.add(ErrorType, fmt.Sprintf("Fetching %s failed. Status code %d (%s)",
path, res.StatusCode, res.Status))
}
return ""
}
// checkWellknownSecurityDNS
@ -1404,56 +1411,41 @@ func (p *processor) checkWellknown(domain string) string {
// 4. Finally it checks if the "csaf.data.security.domain.tld" DNS record
// is available and serves the "provider-metadata.json".
//
// /
// If all three checks fail, errors are given,
// otherwise warnings for all failed checks.
// The function returns nil, unless errors outside the checks were found.
// In that case, errors are returned.
// For the security.txt checks, it first checks the default location.
// Should this lookup fail, a warning is will be given and a lookup
// for the legacy location will be made. If this fails as well, then an
// error is given.
func (p *processor) checkWellknownSecurityDNS(domain string) error {
warningsW := p.checkWellknown(domain)
p.checkWellknown(domain)
// Security check for well known (default) and legacy location
warningsS, sDMessage := p.checkSecurity(domain, false)
warnings, sDMessage := p.checkSecurity(domain, false)
// if the security.txt under .well-known was not okay
// check for a security.txt within its legacy location
sLMessage := ""
if warningsS == 1 {
warningsS, sLMessage = p.checkSecurity(domain, true)
if warnings == 1 {
warnings, sLMessage = p.checkSecurity(domain, true)
}
warningsD := p.checkDNS(domain)
p.badWellknownMetadata.use()
p.badSecurity.use()
p.badDNSPath.use()
var kind MessageType
if warningsS != 1 || warningsD == "" || warningsW == "" {
kind = WarnType
} else {
kind = ErrorType
// Report about Securitytxt:
// Only report about default location if it was succesful (0).
// Report default and legacy as errors if neither was succesful (1).
// Warn about missing security in the default position if not found
// but found in the legacy location, and inform about finding it there (2).
switch warnings {
case 0:
p.badSecurity.add(InfoType, sDMessage)
case 1:
p.badSecurity.add(ErrorType, sDMessage)
p.badSecurity.add(ErrorType, sLMessage)
case 2:
p.badSecurity.add(WarnType, sDMessage)
p.badSecurity.add(InfoType, sLMessage)
}
// Info, Warning or Error depending on kind and warningS
kindSD := kind
if warningsS == 0 {
kindSD = InfoType
}
kindSL := kind
if warningsS == 2 {
kindSL = InfoType
}
p.checkDNS(domain)
if warningsW != "" {
p.badWellknownMetadata.add(kind, warningsW)
}
p.badSecurity.add(kindSD, sDMessage)
// only if the well-known security.txt was not successful:
// report about the legacy location
if warningsS != 0 {
p.badSecurity.add(kindSL, sLMessage)
}
if warningsD != "" {
p.badDNSPath.add(kind, warningsD)
}
return nil
}