Move unfinished or suspended packages to feature branches
This commit is contained in:
@@ -1,102 +0,0 @@
|
||||
package index
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/safing/portbase/database/record"
|
||||
"github.com/safing/portbase/utils"
|
||||
)
|
||||
|
||||
// ProfileIndex links an Identifier to Profiles
|
||||
type ProfileIndex struct {
|
||||
record.Base
|
||||
sync.Mutex
|
||||
|
||||
ID string
|
||||
|
||||
UserProfiles []string
|
||||
StampProfiles []string
|
||||
}
|
||||
|
||||
func makeIndexRecordKey(fpType, id string) string {
|
||||
return fmt.Sprintf("index:profiles/%s:%s", fpType, base64.RawURLEncoding.EncodeToString([]byte(id)))
|
||||
}
|
||||
|
||||
// NewIndex returns a new ProfileIndex.
|
||||
func NewIndex(id string) *ProfileIndex {
|
||||
return &ProfileIndex{
|
||||
ID: id,
|
||||
}
|
||||
}
|
||||
|
||||
// AddUserProfile adds a User Profile to the index.
|
||||
func (pi *ProfileIndex) AddUserProfile(identifier string) (changed bool) {
|
||||
if !utils.StringInSlice(pi.UserProfiles, identifier) {
|
||||
pi.UserProfiles = append(pi.UserProfiles, identifier)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// AddStampProfile adds a Stamp Profile to the index.
|
||||
func (pi *ProfileIndex) AddStampProfile(identifier string) (changed bool) {
|
||||
if !utils.StringInSlice(pi.StampProfiles, identifier) {
|
||||
pi.StampProfiles = append(pi.StampProfiles, identifier)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveUserProfile removes a profile from the index.
|
||||
func (pi *ProfileIndex) RemoveUserProfile(id string) {
|
||||
pi.UserProfiles = utils.RemoveFromStringSlice(pi.UserProfiles, id)
|
||||
}
|
||||
|
||||
// RemoveStampProfile removes a profile from the index.
|
||||
func (pi *ProfileIndex) RemoveStampProfile(id string) {
|
||||
pi.StampProfiles = utils.RemoveFromStringSlice(pi.StampProfiles, id)
|
||||
}
|
||||
|
||||
// Get gets a ProfileIndex from the database.
|
||||
func Get(fpType, id string) (*ProfileIndex, error) {
|
||||
key := makeIndexRecordKey(fpType, id)
|
||||
|
||||
r, err := indexDB.Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// unwrap
|
||||
if r.IsWrapped() {
|
||||
// only allocate a new struct, if we need it
|
||||
new := &ProfileIndex{}
|
||||
err = record.Unwrap(r, new)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return new, nil
|
||||
}
|
||||
|
||||
// or adjust type
|
||||
new, ok := r.(*ProfileIndex)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("record not of type *ProfileIndex, but %T", r)
|
||||
}
|
||||
return new, nil
|
||||
}
|
||||
|
||||
// Save saves the Identifiers to the database
|
||||
func (pi *ProfileIndex) Save() error {
|
||||
if !pi.KeyIsSet() {
|
||||
if pi.ID != "" {
|
||||
pi.SetKey(makeIndexRecordKey(pi.ID))
|
||||
} else {
|
||||
return errors.New("missing identification Key")
|
||||
}
|
||||
}
|
||||
|
||||
return indexDB.Put(pi)
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package index
|
||||
|
||||
import (
|
||||
"github.com/safing/portbase/database"
|
||||
"github.com/safing/portbase/database/query"
|
||||
"github.com/safing/portbase/database/record"
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portbase/modules"
|
||||
|
||||
"github.com/safing/portmaster/profile"
|
||||
)
|
||||
|
||||
// FIXME: listen for profile changes and update the index
|
||||
|
||||
var (
|
||||
indexDB = database.NewInterface(&database.Options{
|
||||
Local: true, // we want to access crownjewel records
|
||||
AlwaysMakeCrownjewel: true, // never sync the index
|
||||
})
|
||||
indexSub *database.Subscription
|
||||
|
||||
shutdownIndexer = make(chan struct{})
|
||||
)
|
||||
|
||||
func init() {
|
||||
modules.Register("profile:index", nil, start, stop, "core", "profile")
|
||||
}
|
||||
|
||||
func start() (err error) {
|
||||
indexSub, err = indexDB.Subscribe(query.New("core:profiles/user/"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func stop() error {
|
||||
close(shutdownIndexer)
|
||||
indexSub.Cancel()
|
||||
return nil
|
||||
}
|
||||
|
||||
func indexer() {
|
||||
for {
|
||||
select {
|
||||
case <-shutdownIndexer:
|
||||
return
|
||||
case r := <-indexSub.Feed:
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
|
||||
prof := ensureProfile(r)
|
||||
if prof != nil {
|
||||
for _, fp := range prof.Fingerprints {
|
||||
if fp.MatchesOS() && fp.Type == "full_path" {
|
||||
|
||||
// get Profile and ensure identifier is set
|
||||
pi, err := Get("full_path", fp.Value)
|
||||
if err != nil {
|
||||
if err == database.ErrNotFound {
|
||||
pi = NewIndex(id)
|
||||
} else {
|
||||
log.Errorf("profile/index: could not save updated profile index: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if pi.AddUserProfile(prof.ID) {
|
||||
err := pi.Save()
|
||||
if err != nil {
|
||||
log.Errorf("profile/index: could not save updated profile index: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ensureProfile(r record.Record) *profile.Profile {
|
||||
// unwrap
|
||||
if r.IsWrapped() {
|
||||
// only allocate a new struct, if we need it
|
||||
new := &profile.Profile{}
|
||||
err := record.Unwrap(r, new)
|
||||
if err != nil {
|
||||
log.Errorf("profile/index: could not unwrap Profile: %s", err)
|
||||
return nil
|
||||
}
|
||||
return new
|
||||
}
|
||||
|
||||
// or adjust type
|
||||
new, ok := r.(*profile.Profile)
|
||||
if !ok {
|
||||
log.Errorf("profile/index: record not of type *Profile, but %T", r)
|
||||
return nil
|
||||
}
|
||||
return new
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package matching
|
||||
|
||||
import (
|
||||
"github.com/safing/portbase/database"
|
||||
)
|
||||
|
||||
// core:profiles/user/12345-1234-125-1234-1235
|
||||
// core:profiles/special/default
|
||||
// /global
|
||||
// core:profiles/stamp/12334-1235-1234-5123-1234
|
||||
// core:profiles/identifier/base64
|
||||
|
||||
var (
|
||||
profileDB = database.NewInterface(&database.Options{
|
||||
Local: true, // we want to access crownjewel records (indexes are)
|
||||
})
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
package matcher
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/safing/portmaster/process"
|
||||
"github.com/safing/portmaster/profile"
|
||||
)
|
||||
|
||||
// CheckFingerprints checks what fingerprints match and returns the total score.
|
||||
func CheckFingerprints(proc *process.Process, prof *profile.Profile) (score int, err error) {
|
||||
// FIXME: kinda a dummy for now
|
||||
|
||||
for _, fp := range prof.Fingerprints {
|
||||
if strings.HasPrefix(fp, "fullpath:") {
|
||||
if fp[9:] == proc.Path {
|
||||
return 3, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package matcher
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/safing/portmaster/process"
|
||||
"github.com/safing/portmaster/profile"
|
||||
)
|
||||
|
||||
// GetIdentificationPath returns the identifier for the given process (linux edition).
|
||||
func GetIdentificationPath(p *process.Process) string {
|
||||
splittedPath := strings.Split(p.Path, "/")
|
||||
if len(splittedPath) > 3 {
|
||||
return fmt.Sprintf("%s%s", profile.IdentifierPrefix, strings.Join(splittedPath[len(splittedPath)-3:len(splittedPath)], "/"))
|
||||
}
|
||||
return fmt.Sprintf("%s%s", profile.IdentifierPrefix, p.Path)
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package matcher
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/safing/portmaster/process"
|
||||
)
|
||||
|
||||
func TestGetIdentifierLinux(t *testing.T) {
|
||||
p := &process.Process{
|
||||
Path: "/usr/lib/firefox/firefox",
|
||||
}
|
||||
|
||||
if GetIdentificationPath(p) != "lin:lib/firefox/firefox" {
|
||||
t.Fatal("mismatch!")
|
||||
}
|
||||
|
||||
p = &process.Process{
|
||||
Path: "/opt/start",
|
||||
}
|
||||
|
||||
if GetIdentificationPath(p) != "lin:/opt/start" {
|
||||
t.Fatal("mismatch!")
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package matcher
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/safing/portbase/log"
|
||||
"github.com/safing/portmaster/process"
|
||||
"github.com/safing/portmaster/profile"
|
||||
"github.com/safing/portmaster/profile/index"
|
||||
)
|
||||
|
||||
// GetProfileSet finds a local profile.
|
||||
func GetProfileSet(proc *process.Process) (set *profile.ProfileSet, err error) {
|
||||
|
||||
identPath := GetIdentificationPath(proc)
|
||||
pi, err := index.GetIndex(identPath)
|
||||
|
||||
var bestScore int
|
||||
var bestProfile *profile.Profile
|
||||
|
||||
for _, id := range pi.UserProfiles {
|
||||
prof, err := profile.GetUserProfile(id)
|
||||
if err != nil {
|
||||
log.Errorf("profile/matcher: failed to load profile: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
score, err := CheckFingerprints(proc, prof)
|
||||
if score > bestScore {
|
||||
bestScore = score
|
||||
bestProfile = prof
|
||||
}
|
||||
}
|
||||
|
||||
if bestProfile == nil {
|
||||
bestProfile = ProfileFromProcess(proc)
|
||||
}
|
||||
|
||||
// FIXME: fetch stamp profile
|
||||
set = profile.NewSet(bestProfile, nil)
|
||||
return set, nil
|
||||
}
|
||||
|
||||
// ProfileFromProcess creates an initial profile based on the given process.
|
||||
func ProfileFromProcess(proc *process.Process) *profile.Profile {
|
||||
new := profile.New()
|
||||
|
||||
splittedPath := strings.Split(proc.Path, "/")
|
||||
new.Name = strings.ToTitle(splittedPath[len(splittedPath)-1])
|
||||
|
||||
new.Identifiers = append(new.Identifiers, GetIdentificationPath(proc))
|
||||
new.Fingerprints = append(new.Fingerprints, fmt.Sprintf("fullpath:%s", proc.Path))
|
||||
|
||||
err := new.Save(profile.UserNamespace)
|
||||
if err != nil {
|
||||
log.Errorf("profile/matcher: could not save new profile: %s", new.Name)
|
||||
}
|
||||
|
||||
return new
|
||||
}
|
||||
Reference in New Issue
Block a user