2017-01-13 18:35:25 +00:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
2017-03-15 15:55:30 +00:00
|
|
|
"context"
|
2017-01-13 18:35:25 +00:00
|
|
|
"strconv"
|
|
|
|
|
2017-06-22 19:50:45 +00:00
|
|
|
"github.com/kolide/fleet/server/kolide"
|
2017-01-13 18:35:25 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func (vm validationMiddleware) ImportConfig(ctx context.Context, cfg *kolide.ImportConfig) (*kolide.ImportConfigResponse, error) {
|
|
|
|
var invalid invalidArgumentError
|
|
|
|
vm.validateConfigOptions(cfg, &invalid)
|
|
|
|
vm.validatePacks(cfg, &invalid)
|
|
|
|
vm.validateDecorator(cfg, &invalid)
|
|
|
|
vm.validateYARA(cfg, &invalid)
|
|
|
|
if invalid.HasErrors() {
|
|
|
|
return nil, invalid
|
|
|
|
}
|
|
|
|
return vm.Service.ImportConfig(ctx, cfg)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (vm validationMiddleware) validateYARA(cfg *kolide.ImportConfig, argErrs *invalidArgumentError) {
|
|
|
|
if cfg.YARA != nil {
|
|
|
|
if cfg.YARA.FilePaths == nil {
|
|
|
|
argErrs.Append("yara", "missing file_paths")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if cfg.YARA.Signatures == nil {
|
|
|
|
argErrs.Append("yara", "missing signatures")
|
|
|
|
}
|
|
|
|
for fileSection, sigs := range cfg.YARA.FilePaths {
|
|
|
|
if cfg.FileIntegrityMonitoring == nil {
|
|
|
|
argErrs.Append("yara", "missing file paths section")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if _, ok := cfg.FileIntegrityMonitoring[fileSection]; !ok {
|
|
|
|
argErrs.Appendf("yara", "missing referenced file_paths section '%s'", fileSection)
|
|
|
|
}
|
|
|
|
for _, sig := range sigs {
|
|
|
|
if _, ok := cfg.YARA.Signatures[sig]; !ok {
|
|
|
|
argErrs.Appendf(
|
|
|
|
"yara",
|
|
|
|
"missing signature '%s' referenced in '%s'",
|
|
|
|
sig,
|
|
|
|
fileSection,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (vm validationMiddleware) validateDecorator(cfg *kolide.ImportConfig, argErrs *invalidArgumentError) {
|
|
|
|
if cfg.Decorators != nil {
|
|
|
|
for str := range cfg.Decorators.Interval {
|
|
|
|
val, err := strconv.ParseInt(str, 10, 32)
|
|
|
|
if err != nil {
|
|
|
|
argErrs.Appendf("decorators", "interval '%s' must be an integer", str)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if val%60 != 0 {
|
|
|
|
|
|
|
|
argErrs.Appendf("decorators", "interval '%d' must be divisible by 60", val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (vm validationMiddleware) validateConfigOptions(cfg *kolide.ImportConfig, argErrs *invalidArgumentError) {
|
|
|
|
if cfg.Options != nil {
|
|
|
|
for optName, optValue := range cfg.Options {
|
|
|
|
opt, err := vm.ds.OptionByName(string(optName))
|
|
|
|
if err != nil {
|
|
|
|
// skip validation for an option we don't know about, this will generate
|
|
|
|
// a warning in the service layer
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if !opt.SameType(optValue) {
|
|
|
|
argErrs.Appendf("options", "invalid type for '%s'", optName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (vm validationMiddleware) validatePacks(cfg *kolide.ImportConfig, argErrs *invalidArgumentError) {
|
|
|
|
if cfg.Packs != nil {
|
|
|
|
for packName, pack := range cfg.Packs {
|
|
|
|
// if glob packs is defined we expect at least one external pack
|
|
|
|
if packName == kolide.GlobPacks {
|
|
|
|
if len(cfg.GlobPackNames) == 0 {
|
|
|
|
argErrs.Append("external_packs", "missing glob packs")
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// make sure that each glob pack has JSON content
|
|
|
|
for _, p := range cfg.GlobPackNames {
|
2017-04-24 00:41:27 +00:00
|
|
|
if pd, ok := cfg.ExternalPacks[p]; !ok {
|
2017-01-13 18:35:25 +00:00
|
|
|
argErrs.Appendf("external_packs", "missing content for '%s'", p)
|
2017-04-24 00:41:27 +00:00
|
|
|
} else {
|
|
|
|
vm.validatePackContents(p, pd, argErrs)
|
2017-01-13 18:35:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// if value is a string we expect a file path, in this case, the user has to supply the
|
|
|
|
// contents of said file which we store in ExternalPacks, if it's not there we need to
|
|
|
|
// raise an error
|
2017-04-24 00:41:27 +00:00
|
|
|
switch val := pack.(type) {
|
2017-01-13 18:35:25 +00:00
|
|
|
case string:
|
2017-04-24 00:41:27 +00:00
|
|
|
if pd, ok := cfg.ExternalPacks[packName]; !ok {
|
2017-01-13 18:35:25 +00:00
|
|
|
argErrs.Appendf("external_packs", "missing content for '%s'", packName)
|
2017-04-24 00:41:27 +00:00
|
|
|
} else {
|
|
|
|
vm.validatePackContents(packName, pd, argErrs)
|
2017-01-13 18:35:25 +00:00
|
|
|
}
|
2017-04-24 00:41:27 +00:00
|
|
|
case kolide.PackDetails:
|
|
|
|
vm.validatePackContents(packName, val, argErrs)
|
2017-01-13 18:35:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-04-24 00:41:27 +00:00
|
|
|
|
|
|
|
func (vm validationMiddleware) validatePackContents(packName string, pack kolide.PackDetails, argErrs *invalidArgumentError) {
|
|
|
|
switch pack.Platform {
|
|
|
|
case "", "darwin", "freebsd", "windows", "linux", "any", "all":
|
|
|
|
default:
|
|
|
|
argErrs.Appendf("pack", "'%s' is not a valid platform", pack.Platform)
|
|
|
|
}
|
|
|
|
}
|