Skip to content

Commit ea1668c

Browse files
committed
Initial implementation of fileshare monitoring
1 parent 4b094ef commit ea1668c

File tree

16 files changed

+421
-359
lines changed

16 files changed

+421
-359
lines changed

cmd/daemon/main.go

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import (
6565
"github.com/NordSecurity/nordvpn-linux/request"
6666
"github.com/NordSecurity/nordvpn-linux/sharedctx"
6767
"github.com/NordSecurity/nordvpn-linux/snapconf"
68+
"github.com/vishvananda/netlink"
6869

6970
"google.golang.org/grpc"
7071
)
@@ -127,7 +128,7 @@ func main() {
127128

128129
// Config
129130
configEvents := daemonevents.NewConfigEvents()
130-
fsystem := config.NewFilesystemConfigManager(
131+
cfgMgr := config.NewFilesystemConfigManager(
131132
config.SettingsDataFilePath,
132133
config.InstallFilePath,
133134
Salt,
@@ -136,9 +137,9 @@ func main() {
136137
configEvents.Config,
137138
)
138139
var cfg config.Config
139-
if err := fsystem.Load(&cfg); err != nil {
140+
if err := cfgMgr.Load(&cfg); err != nil {
140141
log.Println(err)
141-
if err := fsystem.Reset(); err != nil {
142+
if err := cfgMgr.Reset(); err != nil {
142143
log.Fatalln(err)
143144
}
144145
}
@@ -234,7 +235,7 @@ func main() {
234235
httpClientWithRotator,
235236
validator,
236237
)
237-
meshAPIex := registry.NewRegistry(
238+
meshRegistry := registry.NewRegistry(
238239
defaultAPI,
239240
meshnetEvents.SelfRemoved,
240241
)
@@ -282,17 +283,17 @@ func main() {
282283
// obfuscated machineID
283284
deviceID := fmt.Sprintf("%x", sha256.Sum256([]byte(cfg.MachineID.String()+Salt)))
284285

285-
analytics := newAnalytics(eventsDbPath, fsystem, defaultAPI, Version, Environment, deviceID)
286+
analytics := newAnalytics(eventsDbPath, cfgMgr, defaultAPI, Version, Environment, deviceID)
286287
heartBeatSubject.Subscribe(analytics.NotifyHeartBeat)
287288
daemonEvents.Subscribe(analytics)
288289
daemonEvents.Service.Connect.Subscribe(loggerSubscriber.NotifyConnect)
289290
daemonEvents.Settings.Publish(cfg)
290291

291-
if fsystem.NewInstallation {
292+
if cfgMgr.NewInstallation {
292293
daemonEvents.Service.UiItemsClick.Publish(events.UiItemsAction{ItemName: "first_open", ItemType: "button", ItemValue: "first_open", FormReference: "daemon"})
293294
}
294295

295-
vpnLibConfigGetter := vpnLibConfigGetterImplementation(fsystem)
296+
vpnLibConfigGetter := vpnLibConfigGetterImplementation(cfgMgr)
296297

297298
internalVpnEvents := vpn.NewInternalVPNEvents()
298299

@@ -394,17 +395,17 @@ func main() {
394395
norduserClient := norduserservice.NewNorduserGRPCClient()
395396

396397
meshnetChecker := meshnet.NewRegisteringChecker(
397-
fsystem,
398+
cfgMgr,
398399
keygen,
399-
meshAPIex,
400+
meshRegistry,
400401
)
401402

402403
meshnetEvents.PeerUpdate.Subscribe(refresher.NewMeshnet(
403-
meshAPIex, meshnetChecker, fsystem, netw,
404+
meshRegistry, meshnetChecker, cfgMgr, netw,
404405
).NotifyPeerUpdate)
405406

406407
meshUnsetter := meshunsetter.NewMeshnet(
407-
fsystem,
408+
cfgMgr,
408409
netw,
409410
errSubject,
410411
norduserClient,
@@ -414,7 +415,7 @@ func main() {
414415
accountUpdateEvents := daemonevents.NewAccountUpdateEvents()
415416
accountUpdateEvents.Subscribe(statePublisher)
416417
authChecker := auth.NewRenewingChecker(
417-
fsystem,
418+
cfgMgr,
418419
defaultAPI,
419420
daemonEvents.User.MFA,
420421
errSubject,
@@ -426,7 +427,7 @@ func main() {
426427
infoSubject,
427428
errSubject,
428429
meshnetEvents.PeerUpdate,
429-
nc.NewCredsFetcher(defaultAPI, fsystem))
430+
nc.NewCredsFetcher(defaultAPI, cfgMgr))
430431

431432
dataUpdateEvents := daemonevents.NewDataUpdateEvents()
432433
dataUpdateEvents.Subscribe(statePublisher)
@@ -442,7 +443,7 @@ func main() {
442443
rpc := daemon.NewRPC(
443444
internal.Environment(Environment),
444445
authChecker,
445-
fsystem,
446+
cfgMgr,
446447
dm,
447448
defaultAPI,
448449
defaultAPI,
@@ -460,22 +461,30 @@ func main() {
460461
notificationClient,
461462
analytics,
462463
norduserService,
463-
meshAPIex,
464+
meshRegistry,
464465
statePublisher,
465466
sharedContext,
466467
)
468+
469+
filesharePortController := meshnet.NewPortAccessController(cfgMgr, netw, meshRegistry)
470+
fileshareProcMonitor := meshnet.NewProcMonitor(
471+
&filesharePortController,
472+
netlinkMonitorSetupFn,
473+
)
474+
467475
meshService := meshnet.NewServer(
468476
authChecker,
469-
fsystem,
477+
cfgMgr,
470478
meshnetChecker,
471479
defaultAPI,
472480
netw,
473-
meshAPIex,
481+
meshRegistry,
474482
threatProtectionLiteServers,
475483
errSubject,
476484
meshnetEvents.PeerUpdate,
477485
daemonEvents,
478486
norduserClient,
487+
fileshareProcMonitor,
479488
sharedContext,
480489
)
481490

@@ -573,11 +582,11 @@ func main() {
573582
go rpc.StartAutoConnect(network.ExponentialBackoff)
574583
}
575584

576-
monitor, err := netstate.NewNetlinkMonitor([]string{openvpn.InterfaceName, nordlynx.InterfaceName})
585+
netMonitor, err := netstate.NewNetlinkMonitor([]string{openvpn.InterfaceName, nordlynx.InterfaceName})
577586
if err != nil {
578587
log.Fatalln(err)
579588
}
580-
monitor.Start(netw)
589+
netMonitor.Start(netw)
581590

582591
if authChecker.IsLoggedIn() {
583592
go daemon.StartNC("[startup]", notificationClient)
@@ -606,3 +615,17 @@ func main() {
606615
log.Println(internal.ErrorPrefix, "stopping KillSwitch:", err)
607616
}
608617
}
618+
619+
func netlinkMonitorSetupFn() (meshnet.MonitorChannels, error) {
620+
eventCh := make(chan netlink.ProcEvent, 128)
621+
doneCh := make(chan struct{})
622+
errCh := make(chan error)
623+
if err := netlink.ProcEventMonitor(eventCh, doneCh, errCh); err != nil {
624+
return meshnet.MonitorChannels{}, err
625+
}
626+
return meshnet.MonitorChannels{
627+
EventCh: eventCh,
628+
DoneCh: doneCh,
629+
ErrCh: errCh,
630+
}, nil
631+
}

daemon/jobs_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func (failingLoginChecker) IsMFAEnabled() (bool, error) { return false, nil }
3636
func (failingLoginChecker) IsVPNExpired() (bool, error) {
3737
return true, errors.New("IsVPNExpired error")
3838
}
39+
3940
func (failingLoginChecker) GetDedicatedIPServices() ([]auth.DedicatedIPService, error) {
4041
return nil, fmt.Errorf("Not implemented")
4142
}
@@ -154,6 +155,15 @@ func (*meshNetworker) GetConnectionParameters() (vpn.ServerData, bool) {
154155
return vpn.ServerData{}, false
155156
}
156157

158+
type handlerDummy struct{}
159+
160+
func (handlerDummy) OnProcessStarted(meshnet.ProcEvent) {}
161+
func (handlerDummy) OnProcessStopped(meshnet.ProcEvent) {}
162+
163+
func monitorSetupDummy() (meshnet.MonitorChannels, error) {
164+
return meshnet.MonitorChannels{}, nil
165+
}
166+
157167
func TestStartAutoMeshnet(t *testing.T) {
158168
category.Set(t, category.Unit)
159169

@@ -215,6 +225,7 @@ func TestStartAutoMeshnet(t *testing.T) {
215225
nil,
216226
&daemonevents.Events{},
217227
&testnorduser.MockNorduserClient{},
228+
meshnet.NewProcMonitor(handlerDummy{}, monitorSetupDummy),
218229
sharedctx.New(),
219230
)
220231

daemon/routes/iprule/iprule.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ func fwmarkRule(prioID int, fwmark uint32, tableID int, ipv6 bool) *netlink.Rule
469469
rule := netlink.NewRule()
470470
rule.Priority = prioID
471471
rule.Invert = true
472-
rule.Mark = int(fwmark)
472+
rule.Mark = fwmark
473473
rule.Table = tableID
474474
rule.Family = toNetlinkFamily(ipv6)
475475
return rule

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.21.1
55
toolchain go1.22.2
66

77
// Bindings
8-
// NOTE: If you are chaning the binding versions here, keep in mind that you
8+
// NOTE: If you are changing the binding versions here, keep in mind that you
99
// may also need to update versions in `./lib-versions.env` file.
1010
require (
1111
github.com/NordSecurity/libdrop-go/v8 v8.0.0-20241017064027-670787595588
@@ -36,7 +36,7 @@ require (
3636
github.com/quic-go/quic-go v0.42.0
3737
github.com/stretchr/testify v1.9.0
3838
github.com/urfave/cli/v2 v2.25.0
39-
github.com/vishvananda/netlink v1.1.0
39+
github.com/vishvananda/netlink v1.3.0
4040
golang.org/x/crypto v0.24.0
4141
golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f
4242
golang.org/x/mod v0.17.0
@@ -89,7 +89,7 @@ require (
8989
github.com/quic-go/qpack v0.4.0 // indirect
9090
github.com/robfig/cron/v3 v3.0.1 // indirect
9191
github.com/russross/blackfriday/v2 v2.1.0 // indirect
92-
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
92+
github.com/vishvananda/netns v0.0.4 // indirect
9393
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
9494
go.opencensus.io v0.24.0 // indirect
9595
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,13 @@ github.com/urfave/cli/v2 v2.25.0 h1:ykdZKuQey2zq0yin/l7JOm9Mh+pg72ngYMeB0ABn6q8=
188188
github.com/urfave/cli/v2 v2.25.0/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
189189
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
190190
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
191+
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
192+
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
191193
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
192194
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
193195
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
196+
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
197+
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
194198
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
195199
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
196200
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -277,6 +281,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
277281
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
278282
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
279283
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
284+
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
285+
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
280286
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
281287
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
282288
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

internal/filesystem.go

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -518,45 +518,3 @@ func OpenOrCreateRegularFile(fileName string, flags int, permission fs.FileMode)
518518

519519
return file, nil
520520
}
521-
522-
type (
523-
readfileFunc func(name string) ([]byte, error)
524-
readdirFunc func(name string) ([]os.DirEntry, error)
525-
)
526-
527-
var (
528-
defaultReadfile readfileFunc = os.ReadFile
529-
defaultReaddir readdirFunc = os.ReadDir
530-
)
531-
532-
// IsProcessRunning returns `true` if the executable specified as an argument is being executed, `false` otherwise.
533-
func IsProcessRunning(execPath string) bool {
534-
isRunning, err := isProcessRunning(execPath, defaultReaddir, defaultReadfile)
535-
if err != nil {
536-
log.Println(WarningPrefix, "failed to check if process is running, returning false:", err)
537-
return false
538-
}
539-
return isRunning
540-
}
541-
542-
func isProcessRunning(executablePath string, readdir readdirFunc, readfile readfileFunc) (bool, error) {
543-
procDirs, err := readdir("/proc")
544-
if err != nil {
545-
return false, fmt.Errorf("error while reading /proc directories: %w", err)
546-
}
547-
548-
for _, dir := range procDirs {
549-
cmdlinePath := filepath.Join("/proc", dir.Name(), "cmdline")
550-
551-
cmdline, err := readfile(cmdlinePath)
552-
if err != nil {
553-
continue
554-
}
555-
args := strings.Split(string(cmdline), "\x00")
556-
if len(args) > 0 && args[0] == filepath.Clean(executablePath) {
557-
return true, nil
558-
}
559-
}
560-
561-
return false, nil
562-
}

0 commit comments

Comments
 (0)