mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 18:15:42 +01:00
Be more precise with conditional rules.
This commit is contained in:
parent
7eae607810
commit
c7453a6448
3 changed files with 124 additions and 43 deletions
|
|
@ -254,7 +254,16 @@ func (p *processor) run(domains []string) (*Report, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range buildReporters(*domain.Role) {
|
rules := roleRequirements(*domain.Role)
|
||||||
|
// TODO: store error base on rules eval in report.
|
||||||
|
if rules == nil {
|
||||||
|
log.Printf(
|
||||||
|
"WARN: Cannot find requirement rules for role %q. Assuming trusted provider.\n",
|
||||||
|
*domain.Role)
|
||||||
|
rules = trustedProviderRules
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range rules.reporters() {
|
||||||
r.report(p, domain)
|
r.report(p, domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/csaf-poc/csaf_distribution/v2/csaf"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
|
@ -72,46 +70,6 @@ var reporters = [23]reporter{
|
||||||
&mirrorReporter{baseReporter{num: 23, description: "Mirror"}},
|
&mirrorReporter{baseReporter{num: 23, description: "Mirror"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
var roleImplies = map[csaf.MetadataRole][]csaf.MetadataRole{
|
|
||||||
csaf.MetadataRoleProvider: {csaf.MetadataRolePublisher},
|
|
||||||
csaf.MetadataRoleTrustedProvider: {csaf.MetadataRoleProvider},
|
|
||||||
}
|
|
||||||
|
|
||||||
func requirements(role csaf.MetadataRole) [][2]int {
|
|
||||||
var own [][2]int
|
|
||||||
switch role {
|
|
||||||
case csaf.MetadataRoleTrustedProvider:
|
|
||||||
own = [][2]int{{18, 20}}
|
|
||||||
case csaf.MetadataRoleProvider:
|
|
||||||
// TODO: use commented numbers when TLPs should be checked.
|
|
||||||
own = [][2]int{{6 /* 5 */, 7}, {8, 10}, {11, 14}, {15, 17}}
|
|
||||||
case csaf.MetadataRolePublisher:
|
|
||||||
own = [][2]int{{1, 3 /* 4 */}}
|
|
||||||
}
|
|
||||||
for _, base := range roleImplies[role] {
|
|
||||||
own = append(own, requirements(base)...)
|
|
||||||
}
|
|
||||||
return own
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildReporters initializes each report by assigning a number and description to it.
|
|
||||||
// It returns an array of the reporter interface type.
|
|
||||||
func buildReporters(role csaf.MetadataRole) []reporter {
|
|
||||||
var reps []reporter
|
|
||||||
reqs := requirements(role)
|
|
||||||
// sort to have them ordered by there number.
|
|
||||||
sort.Slice(reqs, func(i, j int) bool { return reqs[i][0] < reqs[j][0] })
|
|
||||||
for _, req := range reqs {
|
|
||||||
from, to := req[0]-1, req[1]-1
|
|
||||||
for i := from; i <= to; i++ {
|
|
||||||
if rep := reporters[i]; rep != nil {
|
|
||||||
reps = append(reps, rep)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return reps
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bc *baseReporter) requirement(domain *Domain) *Requirement {
|
func (bc *baseReporter) requirement(domain *Domain) *Requirement {
|
||||||
req := &Requirement{
|
req := &Requirement{
|
||||||
Num: bc.num,
|
Num: bc.num,
|
||||||
|
|
|
||||||
114
cmd/csaf_checker/rules.go
Normal file
114
cmd/csaf_checker/rules.go
Normal file
|
|
@ -0,0 +1,114 @@
|
||||||
|
// This file is Free Software under the MIT License
|
||||||
|
// without warranty, see README.md and LICENSES/MIT.txt for details.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
//
|
||||||
|
// SPDX-FileCopyrightText: 2023 German Federal Office for Information Security (BSI) <https://www.bsi.bund.de>
|
||||||
|
// Software-Engineering: 2023 Intevation GmbH <https://intevation.de>
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/csaf-poc/csaf_distribution/v2/csaf"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ruleCondition int
|
||||||
|
|
||||||
|
const (
|
||||||
|
condAll ruleCondition = iota
|
||||||
|
condOneOf
|
||||||
|
)
|
||||||
|
|
||||||
|
type requirementRules struct {
|
||||||
|
cond ruleCondition
|
||||||
|
satisfies int
|
||||||
|
subs []*requirementRules
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
publisherRules = &requirementRules{
|
||||||
|
cond: condAll,
|
||||||
|
subs: ruleAtoms(1, 2, 3 /* 4 */),
|
||||||
|
}
|
||||||
|
|
||||||
|
providerRules = &requirementRules{
|
||||||
|
cond: condAll,
|
||||||
|
subs: []*requirementRules{
|
||||||
|
publisherRules,
|
||||||
|
{cond: condOneOf, subs: ruleAtoms(8, 9, 10)},
|
||||||
|
{cond: condOneOf, subs: []*requirementRules{
|
||||||
|
{cond: condAll, subs: ruleAtoms(11, 12, 13, 14)},
|
||||||
|
{cond: condAll, subs: ruleAtoms(15, 16, 17)},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
trustedProviderRules = &requirementRules{
|
||||||
|
cond: condAll,
|
||||||
|
subs: []*requirementRules{
|
||||||
|
providerRules,
|
||||||
|
{cond: condAll, subs: ruleAtoms(18, 19, 20)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func ruleAtoms(nums ...int) []*requirementRules {
|
||||||
|
rules := make([]*requirementRules, len(nums))
|
||||||
|
for i, num := range nums {
|
||||||
|
rules[i] = &requirementRules{
|
||||||
|
cond: condAll,
|
||||||
|
satisfies: num,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rules
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rules *requirementRules) reporters() []reporter {
|
||||||
|
if rules == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var nums []int
|
||||||
|
|
||||||
|
var recurse func(*requirementRules)
|
||||||
|
recurse = func(rules *requirementRules) {
|
||||||
|
if rules.satisfies != 0 {
|
||||||
|
// There should not be any dupes
|
||||||
|
for _, n := range nums {
|
||||||
|
if n == rules.satisfies {
|
||||||
|
goto doRecurse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nums = append(nums, rules.satisfies)
|
||||||
|
}
|
||||||
|
doRecurse:
|
||||||
|
for _, sub := range rules.subs {
|
||||||
|
recurse(sub)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recurse(rules)
|
||||||
|
|
||||||
|
sort.Ints(nums)
|
||||||
|
|
||||||
|
reps := make([]reporter, len(nums))
|
||||||
|
|
||||||
|
for i, n := range nums {
|
||||||
|
reps[i] = reporters[n]
|
||||||
|
}
|
||||||
|
return reps
|
||||||
|
}
|
||||||
|
|
||||||
|
// roleRequirements returns the rules for the given role.
|
||||||
|
func roleRequirements(role csaf.MetadataRole) *requirementRules {
|
||||||
|
switch role {
|
||||||
|
case csaf.MetadataRoleTrustedProvider:
|
||||||
|
return trustedProviderRules
|
||||||
|
case csaf.MetadataRoleProvider:
|
||||||
|
return providerRules
|
||||||
|
case csaf.MetadataRolePublisher:
|
||||||
|
return publisherRules
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue