code wiki / _hdl_build / nx_aw_lsdir.nx

nx_aw_lsdir.nx source

↩ module page · 143 lines · 7704 B

1// nx_aw_lsdir.nx -- CAP-AW-LSDIR: sovereign REMOTE directory lister over SSH sftp (FXP_OPENDIR/READDIR/NAME) -- the 2// remote counterpart of nx_lsdir, no shell on the NAS. Lists a remote dir owned by elderwesto (reachable over SSH 3// even when the home SMB share mounts empty locally) so we can find the auth crown jewels to DR-archive. Read-only. 4// nx_aw_lsdir <remote-dir> (e.g. "." for the home) 5// license_tier: ORIGINAL (vault+SSH+sftp spine from nx_aw_fetch; the READDIR path is new) 6import "nx_syscalls.nx" 7import "nx_ssh_lib.nx" 8const FT_MAGIC_1000000: i64 = 1000000 9const FT_MAGIC_131072: i64 = 131072 10const FT_MAGIC_1048576: i64 = 1048576 11const FT_MAGIC_16384: i64 = 16384 12 13const FT_SECRET_OUT: *u8 = "/tmp/nxsecret.out" as *u8 14const FT_VAULT_NV: *u8 = "/home/elderwesto/.nishi/secrets/nas.nv" as *u8 15 16func ft_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 17func ft_run(path: *u8, a1: *u8, a2: *u8) -> i64 { 18 let pid: i64 = sys_fork() 19 if pid == 0 { 20 let argv: *i64 = sys_mmap(64) as *i64 21 argv[0] = path as i64 22 var ai: i64 = 1 23 if (a1 as i64) != 0 { argv[ai] = a1 as i64; ai = ai + 1 } 24 if (a2 as i64) != 0 { argv[ai] = a2 as i64; ai = ai + 1 } 25 argv[ai] = 0 26 let envp: *i64 = sys_mmap(16) as *i64 27 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 28 sys_execve(path, argv, envp) 29 sys_exit(127) 30 } 31 let st: *i64 = sys_mmap(16) as *i64 32 sys_wait4(pid, st, 0) 33 return (st[0] >> 8) & 0xff 34} 35func ft_unlink(path: *u8) -> i64 { __syscall(263, AT_FDCWD, path, 0, 0, 0, 0) return 0 } 36func ft_napms(ms: i64) -> i64 { let ts: *i64 = sys_mmap(16) as *i64; ts[0] = 0; ts[1] = ms * FT_MAGIC_1000000; __syscall(35, ts as i64, 0, 0, 0, 0, 0); return 0 } 37func sftp_send(st: *SshState, rcid: i64, pkt: *u8, plen: i64) -> i64 { 38 let cd: *u8 = sys_mmap(plen + 32); var c: i64 = 0 39 c = ssh_put_byte(cd, c, 94); c = ssh_put_u32(cd, c, rcid); c = ssh_put_u32(cd, c, plen) 40 ssh_put_bytes(cd, c, pkt, plen); c = c + plen 41 ssh_enc_send(st, cd, c) 42 return 0 43} 44func sftp_reply(st: *SshState, rep: *u8) -> i64 { 45 var guard: i64 = 0 46 while guard < 128 { let rl: i64 = ssh_enc_recv(st, rep); if rl < 0 { return 0 - 1 } if rep[0] == 94 as u8 { return rep[13] as i64 } guard = guard + 1 } 47 return 0 - 2 48} 49func sftp_chan_ok(st: *SshState, rep: *u8) -> i64 { 50 var guard: i64 = 0 51 while guard < 32 { let rl: i64 = ssh_enc_recv(st, rep); if rl < 0 { return 0 - 1 } if rep[0] == 99 as u8 { return 1 } if rep[0] == 100 as u8 { return 0 } guard = guard + 1 } 52 return 0 - 2 53} 54 55func main(argc: i64, argv: *i64) -> i64 { 56 if argc < 2 { ssh_puts("usage: nx_aw_lsdir <remote-dir>\n" as *u8); return 2 } 57 let dirp: *u8 = argv[1] as *u8 58 let dlen: i64 = ft_slen(dirp) 59 60 let pwbox: *i64 = sys_mmap(16) as *i64 61 var pw: *u8 = 0 as *u8; var att: i64 = 0 62 while att < 12 { 63 if ft_run("_offc/nx_machine_key.elf" as *u8, 0 as *u8, 0 as *u8) == 0 { 64 if ft_run("_offc/nx_vault.elf" as *u8, "open" as *u8, FT_VAULT_NV) == 0 { pw = sys_read_file(FT_SECRET_OUT, pwbox); if (pw as i64) != 0 { att = 1000 } } 65 } 66 if att < 1000 { att = att + 1; ft_napms(150) } 67 } 68 if (pw as i64) == 0 { ssh_puts("nx_aw_lsdir: secret derivation FAIL\n" as *u8); return 3 } 69 var pwlen: i64 = pwbox[0] 70 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 } } } 71 72 let st: *SshState = sys_mmap(SSH_STATE_BYTES) as *SshState 73 if ssh_open_session(st, (192 << 24) | (168 << 16) | (8 << 8) | 227) != 0 { ssh_puts("nx_aw_lsdir: SSH FAIL\n" as *u8); ft_unlink(FT_SECRET_OUT); return 7 } 74 if ssh_userauth_password(st, "elderwesto" as *u8, 10, pw, pwlen) != 1 { ssh_puts("nx_aw_lsdir: AUTH FAIL\n" as *u8); sys_close(st.fd); ft_unlink(FT_SECRET_OUT); return 8 } 75 ft_unlink(FT_SECRET_OUT) 76 77 let rep: *u8 = sys_mmap(FT_MAGIC_131072) 78 let co: *u8 = sys_mmap(64); var c: i64 = 0 79 c = ssh_put_byte(co, c, 90); c = ssh_put_str(co, c, "session" as *u8, 7) 80 c = ssh_put_u32(co, c, 0); c = ssh_put_u32(co, c, FT_MAGIC_1048576); c = ssh_put_u32(co, c, FT_MAGIC_16384) 81 ssh_enc_send(st, co, c) 82 var rcid: i64 = 0 - 1; var guard: i64 = 0 83 while rcid < 0 { if guard > 16 { ssh_puts("nx_aw_lsdir: chan FAIL\n" as *u8); sys_close(st.fd); return 9 } let rl: i64 = ssh_enc_recv(st, rep); if rl < 0 { sys_close(st.fd); return 9 } if rep[0] == 91 as u8 { rcid = ssh_u32be(rep, 5) } if rep[0] == 92 as u8 { sys_close(st.fd); return 9 } guard = guard + 1 } 84 85 let sr: *u8 = sys_mmap(64); var q: i64 = 0 86 q = ssh_put_byte(sr, q, 98); q = ssh_put_u32(sr, q, rcid); q = ssh_put_str(sr, q, "subsystem" as *u8, 9) 87 q = ssh_put_byte(sr, q, 1); q = ssh_put_str(sr, q, "sftp" as *u8, 4) 88 ssh_enc_send(st, sr, q) 89 if sftp_chan_ok(st, rep) != 1 { ssh_puts("nx_aw_lsdir: sftp REFUSED\n" as *u8); sys_close(st.fd); return 10 } 90 91 let initp: *u8 = sys_mmap(32); var ip: i64 = 0 92 ip = ssh_put_u32(initp, ip, 5); ip = ssh_put_byte(initp, ip, 1); ip = ssh_put_u32(initp, ip, 3) 93 sftp_send(st, rcid, initp, ip) 94 if sftp_reply(st, rep) != 2 { ssh_puts("nx_aw_lsdir: no VERSION\n" as *u8); sys_close(st.fd); return 11 } 95 96 // ---- FXP_OPENDIR ---- 97 let ob: *u8 = sys_mmap(dlen + 64); var b: i64 = 0 98 b = ssh_put_byte(ob, b, 11); b = ssh_put_u32(ob, b, 1); b = ssh_put_str(ob, b, dirp, dlen) 99 let op: *u8 = sys_mmap(dlen + 80); var on: i64 = 0 100 on = ssh_put_u32(op, on, b); ssh_put_bytes(op, on, ob, b); on = on + b 101 sftp_send(st, rcid, op, on) 102 let ot: i64 = sftp_reply(st, rep) 103 if ot != 102 { ssh_puts("nx_aw_lsdir: OPENDIR failed type=" as *u8); if ot==101 { ssh_puts("STATUS fx=" as *u8) } sys_close(st.fd); return 12 } 104 let hlen: i64 = ssh_u32be(rep, 18) 105 let handle: *u8 = sys_mmap(hlen + 8) 106 ssh_put_bytes(handle, 0, (rep + 22) as *u8, hlen) 107 108 ssh_puts("== remote " as *u8); ssh_puts(dirp); ssh_puts(" ==\n" as *u8) 109 // ---- FXP_READDIR loop ---- 110 var rid: i64 = 2; var go: i64 = 1 111 while go == 1 { 112 let rb: *u8 = sys_mmap(hlen + 64); var r: i64 = 0 113 r = ssh_put_byte(rb, r, 12); r = ssh_put_u32(rb, r, rid); r = ssh_put_str(rb, r, handle, hlen) 114 let rp: *u8 = sys_mmap(hlen + 80); var rn: i64 = 0 115 rn = ssh_put_u32(rp, rn, r); ssh_put_bytes(rp, rn, rb, r); rn = rn + r 116 sftp_send(st, rcid, rp, rn) 117 let rt: i64 = sftp_reply(st, rep) 118 if rt == 104 { 119 let count: i64 = ssh_u32be(rep, 18) 120 var p: i64 = 22; var i: i64 = 0 121 while i < count { 122 let fnlen: i64 = ssh_u32be(rep, p); p = p + 4 123 ssh_puts(" " as *u8); sys_write(1, (rep + p) as *u8, fnlen); sys_write(1, "\n" as *u8, 1); p = p + fnlen 124 let lnlen: i64 = ssh_u32be(rep, p); p = p + 4 + lnlen // skip longname 125 let flags: i64 = ssh_u32be(rep, p); p = p + 4 // skip attrs 126 if (flags & 0x01) != 0 { p = p + 8 } 127 if (flags & 0x02) != 0 { p = p + 8 } 128 if (flags & 0x04) != 0 { p = p + 4 } 129 if (flags & 0x08) != 0 { p = p + 8 } 130 i = i + 1 131 } 132 rid = rid + 1 133 } else { go = 0 } 134 } 135 136 let cb: *u8 = sys_mmap(hlen + 32); var cbn: i64 = 0 137 cbn = ssh_put_byte(cb, cbn, 4); cbn = ssh_put_u32(cb, cbn, rid); cbn = ssh_put_str(cb, cbn, handle, hlen) 138 let cp: *u8 = sys_mmap(hlen + 48); var cpn: i64 = 0 139 cpn = ssh_put_u32(cp, cpn, cbn); ssh_put_bytes(cp, cpn, cb, cbn); cpn = cpn + cbn 140 sftp_send(st, rcid, cp, cpn); sftp_reply(st, rep) 141 sys_close(st.fd) 142 return 0 143}