Commit Graph

2848 Commits

Author SHA1 Message Date
Alexandr Stelnykovych 52bfe1750f service/splittun/proxy: refactor DeciderFunc API and extract session cache
- Change DeciderFunc signature to return (remoteIP net.IP,
  remotePort uint16, localAddr string, extraInfo any, err error)
  instead of a single "host:port" dest string
- Extract ConnContext, Metrics, sessionCache, and idCounter into
  a new cache.go file
- Add a secondary destKey index to sessionCache for O(1)
  FindProxiedEgressConnection lookups by upstream destination
- Attach per-session extraInfo and atomic byte/packet counters
  to ConnContext
- Update TCP and UDP proxies, tests, and README accordingly
2026-04-17 20:30:36 +03:00
Alexandr Stelnykovych f5bad230fc Merge branch 'development' into feature/split-tunneling 2026-04-14 12:22:48 +03:00
Alexandr Stelnykovych 7fca633cd8 test(resolver): TestResolveIPAndValidate fix 2026-04-13 18:17:20 +03:00
Alexandr Stelnykovych 0c83c5c1b9 test(resolver): refresh public suffix expectations after x/net PSL update 2026-04-13 17:22:14 +03:00
Alexandr Stelnykovych e54f2a23fe Merge pull request #2155 from safing/feature/s40-restart_ui_on_upgrade
(feat) Restart the UI process after automatic update

The Tauri (UI) process now automatically restarts after a successful update.
2026-04-10 16:54:30 +03:00
Alexandr Stelnykovych ce67af81e3 fix(tauri): harden UI process restart path resolution and avoid exit on relaunch failure
This fixes Linux-related issue when UI process do not start automatically after upgrade.

- replace direct current_exe relaunch usage with verified launch program resolution
- consider both current_exe and argv0, but only accept verified launchable file paths
- fail relaunch with explicit error when no safe executable path is available
- in reconnect flow, exit current UI only if relaunch spawn succeeds
- if relaunch request fails, keep current UI process running and continue normal startup

https://github.com/safing/portmaster-shadow/issues/40
2026-04-10 16:01:13 +03:00
Alexandr Stelnykovych fab4d3e68b fix: fix variable shadowing in copyAndCheckSHA256Sum
Separate variable declaration from assignment in the SHA256 validation
logic to prevent variable shadowing and ensure proper error handling
scope.
2026-04-10 13:30:22 +03:00
Alexandr Stelnykovych 14a8df4b11 Restart UI process (Tauri) after automatic update
https://github.com/safing/portmaster-shadow/issues/40
2026-04-10 13:12:04 +03:00
Alexandr Stelnykovych 67802f5cfb vscode config: Use consistent debug binary output path in VS Code launch configuration
- Add fixed output path for portmaster-core debug configurations
- Prevents creation of temporary debug binaries with random suffixes
- Reuses same binary across debug sessions
2026-04-08 15:30:04 +03:00
Alexandr Stelnykovych b298265c46 fix(updates): prevent downgrade due to CDN caching issues for recent index updates
https://github.com/safing/portmaster-shadow/issues/39
2026-04-03 13:26:51 +03:00
Alexandr Stelnykovych d8cc799203 fix(interop/ivpn): Handle local service port connections
The changes add support for tracking and properly routing connections to the IVPN client's local service port,
which is needed when the default firewall action is to block unknown connections.
The verdict handler is now registered earlier in the connection flow to handle connections while the client is connecting.

https://github.com/safing/portmaster-shadow/issues/34
2026-04-03 10:13:07 +03:00
Alexandr Stelnykovych a3f746d2b1 fix: avoid error "config: request for unregistered option: spn/enable"
Access option 'spn/enable' only after full initialisation by replacing
the eagerly-initialised struct field (config.GetAsBool called at
construction time) with local variables declared at the call-site of
each function that needs the option.

Affected: service/control, service/interop/ivpn
2026-04-01 15:17:13 +03:00
Alexandr Stelnykovych b2805d35ae interop/ivpn: suppress network-derived location while VPN is active
When IVPN connects, virtual interface IPs can cause netenv to detect
the VPN egress as the device's physical location, leading to a wrong
SPN home hub selection. Fix this by gating interface- and traceroute-
based location methods behind a new flag.

- Add DisableNetworkDerivedLocation(bool) to netenv/location.go backed
  by an atomic.Bool; getLocationFromInterfaces and getLocationFromTraceroute
  return early when the flag is set
- Call DisableNetworkDerivedLocation(true) in onConnectionStarting and
  DisableNetworkDerivedLocation(false) in onConnectionStopped and in the
  connectIvpnClient defer (covers unexpected client disconnects)

https://github.com/safing/portmaster-shadow/issues/34
2026-03-27 17:00:19 +02:00
Alexandr Stelnykovych e0fc06aa49 interop/ivpn/windows: bind SPN connections to physical interface on Windows
Add a Windows-specific hook that calls conf.SetBindAddr with the default
physical interface's addresses when SPN is connecting. This ensures SPN
hub traffic bypasses the IVPN tunnel rather than being routed through it.

- Add hook_windows.go with spnConnectingHook that reads the default
  interface via netenv.GetDefaultInterface and sets the SPN bind address
- Update hook_default.go build constraint to exclude windows
- Export DefaultNetInterface and GetDefaultInterface in netenv to allow
  cross-package access from the ivpn interop layer

https://github.com/safing/portmaster-shadow/issues/34
2026-03-27 16:04:45 +02:00
Alexandr Stelnykovych 9d5ea6287a Merge branch 'development' into fix/spn_bypass_ivpn 2026-03-27 14:13:32 +02:00
Alexandr Stelnykovych 25ce0e545f firewall/Linux: add MarkAcceptFinal to bypass third-party iptables OUTPUT rules for Portmaster-owned connections
Introduce mark 1709 (MarkAcceptFinal) and a corresponding
PermanentAcceptFinal() method that sets this mark on packets belonging
to Portmaster-owned outbound connections.

Add iptables rules (both IPv4 and IPv6, filter and mangle chains) to
ACCEPT packets/connections carrying mark 1709, so  further OUTPUT rules from
third-party software (e.g. iVPN) cannot override the allow decision.

https://github.com/safing/portmaster-shadow/issues/34
2026-03-27 14:04:45 +02:00
Alexandr Stelnykovych 9686aeb439 fix(dependencies): update ivpnclient module version to v0.0.0-20260326085211 2026-03-26 23:33:09 +02:00
Alexandr Stelnykovych 2252fd17ed ivpn/linux: route SPN hub traffic around VPN tunnel (split tunnel)
Add a synchronous HookMgr[T] that lets callers register pre-connect
hooks before SPN dials a home hub. The IVPN interop layer subscribes
to this hook and uses Linux ip-rule/ip-route to steer SPN hub IPs
through a dedicated routing table (717) pointing to the non-VPN default
gateway, preventing SPN control traffic from being tunnelled into IVPN.

- service/mgr: add generic HookMgr[T] (synchronous, cancellable)
- spn/captain: expose HookSPNConnecting; invoke it in connectToHomeHub
- service/netenv: add GatewayInfo + GatewaysInfo() with interface/mask
- service/interop/ivpn: add ensureSpnHubBypassVpnRoutes managing policy
  routing; call it from the SPN pre-connect hook and on VPN stop/connect
- nfq/packet: add hex comments next to mark constants

https://github.com/safing/portmaster-shadow/issues/34
2026-03-26 23:20:34 +02:00
Alexandr Stelnykovych 7523eb038b fix(ivpn): add Linux WireGuard SPN compatibility fallback for iptables raw rules
When nft/nftables is unavailable on a Linux host, wg-quick falls back to
installing equivalent kill-switch rules via iptables (raw/PREROUTING).
This change adds support for that fallback path so SPN reverse-NAT loopback
traffic is allowed in both backends, while keeping rule scope narrow and
cleanup idempotent.

- extend SPN compatibility reconcile logic to support both nft and iptables backends
- keep nft path as preferred behavior and continue tracking/removing inserted nft rule by handle
- add strict iptables raw PREROUTING fallback rule for loopback reverse-NAT traffic when nft is unavailable
- make rule lifecycle idempotent by cleaning previously managed rules before re-adding on state changes
- refresh inline documentation to describe dual-backend behavior and safety scope
- ensure compatibility rules are reconciled/removed on IVPN disconnect and failed connection teardown

https://github.com/safing/portmaster-shadow/issues/34
2026-03-25 17:37:45 +02:00
Alexandr Stelnykovych 22e4bd5912 fix(ivpn): add event handlers and Linux WireGuard SPN compatibility nft rule
- split IVPN event handlers into dedicated file and add ConnectedResp handling
- store connected session details in client status for follow-up compatibility logic
- add Linux-only SPN compatibility hook that reconciles an nft allow rule for WG loopback reverse-NAT traffic
- track and clean up inserted nft rule handles to avoid stale rules
- add non-Linux no-op hook implementation and trigger compatibility reconciliation on config changes

https://github.com/safing/portmaster-shadow/issues/34
2026-03-25 16:08:03 +02:00
Alexandr Stelnykovych 368822a17e fix(firewall;interop/ivpn): apply external verdict handler in all connection filtering paths
Previously, the external verdict handler was placed in filterHandler,
which is only called for new packets. This meant it was silently
bypassed when connections were re-evaluated via resetConnectionVerdict.

Move the handler into FilterConnection so it is consistently applied
for all filtering paths, including verdict resets.

https://github.com/safing/portmaster-shadow/issues/34
2026-03-17 15:38:09 +02:00
Alexandr Stelnykovych 26a8c03295 fix(ivpn): update VerdictHandler to return skipTunnel flag for better handling of connections 2026-03-17 13:03:26 +02:00
Alexandr Stelnykovych 15c495f5c9 feat(interception; Linux): ensure iptables jump rules remain at top of chains on startup
Add ensureJumpRulesAtTop and reinsertDisplacedRules to detect and fix
iptables jump rules that have been displaced by other services during
boot. A background worker runs checks at 5s, 15s, and 45s after nfqueue
interception starts, reinserting any out-of-position rules.
2026-03-17 12:08:42 +02:00
Alexandr Stelnykovych 93fb39825d fix(interception): streamline rule insertion logic in activateIPTables 2026-03-17 10:48:55 +02:00
Alexandr Stelnykovych d301699bd8 fix(updates): improve ShouldUpgradeTo logic
- fixed issue where downgrades were blocked due to an overly broad
  Published date check
- added symmetric version/date mismatch checks for both upgrades and
  downgrades, skipped when current index is locally generated
- locally generated indexes now follow the standard upgrade path;
  upgrading to the same version is explicitly blocked

https://github.com/safing/portmaster-shadow/issues/39
2026-03-17 10:26:21 +02:00
Alexandr Stelnykovych 8f9dcd5924 fix(config): prevent late option registration from losing saved values
Config options registered after loadConfig() runs were silently
discarded — ReplaceConfig() only applies disk values to already-known
options, so any module registering in Start() rather than New() would
always reset to its DefaultValue on every restart.

Changes:
- base/notifications: move prep()/registerConfig() from Start() to
  New(), ensuring all options exist before loadConfig() runs
- base/config: introduce cfgInitialized flag, set unconditionally in
  start() before loadConfig()
- base/config: add guard in Register() that rejects registrations
  after config is initialized, making the violation explicit

Fixes: core/useSystemNotifications always restoring to true despite
being saved as false in config.json

https://github.com/safing/portmaster/issues/2020
2026-03-12 16:57:42 +02:00
Alexandr Stelnykovych 39a0035c2a fix: correct typo in notification message
https://github.com/safing/portmaster/issues/2113
2026-03-12 15:38:08 +02:00
Alexandr Stelnykovych 971d52b1ec feat(interop/ivpn): Add notification for incompatible IVPN Client version 2026-03-12 15:34:08 +02:00
Alexandr Stelnykovych 631103a4bd Revert "Update dependencies in UI projects"
This reverts commit f1a68c9323.
2026-03-12 15:02:38 +02:00
Alexandr Stelnykovych 4a4b3eacb3 Bump version 2.1.8 2026-03-11 10:26:03 +02:00
Alexandr Stelnykovych f1a68c9323 Update dependencies in UI projects
```
cargo update
npm audit -fix
```
2026-03-11 10:13:41 +02:00
Alexandr Stelnykovych f08707afc5 KEXT: Bump version 2.1.0 2026-03-10 15:52:57 +02:00
Alexandr Stelnykovych 195c4ba8f5 Merge pull request #2135 from safing/feature/ivpn_interoperability
feat(interop): IVPN client interoperability
2026-03-10 15:12:52 +02:00
Alexandr Stelnykovych ee8b51d7fe feat: update ivpnclient dependency and add additional test directories to .gitignore 2026-03-10 15:06:38 +02:00
Alexandr Stelnykovych 6fd5c72b88 Merge pull request #2137 from safing/feature/kext-improvements
feat(windows-kext): owner PID tracking, downstream filter bypass, and split-tunneling routing support
2026-03-10 14:23:00 +02:00
Alexandr Stelnykovych 3b0b1745dc Merge pull request #2136 from safing/fix/windows-kext-bsod
fix(windows-kext): fix potential BSODs and block verdict bypass in WFP callouts
2026-03-10 14:20:23 +02:00
Alexandr Stelnykovych 8ed094b282 Merge pull request #2122 from vlabo/develop
Fixes for packet injection checksum calculations.
2026-03-10 14:16:38 +02:00
Alexandr Stelnykovych 8786aac857 Update callout_data.rs
Reverted changes to prevent merge conflicts
2026-03-10 14:05:17 +02:00
Alexandr Stelnykovych 0615270807 Update packet_callouts.rs
Added a comment for the recalc_header_checksums() call.
2026-03-10 14:02:45 +02:00
Alexandr Stelnykovych d07da4e350 feat(resolver): persist stale cache notification suppression
Add "Don't show again" action to the stale cache notification.
Suppression state is stored in the database and checked on startup.
System notification is shown only on first occurrence.
Reset handler in broadcasts now also clears the suppression record.

https://github.com/safing/portmaster/issues/2061
2026-03-10 00:18:53 +02:00
Alexandr Stelnykovych 183ac069eb feat(interop/ivpn): simplify IVPN detection notification message and update action text 2026-03-10 00:14:08 +02:00
Alexandr Stelnykovych 1465fe49af feat(UI/notifications): add "in-app-only" action visibility
Actions with visibility "in-app-only" are shown in the UI but skipped
when displaying system-level notifications (Tauri/OS). Updates Go,
TypeScript/Angular and Rust projects accordingly.
2026-03-10 00:12:02 +02:00
Alexandr Stelnykovych 939010a6ef feat(interop/ivpn): show compatibility notification with persistent suppress option
When Portmaster connects to the IVPN Client, display an info notification
informing the user that IVPN connections are allowed and that DNS will be
handled by Portmaster's local resolver when configured.

The notification includes a "Do not notify me anymore" action that
permanently suppresses future notifications by writing a marker record to
the core database. The check runs before showing the notification on each
subsequent connection.

The "Reset Notification States" API endpoint (and matching UI menu item)
now also clears the IVPN suppression record alongside the broadcast states,
so all suppressed notifications can be restored at once.

- service/interop/ivpn: add notification.go with initAndShowNotification,
  isNotificationSuppressed, and suppressNotification
- service/interop/ivpn/ivpn.go: show notification on connect if not suppressed
- service/broadcasts/api.go: extend reset-state handler to also delete the
  IVPN suppression record; update endpoint name and description
- desktop: rename "Reset Broadcast State" menu item and toast messages to
  "Reset Notifications State"
2026-03-09 22:16:04 +02:00
Alexandr Stelnykovych e395dafa14 feat(UI/notifications): add ActionVisibility for conditional action display
Add a `Visibility` field to the `Action` struct allowing actions to be
hidden in the compact notification view and only shown when the user
expands the full notification (value: "detailed").

- base/notifications: add `ActionVisibility` type and `ActionVisibilityDetailed`
  constant to `Action` struct
- notifications.types.ts: expose `Visibility` field on the frontend `BaseAction`
  interface
- notification-list.component.html: filter out `detailed` actions in the
  compact list view
- generic-setting.ts: set default `Visibility: ''` on the inline UI action
2026-03-09 18:12:42 +02:00
Alexandr Stelnykovych 2f58deafea service/splittun/proxy: add Layer-4 TCP/UDP proxy package
Introduces a standalone Go module with a minimal Layer-4 proxy used by
the split-tunnelling subsystem:

- DeciderFunc injects routing and optional source-address binding per
  session, enabling per-connection traffic steering.
- TCPProxy: accept loop, bidirectional pipe with pooled 32 KiB buffers,
  rolling read/write deadlines, half-close propagation, and graceful
  shutdown via context cancellation.
- UDPProxy: single listen socket with a NAT-like session table keyed by
  client address, double-checked locking for burst safety, idle eviction
  loop, and per-session upstream sockets.
- Shared Config (MaxSessions, ReadTimeout, WriteTimeout, BufferSize,
  DialTimeout), ConnContext with atomic byte/packet counters, and a
  sessionCache with aggregate Metrics.
- Full test suite (functional + race) and benchmarks for throughput and
  session creation cost.
2026-03-06 17:20:39 +02:00
Alexandr Stelnykovych baf436c205 refactor(device): improve comments for clarity on event queue and caches in Device struct 2026-03-06 10:26:29 +02:00
Alexandr Stelnykovych d11b0ee763 feat(kext): bypass downstream filters for Portmaster's own outbound connections
When a permitted connection is initiated by Portmaster itself, clear the
write flag on the classify result so subsequent filters in the sublayer
chain cannot override the permit action.
2026-03-05 15:32:32 +02:00
Alexandr Stelnykovych 13f85929b2 feat(kext): track owner PID of connected user-space process
Add IRP_MJ_CREATE and IRP_MJ_CLEANUP handlers to capture and clear the
PID of the user-space process that holds the device handle open.

- wdk/ffi: expose PsGetCurrentProcessId kernel API
- wdk/irp_helpers: add CreateRequest and CleanupRequest wrappers
- driver/device: add owner_pid AtomicU32 field with lock-free access
  for callouts; add is_owner_pid() helper
- driver/entry: register driver_create/driver_cleanup dispatch routines
  that store/clear owner_pid on connect/disconnect
2026-03-05 14:54:11 +02:00
Alexandr Stelnykovych 78fce7650d feat(kext): add RedirectSplitTunnel verdict support
Add Verdict::RedirectSplitTunnel (11) with PM_SPLIT_TUN_PORT redirection.
Wire up the new verdict in ALE, packet, and device layers alongside the
existing redirect verdicts. RedirectSplitTunnel is kept last in the enum
so older Portmaster versions (which only know verdicts 0–10) remain
unaffected.
2026-03-05 14:11:21 +02:00
Alexandr Stelnykovych 35ecee89d5 fix(kext): prevent block verdicts from being overridden by downstream WFP filters
Rename action_block() to action_block_hard(), which additionally calls
clear_write_flag(). This prevents lower-weight filters in the same WFP
sublayer from overwriting a block action set by Portmaster's callout.

Updated call sites:
- ALE layer: PermanentBlock, Undeterminable, Failed, and inbound Block
- Packet layer: PermanentBlock
2026-03-03 18:15:47 +02:00