mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 18:15:42 +01:00
Rename opts to cfg
This commit is contained in:
parent
0d17db0c59
commit
12ad7706e3
4 changed files with 62 additions and 64 deletions
|
|
@ -10,10 +10,11 @@ package main
|
|||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type options struct {
|
||||
type config struct {
|
||||
Output string `short:"o" long:"output" description:"File name of the generated report" value-name:"REPORT-FILE"`
|
||||
Format string `short:"f" long:"format" choice:"json" choice:"html" description:"Format of report" default:"json"`
|
||||
Insecure bool `long:"insecure" description:"Do not check TLS certificates from provider"`
|
||||
|
|
@ -31,3 +32,28 @@ type options struct {
|
|||
|
||||
clientCerts []tls.Certificate
|
||||
}
|
||||
|
||||
// protectedAccess returns true if we have client certificates or
|
||||
// extra http headers configured.
|
||||
// This may be a wrong assumption, because the certs are not checked
|
||||
// for their domain and custom headers may have other purposes.
|
||||
func (cfg *config) protectedAccess() bool {
|
||||
return len(cfg.clientCerts) > 0 || len(cfg.ExtraHeader) > 0
|
||||
}
|
||||
|
||||
func (cfg *config) prepare() error {
|
||||
// Load client certs.
|
||||
switch hasCert, hasKey := cfg.ClientCert != nil, cfg.ClientKey != nil; {
|
||||
|
||||
case hasCert && !hasKey || !hasCert && hasKey:
|
||||
return errors.New("both client-key and client-cert options must be set for the authentication")
|
||||
|
||||
case hasCert:
|
||||
cert, err := tls.LoadX509KeyPair(*cfg.ClientCert, *cfg.ClientKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.clientCerts = []tls.Certificate{cert}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,8 @@ package main
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
_ "embed" // Used for embedding.
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
|
|
@ -37,31 +35,6 @@ func errCheck(err error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (o *options) prepare() error {
|
||||
// Load client certs.
|
||||
switch hasCert, hasKey := o.ClientCert != nil, o.ClientKey != nil; {
|
||||
|
||||
case hasCert && !hasKey || !hasCert && hasKey:
|
||||
return errors.New("both client-key and client-cert options must be set for the authentication")
|
||||
|
||||
case hasCert:
|
||||
cert, err := tls.LoadX509KeyPair(*o.ClientCert, *o.ClientKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.clientCerts = []tls.Certificate{cert}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// protectedAccess returns true if we have client certificates or
|
||||
// extra http headers configured.
|
||||
// This may be a wrong assumption, because the certs are not checked
|
||||
// for their domain and custom headers may have other purposes.
|
||||
func (o *options) protectedAccess() bool {
|
||||
return len(o.clientCerts) > 0 || len(o.ExtraHeader) > 0
|
||||
}
|
||||
|
||||
// writeJSON writes the JSON encoding of the given report to the given stream.
|
||||
// It returns nil, otherwise an error.
|
||||
func writeJSON(report *Report, w io.WriteCloser) error {
|
||||
|
|
@ -102,14 +75,14 @@ func (nc *nopCloser) Close() error { return nil }
|
|||
|
||||
// writeReport defines where to write the report according to the "output" flag option.
|
||||
// It calls also the "writeJSON" or "writeHTML" function according to the "format" flag option.
|
||||
func writeReport(report *Report, opts *options) error {
|
||||
func writeReport(report *Report, cfg *config) error {
|
||||
|
||||
var w io.WriteCloser
|
||||
|
||||
if opts.Output == "" {
|
||||
if cfg.Output == "" {
|
||||
w = &nopCloser{os.Stdout}
|
||||
} else {
|
||||
f, err := os.Create(opts.Output)
|
||||
f, err := os.Create(cfg.Output)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -118,7 +91,7 @@ func writeReport(report *Report, opts *options) error {
|
|||
|
||||
var writer func(*Report, io.WriteCloser) error
|
||||
|
||||
switch opts.Format {
|
||||
switch cfg.Format {
|
||||
case "json":
|
||||
writer = writeJSON
|
||||
default:
|
||||
|
|
@ -130,8 +103,8 @@ func writeReport(report *Report, opts *options) error {
|
|||
|
||||
// run uses a processor to check all the given domains or direct urls
|
||||
// and generates a report.
|
||||
func run(opts *options, domains []string) (*Report, error) {
|
||||
p, err := newProcessor(opts)
|
||||
func run(cfg *config, domains []string) (*Report, error) {
|
||||
p, err := newProcessor(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -140,27 +113,27 @@ func run(opts *options, domains []string) (*Report, error) {
|
|||
}
|
||||
|
||||
func main() {
|
||||
opts := new(options)
|
||||
cfg := new(config)
|
||||
|
||||
parser := flags.NewParser(opts, flags.Default)
|
||||
parser := flags.NewParser(cfg, flags.Default)
|
||||
parser.Usage = "[OPTIONS] domain..."
|
||||
domains, err := parser.Parse()
|
||||
errCheck(err)
|
||||
|
||||
if opts.Version {
|
||||
if cfg.Version {
|
||||
fmt.Println(util.SemVersion)
|
||||
return
|
||||
}
|
||||
|
||||
errCheck(opts.prepare())
|
||||
errCheck(cfg.prepare())
|
||||
|
||||
if len(domains) == 0 {
|
||||
log.Println("No domain or direct url given.")
|
||||
return
|
||||
}
|
||||
|
||||
report, err := run(opts, domains)
|
||||
report, err := run(cfg, domains)
|
||||
errCheck(err)
|
||||
|
||||
errCheck(writeReport(report, opts))
|
||||
errCheck(writeReport(report, cfg))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import (
|
|||
type topicMessages []Message
|
||||
|
||||
type processor struct {
|
||||
opts *options
|
||||
cfg *config
|
||||
validator csaf.RemoteValidator
|
||||
client util.Client
|
||||
unauthClient util.Client
|
||||
|
|
@ -165,17 +165,16 @@ func (m *topicMessages) hasErrors() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// 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, error) {
|
||||
// newProcessor returns an initilaized processor.
|
||||
func newProcessor(cfg *config) (*processor, error) {
|
||||
|
||||
var validator csaf.RemoteValidator
|
||||
|
||||
if opts.RemoteValidator != "" {
|
||||
if cfg.RemoteValidator != "" {
|
||||
validatorOptions := csaf.RemoteValidatorOptions{
|
||||
URL: opts.RemoteValidator,
|
||||
Presets: opts.RemoteValidatorPresets,
|
||||
Cache: opts.RemoteValidatorCache,
|
||||
URL: cfg.RemoteValidator,
|
||||
Presets: cfg.RemoteValidatorPresets,
|
||||
Cache: cfg.RemoteValidatorCache,
|
||||
}
|
||||
var err error
|
||||
if validator, err = validatorOptions.Open(); err != nil {
|
||||
|
|
@ -185,10 +184,10 @@ func newProcessor(opts *options) (*processor, error) {
|
|||
}
|
||||
|
||||
return &processor{
|
||||
opts: opts,
|
||||
cfg: cfg,
|
||||
alreadyChecked: map[string]whereType{},
|
||||
expr: util.NewPathEval(),
|
||||
ageAccept: ageAccept(opts),
|
||||
ageAccept: ageAccept(cfg),
|
||||
validator: validator,
|
||||
labelChecker: labelChecker{
|
||||
advisories: map[csaf.TLPLabel]util.Set[string]{},
|
||||
|
|
@ -205,11 +204,11 @@ func (p *processor) close() {
|
|||
}
|
||||
}
|
||||
|
||||
func ageAccept(opts *options) func(time.Time) bool {
|
||||
if opts.Years == nil {
|
||||
func ageAccept(cfg *config) func(time.Time) bool {
|
||||
if cfg.Years == nil {
|
||||
return nil
|
||||
}
|
||||
good := time.Now().AddDate(-int(*opts.Years), 0, 0)
|
||||
good := time.Now().AddDate(-int(*cfg.Years), 0, 0)
|
||||
return func(t time.Time) bool {
|
||||
return !t.Before(good)
|
||||
}
|
||||
|
|
@ -431,12 +430,12 @@ func (p *processor) fullClient() util.Client {
|
|||
hClient.CheckRedirect = p.checkRedirect
|
||||
|
||||
var tlsConfig tls.Config
|
||||
if p.opts.Insecure {
|
||||
if p.cfg.Insecure {
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
}
|
||||
|
||||
if len(p.opts.clientCerts) != 0 {
|
||||
tlsConfig.Certificates = p.opts.clientCerts
|
||||
if len(p.cfg.clientCerts) != 0 {
|
||||
tlsConfig.Certificates = p.cfg.clientCerts
|
||||
}
|
||||
|
||||
hClient.Transport = &http.Transport{
|
||||
|
|
@ -446,23 +445,23 @@ func (p *processor) fullClient() util.Client {
|
|||
client := util.Client(&hClient)
|
||||
|
||||
// Add extra headers.
|
||||
if len(p.opts.ExtraHeader) > 0 {
|
||||
if len(p.cfg.ExtraHeader) > 0 {
|
||||
client = &util.HeaderClient{
|
||||
Client: client,
|
||||
Header: p.opts.ExtraHeader,
|
||||
Header: p.cfg.ExtraHeader,
|
||||
}
|
||||
}
|
||||
|
||||
// Add optional URL logging.
|
||||
if p.opts.Verbose {
|
||||
if p.cfg.Verbose {
|
||||
client = &util.LoggingClient{Client: client}
|
||||
}
|
||||
|
||||
// Add optional rate limiting.
|
||||
if p.opts.Rate != nil {
|
||||
if p.cfg.Rate != nil {
|
||||
client = &util.LimitingClient{
|
||||
Client: client,
|
||||
Limiter: rate.NewLimiter(rate.Limit(*p.opts.Rate), 1),
|
||||
Limiter: rate.NewLimiter(rate.Limit(*p.cfg.Rate), 1),
|
||||
}
|
||||
}
|
||||
return client
|
||||
|
|
@ -470,7 +469,7 @@ func (p *processor) fullClient() util.Client {
|
|||
|
||||
// basicClient returns a http Client w/o certs and headers.
|
||||
func (p *processor) basicClient() *http.Client {
|
||||
if p.opts.Insecure {
|
||||
if p.cfg.Insecure {
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
|
|
@ -500,7 +499,7 @@ func (p *processor) unauthorizedClient() util.Client {
|
|||
// usedAuthorizedClient tells if an authorized client is used
|
||||
// for downloading.
|
||||
func (p *processor) usedAuthorizedClient() bool {
|
||||
return p.opts.protectedAccess()
|
||||
return p.cfg.protectedAccess()
|
||||
}
|
||||
|
||||
// rolieFeedEntries loads the references to the advisory files for a given feed.
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ func (r *validReporter) report(p *processor, domain *Domain) {
|
|||
case !p.invalidAdvisories.used():
|
||||
req.message(InfoType, "No validations performed")
|
||||
case len(p.invalidAdvisories) == 0:
|
||||
if p.validator != nil && containsAny(p.opts.RemoteValidatorPresets,
|
||||
if p.validator != nil && containsAny(p.cfg.RemoteValidatorPresets,
|
||||
"basic", "mandatory", "extended", "full") {
|
||||
req.message(InfoType, "All advisories validated fine.")
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue