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}