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 }