The service answers the tray's requests on a named pipe, as the macOS extension answers the app's messages. The tray asks for blocks every two seconds, pops each new one up and lists the last ten in its menu.
On Windows the console sends Ctrl+C to both processes. The firewall
exited at once with 0xC000013A, handing the prompt back while a .cmd
shim's cmd.exe still asked "Terminate batch job (Y/N)?". It now ignores
Ctrl+C and Ctrl+Break while the manager runs and exits with its code.
A killed firewall also left the manager and its children running. The
firewall now joins a kill-on-close job before spawning, so whatever is
left dies with it.
An argument with a line break, which Rust refuses to pass to a batch
file, now says so instead of "batch file arguments are invalid".
Co-authored-by: Ian Graham Martinez <[email protected]>
The service now answers Pause and Continue only after rewriting the hosts
file, returning the write's error so the tray's ControlService call fails
and shows it. The tray's popup includes the error's source, which
windows-service's own message hides.
* Show screening status in the Windows notification area
firewall-tray.exe shows a tray icon: whether the service is screening,
paused or not running, with Pause/Resume and Open log. The MSI
starts it at every sign-in and closes it before replacing or removing it.
The icon is the Strix logo, white on a dark taskbar and black on a light
one like the macOS template image, and dimmed when not screening.
tray.png is assets/logo-transparent.png scaled and padded to 32x32:
sips -Z 32 logo-transparent.png --out a.png && sips -p 32 32 a.png --out tray.png
* Open the folder of dated service logs from the tray
The MSI installs both binaries, registers and starts the service with a
DACL that lets interactive users start, stop and pause it, restarts it on
failure, and sets NODE_EXTRA_CA_CERTS and UV_SYSTEM_CERTS. Removing it runs
`firewall-service.exe uninstall` once the service is deleted, which clears
the hosts entries and removes the CA, its TPM key and the data folder but
the config.
The wrapper's forward proxy upgraded every request to HTTPS and rewrote
links in index responses. Only an HTTPS registry is downgraded to reach
us, so only that should be upgraded back and rewritten; anything else
now goes out exactly as the client sent it, port included.
* Screen redirected registry traffic in a Windows service
Each registry host gets its own loopback address, where a LocalSystem
service serves mitm_service, connecting upstream through a resolver that
ignores the hosts file. It trusts its CA machine-wide and serves the empty
CRL that schannel needs.
The service writes the hosts-file block once it listens. Pausing it removes
the block and continuing rewrites it; a stop, crash or shutdown leaves it,
so a restart fails closed and picks up a changed host list.
* Explain the data folder ACL and the root store arguments
* Use schannel for the root store
* Free the parsed security descriptor on drop instead of through a closure
* Rotate the service log daily with tracing-appender
---------
Co-authored-by: Ian Graham Martinez <[email protected]>
* Hold the CA key in the TPM on Windows
A non-exportable machine key in the TPM, or in software where there is
none, signs as the Secure Enclave key does on macOS.
* Require the TPM for the Windows CA key
A failure to open the TPM fell back to a software key, which minted a new CA
and kept it for good. Fail instead, as macOS does without a Secure Enclave.
* Use the windows crate for the TPM key
---------
Co-authored-by: Ian Graham Martinez <[email protected]>
* Guide the user to the extension approval switch
* Allow uninstalling while the extension waits for approval
* Show the approval instruction in larger orange text
* Leave opening System Settings to the macOS alert
* Shrink the approval instruction slightly
* Hide the setup log
* Add a button that opens System Settings while approval is pending
* Remove the CA from the app, not the extension
* Uninstall through the bundled CLI
* Log uninstall only when something was removed
* Rename the Installer app to StrixFirewall (#28)
* Rename the Installer app to Firewall
* Name the app Strix Firewall
* Name the app StrixFirewall
* Show why the extension failed to start (#31)
* Delete the CA secret without reading it
* Treat a missing extension as already deactivated
* Leave installing the app to the package
* Sign with Developer ID and notarize the package
* Name signing identities by type
* Say how signing identities are matched
* Notarize only when NOTARY_PROFILE is set
schannel's revocation check, which cargo enables, fails closed on a leaf
without a reachable CRL. The CA gains cRLSign, which rcgen needs to sign
one, and leaves carry a distribution point when the platform serves it.
Co-authored-by: Ian Graham Martinez <[email protected]>
* Show Windows users PowerShell syntax and the name they type
On Windows the help said `firewall.exe`, suggested a bash alias, and
`serve` printed bash-style variable assignments. Drop the extension,
suggest a PowerShell function (Set-Alias cannot carry arguments), and
print `$env:` assignments. Other platforms are unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
* Show the cmd doskey alias beside the PowerShell one
---------
Co-authored-by: Ian Graham Martinez <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
bpaf always consumes `--`, so `firewall cargo run -- --release` handed
--release to cargo and our --config flags to the program. The CLI is now clap
with one trailing COMMAND argument, which keeps `--`.
Every manager's environment is set on every run, and cargo's and gem's flags
are added when the command is cargo or gem, so `firewall sh -c '…'` is
screened too. Since every command now gets HTTPS_PROXY, HTTPS to hosts that
aren't registries is tunnelled; registry hosts are still refused.
pipenv installs through pip, which skips the plaintext index on an
untrusted host, so `firewall pipenv install six` fetched nothing and
failed with "No matching distribution found". Set PIP_TRUSTED_HOST as
the pip recipe already does.
Co-Authored-By: Claude Opus 5.5 <[email protected]>