code wiki / _hdl_build / nx_aw_routerfix.nx

nx_aw_routerfix.nx source

↩ module page · 70 lines · 3928 B

1// nx_aw_routerfix.nx -- SOVEREIGN router (GL.iNet/OpenWrt 192.168.8.1) admin for the andelinwest DNS 2// revert. No shells, no printed secret: retrieves router_password from the sovereign vault 3// (~/.nishi/nx_vault get vault.key vault.nxv router_password -> captured to a temp fd, in-memory only), 4// SSHes the router as root via nx_ssh_lib, and runs the command read from a file (so read-only query vs 5// the actual uci set is driven without rebuilding). ssh_exec streams remote stdout to fd 1. 6// license_tier: ORIGINAL (spine reused from nx_aw_nasfix) 7import "nx_syscalls.nx" 8import "nx_ssh_lib.nx" 9 10const RF_CMD_PATH: *u8 = "/mnt/c/Users/elder/AppData/Local/Temp/routercmd.txt" as *u8 11const RF_PW_OUT: *u8 = "/tmp/nxrouter.out" as *u8 12const RF_VAULT_BIN: *u8 = "/home/elderwesto/.nishi/nx_vault" as *u8 13const RF_VAULT_KEY: *u8 = "/home/elderwesto/.nishi/vault.key" as *u8 14const RF_VAULT_NXV: *u8 = "/home/elderwesto/.nishi/vault.nxv" as *u8 15 16// fork/exec a helper with stdout redirected to outfd; parent waits; returns child WEXITSTATUS. 17func rf_run_capture(path: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, outfd: i64) -> i64 { 18 let pid: i64 = sys_fork() 19 if pid == 0 { 20 if outfd >= 0 { sys_dup3(outfd, 1, 0) } 21 let argv: *i64 = sys_mmap(64) as *i64 22 argv[0] = path as i64 23 var ai: i64 = 1 24 if (a1 as i64) != 0 { argv[ai] = a1 as i64; ai = ai + 1 } 25 if (a2 as i64) != 0 { argv[ai] = a2 as i64; ai = ai + 1 } 26 if (a3 as i64) != 0 { argv[ai] = a3 as i64; ai = ai + 1 } 27 if (a4 as i64) != 0 { argv[ai] = a4 as i64; ai = ai + 1 } 28 argv[ai] = 0 29 let envp: *i64 = sys_mmap(16) as *i64 30 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 31 sys_execve(path, argv, envp) 32 sys_exit(127) 33 } 34 let st: *i64 = sys_mmap(16) as *i64 35 sys_wait4(pid, st, 0) 36 return (st[0] >> 8) & 0xff 37} 38func rf_unlink(path: *u8) -> i64 { __syscall(263, AT_FDCWD, path, 0, 0, 0, 0) return 0 } 39 40func main() -> i64 { 41 // ---- retrieve router_password from the sovereign vault (stdout -> temp file, in-memory only) ---- 42 let ofd: i64 = sys_openat_wr(RF_PW_OUT, 0x180) // 0600 43 if ofd < 0 { ssh_puts("routerfix: cannot open pw temp\n" as *u8); return 1 } 44 let grc: i64 = rf_run_capture(RF_VAULT_BIN, "get" as *u8, RF_VAULT_KEY, RF_VAULT_NXV, "router_password" as *u8, ofd) 45 sys_close(ofd) 46 if grc != 0 { ssh_puts("routerfix: vault get router_password FAILED\n" as *u8); rf_unlink(RF_PW_OUT); return 2 } 47 let pwbox: *i64 = sys_mmap(16) as *i64 48 let pw: *u8 = sys_read_file(RF_PW_OUT, pwbox) 49 if (pw as i64) == 0 { ssh_puts("routerfix: cannot read pw\n" as *u8); return 3 } 50 var pwlen: i64 = pwbox[0] 51 while pwlen > 0 { if pw[pwlen-1] == 10 as u8 { pwlen = pwlen - 1 } else { if pw[pwlen-1] == 13 as u8 { pwlen = pwlen - 1 } else { break } } } 52 rf_unlink(RF_PW_OUT) 53 if pwlen <= 0 { ssh_puts("routerfix: empty router password\n" as *u8); return 3 } 54 55 // ---- the command to run on the router (file-driven: read-only query vs uci set) ---- 56 let cbox: *i64 = sys_mmap(16) as *i64 57 let cmd: *u8 = sys_read_file(RF_CMD_PATH, cbox) 58 if (cmd as i64) == 0 { ssh_puts("routerfix: no command file\n" as *u8); return 4 } 59 var clen: i64 = cbox[0] 60 while clen > 0 { if cmd[clen-1] == 10 as u8 { clen = clen - 1 } else { break } } 61 62 // ---- sovereign SSH to the router 192.168.8.1 as root ---- 63 let st: *SshState = sys_mmap(SSH_STATE_BYTES) as *SshState 64 if ssh_open_session(st, (192 << 24) | (168 << 16) | (8 << 8) | 1) != 0 { ssh_puts("routerfix: SSH session FAILED (router unreachable :22)\n" as *u8); return 5 } 65 if ssh_userauth_password(st, "root" as *u8, 4, pw, pwlen) != 1 { ssh_puts("routerfix: SSH auth FAILED\n" as *u8); sys_close(st.fd); return 6 } 66 ssh_puts("routerfix: [auth ok] running on router:\n" as *u8) 67 ssh_exec(st, cmd, clen) 68 sys_close(st.fd) 69 return 0 70}