Skip to content

Commit 34b7bf5

Browse files
committed
Add secure loader option to config.yaml
Now users may specify the sha256 checksum of each plugin in config.yaml, an example can be found in the following: ``` ratsd: secure-loader: true plugins: plugin1: $checksum ``` Signed-off-by: Ian Chin Wang <ian.chin.wang@oracle.com>
1 parent 362202b commit 34b7bf5

File tree

3 files changed

+78
-11
lines changed

3 files changed

+78
-11
lines changed

cmd/main.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type cfg struct {
2424
CertKey string `mapstructure:"cert-key" config:"zerodefault"`
2525
PluginDir string `mapstructure:"plugin-dir" config:"zerodefault"`
2626
ListOptions string `mapstructure:"list-options" valid:"in(all|selected)"`
27+
SecureLoader bool `mapstructure:"secure-loader" config:"zerodefault"`
2728
}
2829

2930
func (o cfg) Validate() error {
@@ -76,8 +77,22 @@ func main() {
7677
}
7778

7879
// Load sub-attesters from the path specified in config.yaml
79-
pluginManager, err := plugin.CreateGoPluginManager(
80-
cfg.PluginDir, log.Named("plugin"))
80+
pluginLoader, err := plugin.CreateGoPluginLoader(cfg.PluginDir, log.Named("plugin"))
81+
if err != nil {
82+
log.Fatalf("could not create the plugin loader: %v", err)
83+
}
84+
if cfg.SecureLoader {
85+
subs, err := config.GetSubs(v, "plugins")
86+
if err != nil {
87+
log.Fatalf("failed to enable secure loader: %v", err)
88+
}
89+
if err := pluginLoader.SetChecksum(subs["plugins"]); err != nil {
90+
log.Fatalf("secure loader failed to set plugin checksum: %v", err)
91+
}
92+
}
93+
94+
pluginManager, err := plugin.CreateGoPluginManagerWithLoader(
95+
pluginLoader, log.Named("plugin"))
8196

8297
if err != nil {
8398
log.Fatalf("could not create the plugin manager: %v", err)

plugin/goplugin_context.go

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
package plugin
44

55
import (
6+
"crypto/sha256"
67
"fmt"
78
"os/exec"
9+
"path/filepath"
810
"strings"
911

1012
"github.com/hashicorp/go-plugin"
@@ -42,15 +44,31 @@ func createPluginContext(
4244
path string,
4345
logger *zap.SugaredLogger,
4446
) (*PluginContext, error) {
45-
client := plugin.NewClient(
46-
&plugin.ClientConfig{
47-
HandshakeConfig: handshakeConfig,
48-
Plugins: loader.pluginMap,
49-
Cmd: exec.Command(path),
50-
Logger: log.NewInternalLogger(logger),
51-
AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
52-
},
53-
)
47+
cfg := &plugin.ClientConfig{
48+
HandshakeConfig: handshakeConfig,
49+
Plugins: loader.pluginMap,
50+
Cmd: exec.Command(path),
51+
Logger: log.NewInternalLogger(logger),
52+
AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC},
53+
}
54+
55+
if len(loader.pluginChecksum) > 0 {
56+
basename := filepath.Base(path)
57+
pluginName := strings.TrimSuffix(basename, filepath.Ext(basename))
58+
59+
checksum, ok := loader.pluginChecksum[pluginName]
60+
if !ok {
61+
return nil, fmt.Errorf("the checksum for plugin %s is missing", pluginName)
62+
}
63+
64+
secureConfig := &plugin.SecureConfig{
65+
Checksum:[]byte(checksum),
66+
Hash: sha256.New(),
67+
}
68+
cfg.SecureConfig = secureConfig
69+
}
70+
71+
client := plugin.NewClient(cfg)
5472

5573
rpcClient, err := client.Client()
5674
if err != nil {

plugin/goplugin_loader.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
package plugin
44

55
import (
6+
"encoding/hex"
67
"errors"
78
"fmt"
89

910
"github.com/hashicorp/go-plugin"
11+
"github.com/spf13/viper"
1012
"go.uber.org/zap"
1113
)
1214

@@ -23,6 +25,7 @@ type GoPluginLoader struct {
2325

2426
logger *zap.SugaredLogger
2527
loadedByName map[string]*PluginContext
28+
pluginChecksum map[string][]byte
2629

2730
// This gets specified as Plugins when creating a new go-plugin client.
2831
pluginMap map[string]plugin.Plugin
@@ -44,6 +47,7 @@ func CreateGoPluginLoader(
4447
func (o *GoPluginLoader) Init(dir string) error {
4548
o.pluginMap = make(map[string]plugin.Plugin)
4649
o.loadedByName = make(map[string]*PluginContext)
50+
o.pluginChecksum = make(map[string][]byte)
4751
o.Location = dir
4852

4953
return nil
@@ -55,6 +59,36 @@ func (o *GoPluginLoader) Close() {
5559
}
5660
}
5761

62+
func (o *GoPluginLoader) SetChecksum(v *viper.Viper) error {
63+
for _, name := range v.AllKeys() {
64+
sha256sum := v.Get(name)
65+
switch t := sha256sum.(type) {
66+
case string:
67+
o.logger.Debugw("registered plugin checksum",
68+
"name", name,
69+
"checksum", t,
70+
)
71+
72+
checksum, err := hex.DecodeString(t)
73+
if err != nil {
74+
return fmt.Errorf(
75+
"failed to load sha256 checksum for %s: %v",
76+
name, err,
77+
)
78+
}
79+
80+
o.pluginChecksum[name] = checksum
81+
default:
82+
return fmt.Errorf(
83+
"invalid checksum for plugin %q: expected string, got %T",
84+
name, t,
85+
)
86+
}
87+
}
88+
89+
return nil
90+
}
91+
5892
func RegisterGoPluginUsing(loader *GoPluginLoader, name string) error {
5993
if _, ok := loader.pluginMap[name]; ok {
6094
return fmt.Errorf("plugin for %q is already registred", name)

0 commit comments

Comments
 (0)