Add option key responsible for the verdict
Also, expose the RevisionCounter
This commit is contained in:
@@ -83,12 +83,10 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
|
||||
// The verdict may change so any access to it must be guarded by the
|
||||
// connection lock.
|
||||
Verdict Verdict
|
||||
// Reason is a human readable description justifying the set verdict.
|
||||
// Reason holds information justifying the verdict, as well as additional
|
||||
// information about the reason.
|
||||
// Access to Reason must be guarded by the connection lock.
|
||||
Reason string
|
||||
// ReasonContext may holds additional reason-specific information and
|
||||
// any access must be guarded by the connection lock.
|
||||
ReasonContext interface{}
|
||||
Reason Reason
|
||||
// Started holds the number of seconds in UNIX epoch time at which
|
||||
// the connection has been initated and first seen by the portmaster.
|
||||
// Staretd is only every set when creating a new connection object
|
||||
@@ -141,10 +139,26 @@ type Connection struct { //nolint:maligned // TODO: fix alignment
|
||||
// inspectorData holds additional meta data for the inspectors.
|
||||
// using the inspectors index as a map key.
|
||||
inspectorData map[uint8]interface{}
|
||||
// profileRevisionCounter is used to track changes to the process
|
||||
// ProfileRevisionCounter is used to track changes to the process
|
||||
// profile and required for correct re-evaluation of a connections
|
||||
// verdict.
|
||||
profileRevisionCounter uint64
|
||||
ProfileRevisionCounter uint64
|
||||
}
|
||||
|
||||
// Reason holds information justifying a verdict, as well as additional
|
||||
// information about the reason.
|
||||
type Reason struct {
|
||||
// Msg is a human readable description of the reason.
|
||||
Msg string
|
||||
// OptionKey is the configuration option key of the setting that
|
||||
// was responsible for the verdict.
|
||||
OptionKey string
|
||||
// Profile is the database key of the profile that held the setting
|
||||
// that was responsible for the verdict.
|
||||
Profile string
|
||||
// ReasonContext may hold additional reason-specific information and
|
||||
// any access must be guarded by the connection lock.
|
||||
Context interface{}
|
||||
}
|
||||
|
||||
func getProcessContext(proc *process.Process) ProcessContext {
|
||||
@@ -290,7 +304,7 @@ func NewConnectionFromFirstPacket(pkt packet.Packet) *Connection {
|
||||
Entity: entity,
|
||||
// meta
|
||||
Started: time.Now().Unix(),
|
||||
profileRevisionCounter: proc.Profile().RevisionCnt(),
|
||||
ProfileRevisionCounter: proc.Profile().RevisionCnt(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,73 +314,77 @@ func GetConnection(id string) (*Connection, bool) {
|
||||
}
|
||||
|
||||
// AcceptWithContext accepts the connection.
|
||||
func (conn *Connection) AcceptWithContext(reason string, ctx interface{}) {
|
||||
if !conn.SetVerdict(VerdictAccept, reason, ctx) {
|
||||
func (conn *Connection) AcceptWithContext(reason, reasonOptionKey string, ctx interface{}) {
|
||||
if !conn.SetVerdict(VerdictAccept, reason, reasonOptionKey, ctx) {
|
||||
log.Warningf("filter: tried to accept %s, but current verdict is %s", conn, conn.Verdict)
|
||||
}
|
||||
}
|
||||
|
||||
// Accept is like AcceptWithContext but only accepts a reason.
|
||||
func (conn *Connection) Accept(reason string) {
|
||||
conn.AcceptWithContext(reason, nil)
|
||||
func (conn *Connection) Accept(reason, reasonOptionKey string) {
|
||||
conn.AcceptWithContext(reason, reasonOptionKey, nil)
|
||||
}
|
||||
|
||||
// BlockWithContext blocks the connection.
|
||||
func (conn *Connection) BlockWithContext(reason string, ctx interface{}) {
|
||||
if !conn.SetVerdict(VerdictBlock, reason, ctx) {
|
||||
func (conn *Connection) BlockWithContext(reason, reasonOptionKey string, ctx interface{}) {
|
||||
if !conn.SetVerdict(VerdictBlock, reason, reasonOptionKey, ctx) {
|
||||
log.Warningf("filter: tried to block %s, but current verdict is %s", conn, conn.Verdict)
|
||||
}
|
||||
}
|
||||
|
||||
// Block is like BlockWithContext but does only accepts a reason.
|
||||
func (conn *Connection) Block(reason string) {
|
||||
conn.BlockWithContext(reason, nil)
|
||||
func (conn *Connection) Block(reason, reasonOptionKey string) {
|
||||
conn.BlockWithContext(reason, reasonOptionKey, nil)
|
||||
}
|
||||
|
||||
// DropWithContext drops the connection.
|
||||
func (conn *Connection) DropWithContext(reason string, ctx interface{}) {
|
||||
if !conn.SetVerdict(VerdictDrop, reason, ctx) {
|
||||
func (conn *Connection) DropWithContext(reason, reasonOptionKey string, ctx interface{}) {
|
||||
if !conn.SetVerdict(VerdictDrop, reason, reasonOptionKey, ctx) {
|
||||
log.Warningf("filter: tried to drop %s, but current verdict is %s", conn, conn.Verdict)
|
||||
}
|
||||
}
|
||||
|
||||
// Drop is like DropWithContext but does only accepts a reason.
|
||||
func (conn *Connection) Drop(reason string) {
|
||||
conn.DropWithContext(reason, nil)
|
||||
func (conn *Connection) Drop(reason, reasonOptionKey string) {
|
||||
conn.DropWithContext(reason, reasonOptionKey, nil)
|
||||
}
|
||||
|
||||
// DenyWithContext blocks or drops the link depending on the connection direction.
|
||||
func (conn *Connection) DenyWithContext(reason string, ctx interface{}) {
|
||||
func (conn *Connection) DenyWithContext(reason, reasonOptionKey string, ctx interface{}) {
|
||||
if conn.Inbound {
|
||||
conn.DropWithContext(reason, ctx)
|
||||
conn.DropWithContext(reason, reasonOptionKey, ctx)
|
||||
} else {
|
||||
conn.BlockWithContext(reason, ctx)
|
||||
conn.BlockWithContext(reason, reasonOptionKey, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// Deny is like DenyWithContext but only accepts a reason.
|
||||
func (conn *Connection) Deny(reason string) {
|
||||
conn.DenyWithContext(reason, nil)
|
||||
func (conn *Connection) Deny(reason, reasonOptionKey string) {
|
||||
conn.DenyWithContext(reason, reasonOptionKey, nil)
|
||||
}
|
||||
|
||||
// FailedWithContext marks the connection with VerdictFailed and stores the reason.
|
||||
func (conn *Connection) FailedWithContext(reason string, ctx interface{}) {
|
||||
if !conn.SetVerdict(VerdictFailed, reason, ctx) {
|
||||
func (conn *Connection) FailedWithContext(reason, reasonOptionKey string, ctx interface{}) {
|
||||
if !conn.SetVerdict(VerdictFailed, reason, reasonOptionKey, ctx) {
|
||||
log.Warningf("filter: tried to drop %s due to error but current verdict is %s", conn, conn.Verdict)
|
||||
}
|
||||
}
|
||||
|
||||
// Failed is like FailedWithContext but only accepts a string.
|
||||
func (conn *Connection) Failed(reason string) {
|
||||
conn.FailedWithContext(reason, nil)
|
||||
func (conn *Connection) Failed(reason, reasonOptionKey string) {
|
||||
conn.FailedWithContext(reason, reasonOptionKey, nil)
|
||||
}
|
||||
|
||||
// SetVerdict sets a new verdict for the connection, making sure it does not interfere with previous verdicts.
|
||||
func (conn *Connection) SetVerdict(newVerdict Verdict, reason string, reasonCtx interface{}) (ok bool) {
|
||||
func (conn *Connection) SetVerdict(newVerdict Verdict, reason, reasonOptionKey string, reasonCtx interface{}) (ok bool) {
|
||||
if newVerdict >= conn.Verdict {
|
||||
conn.Verdict = newVerdict
|
||||
conn.Reason = reason
|
||||
conn.ReasonContext = reasonCtx
|
||||
conn.Reason.Msg = reason
|
||||
conn.Reason.Context = reasonCtx
|
||||
if reasonOptionKey != "" && conn.Process() != nil {
|
||||
conn.Reason.OptionKey = reasonOptionKey
|
||||
conn.Reason.Profile = conn.Process().Profile().GetProfileSource(conn.Reason.OptionKey)
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -490,7 +508,7 @@ func (conn *Connection) packetHandler() {
|
||||
defaultFirewallHandler(conn, pkt)
|
||||
}
|
||||
// log verdict
|
||||
log.Tracer(pkt.Ctx()).Infof("filter: connection %s %s: %s", conn, conn.Verdict.Verb(), conn.Reason)
|
||||
log.Tracer(pkt.Ctx()).Infof("filter: connection %s %s: %s", conn, conn.Verdict.Verb(), conn.Reason.Msg)
|
||||
|
||||
// save does not touch any changing data
|
||||
// must not be locked, will deadlock with cleaner functions
|
||||
|
||||
Reference in New Issue
Block a user