Write the config file in one place too, since both did it identically
Both projects saved by rendering, writing a temp file through `private`,
and renaming over the target. `format::write` is that, and it belongs with
the house rules rather than beside either schema: it is the two existing
modules used together, and the thing worth stating once is why they are
used together at all.
That thing is the temp file, and it is not obvious. It is not always new
-- a save killed partway leaves one behind, and reopening it keeps
whatever mode it already had, which is then renamed straight over the file
holding the enrolled token hashes. Opening through `private` sets the mode
on the way in, so the fresh and the leftover case are the same case.
There is a test that creates a 0644 leftover and asserts the config comes
out 0600, because that state cannot arise on a machine where nothing has
ever crashed mid-save -- which is every machine either project has been
developed on.
The temp name is now appended rather than substituted, so `config.ron`
yields `config.ron.tmp`. `with_extension("tmp")` would have produced
`config.tmp`, which is a name that could plausibly belong to something
else.
This commit is contained in:
1 parent
4de8bff5f2
commit
db4552f4e4
2 files changed
+92
-2
No files matched your search
@@ -100,7 +100,7 @@ diffing the two copies and finding nothing but a name between them.
|
||||
- **`netif`** — `wg_address()`, which fails closed when the tunnel is down, and `local_addresses()` for the certificate's SANs. The product name is a parameter so the failure reads as advice rather than as a library complaining. Both split the *lookup* from the *decision*, so the failure path can be tested on a machine that has a tunnel — every machine this runs on does.
|
||||
- **`enroll`** — token generation, hex-SHA-256 storage, constant-time comparison, the `<scheme>://enroll?…` URI, and the terminal QR. The URI scheme is the parameter, because it is what routes a scan back to the right app.
|
||||
- **`certs`** — the CA generated once and never replaced, the leaf reissued every start. `product` names the organisation and common name and is the whole of what is per-project. Shared because being written twice is worst here: a trust anchor built two ways can be built differently two ways, and the difference surfaces as an opaque handshake failure on a phone.
|
||||
- **`format`** — the two RON house rules. This was byte-identical in both projects, which made it the clearest thing in the evidence table and the easiest deletion.
|
||||
- **`format`** — the two RON house rules, plus `write`, which renders a value and replaces a file with it atomically and owner-only. This was byte-identical in both projects, which made it the clearest thing in the evidence table and the easiest deletion.
|
||||
- **`private`** — owner-only files and directories, taken from ai-app's version, with an `append_file` alongside `create_file` because a transcript must never be truncated by being opened.
|
||||
- **`xdg`** — where each project's state lives: `config_home(product)` and `data_home(product)`, resolving the XDG variable, ignoring it unless absolute, and falling back under `$HOME`. Shared because the *reason* is shared and is not obvious from the code — the repo is a mount that resolves at different absolute paths on each side, so config inside it records paths that work on only one, and a CA private key inside it would let the untrusted side mint a leaf the pinned app trusts.
|
||||
|
||||
@@ -157,7 +157,7 @@ nowhere near the generator. Worth revisiting if it ever needs a second fix.
|
||||
**Should follow, in this order.** Each is already near-identical:
|
||||
|
||||
1. ~~The Kotlin `EnrollmentScanActivity`, `PinnedCert`, and the enrollment/Keystore half of `ServerConfig`.~~ Done — see `app/` above. It paid as predicted: ai-app's `ServerConfig` had gained `localNetworkAllowed` and the KTX `edit` block while dev-updater's had not, so the two had drifted in both directions exactly as the evidence suggested.
|
||||
2. Atomic owner-only config save. Both do temp-file-then-rename with the mode set before the rename; only the schema differs.
|
||||
2. ~~Atomic owner-only config save.~~ Done — `format::write`, since it is the RON house rules and the owner-only rules used together. The subtlety it now states once is that the temp file is *not always new*: a save killed partway leaves one behind, and reopening it keeps whatever mode it had, which is then renamed over the file holding the enrolled token hashes. There is a test for exactly that, because it cannot happen on a machine where nothing has ever crashed mid-save.
|
||||
|
||||
**Should not.** Naming these is the point of the exercise:
|
||||
|
||||
|
||||
Reference in new issue
Block a user