safing-portmaster/profiles/framework.go
2018-08-13 14:14:27 +02:00

76 lines
2.4 KiB
Go

// Copyright Safing ICS Technologies GmbH. Use of this source code is governed by the AGPL license that can be found in the LICENSE file.
package profiles
import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/Safing/safing-core/log"
)
type Framework struct {
// go hirarchy up
FindParent uint8 `json:",omitempty bson:",omitempty"`
// get path from parent, amount of levels to go up the tree (1 means parent, 2 means parent of parents, and so on)
MergeWithParent bool `json:",omitempty bson:",omitempty"`
// instead of getting the path of the parent, merge with it by presenting connections as if they were from that parent
// go hirarchy down
Find string `json:",omitempty bson:",omitempty"`
// Regular expression for finding path elements
Build string `json:",omitempty bson:",omitempty"`
// Path definitions for building path
Virtual bool `json:",omitempty bson:",omitempty"`
// Treat resulting path as virtual, do not check if valid
}
func (f *Framework) GetNewPath(command string, cwd string) (string, error) {
// "/usr/bin/python script"
// to
// "/path/to/script"
regex, err := regexp.Compile(f.Find)
if err != nil {
return "", fmt.Errorf("profiles(framework): failed to compile framework regex: %s", err)
}
matched := regex.FindAllStringSubmatch(command, -1)
if len(matched) == 0 || len(matched[0]) < 2 {
return "", fmt.Errorf("profiles(framework): regex \"%s\" for constructing path did not match command \"%s\"", f.Find, command)
}
var lastError error
var buildPath string
for _, buildPath = range strings.Split(f.Build, "|") {
buildPath = strings.Replace(buildPath, "{CWD}", cwd, -1)
for i := 1; i < len(matched[0]); i++ {
buildPath = strings.Replace(buildPath, fmt.Sprintf("{%d}", i), matched[0][i], -1)
}
buildPath = filepath.Clean(buildPath)
if !f.Virtual {
if !strings.HasPrefix(buildPath, "~/") && !filepath.IsAbs(buildPath) {
lastError = fmt.Errorf("constructed path \"%s\" from framework is not absolute", buildPath)
continue
}
if _, err := os.Stat(buildPath); os.IsNotExist(err) {
lastError = fmt.Errorf("constructed path \"%s\" does not exist", buildPath)
continue
}
}
lastError = nil
break
}
if lastError != nil {
return "", fmt.Errorf("profiles(framework): failed to construct valid path, last error: %s", lastError)
}
log.Tracef("profiles(framework): transformed \"%s\" (%s) to \"%s\"", command, cwd, buildPath)
return buildPath, nil
}