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}