mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-05 00:51:05 +01:00
audit: insert new processes at the top of the list.
And avoid to sort the list of known processes every time we add a new one. Code formatted and documented.
This commit is contained in:
parent
ef04667cdb
commit
ba770fdf0d
2 changed files with 49 additions and 43 deletions
|
@ -47,7 +47,7 @@ type Event struct {
|
|||
ProcMode string // mode
|
||||
TTY string
|
||||
Pid int
|
||||
Uid int
|
||||
UID int
|
||||
Gid int
|
||||
PPid int
|
||||
EUid int
|
||||
|
@ -68,37 +68,42 @@ type Event struct {
|
|||
LastSeen time.Time
|
||||
}
|
||||
|
||||
// MAX_EVENT_AGE is the maximum minutes an audit process can live without network activity.
|
||||
// MaxEventAge is the maximum minutes an audit process can live without network activity.
|
||||
const (
|
||||
MAX_EVENT_AGE = int(10)
|
||||
MaxEventAge = int(10)
|
||||
)
|
||||
|
||||
var (
|
||||
Lock sync.RWMutex
|
||||
Events []*Event
|
||||
// Lock holds a mutex
|
||||
Lock sync.RWMutex
|
||||
events []*Event
|
||||
// EventChan is an output channel where incoming auditd events will be written.
|
||||
// If a client opens it.
|
||||
EventChan = (chan Event)(nil)
|
||||
stop = false
|
||||
// TODO: we may need arm arch
|
||||
rule64 = []string{"exit,always", "-F", "arch=b64", "-S", "socket,connect", "-k", "opensnitch"}
|
||||
rule32 = []string{"exit,always", "-F", "arch=b32", "-F", "a0=1", "-S", "socketcall", "-k", "opensnitch"}
|
||||
audispd_path = "/var/run/audispd_events"
|
||||
ourPid = os.Getpid()
|
||||
rule64 = []string{"exit,always", "-F", "arch=b64", "-S", "socket,connect", "-k", "opensnitch"}
|
||||
rule32 = []string{"exit,always", "-F", "arch=b32", "-F", "a0=1", "-S", "socketcall", "-k", "opensnitch"}
|
||||
audispdPath = "/var/run/audispd_events"
|
||||
ourPid = os.Getpid()
|
||||
)
|
||||
|
||||
// OPENSNITCH_RULES_KEY is the mark we place on every event we are interested in.
|
||||
const (
|
||||
OPENSNITCH_RULES_KEY = "key=\"opensnitch\""
|
||||
OpensnitchRulesKey = "key=\"opensnitch\""
|
||||
)
|
||||
|
||||
// GetEvents returns the list of processes which have opened a connection.
|
||||
func GetEvents() []*Event {
|
||||
return Events
|
||||
return events
|
||||
}
|
||||
|
||||
// GetEventByPid returns an event given a pid.
|
||||
func GetEventByPid(pid int) *Event {
|
||||
Lock.RLock()
|
||||
defer Lock.RUnlock()
|
||||
|
||||
for _, event := range Events {
|
||||
for _, event := range events {
|
||||
if pid == event.Pid {
|
||||
return event
|
||||
}
|
||||
|
@ -110,12 +115,12 @@ func GetEventByPid(pid int) *Event {
|
|||
// sortEvents sorts received events by time and elapsed time since latest network activity.
|
||||
// newest PIDs will be placed on top of the list.
|
||||
func sortEvents() {
|
||||
sort.Slice(Events, func(i, j int) bool {
|
||||
sort.Slice(events, func(i, j int) bool {
|
||||
now := time.Now()
|
||||
elapsedTimeT := now.Sub(Events[i].LastSeen)
|
||||
elapsedTimeU := now.Sub(Events[j].LastSeen)
|
||||
t := Events[i].LastSeen.UnixNano()
|
||||
u := Events[j].LastSeen.UnixNano()
|
||||
elapsedTimeT := now.Sub(events[i].LastSeen)
|
||||
elapsedTimeU := now.Sub(events[j].LastSeen)
|
||||
t := events[i].LastSeen.UnixNano()
|
||||
u := events[j].LastSeen.UnixNano()
|
||||
return t > u && elapsedTimeT < elapsedTimeU
|
||||
})
|
||||
}
|
||||
|
@ -123,34 +128,34 @@ func sortEvents() {
|
|||
// CleanoldEvents deletes the PIDs which do not exist or that are too old to
|
||||
// live.
|
||||
// We start searching from the oldest to the newest.
|
||||
// If the last network activity of a PID has been greater than MAX_EVENT_AGE,
|
||||
// If the last network activity of a PID has been greater than MaxEventAge,
|
||||
// then it'll be deleted.
|
||||
func cleanOldEvents() {
|
||||
for n := len(Events) - 1; n >= 0; n-- {
|
||||
for n := len(events) - 1; n >= 0; n-- {
|
||||
now := time.Now()
|
||||
elapsedTime := now.Sub(Events[n].LastSeen)
|
||||
if int(elapsedTime.Minutes()) >= MAX_EVENT_AGE {
|
||||
Events = append(Events[:n], Events[n+1:]...)
|
||||
elapsedTime := now.Sub(events[n].LastSeen)
|
||||
if int(elapsedTime.Minutes()) >= MaxEventAge {
|
||||
events = append(events[:n], events[n+1:]...)
|
||||
continue
|
||||
}
|
||||
if core.Exists(fmt.Sprint("/proc/", Events[n].Pid)) == false {
|
||||
Events = append(Events[:n], Events[n+1:]...)
|
||||
if core.Exists(fmt.Sprint("/proc/", events[n].Pid)) == false {
|
||||
events = append(events[:n], events[n+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteEvent(pid int) {
|
||||
for n, _ := range Events {
|
||||
if Events[n].Pid == pid || Events[n].PPid == pid {
|
||||
DeleteEventByIndex(n)
|
||||
func deleteEvent(pid int) {
|
||||
for n := range events {
|
||||
if events[n].Pid == pid || events[n].PPid == pid {
|
||||
deleteEventByIndex(n)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteEventByIndex(index int) {
|
||||
func deleteEventByIndex(index int) {
|
||||
Lock.Lock()
|
||||
Events = append(Events[:index], Events[index+1:]...)
|
||||
events = append(events[:index], events[index+1:]...)
|
||||
Lock.Unlock()
|
||||
}
|
||||
|
||||
|
@ -166,16 +171,15 @@ func AddEvent(aevent *Event) {
|
|||
defer Lock.Unlock()
|
||||
|
||||
cleanOldEvents()
|
||||
for n := 0; n < len(Events); n++ {
|
||||
if Events[n].Pid == aevent.Pid {
|
||||
for n := 0; n < len(events); n++ {
|
||||
if events[n].Pid == aevent.Pid {
|
||||
aevent.LastSeen = time.Now()
|
||||
Events[n] = aevent
|
||||
events[n] = aevent
|
||||
return
|
||||
}
|
||||
}
|
||||
aevent.LastSeen = time.Now()
|
||||
Events = append(Events, aevent)
|
||||
sortEvents()
|
||||
events = append([]*Event{aevent}, events...)
|
||||
}
|
||||
|
||||
func addRules() bool {
|
||||
|
@ -243,8 +247,8 @@ func Reader(r io.Reader, eventChan chan<- Event) {
|
|||
if err != nil {
|
||||
if err == io.EOF {
|
||||
log.Error("AuditReader: auditd stopped, reconnecting in 30s", err)
|
||||
if new_reader, err := reconnect(); err == nil {
|
||||
reader = bufio.NewReader(new_reader)
|
||||
if newReader, err := reconnect(); err == nil {
|
||||
reader = bufio.NewReader(newReader)
|
||||
log.Important("Auditd reconnected, continue reading")
|
||||
}
|
||||
continue
|
||||
|
@ -272,9 +276,10 @@ func reconnect() (net.Conn, error) {
|
|||
func connect() (net.Conn, error) {
|
||||
addRules()
|
||||
// TODO: make the unix socket path configurable
|
||||
return net.Dial("unix", audispd_path)
|
||||
return net.Dial("unix", audispdPath)
|
||||
}
|
||||
|
||||
// Stop stops listening for events from auditd and delete the auditd rules.
|
||||
func Stop() {
|
||||
Lock.Lock()
|
||||
stop = true
|
||||
|
@ -286,6 +291,7 @@ func Stop() {
|
|||
}
|
||||
}
|
||||
|
||||
// Start makes a new connection to the audisp af_unix socket.
|
||||
func Start() (net.Conn, error) {
|
||||
c, err := connect()
|
||||
if err != nil {
|
||||
|
|
|
@ -107,11 +107,11 @@ func parseNetLine(line string, decode bool) (family string, dstHost net.IP, dstP
|
|||
// If the string can not be decoded, the original string will be returned.
|
||||
// In that case, usually it means that it's a non-encoded string.
|
||||
func decodeString(s string) string {
|
||||
if decoded, err := hex.DecodeString(s); err != nil {
|
||||
decoded, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
return s
|
||||
} else {
|
||||
return fmt.Sprintf("%s", decoded)
|
||||
}
|
||||
return fmt.Sprintf("%s", decoded)
|
||||
}
|
||||
|
||||
// extractFields parsed an audit raw message, and extracts all the fields.
|
||||
|
@ -189,7 +189,7 @@ func populateEvent(aevent *Event, eventFields *map[string]string) *Event {
|
|||
case "ppid":
|
||||
aevent.PPid, _ = strconv.Atoi(v)
|
||||
case "uid":
|
||||
aevent.Uid, _ = strconv.Atoi(v)
|
||||
aevent.UID, _ = strconv.Atoi(v)
|
||||
case "gid":
|
||||
aevent.Gid, _ = strconv.Atoi(v)
|
||||
case "success":
|
||||
|
@ -234,7 +234,7 @@ func populateEvent(aevent *Event, eventFields *map[string]string) *Event {
|
|||
func parseEvent(rawMessage string, eventChan chan<- Event) {
|
||||
aEvent := make(map[string]string)
|
||||
|
||||
if newEvent == false && strings.Index(rawMessage, OPENSNITCH_RULES_KEY) == -1 {
|
||||
if newEvent == false && strings.Index(rawMessage, OpensnitchRulesKey) == -1 {
|
||||
return
|
||||
}
|
||||
if strings.Index(rawMessage, SYSCALL_SOCKET_STR) != -1 ||
|
||||
|
|
Loading…
Add table
Reference in a new issue