code wiki / _hdl_build / nx_porkbun_dns_show.nx

nx_porkbun_dns_show.nx source

↩ module page · 125 lines · 6573 B

1// nx_porkbun_dns_show.nx -- print the AUTHORITATIVE published DNS records for a domain, straight from 2// the Porkbun API over the sovereign TLS-1.2 client (uninterceptable HTTPS to api.porkbun.com). This is 3// the ground truth for "what does the public actually resolve" -- immune to the LAN's :53 split-horizon. 4// Shows every A/CNAME record's name+content so we can see if the apex points at a PRIVATE ip (broken for 5// external users) or the real WAN ip, and where the capability subdomains point. 6// usage: nx_porkbun_dns_show <domain> (run `nx_secret_cli get porkbun` first -> /tmp/nxsecret.out) 7// license_tier: ORIGINAL 8import "nx_acme_porkbun.nx" 9const K_MAGIC_1000000000: i64 = 1000000000 10const K_MAGIC_4194304: i64 = 4194304 11const K_MAGIC_131072: i64 = 131072 12 13func pds_pp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 14func pds_pe(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(2,s,n); return 0 } 15func pds_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 16 17// scan the JSON body for "type":"A"/"CNAME" records and print name -> content for each. Porkbun returns 18// a flat array of objects each with "name","type","content". We walk object-by-object on '{'. 19func pds_dump(resp: *u8, n: i64) -> i64 { 20 var shown: i64 = 0 21 var i: i64 = 0 22 while i < n { 23 if (resp[i] as i64) == 123 { // '{' -- start of a record object 24 // find this object's end '}' 25 var j: i64 = i + 1 26 var depth: i64 = 1 27 while j < n { let c: i64 = resp[j] as i64; if c == 123 { depth = depth + 1 } if c == 125 { depth = depth - 1; if depth == 0 { j = n + K_MAGIC_1000000000 } } if j < n { j = j + 1 } } 28 var oend: i64 = j 29 if oend >= K_MAGIC_1000000000 { oend = oend - K_MAGIC_1000000000 } 30 // within [i,oend) find "name":" , "type":" , "content":" 31 let no: *i64 = sys_mmap(8) as *i64; let nl: *i64 = sys_mmap(8) as *i64 32 let to: *i64 = sys_mmap(8) as *i64; let tl: *i64 = sys_mmap(8) as *i64 33 let co: *i64 = sys_mmap(8) as *i64; let cl: *i64 = sys_mmap(8) as *i64 34 let hn: i64 = pds_field(resp, i, oend, "\"name\":\"" as *u8, 8, no, nl) 35 let ht: i64 = pds_field(resp, i, oend, "\"type\":\"" as *u8, 8, to, tl) 36 let hc: i64 = pds_field(resp, i, oend, "\"content\":\"" as *u8, 11, co, cl) 37 if ht == 1 { 38 // only A / CNAME / AAAA rows (skip NS/MX/TXT noise) 39 var keep: i64 = 0 40 if pds_eqlit(resp, to[0], tl[0], "A" as *u8) == 1 { keep = 1 } 41 if pds_eqlit(resp, to[0], tl[0], "CNAME" as *u8) == 1 { keep = 1 } 42 if pds_eqlit(resp, to[0], tl[0], "AAAA" as *u8) == 1 { keep = 1 } 43 if pds_eqlit(resp, to[0], tl[0], "ALIAS" as *u8) == 1 { keep = 1 } 44 if keep == 1 { 45 pds_pp(" " as *u8) 46 if ht == 1 { sys_write(1, ((resp as i64)+to[0]) as *u8, tl[0]) } 47 pds_pp(" " as *u8) 48 if hn == 1 { if nl[0] > 0 { sys_write(1, ((resp as i64)+no[0]) as *u8, nl[0]) } else { pds_pp("(apex)" as *u8) } } else { pds_pp("(apex)" as *u8) } 49 pds_pp(" -> " as *u8) 50 if hc == 1 { sys_write(1, ((resp as i64)+co[0]) as *u8, cl[0]) } 51 pds_pp("\n" as *u8) 52 shown = shown + 1 53 } 54 } 55 i = oend 56 } 57 i = i + 1 58 } 59 return shown 60} 61// find "key" (klen incl. quotes+colon+openquote) in resp[st..en); set off/len of the quoted value. 1/0. 62func pds_field(resp: *u8, st: i64, en: i64, key: *u8, klen: i64, off: *i64, len: *i64) -> i64 { 63 var i: i64 = st 64 while i + klen <= en { 65 var m: i64 = 1; var j: i64 = 0 66 while j < klen { if (resp[i+j] as i64) != (key[j] as i64) { m = 0; j = klen } else { j = j + 1 } } 67 if m == 1 { 68 let vs: i64 = i + klen 69 var e: i64 = vs 70 while e < en { if (resp[e] as i64) == 34 { e = en + K_MAGIC_1000000000 } else { e = e + 1 } } 71 var ve: i64 = e; if ve >= K_MAGIC_1000000000 { ve = ve - K_MAGIC_1000000000 } 72 off[0] = vs; len[0] = ve - vs 73 return 1 74 } 75 i = i + 1 76 } 77 off[0] = 0; len[0] = 0 78 return 0 79} 80func pds_eqlit(resp: *u8, off: i64, len: i64, lit: *u8) -> i64 { 81 let ll: i64 = pds_slen(lit) 82 if len != ll { return 0 } 83 var i: i64 = 0 84 while i < ll { if (resp[off+i] as i64) != (lit[i] as i64) { return 0 } i = i + 1 } 85 return 1 86} 87 88func main(argc: i64, argv: *i64) -> i64 { 89 if argc < 2 { pds_pe("usage: nx_porkbun_dns_show <domain>\n" as *u8); return 2 } 90 let domain: *u8 = argv[1] as *u8 91 let dn: i64 = pds_slen(domain) 92 pds_pp("=== Porkbun AUTHORITATIVE DNS for " as *u8); pds_pp(domain); pds_pp(" (what the public resolves) ===\n" as *u8) 93 94 let lr: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt\x00" as *u8, 300, K_MAGIC_4194304) 95 if lr <= 0 { pds_pe("trust load FAIL\n" as *u8); return 1 } 96 let store: *TrustStore = lr as *TrustStore 97 let now: i64 = sys_now_realtime_sec() 98 99 let raw: *u8 = sys_mmap(512) 100 let rawn: i64 = pk_readline_file("/tmp/nxsecret.out\x00" as *u8, raw, 512) 101 if rawn <= 0 { pds_pe("creds read FAIL -- run `nx_secret_cli get porkbun` first\n" as *u8); return 2 } 102 var base: i64 = 0 103 if rawn >= 3 { if (raw[0] as i64) == 0xef { if (raw[1] as i64) == 0xbb { if (raw[2] as i64) == 0xbf { base = 3 } } } } 104 var nl: i64 = base 105 while nl < rawn { if (raw[nl] as i64) == 0x0a { break }; nl = nl + 1 } 106 let ak: *u8 = (raw + base) as *u8 107 let akn: i64 = nl - base 108 var s2: i64 = nl + 1 109 var nl2: i64 = s2 110 while nl2 < rawn { if (raw[nl2] as i64) == 0x0a { break }; nl2 = nl2 + 1 } 111 let sk: *u8 = (raw + s2) as *u8 112 let skn: i64 = nl2 - s2 113 114 let resp: *u8 = sys_mmap(K_MAGIC_131072) 115 let rn: *i64 = sys_mmap(8) as *i64 116 let rc: i64 = nx_porkbun_retrieve(ak, akn, sk, skn, domain, dn, store, now, resp, K_MAGIC_131072, rn) 117 if rc != NX_PORKBUN_OK { 118 pds_pe("retrieve FAIL rc=" as *u8); let c: *u8 = sys_mmap(8); c[0]=(48+rc) as u8; sys_write(2,c,1); pds_pe("\n--- raw ---\n" as *u8) 119 sys_write(2, resp, rn[0]); pds_pe("\n--- end ---\n" as *u8) 120 return 3 121 } 122 let shown: i64 = pds_dump(resp, rn[0]) 123 if shown == 0 { pds_pp(" (no A/CNAME/ALIAS rows parsed -- raw follows)\n" as *u8); sys_write(1, resp, rn[0]); pds_pp("\n" as *u8) } 124 return 0 125}