code wiki / _hdl_build / nx_cms_session_gate.nx
nx_cms_session_gate.nx source
↩ module page · 51 lines · 2866 B
1// nx_cms_session_gate.nx -- INTEGRATION gate for the #8 session-timeout wiring in nx_cms_admin. Drives the
2// REAL ca_session_ok through the login lifecycle: no-session -> reject; fresh login (st_hex128 rotate +
3// sess_issue stamp) -> accept (proves the wiring did NOT break login); absolute-aged + idle-aged sessions
4// -> reject (proves the timeout fires). `now` is the real clock; session AGE is simulated by setting the
5// packed issued_at/last_seen, so no waiting. exit 0 = pass, N = assertion N failed.
6import "nx_cms_admin.nx" // ca_session_ok, ca_cat, st_hex128
7import "nx_session_ttl.nx" // sess_issue, SESS_*_TTL_MS
8import "nx_assert.nx"
9
10// build a request buffer "...Cookie: nsess=<32 token bytes from sess>..." -> returns header end offset.
11func g_req(buf: *u8, sess: *u8) -> i64 {
12 var q: i64 = ca_cat(buf, 0, "GET /admin HTTP/1.1\r\nCookie: nsess=" as *u8)
13 var ti: i64 = 0; while ti < 32 { buf[q] = sess[ti]; q = q + 1; ti = ti + 1 }
14 q = ca_cat(buf, q, "\r\n\r\n" as *u8)
15 return q
16}
17
18func main() -> i64 {
19 let sess: *u8 = sys_mmap(64); sess[0] = 0 as u8
20 let buf: *u8 = sys_mmap(512)
21
22 // 1. no session issued yet -> reject (even though a cookie could be present, sess[0]==0)
23 let h0: i64 = g_req(buf, sess)
24 if ca_session_ok(buf, h0, sess) != 0 { return 1 }
25
26 // 2. fresh login: rotate token + stamp timestamps -> a request with the matching cookie is ACCEPTED.
27 // (this is the login-not-broken assertion -- if sess_issue were missing, issued_at=0 -> instant abs-expiry)
28 st_hex128(sess)
29 sess_issue(sess, sys_now_realtime_ms())
30 let h1: i64 = g_req(buf, sess)
31 if ca_session_ok(buf, h1, sess) != 1 { return 2 }
32
33 // 3. absolute-aged: issued just over the hard cap ago -> REJECT (abs cap, even with recent activity)
34 let pi: *i64 = (sess + 32) as *i64; pi[0] = sys_now_realtime_ms() - SESS_ABS_TTL_MS - 5000
35 let pl: *i64 = (sess + 40) as *i64; pl[0] = sys_now_realtime_ms() // recently active...
36 if ca_session_ok(buf, h1, sess) != 0 { return 3 } // ...still killed by the absolute cap
37
38 // 4. idle-aged: issued recently, but last activity beyond the idle window -> REJECT (idle timeout)
39 sess_issue(sess, sys_now_realtime_ms())
40 let pl2: *i64 = (sess + 40) as *i64; pl2[0] = sys_now_realtime_ms() - SESS_IDLE_TTL_MS - 5000
41 if ca_session_ok(buf, h1, sess) != 0 { return 4 }
42
43 // 5. re-login recovers (fresh stamp) -> accepted again
44 st_hex128(sess); sess_issue(sess, sys_now_realtime_ms())
45 let h5: i64 = g_req(buf, sess)
46 if ca_session_ok(buf, h5, sess) != 1 { return 5 }
47
48 nx_puts_err("session wiring: no-sess=reject, fresh=accept, abs-aged=reject, idle-aged=reject, re-login=accept\n" as *u8)
49 nx_puts_err("nx_cms_session_gate verdict=GREEN pass=5 (login NOT broken + idle/absolute timeout LIVE)\n" as *u8)
50 return 0
51}