Complete first alpha version

This commit is contained in:
Daniel
2018-12-12 19:18:23 +01:00
parent 8c11a35590
commit f35872ec51
36 changed files with 624 additions and 293 deletions

View File

@@ -12,9 +12,9 @@ import (
// Namespaces
const (
userNamespace = "user"
stampNamespace = "stamp"
specialNamespace = "special"
UserNamespace = "user"
StampNamespace = "stamp"
SpecialNamespace = "special"
)
var (

View File

@@ -90,7 +90,7 @@ func Get(fpType, id string) (*ProfileIndex, error) {
// Save saves the Identifiers to the database
func (pi *ProfileIndex) Save() error {
if pi.Key() == "" {
if !pi.KeyIsSet() {
if pi.ID != "" {
pi.SetKey(makeIndexRecordKey(pi.ID))
} else {

View File

@@ -7,7 +7,7 @@ var (
)
func init() {
modules.Register("profile", nil, start, stop, "database")
modules.Register("profile", nil, start, stop, "global", "database")
}
func start() error {

View File

@@ -33,7 +33,9 @@ func TestPorts(t *testing.T) {
},
},
}
if ports.String() != "TCP:[permit:22], <UDP:[deny:80-81], 93:[permit:93]" {
if ports.String() != "TCP:[permit:22], <UDP:[deny:80-81], 93:[permit:93]" &&
ports.String() != "93:[permit:93], TCP:[permit:22], <UDP:[deny:80-81]" &&
ports.String() != "<UDP:[deny:80-81], 93:[permit:93], TCP:[permit:22]" {
t.Errorf("unexpected result: %s", ports.String())
}

View File

@@ -28,6 +28,11 @@ type Profile struct {
// Icon is a path to the icon and is either prefixed "f:" for filepath, "d:" for a database path or "e:" for the encoded data.
Icon string
// User Profile Only
LinkedPath string `json:",omitempty"`
StampProfileID string `json:",omitempty"`
StampProfileAssigned int64 `json:",omitempty"`
// Fingerprints
Fingerprints []*Fingerprint
@@ -37,24 +42,22 @@ type Profile struct {
Domains Domains
Ports Ports
// User Profile Only
CoupledPath string `json:",omitempty"`
StampProfileKey string `json:",omitempty"`
StampProfileAssigned int64 `json:",omitempty"`
// If a Profile is declared as a Framework (i.e. an Interpreter and the likes), then the real process must be found
// Framework *Framework `json:",omitempty bson:",omitempty"`
// When this Profile was approximately last used (for performance reasons not every single usage is saved)
Created int64
ApproxLastUsed int64
}
// New returns a new Profile.
func New() *Profile {
return &Profile{}
return &Profile{
Created: time.Now().Unix(),
}
}
func makeProfileKey(namespace, ID string) string {
func MakeProfileKey(namespace, ID string) string {
return fmt.Sprintf("core:profiles/%s/%s", namespace, ID)
}
@@ -68,11 +71,11 @@ func (profile *Profile) Save(namespace string) error {
profile.ID = u.String()
}
if profile.Key() == "" {
if !profile.KeyIsSet() {
if namespace == "" {
return fmt.Errorf("no key or namespace defined for profile %s", profile.String())
}
profile.SetKey(makeProfileKey(namespace, profile.ID))
profile.SetKey(MakeProfileKey(namespace, profile.ID))
}
return profileDB.Put(profile)
@@ -99,23 +102,24 @@ func (profile *Profile) DetailedString() string {
// GetUserProfile loads a profile from the database.
func GetUserProfile(ID string) (*Profile, error) {
return getProfile(userNamespace, ID)
return getProfile(UserNamespace, ID)
}
// GetStampProfile loads a profile from the database.
func GetStampProfile(ID string) (*Profile, error) {
return getProfile(stampNamespace, ID)
return getProfile(StampNamespace, ID)
}
func getProfile(namespace, ID string) (*Profile, error) {
r, err := profileDB.Get(makeProfileKey(namespace, ID))
r, err := profileDB.Get(MakeProfileKey(namespace, ID))
if err != nil {
return nil, err
}
return ensureProfile(r)
return EnsureProfile(r)
}
func ensureProfile(r record.Record) (*Profile, error) {
// EnsureProfile ensures that the given record is a *Profile, and returns it.
func EnsureProfile(r record.Record) (*Profile, error) {
// unwrap
if r.IsWrapped() {
// only allocate a new struct, if we need it

View File

@@ -21,8 +21,8 @@ type Set struct {
// Stamp
// Default
securityLevel uint8
independent bool
combinedSecurityLevel uint8
independent bool
}
// NewSet returns a new profile set with given the profiles.
@@ -40,6 +40,11 @@ func NewSet(user, stamp *Profile) *Set {
return new
}
// UserProfile returns the user profile.
func (set *Set) UserProfile() *Profile {
return set.profiles[0]
}
// Update gets the new global and default profile and updates the independence status. It must be called when reusing a profile set for a series of calls.
func (set *Set) Update(securityLevel uint8) {
set.Lock()
@@ -52,15 +57,15 @@ func (set *Set) Update(securityLevel uint8) {
set.profiles[3] = fallbackProfile
// update security level
profileSecurityLevel := set.getProfileSecurityLevel()
profileSecurityLevel := set.getSecurityLevel()
if profileSecurityLevel > securityLevel {
set.securityLevel = profileSecurityLevel
set.combinedSecurityLevel = profileSecurityLevel
} else {
set.securityLevel = securityLevel
set.combinedSecurityLevel = securityLevel
}
// update independence
set.Unlock()
// update independence
if set.CheckFlag(Independent) {
set.Lock()
set.independent = true
@@ -72,6 +77,14 @@ func (set *Set) Update(securityLevel uint8) {
}
}
// SecurityLevel returns the applicable security level for the profile set.
func (set *Set) SecurityLevel() uint8 {
set.Lock()
defer set.Unlock()
return set.combinedSecurityLevel
}
// GetProfileMode returns the active profile mode.
func (set *Set) GetProfileMode() uint8 {
switch {
@@ -97,7 +110,7 @@ func (set *Set) CheckFlag(flag uint8) (active bool) {
}
if profile != nil {
active, ok := profile.Flags.Check(flag, set.securityLevel)
active, ok := profile.Flags.Check(flag, set.combinedSecurityLevel)
if ok {
return active
}
@@ -153,8 +166,11 @@ func (set *Set) CheckPort(listen bool, protocol uint8, port uint16) (permit, ok
return false, false
}
// SecurityLevel returns the highest prioritized security level.
func (set *Set) getProfileSecurityLevel() uint8 {
// getSecurityLevel returns the highest prioritized security level.
func (set *Set) getSecurityLevel() uint8 {
if set == nil {
return 0
}
for i, profile := range set.profiles {
if i == 2 {

View File

@@ -24,7 +24,7 @@ func initSpecialProfiles() (err error) {
return err
}
globalProfile = makeDefaultGlobalProfile()
globalProfile.Save(specialNamespace)
globalProfile.Save(SpecialNamespace)
}
fallbackProfile, err = getSpecialProfile("fallback")
@@ -33,12 +33,12 @@ func initSpecialProfiles() (err error) {
return err
}
fallbackProfile = makeDefaultFallbackProfile()
fallbackProfile.Save(specialNamespace)
fallbackProfile.Save(SpecialNamespace)
}
return nil
}
func getSpecialProfile(ID string) (*Profile, error) {
return getProfile(specialNamespace, ID)
return getProfile(SpecialNamespace, ID)
}

View File

@@ -9,7 +9,7 @@ import (
)
func initUpdateListener() error {
sub, err := profileDB.Subscribe(query.New(makeProfileKey(specialNamespace, "")))
sub, err := profileDB.Subscribe(query.New(MakeProfileKey(SpecialNamespace, "")))
if err != nil {
return err
}
@@ -29,7 +29,7 @@ func updateListener(sub *database.Subscription) {
continue
}
profile, err := ensureProfile(r)
profile, err := EnsureProfile(r)
if err != nil {
log.Errorf("profile: received update for special profile, but could not read: %s", err)
continue
@@ -46,9 +46,9 @@ func updateListener(sub *database.Subscription) {
specialProfileLock.Unlock()
default:
switch {
case strings.HasPrefix(profile.Key(), makeProfileKey(userNamespace, "")):
case strings.HasPrefix(profile.Key(), MakeProfileKey(UserNamespace, "")):
updateActiveUserProfile(profile)
case strings.HasPrefix(profile.Key(), makeProfileKey(stampNamespace, "")):
case strings.HasPrefix(profile.Key(), MakeProfileKey(StampNamespace, "")):
updateActiveStampProfile(profile)
}
}