mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 11:55:40 +01:00
Merge pull request #424 from csaf-poc/aggregator-client-certs
Aggregator: Add support for client certificates and extra header
This commit is contained in:
commit
f4d00cd9d8
3 changed files with 112 additions and 24 deletions
|
|
@ -20,6 +20,7 @@ import (
|
|||
|
||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||
"github.com/csaf-poc/csaf_distribution/v2/csaf"
|
||||
"github.com/csaf-poc/csaf_distribution/v2/internal/certs"
|
||||
"github.com/csaf-poc/csaf_distribution/v2/internal/filter"
|
||||
"github.com/csaf-poc/csaf_distribution/v2/internal/options"
|
||||
"github.com/csaf-poc/csaf_distribution/v2/util"
|
||||
|
|
@ -52,6 +53,15 @@ type provider struct {
|
|||
|
||||
// IgnorePattern is a list of patterns of advisory URLs to be ignored.
|
||||
IgnorePattern []string `toml:"ignorepattern"`
|
||||
|
||||
// ExtraHeader adds extra HTTP header fields to client
|
||||
ExtraHeader http.Header `toml:"header"`
|
||||
|
||||
ClientCert *string `toml:"client_cert"`
|
||||
ClientKey *string `toml:"client_key"`
|
||||
ClientPassphrase *string `toml:"client_passphrase"`
|
||||
|
||||
clientCerts []tls.Certificate
|
||||
ignorePattern filter.PatternMatcher
|
||||
}
|
||||
|
||||
|
|
@ -74,6 +84,10 @@ type config struct {
|
|||
Passphrase *string `toml:"passphrase"`
|
||||
AllowSingleProvider bool `toml:"allow_single_provider"`
|
||||
|
||||
ClientCert *string `toml:"client_cert"`
|
||||
ClientKey *string `toml:"client_key"`
|
||||
ClientPassphrase *string `toml:"client_passphrase"`
|
||||
|
||||
// LockFile tries to lock to a given file.
|
||||
LockFile *string `toml:"lock_file"`
|
||||
|
||||
|
|
@ -97,13 +111,18 @@ type config struct {
|
|||
|
||||
// IgnorePattern is a list of patterns of advisory URLs to be ignored.
|
||||
IgnorePattern []string `toml:"ignorepattern"`
|
||||
ignorePattern filter.PatternMatcher
|
||||
|
||||
// ExtraHeader adds extra HTTP header fields to client
|
||||
ExtraHeader http.Header `toml:"header"`
|
||||
|
||||
Config string `short:"c" long:"config" description:"Path to config TOML file" value-name:"TOML-FILE" toml:"-"`
|
||||
|
||||
keyMu sync.Mutex
|
||||
key *crypto.Key
|
||||
keyErr error
|
||||
|
||||
clientCerts []tls.Certificate
|
||||
ignorePattern filter.PatternMatcher
|
||||
}
|
||||
|
||||
// configPaths are the potential file locations of the config file.
|
||||
|
|
@ -217,20 +236,44 @@ func (c *config) privateOpenPGPKey() (*crypto.Key, error) {
|
|||
func (c *config) httpClient(p *provider) util.Client {
|
||||
|
||||
hClient := http.Client{}
|
||||
|
||||
var tlsConfig tls.Config
|
||||
if p.Insecure != nil && *p.Insecure || c.Insecure != nil && *c.Insecure {
|
||||
hClient.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
}
|
||||
|
||||
// Use client certs if needed.
|
||||
switch {
|
||||
// Provider has precedence over global.
|
||||
case len(p.clientCerts) != 0:
|
||||
tlsConfig.Certificates = p.clientCerts
|
||||
case len(c.clientCerts) != 0:
|
||||
tlsConfig.Certificates = c.clientCerts
|
||||
}
|
||||
|
||||
hClient.Transport = &http.Transport{
|
||||
TLSClientConfig: &tlsConfig,
|
||||
}
|
||||
|
||||
client := util.Client(&hClient)
|
||||
|
||||
// Add extra headers.
|
||||
switch {
|
||||
// Provider has precedence over global.
|
||||
case len(p.ExtraHeader) > 0:
|
||||
client = &util.HeaderClient{
|
||||
Client: client,
|
||||
Header: p.ExtraHeader,
|
||||
}
|
||||
case len(c.ExtraHeader) > 0:
|
||||
client = &util.HeaderClient{
|
||||
Client: client,
|
||||
Header: c.ExtraHeader,
|
||||
}
|
||||
}
|
||||
|
||||
var client util.Client
|
||||
|
||||
if c.Verbose {
|
||||
client = &util.LoggingClient{Client: &hClient}
|
||||
} else {
|
||||
client = &hClient
|
||||
client = &util.LoggingClient{Client: client}
|
||||
}
|
||||
|
||||
if p.Rate == nil && c.Rate == nil {
|
||||
|
|
@ -325,7 +368,7 @@ func (c *config) setDefaults() {
|
|||
func (p *provider) compileIgnorePatterns() error {
|
||||
pm, err := filter.NewPatternMatcher(p.IgnorePattern)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("invalid ignore patterns for %q: %w", p.Name, err)
|
||||
}
|
||||
p.ignorePattern = pm
|
||||
return nil
|
||||
|
|
@ -342,7 +385,37 @@ func (c *config) compileIgnorePatterns() error {
|
|||
// Compile the patterns of the providers.
|
||||
for _, p := range c.Providers {
|
||||
if err := p.compileIgnorePatterns(); err != nil {
|
||||
return fmt.Errorf("invalid ignore patterns for %q: %w", p.Name, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareCertificates loads the provider specific client side certificates
|
||||
// used by the HTTP client.
|
||||
func (p *provider) prepareCertificates() error {
|
||||
cert, err := certs.LoadCertificate(
|
||||
p.ClientCert, p.ClientKey, p.ClientPassphrase)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid certificates for %q: %w", p.Name, err)
|
||||
}
|
||||
p.clientCerts = cert
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareCertificates loads the client side certificates used by the HTTP client.
|
||||
func (c *config) prepareCertificates() error {
|
||||
// Global certificates
|
||||
cert, err := certs.LoadCertificate(
|
||||
c.ClientCert, c.ClientKey, c.ClientPassphrase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.clientCerts = cert
|
||||
// Provider certificates
|
||||
for _, p := range c.Providers {
|
||||
if err := p.prepareCertificates(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -355,17 +428,16 @@ func (c *config) prepare() error {
|
|||
return errors.New("no providers given in configuration")
|
||||
}
|
||||
|
||||
if err := c.compileIgnorePatterns(); err != nil {
|
||||
return err
|
||||
for _, prepare := range []func() error{
|
||||
c.prepareCertificates,
|
||||
c.compileIgnorePatterns,
|
||||
c.Aggregator.Validate,
|
||||
c.checkProviders,
|
||||
c.checkMirror,
|
||||
} {
|
||||
if err := prepare(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.Aggregator.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.checkProviders(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.checkMirror()
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,6 +95,10 @@ interim_years // limiting the years for which interim documents are se
|
|||
verbose // print more diagnostic output, e.g. https requests (default false)
|
||||
allow_single_provider // debugging option (default false)
|
||||
ignorepattern // patterns of advisory URLs to be ignored
|
||||
client_cert // path to client certificate to access access-protected advisories
|
||||
client_key // path to client key to access access-protected advisories
|
||||
client_passphrase // client passphrase to access access-protected advisories
|
||||
header // adds extra HTTP header fields to the client
|
||||
```
|
||||
|
||||
Next we have two TOML _tables_:
|
||||
|
|
@ -125,6 +129,10 @@ update_interval
|
|||
create_service_document
|
||||
categories
|
||||
ignorepattern
|
||||
client_cert
|
||||
client_key
|
||||
client_passphrase
|
||||
header
|
||||
```
|
||||
|
||||
Where valid `name` and `domain` settings are required.
|
||||
|
|
@ -196,6 +204,10 @@ insecure = true
|
|||
# rate = 1.2
|
||||
# insecure = true
|
||||
write_indices = true
|
||||
client_cert = "./../devca1/testclient1.crt"
|
||||
client_key = "./../devca1/testclient1-key.pem"
|
||||
# client_passphrase =
|
||||
# header =
|
||||
|
||||
[[providers]]
|
||||
name = "local-dev-provider3"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@ insecure = true
|
|||
# rate = 1.2
|
||||
# insecure = true
|
||||
write_indices = true
|
||||
client_cert = "./../devca1/testclient1.crt"
|
||||
client_key = "./../devca1/testclient1-key.pem"
|
||||
# client_passphrase =
|
||||
# header =
|
||||
|
||||
[[providers]]
|
||||
name = "local-dev-provider3"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue