mirror of
https://github.com/autc04/Retro68.git
synced 2025-03-02 10:30:00 +00:00
272 lines
6.8 KiB
Go
272 lines
6.8 KiB
Go
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package smtp
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"bytes"
|
||
|
"io"
|
||
|
"net"
|
||
|
"net/textproto"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type authTest struct {
|
||
|
auth Auth
|
||
|
challenges []string
|
||
|
name string
|
||
|
responses []string
|
||
|
}
|
||
|
|
||
|
var authTests = []authTest{
|
||
|
{PlainAuth("", "user", "pass", "testserver"), []string{}, "PLAIN", []string{"\x00user\x00pass"}},
|
||
|
{PlainAuth("foo", "bar", "baz", "testserver"), []string{}, "PLAIN", []string{"foo\x00bar\x00baz"}},
|
||
|
{CRAMMD5Auth("user", "pass"), []string{"<123456.1322876914@testserver>"}, "CRAM-MD5", []string{"", "user 287eb355114cf5c471c26a875f1ca4ae"}},
|
||
|
}
|
||
|
|
||
|
func TestAuth(t *testing.T) {
|
||
|
testLoop:
|
||
|
for i, test := range authTests {
|
||
|
name, resp, err := test.auth.Start(&ServerInfo{"testserver", true, nil})
|
||
|
if name != test.name {
|
||
|
t.Errorf("#%d got name %s, expected %s", i, name, test.name)
|
||
|
}
|
||
|
if !bytes.Equal(resp, []byte(test.responses[0])) {
|
||
|
t.Errorf("#%d got response %s, expected %s", i, resp, test.responses[0])
|
||
|
}
|
||
|
if err != nil {
|
||
|
t.Errorf("#%d error: %s", i, err)
|
||
|
}
|
||
|
for j := range test.challenges {
|
||
|
challenge := []byte(test.challenges[j])
|
||
|
expected := []byte(test.responses[j+1])
|
||
|
resp, err := test.auth.Next(challenge, true)
|
||
|
if err != nil {
|
||
|
t.Errorf("#%d error: %s", i, err)
|
||
|
continue testLoop
|
||
|
}
|
||
|
if !bytes.Equal(resp, expected) {
|
||
|
t.Errorf("#%d got %s, expected %s", i, resp, expected)
|
||
|
continue testLoop
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type faker struct {
|
||
|
io.ReadWriter
|
||
|
}
|
||
|
|
||
|
func (f faker) Close() error { return nil }
|
||
|
func (f faker) LocalAddr() net.Addr { return nil }
|
||
|
func (f faker) RemoteAddr() net.Addr { return nil }
|
||
|
func (f faker) SetDeadline(time.Time) error { return nil }
|
||
|
func (f faker) SetReadDeadline(time.Time) error { return nil }
|
||
|
func (f faker) SetWriteDeadline(time.Time) error { return nil }
|
||
|
|
||
|
func TestBasic(t *testing.T) {
|
||
|
basicServer = strings.Join(strings.Split(basicServer, "\n"), "\r\n")
|
||
|
basicClient = strings.Join(strings.Split(basicClient, "\n"), "\r\n")
|
||
|
|
||
|
var cmdbuf bytes.Buffer
|
||
|
bcmdbuf := bufio.NewWriter(&cmdbuf)
|
||
|
var fake faker
|
||
|
fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(basicServer)), bcmdbuf)
|
||
|
c := &Client{Text: textproto.NewConn(fake)}
|
||
|
|
||
|
if err := c.helo(); err != nil {
|
||
|
t.Fatalf("HELO failed: %s", err)
|
||
|
}
|
||
|
if err := c.ehlo(); err == nil {
|
||
|
t.Fatalf("Expected first EHLO to fail")
|
||
|
}
|
||
|
if err := c.ehlo(); err != nil {
|
||
|
t.Fatalf("Second EHLO failed: %s", err)
|
||
|
}
|
||
|
|
||
|
if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" {
|
||
|
t.Fatalf("Expected AUTH supported")
|
||
|
}
|
||
|
if ok, _ := c.Extension("DSN"); ok {
|
||
|
t.Fatalf("Shouldn't support DSN")
|
||
|
}
|
||
|
|
||
|
if err := c.Mail("user@gmail.com"); err == nil {
|
||
|
t.Fatalf("MAIL should require authentication")
|
||
|
}
|
||
|
|
||
|
if err := c.Verify("user1@gmail.com"); err == nil {
|
||
|
t.Fatalf("First VRFY: expected no verification")
|
||
|
}
|
||
|
if err := c.Verify("user2@gmail.com"); err != nil {
|
||
|
t.Fatalf("Second VRFY: expected verification, got %s", err)
|
||
|
}
|
||
|
|
||
|
// fake TLS so authentication won't complain
|
||
|
c.tls = true
|
||
|
c.serverName = "smtp.google.com"
|
||
|
if err := c.Auth(PlainAuth("", "user", "pass", "smtp.google.com")); err != nil {
|
||
|
t.Fatalf("AUTH failed: %s", err)
|
||
|
}
|
||
|
|
||
|
if err := c.Mail("user@gmail.com"); err != nil {
|
||
|
t.Fatalf("MAIL failed: %s", err)
|
||
|
}
|
||
|
if err := c.Rcpt("golang-nuts@googlegroups.com"); err != nil {
|
||
|
t.Fatalf("RCPT failed: %s", err)
|
||
|
}
|
||
|
msg := `From: user@gmail.com
|
||
|
To: golang-nuts@googlegroups.com
|
||
|
Subject: Hooray for Go
|
||
|
|
||
|
Line 1
|
||
|
.Leading dot line .
|
||
|
Goodbye.`
|
||
|
w, err := c.Data()
|
||
|
if err != nil {
|
||
|
t.Fatalf("DATA failed: %s", err)
|
||
|
}
|
||
|
if _, err := w.Write([]byte(msg)); err != nil {
|
||
|
t.Fatalf("Data write failed: %s", err)
|
||
|
}
|
||
|
if err := w.Close(); err != nil {
|
||
|
t.Fatalf("Bad data response: %s", err)
|
||
|
}
|
||
|
|
||
|
if err := c.Quit(); err != nil {
|
||
|
t.Fatalf("QUIT failed: %s", err)
|
||
|
}
|
||
|
|
||
|
bcmdbuf.Flush()
|
||
|
actualcmds := cmdbuf.String()
|
||
|
if basicClient != actualcmds {
|
||
|
t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, basicClient)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var basicServer = `250 mx.google.com at your service
|
||
|
502 Unrecognized command.
|
||
|
250-mx.google.com at your service
|
||
|
250-SIZE 35651584
|
||
|
250-AUTH LOGIN PLAIN
|
||
|
250 8BITMIME
|
||
|
530 Authentication required
|
||
|
252 Send some mail, I'll try my best
|
||
|
250 User is valid
|
||
|
235 Accepted
|
||
|
250 Sender OK
|
||
|
250 Receiver OK
|
||
|
354 Go ahead
|
||
|
250 Data OK
|
||
|
221 OK
|
||
|
`
|
||
|
|
||
|
var basicClient = `HELO localhost
|
||
|
EHLO localhost
|
||
|
EHLO localhost
|
||
|
MAIL FROM:<user@gmail.com> BODY=8BITMIME
|
||
|
VRFY user1@gmail.com
|
||
|
VRFY user2@gmail.com
|
||
|
AUTH PLAIN AHVzZXIAcGFzcw==
|
||
|
MAIL FROM:<user@gmail.com> BODY=8BITMIME
|
||
|
RCPT TO:<golang-nuts@googlegroups.com>
|
||
|
DATA
|
||
|
From: user@gmail.com
|
||
|
To: golang-nuts@googlegroups.com
|
||
|
Subject: Hooray for Go
|
||
|
|
||
|
Line 1
|
||
|
..Leading dot line .
|
||
|
Goodbye.
|
||
|
.
|
||
|
QUIT
|
||
|
`
|
||
|
|
||
|
func TestNewClient(t *testing.T) {
|
||
|
newClientServer = strings.Join(strings.Split(newClientServer, "\n"), "\r\n")
|
||
|
newClientClient = strings.Join(strings.Split(newClientClient, "\n"), "\r\n")
|
||
|
|
||
|
var cmdbuf bytes.Buffer
|
||
|
bcmdbuf := bufio.NewWriter(&cmdbuf)
|
||
|
out := func() string {
|
||
|
bcmdbuf.Flush()
|
||
|
return cmdbuf.String()
|
||
|
}
|
||
|
var fake faker
|
||
|
fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(newClientServer)), bcmdbuf)
|
||
|
c, err := NewClient(fake, "fake.host")
|
||
|
if err != nil {
|
||
|
t.Fatalf("NewClient: %v\n(after %v)", err, out())
|
||
|
}
|
||
|
if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" {
|
||
|
t.Fatalf("Expected AUTH supported")
|
||
|
}
|
||
|
if ok, _ := c.Extension("DSN"); ok {
|
||
|
t.Fatalf("Shouldn't support DSN")
|
||
|
}
|
||
|
if err := c.Quit(); err != nil {
|
||
|
t.Fatalf("QUIT failed: %s", err)
|
||
|
}
|
||
|
|
||
|
actualcmds := out()
|
||
|
if newClientClient != actualcmds {
|
||
|
t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, newClientClient)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var newClientServer = `220 hello world
|
||
|
250-mx.google.com at your service
|
||
|
250-SIZE 35651584
|
||
|
250-AUTH LOGIN PLAIN
|
||
|
250 8BITMIME
|
||
|
221 OK
|
||
|
`
|
||
|
|
||
|
var newClientClient = `EHLO localhost
|
||
|
QUIT
|
||
|
`
|
||
|
|
||
|
func TestNewClient2(t *testing.T) {
|
||
|
newClient2Server = strings.Join(strings.Split(newClient2Server, "\n"), "\r\n")
|
||
|
newClient2Client = strings.Join(strings.Split(newClient2Client, "\n"), "\r\n")
|
||
|
|
||
|
var cmdbuf bytes.Buffer
|
||
|
bcmdbuf := bufio.NewWriter(&cmdbuf)
|
||
|
var fake faker
|
||
|
fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(newClient2Server)), bcmdbuf)
|
||
|
c, err := NewClient(fake, "fake.host")
|
||
|
if err != nil {
|
||
|
t.Fatalf("NewClient: %v", err)
|
||
|
}
|
||
|
if ok, _ := c.Extension("DSN"); ok {
|
||
|
t.Fatalf("Shouldn't support DSN")
|
||
|
}
|
||
|
if err := c.Quit(); err != nil {
|
||
|
t.Fatalf("QUIT failed: %s", err)
|
||
|
}
|
||
|
|
||
|
bcmdbuf.Flush()
|
||
|
actualcmds := cmdbuf.String()
|
||
|
if newClient2Client != actualcmds {
|
||
|
t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, newClient2Client)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var newClient2Server = `220 hello world
|
||
|
502 EH?
|
||
|
250-mx.google.com at your service
|
||
|
250-SIZE 35651584
|
||
|
250-AUTH LOGIN PLAIN
|
||
|
250 8BITMIME
|
||
|
221 OK
|
||
|
`
|
||
|
|
||
|
var newClient2Client = `EHLO localhost
|
||
|
HELO localhost
|
||
|
QUIT
|
||
|
`
|