code wiki / _hdl_build / nx_legal_portal_live_gate.nx

nx_legal_portal_live_gate.nx source

↩ module page · 206 lines · 9629 B

1// nx_legal_portal_live_gate.nx -- LIVE LOOPBACK proof for the legal portal. 2// 3// The same fork pattern as nx_email_live_gate: parent = the portal server 4// (sys_accept -> lp_serve_conn over the real router), child = a real HTTP client 5// that connects over 127.0.0.1 and asserts the response BYTES came back over the 6// wire. This lifts the portal from "pure handler proven in-process" to "served 7// correctly over a real socket" -- WITHOUT any production deploy (loopback only, 8// the process exits; pointing a public daemon at it is a separate operator step). 9// 10// conn 1: GET /portal/envelopes -> 200 + "env 9601 status SENT" over the wire 11// conn 2: GET /portal/doc?id=8601 -> 200 + the document body BYTE-EXACT over 12// the socket (binary integrity end-to-end). 13// GREEN iff the child asserts both and exits 0. 14// 15// Evidence -> knowledge/status/legal_portal_live.log 16// license_tier: ORIGINAL 17import "nx_legal_portal.nx" 18import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 19import "nx_doc_envelope.nx" 20import "nx_doc_serve.nx" 21import "nx_doc_annotate.nx" 22import "nx_doc_vault.nx" 23import "nx_doc_seal.nx" 24import "nx_legal_compliance.nx" 25import "nx_syscalls.nx" 26 27const LPL_PORT: i64 = 0x2560 // 9568, loopback 28const LPL_LOG: *u8 = "knowledge/status/legal_portal_live.log" 29 30func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 31func g_addr(out: *u8, port: i64) -> i64 { 32 out[0] = 2 as u8; out[1] = 0 as u8 33 out[2] = ((port >> 8) & 0xff) as u8; out[3] = (port & 0xff) as u8 34 out[4] = 127 as u8; out[5] = 0 as u8; out[6] = 0 as u8; out[7] = 1 as u8 35 var i: i64 = 8 36 while i < 16 { out[i] = 0 as u8; i = i + 1 } 37 return 0 38} 39func g_starts(buf: *u8, n: i64, s: *u8) -> i64 { 40 let sn: i64 = slen(s) 41 if n < sn { return 0 } 42 var i: i64 = 0 43 while i < sn { if buf[i] != s[i] { return 0 } i = i + 1 } 44 return 1 45} 46func g_contains(hay: *u8, n: i64, needle: *u8) -> i64 { 47 let nn: i64 = slen(needle) 48 if nn == 0 { return 1 } 49 var i: i64 = 0 50 while i + nn <= n { 51 var m: i64 = 1 52 var j: i64 = 0 53 while j < nn { if hay[i + j] != needle[j] { m = 0; break } j = j + 1 } 54 if m == 1 { return 1 } 55 i = i + 1 56 } 57 return 0 58} 59func g_read_all(fd: i64, buf: *u8, cap: i64) -> i64 { 60 var n: i64 = 0 61 while n < cap { 62 let r: i64 = sys_read(fd, (buf as i64 + n) as *u8, cap - n) 63 if r <= 0 { return n } 64 n = n + r 65 } 66 return n 67} 68// one client request/response cycle over a fresh connection; returns response len. 69func g_client_once(addr: *u8, reqline: *u8, resp: *u8, rcap: i64) -> i64 { 70 let cfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 71 if cfd < 0 { return 0 - 1 } 72 if nx_connect_bounded(cfd, addr, 16, NX_CONN_DEFAULT_MS) < 0 { sys_close(cfd); return 0 - 1 } 73 let rl: i64 = slen(reqline) 74 var w: i64 = 0 75 while w < rl { 76 let k: i64 = sys_write(cfd, (reqline as i64 + w) as *u8, rl - w) 77 if k <= 0 { sys_close(cfd); return 0 - 1 } 78 w = w + k 79 } 80 let n: i64 = g_read_all(cfd, resp, rcap) 81 sys_close(cfd) 82 return n 83} 84func mk_seal(s: *NxSeal, dt: i64, ewills: i64, signer: *u8, ts: i64, 85 intent: i64, consent: i64, attribution: i64, retainable: i64, 86 witnesses: i64, notarized: i64) -> i64 { 87 s.doc_type = dt; s.e_wills_allowed = ewills 88 s.intent = intent; s.consent = consent; s.attribution = attribution 89 s.retainable = retainable; s.witnesses = witnesses; s.notarized = notarized 90 s.signer_id = signer; s.signer_id_len = slen(signer); s.ts = ts 91 return nx_seal_create(s) 92} 93func lpl_log(green: i64) -> i64 { 94 let fd: i64 = sys_openat_append(LPL_LOG, 420) 95 if fd < 0 { return 0 } 96 sys_write(fd, "LEGALPORTALLIVEGATE authored=organ live=loopback-http " as *u8, slen("LEGALPORTALLIVEGATE authored=organ live=loopback-http " as *u8)) 97 if green == 1 { sys_write(fd, "envelopes_over_wire=PASS doc_byteexact_over_wire=PASS verdict=GREEN\n" as *u8, slen("envelopes_over_wire=PASS doc_byteexact_over_wire=PASS verdict=GREEN\n" as *u8)) } 98 else { sys_write(fd, "verdict=RED\n" as *u8, slen("verdict=RED\n" as *u8)) } 99 sys_close(fd) 100 return 0 101} 102 103func main() -> i64 { 104 // ---- RFC 8032 test-1 keypair ---- 105 let priv: *u8 = sys_mmap(64) 106 priv[0]=0x9d; priv[1]=0x61; priv[2]=0xb1; priv[3]=0x9d; priv[4]=0xef; priv[5]=0xfd; priv[6]=0x5a; priv[7]=0x60 107 priv[8]=0xba; priv[9]=0x84; priv[10]=0x4a; priv[11]=0xf4; priv[12]=0x92; priv[13]=0xec; priv[14]=0x2c; priv[15]=0xc4 108 priv[16]=0x44; priv[17]=0x49; priv[18]=0xc5; priv[19]=0x69; priv[20]=0x7b; priv[21]=0x32; priv[22]=0x69; priv[23]=0x19 109 priv[24]=0x70; priv[25]=0x3b; priv[26]=0xac; priv[27]=0x03; priv[28]=0x1c; priv[29]=0xae; priv[30]=0x7f; priv[31]=0x60 110 let pub: *u8 = sys_mmap(64) 111 pub[0]=0xd7; pub[1]=0x5a; pub[2]=0x98; pub[3]=0x01; pub[4]=0x82; pub[5]=0xb1; pub[6]=0x0a; pub[7]=0xb7 112 pub[8]=0xd5; pub[9]=0x4b; pub[10]=0xfe; pub[11]=0xd3; pub[12]=0xc9; pub[13]=0x64; pub[14]=0x07; pub[15]=0x3a 113 pub[16]=0x0e; pub[17]=0xe1; pub[18]=0x72; pub[19]=0xf3; pub[20]=0xda; pub[21]=0xa6; pub[22]=0x23; pub[23]=0x25 114 pub[24]=0xaf; pub[25]=0x02; pub[26]=0x1a; pub[27]=0x68; pub[28]=0xf7; pub[29]=0x07; pub[30]=0x51; pub[31]=0x1a 115 let dh: *u8 = sys_mmap(64) 116 var di: i64 = 0 117 while di < 32 { dh[di] = ((di * 7 + 3) & 0xff) as u8; di = di + 1 } 118 let s: *NxSeal = sys_mmap(256) as *NxSeal 119 s.doc_hash = dh; s.doc_hash_len = 32; s.priv = priv; s.canon = sys_mmap(512); s.sig = sys_mmap(128) 120 121 // ---- one tenant's stores: a SENT 1-of-2-signed contract + a vault doc ---- 122 let ecap: i64 = 8 123 let rcap: i64 = 16 124 let ncap: i64 = 8 125 let vcap: i64 = 8 126 let eflat: *i64 = sys_mmap(ecap * EF_STRIDE * 8) as *i64 127 let rflat: *i64 = sys_mmap(rcap * RF_STRIDE * 8) as *i64 128 let anflat: *i64 = sys_mmap(ncap * NF_STRIDE * 8) as *i64 129 let vflat: *i64 = sys_mmap(vcap * VF_STRIDE * 8) as *i64 130 var ne: i64 = 0 131 var nr: i64 = 0 132 var na: i64 = 0 133 var vc: i64 = 0 134 ne = nx_env_create(eflat, ne, ecap, 9601, 8601, "Services Agreement" as *u8, 1, 1000) 135 nr = nx_env_add_recipient(rflat, nr, rcap, 9601, 101, ROLE_SIGNER, 1) 136 nr = nx_env_add_recipient(rflat, nr, rcap, 9601, 102, ROLE_SIGNER, 2) 137 nx_env_send(eflat, ne, rflat, nr, 9601) 138 let cs: i64 = mk_seal(s, DT_CONTRACT, 1, "client1@andelinwest.com" as *u8, 1100, 1, 1, 1, 1, 0, 0) 139 nx_env_sign(eflat, ne, rflat, nr, 9601, 101, s, pub) 140 vc = nx_vault_add(vflat, vc, vcap, 8601, 5001, 64, 1000) 141 142 let docb: *u8 = sys_mmap(64) 143 docb[0]=37; docb[1]=80; docb[2]=68; docb[3]=70; docb[4]=13; docb[5]=10; docb[6]=0; docb[7]=88 144 let doclen: i64 = 8 145 let eidbuf: *i64 = sys_mmap(32) as *i64 146 eidbuf[0] = 9601 147 148 let ctx: *NxPortalCtx = sys_mmap(256) as *NxPortalCtx 149 ctx.user_level = 1 150 ctx.eflat = eflat; ctx.ne = ne 151 ctx.rflat = rflat; ctx.nr = nr 152 ctx.anflat = anflat; ctx.na = na 153 ctx.vflat = vflat; ctx.vc = vc 154 ctx.doc_id = 8601; ctx.doc_bytes = docb; ctx.doc_len = doclen; ctx.doc_fmt = DF_PDF 155 ctx.env_ids = eidbuf; ctx.env_count = 1 156 157 // ---- bind + listen on loopback ---- 158 let addr: *u8 = sys_mmap(16) 159 g_addr(addr, LPL_PORT) 160 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0) 161 if lfd < 0 { lpl_log(0); sys_exit(91); return 91 } 162 let opt: *u8 = sys_mmap(4); opt[0] = 1 as u8; sys_setsockopt(lfd, 1, 2, opt, 4) // SO_REUSEADDR: re-runnable across TIME_WAIT 163 if sys_bind(lfd, addr, 16) < 0 { lpl_log(0); sys_exit(92); return 92 } 164 if sys_listen(lfd, 8) < 0 { lpl_log(0); sys_exit(93); return 93 } 165 166 let pid: i64 = sys_fork() 167 if pid < 0 { lpl_log(0); sys_exit(94); return 94 } 168 if pid == 0 { 169 // child: the HTTP client 170 var spin: i64 = 0 171 while spin < 400000 { spin = spin + 1 } 172 var cok: i64 = 1 173 let resp1: *u8 = sys_mmap(16384) 174 let n1: i64 = g_client_once(addr, "GET /portal/envelopes HTTP/1.1\r\nHost: x\r\n\r\n" as *u8, resp1, 16384) 175 if g_starts(resp1, n1, "HTTP/1.1 200" as *u8) != 1 { cok = 0 } 176 if g_contains(resp1, n1, "env 9601 status SENT" as *u8) != 1 { cok = 0 } 177 let resp2: *u8 = sys_mmap(16384) 178 let n2: i64 = g_client_once(addr, "GET /portal/doc?id=8601 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8, resp2, 16384) 179 if g_starts(resp2, n2, "HTTP/1.1 200" as *u8) != 1 { cok = 0 } 180 if nx_doc_serve_roundtrip_ok(resp2, n2, docb, doclen) != 1 { cok = 0 } 181 if cok == 1 { sys_exit(0); return 0 } 182 sys_exit(7); return 7 183 } 184 185 // parent: serve the two connections through the real router 186 let s1: i64 = sys_accept(lfd) 187 if s1 >= 0 { lp_serve_conn(ctx, s1); sys_close(s1) } 188 let s2: i64 = sys_accept(lfd) 189 if s2 >= 0 { lp_serve_conn(ctx, s2); sys_close(s2) } 190 191 let status: *i64 = sys_mmap(8) as *i64 192 sys_wait4(pid, status, 0) 193 let child_code: i64 = (status[0] >> 8) & 0xff 194 195 var green: i64 = 0 196 if child_code == 0 { green = 1 } 197 198 sys_write(1, "LEGALPORTALLIVEGATE authored=organ live=loopback-http child_code=" as *u8, slen("LEGALPORTALLIVEGATE authored=organ live=loopback-http child_code=" as *u8)) 199 let nb: *u8 = sys_mmap(8); nb[0] = (48 + (child_code % 10)) as u8; sys_write(1, nb, 1) 200 if green == 1 { sys_write(1, " envelopes+doc_over_wire=PASS verdict=GREEN\n" as *u8, slen(" envelopes+doc_over_wire=PASS verdict=GREEN\n" as *u8)) } 201 else { sys_write(1, " verdict=RED\n" as *u8, slen(" verdict=RED\n" as *u8)) } 202 lpl_log(green) 203 204 if green == 1 { sys_exit(0); return 0 } 205 sys_exit(1); return 1 206}