code wiki / _hdl_build / nx_inventory_serve.nx

nx_inventory_serve.nx

buildroot/runtime/_hdl_build/nx_inventory_serve.nx

20557 B394 linesdepth 16pulls 50 transitivereach 1 importersview sourcekind service
docsdependenciesstructsconstsfunctions

about

nx_inventory_serve.nx -- nishifamily.com/inventory : paste a storefront URL, get a LIVING CHECKLIST of what in it you already own. REBUILT 2026-08-07 TO MATCH THE KNOWN GOOD (nx_status_daemon), after the first cut shipped three defects the template would have prevented outright: 1. it bound INADDR_ANY, so an UNAUTHENTICATED, SSRF-capable fetcher answered from another host on the LAN the instant it started (measured, then killed). Now: nx_http_server_addr_loopback. 2. it had NO AUTH, and I intended to route it with proxy mode=gated believing that WAS the login gate. It is not -- `gated` means fail-closed 302 when the BACKEND IS DOWN. Site auth is nx_sa_validate over X-Nishi-Session, NO cookies (charter C1). Now every route but /health is validated, so an unauthenticated request cannot make this daemon fetch anything. 3. its handler was welded to a socket, so the only way to test it was curl from a shell script -- the exact break-glass shape rule 29 forbids. Now the router is a PURE FUNCTION iv_handle(ctx, req, req_n, ...) -> out_n, so a NishiLang gate drives it IN-PROCESS. THIN BY DESIGN. It orchestrates two binaries already proven rather than reimplementing them: 1. ./nx_https_get_cli2.elf <url> -- the sovereign TLS-1.3 client (own trust store) 2. ./nx_ownlib.elf scan <file> -- the ledger diff, selftest 19/19, match key included The match key (ol_norm) is the correctness-critical part, and a daemon holding its own copy is how two components drift into disagreeing about what "the same game" is. So the daemon owns NO matching logic -- it owns a socket, an auth check, and an HTML wrapper. SSRF: this fetches an operator-supplied URL from INSIDE the estate, where mgmt (:18098) and the tools daemon (:18096) sit on loopback. Auth alone is NOT sufficient -- it only means the attacker must be logged in. So the guard is structural and runs before any socket: https only; loopback/private/ link-local refused by construction. nx_inventory_serve <port> <keysfile> <storefile> <realm> <budget> license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 4 imports · 1 importers

nx_syscalls.nx nx_http_server.nx nx_site_auth.nx nx_tool_run.nx nx_inventory_serve.nx nx_inventory_gate.nx

imports: nx_syscalls.nxnx_http_server.nxnx_site_auth.nxnx_tool_run.nx

imported by: nx_inventory_gate.nx

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sys_write sys_exit iv_atoi iv_slen sys_mmap nxa_die sys_write ↻ sys_exit ↻ nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ nx_uas_server_keys_load_or sys_mmap ↻ sys_read_file sys_openat_rd sys_lseek sys_mmap ↻ sys_read sys_munmap sys_close _uas_hex_dec _uas_nib nx_csprng_fill sys_mmap ↻ nx_csprng_urandom_path sys_openat_rd ↻ sys_read ↻ sys_close ↻ nx_opq_derive_keypair sys_mmap ↻ u256_alloc

structs

none

consts

35const IV_MAGIC_4096: i64 = 4096
36const IV_MAGIC_8192: i64 = 8192
37const IV_REQCAP: i64 = 65536
38const IV_PAGECAP: i64 = 4194304 // a bundle page measured 719,027 bytes LIVE; 4 MiB is ~5.8x headroom
39const IV_OUTCAP: i64 = 262144
40const IV_URLCAP: i64 = 2048
41const IV_PATHCAP: i64 = 512
42const IV_SMALL: i64 = 64
43const IV_FETCH_MS: i64 = 45000
44const IV_SCAN_MS: i64 = 30000
45const IV_SESS_TTL: i64 = 900
46const IV_FETCHER: *u8 = "./nx_https_get_cli2.elf" as *u8
47const IV_OWNLIB: *u8 = "./nx_ownlib.elf" as *u8

functions

49func iv_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
called by 1: main
50func iv_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o+i] = s[i]; i = i + 1 } return o + i }
51func iv_catb(d: *u8, o: i64, s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { d[o+i] = s[i]; i = i + 1 } return o + n }
called by 1: iv_resp
52func iv_catn(d: *u8, o: i64, v: i64) -> i64
68func iv_lit_at(buf: *u8, n: i64, i: i64, lit: *u8) -> i64
80func iv_esc(d: *u8, o: i64, s: *u8, n: i64, cap: i64) -> i64
called by 1: iv_check_url calls 1: iv_cat
98func iv_hexval(c: i64) -> i64
called by 1: iv_urldec
110func iv_urldec(src: *u8, sn: i64, i0: i64, dst: *u8, cap: i64) -> i64
called by 2: ig_deciv_handle calls 1: iv_hexval
136func iv_host_start(url: *u8, n: i64) -> i64
144func iv_url_ok(url: *u8, n: i64, whyout: *i64) -> i64
called by 3: ig_urlmainiv_check_url calls 1: iv_lit_at
186func iv_why(w: i64) -> *u8
196func iv_head(d: *u8, o: i64) -> i64
207func iv_foot(d: *u8, o: i64) -> i64
211func iv_resp(out: *u8, status: *u8, body: *u8, blen: i64) -> i64
222func iv_401(out: *u8) -> i64
229func iv_check_url(url: *u8, un: i64, seq: i64, page: *u8, scan: *u8, body: *u8, out: *u8) -> i64
288func iv_handle(ctx: *NxAuthContext, req: *u8, req_n: i64, seq: i64, page: *u8, scan: *u8, body: *u8, out: *u8) -> i64
320func iv_atoi(s: *u8) -> i64
330func main(argc: i64, argv: *i64) -> i64