Complete first alpha version
This commit is contained in:
@@ -12,9 +12,9 @@ import (
|
||||
|
||||
// Namespaces
|
||||
const (
|
||||
userNamespace = "user"
|
||||
stampNamespace = "stamp"
|
||||
specialNamespace = "special"
|
||||
UserNamespace = "user"
|
||||
StampNamespace = "stamp"
|
||||
SpecialNamespace = "special"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user