add "mox dkim sign", useful for testing signatures

for issue #15
This commit is contained in:
Mechiel Lukkien 2023-03-07 21:59:55 +01:00
parent 39a097a5d4
commit a9ef0f2aea
No known key found for this signature in database
2 changed files with 57 additions and 0 deletions

11
doc.go
View file

@ -50,6 +50,7 @@ low-maintenance self-hosted email.
mox dkim lookup selector domain
mox dkim txt <$selector._domainkey.$domain.key.pkcs8.pem
mox dkim verify message
mox dkim sign message
mox dmarc lookup domain
mox dmarc parsereportmsg message ...
mox dmarc verify remoteip mailfromaddress helodomain < message
@ -503,6 +504,16 @@ that was passed.
usage: mox dkim verify message
# mox dkim sign
Sign a message, adding DKIM-Signature headers based on the domain in the From header.
The message is parsed, the domain looked up in the configuration files, and
DKIM-Signature headers generated. The message is printed with the DKIM-Signature
headers prepended.
usage: mox dkim sign message
# mox dmarc lookup
Lookup dmarc policy for domain, a DNS TXT record at _dmarc.<domain>, validate and print it.

46
main.go
View file

@ -116,6 +116,7 @@ var commands = []struct {
{"dkim lookup", cmdDKIMLookup},
{"dkim txt", cmdDKIMTXT},
{"dkim verify", cmdDKIMVerify},
{"dkim sign", cmdDKIMSign},
{"dmarc lookup", cmdDMARCLookup},
{"dmarc parsereportmsg", cmdDMARCParsereportmsg},
{"dmarc verify", cmdDMARCVerify},
@ -1272,6 +1273,51 @@ that was passed.
}
}
func cmdDKIMSign(c *cmd) {
c.params = "message"
c.help = `Sign a message, adding DKIM-Signature headers based on the domain in the From header.
The message is parsed, the domain looked up in the configuration files, and
DKIM-Signature headers generated. The message is printed with the DKIM-Signature
headers prepended.
`
args := c.Parse()
if len(args) != 1 {
c.Usage()
}
msgf, err := os.Open(args[0])
xcheckf(err, "open message")
defer msgf.Close()
p, err := message.Parse(msgf)
xcheckf(err, "parsing message")
if len(p.Envelope.From) != 1 {
log.Fatalf("found %d from headers, need exactly 1", len(p.Envelope.From))
}
localpart := smtp.Localpart(p.Envelope.From[0].User)
dom, err := dns.ParseDomain(p.Envelope.From[0].Host)
xcheckf(err, "parsing domain in from header")
mustLoadConfig()
domConf, ok := mox.Conf.Domain(dom)
if !ok {
log.Fatalf("domain %s not configured", dom)
}
headers, err := dkim.Sign(context.Background(), localpart, dom, domConf.DKIM, false, msgf)
xcheckf(err, "signing message with dkim")
if headers == "" {
log.Fatalf("no DKIM configured for domain %s", dom)
}
_, err = fmt.Fprint(os.Stdout, headers)
xcheckf(err, "write headers")
_, err = io.Copy(os.Stdout, msgf)
xcheckf(err, "write message")
}
func cmdDKIMLookup(c *cmd) {
c.params = "selector domain"
c.help = "Lookup and print the DKIM record for the selector at the domain."