nx_porkbun_publish_a.nx source
↩ module page · 60 lines · 3167 B
1// nx_porkbun_publish_a.nx -- publish an A record <sub>.<domain> -> <ip> at Porkbun, sovereignly (over the
2// TLS-1.2 client). REUSE: nx_porkbun_set_a (nx_acme_porkbun.nx) + the trust store + the vault creds discipline.
3// Creds: run `nx_secret_cli get porkbun` first (-> /tmp/nxsecret.out, line1=apikey line2=secretapikey, UTF-8
4// BOM-prefixed). Trust = data/mozilla_certdata.txt (Amazon Root CA 1 chains here). Clock = real
5// (sys_now_realtime_sec; a stale clock fails cert-validity). Reversible: Porkbun dns/delete undoes it.
6// nx_porkbun_publish_a <domain> <sub> <ip> e.g. andelinwest.com admin 75.28.18.94
7// license_tier: ORIGINAL
8import "nx_acme_porkbun.nx"
9const K_MAGIC_4194304: i64 = 4194304
10const K_MAGIC_16384: i64 = 16384
11
12func ppa_pe(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(2,s,n); return 0 }
13func ppa_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 ppa_strlen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
15
16func main(argc: i64, argv: *i64) -> i64 {
17 if argc < 4 { ppa_pe("usage: nx_porkbun_publish_a <domain> <sub> <ip>\n" as *u8); return 2 }
18 let domain: *u8 = argv[1] as *u8
19 let sub: *u8 = argv[2] as *u8
20 let ip: *u8 = argv[3] as *u8
21 let dn: i64 = ppa_strlen(domain)
22 let sub_n: i64 = ppa_strlen(sub)
23 let ip_n: i64 = ppa_strlen(ip)
24
25 let lr: i64 = nx_trust_store_load_from_certdata("data/mozilla_certdata.txt\x00" as *u8, 300, K_MAGIC_4194304)
26 if lr <= 0 { ppa_pe("trust load FAIL (data/mozilla_certdata.txt)\n" as *u8); return 1 }
27 let store: *TrustStore = lr as *TrustStore
28 let now: i64 = sys_now_realtime_sec()
29
30 // creds straight from the vault decrypt output; line1=apikey, line2=secretapikey (strip a leading UTF-8 BOM)
31 let raw: *u8 = sys_mmap(512)
32 let rawn: i64 = pk_readline_file("/tmp/nxsecret.out\x00" as *u8, raw, 512)
33 if rawn <= 0 { ppa_pe("creds read FAIL -- run `nx_secret_cli get porkbun` first\n" as *u8); return 2 }
34 var base: i64 = 0
35 if rawn >= 3 { if (raw[0] as i64) == 0xef { if (raw[1] as i64) == 0xbb { if (raw[2] as i64) == 0xbf { base = 3 } } } }
36 var nl: i64 = base
37 while nl < rawn { if (raw[nl] as i64) == 0x0a { break }; nl = nl + 1 }
38 let ak: *u8 = (raw + base) as *u8
39 let akn: i64 = nl - base
40 var s2: i64 = nl + 1
41 var nl2: i64 = s2
42 while nl2 < rawn { if (raw[nl2] as i64) == 0x0a { break }; nl2 = nl2 + 1 }
43 let sk: *u8 = (raw + s2) as *u8
44 let skn: i64 = nl2 - s2
45 if akn <= 0 { ppa_pe("apikey empty\n" as *u8); return 2 }
46 if skn <= 0 { ppa_pe("secretapikey empty\n" as *u8); return 2 }
47
48 let resp: *u8 = sys_mmap(K_MAGIC_16384)
49 let rn: *i64 = sys_mmap(8) as *i64
50 ppa_pp("publishing A record ...\n" as *u8)
51 let sv: i64 = nx_porkbun_set_a(ak, akn, sk, skn, domain, dn, sub, sub_n, ip, ip_n, store, now, resp, K_MAGIC_16384, rn)
52 if sv != NX_PORKBUN_OK {
53 ppa_pe("set A FAIL\n--- raw response ---\n" as *u8)
54 sys_write(2, resp, rn[0])
55 ppa_pe("\n--- end ---\n" as *u8)
56 return 3
57 }
58 ppa_pp("A record published OK (status=SUCCESS)\n" as *u8)
59 return 0
60}