maddy

Fork https://github.com/foxcpp/maddy

git clone git://git.lin.moe/go/maddy.git

  1/*
  2Maddy Mail Server - Composable all-in-one email server.
  3Copyright © 2019-2020 Max Mazurov <fox.cpp@disroot.org>, Maddy Mail Server contributors
  4
  5This program is free software: you can redistribute it and/or modify
  6it under the terms of the GNU General Public License as published by
  7the Free Software Foundation, either version 3 of the License, or
  8(at your option) any later version.
  9
 10This program is distributed in the hope that it will be useful,
 11but WITHOUT ANY WARRANTY; without even the implied warranty of
 12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13GNU General Public License for more details.
 14
 15You should have received a copy of the GNU General Public License
 16along with this program.  If not, see <https://www.gnu.org/licenses/>.
 17*/
 18
 19package remote
 20
 21import (
 22	"context"
 23	"crypto/tls"
 24	"errors"
 25	"net"
 26	"strconv"
 27	"testing"
 28
 29	"github.com/emersion/go-smtp"
 30	"github.com/foxcpp/go-mockdns"
 31	"github.com/foxcpp/go-mtasts"
 32	"github.com/foxcpp/maddy/framework/dns"
 33	"github.com/foxcpp/maddy/framework/module"
 34	"github.com/foxcpp/maddy/internal/testutils"
 35)
 36
 37func TestRemoteDelivery_AuthMX_MTASTS(t *testing.T) {
 38	clientCfg, be, srv := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
 39	defer srv.Close()
 40	defer testutils.CheckSMTPConnLeak(t, srv)
 41	zones := map[string]mockdns.Zone{
 42		"example.invalid.": {
 43			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
 44		},
 45		"mx.example.invalid.": {
 46			A: []string{"127.0.0.1"},
 47		},
 48	}
 49
 50	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
 51		if domain != "example.invalid" {
 52			return nil, errors.New("Wrong domain in lookup")
 53		}
 54
 55		return &mtasts.Policy{
 56			// Testing policy is enough.
 57			Mode: mtasts.ModeTesting,
 58			MX:   []string{"mx.example.invalid"},
 59		}, nil
 60	}
 61
 62	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
 63		testSTSPolicy(t, zones, mtastsGet),
 64	})
 65	tgt.tlsConfig = clientCfg
 66	defer tgt.Close()
 67
 68	testutils.DoTestDelivery(t, tgt, "test@example.com", []string{"test@example.invalid"})
 69	be.CheckMsg(t, 0, "test@example.com", []string{"test@example.invalid"})
 70}
 71
 72func TestRemoteDelivery_MTASTS_SkipNonMatching(t *testing.T) {
 73	_, be1, srv1 := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
 74	defer srv1.Close()
 75	defer testutils.CheckSMTPConnLeak(t, srv1)
 76
 77	clientCfg, be, srv := testutils.SMTPServerSTARTTLS(t, "127.0.0.2:"+smtpPort)
 78	defer srv.Close()
 79	defer testutils.CheckSMTPConnLeak(t, srv)
 80	zones := map[string]mockdns.Zone{
 81		"example.invalid.": {
 82			MX: []net.MX{
 83				{Host: "mx2.example.invalid.", Pref: 5},
 84				{Host: "mx1.example.invalid.", Pref: 10},
 85			},
 86		},
 87		"mx1.example.invalid.": {
 88			A: []string{"127.0.0.1"},
 89		},
 90		"mx2.example.invalid.": {
 91			A: []string{"127.0.0.2"},
 92		},
 93	}
 94
 95	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
 96		if domain != "example.invalid" {
 97			return nil, errors.New("Wrong domain in lookup")
 98		}
 99
100		return &mtasts.Policy{
101			Mode: mtasts.ModeEnforce,
102			MX:   []string{"mx2.example.invalid"},
103		}, nil
104	}
105
106	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
107		testSTSPolicy(t, zones, mtastsGet),
108		&localPolicy{minMXLevel: module.MX_MTASTS},
109	})
110	tgt.tlsConfig = clientCfg
111	defer tgt.Close()
112
113	testutils.DoTestDelivery(t, tgt, "test@example.com", []string{"test@example.invalid"})
114	be.CheckMsg(t, 0, "test@example.com", []string{"test@example.invalid"})
115
116	if be1.MailFromCounter != 0 {
117		t.Fatal("MAIL FROM issued for server failing authentication")
118	}
119}
120
121func TestRemoteDelivery_AuthMX_MTASTS_Fail(t *testing.T) {
122	clientCfg, be1, srv1 := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
123	defer srv1.Close()
124	defer testutils.CheckSMTPConnLeak(t, srv1)
125
126	zones := map[string]mockdns.Zone{
127		"example.invalid.": {
128			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
129		},
130		"mx.example.invalid.": {
131			A: []string{"127.0.0.1"},
132		},
133	}
134
135	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
136		if domain != "example.invalid" {
137			return nil, errors.New("Wrong domain in lookup")
138		}
139
140		return &mtasts.Policy{
141			Mode: mtasts.ModeTesting,
142			MX:   []string{"mx4.example.invalid"}, // not mx.example.invalid!
143		}, nil
144	}
145
146	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
147		testSTSPolicy(t, zones, mtastsGet),
148		&localPolicy{minMXLevel: module.MX_MTASTS},
149	})
150	tgt.tlsConfig = clientCfg
151	defer tgt.Close()
152
153	_, err := testutils.DoTestDeliveryErr(t, tgt, "test@example.com", []string{"test@example.invalid"})
154	if err == nil {
155		t.Fatal("Expected an error, got none")
156	}
157
158	if be1.MailFromCounter != 0 {
159		t.Fatal("MAIL FROM issued for server failing authentication")
160	}
161}
162
163func TestRemoteDelivery_AuthMX_MTASTS_NoTLS(t *testing.T) {
164	be1, srv1 := testutils.SMTPServer(t, "127.0.0.1:"+smtpPort)
165	defer srv1.Close()
166	defer testutils.CheckSMTPConnLeak(t, srv1)
167
168	zones := map[string]mockdns.Zone{
169		"example.invalid.": {
170			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
171		},
172		"mx.example.invalid.": {
173			A: []string{"127.0.0.1"},
174		},
175	}
176
177	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
178		if domain != "example.invalid" {
179			return nil, errors.New("Wrong domain in lookup")
180		}
181
182		return &mtasts.Policy{
183			Mode: mtasts.ModeEnforce,
184			MX:   []string{"mx.example.invalid"},
185		}, nil
186	}
187
188	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
189		testSTSPolicy(t, zones, mtastsGet),
190		&localPolicy{minMXLevel: module.MX_MTASTS},
191	})
192	defer tgt.Close()
193
194	_, err := testutils.DoTestDeliveryErr(t, tgt, "test@example.com", []string{"test@example.invalid"})
195	if err == nil {
196		t.Fatal("Expected an error, got none")
197	}
198
199	if be1.MailFromCounter != 0 {
200		t.Fatal("MAIL FROM issued for server failing authentication")
201	}
202}
203
204func TestRemoteDelivery_AuthMX_MTASTS_RequirePKIX(t *testing.T) {
205	_, be1, srv1 := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
206	defer srv1.Close()
207	defer testutils.CheckSMTPConnLeak(t, srv1)
208
209	zones := map[string]mockdns.Zone{
210		"example.invalid.": {
211			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
212		},
213		"mx.example.invalid.": {
214			A: []string{"127.0.0.1"},
215		},
216	}
217
218	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
219		if domain != "example.invalid" {
220			return nil, errors.New("Wrong domain in lookup")
221		}
222
223		return &mtasts.Policy{
224			Mode: mtasts.ModeEnforce,
225			MX:   []string{"mx.example.invalid"},
226		}, nil
227	}
228
229	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
230		testSTSPolicy(t, zones, mtastsGet),
231		&localPolicy{minMXLevel: module.MX_MTASTS},
232	})
233	defer tgt.Close()
234
235	_, err := testutils.DoTestDeliveryErr(t, tgt, "test@example.com", []string{"test@example.invalid"})
236	if err == nil {
237		t.Fatal("Expected an error, got none")
238	}
239
240	if be1.MailFromCounter != 0 {
241		t.Fatal("MAIL FROM issued for server failing authentication")
242	}
243}
244
245func TestRemoteDelivery_AuthMX_MTASTS_NoPolicy(t *testing.T) {
246	// At the moment, implementation ensures all MX policy checks are completed
247	// before attempting to connect.
248	// However, we cannot run complete go-smtp server to check whether it is
249	// violated and the connection is actually estabilished since this causes
250	// weird race conditions when test completes before go-smtp has the
251	// chance to fully initialize itself (Serve is still at the conn.listeners
252	// assignment when Close is called).
253	//
254	// The issue was resolved upstream by introducing locking around internal
255	// listeners slice use. Uses of FailOnConn remain since they pretty much do
256	// not hurt.
257	//
258	// https://builds.sr.ht/~emersion/job/147975
259	tarpit := testutils.FailOnConn(t, "127.0.0.1:"+smtpPort)
260	defer tarpit.Close()
261
262	zones := map[string]mockdns.Zone{
263		"example.invalid.": {
264			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
265		},
266		"mx.example.invalid.": {
267			A: []string{"127.0.0.1"},
268		},
269	}
270
271	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
272		if domain != "example.invalid" {
273			return nil, errors.New("Wrong domain in lookup")
274		}
275
276		return nil, mtasts.ErrNoPolicy
277	}
278
279	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
280		testSTSPolicy(t, zones, mtastsGet),
281		&localPolicy{minMXLevel: module.MX_MTASTS},
282	})
283	defer tgt.Close()
284
285	_, err := testutils.DoTestDeliveryErr(t, tgt, "test@example.com", []string{"test@example.invalid"})
286	if err == nil {
287		t.Fatal("Expected an error, got none")
288	}
289}
290
291func TestRemoteDelivery_AuthMX_DNSSEC(t *testing.T) {
292	be, srv := testutils.SMTPServer(t, "127.0.0.1:"+smtpPort)
293	defer srv.Close()
294	defer testutils.CheckSMTPConnLeak(t, srv)
295
296	zones := map[string]mockdns.Zone{
297		"example.invalid.": {
298			AD: true,
299			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
300		},
301		"mx.example.invalid.": {
302			A: []string{"127.0.0.1"},
303		},
304	}
305
306	dnsSrv, err := mockdns.NewServerWithLogger(zones, testutils.Logger(t, "mockdns"), false)
307	if err != nil {
308		t.Fatal(err)
309	}
310	defer dnsSrv.Close()
311
312	dialer := net.Dialer{}
313	dialer.Resolver = &net.Resolver{}
314	dnsSrv.PatchNet(dialer.Resolver)
315	addr := dnsSrv.LocalAddr().(*net.UDPAddr)
316
317	extResolver, err := dns.NewExtResolver()
318	if err != nil {
319		t.Fatal(err)
320	}
321	extResolver.Cfg.Servers = []string{addr.IP.String()}
322	extResolver.Cfg.Port = strconv.Itoa(addr.Port)
323
324	tgt := testTarget(t, zones, extResolver, nil)
325	defer tgt.Close()
326
327	testutils.DoTestDelivery(t, tgt, "test@example.com", []string{"test@example.invalid"})
328	be.CheckMsg(t, 0, "test@example.com", []string{"test@example.invalid"})
329}
330
331func TestRemoteDelivery_AuthMX_DNSSEC_Fail(t *testing.T) {
332	be, srv := testutils.SMTPServer(t, "127.0.0.1:"+smtpPort)
333	defer srv.Close()
334	defer testutils.CheckSMTPConnLeak(t, srv)
335
336	zones := map[string]mockdns.Zone{
337		"example.invalid.": {
338			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
339		},
340		"mx.example.invalid.": {
341			A: []string{"127.0.0.1"},
342		},
343	}
344
345	dnsSrv, err := mockdns.NewServerWithLogger(zones, testutils.Logger(t, "mockdns"), false)
346	if err != nil {
347		t.Fatal(err)
348	}
349	defer dnsSrv.Close()
350
351	dialer := net.Dialer{}
352	dialer.Resolver = &net.Resolver{}
353	dnsSrv.PatchNet(dialer.Resolver)
354	addr := dnsSrv.LocalAddr().(*net.UDPAddr)
355
356	extResolver, err := dns.NewExtResolver()
357	if err != nil {
358		t.Fatal(err)
359	}
360	extResolver.Cfg.Servers = []string{addr.IP.String()}
361	extResolver.Cfg.Port = strconv.Itoa(addr.Port)
362
363	tgt := testTarget(t, zones, extResolver, []module.MXAuthPolicy{
364		&localPolicy{minMXLevel: module.MX_DNSSEC},
365	})
366	defer tgt.Close()
367
368	_, err = testutils.DoTestDeliveryErr(t, tgt, "test@example.com", []string{"test@example.invalid"})
369	if err == nil {
370		t.Fatal("Expected an error, got none")
371	}
372
373	if be.MailFromCounter != 0 {
374		t.Fatal("MAIL FROM issued for server failing authentication")
375	}
376}
377
378func TestRemoteDelivery_REQUIRETLS(t *testing.T) {
379	clientCfg, be, srv := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
380	srv.EnableREQUIRETLS = true
381	defer srv.Close()
382	defer testutils.CheckSMTPConnLeak(t, srv)
383	zones := map[string]mockdns.Zone{
384		"example.invalid.": {
385			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
386		},
387		"mx.example.invalid.": {
388			A: []string{"127.0.0.1"},
389		},
390	}
391
392	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
393		if domain != "example.invalid" {
394			return nil, errors.New("Wrong domain in lookup")
395		}
396
397		return &mtasts.Policy{
398			// Testing policy is enough.
399			Mode: mtasts.ModeTesting,
400			MX:   []string{"mx.example.invalid"},
401		}, nil
402	}
403
404	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
405		testSTSPolicy(t, zones, mtastsGet),
406	})
407	tgt.tlsConfig = clientCfg
408	defer tgt.Close()
409
410	testutils.DoTestDeliveryMeta(t, tgt, "test@example.com", []string{"test@example.invalid"}, &module.MsgMetadata{
411		OriginalFrom: "test@example.com",
412		SMTPOpts: smtp.MailOptions{
413			RequireTLS: true,
414		},
415	})
416	be.CheckMsg(t, 0, "test@example.com", []string{"test@example.invalid"})
417}
418
419func TestRemoteDelivery_REQUIRETLS_Fail(t *testing.T) {
420	clientCfg, be, srv := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
421	srv.EnableREQUIRETLS = false /* no REQUIRETLS */
422	defer srv.Close()
423	defer testutils.CheckSMTPConnLeak(t, srv)
424	zones := map[string]mockdns.Zone{
425		"example.invalid.": {
426			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
427		},
428		"mx.example.invalid.": {
429			A: []string{"127.0.0.1"},
430		},
431	}
432
433	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
434		if domain != "example.invalid" {
435			return nil, errors.New("Wrong domain in lookup")
436		}
437
438		return &mtasts.Policy{
439			// Testing policy is enough.
440			Mode: mtasts.ModeTesting,
441			MX:   []string{"mx.example.invalid"},
442		}, nil
443	}
444
445	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
446		testSTSPolicy(t, zones, mtastsGet),
447	})
448	tgt.tlsConfig = clientCfg
449	defer tgt.Close()
450
451	if _, err := testutils.DoTestDeliveryErrMeta(t, tgt, "test@example.com", []string{"test@example.invalid"}, &module.MsgMetadata{
452		OriginalFrom: "test@example.com",
453		SMTPOpts: smtp.MailOptions{
454			RequireTLS: true,
455		},
456	}); err == nil {
457		t.Error("Expected an error, got none")
458	}
459	if be.MailFromCounter != 0 {
460		t.Fatal("MAIL FROM issued for server failing authentication")
461	}
462}
463
464func TestRemoteDelivery_REQUIRETLS_Relaxed(t *testing.T) {
465	clientCfg, be, srv := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
466	srv.EnableREQUIRETLS = false /* no REQUIRETLS */
467	defer srv.Close()
468	defer testutils.CheckSMTPConnLeak(t, srv)
469	zones := map[string]mockdns.Zone{
470		"example.invalid.": {
471			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
472		},
473		"mx.example.invalid.": {
474			A: []string{"127.0.0.1"},
475		},
476	}
477
478	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
479		if domain != "example.invalid" {
480			return nil, errors.New("Wrong domain in lookup")
481		}
482
483		return &mtasts.Policy{
484			// Testing policy is enough.
485			Mode: mtasts.ModeTesting,
486			MX:   []string{"mx.example.invalid"},
487		}, nil
488	}
489
490	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
491		testSTSPolicy(t, zones, mtastsGet),
492	})
493	tgt.relaxedREQUIRETLS = true
494	tgt.tlsConfig = clientCfg
495	defer tgt.Close()
496
497	testutils.DoTestDeliveryMeta(t, tgt, "test@example.com", []string{"test@example.invalid"}, &module.MsgMetadata{
498		OriginalFrom: "test@example.com",
499		SMTPOpts: smtp.MailOptions{
500			RequireTLS: true,
501		},
502	})
503	be.CheckMsg(t, 0, "test@example.com", []string{"test@example.invalid"})
504}
505
506func TestRemoteDelivery_REQUIRETLS_Relaxed_NoMXAuth(t *testing.T) {
507	clientCfg, be, srv := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
508	srv.EnableREQUIRETLS = false /* no REQUIRETLS */
509	defer srv.Close()
510	defer testutils.CheckSMTPConnLeak(t, srv)
511	zones := map[string]mockdns.Zone{
512		"example.invalid.": {
513			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
514		},
515		"mx.example.invalid.": {
516			A: []string{"127.0.0.1"},
517		},
518	}
519
520	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
521		if domain != "example.invalid" {
522			return nil, errors.New("Wrong domain in lookup")
523		}
524		return nil, mtasts.ErrNoPolicy
525	}
526
527	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
528		testSTSPolicy(t, zones, mtastsGet),
529	})
530	tgt.relaxedREQUIRETLS = true
531	tgt.tlsConfig = clientCfg
532	defer tgt.Close()
533
534	if _, err := testutils.DoTestDeliveryErrMeta(t, tgt, "test@example.com", []string{"test@example.invalid"}, &module.MsgMetadata{
535		OriginalFrom: "test@example.com",
536		SMTPOpts: smtp.MailOptions{
537			RequireTLS: true,
538		},
539	}); err == nil {
540		t.Error("Expected an error, got none")
541	}
542	if be.MailFromCounter != 0 {
543		t.Fatal("MAIL FROM issued for server failing authentication")
544	}
545}
546
547func TestRemoteDelivery_REQUIRETLS_Relaxed_NoTLS(t *testing.T) {
548	be, srv := testutils.SMTPServer(t, "127.0.0.1:"+smtpPort)
549	srv.EnableREQUIRETLS = false /* no REQUIRETLS */
550	defer srv.Close()
551	defer testutils.CheckSMTPConnLeak(t, srv)
552	zones := map[string]mockdns.Zone{
553		"example.invalid.": {
554			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
555		},
556		"mx.example.invalid.": {
557			A: []string{"127.0.0.1"},
558		},
559	}
560
561	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
562		if domain != "example.invalid" {
563			return nil, errors.New("Wrong domain in lookup")
564		}
565
566		return &mtasts.Policy{
567			// Testing policy is enough.
568			Mode: mtasts.ModeTesting,
569			MX:   []string{"mx.example.invalid"},
570		}, nil
571	}
572
573	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
574		testSTSPolicy(t, zones, mtastsGet),
575	})
576	tgt.relaxedREQUIRETLS = true
577	tgt.tlsConfig = nil
578	defer tgt.Close()
579
580	if _, err := testutils.DoTestDeliveryErrMeta(t, tgt, "test@example.com", []string{"test@example.invalid"}, &module.MsgMetadata{
581		OriginalFrom: "test@example.com",
582		SMTPOpts: smtp.MailOptions{
583			RequireTLS: true,
584		},
585	}); err == nil {
586		t.Error("Expected an error, got none")
587	}
588	if be.MailFromCounter != 0 {
589		t.Fatal("MAIL FROM issued for server failing authentication")
590	}
591}
592
593func TestRemoteDelivery_REQUIRETLS_Relaxed_TLSFail(t *testing.T) {
594	clientCfg, be, srv := testutils.SMTPServerSTARTTLS(t, "127.0.0.1:"+smtpPort)
595	srv.EnableREQUIRETLS = false /* no REQUIRETLS */
596	defer srv.Close()
597	defer testutils.CheckSMTPConnLeak(t, srv)
598	zones := map[string]mockdns.Zone{
599		"example.invalid.": {
600			MX: []net.MX{{Host: "mx.example.invalid.", Pref: 10}},
601		},
602		"mx.example.invalid.": {
603			A: []string{"127.0.0.1"},
604		},
605	}
606
607	mtastsGet := func(_ context.Context, domain string) (*mtasts.Policy, error) {
608		if domain != "example.invalid" {
609			return nil, errors.New("Wrong domain in lookup")
610		}
611
612		return &mtasts.Policy{
613			// Testing policy is enough.
614			Mode: mtasts.ModeTesting,
615			MX:   []string{"mx.example.invalid"},
616		}, nil
617	}
618
619	tgt := testTarget(t, zones, nil, []module.MXAuthPolicy{
620		testSTSPolicy(t, zones, mtastsGet),
621	})
622	tgt.relaxedREQUIRETLS = true
623	// Cause failure through version incompatibility.
624	clientCfg.MaxVersion = tls.VersionTLS12
625	clientCfg.MinVersion = tls.VersionTLS12
626	srv.TLSConfig.MinVersion = tls.VersionTLS11
627	srv.TLSConfig.MaxVersion = tls.VersionTLS11
628	tgt.tlsConfig = clientCfg
629	defer tgt.Close()
630
631	if _, err := testutils.DoTestDeliveryErrMeta(t, tgt, "test@example.com", []string{"test@example.invalid"}, &module.MsgMetadata{
632		OriginalFrom: "test@example.com",
633		SMTPOpts: smtp.MailOptions{
634			RequireTLS: true,
635		},
636	}); err == nil {
637		t.Error("Expected an error, got none")
638	}
639	if be.MailFromCounter != 0 {
640		t.Fatal("MAIL FROM issued for server failing authentication")
641	}
642}