forked from YahooArchive/coname
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dkim.go
77 lines (70 loc) · 1.84 KB
/
dkim.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package dkim
import (
"bytes"
"fmt"
"net/mail"
"strings"
"time"
dkim "github.com/andres-erbsen/go-dkim"
)
func CheckEmailProof(dkimMail []byte, toAddr, subjectPrefix string, LookupTXT func(string) ([]string, error), now func() time.Time) (email, binding string, err error) {
dkimHeader, err := dkim.Verify(dkimMail, LookupTXT, now)
if err != nil {
return "", "", err
}
fromHeaderSigned := false
toHeaderSigned := false
subjectHeaderSigned := false
for _, hdrName := range dkimHeader.Headers {
switch strings.ToLower(hdrName) {
case "to":
toHeaderSigned = true
case "from":
fromHeaderSigned = true
case "subject":
subjectHeaderSigned = true
}
}
if !toHeaderSigned {
return "", "", fmt.Errorf("the To header is not signed")
}
if !fromHeaderSigned {
return "", "", fmt.Errorf("the From header is not signed")
}
if !subjectHeaderSigned {
return "", "", fmt.Errorf("the Subject header is not signed")
}
msg, err := mail.ReadMessage(bytes.NewReader(dkimMail))
if err != nil {
return "", "", err
}
fromAddrs, err := msg.Header.AddressList("from")
if err != nil {
return "", "", err
}
if len(fromAddrs) != 1 {
return "", "", fmt.Errorf("multiple from addresses")
}
email = fromAddrs[0].Address
if !strings.HasSuffix(email, "@"+dkimHeader.Domain) {
return "", "", fmt.Errorf("from address is not within the DKIM domain")
}
toAddrs, err := msg.Header.AddressList("to")
if err != nil {
return "", "", err
}
for _, dst := range toAddrs {
addr := dst.Address
switch {
case addr == email:
case addr == toAddr:
default:
return "", "", fmt.Errorf("unknown address %q on To line", addr)
}
}
subject := msg.Header.Get("subject")
if !strings.HasPrefix(subject, subjectPrefix) {
return "", "", fmt.Errorf("subject line does not match the required format")
}
return email, subject[len(subjectPrefix):], nil
}