Plugins: allow override when allowing unsigned plugins (#28901)

* Plugins: allow override when allowing unsigned plugins

* Update pkg/plugins/plugins.go

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>

* Plugins: removed java-style setter

* Plugins: cleanup

* Update pkg/plugins/plugins.go

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>
This commit is contained in:
Leonard Gram
2020-11-09 09:50:23 +01:00
committed by GitHub
parent 5b00b500a7
commit 8fb06da34e

View File

@ -40,14 +40,17 @@ var (
pluginScanningErrors map[string]*PluginError pluginScanningErrors map[string]*PluginError
) )
type unsignedPluginConditionFunc = func(plugin *PluginBase) bool
type PluginScanner struct { type PluginScanner struct {
pluginPath string pluginPath string
errors []error errors []error
backendPluginManager backendplugin.Manager backendPluginManager backendplugin.Manager
cfg *setting.Cfg cfg *setting.Cfg
requireSigned bool requireSigned bool
log log.Logger log log.Logger
plugins map[string]*PluginBase plugins map[string]*PluginBase
allowUnsignedPluginsCondition unsignedPluginConditionFunc
} }
type PluginManager struct { type PluginManager struct {
@ -55,6 +58,10 @@ type PluginManager struct {
Cfg *setting.Cfg `inject:""` Cfg *setting.Cfg `inject:""`
log log.Logger log log.Logger
scanningErrors []error scanningErrors []error
// AllowUnsignedPluginsCondition changes the policy for allowing unsigned plugins. Signature validation only runs when plugins are starting
// and running plugins will not be terminated if they violate the new policy.
AllowUnsignedPluginsCondition unsignedPluginConditionFunc
} }
func init() { func init() {
@ -187,12 +194,13 @@ func (pm *PluginManager) scanPluginPaths() error {
// scan a directory for plugins. // scan a directory for plugins.
func (pm *PluginManager) scan(pluginDir string, requireSigned bool) error { func (pm *PluginManager) scan(pluginDir string, requireSigned bool) error {
scanner := &PluginScanner{ scanner := &PluginScanner{
pluginPath: pluginDir, pluginPath: pluginDir,
backendPluginManager: pm.BackendPluginManager, backendPluginManager: pm.BackendPluginManager,
cfg: pm.Cfg, cfg: pm.Cfg,
requireSigned: requireSigned, requireSigned: requireSigned,
log: pm.log, log: pm.log,
plugins: map[string]*PluginBase{}, plugins: map[string]*PluginBase{},
allowUnsignedPluginsCondition: pm.AllowUnsignedPluginsCondition,
} }
// 1st pass: Scan plugins, also mapping plugins to their respective directories // 1st pass: Scan plugins, also mapping plugins to their respective directories
@ -405,21 +413,13 @@ func (s *PluginScanner) validateSignature(plugin *PluginBase) *PluginError {
switch plugin.Signature { switch plugin.Signature {
case PluginSignatureUnsigned: case PluginSignatureUnsigned:
allowUnsigned := false if allowed := s.allowUnsigned(plugin); !allowed {
for _, plug := range s.cfg.PluginsAllowUnsigned {
if plug == plugin.Id {
allowUnsigned = true
break
}
}
if setting.Env != setting.Dev && !allowUnsigned {
s.log.Debug("Plugin is unsigned", "id", plugin.Id) s.log.Debug("Plugin is unsigned", "id", plugin.Id)
s.errors = append(s.errors, fmt.Errorf("plugin %q is unsigned", plugin.Id)) s.errors = append(s.errors, fmt.Errorf("plugin %q is unsigned", plugin.Id))
return &PluginError{ return &PluginError{
ErrorCode: signatureMissing, ErrorCode: signatureMissing,
} }
} }
s.log.Warn("Running an unsigned backend plugin", "pluginID", plugin.Id, "pluginDir", s.log.Warn("Running an unsigned backend plugin", "pluginID", plugin.Id, "pluginDir",
plugin.PluginDir) plugin.PluginDir)
return nil return nil
@ -440,6 +440,24 @@ func (s *PluginScanner) validateSignature(plugin *PluginBase) *PluginError {
} }
} }
func (s *PluginScanner) allowUnsigned(plugin *PluginBase) bool {
if s.allowUnsignedPluginsCondition != nil {
return s.allowUnsignedPluginsCondition(plugin)
}
if setting.Env == setting.Dev {
return true
}
for _, plug := range s.cfg.PluginsAllowUnsigned {
if plug == plugin.Id {
return true
}
}
return false
}
func ScanningErrors() []PluginError { func ScanningErrors() []PluginError {
scanningErrs := make([]PluginError, 0) scanningErrs := make([]PluginError, 0)
for id, e := range pluginScanningErrors { for id, e := range pluginScanningErrors {