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

Rename opts to cfg

This commit is contained in:
Sascha L. Teichmann 2023-07-20 01:16:05 +02:00
parent 0d17db0c59
commit 12ad7706e3
4 changed files with 62 additions and 64 deletions

View file

@ -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
}

View file

@ -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))
}

View file

@ -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.

View file

@ -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 {