code wiki / _hdl_build / nx_home_auth_gate.nx

nx_home_auth_gate.nx source

↩ module page · 88 lines · 7222 B

1// nx_home_auth_gate.nx -- SOVEREIGN proof of nx_home H4 operator-only auth. Writes a token file, forks 2// /tmp/nx_home.sov.elf with auth enabled, and proves over a loopback socket (no python/shell) that the control 3// plane is GATED: 4// R1 no Authorization -> 401 unauthorized R2 wrong token -> 401 5// R3 correct token -> 200 + devices R4 correct token POST cmd -> applied (on:1) 6// R5 no-auth POST cmd -> 401 (control gated) R6 no-auth shutdown -> 401 (server not killable w/o auth) 7// then an AUTHED shutdown tears it down. GREEN iff 6/6. Requires /tmp/nx_home.sov.elf. 8// knowledge/status/nx_home_auth_gate.log. license_tier: ORIGINAL 9import "nx_syscalls.nx" 10import "nx_connect.nx" // bounded connect: a raw sys_connect hangs ~127s on a black-holed host 11import "nx_gate_emit_lib.nx" 12 13func g_num(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8=sys_mmap(28); 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 i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(1,bb,k); return 0 } 14func g_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 15func g_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; let t: *u8=sys_mmap(28); 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 i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 16func g_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 17func g_contains(hay: *u8, n: i64, needle: *u8) -> i64 { 18 let nl: i64=g_strlen(needle); if nl==0 { return 0 } 19 var i: i64=0 20 while i+nl<=n { var j: i64=0; var hit: i64=1; while j<nl { if hay[i+j]!=needle[j] { hit=0; j=nl } else { j=j+1 } } if hit==1 { return 1 } i=i+1 } 21 return 0 22} 23func g_sockaddr(buf: *u8, port: i64, a: i64, b: i64, c: i64, d: i64) -> i64 { 24 var i: i64=0; while i<16 { buf[i]=0 as u8; i=i+1 } 25 buf[0]=2 as u8; buf[2]=((port>>8)&0xff) as u8; buf[3]=(port&0xff) as u8 26 buf[4]=a as u8; buf[5]=b as u8; buf[6]=c as u8; buf[7]=d as u8; return 0 27} 28func http_req(port: i64, req: *u8, reqlen: i64, resp: *u8, cap: i64) -> i64 { 29 let dest: *u8=sys_mmap(16); g_sockaddr(dest, port, 127, 0, 0, 1) 30 var fd: i64=0; var connected: i64=0; var tries: i64=0 31 while connected==0 { 32 fd=sys_socket(AF_INET, SOCK_STREAM, 0); if fd<0 { return 0-1 } 33 if nx_connect_bounded(fd, dest, 16, NX_CONN_DEFAULT_MS)==0 { connected=1 } else { sys_close(fd); tries=tries+1; if tries>40000 { return 0-2 } } 34 } 35 sys_write(fd, req, reqlen) 36 var total: i64=0; var r: i64=sys_read(fd, resp, cap) 37 while r>0 { total=total+r; if total>=cap { r=0 } else { r=sys_read(fd, ((resp as i64)+total) as *u8, cap-total) } } 38 sys_close(fd); return total 39} 40func write_file(path: *u8, data: *u8, len: i64) -> i64 { let fd: i64=sys_openat_wr(path, 0x1a4); if fd<0 { return 0-1 } sys_write(fd, data, len); sys_close(fd); return len } 41 42func main() -> i64 { 43 g_puts("=== NX_HOME AUTH GATE: operator-only control plane (H4), Nishi loopback ===\n" as *u8) 44 let TOK: *u8="/tmp/nx_home_token.txt" as *u8 45 write_file(TOK, "s3cr3t-nishi-home" as *u8, 17) 46 let NOAUTH_STATE: *u8="GET /home/state HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n" as *u8 47 let WRONG_STATE: *u8="GET /home/state HTTP/1.1\r\nHost: 127.0.0.1\r\nAuthorization: Bearer wrongtoken\r\nConnection: close\r\n\r\n" as *u8 48 let AUTH_STATE: *u8="GET /home/state HTTP/1.1\r\nHost: 127.0.0.1\r\nAuthorization: Bearer s3cr3t-nishi-home\r\nConnection: close\r\n\r\n" as *u8 49 let AUTH_CMD: *u8="POST /home/cmd?id=living_room&on=1&bri=70 HTTP/1.1\r\nHost: 127.0.0.1\r\nAuthorization: Bearer s3cr3t-nishi-home\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" as *u8 50 let NOAUTH_CMD: *u8="POST /home/cmd?id=living_room&on=1 HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" as *u8 51 let NOAUTH_SD: *u8="POST /home/shutdown HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" as *u8 52 let AUTH_SD: *u8="POST /home/shutdown HTTP/1.1\r\nHost: 127.0.0.1\r\nAuthorization: Bearer s3cr3t-nishi-home\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" as *u8 53 54 let pid: i64=sys_fork() 55 if pid==0 { 56 let o: i64=sys_openat_wr("/tmp/nx_home_auth_srv.log" as *u8, 0x1a4); if o>=0 { sys_dup3(o,1,0); sys_dup3(o,2,0) } 57 let argv: *i64=sys_mmap(8*8) as *i64 58 argv[0]="/tmp/nx_home.sov.elf" as *u8 as i64; argv[1]="8202" as *u8 as i64 59 argv[2]="/tmp/home_none.tsv" as *u8 as i64; argv[3]=TOK as i64; argv[4]=0 // missing registry -> embedded; token -> auth on 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("/tmp/nx_home.sov.elf" as *u8, argv, envp); sys_exit(127) 62 } 63 64 let r1: *u8=sys_mmap(65536); let n1: i64=http_req(8202, NOAUTH_STATE, g_strlen(NOAUTH_STATE), r1, 65536) 65 let r2: *u8=sys_mmap(65536); let n2: i64=http_req(8202, WRONG_STATE, g_strlen(WRONG_STATE), r2, 65536) 66 let r3: *u8=sys_mmap(65536); let n3: i64=http_req(8202, AUTH_STATE, g_strlen(AUTH_STATE), r3, 65536) 67 let r4: *u8=sys_mmap(65536); let n4: i64=http_req(8202, AUTH_CMD, g_strlen(AUTH_CMD), r4, 65536) 68 let r5: *u8=sys_mmap(65536); let n5: i64=http_req(8202, NOAUTH_CMD, g_strlen(NOAUTH_CMD), r5, 65536) 69 let r6: *u8=sys_mmap(65536); let n6: i64=http_req(8202, NOAUTH_SD, g_strlen(NOAUTH_SD), r6, 65536) 70 let r7: *u8=sys_mmap(4096); http_req(8202, AUTH_SD, g_strlen(AUTH_SD), r7, 4096) 71 let st: *i64=sys_mmap(16) as *i64; sys_wait4(pid, st, 0) 72 73 var pass: i64=0; let rows: i64=6 74 var u1: i64=0; if g_contains(r1,n1,"401" as *u8)==1 { if g_contains(r1,n1,"unauthorized" as *u8)==1 { u1=1 } } 75 pass=pass+g_check(" R1 no-auth GET state -> 401 unauthorized" as *u8, u1) 76 pass=pass+g_check(" R2 wrong-token GET state -> 401" as *u8, g_contains(r2,n2,"401" as *u8)) 77 var ok3: i64=0; if g_contains(r3,n3,"200" as *u8)==1 { if g_contains(r3,n3,"living_room" as *u8)==1 { ok3=1 } } 78 pass=pass+g_check(" R3 correct-token GET state -> 200 + devices" as *u8, ok3) 79 pass=pass+g_check(" R4 correct-token POST cmd -> applied (on:1)" as *u8, g_contains(r4,n4,"\"on\":1" as *u8)) 80 pass=pass+g_check(" R5 no-auth POST cmd -> 401 (control gated)" as *u8, g_contains(r5,n5,"401" as *u8)) 81 pass=pass+g_check(" R6 no-auth shutdown -> 401 (not killable w/o auth)" as *u8, g_contains(r6,n6,"401" as *u8)) 82 83 g_puts("----\nNX-HOME-AUTH rows=" as *u8); g_num(rows); g_puts(" pass=" as *u8); g_num(pass); g_puts("\n" as *u8) 84 let lg: i64=sys_openat_append("knowledge/status/nx_home_auth_gate.log" as *u8, 0x1a4) 85 if lg>=0 { g_w(lg, "NX-HOME-AUTH rows=" as *u8); g_wn(lg, rows); g_w(lg, " pass=" as *u8); g_wn(lg, pass); if pass==rows { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) } sys_close(lg) } 86 if pass==rows { g_puts("NX-HOME-AUTH GREEN (operator-only control plane proven)\n" as *u8); sys_exit(0); return 0 } 87 g_puts("NX-HOME-AUTH RED\n" as *u8); sys_exit(1); return 1 88}