mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 16:44:46 +01:00

- Added ability to add a description to the rules. - Display the description field on the Rules view, and remove the internal fields (operator, operator_data, etc). - Added DB migrations. - Improved rules' executable path field tooltip (#661). Closes #652 #466
119 lines
3 KiB
Go
119 lines
3 KiB
Go
package rule
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/evilsocket/opensnitch/daemon/conman"
|
|
"github.com/evilsocket/opensnitch/daemon/log"
|
|
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
|
|
)
|
|
|
|
// Action of a rule
|
|
type Action string
|
|
|
|
// Actions of rules
|
|
const (
|
|
Allow = Action("allow")
|
|
Deny = Action("deny")
|
|
Reject = Action("reject")
|
|
)
|
|
|
|
// Duration of a rule
|
|
type Duration string
|
|
|
|
// daemon possible durations
|
|
const (
|
|
Once = Duration("once")
|
|
Restart = Duration("until restart")
|
|
Always = Duration("always")
|
|
)
|
|
|
|
// Rule represents an action on a connection.
|
|
// The fields match the ones saved as json to disk.
|
|
// If a .json rule file is modified on disk, it's reloaded automatically.
|
|
type Rule struct {
|
|
Created time.Time `json:"created"`
|
|
Updated time.Time `json:"updated"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Enabled bool `json:"enabled"`
|
|
Precedence bool `json:"precedence"`
|
|
Action Action `json:"action"`
|
|
Duration Duration `json:"duration"`
|
|
Operator Operator `json:"operator"`
|
|
}
|
|
|
|
// Create creates a new rule object with the specified parameters.
|
|
func Create(name, description string, enabled bool, precedence bool, action Action, duration Duration, op *Operator) *Rule {
|
|
return &Rule{
|
|
Created: time.Now(),
|
|
Enabled: enabled,
|
|
Precedence: precedence,
|
|
Name: name,
|
|
Description: description,
|
|
Action: action,
|
|
Duration: duration,
|
|
Operator: *op,
|
|
}
|
|
}
|
|
|
|
func (r *Rule) String() string {
|
|
return fmt.Sprintf("%s: if(%s){ %s %s }", r.Name, r.Operator.String(), r.Action, r.Duration)
|
|
}
|
|
|
|
// Match performs on a connection the checks a Rule has, to determine if it
|
|
// must be allowed or denied.
|
|
func (r *Rule) Match(con *conman.Connection) bool {
|
|
return r.Operator.Match(con)
|
|
}
|
|
|
|
// Deserialize translates back the rule received to a Rule object
|
|
func Deserialize(reply *protocol.Rule) (*Rule, error) {
|
|
if reply.Operator == nil {
|
|
log.Warning("Deserialize rule, Operator nil")
|
|
return nil, fmt.Errorf("invalid operator")
|
|
}
|
|
operator, err := NewOperator(
|
|
Type(reply.Operator.Type),
|
|
Sensitive(reply.Operator.Sensitive),
|
|
Operand(reply.Operator.Operand),
|
|
reply.Operator.Data,
|
|
make([]Operator, 0),
|
|
)
|
|
if err != nil {
|
|
log.Warning("Deserialize rule, NewOperator() error: %s", err)
|
|
return nil, err
|
|
}
|
|
|
|
return Create(
|
|
reply.Name,
|
|
reply.Description,
|
|
reply.Enabled,
|
|
reply.Precedence,
|
|
Action(reply.Action),
|
|
Duration(reply.Duration),
|
|
operator,
|
|
), nil
|
|
}
|
|
|
|
// Serialize translates a Rule to the protocol object
|
|
func (r *Rule) Serialize() *protocol.Rule {
|
|
if r == nil {
|
|
return nil
|
|
}
|
|
return &protocol.Rule{
|
|
Name: string(r.Name),
|
|
Description: string(r.Description),
|
|
Enabled: bool(r.Enabled),
|
|
Precedence: bool(r.Precedence),
|
|
Action: string(r.Action),
|
|
Duration: string(r.Duration),
|
|
Operator: &protocol.Operator{
|
|
Type: string(r.Operator.Type),
|
|
Sensitive: bool(r.Operator.Sensitive),
|
|
Operand: string(r.Operator.Operand),
|
|
Data: string(r.Operator.Data),
|
|
},
|
|
}
|
|
}
|