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}