Pure MoonBit email authentication engine: DKIM signature verification, SPF evaluation, DMARC alignment and Authentication-Results output.
Dependencies
moon add Mr-Houjie/mbt-mailauthmoon run cmd/main -- message.eml --ip 192.0.2.5 --zone zone.txttest._domainkey.example.com TXT v=DKIM1; k=rsa; p=MIIBIjAN...
example.com TXT v=spf1 ip4:192.0.2.0/24 -all
_dmarc.example.com TXT v=DMARC1; p=reject--ip <addr> SMTP 对端 IP,SPF 必需
--zone <file> 离线 DNS zone
--mail-from <domain> MAIL FROM 域,默认取 From 头
--helo <name> HELO 名,供 SPF 宏使用
--format <fmt> text | json | header
--now <unix> 校验签名 x= 过期时间
--sample <0-99> DMARC pct 采样值dkim: pass d=example.com s=test
reason: signature verified
- body-hash: canonical body 33 bytes, bh=7x9e9eVKz/7ajCJi+nmVKcjCtQaN2/fohG/wOvpvNnE=
- header-hash: signed headers: 7, input 423 bytes
- key: test._domainkey.example.com: rsa 2048 bits
spf: pass domain=example.com
mechanism: ip4:192.0.2.0/24
dmarc: pass domain=example.com
policy: reject, disposition: none
aligned: dkim=true, spf=truelet zone = @Mr-Houjie/mbt-mailauth.Zone::from_text(zone_text)
let report = @Mr-Houjie/mbt-mailauth.verify_message(
zone,
raw_email,
"192.0.2.5",
"", // mail_from,空表示取 From 头
"", // helo
0, // now,0 表示不校验过期
-1, // sample,负数表示 pct 使用完整策略
)
println(@Mr-Houjie/mbt-mailauth.render_text(report))
println(@Mr-Houjie/mbt-mailauth.render_json(report))
println(@Mr-Houjie/mbt-mailauth.authentication_results(report, "mx.example.com"))types.mbt 判定模型:状态 + 证据 + 原因
message.mbt 原始字节切分(保留头部原始字节)
canon.mbt DKIM simple / relaxed 规范化
sha256.mbt 自研 SHA-256(NIST 向量)
rsa.mbt 最小 DER/SPKI 解析 + PKCS#1 v1.5 验签
dkim.mbt 签名头解析、头部选择、验签
spf.mbt 记录解析、机制、宏、限额、求值
dmarc.mbt 对齐、策略、组织域、聚合报告
render.mbt text / json / Authentication-Results
verify.mbt 编排:一封邮件 → 完整报告
dns.mbt Resolver trait 与离线 Zone
selftest.mbt 19 条固定语料
cmd/main 命令行
cmd/verify 独立自检入口
tests/tools/ 跨实现向量生成脚本(Node/OpenSSL)# 独立自检(Windows 下 moon test 可能受嵌套进程限制)
moon run cmd/verify
# 标准测试(Linux / macOS)
moon testnode tests/tools/gen_dkim_vector.jspub struct DkimResult {
domain : String
selector : String
algorithm : String
status : AuthStatus
reason : String
evidence : Array[Evidence]
}pub struct DmarcPolicy {
policy : String
subdomain_policy : String?
pct : Int
adkim : DmarcAlign
aspf : DmarcAlign
rua : Array[String]
ruf : Array[String]
}pub struct DmarcResult {
domain : String
policy : String
disposition : String
dkim_aligned : Bool
spf_aligned : Bool
status : AuthStatus
reason : String
}pub struct MacroCtx {
sender : String
domain : String
ip : String
helo : String
}pub struct SpfResult {
domain : String
identity : String
status : AuthStatus
qualifier : String
mechanism : String
reason : String
dns_lookups : Int
void_lookups : Int
}pub struct SpfTerm {
qualifier : SpfQualifier
kind : SpfKind
value : String
cidr4 : Int?
cidr6 : Int?
raw : String
}fn dmarc_aggregate_report(report : AuthReport, org_name : String, email : String, begin : Int, end : Int, domain : String) -> Stringfn[R : Resolver] evaluate_dmarc(resolver : R, from_domain : String, dkim : Array[DkimResult], spf : SpfResult?, sample? : Int) -> DmarcResultfn normalize_crlf(input : BytesView) -> Bytesfn organizational_domain(domain : String) -> Stringfn rsa_verify_sha256_base64(public_key_b64 : String, message : BytesView, signature_b64 : String) -> Boolfn[R : Resolver] verify_dkim(resolver : R, message : Message, signature_field : HeaderField, now? : Int) -> DkimResultfn[R : Resolver] verify_message(resolver : R, raw : BytesView, ip : String, mail_from : String, helo : String, now : Int, sample : Int) -> AuthReportInstall
Download zipPure MoonBit email authentication engine: DKIM signature verification, SPF evaluation, DMARC alignment and Authentication-Results output.
Dependencies