forked from blueimp/aws-smtp-relay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain_internal_test.go
353 lines (330 loc) · 9.31 KB
/
main_internal_test.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
package main
import (
"flag"
"io/ioutil"
"os"
"reflect"
"testing"
pinpointrelay "github.com/blueimp/aws-smtp-relay/internal/relay/pinpoint"
sesrelay "github.com/blueimp/aws-smtp-relay/internal/relay/ses"
)
// bcrypt hash for the string "password"
var sampleHash = "$2y$10$85/eICRuwBwutrou64G5HeoF3Ek/qf1YKPLba7ckiMxUTAeLIeyaC"
func createTmpFile(content string) (fileName *string, err error) {
file, err := ioutil.TempFile("", "")
if err != nil {
return
}
_, err = file.Write([]byte(content))
if err != nil {
return
}
err = file.Close()
name := file.Name()
fileName = &name
return
}
func createTLSFiles() (
certFile *string,
keyFile *string,
passphrase string,
err error,
) {
const certPEM = `-----BEGIN CERTIFICATE-----
MIIDRzCCAi+gAwIBAgIJAKtg4oViVwv4MA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
BAMMCWxvY2FsaG9zdDAgFw0xODA0MjAxMzMxNTBaGA8yMDg2MDUwODEzMzE1MFow
FDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA8h7vl0gUquis5jRtcnETyD+8WITZO0s53aIzp0Y+9HXiHW6FGJjbOZjM
IvozNVni+83QWKumRTgeSzIIW2j4V8iFMSNrvWmhmCKloesXS1aY6H979e01Ve8J
WAJFRe6vZJd6gC6Z/P+ELU3ie4Vtr1GYfkV7nZ6VFp5/V/5nxGFag5TUlpP5hcoS
9r2kvXofosVwe3x3udT8SEbv5eBD4bKeVyJs/RLbxSuiU1358Y1cDdVuHjcvfm3c
ajhheQ4vX9WXsk7LGGhnf1SrrPN/y+IDTXfvoHn+nJh4vMAB4yzQdE1V1N1AB8RA
0yBVJ6dwxRrSg4BFrNWhj3gfsvrA7wIDAQABo4GZMIGWMB0GA1UdDgQWBBQ4/ncp
befFuKH1hoYkPqLwuRrPRjAfBgNVHSMEGDAWgBQ4/ncpbefFuKH1hoYkPqLwuRrP
RjAJBgNVHRMEAjAAMBEGCWCGSAGG+EIBAQQEAwIGQDALBgNVHQ8EBAMCBaAwEwYD
VR0lBAwwCgYIKwYBBQUHAwEwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqGSIb3
DQEBCwUAA4IBAQBJBetEXiEIzKAEpXGX87j6aUON51Fdf6BiLMCghuGKyhnaOG32
4KJhtvVoS3ZUKPylh9c2VdItYlhWp76zd7YKk+3xUOixWeTMQHIvCvRGTyFibOPT
mApwp2pEnJCe4vjUrBaRhiyI+xnB70cWVF2qeernlLUeJA1mfYyQLz+v06ebDWOL
c/hPVQFB94lEdiyjGO7RZfIe8KwcK48g7iv0LQU4+c9MoWM2ZsVM1AL2tHzokSeA
u64gDTW4K0Tzx1ab7KmOFXYUjbz/xWuReMt33EwDXAErKCjbVt2T55Qx8UoKzSh1
tY0KDHdnYOzgsm2HIj2xcJqbeylYQvckNnoC
-----END CERTIFICATE-----`
const keyPEM = `-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,C16BF8745B2CDB53AC2B1D7609893AA0
O13z7Yq7butaJmMfg9wRis9YnIDPsp4coYI6Ud+JGcP7iXoy95QMhovKWx25o1ol
tvUTsrsG27fHGf9qG02KizApIVtO9c1e0swCWzFrKRQX0JDiZDmilb9xosBNNst1
BOzOTRZEwFGSOCKZRBfSXyqC93TvLJ3DO9IUnKIeGt7upipvg29b/Dur/fyCy2WV
bLHXwUTDBm7j49yfoEyGkDjoB2QO9wgcgbacbnQJQ25fTFUwZpZJEJv6o1tRhoYM
ZMOhC9x1URmdHKN1+z2y5BrB6oNpParfeAMEvs/9FE6jJwYUR28Ql6Mhphfvr9W2
5Gxd3J65Ao9Vi2I5j5X6aBuNjyhXN3ScLjPG4lVZm9RU/uTPEt81pig/d5nSAjvF
Nfc08NuG3cnMyJSE/xScJ4D+GtX8U969wO4oKPCR4E/NFyXPR730ppupDFG6hzPD
PDmiszDtU438JAZ8AuFa1LkbyFnEW6KVD4h7VRr8YDjirCqnkgjNSI6dFY0NQ8H7
SyexB0lrceX6HZc+oNdAtkX3tYdzY3ExzUM5lSF1dkldnRbApLbqc4uuNIVXhXFM
dJnoPdKAzM6i+2EeVUxWNdafKDxnjVSHIHzHfIFJLQ4GS5rnz9keRFdyDjQL07tT
Lu9pPOmsadDXp7oSa81RgoCUfNZeR4jKpCk2BOft0L6ZSqwYFLcQHLIfJaGfn902
TUOTxHt0KzEUYeYSrXC2a6cyvXAd1YI7lOgy60qG89VHyCc2v5Bs4c4FNUDC/+Dj
4ZwogaAbSNkLaE0q3sYQRPdxSqLftyX0KitAgE7oGtdzBfe1cdBoozw3U67NEMMT
6qvk5j7RepPRSrapHtK5pMMdg5XpKFWcOXZ26VHVrDCj4JKdjVb4iyiQi94VveV0
w9+KcOtyrM7/jbQlCWnXpsIkP8VA/RIgh7CBn/h4oF1sO8ywP25OGQ7VWAVq1R9D
8bl8GzIdR9PZpFyOxuIac4rPa8tkDeoXKs4cxoao7H/OZO9o9aTB7CJMTL9yv0Kb
ntWuYxQchE6syoGsOgdGyZhaw4JeFkasDUP5beyNY+278NkzgGTOIMMTXIX46woP
ehzHKGHXVGf7ZiSFF+zAHMXZRSwNVMkOYwlIoRg1IbvIRbAXqAR6xXQTCVzNG0SU
cskojycBca1Cz3hDVIKYZd9beDhprVdr2a4K2nft2g2xRNjKPopsaqXx+VPibFUx
X7542eQ3eAlhkWUuXvt0q5a9WJdjJp9ODA0/d0akF6JQlEHIAyLfoUKB1HYwgUGG
6uRm651FDAab9U4cVC5PY1hfv/QwzpkNDkzgJAZ5SMOfZhq7IdBcqGd3lzPmq2FP
Vy1LVZIl3eM+9uJx5TLsBHH6NhMwtNhFCNa/5ksodQYlTvR8IrrgWlYg4EL69vjS
yt6HhhEN3lFCWvrQXQMp93UklbTlpVt6qcDXiC7HYbs3+EINargRd5Z+xL5i5vkN
f9k7s0xqhloWNPZcyOXMrox8L81WOY+sP4mVlGcfDRLdEJ8X2ofJpOAcwYCnjsKd
uEGsi+l2fTj/F+eZLE6sYoMprgJrbfeqtRWFguUgTn7s5hfU0tZ46al5d0vz8fWK
-----END RSA PRIVATE KEY-----`
passphrase = "test"
certFile, err = createTmpFile(certPEM)
if err != nil {
return
}
keyFile, err = createTmpFile(keyPEM)
return
}
func resetHelper() {
os.Args = []string{"noop"}
flag.Parse()
*addr = ":1025"
*name = "AWS SMTP Relay"
*host = ""
*certFile = ""
*keyFile = ""
*startTLS = false
*onlyTLS = false
*relayAPI = "ses"
*setName = ""
*ips = ""
*user = ""
ipMap = nil
bcryptHash = nil
password = nil
relayClient = nil
os.Unsetenv("BCRYPT_HASH")
os.Unsetenv("PASSWORD")
os.Unsetenv("TLS_KEY_PASS")
}
func TestConfigure(t *testing.T) {
resetHelper()
err := configure()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if *user != "" {
t.Errorf("Unexpected username: %s", *user)
}
if string(bcryptHash) != "" {
t.Errorf("Unexpected bhash: %s", string(bcryptHash))
}
if *ips != "" {
t.Errorf("Unexpected IPs string: %s", *ips)
}
if len(ipMap) != 0 {
t.Errorf("Unexpected IP map size: %d", len(ipMap))
}
_, ok := interface{}(relayClient).(sesrelay.Client)
if !ok {
t.Error("Unexpected: relayClient function is not an sesrelay.Client")
}
if string(bcryptHash) != "" {
t.Errorf("Unexpected bhash: %s", string(bcryptHash))
}
}
func TestConfigureWithPinpointRelay(t *testing.T) {
resetHelper()
*relayAPI = "pinpoint"
err := configure()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
_, ok := interface{}(relayClient).(pinpointrelay.Client)
if !ok {
t.Error("Unexpected: relayClient function is not an sesrelay.Client")
}
}
func TestConfigureWithInvalidRelay(t *testing.T) {
resetHelper()
*relayAPI = "invalid"
err := configure()
if err == nil {
t.Error("Unexpected nil error")
}
if relayClient != nil {
t.Errorf("Unexpected relay client: %s", relayClient)
}
}
func TestConfigureWithBcryptHash(t *testing.T) {
resetHelper()
os.Setenv("BCRYPT_HASH", sampleHash)
err := configure()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if string(bcryptHash) != sampleHash {
t.Errorf("Unexpected bhash: %s", string(bcryptHash))
}
}
func TestConfigureWithPassword(t *testing.T) {
resetHelper()
os.Setenv("PASSWORD", "password")
err := configure()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if string(password) != "password" {
t.Errorf("Unexpected password: %s", string(password))
}
}
func TestConfigureWithIPs(t *testing.T) {
resetHelper()
*ips = "127.0.0.1,2001:4860:0:2001::68"
err := configure()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if *ips != "127.0.0.1,2001:4860:0:2001::68" {
t.Errorf("Unexpected IPs string: %s", *ips)
}
if len(ipMap) != 2 {
t.Errorf("Unexpected IP map size: %d", len(ipMap))
}
}
func TestServer(t *testing.T) {
resetHelper()
configure()
srv, err := server()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if srv.Addr != ":1025" {
t.Errorf("Unexpected addr: %s. Expected: %s", srv.Addr, ":1025")
}
if srv.Appname != "AWS SMTP Relay" {
t.Errorf("Unexpected addr: %s. Expected: %s", srv.Appname, "AWS SMTP Relay")
}
if srv.Hostname != "" {
t.Errorf("Unexpected host: %s. Expected host to be empty.", srv.Hostname)
}
if srv.TLSConfig != nil {
t.Errorf("Unexpected TLS config defined.")
}
if srv.TLSRequired != false {
t.Errorf("Unexpected TLS required: %t", srv.TLSRequired)
}
if srv.TLSListener != false {
t.Errorf("Unexpected TLS listener: %t", srv.TLSListener)
}
}
func TestServerWithCustomAddress(t *testing.T) {
resetHelper()
*addr = "127.0.0.1:25"
configure()
srv, err := server()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if srv.Addr != *addr {
t.Errorf("Unexpected addr: %s. Expected: %s", srv.Addr, *addr)
}
}
func TestServerWithCustomAppname(t *testing.T) {
resetHelper()
*name = "Custom Appname"
configure()
srv, err := server()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if srv.Appname != "Custom Appname" {
t.Errorf("Unexpected addr: %s. Expected: %s", srv.Appname, "Custom Appname")
}
}
func TestServerWithCustomHostname(t *testing.T) {
resetHelper()
*host = "test"
configure()
srv, err := server()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if srv.Hostname != "test" {
t.Errorf("Unexpected host: %s. Expected: %s", srv.Hostname, "test")
}
}
func TestServerWithIPs(t *testing.T) {
resetHelper()
*ips = "127.0.0.1,2001:4860:0:2001::68"
err := configure()
srv, err := server()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if srv.AuthRequired != true {
t.Errorf(
"Unexpected AuthRequired: %t. Expected: %t",
srv.AuthRequired,
true,
)
}
authMechs := map[string]bool{}
if !reflect.DeepEqual(srv.AuthMechs, authMechs) {
t.Errorf(
"Unexpected AuthMechs: %v. Expected: %v",
srv.AuthMechs,
authMechs,
)
}
}
func TestServerWithBcryptHash(t *testing.T) {
resetHelper()
*user = "username"
os.Setenv("BCRYPT_HASH", sampleHash)
err := configure()
srv, err := server()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if srv.AuthRequired != true {
t.Errorf(
"Unexpected AuthRequired: %t. Expected: %t",
srv.AuthRequired,
true,
)
}
authMechs := map[string]bool{"CRAM-MD5": false}
if !reflect.DeepEqual(srv.AuthMechs, authMechs) {
t.Errorf(
"Unexpected AuthMechs: %v. Expected: %v",
srv.AuthMechs,
authMechs,
)
}
}
func TestServerWithTLS(t *testing.T) {
resetHelper()
var passphrase string
var err error
certFile, keyFile, passphrase, err = createTLSFiles()
if err != nil {
t.Errorf("Unexpected TLS files creation error: %s", err)
return
}
defer func() {
os.Remove(*certFile)
os.Remove(*keyFile)
}()
os.Setenv("TLS_KEY_PASS", passphrase)
configure()
srv, err := server()
if err != nil {
t.Errorf("Unexpected error: %s", err)
}
if srv.TLSConfig == nil {
t.Errorf("Unexpected empty TLS config.")
}
}