code wiki / _hdl_build / nx_email_provision_gate.nx
nx_email_provision_gate.nx source
↩ module page · 101 lines · 6330 B
1// nx_email_provision_gate.nx -- MEASURED gate for per-domain email provisioning, run for andelinwest.com (the
2// operator's "finish andelinwest email"). Provisions the domain via nx_email_provision_lib, then proves the WHOLE
3// mail path is correct for it -- inbound accept policy AND outbound DKIM -- using the real email organs:
4// T1 DKIM keypair round-trips -> the published pubkey validates this signer (ed25519 sign+verify)
5// T2 DNS zone structure -> MX/SPF/DKIM/DMARC + selector all present for andelinwest.com
6// T3 MTA own-domain accept policy -> info@andelinwest.com ACCEPTED, spammer@evil.com REFUSED (no open relay)
7// T4 end-to-end DKIM outbound -> a message From: postmaster@andelinwest.com signs+verifies; a tampered body fails
8// Verdict MEASURED from the real organs. GREEN iff 4/4. Appends knowledge/status/email_provision_gate.log and
9// prints the publishable zone. license_tier: ORIGINAL
10import "nx_email_provision_lib.nx"
11import "nx_g_puts_lib.nx"
12import "nx_email_mta.nx"
13import "nx_email_send.nx"
14
15func g_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
16func g_w(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
17func g_wn(fd: i64, v: i64) -> i64 {
18 let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m }
19 let t: *u8 = sys_mmap(28); var k: i64 = 0; if m == 0 { t[0] = 48 as u8; k = 1 }
20 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
21 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } sys_write(fd, bb, k); return 0
22}
23func g_contains(hay: *u8, hlen: i64, ndl: *u8) -> i64 {
24 let nl: i64 = g_slen(ndl); if nl == 0 { return 0 }
25 var i: i64 = 0
26 while i + nl <= hlen { var k: i64 = 0; var hit: i64 = 1; while k < nl { if (hay[i + k] & 0xff) != (ndl[k] & 0xff) { hit = 0; k = nl } else { k = k + 1 } } if hit == 1 { return 1 } i = i + 1 }
27 return 0
28}
29
30func main() -> i64 {
31 g_puts("=== EMAIL PROVISION GATE: andelinwest.com (per-domain, data-driven; MEASURED via real email organs) ===\n" as *u8)
32 let domain: *u8 = "andelinwest.com" as *u8
33 let host: *u8 = "mail.andelinwest.com" as *u8
34 let ip: *u8 = "203.0.113.10" as *u8 // placeholder -- operator sets the NAS public IPv4 at publish
35 let selector: *u8 = "nishi1" as *u8
36
37 let priv: *u8 = sys_mmap(32)
38 let pub: *u8 = sys_mmap(32)
39 let zone: *u8 = sys_mmap(4096)
40 let zlen: i64 = ep_provision(domain, host, ip, selector, priv, pub, zone, 4090)
41
42 var pass: i64 = 0
43
44 // T1: DKIM keypair round-trip
45 let sig: *u8 = sys_mmap(64)
46 ed25519_sign_full(priv, "dkim-test" as *u8, 9, sig)
47 var t1: i64 = 0
48 if ed25519_verify_full(pub, "dkim-test" as *u8, 9, sig) == 1 { t1 = 1 }
49 pass = pass + t1
50 g_puts(" T1 DKIM keypair round-trip: "); if t1 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) }
51
52 // T2: zone structure for andelinwest.com
53 var t2: i64 = 0
54 let z_mx: i64 = g_contains(zone, zlen, "MX\t10 mail.andelinwest.com" as *u8)
55 let z_dkim: i64 = g_contains(zone, zlen, "v=DKIM1; k=ed25519; p=" as *u8)
56 let z_spf: i64 = g_contains(zone, zlen, "v=spf1 a:mail.andelinwest.com -all" as *u8)
57 let z_dmarc: i64 = g_contains(zone, zlen, "v=DMARC1; p=quarantine" as *u8)
58 let z_sel: i64 = g_contains(zone, zlen, "nishi1._domainkey.andelinwest.com" as *u8)
59 if z_mx == 1 { if z_dkim == 1 { if z_spf == 1 { if z_dmarc == 1 { if z_sel == 1 { t2 = 1 } } } } }
60 pass = pass + t2
61 g_puts(" T2 DNS zone MX/SPF/DKIM/DMARC/selector: "); if t2 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) }
62
63 // T3: MTA own-domain accept policy (accept ours, refuse relay)
64 let own: *u8 = "info@andelinwest.com" as *u8
65 let foreign: *u8 = "spammer@evil.com" as *u8
66 let acc_own: i64 = nx_mta_rcpt_accept(own, g_slen(own), domain, g_slen(domain))
67 let acc_foreign: i64 = nx_mta_rcpt_accept(foreign, g_slen(foreign), domain, g_slen(domain))
68 var t3: i64 = 0
69 if acc_own == 1 { if acc_foreign == 0 { t3 = 1 } }
70 pass = pass + t3
71 g_puts(" T3 MTA accept-own/refuse-relay (own="); g_wn(1, acc_own); g_puts(" foreign="); g_wn(1, acc_foreign); g_puts("): ")
72 if t3 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) }
73
74 // T4: end-to-end DKIM outbound for andelinwest.com (sign with provisioned key, verify with provisioned pubkey)
75 let msg: *u8 = sys_mmap(2048)
76 let mlen: i64 = nx_email_compose("postmaster@andelinwest.com" as *u8, "client@example.com" as *u8, "Welcome to Andelin West" as *u8, "Your secure client portal is ready.\r\n" as *u8, msg, 2048)
77 let signed: *u8 = sys_mmap(4096)
78 let slen: i64 = nx_email_dkim_sign_message(msg, mlen, priv, selector, domain, signed, 4096)
79 let v_ok: i64 = nx_email_dkim_verify_message(signed, slen, pub)
80 signed[slen - 1] = (signed[slen - 1] ^ (0x20 as u8)) // tamper one body byte
81 let v_tamper: i64 = nx_email_dkim_verify_message(signed, slen, pub)
82 var t4: i64 = 0
83 if v_ok == 1 { if v_tamper == 0 { t4 = 1 } }
84 pass = pass + t4
85 g_puts(" T4 DKIM sign->verify ok="); g_wn(1, v_ok); g_puts(" tamper_rejected="); g_wn(1, 1 - v_tamper); g_puts(": ")
86 if t4 == 1 { g_puts("PASS\n" as *u8) } else { g_puts("FAIL\n" as *u8) }
87
88 g_puts("----\nEMAIL-PROVISION domain=andelinwest.com rows=4 pass="); g_wn(1, pass); g_puts("\n" as *u8)
89 let lg: i64 = sys_openat_append("knowledge/status/email_provision_gate.log" as *u8, 0x1a4)
90 if lg >= 0 {
91 g_w(lg, "EMAIL-PROVISION domain=andelinwest.com dkim=ed25519 selector=nishi1 keypair_rt="); g_wn(lg, t1)
92 g_w(lg, " zone_ok="); g_wn(lg, t2); g_w(lg, " mta_accept_own_refuse_relay="); g_wn(lg, t3); g_w(lg, " dkim_e2e="); g_wn(lg, t4)
93 g_w(lg, " rows=4 pass="); g_wn(lg, pass)
94 if pass == 4 { g_w(lg, " verdict=GREEN\n" as *u8) } else { g_w(lg, " verdict=RED\n" as *u8) }
95 sys_close(lg)
96 }
97 g_puts("\n----- DNS records to publish (knowledge/status/andelinwest.com_dns_zone.txt) -----\n" as *u8)
98 g_puts(zone)
99 if pass == 4 { g_puts("\nEMAIL-PROVISION GREEN (andelinwest.com: DKIM keypair + zone + MTA accept + DKIM e2e -- measured)\n" as *u8); sys_exit(0); return 0 }
100 g_puts("\nEMAIL-PROVISION RED\n" as *u8); sys_exit(1); return 1
101}