nx_iot_hub_serve_realm_gate.nx source
↩ module page · 85 lines · 4710 B
1// nx_iot_hub_serve_realm_gate.nx -- rung-4-live proof with a REAL OPAQUE session (not a mock):
2// mint sessions (register+login), enroll via the HR admin seg-store (the SSOT hac reads), then prove
3// session -> HR level -> IoT tier -> house-scoped render, deny-by-default. Plus the request glue:
4// realm-from-path + token-from-header. expect_exit: 0 license_tier: ORIGINAL
5import "nx_iot_hub_serve_realm.nx"
6
7const G_KEYS: *u8 = "/tmp/iotrealm_keys"
8const G_STORE: *u8 = "/tmp/iotrealm_store"
9const G_HR: *u8 = "/tmp/iotrealm_hr"
10
11func gr_find(h: *u8, n: i64, pat: *u8) -> i64 {
12 var pl: i64 = 0
13 while pat[pl] != (0 as u8) { pl = pl + 1 }
14 return cp_find(h, n, pat, pl)
15}
16func gr_mklogin(ctx: *NxAuthContext, handle: *u8, hn: i64, tok: *u8, tokn: *i64) -> i64 {
17 let mn: *u8 = sys_mmap(512); let mnn: *i64 = sys_mmap(16) as *i64
18 if olg_register(ctx, handle, hn, "pw-test-123456" as *u8, 14, mn, 512, mnn) != NX_MAUTH_OK { return 1 }
19 if olg_login(ctx, handle, hn, "pw-test-123456" as *u8, 14, tok, 512, tokn) != NX_MAUTH_OK { return 2 }
20 return 0
21}
22
23func main() -> i64 {
24 // fresh OPAQUE store+keys for determinism
25 __syscall(263, AT_FDCWD, G_STORE as i64, 0, 0, 0, 0)
26 __syscall(263, AT_FDCWD, G_KEYS as i64, 0, 0, 0, 0)
27 __syscall(263, AT_FDCWD, G_HR as i64, 0, 0, 0, 0)
28
29 let ctx: *NxAuthContext = sys_mmap(256) as *NxAuthContext
30 if olg_ctx_setup(ctx, G_KEYS, G_STORE, "westhouse" as *u8, 9, "West House" as *u8, 10, 8, 3, 4) != 0 { return 1 }
31 let now: i64 = sys_now_realtime_sec()
32
33 // mint three real sessions
34 let tA: *u8 = sys_mmap(512); let tAn: *i64 = sys_mmap(16) as *i64
35 let tB: *u8 = sys_mmap(512); let tBn: *i64 = sys_mmap(16) as *i64
36 let tC: *u8 = sys_mmap(512); let tCn: *i64 = sys_mmap(16) as *i64
37 if gr_mklogin(ctx, "alice" as *u8, 5, tA, tAn) != 0 { return 2 }
38 if gr_mklogin(ctx, "bob" as *u8, 3, tB, tBn) != 0 { return 3 }
39 if gr_mklogin(ctx, "carol" as *u8, 5, tC, tCn) != 0 { return 4 }
40
41 // enroll alice=owner(3), bob=family(1) in the HR admin seg-store; carol left UNENROLLED
42 let cid: *u8 = sys_mmap(96)
43 if hra_enroll(G_HR, "westhouse" as *u8, 9, "alice" as *u8, 5, 3, "west" as *u8, now, "test" as *u8, cid) != 0 { return 5 }
44 if hra_enroll(G_HR, "westhouse" as *u8, 9, "bob" as *u8, 3, 1, "west" as *u8, now, "test" as *u8, cid) != 0 { return 6 }
45
46 // ---- session -> tier (deny-by-default) ----
47 if iot_hub_resolve_tier(ctx, tA, tAn[0], now, G_HR) != IOT_OWNER { return 10 } // owner
48 if iot_hub_resolve_tier(ctx, tB, tBn[0], now, G_HR) != IOT_FAMILY { return 11 } // family
49 if iot_hub_resolve_tier(ctx, tC, tCn[0], now, G_HR) != IOT_DENY { return 12 } // authenticated, NOT enrolled
50 if iot_hub_resolve_tier(ctx, "garbage-token" as *u8, 13, now, G_HR) != IOT_DENY { return 13 }
51 if iot_hub_resolve_tier(ctx, "" as *u8, 0, now, G_HR) != IOT_DENY { return 14 }
52
53 // ---- tier -> house-scoped render ----
54 let h: *u8 = sys_mmap(262144)
55 let on: i64 = iot_hub_render_for(ctx, tA, tAn[0], now, "westhouse" as *u8, G_HR, h)
56 if gr_find(h, on, "action=\"/home/cmd\"" as *u8) < 0 { return 20 }
57 if gr_find(h, on, "action=\"/home/manage\"" as *u8) < 0 { return 21 } // owner CAN manage
58 let fn: i64 = iot_hub_render_for(ctx, tB, tBn[0], now, "westhouse" as *u8, G_HR, h)
59 if gr_find(h, fn, "action=\"/home/cmd\"" as *u8) < 0 { return 22 }
60 if gr_find(h, fn, "action=\"/home/manage\"" as *u8) != (0 - 1) { return 23 } // family CANNOT manage
61 let dn: i64 = iot_hub_render_for(ctx, tC, tCn[0], now, "westhouse" as *u8, G_HR, h)
62 if gr_find(h, dn, "Access denied" as *u8) < 0 { return 24 }
63 if gr_find(h, dn, "192.168.10.166" as *u8) != (0 - 1) { return 25 } // DENY leaks no devices
64 if gr_find(h, dn, "<script" as *u8) != (0 - 1) { return 26 } // still zero-JS
65
66 // ---- request glue: realm-from-path + token-from-header ----
67 let req: *u8 = sys_mmap(512)
68 let s: *u8 = "GET /westhouse/ HTTP/1.1\r\nHost: x\r\nX-Nishi-Session: ABC123tok\r\n\r\n" as *u8
69 var i: i64 = 0
70 while s[i] != (0 as u8) { req[i] = s[i]; i = i + 1 }
71 let rn: i64 = i
72 let realm: *u8 = sys_mmap(64)
73 // path "/westhouse/" is at offset 4, length 11
74 let rl: i64 = iot_realm_from_path(req, 4, 11, realm)
75 if rl != 9 { return 30 }
76 if realm[0] != (119 as u8) { return 31 } // 'w'
77 if realm[8] != (101 as u8) { return 32 } // 'e' (westhous*e*)
78 let tokv: *u8 = sys_mmap(64)
79 let tl: i64 = iot_token_from_req(req, rn, tokv)
80 if tl != 9 { return 33 }
81 if tokv[0] != (65 as u8) { return 34 } // 'A'
82 if tokv[8] != (107 as u8) { return 35 } // 'k' (ABC123to*k*)
83
84 return 0
85}