code wiki / _hdl_build / nx_connect_session_gate.nx

nx_connect_session_gate.nx source

↩ module page · 134 lines · 6552 B

1// nx_connect_session_gate.nx -- gate for the CONNECT R2 anonymous-session layer (nx_connect_accounts 2// session helpers). Proves: a session cookie is extracted from a raw request; two different cookies map 3// to two different account_ids (so two visitors get ISOLATED worlds via the R1 persistence); a fresh 4// mint is unique; and Set-Cookie is injected correctly after the status line (body preserved). Combined 5// with nx_connect_accounts_gate (R1 disk isolation), this is the full per-visitor multi-user path minus 6// OPAQUE identity (R3). license_tier: ORIGINAL expect_exit: 0 7import "nx_connect_accounts.nx" 8 9func sg_w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 10func sg_n(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); 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 i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 } 11func sg_check(pass: i64, label: *u8, fails: *i64) -> i64 { 12 sg_w(" " as *u8); sg_w(label); sg_w(": " as *u8) 13 if pass==1 { sg_w("PASS\n" as *u8) } else { sg_w("FAIL\n" as *u8); fails[0]=fails[0]+1 } 14 return 0 15} 16func sg_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 17func sg_streq(a: *u8, b: *u8) -> i64 { 18 var i: i64=0 19 while a[i]!=(0 as u8) { if a[i]!=b[i] { return 0 } i=i+1 } 20 if b[i]!=(0 as u8) { return 0 } 21 return 1 22} 23func sg_has(buf: *u8, n: i64, needle: *u8) -> i64 { 24 let m: i64 = sg_slen(needle) 25 var i: i64=0 26 while i+m<=n { 27 var k: i64=0 28 var hit: i64=1 29 while k<m { if buf[i+k]!=needle[k] { hit=0; k=m } else { k=k+1 } } 30 if hit==1 { return 1 } 31 i=i+1 32 } 33 return 0 34} 35 36func main() -> i64 { 37 let fails: *i64 = sys_mmap(16) as *i64 38 fails[0]=0 39 sg_w("=== nx_connect_session_gate -- anonymous per-visitor sessions (R2) ===\n" as *u8) 40 41 // T1: extract nxc_sess from a real request with a Cookie header 42 let req1: *u8 = "GET /connect HTTP/1.1\r\nHost: x\r\nCookie: nxc_sess=abc123XYZ; other=1\r\n\r\n" as *u8 43 let val: *u8 = sys_mmap(128) 44 let vl: i64 = acc_cookie_get(req1, sg_slen(req1), val, 128) 45 var t1: i64=0 46 if vl==9 { if sg_streq(val, "abc123XYZ" as *u8)==1 { t1=1 } } 47 sg_w(" cookie value='" as *u8); sg_w(val); sg_w("' len="); sg_n(vl); sg_w("\n" as *u8) 48 sg_check(t1, "T1 extract nxc_sess value from the Cookie header (stops at ';')" as *u8, fails) 49 50 // T2: no cookie -> length 0 (daemon signal to mint a new session) 51 let req2: *u8 = "GET /connect HTTP/1.1\r\nHost: x\r\n\r\n" as *u8 52 let val2: *u8 = sys_mmap(128) 53 let vl2: i64 = acc_cookie_get(req2, sg_slen(req2), val2, 128) 54 var t2: i64=0; if vl2==0 { t2=1 } 55 sg_check(t2, "T2 no cookie -> len 0 (new-visitor signal)" as *u8, fails) 56 57 // T3: two DIFFERENT cookies -> two DIFFERENT account_ids (isolation key) 58 let idA: i64 = acc_id_from_range("abc123XYZ" as *u8, 9) 59 let idB: i64 = acc_id_from_range("zzz999QQQ" as *u8, 9) 60 var t3: i64=0; if idA != idB { if idA > 0 { if idB > 0 { t3=1 } } } 61 sg_w(" idA=" as *u8); sg_n(idA); sg_w(" idB=" as *u8); sg_n(idB); sg_w("\n" as *u8) 62 sg_check(t3, "T3 distinct cookies -> distinct account_ids (per-visitor world key)" as *u8, fails) 63 64 // T4: SAME cookie -> SAME account_id (a returning visitor reloads their own world) 65 let idA2: i64 = acc_id_from_range("abc123XYZ" as *u8, 9) 66 var t4: i64=0; if idA==idA2 { t4=1 } 67 sg_check(t4, "T4 same cookie -> same account_id (returning visitor stable)" as *u8, fails) 68 69 // T5: fresh mints with different salts differ (new visitors get distinct sessions) 70 let s1: *u8 = sys_mmap(64) 71 let s2: *u8 = sys_mmap(64) 72 acc_session_mint(1, s1) 73 acc_session_mint(2, s2) 74 var t5: i64=0; if sg_streq(s1, s2)==0 { if sg_slen(s1)>0 { t5=1 } } 75 sg_check(t5, "T5 fresh session mints (distinct salts) are unique + nonempty" as *u8, fails) 76 77 // T6: Set-Cookie injected after the status line; body + status preserved 78 let resp: *u8 = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 5\r\n\r\nhello" as *u8 79 let out: *u8 = sys_mmap(1024) 80 let on: i64 = acc_inject_cookie(resp, sg_slen(resp), "sess777" as *u8, 7, out, 1024) 81 var t6: i64=0 82 if sg_has(out, on, "HTTP/1.1 200 OK" as *u8)==1 { 83 if sg_has(out, on, "Set-Cookie: nxc_sess=sess777; Path=/; HttpOnly" as *u8)==1 { 84 if sg_has(out, on, "hello" as *u8)==1 { 85 if sg_has(out, on, "Content-Type: text/html" as *u8)==1 { t6=1 } } } } 86 sg_check(t6, "T6 Set-Cookie injected after status line; headers + body intact" as *u8, fails) 87 88 // T7: END-TO-END -- two sessions get isolated persistent worlds (R2 cookie -> R1 disk). 89 let dir: *u8 = "/tmp/connsess\x00" as *u8 90 sys_mkdir(dir, 0x1ff) 91 let wa: *i64 = cs_world_new() 92 // session A posts a distinctive message, saved under A's cookie-derived account 93 let spkA: *i64 = wa[CS_SPK] as *i64 94 let txtA: *u8 = wa[CS_TXTA] as *u8 95 let ka: i64 = wa[CS_NMSG] 96 spkA[ka]=0 97 var w: i64=0 98 let ma: *u8 = "SESSION-A-secret" as *u8 99 while ma[w]!=(0 as u8) { txtA[ka*CS_TXT+w]=ma[w]; w=w+1 } 100 txtA[ka*CS_TXT+w]=0 as u8 101 wa[CS_NMSG]=ka+1 102 acc_save(wa, idA, dir) 103 // session B (fresh) loads its OWN account -> must NOT see A's message 104 let wb: *i64 = cs_world_new() 105 cs_world_reset(wb) 106 acc_load(wb, idB, dir) 107 var b_sees_a: i64=0 108 var bi: i64=0 109 while bi < wb[CS_NMSG] { 110 let btxt: *u8 = wb[CS_TXTA] as *u8 111 if sg_has((btxt as i64 + bi*CS_TXT) as *u8, 20, "SESSION-A-secret" as *u8)==1 { b_sees_a=1 } 112 bi=bi+1 113 } 114 // A reloads and DOES see its own 115 let wa2: *i64 = cs_world_new() 116 cs_world_reset(wa2) 117 acc_load(wa2, idA, dir) 118 var a_sees_a: i64=0 119 var ai: i64=0 120 while ai < wa2[CS_NMSG] { 121 let atxt: *u8 = wa2[CS_TXTA] as *u8 122 if sg_has((atxt as i64 + ai*CS_TXT) as *u8, 20, "SESSION-A-secret" as *u8)==1 { a_sees_a=1 } 123 ai=ai+1 124 } 125 var t7: i64=0 126 if b_sees_a==0 { if a_sees_a==1 { t7=1 } } 127 sg_check(t7, "T7 E2E: session A's message persists for A; session B is isolated (never sees it)" as *u8, fails) 128 129 sg_w(" fails=" as *u8); sg_n(fails[0]); sg_w("\n" as *u8) 130 if fails[0]==0 { sg_w("VERDICT: GREEN (per-visitor sessions: cookie->account isolation, unique mint, cookie inject, E2E isolated persistence)\n" as *u8); sys_exit(0) } 131 sg_w("VERDICT: RED\n" as *u8) 132 sys_exit(1) 133 return 1 134}