code wiki / _hdl_build / nx_opaque_login_smoke.nx

nx_opaque_login_smoke.nx source

↩ module page · 108 lines · 6121 B

1// nx_opaque_login_smoke.nx -- R2 smoke: fork the OPAQUE login daemon, drive it as a REAL HTTP client over a 2// socket (POST /register -> POST /login -> GET /whoami[valid] -> GET /whoami[bad token]), proving the 3// no-cookie OPAQUE login works end-to-end over the wire. Requires /tmp/nx_opaque_login_daemon.sov.elf built 4// in the same WSL session (the WOMB emits there). exit 0 = pass, N = assertion N failed. 5import "nx_syscalls.nx" 6import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 7import "nx_assert.nx" 8const SMK_MAGIC_32768: i64 = 32768 9const SMK_MAGIC_2048: i64 = 2048 10const SMK_MAGIC_32767: i64 = 32767 11 12const SMK_PORT: i64 = 18099 13const DAEMON_ELF: *u8 = "/tmp/nx_opaque_login_daemon.sov.elf" as *u8 14 15func smk_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 16func smk_find(buf: *u8, n: i64, needle: *u8, nl: i64) -> i64 { 17 if nl==0 { return 0 } 18 var i: i64=0 19 while i+nl<=n { var j: i64=0; var ok: i64=1; while j<nl { if buf[i+j]!=needle[j]{ok=0;j=nl} else {j=j+1} } if ok==1 {return i} i=i+1 } 20 return 0-1 21} 22func smk_trunc(path: *u8) -> i64 { let fd: i64=sys_openat_wr(path, 0x1a4); if fd>=0 { sys_close(fd) } return 0 } 23 24// connect 127.0.0.1:SMK_PORT, send req[0..reqn], read response into resp -> resp length (or <0). 25func smk_http(req: *u8, reqn: i64, resp: *u8, cap: i64) -> i64 { 26 let fd: i64 = sys_socket(2, 1, 0); if fd < 0 { return 0-1 } 27 sys_set_socket_timeout(fd, 5) 28 let a: *u8 = sys_mmap(16) 29 a[0]=2 as u8; a[1]=0 as u8; a[2]=((SMK_PORT>>8)&0xff) as u8; a[3]=(SMK_PORT&0xff) as u8 30 a[4]=127 as u8; a[5]=0 as u8; a[6]=0 as u8; a[7]=1 as u8 31 var zi: i64=8; while zi<16 { a[zi]=0 as u8; zi=zi+1 } 32 if nx_connect_bounded(fd, a, 16, NX_CONN_DEFAULT_MS) != 0 { sys_close(fd); return 0-2 } 33 sys_write(fd, req, reqn) 34 var off: i64=0; var go: i64=1 35 while go==1 { let r: i64=sys_read(fd, ((resp as i64)+off) as *u8, cap-off); if r<=0 {go=0} else { off=off+r; if off>=cap {go=0} } } 36 sys_close(fd); return off 37} 38// build a POST with form body; returns request length into reqbuf. 39func smk_post(reqbuf: *u8, path: *u8, body: *u8) -> i64 { 40 let bl: i64 = smk_slen(body) 41 var o: i64=0 42 let p1: *u8="POST " as *u8; var i: i64=0; while p1[i]!=(0 as u8){reqbuf[o]=p1[i];o=o+1;i=i+1} 43 i=0; while path[i]!=(0 as u8){reqbuf[o]=path[i];o=o+1;i=i+1} 44 let p2: *u8=" HTTP/1.1\r\nHost: x\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: " as *u8; i=0; while p2[i]!=(0 as u8){reqbuf[o]=p2[i];o=o+1;i=i+1} 45 let t: *u8=sys_mmap(28); var m: i64=bl; var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var q: i64=k-1; while q>=0{reqbuf[o]=t[q];o=o+1;q=q-1} 46 let p3: *u8="\r\nConnection: close\r\n\r\n" as *u8; i=0; while p3[i]!=(0 as u8){reqbuf[o]=p3[i];o=o+1;i=i+1} 47 i=0; while body[i]!=(0 as u8){reqbuf[o]=body[i];o=o+1;i=i+1} 48 return o 49} 50 51func main() -> i64 { 52 smk_trunc("/tmp/nx_olgd_keys.log" as *u8) 53 smk_trunc("/tmp/nx_olgd_store.log" as *u8) 54 55 let pid: i64 = sys_fork() 56 if pid == 0 { 57 let argv: *i64 = sys_mmap(64) as *i64 58 argv[0]=DAEMON_ELF as i64; argv[1]="18099" as *u8 as i64; argv[2]="/tmp/nx_olgd_keys.log" as *u8 as i64 59 argv[3]="/tmp/nx_olgd_store.log" as *u8 as i64; argv[4]="14" as *u8 as i64; argv[5]="8192" as *u8 as i64; argv[6]=0 60 let envp: *i64 = sys_mmap(16) as *i64; envp[0]="PATH=/usr/bin:/bin" as *u8 as i64; envp[1]=0 61 sys_execve(DAEMON_ELF, argv, envp) 62 sys_exit(127) 63 } 64 sys_sleep_ms(500) // let the daemon bind + init the auth context 65 66 let resp: *u8 = sys_mmap(SMK_MAGIC_32768) 67 let req: *u8 = sys_mmap(SMK_MAGIC_2048) 68 69 // 1. register 70 let rqn: i64 = smk_post(req, "/register" as *u8, "handle=smoke&pw=testpass123" as *u8) 71 let r1: i64 = smk_http(req, rqn, resp, SMK_MAGIC_32767) 72 nx_puts_err("register resp bytes="); nx_puti_err(r1) 73 if smk_find(resp, r1, "200 OK" as *u8, 6) < 0 { nx_kill(pid,9); return 1 } 74 if smk_find(resp, r1, "mnemonic" as *u8, 8) < 0 { nx_kill(pid,9); return 2 } 75 76 // 2. login -> extract the no-cookie token 77 let lqn: i64 = smk_post(req, "/login" as *u8, "handle=smoke&pw=testpass123" as *u8) 78 let r2: i64 = smk_http(req, lqn, resp, SMK_MAGIC_32767) 79 if smk_find(resp, r2, "200 OK" as *u8, 6) < 0 { nx_kill(pid,9); return 3 } 80 let tp: i64 = smk_find(resp, r2, "\"token\":\"" as *u8, 9) 81 if tp < 0 { nx_kill(pid,9); return 4 } 82 let tok: *u8 = sys_mmap(512); var ti: i64=0; var si: i64=tp+9 83 while si < r2 { if resp[si]==(34 as u8) { si=r2 } else { tok[ti]=resp[si]; ti=ti+1; si=si+1 } } 84 tok[ti]=0 as u8 85 nx_puts_err("\nlogin OK; token chars="); nx_puti_err(ti) 86 87 // 3. whoami with the valid token -> 200 + uid 88 let wq: *u8 = sys_mmap(SMK_MAGIC_2048); var o: i64=0 89 let h1: *u8="GET /whoami HTTP/1.1\r\nHost: x\r\nX-Nishi-Session: " as *u8; var i: i64=0; while h1[i]!=(0 as u8){wq[o]=h1[i];o=o+1;i=i+1} 90 i=0; while tok[i]!=(0 as u8){wq[o]=tok[i];o=o+1;i=i+1} 91 let h2: *u8="\r\nConnection: close\r\n\r\n" as *u8; i=0; while h2[i]!=(0 as u8){wq[o]=h2[i];o=o+1;i=i+1} 92 let r3: i64 = smk_http(wq, o, resp, SMK_MAGIC_32767) 93 if smk_find(resp, r3, "200 OK" as *u8, 6) < 0 { nx_kill(pid,9); return 5 } 94 if smk_find(resp, r3, "uid" as *u8, 3) < 0 { nx_kill(pid,9); return 6 } 95 nx_puts_err("\nwhoami(valid) -> 200 + uid\n" as *u8) 96 97 // 4. whoami with a bad token -> 401 98 let bq: *u8 = sys_mmap(512) 99 let b1: *u8="GET /whoami HTTP/1.1\r\nHost: x\r\nX-Nishi-Session: AAAAAAAAAAAAAAAAAAAAAAAA\r\nConnection: close\r\n\r\n" as *u8 100 var bo: i64=0; i=0; while b1[i]!=(0 as u8){bq[bo]=b1[i];bo=bo+1;i=i+1} 101 let r4: i64 = smk_http(bq, bo, resp, SMK_MAGIC_32767) 102 if smk_find(resp, r4, "401" as *u8, 3) < 0 { nx_kill(pid,9); return 7 } 103 nx_puts_err("whoami(bad token) -> 401 rejected\n" as *u8) 104 105 let st: *i64 = sys_mmap(16) as *i64; nx_kill(pid, 9); sys_wait4(pid, st, 0) 106 nx_puts_err("nx_opaque_login_smoke verdict=GREEN pass=4 (HTTP register/login/whoami-valid/bad-token over the wire)\n" as *u8) 107 return 0 108}