code wiki / _hdl_build / nx_studio_daemon_gate.nx
nx_studio_daemon_gate.nx source
↩ module page · 165 lines · 9363 B
1// nx_studio_daemon_gate.nx -- SOVEREIGN in-process referee for the OPAQUE-gated studio daemon (no socket, no
2// curl, no shell). Arms a realm + registers an admin via the REAL Modern Auth (OPAQUE-3DH), then feeds crafted
3// HTTP request BYTES into the pure router stu_handle and asserts the response bytes -- the whole no-cookie
4// login -> token -> gated-build -> deny flow, inside one Nishi organ. Proves the studio is behind the CANONICAL
5// login (X-Nishi-Session, NOT a cookie, NOT nx_cms_admin).
6// T1 GET /webdev -> 200 + SPA shell (public)
7// T2 POST /webdev/login ok -> 200 + {"token":...} (mint a real 152B no-cookie token)
8// T3 POST /webdev/build WITH token, tier|guided -> 200 + governed guided page
9// T4 POST /webdev/build NO token -> 401 (default-deny: cannot build/publish unauthenticated)
10// T5 POST /webdev/login WRONG pw -> 401
11// T6 POST /webdev/build BAD token -> 401 (forged token rejected by Ed25519)
12// T7 GET /webdev/guided -> 200 + the guided surface (served)
13// T8 POST /webdev/build WITH token, tier|freeform -> 200 + governed canvas (placement honored)
14// Sovereign: nx_sitegen_studio_daemon + nx_modern_auth_flow + nx_syscalls. license_tier: ORIGINAL
15import "nx_sitegen_studio_daemon.nx"
16import "hub/nx_modern_auth_flow.nx"
17import "nx_syscalls.nx"
18
19func sdg_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
20func sdg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
21func sdg_row(name: *u8, ok: i64) -> i64 { if ok == 1 { sdg_w(" PASS " as *u8) } if ok != 1 { sdg_w(" FAIL " as *u8) } sdg_w(name); sdg_w("\n" as *u8); return ok }
22func sdg_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o + i] = s[i]; i = i + 1 } return o + i }
23func sdg_cat_n(d: *u8, o: i64, s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { d[o + i] = s[i]; i = i + 1 } return o + n }
24func sdg_trunc(path: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x180); if fd >= 0 { sys_close(fd) } return 0 }
25func sdg_starts(buf: *u8, n: i64, s: *u8) -> i64 {
26 let sn: i64 = sdg_len(s)
27 if n < sn { return 0 }
28 var i: i64 = 0
29 while i < sn { if (buf[i] as i64) != (s[i] as i64) { return 0 } i = i + 1 }
30 return 1
31}
32func sdg_contains(hay: *u8, n: i64, needle: *u8) -> i64 {
33 let nn: i64 = sdg_len(needle)
34 var i: i64 = 0
35 while i + nn <= n {
36 var m: i64 = 1
37 var j: i64 = 0
38 while j < nn { if (hay[i + j] as i64) != (needle[j] as i64) { m = 0; j = nn } else { j = j + 1 } }
39 if m == 1 { return 1 }
40 i = i + 1
41 }
42 return 0
43}
44func sdg_extract_token(resp: *u8, n: i64, out: *u8) -> i64 {
45 let key: *u8 = "{\"token\":\"" as *u8
46 let kn: i64 = 10
47 var start: i64 = 0 - 1
48 var i: i64 = 0
49 while i + kn <= n {
50 var m: i64 = 1
51 var j: i64 = 0
52 while j < kn { if (resp[i + j] as i64) != (key[j] as i64) { m = 0; j = kn } else { j = j + 1 } }
53 if m == 1 { start = i + kn; i = n }
54 i = i + 1
55 }
56 if start < 0 { return 0 }
57 var w: i64 = 0
58 var k: i64 = start
59 var done: i64 = 0
60 while done == 0 {
61 if k >= n { done = 1 }
62 if done == 0 { if (resp[k] as i64) == 34 { done = 1 } }
63 if done == 0 { out[w] = resp[k]; w = w + 1; k = k + 1 }
64 }
65 return w
66}
67
68func main() -> i64 {
69 sdg_w("studio-daemon SOVEREIGN in-process gate (OPAQUE no-cookie; stu_handle bytes-in/bytes-out)\n" as *u8)
70 let store_path: *u8 = "/tmp/nx_stu_gate_store.log" as *u8
71 let keys_path: *u8 = "/tmp/nx_stu_gate_keys.log" as *u8
72 sdg_trunc(store_path)
73 sdg_trunc(keys_path)
74
75 let oprf_seed: *u8 = sys_mmap(32)
76 let akp: *u8 = sys_mmap(32)
77 let akb: *u8 = sys_mmap(33)
78 let edp: *u8 = sys_mmap(32)
79 let edb: *u8 = sys_mmap(32)
80 if nx_uas_server_keys_load_or_init(keys_path, oprf_seed, akp, akb, edp, edb) != NX_UAS_OK { sdg_w("KEYS FAIL\n" as *u8); sys_exit(1) }
81 let realm: *u8 = "nishi_webdev_adm" as *u8
82 let realm_n: i64 = sdg_len(realm)
83 let ctx: *NxAuthContext = sys_mmap(256) as *NxAuthContext
84 if nx_auth_context_init(ctx, realm, realm_n, realm, realm_n, store_path as i64, oprf_seed, edp, edb, 900, 8192, 1, 1, 5, 1) != NX_MAUTH_OK { sdg_w("CTX FAIL\n" as *u8); sys_exit(1) }
85 let mn: *u8 = sys_mmap(512)
86 let mn_n: *i64 = sys_mmap(16) as *i64
87 if nx_modern_auth_register(ctx, "elder" as *u8, 5, "correct horse battery staple" as *u8, 28, mn, 512, mn_n) != NX_MAUTH_OK { sdg_w("REGISTER FAIL\n" as *u8); sys_exit(1) }
88
89 let req: *u8 = sys_mmap(16384)
90 let out: *u8 = sys_mmap(STU_OUTCAP)
91 var pass: i64 = 0
92
93 // T1: GET /webdev -> 200 + shell
94 let n1: i64 = sdg_cat(req, 0, "GET /webdev HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
95 let o1: i64 = stu_handle(ctx, req, n1, out)
96 var t1: i64 = 0
97 if sdg_starts(out, o1, "HTTP/1.1 200" as *u8) == 1 { if sdg_contains(out, o1, "id=login" as *u8) == 1 { if sdg_contains(out, o1, "How do you want to build" as *u8) == 1 { t1 = 1 } } }
98 pass = pass + sdg_row("T1 GET /webdev -> 200 + SPA shell\x00" as *u8, t1)
99
100 // T2: POST /webdev/login (correct) -> 200 + token
101 let n2: i64 = sdg_cat(req, 0, "POST /webdev/login HTTP/1.1\r\nHost: x\r\n\r\nhandle=elder&passphrase=correct+horse+battery+staple" as *u8)
102 let o2: i64 = stu_handle(ctx, req, n2, out)
103 let tokbuf: *u8 = sys_mmap(256)
104 var tok_n: i64 = 0
105 var t2: i64 = 0
106 if sdg_starts(out, o2, "HTTP/1.1 200" as *u8) == 1 { tok_n = sdg_extract_token(out, o2, tokbuf); if tok_n > 0 { t2 = 1 } }
107 pass = pass + sdg_row("T2 POST /webdev/login ok -> 200 + token\x00" as *u8, t2)
108
109 // T3: POST /webdev/build WITH token, tier|guided -> 200 + governed guided page
110 var n3: i64 = sdg_cat(req, 0, "POST /webdev/build HTTP/1.1\r\nHost: x\r\nX-Nishi-Session: " as *u8)
111 n3 = sdg_cat_n(req, n3, tokbuf, tok_n)
112 n3 = sdg_cat(req, n3, "\r\n\r\ntier|guided\nbrand|WD Brand\ncta|Go\ncta_href|#g\nheadline|WD Headline\nsub|s\nsearch|/s\ncard_title|A\ncard_body|b\nstep1|1\nstep2|2\ntrust|T\nfooter|F\n" as *u8)
113 let o3: i64 = stu_handle(ctx, req, n3, out)
114 var t3: i64 = 0
115 if sdg_starts(out, o3, "HTTP/1.1 200" as *u8) == 1 { if sdg_contains(out, o3, "WD Brand" as *u8) == 1 { if sdg_contains(out, o3, "width=device-width" as *u8) == 1 { t3 = 1 } } }
116 pass = pass + sdg_row("T3 POST /webdev/build WITH token (guided) -> 200 + governed page\x00" as *u8, t3)
117
118 // T4: POST /webdev/build NO token -> 401
119 let n4: i64 = sdg_cat(req, 0, "POST /webdev/build HTTP/1.1\r\nHost: x\r\n\r\ntier|guided\nbrand|x\n" as *u8)
120 let o4: i64 = stu_handle(ctx, req, n4, out)
121 var t4: i64 = 0
122 if sdg_starts(out, o4, "HTTP/1.1 401" as *u8) == 1 { t4 = 1 }
123 pass = pass + sdg_row("T4 POST /webdev/build NO token -> 401 (default-deny)\x00" as *u8, t4)
124
125 // T5: POST /webdev/login WRONG pw -> 401
126 let n5: i64 = sdg_cat(req, 0, "POST /webdev/login HTTP/1.1\r\nHost: x\r\n\r\nhandle=elder&passphrase=wrong+passphrase" as *u8)
127 let o5: i64 = stu_handle(ctx, req, n5, out)
128 var t5: i64 = 0
129 if sdg_starts(out, o5, "HTTP/1.1 401" as *u8) == 1 { t5 = 1 }
130 pass = pass + sdg_row("T5 POST /webdev/login WRONG pw -> 401\x00" as *u8, t5)
131
132 // T6: POST /webdev/build BAD token -> 401
133 let n6: i64 = sdg_cat(req, 0, "POST /webdev/build HTTP/1.1\r\nHost: x\r\nX-Nishi-Session: AAAAAAAA\r\n\r\ntier|guided\nbrand|x\n" as *u8)
134 let o6: i64 = stu_handle(ctx, req, n6, out)
135 var t6: i64 = 0
136 if sdg_starts(out, o6, "HTTP/1.1 401" as *u8) == 1 { t6 = 1 }
137 pass = pass + sdg_row("T6 POST /webdev/build BAD token -> 401 (forged rejected)\x00" as *u8, t6)
138
139 // T7: GET /webdev/guided -> 200 + guided surface
140 let n7: i64 = sdg_cat(req, 0, "GET /webdev/guided HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
141 let o7: i64 = stu_handle(ctx, req, n7, out)
142 var t7: i64 = 0
143 if sdg_starts(out, o7, "HTTP/1.1 200" as *u8) == 1 { if sdg_contains(out, o7, "id=\"brand\"" as *u8) == 1 { t7 = 1 } }
144 pass = pass + sdg_row("T7 GET /webdev/guided -> 200 + guided surface\x00" as *u8, t7)
145
146 // T8: POST /webdev/build WITH token, tier|freeform -> 200 + governed canvas
147 var n8: i64 = sdg_cat(req, 0, "POST /webdev/build HTTP/1.1\r\nHost: x\r\nX-Nishi-Session: " as *u8)
148 n8 = sdg_cat_n(req, n8, tokbuf, tok_n)
149 n8 = sdg_cat(req, n8, "\r\n\r\ntier|freeform\ntitle|WD\nel|heading|30|40|400|WD Canvas|\n" as *u8)
150 let o8: i64 = stu_handle(ctx, req, n8, out)
151 var t8: i64 = 0
152 if sdg_starts(out, o8, "HTTP/1.1 200" as *u8) == 1 { if sdg_contains(out, o8, "WD Canvas" as *u8) == 1 { if sdg_contains(out, o8, "left:30px;top:40px;width:400px" as *u8) == 1 { t8 = 1 } } }
153 pass = pass + sdg_row("T8 POST /webdev/build WITH token (freeform) -> 200 + governed canvas\x00" as *u8, t8)
154
155 if pass == 8 {
156 let line: *u8 = "CMSGATE row=nx_studio_daemon webdev-opaque-modern-auth rows=8 pass=8 verdict=PASS\n" as *u8
157 let gf: i64 = sys_openat_append("knowledge/status/cms_gate.log" as *u8, 0x1a4)
158 if gf >= 0 { sys_write(gf, line, sdg_len(line)); sys_close(gf) }
159 sdg_w("STUDIO-DAEMON GATE GREEN 8/8 (OPAQUE no-cookie login -> token -> gated build -> deny, sovereign in-process)\n" as *u8)
160 sys_exit(0)
161 }
162 sdg_w("STUDIO-DAEMON GATE RED\n" as *u8)
163 sys_exit(1)
164 return 1
165}