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}