Commit Graph

74 Commits

Author SHA1 Message Date
ospab b18852ac07 fix(gui): relax the helper-task check, and make its decision observable
The installer's task is correct on the reporting machine — right path, right
principal, and running it by hand starts the helper with no prompt — yet the
app still fell back to an elevated launch on every connect. The exact-path
comparison is the only thing that can reject it, and it was never worth its
strictness: what the check exists to catch is a task left pointing at a binary
that is gone, since `schtasks /Run` reports success merely for accepting such a
request and the app would then wait on a helper that never starts. Testing that
the registered file exists and is the helper catches exactly that case, without
charging a prompt for any other difference.

The reason this took several rounds to narrow down is the real defect: every
failure on this path went to `eprintln!`, and the GUI is a windowed binary with
no console, so the one decision that determines whether the user gets a consent
prompt was completely unobservable on their machine. It now appends to
%LOCALAPPDATA%\OSTP\helper-launch.log — what was registered, whether it exists,
what schtasks /Run answered, and whether the fallback was taken.
2026-08-11 21:33:05 +03:00
ospab 234497759b fix(gui): config went to the working directory; installer wrote unusable XML
Three defects the first installer build exposed.

Settings could not be read or saved, "os error 5". With no config beside the
executable — which is the case for every fresh install — get_config_path fell
back to a bare relative "config.json", resolved against the process working
directory. Launched from a Start Menu shortcut that is whatever Windows chose,
frequently C:\Windows\System32. On a writable working directory the silent
outcome would have been worse than the error: settings persisting somewhere
unrelated and appearing to vanish. The config now lives beside the executable
only where that directory actually accepts writes, and otherwise under the
user's own profile, carrying an existing read-only copy across once.
Writability is measured, not inferred from the path: an install onto a data
drive may well be writable where Program Files is not.

The installer could not register the task: "The task XML is malformed.
(1,2)::ERROR: incorrect document syntax". Writing it from NSIS emitted a UTF-16
byte-order mark ahead of content whose encoding depends on whether makensis was
built in Unicode mode. Replaced with the ScheduledTasks cmdlets, which take the
same settings as arguments — no file, so no encoding to get wrong. Verified the
invocation reaches Register-ScheduledTask and fails only on "Access is denied"
when unelevated, which is exactly what the elevated installer supplies.

That command is delimited with backticks, NSIS's third quote character. As a
single-quoted string it would have ended at PowerShell's first quote.

"Copy failed" on wintun.dll: CopyFiles takes a destination directory, and it
was given a file path. It is also guarded now, so a missing resource says so
instead of failing mutely.

Finally, per request, the app no longer registers the task itself — that is the
installer's job alone. Without a task it goes straight to the direct elevated
launch, which prompts per connect as it always did, rather than spending a
prompt on a registration attempt and then another on the launch.
2026-08-11 17:43:04 +03:00
ospab 96d6bb61d2 chore: release v0.4.5-beta.1 on beta 2026-08-11 16:54:34 +03:00
ospab 8af4be9b0a fix(gui): confine the installer's sidecar to the installer build
Naming the file tauri.windows.conf.json made Tauri merge it into every Windows
build automatically, and externalBin is resolved by the build script — so a
bare `cargo check` in src-tauri started failing with "resource path
binaries\ostp-tun-helper-x86_64-pc-windows-msvc.exe doesn't exist" unless the
sidecar had been staged first. That broke the release script's own cargo check
and would have broken the portable zip build too.

Renamed to tauri.installer.conf.json, which Tauri does not pick up on its own,
and passed explicitly with --config from the one step that wants it. Plain
builds are back to exactly what they were; only the installer needs staging.
2026-08-11 16:54:11 +03:00
ospab 8b5c0a3a8c feat(gui): register the helper task from an installer, not from the app
Elevation belongs to install time. Registering a task that runs elevated is
itself privileged, so an unprivileged GUI can only obtain one by raising the
very prompt we are trying to remove. There was nowhere to put it: the Windows
GUI ships as a portable zip built with --no-bundle, so the project had no
installer at all. Adds an NSIS one, whose POSTINSTALL hook registers the task
while already elevated. Connecting then prompts zero times.

NSIS over WiX because installerHooks is an NSIS feature; the MSI equivalent
needs a custom action, which is more bespoke machinery, not less. installMode
is perMachine — the default, currentUser, does not run elevated, and the hook
would fail exactly as the in-app attempt did.

The task's principal is the SID S-1-5-32-545 (BUILTIN\Users) with
InteractiveToken rather than the installing user, so a machine-wide install
serves every account instead of only whoever ran the installer; the name is
localized and would not resolve. %LOCALAPPDATA% in the arguments is left
unexpanded for the same reason — Task Scheduler expands it per running user.

Also fixes the in-app fallback, which the portable zip still needs and which
had never once worked. It trusted the exit code of an elevated schtasks, but
-Verb RunAs launches through ShellExecute and a non-elevated parent generally
cannot read the child's exit code: $p.ExitCode yields $null, and `exit $null`
leaves PowerShell reporting 0 (measured, not assumed). Failure was arriving
disguised as success. -Wait does not reliably block either, so deleting the
task XML afterwards raced schtasks reading it. It now waits for the task to
actually appear before deleting anything, and treats the exit code as advisory
except for 1223, a declined prompt, which is worth failing fast on.

Corrects one comment that asserted the opposite of the truth: schtasks writes
UTF-16 to a console but UTF-8 with no BOM into a redirected pipe, which is the
case that matters here. Only the fallback made the path check work at all.

wintun.dll rides along as a bundled resource and the hook copies it beside the
executables, since the helper loads it with a plain LoadLibrary. The uninstall
hook removes both it and the task, so no stale registration is left pointing at
a deleted binary.
2026-08-11 16:43:49 +03:00
ospab cf14a4243c chore: release v0.4.4 on master 2026-08-08 21:37:55 +03:00
ospab 66368c9d0f fix(gui): helper task checked only its name, not the exe it points at
A Scheduled Task stores an absolute path. Checking that a task named
"OSTP TUN Helper" exists said nothing about whether its <Command> still points
at the helper we are about to run, and the paths do drift: a dev build
registers target\debug\ostp-tun-helper.exe, an installer registers Program
Files, and moving or reinstalling the app leaves the old path behind.

That failed silently in the worst way. schtasks /Run reports success for
merely ACCEPTING the launch request — a task whose exe no longer exists fails
afterwards, out of band, with nothing returned to us. So launch_as_admin
returned Ok, and the caller then sat in its 60-second connect loop before
reporting "Timeout connecting to helper." On every connect, permanently, with
no way out except deleting the task by hand.

The check now reads the registered <Command> back and compares it to the exe,
re-registering through the existing /F overwrite when they differ: one consent
prompt, once, instead of a permanent silent breakage.

The path is read via /Query /XML rather than /FO LIST /V because the list
format's field labels are localized — "Task To Run" is "Задача для запуска" on
a Russian Windows — while XML tag names are not. schtasks emits UTF-16LE with
a BOM there, which is decoded explicitly, with UTF-8 tolerated as a fallback.
Both paths are canonicalized before comparison so casing, `..` and 8.3 short
names do not read as a mismatch; a path that cannot be canonicalized no longer
exists, which is itself grounds to re-register.
2026-08-07 22:24:40 +03:00
ospab bc61b47817 fix(gui): the UAC-once change did not work and flashed consoles
Reported from v0.4.3: a consent prompt for schtasks, then 10-20 console windows
opening and closing, then STILL a prompt for the helper. Two defects of mine,
both in the change that was supposed to remove the repeated prompt.

Registration never succeeded. ShellExecuteW returns as soon as the elevated
process is LAUNCHED, not when it finishes, so the generated XML was deleted
while schtasks was still starting — it then had nothing to read. The task was
never created, so the code fell through to the direct elevated launch and the
user paid for two prompts to get what one used to do. Registration now goes
through PowerShell's Start-Process -Verb RunAs -Wait -PassThru, which actually
waits, lets the XML be deleted safely afterwards, and surfaces the real exit
code instead of it being inferred by polling. Arguments are passed as an array,
so the task name and XML path never touch a command line; verified the
generated script parses with a path containing an apostrophe, an ampersand and
spaces at once.

The flashing was every schtasks/reg/tasklist invocation: the GUI is a
windowed-subsystem binary, so each console child pops a window, and the
registration polled up to twenty times in a row. All of them now go through a
wrapper that sets CREATE_NO_WINDOW. This also silences flashes that predate
this feature — `tasklist` runs whenever the exclusions screen opens, and `reg`
on autostart changes.

Polling is gone with it: the exit code is authoritative, and the task's
presence is confirmed once rather than up to twenty times.

Also drops shell_execute_elevated, which this change had left with no callers.
2026-08-07 20:51:14 +03:00
ospab 05f25155bd feat(gui): one UAC prompt per machine instead of one per connect
Enabling TUN raised a consent dialog every single time, because the GUI
elevated the helper with ShellExecuteW("runas") on each connect.

Registers a Scheduled Task with RunLevel=HighestAvailable the first time TUN
is used — that registration is the one prompt — and triggers the task on every
later connect. Running a task is not an elevation request, so Windows shows no
dialog for it. If the task is missing or cannot be triggered, the code falls
back to the original direct elevated launch, so this can only improve on the
old behaviour, never break it.

A task stores a FIXED command line, so the per-launch port and token cannot be
arguments. The helper gained --args-file and the GUI writes them to
%LOCALAPPDATA%\OSTP\helper-args.json immediately before triggering; the helper
deletes it after reading. That path keeps the token inside the trust boundary
it already had — the helper runs elevated but as the same user, and no other
user can read it, which a shared location would not guarantee.

Registered from an XML definition rather than /TR: the exe and args paths would
otherwise need quoting inside an already-quoted /TR value, escaped again
through ShellExecuteW, which breaks as soon as either contains a space — and
both do by default (Program Files, usernames with spaces). Validated that the
generated XML parses with a path containing both a space and an ampersand.
XML also lets DisallowStartIfOnBatteries=false and ExecutionTimeLimit=PT0S be
stated explicitly, without which a laptop would refuse to start the tunnel on
battery and Windows would kill it after three days.

Deliberately NOT a Windows service, contrary to what I suggested earlier. The
helper is one-shot by design: it force-exits after teardown because WinTun's
blocking receive otherwise keeps the adapter and its default route alive and
breaks the next connect. A persistent LocalSystem service would mean
restructuring that lifecycle for the same end-user result. The task also runs
with the user's own token rather than LocalSystem, which is less privilege for
the same outcome. A service is still the better answer if the tunnel should
come up before login — that is the one thing this cannot do.
2026-08-07 17:19:36 +03:00
ospab 8f0ffd08c0 feat(gui): TUN mode and autostart on Linux
Brings the Linux GUI up to parity with Windows. Four things blocked it, each
independently sufficient:

  - build.rs keyed the Windows-manifest step off cfg(windows), which in a build
    script describes the HOST. Cross-compiling the helper from Windows to Linux
    therefore took that branch and died with "Can only compile resource file
    when target_env is gnu or msvc". Now keyed off CARGO_CFG_TARGET_OS, with
    the cfg(windows) gate kept as a second check because winres is a host-
    resolved build-dependency and simply does not exist on a Linux host.
  - launch_as_admin was bail!("Windows only.") outside Windows. Implemented for
    Linux via pkexec, polkit's front-end, which raises a graphical auth prompt;
    sudo is unusable from a GUI with no terminal. Missing pkexec now names the
    package to install instead of failing opaquely.
  - The release workflow only built ostp-tun-helper in the Windows job, so the
    Linux package shipped without it. It is now built and placed next to the
    GUI binary, where find_helper_exe looks first.
  - set_autostart/get_autostart were no-ops off Windows. Implemented via XDG
    autostart (~/.config/autostart/ostp.desktop, honouring XDG_CONFIG_HOME),
    the direct equivalent of the HKCU Run key.

The helper's own code needed no changes — it already compiled for Linux once
the build script stopped rejecting it. list_running_processes already had a
Linux branch.

The token file is created 0600 on Linux: /tmp is world-readable there, unlike
the Windows temp dir, and that token authorises control of the privileged
helper.

Not verified on a live Linux desktop from here — the Tauri backend cannot be
compiled for Linux on a Windows host (GTK dev libraries), so the cfg(linux)
paths are reviewed rather than built. CI compiles them.
2026-08-04 01:08:33 +03:00
ospab 8a1426ecf5 fix(gui): honest TUN error on Linux, and a window that can be resized
Reported from the Linux GUI: it asked for "helper.exe" on Linux, and the
window was tiny.

The helper name had ".exe" hardcoded in every lookup path, so on Linux the
search could only ever fail. Fixing the name alone would have been misleading
though, because TUN mode does not work on Linux for a deeper reason:
launch_as_admin is `bail!("Windows only.")` outside Windows, and the release
workflow only builds ostp-tun-helper in the Windows GUI job. So the feature is
Windows-only, and the message now says exactly that and points at proxy mode,
instead of surfacing as a missing file named after a Windows executable —
which reads like a packaging mistake rather than an unimplemented feature. The
name is still resolved per-platform for when Linux elevation does land.

The window was 360x680 and `resizable: false`. Windows scales that by DPI, but
WebKitGTK on a HiDPI Linux display renders it close to raw pixels, giving a
postage-stamp window the user then could not resize. It is now resizable with
a sensible minimum, and .app-root caps and centres the column so a wider
window keeps the intended narrow layout instead of stretching the controls.
2026-08-04 00:56:28 +03:00
ospab 365b4ccbf5 chore: release v0.4.3-beta.1 on beta 2026-07-31 19:47:26 +03:00
ospab 66a1e97840 chore: release v0.4.2-beta.1 on beta 2026-07-12 02:18:47 +03:00
ospab 44f9067222 feat(icons): apply logo_new.png to all apps and watermarks 2026-07-11 00:58:44 +03:00
ospab 10ec253fa0 chore: release v0.4.1-.0 on master 2026-07-10 03:17:41 +03:00
ospab e52087ee8e fix: restore LICENSE file to actual AGPL-3.0 text (was stuck on old BSL 1.1)
The repo switched to AGPLv3 back on 2026-06-18 (commit 9ce9e6d), and
Cargo.toml/README have said AGPL-3.0 ever since — but that license-change
commit was never carried forward into the 0.4.x rebuild branch, so the
actual LICENSE file silently reverted to the pre-rebuild BSL 1.1 text
(with a "converts to MIT in 2030" clause that hasn't applied for months).
Restored the real AGPLv3 text from 9ce9e6d.

Also added the missing `license` field to a few crate manifests that
didn't declare one (ostp-gui/src-tauri, ostp-jni, ostp-tun-helper), and
dropped the Tauri template placeholder authors/description.
2026-07-10 01:36:41 +03:00
ospab 1d1a1ea5af refactor: remove dead stealth_sni config field across the whole stack
stealth_sni was never actually consumed to construct any wire bytes —
verified dead in bridge.rs (only stored, never read). It implied
TLS/HTTP SNI mimicry that this project deliberately does not do
(zapret-like: packet-level DPI obfuscation only, no protocol
mimicry). Removed from the runtime schema (config.rs, bridge.rs),
both CLI/GUI local config shapes and their JSON templates, the
Flutter profile model/UI/share-link logic, and README feature docs.
migrate.rs now drops the field from legacy configs with a note
instead of carrying it forward.
2026-07-10 01:04:56 +03:00
ospab 61091b6d56 chore(release): 0.4.7 + fix resolve-channel prerelease labelling
resolve-channel treated EVERY v* tag as stable, so v0.4.6-beta got published
as a non-prerelease "Latest" release, sitting on top of the release line. Now
a pushed tag is used as-is and its suffix decides the channel: v*-alpha / v*-beta
are prereleases, only a bare vX.Y.Z is stable. (A tag is never recomputed from
Cargo.toml, so the release can't upload to a different tag than the one pushed.)

Version bumped 0.4.5 -> 0.4.7 (0.4.6 is already taken by the mislabelled beta).
This commit's tip is what gets tagged v0.4.7-beta to cut the beta build.
2026-07-09 14:58:40 +03:00
ospab 5dc3a60017 refactor(logging): consolidate all logs into one ostp.log, Windows clears on start
Every process (CLI daemon, GUI, TUN helper) and every subsystem (tracing, the
core event logger, the helper IPC, panic hook) wrote its own file: ostp-cli.log
+ ostp-core.log + ostp-helper.log + ostp-crash.log — a pile per run. Now they
all funnel into a single ostp.log next to the exe.

- logging: LOG_FILE_NAME/log_file_path() as the one source of truth; init_tracing
  gains a `truncate` arg. Truncation is gated twice: Windows-only (cfg!(windows))
  AND daemon-only. One-shot commands (gk/check/init/-V/...) and the elevated TUN
  helper pass truncate=false so they can never wipe a running daemon's log;
  invocation_is_daemon() detects the daemon from argv. On Linux the server always
  appends (history kept, OS-rotated) as requested.
- runner/helper manual writers + panic hook now target log_file_path(), so their
  output lands in the same ostp.log instead of separate files.
2026-07-09 14:32:08 +03:00
ospab e21acc2ee1 docs: update references from nightly to alpha 2026-07-09 02:49:33 +03:00
ospab db581ca391 fix(gui): fix UAC SmartScreen and scrolling UI layout 2026-07-08 22:45:03 +03:00
ospab d065f6ceca chore: release 0.4.4-nightly on nightly 2026-07-08 19:13:55 +03:00
ospab ec947ec9d1 chore: release 0.4.3-nightly on nightly 2026-07-08 18:13:37 +03:00
ospab f81610f939 chore: bump version to 0.4.2 2026-07-08 17:28:14 +03:00
ospab c330a0abe3 Fix UAC diagnostics parity, gk alias, flutter version, and versioned CI channels
- GUI launch_as_admin now matches the CLI's UAC diagnosis: detects
  ERROR_CANCELLED (1223, user declined the prompt) instead of silently
  treating it as success, and reports GetLastError()+exe path for any other
  ShellExecuteW failure, replacing the old single opaque "denied or missing"
  message that made GUI/TUI failures impossible to tell apart.
- generate-key subcommand renamed to `gk` (kept `generate-key` as an alias).
- Fixed a real short-flag collision: GenerateKey's --count used short='c',
  which collides with the global --config short (propagated into every
  subcommand); clap validates the whole command tree on first parse(), so
  this could break parsing for the entire CLI, not just generate-key/gk.
  --count is now short='n'.
- ostp-flutter/pubspec.yaml version was stuck at 0.2.97+12; bumped to 0.4.1+13.
- release.yml: added a resolve-channel job that computes one release tag per
  run instead of repeating the logic in five upload steps. Rolling channel
  pushes now carry the actual Cargo.toml version instead of a bare channel
  name: `{version}-nightly` for the nightly branch, `{version}-beta` for
  pre-release. workflow_dispatch gained a `channel` input restricted to
  nightly/beta only — a manual run can never accidentally publish a "stable"
  release; that still requires an explicit vX.Y.Z tag push.
2026-07-08 02:52:23 +03:00
ospab acab38c551 0.4.1: per-key junk marker, GUI polish, pre-release pipeline
security / protocol:
- Derive a PER-KEY junk marker (obfuscation.rs, info byte 0x04) instead of the
  global constant [0x88,0x1A,0x93,0x5D]. A fixed marker was a universal DPI
  signature identifying ALL OSTP users at once — exactly what the HKDF version
  gate avoids for the handshake. Server drops junk via a new DispatchOutcome::Junk
  inside the existing key-trial loop (secrets already derived → zero extra cost);
  client stamps its own key's marker.
- §E: configurable junk/fragmentation params (junk_pc / junk_ps / frag_chunk / frag_sleep).

GUI (desktop):
- Light theme + toggle, GUI version footer in Settings.
- Fix mouse-wheel scroll on Settings (flex child needed min-height: 0).
- Drop the false "process exclusions unsupported in TUN mode" warning — they DO
  work (native_handler maps port->process via GetExtendedTcpTable).

release / infra:
- build.ps1: add -PreRelease (tag CURRENT version as v<ver>-beta.N, no bump, no
  master commit); guard the panel build when ostp-control ships no source; bump
  the real ostp-gui/package.json instead of the nonexistent ostp-control one.
- release.yml: mark hyphenated tags as GitHub pre-releases; don't hard-fail the
  web-panel step when there is no source (use committed dist/).
- Versions aligned to 0.4.1; README license badge BSL 1.1 -> AGPL v3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:33:57 +03:00
ospab e1bf18e653 core_fixes 2026-06-28 17:11:27 +03:00
ospab 5c9ec89821 §F: GUI start_tunnel tears down existing tunnel first (stop+start)
Previously start_tunnel returned early if a tunnel was already running, so
changing the server while connected silently kept the OLD connection. Per
the plan ("server change = full stop+start, not hot-reload"), tear down any
existing InProcess/Helper tunnel before starting a fresh one. For the
elevated helper, wait ~1.2s after sending stop so it releases the ostp_tun
adapter before a new helper recreates it (avoids name clashes). start_tunnel
is only invoked on an explicit connect, so restarting here is safe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 21:40:09 +03:00
ospab 4f7f1ca838 §F: desktop Share — local QR + copyable ostp:// link
The plan's share feature for the (single-config) desktop GUI. The QR is
rendered locally so the access key never leaves the device.

- src-tauri: add `qrcode = "0.14"` (features=["svg"]) + `generate_qr`
  command (string -> SVG), registered in the invoke handler. Ported from
  the current ostp-gui. (cargo check on src-tauri passes.)
- Frontend: "Share" button next to Import builds `ostp://KEY@HOST?sni&type`
  from the current config fields, calls generate_qr, and shows a modal with
  the QR + a read-only link + Copy. Added i18n keys (en/ru) so the new
  data-i18n labels resolve (missing keys would render as the raw key).

Note: Rust side verified via cargo check; the frontend is syntax-checked
(node --check) but not runtime-verified — needs a Tauri build to confirm
visually.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 21:38:21 +03:00
ospab db65e3367f §E (base): port junk packets + TCP fragmentation (stream-only)
Anti-DPI obfuscation the project wants to keep, ported from 0.3.x with the
harmful UDP behaviour designed out from the start.

- Junk: before the handshake on a UoT/TCP connection, send 2-5 random
  length-prefixed frames (100-1000 B). The server reads each as a frame,
  fails to authenticate it, drops it and keeps reading (drop-and-continue),
  so junk perturbs DPI flow analysis without breaking the connection. Junk
  is NEVER sent over UDP — there each junk would be a lone datagram
  indistinguishable from a port scan (probe-flood / wasted CPU / the very
  "self-ban" risk the plan calls out). Verified the server has no
  probe-based ban, and the unauthorized-probe log is already rate-limited
  (§B), so junk-over-UoT produces one debug line, not a flood.
- TCP fragmentation: new `transport.tcp_fragmentation` flag (default off).
  When set, the writer splits the first real frame (the handshake) — length
  header byte-by-byte then payload in 2-byte chunks with short gaps — so DPI
  can't classify the handshake from a single read.
- Ranges are hardcoded for now; §E fine-tuning (configurable Jc/Jmin/Jmax,
  S1/S2, H1..H4) is deferred.

Verified by loopback E2E: a UoT client with tcp_fragmentation=true connects
(junk logged as one rate-limited probe, then real handshake accepted) and
curl via SOCKS5 tunnels HTTPS successfully.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 17:11:12 +03:00
ospab 92d6b06d75 §A: remove WSS + Reality (TLS-mimicry); bump to 0.4.0 / AGPL-3.0
Clean-rebuild on the stably-working v0.2.98 base. The project's stealth
path is zapret-like (packet obfuscation / junk / fragmentation), NOT
TLS-mimicry, so WSS and Reality are dropped entirely.

- Delete dead orphan files: ostp-client/src/transport/xhttp.rs and
  ostp-core/src/crypto/reality.rs (never declared as modules → not even
  compiled), plus ostp-core/src/framing/wss.rs.
- Scrub the `wss` transport field from client config/bridge, the unified
  CLI (ostp/src/main.rs), the Tauri GUI backend, the GUI frontend
  (index.html/main.js), and the Flutter UI; also drop the Reality
  pbk/sid plumbing and XTLS auto-search modes from both frontends.
- Drop now-unused client deps (x25519-dalek, chacha20poly1305, hex).
- Bump workspace to version 0.4.0 and license AGPL-3.0; make ostp's
  ostp-core dep path-only so the version bump resolves.
- gitignore ostp-control/ (panel assets built separately; a dummy dist
  is created for the rust-embed build).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 16:29:42 +03:00
ospab 04761fb6a3 Fix memory leaks, hang issues, gui helper token vulns, and log spam 2026-06-16 14:11:37 +03:00
ospab b841053628 fix(jni): add exclusions_rx param to run_native_tunnel_from_fd stub to fix non-Android builds 2026-06-14 01:49:06 +03:00
ospab 4543fa82f8 fix(split-tunnel): hot-reload exclusions into running proxy tunnel without reconnect 2026-06-13 22:30:01 +03:00
ospab 83ba39e59a feat(gui): split tunneling — tag-chip UI, process picker with live process list 2026-06-13 02:55:28 +03:00
ospab 55215567dd Fix all compilation errors and suppress all warnings across workspace 2026-06-13 02:30:57 +03:00
ospab 2a24ac34d0 Remove Reality/XTLS from all UI components and TSX pages (Dashboard, Settings, Tools) 2026-06-13 02:19:53 +03:00
ospab a9e4511190 Fix CLI setup permissions, enforce global debug tracing, and fix GUI silent startup crash 2026-06-13 01:25:54 +03:00
ospab 7bb7d211fa Remove stealth_port entirely and integrate fallback into UoT HTTP handler 2026-06-10 02:26:13 +03:00
ospab 04c31c7f53 feat: implement wintun dynamic downloading, add missing driver frontend modal, fix background logging and UAC helper issues 2026-06-09 01:01:36 +03:00
ospab 730eab8553 feat: implement built-in DNS server, adblock and dns leak prevention 2026-06-07 19:55:42 +03:00
ospab 29e9ef739c Refactor: Phase 1 and 2 - Async architecture, JNI fixes, SmolTCP data races, and Tunnel optimizations 2026-06-03 02:06:06 +03:00
ospab f9e272d6bf chore: apply icon variant 2 (infinity tunnel) to tauri and flutter 2026-06-02 23:12:47 +03:00
ospab ee539ea4a6 fix(gui): add tray-icon feature and missing Emitter import 2026-06-02 23:05:32 +03:00
ospab c2bc764613 feat: linux auto-sudo and tauri system tray background mode 2026-06-02 22:58:04 +03:00
ospab 7257da174a fix(client/mobile): resolve fdsan crash and mobile network proxy issues, add auto config UI 2026-05-30 00:54:46 +03:00
ospab 907d03ca38 fix(android): protect xhttp TCP socket from VPN routing loop
When using xhttp (UoT) mode on Android, the underlying TcpStream was
not protected with VpnService.protect(fd). This caused the TCP connection
to be routed back into the TUN interface, creating an infinite routing
loop and failing the connection immediately.

Added Android-specific socket protection to the TcpStream in connect_xhttp.
This fixes xhttp/UoT mode on mobile networks.
2026-05-29 17:27:50 +03:00
ospab 7986b1ca5b fix(reality): fix TLS 1.3 handshake causing 1KB DPI cutoff on mobile
The core bug: server sent 5 TLS records in server_hello but client only
read the first one (ServerHello), then passed remaining bytes (CCS + fake
records) into RealityStream. RealityStream saw 0x14 (CCS) != 0x17 and
immediately returned an error, killing the connection.

Changes:
- reality.rs: append ChangeCipherSpec after ClientHello (RFC 8446 D.4)
  export REALITY_SERVER_HANDSHAKE_RECORDS=5 constant
- xhttp.rs: drain all 5 server handshake records before creating RealityStream
- uot.rs: rebuild server_hello as proper 5-record TLS 1.3 flight:
  ServerHello + CCS + fake EE (108B) + fake Cert (812B) + fake Fin (52B)
  drain client CCS from raw stream before wrapping in RealityStream
2026-05-29 16:21:59 +03:00
ospab f4830f043f feat: implement optional WSS framing for DPI bypass & extract framing logic 2026-05-29 13:59:59 +03:00
ospab 8cfb7e9c17 docs: add CONTRIBUTING guide in English and Russian, link in README 2026-05-29 00:25:40 +03:00