/
config.go
130 lines (116 loc) · 2.8 KB
/
config.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"fmt"
"io/ioutil"
"os"
"os/user"
"path/filepath"
"code.google.com/p/go.crypto/openpgp"
"code.google.com/p/go.crypto/openpgp/armor"
"github.com/BurntSushi/toml"
"github.com/nymsio/pgpmail"
)
const defaultConfigPath = ".nyms/verify_config"
const defaultPublicKey = ".nyms/verify_key.pub"
const defaultPrivateKey = ".nyms/verify_key.sec"
const defaultDKIMPEM = ".nyms/verify_dkim.pem"
type configData struct {
VerifyAddress string `toml:"verify_address"`
LogPath string `toml:"log_path"`
DKIMDisabled bool `toml:"dkim_disabled"`
DKIMSelector string `toml:"dkim_selector"`
DKIMDomain string `toml:"dkim_domain"`
PublicKey string `toml:"public_key"`
PrivateKey string `toml:"private_key"`
DKIMKeyPEM string `toml:dkim_key_pem"`
}
type Config struct {
VerifyEmail string
LogPath string
KeySource pgpmail.KeySource
DKIMPrivatePEM []byte
DKIMDomain string
DKIMSelector string
}
func loadConfig(path string) (*Config, error) {
if path == "" {
path = getHomePath(defaultConfigPath)
}
cd := new(configData)
_, err := toml.DecodeFile(path, cd)
if err != nil {
return nil, err
}
keySource, err := loadPGPKeys(cd)
if err != nil {
return nil, err
}
c := new(Config)
c.VerifyEmail = cd.VerifyAddress
c.LogPath = cd.LogPath
c.KeySource = keySource
if !cd.DKIMDisabled {
dkim, err := loadDKIMPEM(cd)
if err != nil {
return nil, err
}
c.DKIMPrivatePEM = dkim
c.DKIMDomain = cd.DKIMDomain
c.DKIMSelector = cd.DKIMSelector
}
return c, nil
}
func getHomePath(subpath string) string {
u, err := user.Current()
if err != nil {
panic("Could not look up current user: " + err.Error())
}
return filepath.Join(u.HomeDir, subpath)
}
func loadPGPKeys(cd *configData) (pgpmail.KeySource, error) {
pub, err := loadPGPKey(cd.PublicKey, defaultPublicKey)
if err != nil {
return nil, err
}
sec, err := loadPGPKey(cd.PrivateKey, defaultPrivateKey)
if err != nil {
return nil, err
}
kr := new(pgpmail.KeyRing)
kr.AddPublicKey(pub)
kr.AddSecretKey(sec)
return kr, nil
}
func loadDKIMPEM(cd *configData) ([]byte, error) {
path := cd.DKIMKeyPEM
if path == "" {
path = getHomePath(defaultDKIMPEM)
}
pem, err := ioutil.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to load DKIM PEM file '%s': %v", path, err)
}
return pem, nil
}
func loadPGPKey(path string, defaultPath string) (*openpgp.Entity, error) {
if path == "" {
path = getHomePath(defaultPath)
}
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
block, err := armor.Decode(f)
if err != nil {
return nil, err
}
el, err := openpgp.ReadKeyRing(block.Body)
if err != nil {
return nil, err
}
if len(el) != 1 {
return nil, fmt.Errorf("Key file %s contained %d keys, expecting 1", path, len(el))
}
return el[0], nil
}