mirror of
https://github.com/wneessen/go-mail.git
synced 2024-11-15 02:12:55 +01:00
Add extensive client tests for Mail, Verify, and Auth commands
Introduce new tests for the SMTP client covering scenarios for Mail, Verify, and Auth commands to ensure correct behavior under various conditions. Updated `simpleSMTPServer` implementation to handle more cases including VRFY and SMTPUTF8.
This commit is contained in:
parent
b7ffce62aa
commit
0df228178a
1 changed files with 436 additions and 58 deletions
|
@ -1867,44 +1867,408 @@ func TestClient_TLSConnectionState(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue 17794: don't send a trailing space on AUTH command when there's no password.
|
func TestClient_Verify(t *testing.T) {
|
||||||
func TestClient_Auth_trimSpace(t *testing.T) {
|
t.Run("Verify on existing user succeeds", func(t *testing.T) {
|
||||||
server := "220 hello world\r\n" +
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
"200 some more"
|
defer cancel()
|
||||||
var wrote strings.Builder
|
PortAdder.Add(1)
|
||||||
var fake faker
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
fake.ReadWriter = struct {
|
featureSet := "250-STARTTLS\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
io.Reader
|
go func() {
|
||||||
io.Writer
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
}{
|
FeatureSet: featureSet,
|
||||||
strings.NewReader(server),
|
ListenPort: serverPort,
|
||||||
&wrote,
|
},
|
||||||
}
|
); err != nil {
|
||||||
c, err := NewClient(fake, "fake.host")
|
t.Errorf("failed to start test server: %s", err)
|
||||||
if err != nil {
|
return
|
||||||
t.Fatalf("NewClient: %v", err)
|
}
|
||||||
}
|
}()
|
||||||
c.tls = true
|
time.Sleep(time.Millisecond * 30)
|
||||||
c.didHello = true
|
|
||||||
_ = c.Auth(toServerEmptyAuth{})
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
if err = c.Close(); err != nil {
|
if err != nil {
|
||||||
t.Errorf("close failed: %s", err)
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
}
|
}
|
||||||
if got, want := wrote.String(), "AUTH FOOAUTH\r\n*\r\nQUIT\r\n"; got != want {
|
t.Cleanup(func() {
|
||||||
t.Errorf("wrote %q; want %q", got, want)
|
if err = client.Close(); err != nil {
|
||||||
}
|
t.Errorf("failed to close client: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err = client.Verify("toni.tester@example.com"); err != nil {
|
||||||
|
t.Errorf("failed to verify user: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("Verify on non-existing user fails", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250-STARTTLS\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
VRFYUserUnknown: true,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err = client.Close(); err != nil {
|
||||||
|
t.Errorf("failed to close client: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err = client.Verify("toni.tester@example.com"); err == nil {
|
||||||
|
t.Error("verify on non-existing user should fail")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("Verify with newlines should fails", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250-STARTTLS\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err = client.Close(); err != nil {
|
||||||
|
t.Errorf("failed to close client: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err = client.Verify("toni.tester@example.com\r\n"); err == nil {
|
||||||
|
t.Error("verify with new lines should fail")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("Verify should fail on HELO/EHLO", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250-STARTTLS\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FailOnEhlo: true,
|
||||||
|
FailOnHelo: true,
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err = client.Close(); err != nil {
|
||||||
|
t.Errorf("failed to close client: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if err = client.Verify("toni.tester@example.com"); err == nil {
|
||||||
|
t.Error("verify with new lines should fail")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_Auth(t *testing.T) {
|
||||||
|
t.Run("Auth fails on EHLO/HELO", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250-STARTTLS\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FailOnEhlo: true,
|
||||||
|
FailOnHelo: true,
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
auth := LoginAuth("username", "password", TestServerAddr, false)
|
||||||
|
if err = client.Auth(auth); err == nil {
|
||||||
|
t.Error("auth should fail on EHLO/HELO")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("Auth fails on auth-start", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250-STARTTLS\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FailOnAuth: true,
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
auth := LoginAuth("username", "password", "not.localhost.com", false)
|
||||||
|
if err = client.Auth(auth); err == nil {
|
||||||
|
t.Error("auth should fail on auth-start, then on quit")
|
||||||
|
}
|
||||||
|
expErr := "wrong host name"
|
||||||
|
if !strings.EqualFold(expErr, err.Error()) {
|
||||||
|
t.Errorf("expected error: %q, got: %q", expErr, err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("Auth fails on auth-start and then on quit", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250-STARTTLS\r\n250-8BITMIME\r\n250-DSN\r\n250 SMTPUTF8"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FailOnAuth: true,
|
||||||
|
FailOnQuit: true,
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
auth := LoginAuth("username", "password", "not.localhost.com", false)
|
||||||
|
if err = client.Auth(auth); err == nil {
|
||||||
|
t.Error("auth should fail on auth-start, then on quit")
|
||||||
|
}
|
||||||
|
expErr := "wrong host name, 500 5.1.2 Error: quit failed"
|
||||||
|
if !strings.EqualFold(expErr, err.Error()) {
|
||||||
|
t.Errorf("expected error: %q, got: %q", expErr, err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Issue 17794: don't send a trailing space on AUTH command when there's no password.
|
||||||
|
t.Run("No trailing space on AUTH when there is no password (Issue 17794)", func(t *testing.T) {
|
||||||
|
server := "220 hello world\r\n" +
|
||||||
|
"200 some more"
|
||||||
|
var wrote strings.Builder
|
||||||
|
var fake faker
|
||||||
|
fake.ReadWriter = struct {
|
||||||
|
io.Reader
|
||||||
|
io.Writer
|
||||||
|
}{
|
||||||
|
strings.NewReader(server),
|
||||||
|
&wrote,
|
||||||
|
}
|
||||||
|
c, err := NewClient(fake, "fake.host")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("NewClient: %v", err)
|
||||||
|
}
|
||||||
|
c.tls = true
|
||||||
|
c.didHello = true
|
||||||
|
_ = c.Auth(toServerEmptyAuth{})
|
||||||
|
if err = c.Close(); err != nil {
|
||||||
|
t.Errorf("close failed: %s", err)
|
||||||
|
}
|
||||||
|
if got, want := wrote.String(), "AUTH FOOAUTH\r\n*\r\nQUIT\r\n"; got != want {
|
||||||
|
t.Errorf("wrote %q; want %q", got, want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClient_Mail(t *testing.T) {
|
||||||
|
t.Run("normal from address succeeds", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250 STARTTLS"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
if err = client.Mail("valid-from@domain.tld"); err != nil {
|
||||||
|
t.Errorf("failed to set mail from address: %s", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("from address with new lines fails", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250 STARTTLS"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
if err = client.Mail("valid-from@domain.tld\r\n"); err == nil {
|
||||||
|
t.Error("mail from address with new lines should fail")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("from address fails on EHLO/HELO", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250 STARTTLS"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
FailOnEhlo: true,
|
||||||
|
FailOnHelo: true,
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
if err = client.Mail("valid-from@domain.tld"); err == nil {
|
||||||
|
t.Error("mail from address should fail on EHLO/HELO")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("from address and server supports 8BITMIME", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250-8BITMIME\r\n250 STARTTLS"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
EchoCommandAsError: "MAIL FROM:",
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
if err = client.Mail("valid-from@domain.tld"); err == nil {
|
||||||
|
t.Error("server should echo the command as error but didn't")
|
||||||
|
}
|
||||||
|
sent := strings.Replace(err.Error(), "500 ", "", -1)
|
||||||
|
expected := "MAIL FROM:<valid-from@domain.tld> BODY=8BITMIME"
|
||||||
|
if !strings.EqualFold(sent, expected) {
|
||||||
|
t.Errorf("expected mail from command to be %q, but sent %q", expected, sent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
t.Run("from address and server supports SMTPUTF8", func(t *testing.T) {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
PortAdder.Add(1)
|
||||||
|
serverPort := int(TestServerPortBase + PortAdder.Load())
|
||||||
|
featureSet := "250-SMTPUTF8\r\n250 STARTTLS"
|
||||||
|
go func() {
|
||||||
|
if err := simpleSMTPServer(ctx, t, &serverProps{
|
||||||
|
EchoCommandAsError: "MAIL FROM:",
|
||||||
|
FeatureSet: featureSet,
|
||||||
|
ListenPort: serverPort,
|
||||||
|
},
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to start test server: %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
time.Sleep(time.Millisecond * 30)
|
||||||
|
|
||||||
|
client, err := Dial(fmt.Sprintf("%s:%d", TestServerAddr, serverPort))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to dial to test server: %s", err)
|
||||||
|
}
|
||||||
|
if err = client.Mail("valid-from@domain.tld"); err == nil {
|
||||||
|
t.Error("server should echo the command as error but didn't")
|
||||||
|
}
|
||||||
|
sent := strings.Replace(err.Error(), "500 ", "", -1)
|
||||||
|
expected := "MAIL FROM:<valid-from@domain.tld> SMTPUTF8"
|
||||||
|
if !strings.EqualFold(sent, expected) {
|
||||||
|
t.Errorf("expected mail from command to be %q, but sent %q", expected, sent)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func TestBasic(t *testing.T) {
|
func TestBasic(t *testing.T) {
|
||||||
server := strings.Join(strings.Split(basicServer, "\n"), "\r\n")
|
server := strings.Join(strings.Split(basicServer, "\n"), "\r\n")
|
||||||
client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
|
client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
|
||||||
|
@ -3422,26 +3786,28 @@ func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "
|
||||||
|
|
||||||
// serverProps represents the configuration properties for the SMTP server.
|
// serverProps represents the configuration properties for the SMTP server.
|
||||||
type serverProps struct {
|
type serverProps struct {
|
||||||
FailOnAuth bool
|
EchoCommandAsError string
|
||||||
FailOnDataInit bool
|
FailOnAuth bool
|
||||||
FailOnDataClose bool
|
FailOnDataInit bool
|
||||||
FailOnDial bool
|
FailOnDataClose bool
|
||||||
FailOnEhlo bool
|
FailOnDial bool
|
||||||
FailOnHelo bool
|
FailOnEhlo bool
|
||||||
FailOnMailFrom bool
|
FailOnHelo bool
|
||||||
FailOnNoop bool
|
FailOnMailFrom bool
|
||||||
FailOnQuit bool
|
FailOnNoop bool
|
||||||
FailOnReset bool
|
FailOnQuit bool
|
||||||
FailOnSTARTTLS bool
|
FailOnReset bool
|
||||||
FailTemp bool
|
FailOnSTARTTLS bool
|
||||||
FeatureSet string
|
FailTemp bool
|
||||||
ListenPort int
|
FeatureSet string
|
||||||
SSLListener bool
|
ListenPort int
|
||||||
IsSCRAMPlus bool
|
HashFunc func() hash.Hash
|
||||||
IsTLS bool
|
IsSCRAMPlus bool
|
||||||
SupportDSN bool
|
IsTLS bool
|
||||||
TestSCRAM bool
|
SupportDSN bool
|
||||||
HashFunc func() hash.Hash
|
SSLListener bool
|
||||||
|
TestSCRAM bool
|
||||||
|
VRFYUserUnknown bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// simpleSMTPServer starts a simple TCP server that resonds to SMTP commands.
|
// simpleSMTPServer starts a simple TCP server that resonds to SMTP commands.
|
||||||
|
@ -3540,6 +3906,9 @@ func handleTestServerConnection(connection net.Conn, t *testing.T, props *server
|
||||||
var datastring string
|
var datastring string
|
||||||
data = strings.TrimSpace(data)
|
data = strings.TrimSpace(data)
|
||||||
switch {
|
switch {
|
||||||
|
case props.EchoCommandAsError != "" && strings.HasPrefix(data, props.EchoCommandAsError):
|
||||||
|
writeLine("500 " + data)
|
||||||
|
break
|
||||||
case strings.HasPrefix(data, "HELO"):
|
case strings.HasPrefix(data, "HELO"):
|
||||||
if len(strings.Split(data, " ")) != 2 {
|
if len(strings.Split(data, " ")) != 2 {
|
||||||
writeLine("501 Syntax: HELO hostname")
|
writeLine("501 Syntax: HELO hostname")
|
||||||
|
@ -3643,8 +4012,17 @@ func handleTestServerConnection(connection net.Conn, t *testing.T, props *server
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
writeOK()
|
writeOK()
|
||||||
case strings.EqualFold(data, "vrfy"):
|
case strings.HasPrefix(data, "VRFY"):
|
||||||
writeOK()
|
if props.VRFYUserUnknown {
|
||||||
|
writeLine("550 5.1.1 User unknown")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
parts := strings.SplitN(data, " ", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
writeLine("500 5.0.0 Error: invalid syntax for VRFY")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
writeLine(fmt.Sprintf("250 2.0.0 Ok: %s OK", parts[1]))
|
||||||
case strings.EqualFold(data, "rset"):
|
case strings.EqualFold(data, "rset"):
|
||||||
if props.FailOnReset {
|
if props.FailOnReset {
|
||||||
writeLine("500 5.1.2 Error: reset failed")
|
writeLine("500 5.1.2 Error: reset failed")
|
||||||
|
@ -3674,7 +4052,7 @@ func handleTestServerConnection(connection net.Conn, t *testing.T, props *server
|
||||||
props.IsTLS = true
|
props.IsTLS = true
|
||||||
handleTestServerConnection(connection, t, props)
|
handleTestServerConnection(connection, t, props)
|
||||||
default:
|
default:
|
||||||
writeLine("500 5.5.2 Error: bad syntax")
|
writeLine("500 5.5.2 Error: bad syntax - " + data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue