forked from pereiro/smtprelay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdkim.go
107 lines (92 loc) · 2.31 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package main
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"os"
"smtprelay/dkim"
"strings"
)
const KEY_CONFIG_SUFFIX string = ".config"
type DKIM struct {
Selector string
Domain string
Data []byte
dkimConf dkim.Conf
dkim dkim.DKIM
}
var DKIMRepo map[string]DKIM
func DKIMLoadKeyRepository() error {
DKIMRepo = make(map[string]DKIM)
dir, err := ioutil.ReadDir(conf.DKIMKeyDir)
if err != nil {
return err
}
var keyCount int
var sep = os.PathSeparator
for _, keyFile := range dir {
if strings.Contains(keyFile.Name(), KEY_CONFIG_SUFFIX) {
continue
}
key, err := DKIMLoadConfig(conf.DKIMKeyDir + string(sep) + keyFile.Name() + KEY_CONFIG_SUFFIX)
if err != nil {
log.Warn("can't read key config from %s:%s", conf.DKIMKeyDir+string(sep)+keyFile.Name(), err.Error()+KEY_CONFIG_SUFFIX)
continue
}
key.Data, err = ioutil.ReadFile(conf.DKIMKeyDir + string(sep) + keyFile.Name())
if err != nil {
log.Warn("can't read key data from %s:%s", conf.DKIMKeyDir+string(sep)+keyFile.Name(), err.Error())
continue
}
key.dkimConf, err = dkim.NewConf(key.Domain, key.Selector)
if err != nil {
log.Error("DKIM configuration error: %v", err)
continue
}
d, err := dkim.New(key.dkimConf, key.Data)
if err != nil {
log.Error("DKIM error: %v", err)
continue
}
key.dkim = *d
DKIMRepo[key.Domain] = key
keyCount++
}
log.Info("DKIM keys loaded - %d :", keyCount)
for _, val := range DKIMRepo {
log.Info("%s - %s", val.Domain, val.Selector)
}
return nil
}
func DKIMLoadConfig(filename string) (keyConfig DKIM, err error) {
file, err := ioutil.ReadFile(filename)
if err != nil {
return keyConfig, err
}
err = json.Unmarshal(file, &keyConfig)
if err != nil {
return keyConfig, err
}
return keyConfig, nil
}
func DKIMSign(data []byte, domain string) ([]byte, error) {
var err error
privKey := DKIMRepo[domain]
if len(privKey.Domain) == 0 {
return data, errors.New("no key in keyrepo")
}
privKey.dkim.Conf, err = dkim.NewConf(privKey.Domain, privKey.Selector)
if err != nil {
return data, err
}
if bytes.Index(data, []byte("\r\n")) < 0 {
data = bytes.Replace(data, []byte("\n"), []byte("\r\n"), -1)
}
signeddata, err := privKey.dkim.Sign(data)
if err != nil {
log.Error("DKIM signing error: %v", err)
return data, err
}
return signeddata, nil
}