code wiki / _hdl_build / nx_access_gate.nx

nx_access_gate.nx source

↩ module page · 120 lines · 7931 B

1import "nx_gate_gn.nx" 2// nx_access_gate.nx -- hermetic gate for the S-class authorization core (ag_allow). Builds fixture 3// site-locks + a roles registry in memory and proves the load-bearing security properties: 4// T1 public area -> ALLOW for anyone (even no session) 5// T2 family area + member(L1) -> ALLOW 6// T3 (NEG) family area + no-session(L0) -> DENY [deny-by-default] 7// T4 owner area + owner(L3) -> ALLOW 8// T5 (NEG) owner area + member(L1) -> DENY [NO privilege escalation] 9// T6 (NEG) owner area + no-session(L0) -> DENY 10// T7 owner(L3) on a family area(L1) -> ALLOW [owner clears everything] 11// T8 (NEG) unknown handle on a gated area -> DENY [unlisted = level 0] 12// Sovereign: nx_syscalls + nx_access_lib. license_tier: ORIGINAL 13import "nx_syscalls.nx" 14import "nx_access_lib.nx" 15 16func gp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 17func g_app(buf: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { buf[off + i] = s[i]; i = i + 1 } return off + i } 18func g_row2(buf: *u8, off: i64, a: *u8, b: *u8) -> i64 { 19 var o: i64 = g_app(buf, off, a); buf[o] = 9 as u8; o = o + 1 20 o = g_app(buf, o, b); buf[o] = 10 as u8; o = o + 1 21 return o 22} 23func g_row4(buf: *u8, off: i64, a: *u8, b: *u8, c: *u8, d: *u8) -> i64 { 24 var o: i64 = g_app(buf, off, a); buf[o] = 9 as u8; o = o + 1 25 o = g_app(buf, o, b); buf[o] = 9 as u8; o = o + 1 26 o = g_app(buf, o, c); buf[o] = 9 as u8; o = o + 1 27 o = g_app(buf, o, d); buf[o] = 10 as u8; o = o + 1 28 return o 29} 30func g_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 31func g_write_file(path: *u8, buf: *u8, n: i64) -> i64 { 32 let fd: i64 = sys_openat_wr(path, 0x1a4) 33 if fd < 0 { return 0 - 1 } 34 sys_write(fd, buf, n); sys_close(fd) 35 return n 36} 37 38func main(argc: i64, argv: *i64) -> i64 { 39 gp("=== nx_access_gate (S-class authz: allow iff granted>=required, deny-by-default) ===\n" as *u8) 40 // fixture site-locks: a family area (L1) + an owner-only area (L3); everything else public. 41 let sl: *u8 = sys_mmap(4096); var sn: i64 = 0 42 sn = g_row4(sl, sn, "area" as *u8, "nishifamily/family" as *u8, "Nishi Family" as *u8, "1" as *u8) 43 sn = g_row4(sl, sn, "area" as *u8, "nishifamily/gallery" as *u8, "Nishi Gallery" as *u8, "3" as *u8) 44 // fixture roles: owner=3, a family member=1; anyone else unlisted=0. 45 let roles: *u8 = sys_mmap(4096); var rn: i64 = 0 46 rn = g_row2(roles, rn, "owner_h" as *u8, "3" as *u8) 47 rn = g_row2(roles, rn, "family_h" as *u8, "1" as *u8) 48 49 let realm: *u8 = sys_mmap(128); let req: *i64 = sys_mmap(8); let grant: *i64 = sys_mmap(8) 50 let nf: *u8 = "nishifamily" as *u8; let nfl: i64 = g_slen(nf) 51 let p_pub: *u8 = "/charter.html" as *u8 52 let p_fam: *u8 = "/family/notes.html" as *u8 53 let p_gal: *u8 = "/gallery/photo1.jpg" as *u8 54 let owner: *u8 = "owner_h" as *u8; let fam: *u8 = "family_h" as *u8; let ghost: *u8 = "ghost_h" as *u8 55 var pass: i64 = 0; var fail: i64 = 0 56 57 // T1 public -> allow for nobody-session 58 var a: i64 = ag_allow(sl, sn, roles, rn, nf, nfl, p_pub, g_slen(p_pub), "none" as *u8, 0, req, grant, realm, 128) 59 if a == 1 { pass = pass + 1; gp(" T1 public->ALLOW(any) PASS\n" as *u8) } else { fail = fail + 1; gp(" T1 FAIL\n" as *u8) } 60 61 // T2 family area + member -> allow 62 a = ag_allow(sl, sn, roles, rn, nf, nfl, p_fam, g_slen(p_fam), fam, g_slen(fam), req, grant, realm, 128) 63 if a == 1 { if req[0] == 1 { if grant[0] == 1 { pass = pass + 1; gp(" T2 family+member->ALLOW PASS\n" as *u8) } } } 64 if a != 1 { fail = fail + 1; gp(" T2 FAIL denied\n" as *u8) } 65 66 // T3 (NEG) family area + no session -> DENY 67 a = ag_allow(sl, sn, roles, rn, nf, nfl, p_fam, g_slen(p_fam), "none" as *u8, 0, req, grant, realm, 128) 68 if a == 0 { pass = pass + 1; gp(" T3 family+no-session->DENY PASS\n" as *u8) } else { fail = fail + 1; gp(" T3 FAIL allowed\n" as *u8) } 69 70 // T4 owner area + owner -> allow 71 a = ag_allow(sl, sn, roles, rn, nf, nfl, p_gal, g_slen(p_gal), owner, g_slen(owner), req, grant, realm, 128) 72 if a == 1 { if req[0] == 3 { pass = pass + 1; gp(" T4 owner-area+owner->ALLOW PASS\n" as *u8) } } 73 if a != 1 { fail = fail + 1; gp(" T4 FAIL\n" as *u8) } 74 75 // T5 (NEG) owner area + family member -> DENY (no escalation) 76 a = ag_allow(sl, sn, roles, rn, nf, nfl, p_gal, g_slen(p_gal), fam, g_slen(fam), req, grant, realm, 128) 77 if a == 0 { pass = pass + 1; gp(" T5 owner-area+member->DENY (no escalation) PASS\n" as *u8) } else { fail = fail + 1; gp(" T5 FAIL escalation\n" as *u8) } 78 79 // T6 (NEG) owner area + no session -> DENY 80 a = ag_allow(sl, sn, roles, rn, nf, nfl, p_gal, g_slen(p_gal), "none" as *u8, 0, req, grant, realm, 128) 81 if a == 0 { pass = pass + 1; gp(" T6 owner-area+no-session->DENY PASS\n" as *u8) } else { fail = fail + 1; gp(" T6 FAIL\n" as *u8) } 82 83 // T7 owner on family area -> allow (clears everything) 84 a = ag_allow(sl, sn, roles, rn, nf, nfl, p_fam, g_slen(p_fam), owner, g_slen(owner), req, grant, realm, 128) 85 if a == 1 { pass = pass + 1; gp(" T7 owner-clears-family-area->ALLOW PASS\n" as *u8) } else { fail = fail + 1; gp(" T7 FAIL\n" as *u8) } 86 87 // T8 (NEG) unknown handle on gated area -> DENY 88 a = ag_allow(sl, sn, roles, rn, nf, nfl, p_fam, g_slen(p_fam), ghost, g_slen(ghost), req, grant, realm, 128) 89 if a == 0 { if grant[0] == 0 { pass = pass + 1; gp(" T8 unknown-handle->DENY (level 0) PASS\n" as *u8) } } 90 if a != 0 { fail = fail + 1; gp(" T8 FAIL allowed\n" as *u8) } 91 92 // ---- ag_uid_to_level: the SHARED session-identity -> level chain the mgmt API + hub gw now compose ---- 93 // (session uid HASH -> hex -> the uid->handle index -> the roles registry -> level). File fixtures written to /tmp. 94 let fidx: *u8 = sys_mmap(256); var fin: i64 = 0 95 fin = g_row2(fidx, fin, "aabb" as *u8, "elderwesto" as *u8) // uid 0xAA 0xBB -> handle elderwesto 96 fin = g_row2(fidx, fin, "ccdd" as *u8, "ghost_h" as *u8) // a uid whose handle is absent from roles 97 g_write_file("/tmp/ag_fix_idx.tsv" as *u8, fidx, fin) 98 let frol: *u8 = sys_mmap(256); var frn: i64 = 0 99 frn = g_row2(frol, frn, "elderwesto" as *u8, "3" as *u8) // operator=3 100 g_write_file("/tmp/ag_fix_roles.tsv" as *u8, frol, frn) 101 102 // T9 uid -> index handle -> roles level = operator(3) 103 let uid1: *u8 = sys_mmap(8); uid1[0]=0xaa as u8; uid1[1]=0xbb as u8 104 let lv1: i64 = ag_uid_to_level(uid1, 2, "/tmp/ag_fix_idx.tsv" as *u8, "/tmp/ag_fix_roles.tsv" as *u8) 105 if lv1 == 3 { pass = pass + 1; gp(" T9 uid->index->roles = operator(3) PASS\n" as *u8) } else { fail = fail + 1; gp(" T9 FAIL lv=" as *u8); gn(lv1); gp("\n" as *u8) } 106 107 // T10 (NEG) uid not in the index -> 0 (deny-by-default: an ecosystem session with no identity row grants nothing) 108 let uid2: *u8 = sys_mmap(8); uid2[0]=0xee as u8; uid2[1]=0xff as u8 109 let lv2: i64 = ag_uid_to_level(uid2, 2, "/tmp/ag_fix_idx.tsv" as *u8, "/tmp/ag_fix_roles.tsv" as *u8) 110 if lv2 == 0 { pass = pass + 1; gp(" T10 uid-not-in-index->0 (deny-by-default) PASS\n" as *u8) } else { fail = fail + 1; gp(" T10 FAIL lv=" as *u8); gn(lv2); gp("\n" as *u8) } 111 112 // T11 (NEG) uid -> handle present but NOT in roles -> 0 (a family member's session can't reach operator routes) 113 let uid3: *u8 = sys_mmap(8); uid3[0]=0xcc as u8; uid3[1]=0xdd as u8 114 let lv3: i64 = ag_uid_to_level(uid3, 2, "/tmp/ag_fix_idx.tsv" as *u8, "/tmp/ag_fix_roles.tsv" as *u8) 115 if lv3 == 0 { pass = pass + 1; gp(" T11 handle-not-in-roles->0 PASS\n" as *u8) } else { fail = fail + 1; gp(" T11 FAIL lv=" as *u8); gn(lv3); gp("\n" as *u8) } 116 117 gp("RESULT pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail) 118 if fail == 0 { gp(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 119 gp(" verdict=RED\n" as *u8); sys_exit(1); return 1 120}