mirror of
https://github.com/evilsocket/opensnitch.git
synced 2025-03-04 08:34:40 +01:00
introducing daemon tasks
daemon tasks are actions that are executed in background by the daemon. They're started from the GUI (server) via a Notification (protobuf), with the type TASK_START (protobuf). Once received in the daemon, the TaskManager starts the task in background. Tasks may run at interval times (every 5s, 2days, etc), until they finish an operation, until a timeout, etc. Each task has each own configuration options, which will customize the behaviour of its operations. In this version, if the GUI is closed, the daemon will stop all the running tasks. Each Task has a flag to ignore this behaviour, for example if they need to run until they finish and only send a notification to the GUI, instead of streaming data continuously to the GUI (server). - Up until now we only had one task that could be initiated from the GUI: the process monitor dialog. It has been migrated to a Task{}. - go.mod bumped to v1.20, to use unsafe string functions. - go.sum updated accordingly.
This commit is contained in:
parent
05eed4ef04
commit
9e0f3a4797
11 changed files with 456 additions and 95 deletions
|
@ -1,6 +1,6 @@
|
||||||
module github.com/evilsocket/opensnitch/daemon
|
module github.com/evilsocket/opensnitch/daemon
|
||||||
|
|
||||||
go 1.17
|
go 1.20
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/fsnotify/fsnotify v1.4.7
|
github.com/fsnotify/fsnotify v1.4.7
|
||||||
|
|
|
@ -78,18 +78,13 @@ github.com/varlink/go v0.4.0 h1:+/BQoUO9eJK/+MTSHwFcJch7TMsb6N6Dqp6g0qaXXRo=
|
||||||
github.com/varlink/go v0.4.0/go.mod h1:DKg9Y2ctoNkesREGAEak58l+jOC6JU2aqZvUYs5DynU=
|
github.com/varlink/go v0.4.0/go.mod h1:DKg9Y2ctoNkesREGAEak58l+jOC6JU2aqZvUYs5DynU=
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20220115184804-dd687eb2f2d4 h1:fB26rIBlWTVJyEB6ONHdoEvUbvwoudH0/cMEXHiD1RU=
|
github.com/vishvananda/netlink v1.1.1-0.20220115184804-dd687eb2f2d4 h1:fB26rIBlWTVJyEB6ONHdoEvUbvwoudH0/cMEXHiD1RU=
|
||||||
github.com/vishvananda/netlink v1.1.1-0.20220115184804-dd687eb2f2d4/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
github.com/vishvananda/netlink v1.1.1-0.20220115184804-dd687eb2f2d4/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
|
||||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns=
|
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae h1:4hwBBUfQCFe3Cym0ZtKyq7L16eZUtYKs+BaHDN6mAns=
|
||||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
|
||||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
|
@ -99,7 +94,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
|
||||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -121,13 +115,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
|
||||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
@ -136,9 +125,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
@ -162,31 +149,17 @@ golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
|
||||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
|
||||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
@ -198,8 +171,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
|
||||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|
55
daemon/tasks/base.go
Normal file
55
daemon/tasks/base.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package tasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TaskBase holds the common fields of every task.
|
||||||
|
// Warning: don't define fields in tasks with these names.
|
||||||
|
type TaskBase struct {
|
||||||
|
Ctx context.Context
|
||||||
|
Cancel context.CancelFunc
|
||||||
|
Results chan interface{}
|
||||||
|
Errors chan error
|
||||||
|
StopChan chan struct{}
|
||||||
|
|
||||||
|
// Stop the task if the daemon is disconnected from the GUI (server).
|
||||||
|
// Some tasks don't need to run if the daemon is not connected to the GUI,
|
||||||
|
// like PIDMonitor, SocketsMonitor,etc.
|
||||||
|
// There might be other tasks that will perform some actions, and they
|
||||||
|
// may send a notification on finish.
|
||||||
|
StopOnDisconnect bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task defines the interface for tasks that the task manager will execute.
|
||||||
|
type Task interface {
|
||||||
|
// Start starts the task, potentially running it asynchronously.
|
||||||
|
Start(ctx context.Context, cancel context.CancelFunc) error
|
||||||
|
|
||||||
|
// Stop stops the task.
|
||||||
|
Stop() error
|
||||||
|
|
||||||
|
Pause() error
|
||||||
|
Resume() error
|
||||||
|
|
||||||
|
// Results returns a channel that can be used to receive task results.
|
||||||
|
Results() <-chan interface{}
|
||||||
|
|
||||||
|
// channel used to send errors
|
||||||
|
Errors() <-chan error
|
||||||
|
}
|
||||||
|
|
||||||
|
// TaskNotification is the data we receive when a new task is started from
|
||||||
|
// the GUI (server).
|
||||||
|
// The notification.data field will contain a string like:
|
||||||
|
// '{"name": "...", "data": {"interval": "3s", "...": ...} }'
|
||||||
|
//
|
||||||
|
// where Name is the task to start, sa defined by the Name var of each task,
|
||||||
|
// and Data is the configuration of each task (a map[string]string, converted by the json package).
|
||||||
|
type TaskNotification struct {
|
||||||
|
// Data of the task.
|
||||||
|
Data map[string]string
|
||||||
|
|
||||||
|
// Name of the task.
|
||||||
|
Name string
|
||||||
|
}
|
20
daemon/tasks/doc.go
Normal file
20
daemon/tasks/doc.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package tasks
|
||||||
|
|
||||||
|
// Copyright 2024 The OpenSnitch Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by the GPLv3
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package tasks manages actions launched by/to the daemon.
|
||||||
|
|
||||||
|
These tasks are handled by the TaskManager, which is in charge of start new
|
||||||
|
task, update and stop them.
|
||||||
|
|
||||||
|
The name of each task serves as the unique key inside the task manager.
|
||||||
|
Some tasks will be unique, like SocketsMonitor, and others might have more than one instance, like "pid-monitor-123", "pid-monitor-987".
|
||||||
|
|
||||||
|
Tasks run in background.
|
||||||
|
|
||||||
|
Some tasks may run periodically (every 5s, every 2 days, ...), others will run until stop and others until a timeout.
|
||||||
|
|
||||||
|
*/
|
126
daemon/tasks/main.go
Normal file
126
daemon/tasks/main.go
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
package tasks
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/evilsocket/opensnitch/daemon/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TaskManager manages a collection of tasks.
|
||||||
|
type TaskManager struct {
|
||||||
|
tasks map[string]Task
|
||||||
|
stopChan chan struct{}
|
||||||
|
mu sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTaskManager creates a new task manager.
|
||||||
|
func NewTaskManager() *TaskManager {
|
||||||
|
return &TaskManager{
|
||||||
|
tasks: make(map[string]Task),
|
||||||
|
stopChan: make(chan struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddTask adds a new task to the task manager.
|
||||||
|
func (tm *TaskManager) AddTask(name string, task Task) (context.Context, error) {
|
||||||
|
tm.mu.Lock()
|
||||||
|
defer tm.mu.Unlock()
|
||||||
|
|
||||||
|
if _, ok := tm.tasks[name]; ok {
|
||||||
|
return nil, fmt.Errorf("task with name %s already exists", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
tm.tasks[name] = task
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
go func(ctx context.Context, cancel context.CancelFunc) {
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
err := task.Start(ctx, cancel)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to start task %s: %v\n", name, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-tm.stopChan:
|
||||||
|
task.Stop()
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}(ctx, cancel)
|
||||||
|
|
||||||
|
return ctx, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PauseAll pauses all tasks that don't need to run while the daemon is
|
||||||
|
// disconnected from the GUI (server).
|
||||||
|
// Things to take into account:
|
||||||
|
// - The GUI may have been closed, therefore, the GUI won't have the id of the
|
||||||
|
// paused notifications. So when we resume the tasks, the GUI won't know
|
||||||
|
// about those notifications.
|
||||||
|
func (tm *TaskManager) PauseAll() {
|
||||||
|
for name, task := range tm.tasks {
|
||||||
|
log.Debug("taskManager. Pausing task %s", name)
|
||||||
|
task.Pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResumeAll resumes paused tasks
|
||||||
|
func (tm *TaskManager) ResumeAll() {
|
||||||
|
for name, task := range tm.tasks {
|
||||||
|
log.Debug("taskManager. Resuming task %s", name)
|
||||||
|
task.Resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StopAll stops all running tasks
|
||||||
|
// TODO: stop only tasks with a TTL while it's connected to the GUI (server)
|
||||||
|
// example of such tasks are: monitor PID, monitor node details, monitor listening/established connections, on-demand scan, ...
|
||||||
|
func (tm *TaskManager) StopAll() {
|
||||||
|
for name := range tm.tasks {
|
||||||
|
log.Debug("taskManager. Stopping task %s", name)
|
||||||
|
tm.RemoveTask(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTask ...
|
||||||
|
func (tm *TaskManager) GetTask(name string) (tk Task, found bool) {
|
||||||
|
tk, found = tm.tasks[name]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateTask replaces and existing task, with a new one.
|
||||||
|
func (tm *TaskManager) UpdateTask(name string, task Task) (context.Context, error) {
|
||||||
|
if _, found := tm.GetTask(name); !found {
|
||||||
|
return nil, fmt.Errorf("task %s not found", name)
|
||||||
|
}
|
||||||
|
if err := tm.RemoveTask(name); err != nil {
|
||||||
|
return nil, fmt.Errorf("Error updating task %s (remove)", name)
|
||||||
|
}
|
||||||
|
if err, ctx := tm.AddTask(name, task); err != nil {
|
||||||
|
return err, ctx
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Error updating task %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveTask removes a task from the task manager.
|
||||||
|
func (tm *TaskManager) RemoveTask(name string) error {
|
||||||
|
tm.mu.Lock()
|
||||||
|
defer tm.mu.Unlock()
|
||||||
|
|
||||||
|
tk, ok := tm.tasks[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("task with name %s does not exist", name)
|
||||||
|
}
|
||||||
|
tk.Stop()
|
||||||
|
|
||||||
|
delete(tm.tasks, name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop stops all running tasks.
|
||||||
|
func (tm *TaskManager) Stop() {
|
||||||
|
close(tm.stopChan)
|
||||||
|
}
|
134
daemon/tasks/pidmonitor/main.go
Normal file
134
daemon/tasks/pidmonitor/main.go
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
package pidmonitor
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/evilsocket/opensnitch/daemon/log"
|
||||||
|
"github.com/evilsocket/opensnitch/daemon/procmon"
|
||||||
|
"github.com/evilsocket/opensnitch/daemon/tasks"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Name s the base name of this task.
|
||||||
|
// When adding a new task, it'll be created as "pid-monitor-" + <pid>
|
||||||
|
var Name = "pid-monitor"
|
||||||
|
|
||||||
|
// Config of this task
|
||||||
|
type Config struct {
|
||||||
|
Interval string
|
||||||
|
Pid int
|
||||||
|
}
|
||||||
|
|
||||||
|
// PIDMonitor monitors a process ID.
|
||||||
|
type PIDMonitor struct {
|
||||||
|
tasks.TaskBase
|
||||||
|
Ticker *time.Ticker
|
||||||
|
Interval string
|
||||||
|
Pid int
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a new PIDMonitor
|
||||||
|
func New(pid int, interval string, stopOnDisconnect bool) (string, *PIDMonitor) {
|
||||||
|
return fmt.Sprint(Name, "-", pid), &PIDMonitor{
|
||||||
|
TaskBase: tasks.TaskBase{
|
||||||
|
Results: make(chan interface{}),
|
||||||
|
Errors: make(chan error),
|
||||||
|
StopChan: make(chan struct{}),
|
||||||
|
},
|
||||||
|
Pid: pid,
|
||||||
|
Interval: interval,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start ...
|
||||||
|
func (pm *PIDMonitor) Start(ctx context.Context, cancel context.CancelFunc) error {
|
||||||
|
pm.Ctx = ctx
|
||||||
|
pm.Cancel = cancel
|
||||||
|
p := &procmon.Process{}
|
||||||
|
item, found := procmon.EventsCache.IsInStoreByPID(pm.Pid)
|
||||||
|
if found {
|
||||||
|
newProc := item.Proc
|
||||||
|
p = &newProc
|
||||||
|
if len(p.Tree) == 0 {
|
||||||
|
p.GetParent()
|
||||||
|
p.BuildTree()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p = procmon.NewProcess(pm.Pid, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pm.Interval == "" {
|
||||||
|
pm.Interval = "5s"
|
||||||
|
}
|
||||||
|
interval, err := time.ParseDuration(pm.Interval)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pm.Ticker = time.NewTicker(interval)
|
||||||
|
go func(ctx context.Context) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-pm.StopChan:
|
||||||
|
goto Exit
|
||||||
|
case <-ctx.Done():
|
||||||
|
goto Exit
|
||||||
|
case <-pm.Ticker.C:
|
||||||
|
// TODO: errors counter, and exit on errors > X
|
||||||
|
if err := p.GetExtraInfo(); err != nil {
|
||||||
|
pm.TaskBase.Errors <- err
|
||||||
|
goto Exit
|
||||||
|
}
|
||||||
|
pJSON, err := json.Marshal(p)
|
||||||
|
if err != nil {
|
||||||
|
pm.TaskBase.Errors <- err
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// ~200µs (string()) vs ~60ns
|
||||||
|
pm.TaskBase.Results <- unsafe.String(unsafe.SliceData(pJSON), len(pJSON))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Exit:
|
||||||
|
log.Debug("[tasks.PIDMonitor] stopped (%d)", pm.Pid)
|
||||||
|
}(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pause stops temporarily the task. For example it might be paused when the
|
||||||
|
// connection with the GUI (server) is closed.
|
||||||
|
func (pm *PIDMonitor) Pause() error {
|
||||||
|
// TODO
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resume stopped tasks.
|
||||||
|
func (pm *PIDMonitor) Resume() error {
|
||||||
|
// TODO
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop ...
|
||||||
|
func (pm *PIDMonitor) Stop() error {
|
||||||
|
if pm.StopOnDisconnect {
|
||||||
|
log.Debug("[task.PIDMonitor] ignoring Stop()")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
log.Debug("[task.PIDMonitor] Stop()")
|
||||||
|
pm.StopChan <- struct{}{}
|
||||||
|
pm.Cancel()
|
||||||
|
close(pm.TaskBase.Results)
|
||||||
|
close(pm.TaskBase.Errors)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Results ...
|
||||||
|
func (pm *PIDMonitor) Results() <-chan interface{} {
|
||||||
|
return pm.TaskBase.Results
|
||||||
|
}
|
||||||
|
|
||||||
|
// Errors ...
|
||||||
|
func (pm *PIDMonitor) Errors() <-chan error {
|
||||||
|
return pm.TaskBase.Errors
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/evilsocket/opensnitch/daemon/procmon"
|
"github.com/evilsocket/opensnitch/daemon/procmon"
|
||||||
"github.com/evilsocket/opensnitch/daemon/rule"
|
"github.com/evilsocket/opensnitch/daemon/rule"
|
||||||
"github.com/evilsocket/opensnitch/daemon/statistics"
|
"github.com/evilsocket/opensnitch/daemon/statistics"
|
||||||
|
"github.com/evilsocket/opensnitch/daemon/tasks"
|
||||||
"github.com/evilsocket/opensnitch/daemon/ui/auth"
|
"github.com/evilsocket/opensnitch/daemon/ui/auth"
|
||||||
"github.com/evilsocket/opensnitch/daemon/ui/config"
|
"github.com/evilsocket/opensnitch/daemon/ui/config"
|
||||||
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
|
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
|
||||||
|
@ -33,6 +34,8 @@ var (
|
||||||
clientErrorRule = rule.Create("ui.client.error", "", true, false, false, rule.Allow, rule.Once, dummyOperator)
|
clientErrorRule = rule.Create("ui.client.error", "", true, false, false, rule.Allow, rule.Once, dummyOperator)
|
||||||
|
|
||||||
maxQueuedAlerts = 1024
|
maxQueuedAlerts = 1024
|
||||||
|
|
||||||
|
TaskMgr = tasks.NewTaskManager()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client holds the connection information of a client.
|
// Client holds the connection information of a client.
|
||||||
|
|
|
@ -12,16 +12,15 @@ import (
|
||||||
"github.com/evilsocket/opensnitch/daemon/core"
|
"github.com/evilsocket/opensnitch/daemon/core"
|
||||||
"github.com/evilsocket/opensnitch/daemon/firewall"
|
"github.com/evilsocket/opensnitch/daemon/firewall"
|
||||||
"github.com/evilsocket/opensnitch/daemon/log"
|
"github.com/evilsocket/opensnitch/daemon/log"
|
||||||
"github.com/evilsocket/opensnitch/daemon/procmon"
|
|
||||||
"github.com/evilsocket/opensnitch/daemon/procmon/monitor"
|
"github.com/evilsocket/opensnitch/daemon/procmon/monitor"
|
||||||
"github.com/evilsocket/opensnitch/daemon/rule"
|
"github.com/evilsocket/opensnitch/daemon/rule"
|
||||||
|
"github.com/evilsocket/opensnitch/daemon/tasks"
|
||||||
|
"github.com/evilsocket/opensnitch/daemon/tasks/pidmonitor"
|
||||||
"github.com/evilsocket/opensnitch/daemon/ui/config"
|
"github.com/evilsocket/opensnitch/daemon/ui/config"
|
||||||
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
|
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
var stopMonitoringProcess = make(chan int)
|
|
||||||
|
|
||||||
// NewReply constructs a new protocol notification reply
|
// NewReply constructs a new protocol notification reply
|
||||||
func NewReply(rID uint64, replyCode protocol.NotificationReplyCode, data string) *protocol.NotificationReply {
|
func NewReply(rID uint64, replyCode protocol.NotificationReplyCode, data string) *protocol.NotificationReply {
|
||||||
return &protocol.NotificationReply{
|
return &protocol.NotificationReply{
|
||||||
|
@ -59,44 +58,37 @@ func (c *Client) getClientConfig() *protocol.ClientConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) monitorProcessDetails(pid int, stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
func (c *Client) monitorProcessDetails(pid int, interval string, stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
||||||
p := &procmon.Process{}
|
if !core.Exists(fmt.Sprint("/proc/", pid)) {
|
||||||
item, found := procmon.EventsCache.IsInStoreByPID(pid)
|
c.sendNotificationReply(stream, notification.Id, "", fmt.Errorf("The process is no longer running"))
|
||||||
if found {
|
return
|
||||||
newProc := item.Proc
|
|
||||||
p = &newProc
|
|
||||||
if len(p.Tree) == 0 {
|
|
||||||
p.GetParent()
|
|
||||||
p.BuildTree()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p = procmon.NewProcess(pid, "")
|
|
||||||
}
|
|
||||||
ticker := time.NewTicker(2 * time.Second)
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case _pid := <-stopMonitoringProcess:
|
|
||||||
if _pid != pid {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
goto Exit
|
|
||||||
case <-ticker.C:
|
|
||||||
if err := p.GetExtraInfo(); err != nil {
|
|
||||||
c.sendNotificationReply(stream, notification.Id, notification.Data, err)
|
|
||||||
goto Exit
|
|
||||||
}
|
|
||||||
|
|
||||||
pJSON, err := json.Marshal(p)
|
|
||||||
notification.Data = string(pJSON)
|
|
||||||
if errs := c.sendNotificationReply(stream, notification.Id, notification.Data, err); errs != nil {
|
|
||||||
goto Exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit:
|
taskName, pidMonTask := pidmonitor.New(pid, interval, true)
|
||||||
ticker.Stop()
|
ctx, err := TaskMgr.AddTask(taskName, pidMonTask)
|
||||||
|
if err != nil {
|
||||||
|
c.sendNotificationReply(stream, notification.Id, "", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func(ctx context.Context) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
goto Exit
|
||||||
|
case err := <-pidMonTask.Errors():
|
||||||
|
c.sendNotificationReply(stream, notification.Id, "", err)
|
||||||
|
case temp := <-pidMonTask.Results():
|
||||||
|
data, ok := temp.(string)
|
||||||
|
if !ok {
|
||||||
|
goto Exit
|
||||||
|
}
|
||||||
|
c.sendNotificationReply(stream, notification.Id, data, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Exit:
|
||||||
|
TaskMgr.RemoveTask(taskName)
|
||||||
|
}(ctx)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) handleActionChangeConfig(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
func (c *Client) handleActionChangeConfig(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
||||||
|
@ -176,28 +168,50 @@ func (c *Client) handleActionDeleteRule(stream protocol.UI_NotificationsClient,
|
||||||
c.sendNotificationReply(stream, notification.Id, "", err)
|
c.sendNotificationReply(stream, notification.Id, "", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) handleActionMonitorProcess(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
func (c *Client) handleActionTaskStart(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
||||||
pid, err := strconv.Atoi(notification.Data)
|
var taskConf tasks.TaskNotification
|
||||||
|
err := json.Unmarshal([]byte(notification.Data), &taskConf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("parsing PID to monitor: %d, err: %s", pid, err)
|
log.Error("parsing TaskStart, err: %s, %s", err, notification.Data)
|
||||||
|
c.sendNotificationReply(stream, notification.Id, "", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !core.Exists(fmt.Sprint("/proc/", pid)) {
|
switch taskConf.Name {
|
||||||
c.sendNotificationReply(stream, notification.Id, "", fmt.Errorf("The process is no longer running"))
|
case pidmonitor.Name:
|
||||||
return
|
pid, err := strconv.Atoi(taskConf.Data["pid"])
|
||||||
|
if err != nil {
|
||||||
|
log.Error("TaskStart.Data, PID err: %s, %v", err, taskConf)
|
||||||
|
c.sendNotificationReply(stream, notification.Id, "", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.monitorProcessDetails(pid, taskConf.Data["interval"], stream, notification)
|
||||||
|
default:
|
||||||
|
log.Debug("TaskStart, unknown task: %v", taskConf)
|
||||||
|
//c.sendNotificationReply(stream, notification.Id, "", err)
|
||||||
}
|
}
|
||||||
go c.monitorProcessDetails(pid, stream, notification)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) handleActionStopMonitorProcess(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
func (c *Client) handleActionTaskStop(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
||||||
pid, err := strconv.Atoi(notification.Data)
|
var taskConf tasks.TaskNotification
|
||||||
|
err := json.Unmarshal([]byte(notification.Data), &taskConf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("parsing PID to stop monitor: %d, err: %s", pid, err)
|
log.Error("parsing TaskStop, err: %s, %s", err, notification.Data)
|
||||||
c.sendNotificationReply(stream, notification.Id, "", fmt.Errorf("Error stopping monitor: %s", notification.Data))
|
c.sendNotificationReply(stream, notification.Id, "", fmt.Errorf("Error stopping task: %s", notification.Data))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
stopMonitoringProcess <- pid
|
switch taskConf.Name {
|
||||||
c.sendNotificationReply(stream, notification.Id, "", nil)
|
case pidmonitor.Name:
|
||||||
|
pid, err := strconv.Atoi(taskConf.Data["pid"])
|
||||||
|
if err != nil {
|
||||||
|
log.Error("TaskStop.Data, err: %s, %s, %v+, %q", err, notification.Data, taskConf.Data, taskConf.Data)
|
||||||
|
c.sendNotificationReply(stream, notification.Id, "", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
TaskMgr.RemoveTask(fmt.Sprint(taskConf.Name, "-", pid))
|
||||||
|
default:
|
||||||
|
log.Debug("TaskStop, unknown task: %v", taskConf)
|
||||||
|
//c.sendNotificationReply(stream, notification.Id, "", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) handleActionEnableInterception(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
func (c *Client) handleActionEnableInterception(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
||||||
|
@ -269,11 +283,11 @@ func (c *Client) handleActionReloadFw(stream protocol.UI_NotificationsClient, no
|
||||||
|
|
||||||
func (c *Client) handleNotification(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
func (c *Client) handleNotification(stream protocol.UI_NotificationsClient, notification *protocol.Notification) {
|
||||||
switch {
|
switch {
|
||||||
case notification.Type == protocol.Action_MONITOR_PROCESS:
|
case notification.Type == protocol.Action_TASK_START:
|
||||||
c.handleActionMonitorProcess(stream, notification)
|
c.handleActionTaskStart(stream, notification)
|
||||||
|
|
||||||
case notification.Type == protocol.Action_STOP_MONITOR_PROCESS:
|
case notification.Type == protocol.Action_TASK_STOP:
|
||||||
c.handleActionStopMonitorProcess(stream, notification)
|
c.handleActionTaskStop(stream, notification)
|
||||||
|
|
||||||
case notification.Type == protocol.Action_CHANGE_CONFIG:
|
case notification.Type == protocol.Action_CHANGE_CONFIG:
|
||||||
c.handleActionChangeConfig(stream, notification)
|
c.handleActionChangeConfig(stream, notification)
|
||||||
|
@ -384,4 +398,5 @@ Exit:
|
||||||
notisStream.CloseSend()
|
notisStream.CloseSend()
|
||||||
log.Info("Stop receiving notifications")
|
log.Info("Stop receiving notifications")
|
||||||
c.disconnect()
|
c.disconnect()
|
||||||
|
TaskMgr.StopAll()
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,8 @@ message Rule {
|
||||||
Operator operator = 9;
|
Operator operator = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Action is the list of actions sent or received via the Notifications channel.
|
||||||
|
*/
|
||||||
enum Action {
|
enum Action {
|
||||||
NONE = 0;
|
NONE = 0;
|
||||||
ENABLE_INTERCEPTION = 1;
|
ENABLE_INTERCEPTION = 1;
|
||||||
|
@ -178,8 +180,18 @@ enum Action {
|
||||||
CHANGE_RULE = 10;
|
CHANGE_RULE = 10;
|
||||||
LOG_LEVEL = 11;
|
LOG_LEVEL = 11;
|
||||||
STOP = 12;
|
STOP = 12;
|
||||||
MONITOR_PROCESS = 13;
|
|
||||||
STOP_MONITOR_PROCESS = 14;
|
/* Notifications of type TASK_START or TASK_STOP expect a JSON in the
|
||||||
|
* Notification.data field.
|
||||||
|
* It's parsed to a struct with format
|
||||||
|
* TaskNotification { Name string, Data interface{} }
|
||||||
|
* where Data is translated to a map of values (map[string]string), with
|
||||||
|
* the configuration for each task:
|
||||||
|
* PidMonitor: {"interval": "5s", "pid": "1234"}
|
||||||
|
* SocketsMonitor: {"interval": "5s", "states": "1,10"}
|
||||||
|
*/
|
||||||
|
TASK_START = 13;
|
||||||
|
TASK_STOP = 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StatementValues {
|
message StatementValues {
|
||||||
|
@ -248,7 +260,16 @@ message ClientConfig {
|
||||||
SysFirewall systemFirewall = 8;
|
SysFirewall systemFirewall = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// notification sent to the clients (daemons)
|
/* Notification message is sent to the clients (daemons) from the GUI (server)
|
||||||
|
* for several purposes:
|
||||||
|
* - Start tasks.
|
||||||
|
* - Change configurations (rules, firewall, configuration)
|
||||||
|
* - Start / Stop interception or firewall.
|
||||||
|
* - Sent back the status of each task (errors, ok)
|
||||||
|
*
|
||||||
|
* Notifications are sent via an always open streaming channel.
|
||||||
|
* It's also used indirectly to maintain the connection status with the GUI (server).
|
||||||
|
*/
|
||||||
message Notification {
|
message Notification {
|
||||||
uint64 id = 1;
|
uint64 id = 1;
|
||||||
string clientName = 2;
|
string clientName = 2;
|
||||||
|
|
|
@ -132,10 +132,14 @@ class ProcessDetailsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0])
|
||||||
self._delete_notification(reply.id)
|
self._delete_notification(reply.id)
|
||||||
return
|
return
|
||||||
|
|
||||||
if noti.type == ui_pb2.MONITOR_PROCESS and reply.data != "":
|
if noti.type != ui_pb2.TASK_START:
|
||||||
|
print("proc-details, invalid notification type?", noti)
|
||||||
|
return
|
||||||
|
|
||||||
|
if noti.type == ui_pb2.TASK_START and reply.data != "":
|
||||||
self._load_data(reply.data)
|
self._load_data(reply.data)
|
||||||
|
|
||||||
elif noti.type == ui_pb2.STOP_MONITOR_PROCESS:
|
elif noti.type == ui_pb2.TASK_STOP:
|
||||||
if reply.data != "":
|
if reply.data != "":
|
||||||
self._show_message(
|
self._show_message(
|
||||||
QtCore.QCoreApplication.translate(
|
QtCore.QCoreApplication.translate(
|
||||||
|
@ -233,7 +237,12 @@ class ProcessDetailsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0])
|
||||||
return
|
return
|
||||||
|
|
||||||
self._set_button_running(True)
|
self._set_button_running(True)
|
||||||
noti = ui_pb2.Notification(clientName="", serverName="", type=ui_pb2.MONITOR_PROCESS, data=self._pid, rules=[])
|
noti = ui_pb2.Notification(
|
||||||
|
clientName="",
|
||||||
|
serverName="",
|
||||||
|
type=ui_pb2.TASK_START,
|
||||||
|
data=self._build_notification_message(self._pid),
|
||||||
|
rules=[])
|
||||||
self._nid = self._nodes.send_notification(self._pids[self._pid], noti, self._notification_callback)
|
self._nid = self._nodes.send_notification(self._pids[self._pid], noti, self._notification_callback)
|
||||||
self._notifications_sent[self._nid] = noti
|
self._notifications_sent[self._nid] = noti
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -244,7 +253,12 @@ class ProcessDetailsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0])
|
||||||
return
|
return
|
||||||
|
|
||||||
self._set_button_running(False)
|
self._set_button_running(False)
|
||||||
noti = ui_pb2.Notification(clientName="", serverName="", type=ui_pb2.STOP_MONITOR_PROCESS, data=str(self._pid), rules=[])
|
noti = ui_pb2.Notification(
|
||||||
|
clientName="",
|
||||||
|
serverName="",
|
||||||
|
type=ui_pb2.TASK_STOP,
|
||||||
|
data=self._build_notification_message(self._pid),
|
||||||
|
rules=[])
|
||||||
self._nid = self._nodes.send_notification(self._pids[self._pid], noti, self._notification_callback)
|
self._nid = self._nodes.send_notification(self._pids[self._pid], noti, self._notification_callback)
|
||||||
self._notifications_sent[self._nid] = noti
|
self._notifications_sent[self._nid] = noti
|
||||||
self._pid = ""
|
self._pid = ""
|
||||||
|
@ -379,4 +393,6 @@ class ProcessDetailsDialog(QtWidgets.QDialog, uic.loadUiType(DIALOG_UI_PATH)[0])
|
||||||
|
|
||||||
self._set_tab_text(self.TAB_ENVS, text)
|
self._set_tab_text(self.TAB_ENVS, text)
|
||||||
|
|
||||||
|
def _build_notification_message(self, pid):
|
||||||
|
# TODO: make interval configurable
|
||||||
|
return '{"name": "pid-monitor", "data": { "interval": "5s", "pid": "%s" }}' % pid
|
||||||
|
|
|
@ -334,7 +334,7 @@ class Nodes(QObject):
|
||||||
# delete only one-time notifications
|
# delete only one-time notifications
|
||||||
# we need the ID of streaming notifications from the server
|
# we need the ID of streaming notifications from the server
|
||||||
# (monitor_process for example) to keep track of the data sent to us.
|
# (monitor_process for example) to keep track of the data sent to us.
|
||||||
if self._notifications_sent[reply.id]['type'] != ui_pb2.MONITOR_PROCESS:
|
if self._notifications_sent[reply.id]['type'] != ui_pb2.TASK_START:
|
||||||
del self._notifications_sent[reply.id]
|
del self._notifications_sent[reply.id]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(self.LOG_TAG, "notification exception:", e)
|
print(self.LOG_TAG, "notification exception:", e)
|
||||||
|
|
Loading…
Add table
Reference in a new issue