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 smtp_downstream
 20
 21import (
 22	"testing"
 23
 24	"github.com/emersion/go-smtp"
 25	"github.com/foxcpp/maddy/framework/config"
 26	"github.com/foxcpp/maddy/framework/module"
 27	"github.com/foxcpp/maddy/internal/testutils"
 28)
 29
 30func testSaslFactory(t *testing.T, args ...string) saslClientFactory {
 31	factory, err := saslAuthDirective(&config.Map{}, config.Node{
 32		Name: "auth",
 33		Args: args,
 34	})
 35	if err != nil {
 36		t.Fatal(err)
 37	}
 38	return factory.(saslClientFactory)
 39}
 40
 41func TestSASL_Plain(t *testing.T) {
 42	be, srv := testutils.SMTPServer(t, "127.0.0.1:"+testPort)
 43	defer srv.Close()
 44	defer testutils.CheckSMTPConnLeak(t, srv)
 45
 46	mod := &Downstream{
 47		hostname: "mx.example.invalid",
 48		endpoints: []config.Endpoint{
 49			{
 50				Scheme: "tcp",
 51				Host:   "127.0.0.1",
 52				Port:   testPort,
 53			},
 54		},
 55		saslFactory: testSaslFactory(t, "plain", "test", "testpass"),
 56		log:         testutils.Logger(t, "target.smtp"),
 57	}
 58
 59	testutils.DoTestDelivery(t, mod, "test@example.invalid", []string{"rcpt@example.invalid"})
 60	be.CheckMsg(t, 0, "test@example.invalid", []string{"rcpt@example.invalid"})
 61	if be.Messages[0].AuthUser != "test" {
 62		t.Errorf("Wrong AuthUser: %v", be.Messages[0].AuthUser)
 63	}
 64	if be.Messages[0].AuthPass != "testpass" {
 65		t.Errorf("Wrong AuthPass: %v", be.Messages[0].AuthPass)
 66	}
 67}
 68
 69func TestSASL_Plain_AuthFail(t *testing.T) {
 70	be, srv := testutils.SMTPServer(t, "127.0.0.1:"+testPort)
 71	defer srv.Close()
 72	defer testutils.CheckSMTPConnLeak(t, srv)
 73
 74	be.AuthErr = &smtp.SMTPError{
 75		Code:         550,
 76		EnhancedCode: smtp.EnhancedCode{5, 1, 2},
 77		Message:      "Hey",
 78	}
 79
 80	mod := &Downstream{
 81		hostname: "mx.example.invalid",
 82		endpoints: []config.Endpoint{
 83			{
 84				Scheme: "tcp",
 85				Host:   "127.0.0.1",
 86				Port:   testPort,
 87			},
 88		},
 89		saslFactory: testSaslFactory(t, "plain", "test", "testpass"),
 90		log:         testutils.Logger(t, "target.smtp"),
 91	}
 92
 93	_, err := testutils.DoTestDeliveryErr(t, mod, "test@example.invalid", []string{"rcpt@example.invalid"})
 94	if err == nil {
 95		t.Error("Expected an error, got none")
 96	}
 97}
 98
 99func TestSASL_Forward(t *testing.T) {
100	be, srv := testutils.SMTPServer(t, "127.0.0.1:"+testPort)
101	defer srv.Close()
102	defer testutils.CheckSMTPConnLeak(t, srv)
103
104	mod := &Downstream{
105		hostname: "mx.example.invalid",
106		endpoints: []config.Endpoint{
107			{
108				Scheme: "tcp",
109				Host:   "127.0.0.1",
110				Port:   testPort,
111			},
112		},
113		saslFactory: testSaslFactory(t, "forward"),
114		log:         testutils.Logger(t, "target.smtp"),
115	}
116
117	testutils.DoTestDeliveryMeta(t, mod, "test@example.invalid", []string{"rcpt@example.invalid"}, &module.MsgMetadata{
118		Conn: &module.ConnState{
119			AuthUser:     "test",
120			AuthPassword: "testpass",
121		},
122	})
123	be.CheckMsg(t, 0, "test@example.invalid", []string{"rcpt@example.invalid"})
124	if be.Messages[0].AuthUser != "test" {
125		t.Errorf("Wrong AuthUser: %v", be.Messages[0].AuthUser)
126	}
127	if be.Messages[0].AuthPass != "testpass" {
128		t.Errorf("Wrong AuthPass: %v", be.Messages[0].AuthPass)
129	}
130}
131
132func TestSASL_Forward_NoCreds(t *testing.T) {
133	_, srv := testutils.SMTPServer(t, "127.0.0.1:"+testPort)
134	defer srv.Close()
135	defer testutils.CheckSMTPConnLeak(t, srv)
136
137	mod := &Downstream{
138		hostname: "mx.example.invalid",
139		endpoints: []config.Endpoint{
140			{
141				Scheme: "tcp",
142				Host:   "127.0.0.1",
143				Port:   testPort,
144			},
145		},
146		saslFactory: testSaslFactory(t, "forward"),
147		log:         testutils.Logger(t, "target.smtp"),
148	}
149
150	_, err := testutils.DoTestDeliveryErr(t, mod, "test@example.invalid", []string{"rcpt@example.invalid"})
151	if err == nil {
152		t.Error("Expected an error, got none")
153	}
154}