mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-05 17:10:57 +01:00

(1/2) We start receiving notifications from the UI, which allow us to change configurations and perform actions on the daemon. The concept of Node has also been introduced, which identifies every daemon (client) connected to the UI (server). These options has been added: - Enable/Disable firewall interception (for all nodes) - Change daemons (clients) configuration. globally or per node. - Change prompt dialog options. We have fixed some bugs along the way: - Close audit client connection gracefully. - Exclude our own connections from being intercepted. - Better handling of client connection status with the UI. We probably has also introduced some other bugs (not listed here).
103 lines
2.3 KiB
Go
103 lines
2.3 KiB
Go
package procmon
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
"strconv"
|
|
)
|
|
|
|
func sortPidsByTime(fdList []os.FileInfo) []os.FileInfo {
|
|
sort.Slice(fdList, func(i, j int) bool {
|
|
t := fdList[i].ModTime().UnixNano()
|
|
u := fdList[j].ModTime().UnixNano()
|
|
return t > u
|
|
})
|
|
return fdList
|
|
}
|
|
|
|
// inodeFound searches for the given inode in /proc/<pid>/fd/ or
|
|
// /proc/<pid>/task/<tid>/fd/ and gets the symbolink link it points to,
|
|
// in order to compare it against the given inode.
|
|
//
|
|
// If the inode is found, the cache is updated ans sorted.
|
|
func inodeFound(pidsPath, expect, inodeKey string, inode, pid int) bool {
|
|
fdPath := fmt.Sprint(pidsPath, pid, "/fd/")
|
|
fdList := lookupPidDescriptors(fdPath)
|
|
if fdList == nil {
|
|
return false
|
|
}
|
|
|
|
for idx := 0; idx < len(fdList); idx++ {
|
|
descLink := fmt.Sprint(fdPath, fdList[idx])
|
|
if link, err := os.Readlink(descLink); err == nil && link == expect {
|
|
inodesCache[inodeKey] = &Inode{FdPath: descLink, Pid: pid}
|
|
addProcEntry(fdPath, fdList, pid)
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// lookupPidInProc searches for an inode in /proc.
|
|
// First it gets the running PIDs and obtains the opened sockets.
|
|
// TODO: If the inode is not found, search again in the task/threads
|
|
// of every PID (costly).
|
|
func lookupPidInProc(pidsPath, expect, inodeKey string, inode int) int {
|
|
pidList := getProcPids(pidsPath)
|
|
for _, pid := range pidList {
|
|
if inodeFound(pidsPath, expect, inodeKey, inode, pid) {
|
|
return pid
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
// lookupPidDescriptors returns the list of descriptors inside
|
|
// /proc/<pid>/fd/
|
|
// TODO: search in /proc/<pid>/task/<tid>/fd/ .
|
|
func lookupPidDescriptors(fdPath string) []string {
|
|
f, err := os.Open(fdPath)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
fdList, err := f.Readdir(-1)
|
|
f.Close()
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
fdList = sortPidsByTime(fdList)
|
|
|
|
s := make([]string, len(fdList))
|
|
for n, f := range fdList {
|
|
s[n] = f.Name()
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
// getProcPids returns the list of running PIDs, /proc or /proc/<pid>/task/ .
|
|
func getProcPids(pidsPath string) (pidList []int) {
|
|
f, err := os.Open(pidsPath)
|
|
if err != nil {
|
|
return pidList
|
|
}
|
|
ls, err := f.Readdir(-1)
|
|
f.Close()
|
|
if err != nil {
|
|
return pidList
|
|
}
|
|
ls = sortPidsByTime(ls)
|
|
|
|
for _, f := range ls {
|
|
if f.IsDir() == false {
|
|
continue
|
|
}
|
|
if pid, err := strconv.Atoi(f.Name()); err == nil {
|
|
pidList = append(pidList, []int{pid}...)
|
|
}
|
|
}
|
|
|
|
return pidList
|
|
}
|