-
-
Notifications
You must be signed in to change notification settings - Fork 312
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/systemd query events (#1728)
* [service] Subscribe to systemd-resolver events * [service] Add disabled state to the resolver * [service] Add ETW DNS event listener * [service] DNS listener refactoring * [service] Add windows core dll project * [service] DNSListener refactoring, small bugfixes * [service] Change dns bypass rule * [service] Update gitignore * [service] Remove shim from integration module * [service] Add DNS packet analyzer * [service] Add self-check in dns monitor * [service] Fix go linter errors * [CI] Add github workflow for the windows core dll * [service] Minor fixes to the dns monitor
- Loading branch information
Showing
41 changed files
with
1,668 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
name: Windows Portmaster Core DLL | ||
|
||
on: | ||
push: | ||
paths: | ||
- 'windows_core_dll/**' | ||
branches: | ||
- master | ||
- develop | ||
|
||
pull_request: | ||
paths: | ||
- 'windows_core_dll/**' | ||
branches: | ||
- master | ||
- develop | ||
workflow_dispatch: | ||
|
||
jobs: | ||
build: | ||
name: Build | ||
runs-on: windows-latest | ||
steps: | ||
- name: Checkout Repository | ||
uses: actions/checkout@v4 | ||
- name: Add msbuild to PATH | ||
uses: microsoft/setup-msbuild@v2 | ||
- name: Build DLL | ||
run: msbuild windows_core_dll\windows_core_dll.sln -t:rebuild -property:Configuration=Release | ||
- name: Verify DLL | ||
shell: powershell | ||
run: | | ||
if (!(Test-Path "windows_core_dll/x64/Release/portmaster-core.dll")) { | ||
Write-Error "DLL build failed: portmaster-core.dll not found" | ||
exit 1 | ||
} | ||
- name: Upload artifacts | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: portmaster-core-dll | ||
path: windows_core_dll/x64/Release/portmaster-core.dll |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,3 +52,4 @@ go.work.sum | |
|
||
# Kext releases | ||
windows_kext/release/kext_release_*.zip | ||
windows_core_dll/.vs/windows_core_dll |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
service/firewall/interception/dnsmonitor/etwlink_windows.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
//go:build windows | ||
// +build windows | ||
|
||
package dnsmonitor | ||
|
||
import ( | ||
"fmt" | ||
"runtime" | ||
"sync" | ||
"sync/atomic" | ||
|
||
"github.com/safing/portmaster/service/integration" | ||
"golang.org/x/sys/windows" | ||
) | ||
|
||
type ETWSession struct { | ||
i integration.ETWFunctions | ||
|
||
shutdownGuard atomic.Bool | ||
shutdownMutex sync.Mutex | ||
|
||
state uintptr | ||
} | ||
|
||
// NewSession creates new ETW event listener and initilizes it. This is a low level interface, make sure to call DestorySession when you are done using it. | ||
func NewSession(etwInterface integration.ETWFunctions, callback func(domain string, result string)) (*ETWSession, error) { | ||
etwSession := &ETWSession{ | ||
i: etwInterface, | ||
} | ||
|
||
// Make sure session from previous instances are not running. | ||
_ = etwSession.i.StopOldSession() | ||
|
||
// Initialize notification activated callback | ||
win32Callback := windows.NewCallback(func(domain *uint16, result *uint16) uintptr { | ||
callback(windows.UTF16PtrToString(domain), windows.UTF16PtrToString(result)) | ||
return 0 | ||
}) | ||
// The function only allocates memory it will not fail. | ||
etwSession.state = etwSession.i.CreateState(win32Callback) | ||
|
||
// Make sure DestroySession is called even if caller forgets to call it. | ||
runtime.SetFinalizer(etwSession, func(s *ETWSession) { | ||
_ = s.i.DestroySession(s.state) | ||
}) | ||
|
||
// Initialize session. | ||
err := etwSession.i.InitializeSession(etwSession.state) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to initialzie session: %q", err) | ||
} | ||
|
||
return etwSession, nil | ||
} | ||
|
||
// StartTrace starts the tracing session of dns events. This is a blocking call. It will not return until the trace is stopped. | ||
func (l *ETWSession) StartTrace() error { | ||
return l.i.StartTrace(l.state) | ||
} | ||
|
||
// IsRunning returns true if DestroySession has NOT been called. | ||
func (l *ETWSession) IsRunning() bool { | ||
return !l.shutdownGuard.Load() | ||
} | ||
|
||
// FlushTrace flushes the trace buffer. | ||
func (l *ETWSession) FlushTrace() error { | ||
l.shutdownMutex.Lock() | ||
defer l.shutdownMutex.Unlock() | ||
|
||
// Make sure session is still running. | ||
if l.shutdownGuard.Load() { | ||
return nil | ||
} | ||
|
||
return l.i.FlushTrace(l.state) | ||
} | ||
|
||
// StopTrace stopes the trace. This will cause StartTrace to return. | ||
func (l *ETWSession) StopTrace() error { | ||
return l.i.StopTrace(l.state) | ||
} | ||
|
||
// DestroySession closes the session and frees the allocated memory. Listener cannot be used after this function is called. | ||
func (l *ETWSession) DestroySession() error { | ||
l.shutdownMutex.Lock() | ||
defer l.shutdownMutex.Unlock() | ||
|
||
if l.shutdownGuard.Swap(true) { | ||
return nil | ||
} | ||
|
||
err := l.i.DestroySession(l.state) | ||
if err != nil { | ||
return err | ||
} | ||
l.state = 0 | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//go:build !linux && !windows | ||
// +build !linux,!windows | ||
|
||
package dnsmonitor | ||
|
||
type Listener struct{} | ||
|
||
func newListener(_ *DNSMonitor) (*Listener, error) { | ||
return &Listener{}, nil | ||
} | ||
|
||
func (l *Listener) flush() error { | ||
// Nothing to flush | ||
return nil | ||
} | ||
|
||
func (l *Listener) stop() error { | ||
return nil | ||
} |
Oops, something went wrong.