code wiki / _hdl_build / nx_mesh_gateway.nx

nx_mesh_gateway.nx

buildroot/runtime/_hdl_build/nx_mesh_gateway.nx

24911 B336 linesdepth 16pulls 48 transitivereach 0 importersview sourcekind tooltopic mesh
docsdependenciesstructsconstsfunctions

about

nx_gallery_gateway.nx -- OPAQUE-gated reverse proxy for the NSFW gallery, mounted under /mesh/*. Auth = the gallery's OWN OPAQUE realm (own keys+store via argv -> isolated NSFW realm) + the Service-Worker header-injection model (the SW adds X-Nishi-Session to every /mesh/* request incl. media -> NO cookie, cardinal C1 preserved). The gateway validates X-Nishi-Session per request via olg_whoami, then reverse-proxies the request (prefix-stripped) to the gallery backend. No valid session -> 401 (never a public byte). Bootstrap: GET /mesh/login (page) registers the SW. argv: [1]=listen_port [2]=keys_path [3]=store_path [4]=budget [5]=backend_port [6]=allow_register(0|1; PROD=0) [7]=m_cost(opt 65536) [8]=t(opt 3) [9]=p(opt 4) R1 = loopback proof (no TLS yet; TLS termination + path-route into nishifamily.com = R3).

dependencies 3 imports · 0 importers

nx_opaque_login.nx nx_http_form.nx nx_connect.nx nx_mesh_gateway.nx

imports: nx_opaque_login.nxnx_http_form.nxnx_connect.nx

imported by: nobody (leaf or entry point)

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

main gw_atoi olg_ctx_setup_ttl nx_uas_server_keys_load_or sys_mmap sys_read_file sys_openat_rd sys_lseek sys_mmap ↻ sys_read 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 ↻ _voprf_load_context_string u256_alloc nx_scratch nx_scratch_init nx_scratch_oom sys_mmap ↻ nx_opq_hash_to_scalar sys_mmap ↻ nx_h2c_expand_message_xmd_ sys_mmap ↻ _h2c_i2osp_1 _h2c_i2osp_2 u256_alloc ↻ _opq_reduce_48be_mod_n u256_alloc ↻ sys_mmap ↻ u256_load_be p256_modn_load_n u256_cmp

structs

none

consts

13const GGW_MAGIC_262144: i64 = 262144
14const GGW_MAGIC_6291456: i64 = 6291456
15const GGW_MAGIC_131072: i64 = 131072
16const GGW_MAGIC_131071: i64 = 131071
17const GGW_MAGIC_8192: i64 = 8192
19const GGW_PROD_M: i64 = 65536
24const GGW_SESSION_TTL: i64 = 86400
167const GGW_SW_JS: *u8 = "var DBN='nishi_gallery',ST='auth';function tok(){return new Promise(function(res){try{var r=indexedDB.open(DBN,1);r.onupgradeneeded=function(e){e.target.result.createObjectStore(ST)};r.onsuccess=function(e){var db=e.target.result;try{var g=db.transaction(ST,'readonly').objectStore(ST).get('nsess');g.onsuccess=function(){res(g.result||'')};g.onerror=function(){res('')}}catch(x){res('')}};r.onerror=function(){res('')}}catch(x){res('')}})}self.addEventListener('install',function(e){self.skipWaiting()});self.addEventListener('activate',function(e){e.waitUntil(self.clients.claim())});self.addEventListener('fetch',function(e){var u;try{u=new URL(e.request.url)}catch(x){return}if(u.origin!==self.location.origin){return}var pn=u.pathname;if(pn.indexOf('/mesh/')!==0){return}if(pn.indexOf('/mesh/auth/')===0||pn==='/mesh/sw.js'||pn==='/mesh/login'){return}e.respondWith(tok().then(function(t){var h=new Headers(e.request.headers);if(t){h.set('X-Nishi-Session',t)}if(e.request.method==='GET'){return fetch(new Request(u.href,{headers:h}))}var rq;try{rq=new Request(e.request,{headers:h})}catch(x){rq=e.request}return fetch(rq)}).catch(function(){return fetch(e.request)}))});" as *u8
171const GGW_LOGIN_HTML: *u8 = "<!doctype html><html><head><meta charset=utf-8><meta name=viewport content=\"width=device-width,initial-scale=1\"><title>Nishi Mesh</title><style>body{font-family:system-ui,sans-serif;max-width:420px;margin:8vh auto;padding:0 18px;color:#cdd7e6;background:#0b1019}h1{font-size:1.2rem;color:#e8eef7}p{color:#7c8aa5;font-size:.86rem}input{width:100%;padding:9px;margin:5px 0;box-sizing:border-box;border:1px solid #2a3550;border-radius:5px;background:#121a28;color:#e8eef7}button{padding:9px 16px;margin:6px 6px 0 0;background:#2d6cdf;color:#fff;border:0;border-radius:5px;cursor:pointer}#m{margin:14px 0;padding:12px;background:#121a28;border-left:3px solid #2d6cdf;color:#cdd7e6;word-break:break-all;min-height:1.2em}</style></head><body><h1>Nishi Mesh &mdash; private console</h1><p>Full OPAQUE aPAKE (RFC 9807). The passphrase never leaves your browser as anything crackable; the session rides a Service Worker, not a cookie.</p><div id=m>Log in to reach the sovereign mesh console.</div><input id=h placeholder=handle autocomplete=username><input id=p type=password placeholder=passphrase autocomplete=current-password><button onclick=login()>Login</button> <button onclick=reg()>Register</button><script>function $(i){return document.getElementById(i)} function M(t){$('m').textContent=t} function setTok(t){return new Promise(function(res){var r=indexedDB.open('nishi_gallery',1);r.onupgradeneeded=function(e){e.target.result.createObjectStore('auth')};r.onsuccess=function(e){var db=e.target.result;var tx=db.transaction('auth','readwrite').objectStore('auth').put(t,'nsess');tx.onsuccess=function(){res()};tx.onerror=function(){res()}};r.onerror=function(){res()}})} async function reg(){M('Registering (memory-hard, a moment)...');try{var r=await fetch('/mesh/auth/register',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'handle='+encodeURIComponent($('h').value)+'&pw='+encodeURIComponent($('p').value)});var j=await r.json();M(r.ok?('Registered. SAVE THIS RECOVERY MNEMONIC: '+j.mnemonic):('Register failed: '+(j.error||r.status)))}catch(e){M('error: '+e)}} async function login(){M('Logging in...');try{var r=await fetch('/mesh/auth/login',{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:'handle='+encodeURIComponent($('h').value)+'&pw='+encodeURIComponent($('p').value)});var j=await r.json();if(!r.ok){M('Login failed: '+(j.error||r.status));return}await setTok(j.token);if('serviceWorker' in navigator){try{await navigator.serviceWorker.register('/mesh/sw.js',{scope:'/mesh/'});await navigator.serviceWorker.ready}catch(e){}}M('Logged in. Opening mesh console...');location.href='/mesh/'}catch(e){M('error: '+e)}}</script></body></html>" as *u8

functions

26func gw_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
27func gw_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c<48{return v} if c>57{return v} v=v*10+(c-48); i=i+1 } return v }
called by 2: gw_read_fullmain
28func gw_starts(buf: *u8, n: i64, pre: *u8) -> i64 { var i: i64=0; while pre[i]!=(0 as u8){ if i>=n {return 0} if buf[i]!=pre[i]{return 0} i=i+1 } return 1 }
called by 1: main
29func gw_find(buf: *u8, n: i64, needle: *u8, nl: i64) -> i64
35func gw_cat(dst: *u8, off: i64, s: *u8) -> i64 { var o: i64=off; var i: i64=0; while s[i]!=(0 as u8){dst[o]=s[i]; o=o+1; i=i+1} return o }
36func gw_catb(dst: *u8, off: i64, src: *u8, n: i64) -> i64 { var o: i64=off; var i: i64=0; while i<n {dst[o]=src[i]; o=o+1; i=i+1} return o }
37func gw_itoa(dst: *u8, off: i64, v: i64) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var o: i64=off; var q: i64=k-1; while q>=0{dst[o]=t[q];o=o+1;q=q-1} return o }
40func gw_send(cfd: i64, status: *u8, ctype: *u8, body: *u8, blen: i64) -> i64
called by 2: gw_401main calls 3: gw_catgw_itoagw_catb
49func gw_401(cfd: i64) -> i64
called by 1: main calls 2: gw_sendgw_slen
55func gw_is_nav(req: *u8, n: i64) -> i64 { if gw_find(req, n, "Sec-Fetch-Mode: navigate" as *u8, 24) >= 0 { return 1 } return 0 }
called by 1: main calls 1: gw_find
57func gw_302_login(cfd: i64) -> i64
called by 1: main calls 1: gw_slen
64func gw_send_ck(cfd: i64, ctype: *u8, body: *u8, blen: i64, ckval: *u8, ckvallen: i64, ttl: i64) -> i64
called by 1: main calls 3: gw_catgw_catbgw_itoa
83func gw_hdr_val(req: *u8, hend: i64, name: *u8, nl: i64, out: *u8, cap: i64) -> i64
called by 3: gw_proxygw_read_fullmain calls 1: gw_find
93func gw_reqpath(req: *u8, rn: i64, out: *u8, cap: i64) -> i64
called by 1: main
104func gw_emit_range_raw(rq: *u8, o0: i64, rng: *u8, rngn: i64) -> i64
called by 1: gw_cap_range calls 2: gw_catgw_catb
112func gw_cap_range(rq: *u8, o0: i64, rng: *u8, rngn: i64) -> i64
132func gw_proxy(cfd: i64, bport: i64, method: *u8, mlen: i64, bpath: *u8, bplen: i64, body: *u8, blen: i64, oreq: *u8, ohe: i64) -> i64
177func gw_read_full(cfd: i64, req: *u8, cap: i64) -> i64
200func main(argc: i64, argv: *i64) -> i64