github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/logfwd/syslog/config.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package syslog
     5  
     6  import (
     7  	"crypto/tls"
     8  	"crypto/x509"
     9  	"net"
    10  
    11  	"github.com/juju/errors"
    12  	"github.com/juju/utils/cert"
    13  )
    14  
    15  // RawConfig holds the raw configuration data for a connection to a
    16  // syslog forwarding target.
    17  type RawConfig struct {
    18  	// Enabled is true if the log forwarding feature is enabled.
    19  	Enabled bool
    20  
    21  	// Host is the host-port of the syslog host. The format is:
    22  	//
    23  	//   [domain-or-ip-addr] or [domain-or-ip-addr][:port]
    24  	//
    25  	// If the port is not set then the default TLS port (6514) will
    26  	// be used.
    27  	Host string
    28  
    29  	// CACert is the TLS CA certificate (x.509, PEM-encoded) to use
    30  	// for validating the server certificate when connecting.
    31  	CACert string
    32  
    33  	// ClientCert is the TLS certificate (x.509, PEM-encoded) to use
    34  	// when connecting.
    35  	ClientCert string
    36  
    37  	// ClientKey is the TLS private key (x.509, PEM-encoded) to use
    38  	// when connecting.
    39  	ClientKey string
    40  }
    41  
    42  // Validate ensures that the config is currently valid.
    43  func (cfg RawConfig) Validate() error {
    44  	if err := cfg.validateHost(); err != nil {
    45  		return errors.Trace(err)
    46  	}
    47  
    48  	if cfg.Enabled || cfg.ClientKey != "" || cfg.ClientCert != "" || cfg.CACert != "" {
    49  		if _, err := cfg.tlsConfig(); err != nil {
    50  			return errors.Annotate(err, "validating TLS config")
    51  		}
    52  	}
    53  	return nil
    54  }
    55  
    56  func (cfg RawConfig) validateHost() error {
    57  	host, _, err := net.SplitHostPort(cfg.Host)
    58  	if err != nil {
    59  		host = cfg.Host
    60  	}
    61  	if host == "" && cfg.Enabled {
    62  		return errors.NotValidf("Host %q", cfg.Host)
    63  	}
    64  	return nil
    65  }
    66  
    67  func (cfg RawConfig) tlsConfig() (*tls.Config, error) {
    68  	clientCert, err := tls.X509KeyPair([]byte(cfg.ClientCert), []byte(cfg.ClientKey))
    69  	if err != nil {
    70  		return nil, errors.Annotate(err, "parsing client key pair")
    71  	}
    72  
    73  	caCert, err := cert.ParseCert(cfg.CACert)
    74  	if err != nil {
    75  		return nil, errors.Annotate(err, "parsing CA certificate")
    76  	}
    77  	rootCAs := x509.NewCertPool()
    78  	rootCAs.AddCert(caCert)
    79  
    80  	return &tls.Config{
    81  		Certificates: []tls.Certificate{clientCert},
    82  		RootCAs:      rootCAs,
    83  	}, nil
    84  }