moshcode 0.87.0 → 0.89.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/dns.mjs +56 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moshcode",
3
- "version": "0.87.0",
3
+ "version": "0.89.0",
4
4
  "type": "module",
5
5
  "description": "moshcode \u2014 a metal wrapper for coding engines and native UGig/CoinPay workflow CLIs, with OpenPRD and moshscript",
6
6
  "repository": {
package/src/dns.mjs CHANGED
@@ -1695,6 +1695,36 @@ export function proxyProbeFromArgs(args = [], claimed = []) {
1695
1695
  return { name: claimed[0] ? `a.${claimed[0]}` : null, invalid: false };
1696
1696
  }
1697
1697
 
1698
+ /**
1699
+ * A Moshpit name to test this machine's setup with.
1700
+ *
1701
+ * Synthetic on purpose — the proxy mints a certificate for any name inside the
1702
+ * namespace, so the probe does not have to name something anybody registered.
1703
+ * What it does have to be is a hostname the rest of the program can parse.
1704
+ *
1705
+ * `a.${tlds[0]}` was not. The first ending the registry returns is `00`, and
1706
+ * `https://a.00/` is rejected outright by the WHATWG URL parser: a final label
1707
+ * of digits makes the whole host a candidate IPv4 literal, and `a.00` is not a
1708
+ * valid one. So proxy detection asked about a name that could not be looked up,
1709
+ * concluded there was no proxy on a machine that had one running and holding
1710
+ * 443, and started the bridge without proxy mode — leaving every name to answer
1711
+ * its origin with a certificate no CA has signed.
1712
+ *
1713
+ * An all-numeric ending is legal and wanted (`.420`, `.2600`); it is unusable
1714
+ * only here, which is why this skips them for the probe rather than the registry
1715
+ * refusing to sell them. `--proxy-probe <name>` overrides, for a machine where
1716
+ * the choice has to be a specific real name.
1717
+ */
1718
+ export function probeName(tlds = [], args = []) {
1719
+ const at = args.indexOf("--proxy-probe");
1720
+ if (at >= 0) {
1721
+ const given = args[at + 1];
1722
+ if (given && !given.startsWith("--")) return given;
1723
+ }
1724
+ const usable = tlds.find((t) => !/^\d+$/.test(String(t)));
1725
+ return usable ? `a.${usable}` : null;
1726
+ }
1727
+
1698
1728
  export function upstreamsFromArgs(args = []) {
1699
1729
  const servers = [];
1700
1730
  const invalid = [];
@@ -3095,7 +3125,7 @@ export async function dnsCommand(args = [], out = console.log, deps = {}) {
3095
3125
 
3096
3126
  // The name whose resolution proves the bridge is answering, alongside the
3097
3127
  // clearnet one that proves it is forwarding.
3098
- const moshpitProbe = tlds[0] ? `a.${tlds[0]}` : null;
3128
+ const moshpitProbe = probeName(tlds, rest);
3099
3129
  // Restoring files is not a rollback on Windows: NRPT rules are not files,
3100
3130
  // so the undo is the disable plan's commands rather than the enable plan's.
3101
3131
  const undoSteps = platform === "windows" ? disablePlan({ platform, tlds, linuxBackend }).steps : undefined;
@@ -3264,6 +3294,7 @@ export async function dnsCommand(args = [], out = console.log, deps = {}) {
3264
3294
  // Moshpit names and cannot verify them, which is bad; a machine whose DNS
3265
3295
  // was refused because an optional component would not start is worse.
3266
3296
  let proxyUnitPath = null;
3297
+ let ours = false;
3267
3298
  if (!rest.includes("--no-proxy") && platform === "linux") {
3268
3299
  if (!proxyWrapper()) {
3269
3300
  out(" -- no pinned-TLS proxy installed — https:// on a name will not verify");
@@ -3276,6 +3307,10 @@ export async function dnsCommand(args = [], out = console.log, deps = {}) {
3276
3307
  out(` ${step.ok ? "ok " : "-- "} ${step.step}${step.error ? ` — ${step.error}` : ""}`);
3277
3308
  }
3278
3309
  if (!ensured.ok) out(` -- the proxy is not serving (${ensured.reason}) — https:// will not verify`);
3310
+ // Started by this run, and confirmed holding the port. That is the
3311
+ // strongest evidence available that the proxy on 443 is ours, and it is
3312
+ // strictly better than the handshake below.
3313
+ ours = ensured.ok;
3279
3314
  }
3280
3315
  }
3281
3316
 
@@ -3333,6 +3368,26 @@ export async function dnsCommand(args = [], out = console.log, deps = {}) {
3333
3368
  // proxy and retracting it two lines later is worse than not looking.
3334
3369
  out(" -- the bridge already running was not started by this run, so it keeps its own");
3335
3370
  out(" mode — to pick up proxy mode: moshcode dns disable && moshcode dns enable");
3371
+ } else if (ours) {
3372
+ // No handshake needed, and none that would work.
3373
+ //
3374
+ // The probe asks the proxy for a certificate under some name. The proxy
3375
+ // will not present one for a name with no key published in the registry —
3376
+ // deliberately, so a browser gets a TLS failure it can explain rather than
3377
+ // a reset mid-request — and this command has no way to invent a name that
3378
+ // someone has registered. There is no endpoint that lists names, only
3379
+ // endings, so `a.<ending>` is the best it could ever do and that is
3380
+ // exactly the name the proxy refuses.
3381
+ //
3382
+ // Which made the check impossible to pass on a correctly configured
3383
+ // machine: `proxy holds 127.0.0.1:443` and `no pinned-TLS proxy on this
3384
+ // machine`, three lines apart, both true as written.
3385
+ //
3386
+ // So when this run installed the unit, started it, and watched it take the
3387
+ // port, that is the answer. The probe below stays for a proxy this run did
3388
+ // not start, where the question is genuinely open.
3389
+ proxyAddress = { v4: DEFAULT_HOST, v6: null };
3390
+ out(` ok pinned-TLS proxy on ${DEFAULT_HOST}:${PROXY_PORT} — started by this run, so every live name will answer there`);
3336
3391
  } else if (!rest.includes("--no-proxy")) {
3337
3392
  const probeName = moshpitProbe || "";
3338
3393
  if (!probeName) {