diff --git a/cmd/snaptel/commands.go b/cmd/snaptel/commands.go index 6c2c22c16..08407b422 100644 --- a/cmd/snaptel/commands.go +++ b/cmd/snaptel/commands.go @@ -101,13 +101,13 @@ var ( Subcommands: []cli.Command{ { Name: "load", - Usage: "load [--plugin-cert= --plugin-key= --plugin-root-certs=]", + Usage: "load [--plugin-cert= --plugin-key= --plugin-ca-certs=]", Action: loadPlugin, Flags: []cli.Flag{ flPluginAsc, flPluginCert, flPluginKey, - flPluginRootCerts, + flPluginCACerts, }, }, { @@ -117,7 +117,7 @@ var ( }, { Name: "swap", - Usage: "swap :: or swap -t -n -v [--plugin-cert= --plugin-key= --plugin-root-certs=]", + Usage: "swap :: or swap -t -n -v [--plugin-cert= --plugin-key= --plugin-ca-certs=]", Action: swapPlugins, Flags: []cli.Flag{ flPluginAsc, @@ -126,7 +126,7 @@ var ( flPluginVersion, flPluginCert, flPluginKey, - flPluginRootCerts, + flPluginCACerts, }, }, { diff --git a/cmd/snaptel/flags.go b/cmd/snaptel/flags.go index fd764a226..acdad50e6 100644 --- a/cmd/snaptel/flags.go +++ b/cmd/snaptel/flags.go @@ -73,15 +73,15 @@ var ( } flPluginCert = cli.StringFlag{ Name: "plugin-cert, c", - Usage: "The plugin cert", + Usage: "The path to plugin certificate file", } flPluginKey = cli.StringFlag{ Name: "plugin-key, k", - Usage: "The plugin key", + Usage: "The path to plugin private key file", } - flPluginRootCerts = cli.StringFlag{ - Name: "plugin-root-certs, r", - Usage: "List of root cert paths for TLS to use (folder/file)", + flPluginCACerts = cli.StringFlag{ + Name: "plugin-ca-certs, r", + Usage: "List of CA cert paths for plugin (directory/file) to verify TLS clients", } flPluginType = cli.StringFlag{ Name: "plugin-type, t", diff --git a/cmd/snaptel/plugin.go b/cmd/snaptel/plugin.go index 20d9b9691..3e9edbe40 100644 --- a/cmd/snaptel/plugin.go +++ b/cmd/snaptel/plugin.go @@ -205,13 +205,13 @@ func listPlugins(ctx *cli.Context) error { return nil } -// storeTLSPaths extracts paths related to TLS (certificate, key, root certs) +// storeTLSPaths extracts paths related to TLS (certificate, key, plugin CA certs) // from command line context into temporary files. Those files are appended to // list of paths returned from this function. func storeTLSPaths(ctx *cli.Context, paths []string) ([]string, error) { pCert := ctx.String("plugin-cert") pKey := ctx.String("plugin-key") - pRootCertPaths := ctx.String("plugin-root-certs") + pCACertPaths := ctx.String("plugin-ca-certs") if pCert != pKey && (pCert == "" || pKey == "") { return paths, fmt.Errorf("Error processing plugin TLS arguments - one of (certificate, key) arguments is missing") } @@ -237,14 +237,14 @@ func storeTLSPaths(ctx *cli.Context, paths []string) ([]string, error) { } paths = append(paths, tmpFile.Name()) } - if pRootCertPaths != "" { - tmpFile, err := ioutil.TempFile("", v1.TLSRootCertsPrefix) + if pCACertPaths != "" { + tmpFile, err := ioutil.TempFile("", v1.TLSCACertsPrefix) if err != nil { - return paths, fmt.Errorf("Error processing plugin TLS root certificates - unable to create link:\n%v", err.Error()) + return paths, fmt.Errorf("Error processing plugin TLS CA certificates - unable to create link:\n%v", err.Error()) } - _, err = tmpFile.WriteString(pRootCertPaths) + _, err = tmpFile.WriteString(pCACertPaths) if err != nil { - return paths, fmt.Errorf("Error processing plugin TLS root certificates - unable to write link:\n%v", err.Error()) + return paths, fmt.Errorf("Error processing plugin TLS CA certificates - unable to write link:\n%v", err.Error()) } paths = append(paths, tmpFile.Name()) } diff --git a/control/config.go b/control/config.go index 529fc99bf..3e8ab0628 100644 --- a/control/config.go +++ b/control/config.go @@ -50,7 +50,7 @@ var ( defaultTempDirPath = os.TempDir() defaultTLSCertPath = "" defaultTLSKeyPath = "" - defaultRootCertPaths = "" + defaultCACertPaths = "" ) type pluginConfig struct { @@ -91,7 +91,7 @@ type Config struct { TempDirPath string `json:"temp_dir_path"yaml:"temp_dir_path"` TLSCertPath string `json:"tls_cert_path"yaml:"tls_cert_path"` TLSKeyPath string `json:"tls_key_path"yaml:"tls_key_path"` - RootCertPaths string `json:"root_cert_paths"yaml:"root_cert_paths"` + CACertPaths string `json:"ca_cert_paths"yaml:"ca_cert_paths"` } const ( @@ -153,7 +153,7 @@ const ( "tls_key_path": { "type": "string" }, - "root_cert_paths": { + "ca_cert_paths": { "type": "string" } }, @@ -180,7 +180,7 @@ func GetDefaultConfig() *Config { TempDirPath: defaultTempDirPath, TLSCertPath: defaultTLSCertPath, TLSKeyPath: defaultTLSKeyPath, - RootCertPaths: defaultRootCertPaths, + CACertPaths: defaultCACertPaths, } } @@ -250,7 +250,7 @@ func (p *Config) GetPluginConfigDataNodeAll() cdata.ConfigDataNode { return *p.Plugins.All } -// IsTLSEnabled returns true if config values enable TLS security +// IsTLSEnabled returns true if config values enable TLS in plugin communication func (p *Config) IsTLSEnabled() bool { if p.TLSCertPath != "" && p.TLSKeyPath != "" { return true diff --git a/control/control.go b/control/control.go index 236f24f11..de26cfa78 100644 --- a/control/control.go +++ b/control/control.go @@ -217,21 +217,21 @@ func New(cfg *Config) *pluginControl { "_block": "new", }).Debug("metric catalog created") - // Plugin Manager managerOpts := []pluginManagerOpt{ OptSetPprof(cfg.Pprof), OptSetTempDirPath(cfg.TempDirPath), } + runnerOpts := []pluginRunnerOpt{} + // Plugin Manager if cfg.IsTLSEnabled() { - if cfg.RootCertPaths != "" { - certPaths := filepath.SplitList(cfg.RootCertPaths) + if cfg.CACertPaths != "" { + certPaths := filepath.SplitList(cfg.CACertPaths) c.grpcSecurity = client.SecurityTLSExtended(cfg.TLSCertPath, cfg.TLSKeyPath, client.SecureClient, certPaths) } else { c.grpcSecurity = client.SecurityTLSEnabled(cfg.TLSCertPath, cfg.TLSKeyPath, client.SecureClient) } - } - if cfg.IsTLSEnabled() { managerOpts = append(managerOpts, OptEnableManagerTLS(c.grpcSecurity)) + runnerOpts = append(runnerOpts, OptEnableRunnerTLS(c.grpcSecurity)) } c.pluginManager = newPluginManager(managerOpts...) controlLogger.WithFields(log.Fields{ @@ -247,11 +247,7 @@ func New(cfg *Config) *pluginControl { }).Debug("signing manager created") // Plugin Runner - if cfg.IsTLSEnabled() { - c.pluginRunner = newRunner(OptEnableRunnerTLS(c.grpcSecurity)) - } else { - c.pluginRunner = newRunner() - } + c.pluginRunner = newRunner(runnerOpts...) controlLogger.WithFields(log.Fields{ "_block": "new", }).Debug("runner created") @@ -604,7 +600,7 @@ func (p *pluginControl) returnPluginDetails(rp *core.RequestedPlugin) (*pluginDe details.Signature = rp.Signature() details.CertPath = rp.CertPath() details.KeyPath = rp.KeyPath() - details.RootCertPaths = rp.RootCertPaths() + details.CACertPaths = rp.CACertPaths() details.TLSEnabled = rp.TLSEnabled() if filepath.Ext(rp.Path()) == ".aci" { diff --git a/control/control_security_test.go b/control/control_security_test.go index 839247910..93cf6dc7c 100644 --- a/control/control_security_test.go +++ b/control/control_security_test.go @@ -91,7 +91,7 @@ func TestSecureCollector(t *testing.T) { ap, err = runPlugin(plugin.Arg{}. SetCertPath(tlsTestSrv+fixtures.TestCrtFileExt). SetKeyPath(tlsTestSrv+fixtures.TestKeyFileExt). - SetRootCertPaths(tlsTestCA+fixtures.TestCrtFileExt). + SetCACertPaths(tlsTestCA+fixtures.TestCrtFileExt). SetTLSEnabled(true), helper.PluginFilePath("snap-plugin-collector-mock2-grpc"), security) So(err, ShouldBeNil) @@ -133,7 +133,7 @@ func TestSecureProcessor(t *testing.T) { ap, err = runPlugin(plugin.Arg{}. SetCertPath(tlsTestSrv+fixtures.TestCrtFileExt). SetKeyPath(tlsTestSrv+fixtures.TestKeyFileExt). - SetRootCertPaths(tlsTestCA+fixtures.TestCrtFileExt). + SetCACertPaths(tlsTestCA+fixtures.TestCrtFileExt). SetTLSEnabled(true), helper.PluginFilePath("snap-plugin-processor-passthru-grpc"), security) So(err, ShouldBeNil) @@ -171,7 +171,7 @@ func TestSecurePublisher(t *testing.T) { ap, err = runPlugin(plugin.NewArg(int(log.DebugLevel), false). SetCertPath(tlsTestSrv+fixtures.TestCrtFileExt). SetKeyPath(tlsTestSrv+fixtures.TestKeyFileExt). - SetRootCertPaths(tlsTestCA+fixtures.TestCrtFileExt). + SetCACertPaths(tlsTestCA+fixtures.TestCrtFileExt). SetTLSEnabled(true), helper.PluginFilePath("snap-plugin-publisher-mock-file-grpc"), security) So(err, ShouldBeNil) @@ -216,7 +216,7 @@ func TestSecureStreamingCollector(t *testing.T) { ap, err = runPlugin(plugin.Arg{}. SetCertPath(tlsTestSrv+fixtures.TestCrtFileExt). SetKeyPath(tlsTestSrv+fixtures.TestKeyFileExt). - SetRootCertPaths(tlsTestCA+fixtures.TestCrtFileExt). + SetCACertPaths(tlsTestCA+fixtures.TestCrtFileExt). SetTLSEnabled(true), helper.PluginFilePath("snap-plugin-stream-collector-rand1"), security) So(err, ShouldBeNil) @@ -289,7 +289,7 @@ func TestInsecureConfigurationFails(t *testing.T) { { name: "SecureFrameworkInsecurePlugin_Fail", msg: func(srv *plugin.Arg, cli *client.GRPCSecurity, f func(string)) { - // note: server root certs are used to validate client certs (and vice versa) + // note: server CA certs are used to validate client certs (and vice versa) *srv = srv.SetTLSEnabled(false) f("Attempting TLS connection between secure framework and insecure plugin") }, @@ -302,17 +302,17 @@ func TestInsecureConfigurationFails(t *testing.T) { }, }, { - name: "BadRootCertInFramework_Fail", + name: "BadCACertInFramework_Fail", msg: func(srv *plugin.Arg, cli *client.GRPCSecurity, f func(string)) { - cli.RootCertPaths = []string{tlsTestCA + fixtures.TestBadCrtFileExt} - f("Attempting TLS connection between framework and plugin using incompatible root certs, bad cert in framework") + cli.CACertPaths = []string{tlsTestCA + fixtures.TestBadCrtFileExt} + f("Attempting TLS connection between framework and plugin using incompatible CA certs, bad cert in framework") }, }, { - name: "PluginRootCertsUnknownToFramework_Fail", + name: "PluginCACertsUnknownToFramework_Fail", msg: func(srv *plugin.Arg, cli *client.GRPCSecurity, f func(string)) { - cli.RootCertPaths = []string{} - f("Attempting TLS connection between secure framework and plugin with certificate without root certs known to framework") + cli.CACertPaths = []string{} + f("Attempting TLS connection between secure framework and plugin with certificate without CA certs known to framework") }, }, { @@ -330,17 +330,17 @@ func TestInsecureConfigurationFails(t *testing.T) { }, }, { - name: "FrameworkRootCertsUnknownToPlugin_Fail", + name: "FrameworkCACertsUnknownToPlugin_Fail", msg: func(srv *plugin.Arg, cli *client.GRPCSecurity, f func(string)) { - srv.RootCertPaths = "" - f("Attempting TLS connection between invalid framework with no root certs known to plugin and secure plugin") + srv.CACertPaths = "" + f("Attempting TLS connection between invalid framework with no CA certs known to plugin and secure plugin") }, }, { - name: "BadRootCertInPlugin_Fail", + name: "BadCACertInPlugin_Fail", msg: func(srv *plugin.Arg, cli *client.GRPCSecurity, f func(string)) { - srv.RootCertPaths = tlsTestCA + fixtures.TestBadCrtFileExt - f("Attempting TLS connection between framework and plugin using incompatible root certs, bad cert in plugin") + srv.CACertPaths = tlsTestCA + fixtures.TestBadCrtFileExt + f("Attempting TLS connection between framework and plugin using incompatible CA certs, bad cert in plugin") }, }, } @@ -349,7 +349,7 @@ func TestInsecureConfigurationFails(t *testing.T) { pluginArgs := plugin.Arg{}. SetCertPath(tlsTestSrv + fixtures.TestCrtFileExt). SetKeyPath(tlsTestSrv + fixtures.TestKeyFileExt). - SetRootCertPaths(tlsTestCA + fixtures.TestCrtFileExt). + SetCACertPaths(tlsTestCA + fixtures.TestCrtFileExt). SetTLSEnabled(true) runThisCase := func(f func(msg string)) { t.Run(tc.name, func(_ *testing.T) { @@ -386,17 +386,17 @@ func TestInsecureConfigurationFails(t *testing.T) { } } -func (m *configTLSMock) setRootCertPaths(rootCertPaths string) *configTLSMock { - m.RootCertPaths = rootCertPaths +func (m *configTLSMock) setCACertPaths(caCertPaths string) *configTLSMock { + m.CACertPaths = caCertPaths return m } func TestSecuritySetupFromConfig(t *testing.T) { var ( - fakeSampleCert = "/fake-samples/certs/server-cert" - fakeSampleKey = "/fake-samples/keys/server-key" - fakeSampleRootCertsSplit = []string{"/fake-samples/root-ca/ca-one", "/fake-samples/root-ca/ca-two"} - fakeSampleRootCerts = strings.Join(fakeSampleRootCertsSplit, string(filepath.ListSeparator)) + fakeSampleCert = "/fake-samples/certs/server-cert" + fakeSampleKey = "/fake-samples/keys/server-key" + fakeSampleCACertsSplit = []string{"/fake-samples/root-ca/ca-one", "/fake-samples/root-ca/ca-two"} + fakeSampleCACerts = strings.Join(fakeSampleCACertsSplit, string(filepath.ListSeparator)) ) tcs := []struct { name string @@ -430,18 +430,18 @@ func TestSecuritySetupFromConfig(t *testing.T) { wantManagersec: client.SecurityTLSEnabled(fakeSampleCert, fakeSampleKey, client.SecureClient), }, { - name: "TLSEnabledRootCertsForwardedToSubmodules", + name: "TLSEnabledCACertsForwardedToSubmodules", msg: func(f func(string)) { - f("having TLS enabled with root cert paths in config, plugin runner and manager receive same security values") + f("having TLS enabled with CA cert paths in config, plugin runner and manager receive same security values") }, cfg: (*configTLSMock)(GetDefaultConfig()). setTLSCertPath(fakeSampleCert). setTLSKeyPath(fakeSampleKey). - setRootCertPaths(fakeSampleRootCerts). + setCACertPaths(fakeSampleCACerts). export(), wantError: false, - wantRunnersec: client.SecurityTLSExtended(fakeSampleCert, fakeSampleKey, client.SecureClient, fakeSampleRootCertsSplit), - wantManagersec: client.SecurityTLSExtended(fakeSampleCert, fakeSampleKey, client.SecureClient, fakeSampleRootCertsSplit), + wantRunnersec: client.SecurityTLSExtended(fakeSampleCert, fakeSampleKey, client.SecureClient, fakeSampleCACertsSplit), + wantManagersec: client.SecurityTLSExtended(fakeSampleCert, fakeSampleKey, client.SecureClient, fakeSampleCACertsSplit), }, } var gotRunner *runner @@ -484,7 +484,7 @@ func TestSecuritySetupFromConfig(t *testing.T) { } func runPlugin(args plugin.Arg, pluginPath string, security client.GRPCSecurity) (*availablePlugin, error) { - ep, err := fixtures.NewExecutablePlugin(args, pluginPath) + ep, err := plugin.NewExecutablePlugin(args, pluginPath) if err != nil { panic(err) } diff --git a/control/fixtures/fixtures.go b/control/fixtures/fixtures.go index c622d0256..dde12717e 100644 --- a/control/fixtures/fixtures.go +++ b/control/fixtures/fixtures.go @@ -24,7 +24,6 @@ import ( "encoding/json" "time" - "github.com/intelsdi-x/snap/control/plugin" "github.com/intelsdi-x/snap/core" "github.com/intelsdi-x/snap/core/cdata" "github.com/intelsdi-x/snap/plugin/helper" @@ -157,19 +156,19 @@ func (m MockRequestedMetric) Namespace() core.Namespace { return m.namespace } -func NewExecutablePlugin(a plugin.Arg, path string) (*plugin.ExecutablePlugin, error) { - // Travis optimization: Try starting the plugin three times before finally - // returning an error - var e error - var ep *plugin.ExecutablePlugin - for i := 0; i < 3; i++ { - ep, e = plugin.NewExecutablePlugin(a, path) - if e == nil { - break - } - if e != nil && i == 2 { - return nil, e - } - } - return ep, nil -} +// func NewExecutablePlugin(a plugin.Arg, path string) (*plugin.ExecutablePlugin, error) { +// // Travis optimization: Try starting the plugin three times before finally +// // returning an error +// var e error +// var ep *plugin.ExecutablePlugin +// for i := 0; i < 3; i++ { +// ep, e = plugin.NewExecutablePlugin(a, path) +// if e == nil { +// break +// } +// if e != nil && i == 2 { +// return nil, e +// } +// } +// return ep, nil +// } diff --git a/control/fixtures/tls_cert_util.go b/control/fixtures/tls_cert_util.go index f9e77db13..e4a8bb8ef 100644 --- a/control/fixtures/tls_cert_util.go +++ b/control/fixtures/tls_cert_util.go @@ -60,6 +60,7 @@ type CertTestUtil struct { Prefix string } +// WritePEMFile writes block of bytes into a PEM formatted file with given header. func (u CertTestUtil) WritePEMFile(fn string, pemHeader string, b []byte) error { f, err := os.Create(fn) if err != nil { @@ -75,6 +76,8 @@ func (u CertTestUtil) WritePEMFile(fn string, pemHeader string, b []byte) error return nil } +// MakeCACertKeyPair generates asymmetric private key and certificate +// for CA, suitable for signing certificates func (u CertTestUtil) MakeCACertKeyPair(caName, ouName string, keyValidPeriod time.Duration) (caCertTpl *x509.Certificate, caCertBytes []byte, caPrivKey *rsa.PrivateKey, err error) { caPrivKey, err = rsa.GenerateKey(rand.Reader, keyBitsDefault) if err != nil { @@ -109,6 +112,8 @@ func (u CertTestUtil) MakeCACertKeyPair(caName, ouName string, keyValidPeriod ti return caCertTpl, caCertBytes, caPrivKey, nil } +// MakeSubjCertKeyPair generates a private key and a certificate for subject +// suitable for securing TLS communication func (u CertTestUtil) MakeSubjCertKeyPair(cn, ou string, keyValidPeriod time.Duration, caCertTpl *x509.Certificate, caPrivKey *rsa.PrivateKey) (subjCertBytes []byte, subjPrivKey *rsa.PrivateKey, err error) { subjPrivKey, err = rsa.GenerateKey(rand.Reader, keyBitsDefault) if err != nil { diff --git a/control/flags.go b/control/flags.go index 5259b7a6a..583acfd66 100644 --- a/control/flags.go +++ b/control/flags.go @@ -60,15 +60,15 @@ var ( flTLSCert = cli.StringFlag{ Name: "tls-cert", - Usage: "A path to PEM-encoded certificate to use for TLS channels", + Usage: "A path to PEM-encoded certificate to use for GRPC TLS channels", } flTLSKey = cli.StringFlag{ Name: "tls-key", - Usage: "A path to PEM-encoded private key file to use for TLS channels", + Usage: "A path to PEM-encoded private key file to use for GRPC TLS channels", } - flRootCertPaths = cli.StringFlag{ - Name: "root-cert-paths", - Usage: "A list of paths to root certificates or their parent directories, separated with OS path separator", + flCACertPaths = cli.StringFlag{ + Name: "ca-cert-paths", + Usage: "A list of paths to CA certificates or their parent directories, separated with OS path separator", } flControlRpcPort = cli.StringFlag{ @@ -89,5 +89,5 @@ var ( EnvVar: "SNAP_TEMP_DIR_PATH", } - Flags = []cli.Flag{flNumberOfPLs, flPluginLoadTimeout, flAutoDiscover, flPluginTrust, flKeyringPaths, flCache, flControlRpcPort, flControlRpcAddr, flTempDirPath, flTLSCert, flTLSKey, flRootCertPaths} + Flags = []cli.Flag{flNumberOfPLs, flPluginLoadTimeout, flAutoDiscover, flPluginTrust, flKeyringPaths, flCache, flControlRpcPort, flControlRpcAddr, flTempDirPath, flTLSCert, flTLSKey, flCACertPaths} ) diff --git a/control/plugin/client/grpc.go b/control/plugin/client/grpc.go index 9b7df2d3d..56aad57ca 100644 --- a/control/plugin/client/grpc.go +++ b/control/plugin/client/grpc.go @@ -82,14 +82,14 @@ type grpcClient struct { // GRPCSecurity contains data necessary to setup secure gRPC communication type GRPCSecurity struct { - TLSEnabled bool - SecureSide SecureSide - TLSCertPath string - TLSKeyPath string - RootCertPaths []string + TLSEnabled bool + SecureSide SecureSide + TLSCertPath string + TLSKeyPath string + CACertPaths []string } -// SecurityTLSEnabled generates setup object for securing gRPC communication +// SecurityTLSEnabled generates security object for securing gRPC communication func SecurityTLSEnabled(certPath, keyPath string, secureSide SecureSide) GRPCSecurity { return GRPCSecurity{ TLSEnabled: true, @@ -99,14 +99,16 @@ func SecurityTLSEnabled(certPath, keyPath string, secureSide SecureSide) GRPCSec } } -// SecurityTLSExtended generates setup object for securing gRPC communication -func SecurityTLSExtended(certPath, keyPath string, secureSide SecureSide, rootCertPaths []string) GRPCSecurity { +// SecurityTLSExtended generates security object for securing gRPC communication. +// This function accepts also a list of CA cert paths for verifying TLS participant's +// identity. +func SecurityTLSExtended(certPath, keyPath string, secureSide SecureSide, caCertPaths []string) GRPCSecurity { return GRPCSecurity{ - TLSEnabled: true, - SecureSide: secureSide, - TLSCertPath: certPath, - TLSKeyPath: keyPath, - RootCertPaths: rootCertPaths, + TLSEnabled: true, + SecureSide: secureSide, + TLSCertPath: certPath, + TLSKeyPath: keyPath, + CACertPaths: caCertPaths, } } @@ -154,7 +156,7 @@ func NewPublisherGrpcClient(address string, timeout time.Duration, security GRPC return p.(PluginPublisherClient), err } -func loadRootCerts(certPaths []string) (rootCAs *x509.CertPool, err error) { +func loadCACerts(certPaths []string) (rootCAs *x509.CertPool, err error) { var path string var filepaths []string // list potential certificate files @@ -209,14 +211,14 @@ func buildCredentials(security GRPCSecurity) (creds credentials.TransportCredent return nil, fmt.Errorf("unable to load TLS key pair: %v", err) } var rootCAs *x509.CertPool - if len(security.RootCertPaths) > 0 { - log.Debug("Loading root certificates given explicitly") - rootCAs, err = loadRootCerts(security.RootCertPaths) + if len(security.CACertPaths) > 0 { + log.Debug("Loading CA certificates given explicitly") + rootCAs, err = loadCACerts(security.CACertPaths) if err != nil { return nil, err } } else { - log.Debug("Loading root certificates from operating system") + log.Debug("Loading CA certificates from operating system") rootCAs, err = x509.SystemCertPool() if err != nil { return nil, fmt.Errorf("unable to load system-wide root TLS certificates: %v", err) diff --git a/control/plugin/plugin.go b/control/plugin/plugin.go index 0244da821..14c0371af 100644 --- a/control/plugin/plugin.go +++ b/control/plugin/plugin.go @@ -150,10 +150,10 @@ type Arg struct { // enable pprof Pprof bool - CertPath string `json:"CertPath"` - KeyPath string `json:"KeyPath"` - RootCertPaths string `json:"RootCertPaths"` - TLSEnabled bool `json:"TLSEnabled"` + CertPath string `json:"CertPath"` + KeyPath string `json:"KeyPath"` + CACertPaths string `json:"RootCertPaths"` + TLSEnabled bool `json:"TLSEnabled"` } // SetCertPath sets path to TLS certificate in plugin arguments @@ -174,9 +174,9 @@ func (a Arg) SetTLSEnabled(tlsEnabled bool) Arg { return a } -// SetRootCertPaths sets list of certificate paths for client verification -func (a Arg) SetRootCertPaths(rootCertPaths string) Arg { - a.RootCertPaths = rootCertPaths +// SetCACertPaths sets list of certificate paths for client verification +func (a Arg) SetCACertPaths(caCertPaths string) Arg { + a.CACertPaths = caCertPaths return a } diff --git a/control/plugin_manager.go b/control/plugin_manager.go index 3f34b24d1..91f6b7cde 100644 --- a/control/plugin_manager.go +++ b/control/plugin_manager.go @@ -158,18 +158,18 @@ func (l *loadedPlugins) findLatest(typeName, name string) (*loadedPlugin, error) // the struct representing a plugin that is loaded into snap type pluginDetails struct { - CheckSum [sha256.Size]byte - Exec []string - ExecPath string - IsPackage bool - Manifest *schema.ImageManifest - Path string - Signed bool - Signature []byte - CertPath string - KeyPath string - RootCertPaths string - TLSEnabled bool + CheckSum [sha256.Size]byte + Exec []string + ExecPath string + IsPackage bool + Manifest *schema.ImageManifest + Path string + Signed bool + Signature []byte + CertPath string + KeyPath string + CACertPaths string + TLSEnabled bool } type loadedPlugin struct { @@ -359,7 +359,7 @@ func (p *pluginManager) LoadPlugin(details *pluginDetails, emitter gomit.Emitter p.GenerateArgs(int(log.GetLevel())). SetCertPath(details.CertPath). SetKeyPath(details.KeyPath). - SetRootCertPaths(details.RootCertPaths). + SetCACertPaths(details.CACertPaths). SetTLSEnabled(details.TLSEnabled), commands...) if err != nil { diff --git a/control/runner.go b/control/runner.go index df4fccd9c..458cae81c 100644 --- a/control/runner.go +++ b/control/runner.go @@ -347,7 +347,7 @@ func (r *runner) runPlugin(name string, details *pluginDetails) error { ePlugin, err := plugin.NewExecutablePlugin(r.pluginManager.GenerateArgs(int(log.GetLevel())). SetCertPath(details.CertPath). SetKeyPath(details.KeyPath). - SetRootCertPaths(details.RootCertPaths). + SetCACertPaths(details.CACertPaths). SetTLSEnabled(details.TLSEnabled), commands...) if err != nil { runnerLog.WithFields(log.Fields{ diff --git a/control/runner_test.go b/control/runner_test.go index eb6279eaa..d24108fdc 100644 --- a/control/runner_test.go +++ b/control/runner_test.go @@ -336,7 +336,7 @@ func TestRunnerPluginRunning(t *testing.T) { r := newRunner() r.SetEmitter(new(MockEmitter)) a := plugin.Arg{} - exPlugin, err := fixtures.NewExecutablePlugin(a, fixtures.PluginPathMock2) + exPlugin, err := plugin.NewExecutablePlugin(a, fixtures.PluginPathMock2) if err != nil { panic(err) } @@ -358,7 +358,7 @@ func TestRunnerPluginRunning(t *testing.T) { r := newRunner() r.SetEmitter(new(MockEmitter)) a := plugin.Arg{} - exPlugin, err := fixtures.NewExecutablePlugin(a, fixtures.PluginPathMock2) + exPlugin, err := plugin.NewExecutablePlugin(a, fixtures.PluginPathMock2) if err != nil { panic(err) } @@ -376,7 +376,7 @@ func TestRunnerPluginRunning(t *testing.T) { r := newRunner() r.SetEmitter(new(MockEmitter)) a := plugin.Arg{} - exPlugin, err := fixtures.NewExecutablePlugin(a, fixtures.PluginPathMock2) + exPlugin, err := plugin.NewExecutablePlugin(a, fixtures.PluginPathMock2) if err != nil { panic(err) } @@ -393,7 +393,7 @@ func TestRunnerPluginRunning(t *testing.T) { r := newRunner() r.SetEmitter(new(MockEmitter)) a := plugin.Arg{} - exPlugin, err := fixtures.NewExecutablePlugin(a, fixtures.PluginPathMock2) + exPlugin, err := plugin.NewExecutablePlugin(a, fixtures.PluginPathMock2) if err != nil { panic(err) } @@ -410,7 +410,7 @@ func TestRunnerPluginRunning(t *testing.T) { r := newRunner() r.SetEmitter(new(MockEmitter)) a := plugin.Arg{} - exPlugin, err := fixtures.NewExecutablePlugin(a, fixtures.PluginPathMock2) + exPlugin, err := plugin.NewExecutablePlugin(a, fixtures.PluginPathMock2) if err != nil { panic(err) } @@ -431,7 +431,7 @@ func TestRunnerPluginRunning(t *testing.T) { r := newRunner() r.SetEmitter(new(MockEmitter)) a := plugin.Arg{} - exPlugin, err := fixtures.NewExecutablePlugin(a, fixtures.PluginPathMock2) + exPlugin, err := plugin.NewExecutablePlugin(a, fixtures.PluginPathMock2) if err != nil { panic(err) } @@ -464,7 +464,7 @@ func TestRunnerPluginRunning(t *testing.T) { r := newRunner() r.SetEmitter(new(MockEmitter)) a := plugin.Arg{} - exPlugin, err := fixtures.NewExecutablePlugin(a, fixtures.PluginPathMock2) + exPlugin, err := plugin.NewExecutablePlugin(a, fixtures.PluginPathMock2) if err != nil { panic(err) } diff --git a/core/plugin.go b/core/plugin.go index 44bed4894..7c6a644a6 100644 --- a/core/plugin.go +++ b/core/plugin.go @@ -122,13 +122,13 @@ type SubscribedPlugin interface { } type RequestedPlugin struct { - path string - checkSum [sha256.Size]byte - signature []byte - certPath string - keyPath string - rootCertPaths string - tlsEnabled bool + path string + checkSum [sha256.Size]byte + signature []byte + certPath string + keyPath string + caCertPaths string + tlsEnabled bool } // NewRequestedPlugin returns a Requested Plugin which represents the plugin path and signature @@ -199,9 +199,9 @@ func (p *RequestedPlugin) KeyPath() string { return p.keyPath } -// RootCertPaths returns the list of TLS root cert paths for plugin to use -func (p *RequestedPlugin) RootCertPaths() string { - return p.rootCertPaths +// CACertPaths returns the list of TLS CA cert paths for plugin to use +func (p *RequestedPlugin) CACertPaths() string { + return p.caCertPaths } // TLSEnabled returns the TLS enabled flag for requested plugin @@ -231,9 +231,9 @@ func (p *RequestedPlugin) SetKeyPath(keyPath string) { p.keyPath = keyPath } -// SetRootCertPaths sets the list of paths to TLS root certificate for plugin to use -func (p *RequestedPlugin) SetRootCertPaths(rootCertPaths string) { - p.rootCertPaths = rootCertPaths +// SetCACertPaths sets the list of paths to TLS CA certificate for plugin to use +func (p *RequestedPlugin) SetCACertPaths(caCertPaths string) { + p.caCertPaths = caCertPaths } // SetTLSEnabled sets the TLS flag on requested plugin diff --git a/mgmt/rest/client/client.go b/mgmt/rest/client/client.go index 3642afe79..0ee006a87 100644 --- a/mgmt/rest/client/client.go +++ b/mgmt/rest/client/client.go @@ -320,7 +320,7 @@ func (c *Client) pluginUploadRequest(pluginPaths []string) (*rbody.APIResponse, bufin := bufio.NewReader(file) bufins = append(bufins, bufin) if baseName := filepath.Base(pluginPath); strings.HasPrefix(baseName, v1.TLSCertPrefix) || - strings.HasPrefix(baseName, v1.TLSKeyPrefix) || strings.HasPrefix(baseName, v1.TLSRootCertsPrefix) { + strings.HasPrefix(baseName, v1.TLSKeyPrefix) || strings.HasPrefix(baseName, v1.TLSCACertsPrefix) { defer os.Remove(pluginPath) } paths = append(paths, filepath.Base(pluginPath)) diff --git a/mgmt/rest/v1/api.go b/mgmt/rest/v1/api.go index 86cd5bfdc..369a22e4f 100644 --- a/mgmt/rest/v1/api.go +++ b/mgmt/rest/v1/api.go @@ -12,8 +12,8 @@ const ( TLSCertPrefix = "crt." // TLSKeyPrefix defines a prefix for file fragment carrying path to TLS private key TLSKeyPrefix = "key." - // TLSRootCertsPrefix defines a prefix for file fragment carrying paths to TLS root certificates - TLSRootCertsPrefix = "root." + // TLSCACertsPrefix defines a prefix for file fragment carrying paths to TLS CA certificates + TLSCACertsPrefix = "cacerts." version = "v1" prefix = "/" + version diff --git a/mgmt/rest/v1/plugin.go b/mgmt/rest/v1/plugin.go index af456dd18..dd3ab771e 100644 --- a/mgmt/rest/v1/plugin.go +++ b/mgmt/rest/v1/plugin.go @@ -76,7 +76,7 @@ func (s *apiV1) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. if strings.HasPrefix(mediaType, "multipart/") { var certPath string var keyPath string - var rootCertPaths string + var caCertPaths string var signature []byte var checkSum [sha256.Size]byte lp := &rbody.PluginsLoaded{} @@ -120,7 +120,8 @@ func (s *apiV1) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. // extension, an error is returned. // If we loop around more than twice before receiving io.EOF, then // an error is returned. - + // Reception of TLS security file paths (ceritificate file, private key file, CA certificate files) + // is also taking place here. Paths are extracted and used to set up a RequestedPlugin object. switch { case i == 0: if filepath.Ext(p.FileName()) == ".asc" { @@ -150,8 +151,8 @@ func (s *apiV1) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. rbody.Write(500, rbody.FromError(e), w) return } - } else if strings.HasPrefix(p.FileName(), TLSRootCertsPrefix) { - rootCertPaths = string(b) + } else if strings.HasPrefix(p.FileName(), TLSCACertsPrefix) { + caCertPaths = string(b) // validation will take place later; take it as it is } else { e := errors.New("Error: unrecognized file was passed") @@ -175,7 +176,7 @@ func (s *apiV1) loadPlugin(w http.ResponseWriter, r *http.Request, _ httprouter. rp.SetSignature(signature) rp.SetCertPath(certPath) rp.SetKeyPath(keyPath) - rp.SetRootCertPaths(rootCertPaths) + rp.SetCACertPaths(caCertPaths) if certPath != "" && keyPath != "" { rp.SetTLSEnabled(true) } else if certPath != "" || keyPath != "" { diff --git a/snapteld.go b/snapteld.go index 1c2ce02a6..1786c28bb 100644 --- a/snapteld.go +++ b/snapteld.go @@ -856,7 +856,7 @@ func applyCmdLineFlags(cfg *Config, ctx runtimeFlagsContext) { cfg.Control.TempDirPath = setStringVal(cfg.Control.TempDirPath, ctx, "temp_dir_path") cfg.Control.TLSCertPath = setStringVal(cfg.Control.TLSCertPath, ctx, "tls-cert") cfg.Control.TLSKeyPath = setStringVal(cfg.Control.TLSKeyPath, ctx, "tls-key") - cfg.Control.RootCertPaths = setStringVal(cfg.Control.RootCertPaths, ctx, "root-cert-paths") + cfg.Control.CACertPaths = setStringVal(cfg.Control.CACertPaths, ctx, "ca-cert-paths") // next for the RESTful server related flags cfg.RestAPI.Enable = setBoolVal(cfg.RestAPI.Enable, ctx, "disable-api", invertBoolean) cfg.RestAPI.Port = setIntVal(cfg.RestAPI.Port, ctx, "api-port") diff --git a/snapteld_test.go b/snapteld_test.go index 411bd9ff0..acf3491b8 100644 --- a/snapteld_test.go +++ b/snapteld_test.go @@ -55,7 +55,7 @@ var validCmdlineFlags_input = mockFlags{ "temp_dir_path": "/no/temp/files", "tls-cert": "/no/cert/here", "tls-key": "/no/key/here", - "root-cert-paths": "/no/root/certs", + "ca-cert-paths": "/no/root/certs", "disable-api": "false", "api-port": "12400", "api-addr": "120.121.122.123", @@ -88,7 +88,7 @@ var validCmdlineFlags_expected = &Config{ TempDirPath: "/no/temp/files", TLSCertPath: "/no/cert/here", TLSKeyPath: "/no/key/here", - RootCertPaths: "/no/root/certs", + CACertPaths: "/no/root/certs", }, RestAPI: &rest.Config{ Enable: true, @@ -189,8 +189,8 @@ func (c *mockCfg) setTLSKey(tlsKeyPath string) *mockCfg { return c } -func (c *mockCfg) setRootCertPaths(rootCertPaths string) *mockCfg { - c.Control.RootCertPaths = rootCertPaths +func (c *mockCfg) setCACertPaths(caCertPaths string) *mockCfg { + c.Control.CACertPaths = caCertPaths return c } @@ -218,11 +218,11 @@ func (c *mockCfg) export() *Config { func Test_checkCmdLineFlags(t *testing.T) { testCtx := mockFlags{ - "tls-cert": "mock-cli.crt", - "tls-key": "mock-cli.key", - "root-cert-paths": "mock-ca.crt", - "api-addr": "localhost", - "api-port": "9000"} + "tls-cert": "mock-cli.crt", + "tls-key": "mock-cli.key", + "ca-cert-paths": "mock-ca.crt", + "api-addr": "localhost", + "api-port": "9000"} tests := []struct { name string msg func(func(string)) @@ -244,7 +244,7 @@ func Test_checkCmdLineFlags(t *testing.T) { f("Having valid command line flags without any TLS parameters, parsing suceeds") }, ctx: testCtx. - copyWithout("tls-cert", "tls-key", "root-cert-paths", "api-port"). + copyWithout("tls-cert", "tls-key", "ca-cert-paths", "api-port"). update("api-addr", "127.0.0.1:9002"), wantErr: false, wantPort: 9002, @@ -315,7 +315,7 @@ func Test_checkCfgSettings(t *testing.T) { setApiAddr("localhost:9000"). setTLSCert("mock-cli.crt"). setTLSKey("mock-cli.key"). - setRootCertPaths("mock-ca.crt"). + setCACertPaths("mock-ca.crt"). export(), wantErr: false, wantPort: 9000,