package smtp
import (
+ "crypto/tls"
"fmt"
"net"
"net/mail"
type testServer struct {
EmptyServerCallbacks
blockList []string
+ tlsConfig *tls.Config
}
func (s *testServer) Name() string {
return "Test-Server"
}
+func (s *testServer) TLSConfig() *tls.Config {
+ return s.tlsConfig
+}
+
func (s *testServer) VerifyAddress(addr mail.Address) ReplyLine {
for _, block := range s.blockList {
if strings.ToLower(block) == addr.Address {
}
}
+
+func getTLSConfig(t *testing.T) *tls.Config {
+ cert, err := tls.LoadX509KeyPair("../testtls/domain.crt", "../testtls/domain.key")
+ if err != nil {
+ t.Fatal(err)
+ return nil
+ }
+ return &tls.Config{
+ ServerName: "localhost",
+ Certificates: []tls.Certificate{cert},
+ InsecureSkipVerify: true,
+ }
+}
+
+func TestTLS(t *testing.T) {
+ l := runServer(t, &testServer{tlsConfig: getTLSConfig(t)})
+ defer l.Close()
+
+ nc, err := net.Dial(l.Addr().Network(), l.Addr().String())
+ ok(t, err)
+
+ conn := textproto.NewConn(nc)
+ readCodeLine(t, conn, 220)
+
+ ok(t, conn.PrintfLine("EHLO test-tls"))
+ _, resp, err := conn.ReadResponse(250)
+ ok(t, err)
+ if !strings.Contains(resp, "STARTTLS\n") {
+ t.Errorf("STARTTLS not advertised")
+ }
+
+ ok(t, conn.PrintfLine("STARTTLS"))
+ readCodeLine(t, conn, 220)
+
+ tc := tls.Client(nc, getTLSConfig(t))
+ err = tc.Handshake()
+ ok(t, err)
+
+ conn = textproto.NewConn(tc)
+
+ ok(t, conn.PrintfLine("EHLO test-tls-started"))
+ _, resp, err = conn.ReadResponse(250)
+ ok(t, err)
+ if strings.Contains(resp, "STARTTLS\n") {
+ t.Errorf("STARTTLS advertised when already started")
+ }
+}
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIID0DCCArigAwIBAgIJAKKsGKE6sUkAMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNV
+BAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazEYMBYGA1UEChMPVEVTVCBNQUlMUE9Q
+Qk9YMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTgwOTA2MDAzOTQxWhcNMTgxMDA2
+MDAzOTQxWjBOMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxGDAWBgNV
+BAoTD1RFU1QgTUFJTFBPUEJPWDESMBAGA1UEAxMJbG9jYWxob3N0MIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqRckvnfo5MdbIWZHLP+g1wDrBLC3LS3M
+9JFumGXXe19Ooy9a+WvBK3tnFfEhpMIKJ3iphgPlf3fU8W96kuE3o6rPRUzpv6FU
+z+w1FTBiOd1FfUmKwULdjmMFFdl2nYzjp4le9yfaUDNdu8bj9Wk2tL6sBaO6gkHr
+thJiPPtCv19YxGPG5FZIDnlDwLkwuaUxQCTgZ7BZ0qM036gmXJ6gYd1Scgz5iSHC
+Pfj9v1dEOPowA9MRrDa9sQdjrFCq2vgdsdsVdVfoWhHeQfd6PCFUTy06xDHfGnor
+/+wAklbnIVCnVbyQeQHpPkQjlzcVMZkHnxwfG4CJ/WgF+inzQ0hNTQIDAQABo4Gw
+MIGtMB0GA1UdDgQWBBSqQHNqsbIav6Q0SYwla379Q19YsjB+BgNVHSMEdzB1gBSq
+QHNqsbIav6Q0SYwla379Q19YsqFSpFAwTjELMAkGA1UEBhMCVVMxETAPBgNVBAgT
+CE5ldyBZb3JrMRgwFgYDVQQKEw9URVNUIE1BSUxQT1BCT1gxEjAQBgNVBAMTCWxv
+Y2FsaG9zdIIJAKKsGKE6sUkAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
+ggEBAJeT2v5N+i15zlEeOVSsuvV/aGe068K5e+FE1qOnkmBsvqN2/BmWT5oeJuNc
+AT0ZyKI1vR5/Enq1Fta5xSNWLVeFQwm4DYEFxJ21SGWnY6+hl213nr7x0pmLG3tT
+YFq9/A+4iG5LQuDroQOC2TAqZFMTpdgLQgFZYKJvI4rk6/QrcI2pdMdwpAIJgMgd
+USV/MHoj30ll17cAukHnaZGKxkkZu0BKhadOEkB7p4zSZsVFWJfGsi5Pf3+LFmyE
+dkxewA5SVD7KwVkZ+wSkxEBuaIYAArbuxc9aT2u4H3+fxVrd2UnuDeq0nv0lMZN/
+eAHjIwvvWme+6AxRhIA5z5eTpcA=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAqRckvnfo5MdbIWZHLP+g1wDrBLC3LS3M9JFumGXXe19Ooy9a
++WvBK3tnFfEhpMIKJ3iphgPlf3fU8W96kuE3o6rPRUzpv6FUz+w1FTBiOd1FfUmK
+wULdjmMFFdl2nYzjp4le9yfaUDNdu8bj9Wk2tL6sBaO6gkHrthJiPPtCv19YxGPG
+5FZIDnlDwLkwuaUxQCTgZ7BZ0qM036gmXJ6gYd1Scgz5iSHCPfj9v1dEOPowA9MR
+rDa9sQdjrFCq2vgdsdsVdVfoWhHeQfd6PCFUTy06xDHfGnor/+wAklbnIVCnVbyQ
+eQHpPkQjlzcVMZkHnxwfG4CJ/WgF+inzQ0hNTQIDAQABAoIBAGmTocWraScvsp7w
+FZDrK6oTUKrlC/qRll8+TyeorxrBL4CEmPETbtGPg5YXsUIGRgDPPkoHNMyaLcNy
+L752ER+ID1Ld6zVTrnkEq0BHrY0js7e+q3xwG5ZEDXDPD1jgF2UMSNdZct6Qs/4C
++WLKBvZj91SuHk4mit5sLBqXZ93EzvmK6mb2OSwrtla2500Pf1CsY9VAT75z0kBi
+cLV+WYrA1Q84eNqFm4gW1wjfz9xs8+u+jRTgtI0X4HkXpDBzliIecxR8RmjPG0ET
+xykW4gfnVZoTPI1iRnCdaXhzP2oyx96/i1BUWoNQmQjki0TzOY56XgiLRpWnrD5b
+XaoHrqECgYEA0s6STz8qe5Cz96J3B4nm4yZcvsfTPm9R/L5k9dg9bPed8KcqPuT8
+KSA/1JWk8Z4XcHdO3DilvHVYgENEBBNEPKfjL5Dz9r62EEn4Xjt2pHjgSkDAEKtr
+BRKXhdTWCoT0fpx8I6yCPzCDV6IA4yfT2J7RZeuoK5hYXVaE5I1oGUcCgYEAzVcZ
+9qhR/DkStQ41wtyepZXHmkgzwqi2drb6tj+EsQfi/jHm1SX7uCkrbYgLwWMARmBO
+zS2cqEKP7Fzv1yBw0ooDxvGOqtsi7HKFsHeYWXXZCrrxiinMg1lpVjfLFchW10jY
+deiUBDGeYsu8gCe1ekOVRJrXbFpC8mxxe2ICrssCgYEAjHC8fnkZh1qe2vJslCQm
+Itxy21LrA+RL3bLGNhbKzWal3Saw+Ve6OnfWrnzHd4SYHwANFJ/UopoWzNSDYqen
+RTWgIBdUwOTLDE0LX1QENYyl+DHtAu4AjU+WjL1/n2B2NkdwWJ/b4dcjGWW/a5Yk
+B2O/I0R9NBX5gK1cOZuPZ48CgYAoVJs83wJ7T5plBU154GsoiqqRmuzPpuNvnbDQ
+atldC/eBhbuY0cUG/s8QzE/Cw/ch23iew/6o7anm+roAvtZqA8GKKZej5zaMylGH
+v3Wk3IismtsmD9+jTMRrsrmopZio4B3jyrKHwFcjgHCdmy8BvJRszRzSo0fS5YnE
+ehOc0QKBgQCGhYKMbhGNobsXnjxKQDRlrKxvWXSHtx6wgcyAPdb1iqaFe+jIEgvx
+6Vd63Jin2/kruSr8m9VSltkdXmcbLKRNff55J8dyH322Z09R8WrVkCtw8nWIWvgJ
+EVR2rG4y0S2YhzhO8bOlybZS0egg93RSye0Xd3pPyLFgAXmixgqmgw==
+-----END RSA PRIVATE KEY-----