code wiki / _hdl_build / nx_mesh_gateway.nx
nx_mesh_gateway.nx
buildroot/runtime/_hdl_build/nx_mesh_gateway.nx
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
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
structs
| none |
consts
| 13 | const GGW_MAGIC_262144: i64 = 262144 |
| 14 | const GGW_MAGIC_6291456: i64 = 6291456 |
| 15 | const GGW_MAGIC_131072: i64 = 131072 |
| 16 | const GGW_MAGIC_131071: i64 = 131071 |
| 17 | const GGW_MAGIC_8192: i64 = 8192 |
| 19 | const GGW_PROD_M: i64 = 65536 |
| 24 | const GGW_SESSION_TTL: i64 = 86400 |
| 167 | const 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 |
| 171 | const 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 — 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
| 26 | func gw_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } |
| 27 | func 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 } |
| 28 | func 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 |
| 29 | func gw_find(buf: *u8, n: i64, needle: *u8, nl: i64) -> i64 |
| 35 | func 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 } |
| 36 | func 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 } |
| 37 | func 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 } |
| 40 | func gw_send(cfd: i64, status: *u8, ctype: *u8, body: *u8, blen: i64) -> i64 |
| 49 | func gw_401(cfd: i64) -> i64 |
| 55 | func 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 } |
| 57 | func gw_302_login(cfd: i64) -> i64 |
| 64 | func gw_send_ck(cfd: i64, ctype: *u8, body: *u8, blen: i64, ckval: *u8, ckvallen: i64, ttl: i64) -> i64 |
| 75 | func gw_cookie_val(req: *u8, hend: i64, out: *u8, cap: i64) -> i64 |
| 83 | func gw_hdr_val(req: *u8, hend: i64, name: *u8, nl: i64, out: *u8, cap: i64) -> i64 |
| 93 | func gw_reqpath(req: *u8, rn: i64, out: *u8, cap: i64) -> i64 called by 1: main |
| 104 | func gw_emit_range_raw(rq: *u8, o0: i64, rng: *u8, rngn: i64) -> i64 |
| 112 | func gw_cap_range(rq: *u8, o0: i64, rng: *u8, rngn: i64) -> i64 |
| 132 | func gw_proxy(cfd: i64, bport: i64, method: *u8, mlen: i64, bpath: *u8, bplen: i64, body: *u8, blen: i64, oreq: *u8, ohe: i64) -> i64 called by 1: main calls 9: sys_socketsys_set_socket_timeoutnx_connect_boundedgw_catbgw_catgw_hdr_val+3 |
| 177 | func gw_read_full(cfd: i64, req: *u8, cap: i64) -> i64 |
| 200 | func main(argc: i64, argv: *i64) -> i64 |