Plugins: Add support for signature manifest V2 (#29240)

* add support for signing manifest v2

* add log and fix var name

* shorten comment

* improve comment

* remove unnecessary param

* improve naming

* reformat

* rename var

* refactor test

* remove unnecessary assert

* simplify test requirements

* add more test cases

* address feedback

* revert naming

* flip tracking missing

* fix check

* Trigger Build
This commit is contained in:
Will Browne
2020-12-11 12:57:57 +01:00
committed by GitHub
parent e2351f7951
commit a515c54404
18 changed files with 557 additions and 58 deletions

View File

@ -145,7 +145,7 @@ func (pm *PluginManager) Init() error {
for _, p := range Plugins {
if p.IsCorePlugin {
p.Signature = PluginSignatureInternal
p.Signature = pluginSignatureInternal
} else {
metrics.SetPluginBuildInformation(p.Id, p.Type, p.Info.Version)
}
@ -370,7 +370,20 @@ func (s *PluginScanner) loadPlugin(pluginJSONFilePath string) error {
}
pluginCommon.PluginDir = filepath.Dir(pluginJSONFilePath)
pluginCommon.Signature = getPluginSignatureState(s.log, &pluginCommon)
pluginCommon.Files, err = collectPluginFilesWithin(pluginCommon.PluginDir)
if err != nil {
s.log.Warn("Could not collect plugin file information in directory", "pluginID", pluginCommon.Id, "dir", pluginCommon.PluginDir)
return err
}
signatureState, err := getPluginSignatureState(s.log, &pluginCommon)
if err != nil {
s.log.Warn("Could not get plugin signature state", "pluginID", pluginCommon.Id, "err", err)
return err
}
pluginCommon.Signature = signatureState.Status
pluginCommon.SignatureType = signatureState.Type
pluginCommon.SignatureOrg = signatureState.SigningOrg
s.plugins[currentDir] = &pluginCommon
@ -383,21 +396,21 @@ func (*PluginScanner) IsBackendOnlyPlugin(pluginType string) bool {
// validateSignature validates a plugin's signature.
func (s *PluginScanner) validateSignature(plugin *PluginBase) *PluginError {
if plugin.Signature == PluginSignatureValid {
if plugin.Signature == pluginSignatureValid {
s.log.Debug("Plugin has valid signature", "id", plugin.Id)
return nil
}
if plugin.Root != nil {
// If a descendant plugin with invalid signature, set signature to that of root
if plugin.IsCorePlugin || plugin.Signature == PluginSignatureInternal {
if plugin.IsCorePlugin || plugin.Signature == pluginSignatureInternal {
s.log.Debug("Not setting descendant plugin's signature to that of root since it's core or internal",
"plugin", plugin.Id, "signature", plugin.Signature, "isCore", plugin.IsCorePlugin)
} else {
s.log.Debug("Setting descendant plugin's signature to that of root", "plugin", plugin.Id,
"root", plugin.Root.Id, "signature", plugin.Signature, "rootSignature", plugin.Root.Signature)
plugin.Signature = plugin.Root.Signature
if plugin.Signature == PluginSignatureValid {
if plugin.Signature == pluginSignatureValid {
s.log.Debug("Plugin has valid signature (inherited from root)", "id", plugin.Id)
return nil
}
@ -414,7 +427,7 @@ func (s *PluginScanner) validateSignature(plugin *PluginBase) *PluginError {
}
switch plugin.Signature {
case PluginSignatureUnsigned:
case pluginSignatureUnsigned:
if allowed := s.allowUnsigned(plugin); !allowed {
s.log.Debug("Plugin is unsigned", "id", plugin.Id)
s.errors = append(s.errors, fmt.Errorf("plugin %q is unsigned", plugin.Id))
@ -425,13 +438,13 @@ func (s *PluginScanner) validateSignature(plugin *PluginBase) *PluginError {
s.log.Warn("Running an unsigned backend plugin", "pluginID", plugin.Id, "pluginDir",
plugin.PluginDir)
return nil
case PluginSignatureInvalid:
case pluginSignatureInvalid:
s.log.Debug("Plugin %q has an invalid signature", plugin.Id)
s.errors = append(s.errors, fmt.Errorf("plugin %q has an invalid signature", plugin.Id))
return &PluginError{
ErrorCode: signatureInvalid,
}
case PluginSignatureModified:
case pluginSignatureModified:
s.log.Debug("Plugin %q has a modified signature", plugin.Id)
s.errors = append(s.errors, fmt.Errorf("plugin %q's signature has been modified", plugin.Id))
return &PluginError{
@ -506,3 +519,23 @@ func GetPluginMarkdown(pluginId string, name string) ([]byte, error) {
}
return data, nil
}
// gets plugin filenames that require verification for plugin signing
func collectPluginFilesWithin(rootDir string) ([]string, error) {
var files []string
err := filepath.Walk(rootDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && info.Name() != "MANIFEST.txt" {
file, err := filepath.Rel(rootDir, path)
if err != nil {
return err
}
files = append(files, file)
}
return nil
})
return files, err
}