1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
23 type authTest
struct {
30 var authTests
= []authTest
{
31 {PlainAuth("", "user", "pass", "testserver"), []string{}, "PLAIN", []string{"\x00user\x00pass"}},
32 {PlainAuth("foo", "bar", "baz", "testserver"), []string{}, "PLAIN", []string{"foo\x00bar\x00baz"}},
33 {CRAMMD5Auth("user", "pass"), []string{"<123456.1322876914@testserver>"}, "CRAM-MD5", []string{"", "user 287eb355114cf5c471c26a875f1ca4ae"}},
36 func TestAuth(t
*testing
.T
) {
38 for i
, test
:= range authTests
{
39 name
, resp
, err
:= test
.auth
.Start(&ServerInfo
{"testserver", true, nil})
40 if name
!= test
.name
{
41 t
.Errorf("#%d got name %s, expected %s", i
, name
, test
.name
)
43 if !bytes
.Equal(resp
, []byte(test
.responses
[0])) {
44 t
.Errorf("#%d got response %s, expected %s", i
, resp
, test
.responses
[0])
47 t
.Errorf("#%d error: %s", i
, err
)
49 for j
:= range test
.challenges
{
50 challenge
:= []byte(test
.challenges
[j
])
51 expected
:= []byte(test
.responses
[j
+1])
52 resp
, err
:= test
.auth
.Next(challenge
, true)
54 t
.Errorf("#%d error: %s", i
, err
)
57 if !bytes
.Equal(resp
, expected
) {
58 t
.Errorf("#%d got %s, expected %s", i
, resp
, expected
)
65 func TestAuthPlain(t
*testing
.T
) {
73 authName
: "servername",
74 server
: &ServerInfo
{Name
: "servername", TLS
: true},
77 // OK to use PlainAuth on localhost without TLS
78 authName
: "localhost",
79 server
: &ServerInfo
{Name
: "localhost", TLS
: false},
82 // NOT OK on non-localhost, even if server says PLAIN is OK.
83 // (We don't know that the server is the real server.)
84 authName
: "servername",
85 server
: &ServerInfo
{Name
: "servername", Auth
: []string{"PLAIN"}},
86 err
: "unencrypted connection",
89 authName
: "servername",
90 server
: &ServerInfo
{Name
: "servername", Auth
: []string{"CRAM-MD5"}},
91 err
: "unencrypted connection",
94 authName
: "servername",
95 server
: &ServerInfo
{Name
: "attacker", TLS
: true},
96 err
: "wrong host name",
99 for i
, tt
:= range tests
{
100 auth
:= PlainAuth("foo", "bar", "baz", tt
.authName
)
101 _
, _
, err
:= auth
.Start(tt
.server
)
107 t
.Errorf("%d. got error = %q; want %q", i
, got
, tt
.err
)
112 // Issue 17794: don't send a trailing space on AUTH command when there's no password.
113 func TestClientAuthTrimSpace(t
*testing
.T
) {
114 server
:= "220 hello world\r\n" +
116 var wrote bytes
.Buffer
118 fake
.ReadWriter
= struct {
122 strings
.NewReader(server
),
125 c
, err
:= NewClient(fake
, "fake.host")
127 t
.Fatalf("NewClient: %v", err
)
131 c
.Auth(toServerEmptyAuth
{})
133 if got
, want
:= wrote
.String(), "AUTH FOOAUTH\r\n*\r\nQUIT\r\n"; got
!= want
{
134 t
.Errorf("wrote %q; want %q", got
, want
)
138 // toServerEmptyAuth is an implementation of Auth that only implements
139 // the Start method, and returns "FOOAUTH", nil, nil. Notably, it returns
140 // zero bytes for "toServer" so we can test that we don't send spaces at
141 // the end of the line. See TestClientAuthTrimSpace.
142 type toServerEmptyAuth
struct{}
144 func (toServerEmptyAuth
) Start(server
*ServerInfo
) (proto
string, toServer
[]byte, err error
) {
145 return "FOOAUTH", nil, nil
148 func (toServerEmptyAuth
) Next(fromServer
[]byte, more
bool) (toServer
[]byte, err error
) {
149 panic("unexpected call")
156 func (f faker
) Close() error
{ return nil }
157 func (f faker
) LocalAddr() net
.Addr
{ return nil }
158 func (f faker
) RemoteAddr() net
.Addr
{ return nil }
159 func (f faker
) SetDeadline(time
.Time
) error
{ return nil }
160 func (f faker
) SetReadDeadline(time
.Time
) error
{ return nil }
161 func (f faker
) SetWriteDeadline(time
.Time
) error
{ return nil }
163 func TestBasic(t
*testing
.T
) {
164 server
:= strings
.Join(strings
.Split(basicServer
, "\n"), "\r\n")
165 client
:= strings
.Join(strings
.Split(basicClient
, "\n"), "\r\n")
167 var cmdbuf bytes
.Buffer
168 bcmdbuf
:= bufio
.NewWriter(&cmdbuf
)
170 fake
.ReadWriter
= bufio
.NewReadWriter(bufio
.NewReader(strings
.NewReader(server
)), bcmdbuf
)
171 c
:= &Client
{Text
: textproto
.NewConn(fake
), localName
: "localhost"}
173 if err
:= c
.helo(); err
!= nil {
174 t
.Fatalf("HELO failed: %s", err
)
176 if err
:= c
.ehlo(); err
== nil {
177 t
.Fatalf("Expected first EHLO to fail")
179 if err
:= c
.ehlo(); err
!= nil {
180 t
.Fatalf("Second EHLO failed: %s", err
)
184 if ok
, args
:= c
.Extension("aUtH"); !ok || args
!= "LOGIN PLAIN" {
185 t
.Fatalf("Expected AUTH supported")
187 if ok
, _
:= c
.Extension("DSN"); ok
{
188 t
.Fatalf("Shouldn't support DSN")
191 if err
:= c
.Mail("user@gmail.com"); err
== nil {
192 t
.Fatalf("MAIL should require authentication")
195 if err
:= c
.Verify("user1@gmail.com"); err
== nil {
196 t
.Fatalf("First VRFY: expected no verification")
198 if err
:= c
.Verify("user2@gmail.com>\r\nDATA\r\nAnother injected message body\r\n.\r\nQUIT\r\n"); err
== nil {
199 t
.Fatalf("VRFY should have failed due to a message injection attempt")
201 if err
:= c
.Verify("user2@gmail.com"); err
!= nil {
202 t
.Fatalf("Second VRFY: expected verification, got %s", err
)
205 // fake TLS so authentication won't complain
207 c
.serverName
= "smtp.google.com"
208 if err
:= c
.Auth(PlainAuth("", "user", "pass", "smtp.google.com")); err
!= nil {
209 t
.Fatalf("AUTH failed: %s", err
)
212 if err
:= c
.Rcpt("golang-nuts@googlegroups.com>\r\nDATA\r\nInjected message body\r\n.\r\nQUIT\r\n"); err
== nil {
213 t
.Fatalf("RCPT should have failed due to a message injection attempt")
215 if err
:= c
.Mail("user@gmail.com>\r\nDATA\r\nAnother injected message body\r\n.\r\nQUIT\r\n"); err
== nil {
216 t
.Fatalf("MAIL should have failed due to a message injection attempt")
218 if err
:= c
.Mail("user@gmail.com"); err
!= nil {
219 t
.Fatalf("MAIL failed: %s", err
)
221 if err
:= c
.Rcpt("golang-nuts@googlegroups.com"); err
!= nil {
222 t
.Fatalf("RCPT failed: %s", err
)
224 msg
:= `From: user@gmail.com
225 To: golang-nuts@googlegroups.com
226 Subject: Hooray for Go
233 t
.Fatalf("DATA failed: %s", err
)
235 if _
, err
:= w
.Write([]byte(msg
)); err
!= nil {
236 t
.Fatalf("Data write failed: %s", err
)
238 if err
:= w
.Close(); err
!= nil {
239 t
.Fatalf("Bad data response: %s", err
)
242 if err
:= c
.Quit(); err
!= nil {
243 t
.Fatalf("QUIT failed: %s", err
)
247 actualcmds
:= cmdbuf
.String()
248 if client
!= actualcmds
{
249 t
.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds
, client
)
253 var basicServer
= `250 mx.google.com at your service
254 502 Unrecognized command.
255 250-mx.google.com at your service
259 530 Authentication required
260 252 Send some mail, I'll try my best
270 var basicClient
= `HELO localhost
273 MAIL FROM:<user@gmail.com> BODY=8BITMIME
276 AUTH PLAIN AHVzZXIAcGFzcw==
277 MAIL FROM:<user@gmail.com> BODY=8BITMIME
278 RCPT TO:<golang-nuts@googlegroups.com>
281 To: golang-nuts@googlegroups.com
282 Subject: Hooray for Go
291 func TestNewClient(t
*testing
.T
) {
292 server
:= strings
.Join(strings
.Split(newClientServer
, "\n"), "\r\n")
293 client
:= strings
.Join(strings
.Split(newClientClient
, "\n"), "\r\n")
295 var cmdbuf bytes
.Buffer
296 bcmdbuf
:= bufio
.NewWriter(&cmdbuf
)
297 out
:= func() string {
299 return cmdbuf
.String()
302 fake
.ReadWriter
= bufio
.NewReadWriter(bufio
.NewReader(strings
.NewReader(server
)), bcmdbuf
)
303 c
, err
:= NewClient(fake
, "fake.host")
305 t
.Fatalf("NewClient: %v\n(after %v)", err
, out())
308 if ok
, args
:= c
.Extension("aUtH"); !ok || args
!= "LOGIN PLAIN" {
309 t
.Fatalf("Expected AUTH supported")
311 if ok
, _
:= c
.Extension("DSN"); ok
{
312 t
.Fatalf("Shouldn't support DSN")
314 if err
:= c
.Quit(); err
!= nil {
315 t
.Fatalf("QUIT failed: %s", err
)
319 if client
!= actualcmds
{
320 t
.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds
, client
)
324 var newClientServer
= `220 hello world
325 250-mx.google.com at your service
332 var newClientClient
= `EHLO localhost
336 func TestNewClient2(t
*testing
.T
) {
337 server
:= strings
.Join(strings
.Split(newClient2Server
, "\n"), "\r\n")
338 client
:= strings
.Join(strings
.Split(newClient2Client
, "\n"), "\r\n")
340 var cmdbuf bytes
.Buffer
341 bcmdbuf
:= bufio
.NewWriter(&cmdbuf
)
343 fake
.ReadWriter
= bufio
.NewReadWriter(bufio
.NewReader(strings
.NewReader(server
)), bcmdbuf
)
344 c
, err
:= NewClient(fake
, "fake.host")
346 t
.Fatalf("NewClient: %v", err
)
349 if ok
, _
:= c
.Extension("DSN"); ok
{
350 t
.Fatalf("Shouldn't support DSN")
352 if err
:= c
.Quit(); err
!= nil {
353 t
.Fatalf("QUIT failed: %s", err
)
357 actualcmds
:= cmdbuf
.String()
358 if client
!= actualcmds
{
359 t
.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds
, client
)
363 var newClient2Server
= `220 hello world
365 250-mx.google.com at your service
372 var newClient2Client
= `EHLO localhost
377 func TestNewClientWithTLS(t
*testing
.T
) {
378 cert
, err
:= tls
.X509KeyPair(localhostCert
, localhostKey
)
380 t
.Fatalf("loadcert: %v", err
)
383 config
:= tls
.Config
{Certificates
: []tls
.Certificate
{cert
}}
385 ln
, err
:= tls
.Listen("tcp", "127.0.0.1:0", &config
)
387 ln
, err
= tls
.Listen("tcp", "[::1]:0", &config
)
389 t
.Fatalf("server: listen: %v", err
)
394 conn
, err
:= ln
.Accept()
396 t
.Errorf("server: accept: %v", err
)
401 _
, err
= conn
.Write([]byte("220 SIGNS\r\n"))
403 t
.Errorf("server: write: %v", err
)
408 config
.InsecureSkipVerify
= true
409 conn
, err
:= tls
.Dial("tcp", ln
.Addr().String(), &config
)
411 t
.Fatalf("client: dial: %v", err
)
415 client
, err
:= NewClient(conn
, ln
.Addr().String())
417 t
.Fatalf("smtp: newclient: %v", err
)
420 t
.Errorf("client.tls Got: %t Expected: %t", client
.tls
, true)
424 func TestHello(t
*testing
.T
) {
426 if len(helloServer
) != len(helloClient
) {
427 t
.Fatalf("Hello server and client size mismatch")
430 for i
:= 0; i
< len(helloServer
); i
++ {
431 server
:= strings
.Join(strings
.Split(baseHelloServer
+helloServer
[i
], "\n"), "\r\n")
432 client
:= strings
.Join(strings
.Split(baseHelloClient
+helloClient
[i
], "\n"), "\r\n")
433 var cmdbuf bytes
.Buffer
434 bcmdbuf
:= bufio
.NewWriter(&cmdbuf
)
436 fake
.ReadWriter
= bufio
.NewReadWriter(bufio
.NewReader(strings
.NewReader(server
)), bcmdbuf
)
437 c
, err
:= NewClient(fake
, "fake.host")
439 t
.Fatalf("NewClient: %v", err
)
442 c
.localName
= "customhost"
447 err
= c
.Hello("hostinjection>\n\rDATA\r\nInjected message body\r\n.\r\nQUIT\r\n")
449 t
.Errorf("Expected Hello to be rejected due to a message injection attempt")
451 err
= c
.Hello("customhost")
453 err
= c
.StartTLS(nil)
454 if err
.Error() == "502 Not implemented" {
458 err
= c
.Verify("test@example.com")
461 c
.serverName
= "smtp.google.com"
462 err
= c
.Auth(PlainAuth("", "user", "pass", "smtp.google.com"))
464 err
= c
.Mail("test@example.com")
466 ok
, _
:= c
.Extension("feature")
468 t
.Errorf("Expected FEATURE not to be supported")
475 err
= c
.Verify("test@example.com")
477 err
= c
.Hello("customhost")
479 t
.Errorf("Want error, got none")
485 t
.Fatalf("Unhandled command")
489 t
.Errorf("Command %d failed: %v", i
, err
)
493 actualcmds
:= cmdbuf
.String()
494 if client
!= actualcmds
{
495 t
.Errorf("Got:\n%s\nExpected:\n%s", actualcmds
, client
)
500 var baseHelloServer
= `220 hello world
502 250-mx.google.com at your service
506 var helloServer
= []string{
508 "502 Not implemented\n",
509 "250 User is valid\n",
519 var baseHelloClient
= `EHLO customhost
523 var helloClient
= []string{
526 "VRFY test@example.com\n",
527 "AUTH PLAIN AHVzZXIAcGFzcw==\n",
528 "MAIL FROM:<test@example.com>\n",
532 "VRFY test@example.com\n",
536 func TestSendMail(t
*testing
.T
) {
537 server
:= strings
.Join(strings
.Split(sendMailServer
, "\n"), "\r\n")
538 client
:= strings
.Join(strings
.Split(sendMailClient
, "\n"), "\r\n")
539 var cmdbuf bytes
.Buffer
540 bcmdbuf
:= bufio
.NewWriter(&cmdbuf
)
541 l
, err
:= net
.Listen("tcp", "127.0.0.1:0")
543 t
.Fatalf("Unable to to create listener: %v", err
)
547 // prevent data race on bcmdbuf
548 var done
= make(chan struct{})
549 go func(data
[]string) {
553 conn
, err
:= l
.Accept()
555 t
.Errorf("Accept error: %v", err
)
560 tc
:= textproto
.NewConn(conn
)
561 for i
:= 0; i
< len(data
) && data
[i
] != ""; i
++ {
562 tc
.PrintfLine(data
[i
])
563 for len(data
[i
]) >= 4 && data
[i
][3] == '-' {
565 tc
.PrintfLine(data
[i
])
567 if data
[i
] == "221 Goodbye" {
571 for !read || data
[i
] == "354 Go ahead" {
572 msg
, err
:= tc
.ReadLine()
573 bcmdbuf
.Write([]byte(msg
+ "\r\n"))
576 t
.Errorf("Read error: %v", err
)
579 if data
[i
] == "354 Go ahead" && msg
== "." {
584 }(strings
.Split(server
, "\r\n"))
586 err
= SendMail(l
.Addr().String(), nil, "test@example.com", []string{"other@example.com>\n\rDATA\r\nInjected message body\r\n.\r\nQUIT\r\n"}, []byte(strings
.Replace(`From: test@example.com
587 To: other@example.com
588 Subject: SendMail test
590 SendMail is working for me.
591 `, "\n", "\r\n", -1)))
593 t
.Errorf("Expected SendMail to be rejected due to a message injection attempt")
596 err
= SendMail(l
.Addr().String(), nil, "test@example.com", []string{"other@example.com"}, []byte(strings
.Replace(`From: test@example.com
597 To: other@example.com
598 Subject: SendMail test
600 SendMail is working for me.
601 `, "\n", "\r\n", -1)))
609 actualcmds
:= cmdbuf
.String()
610 if client
!= actualcmds
{
611 t
.Errorf("Got:\n%s\nExpected:\n%s", actualcmds
, client
)
615 var sendMailServer
= `220 hello world
617 250 mx.google.com at your service
625 var sendMailClient
= `EHLO localhost
627 MAIL FROM:<test@example.com>
628 RCPT TO:<other@example.com>
630 From: test@example.com
631 To: other@example.com
632 Subject: SendMail test
634 SendMail is working for me.
639 func TestSendMailWithAuth(t
*testing
.T
) {
640 l
, err
:= net
.Listen("tcp", "127.0.0.1:0")
642 t
.Fatalf("Unable to to create listener: %v", err
)
645 wg
:= sync
.WaitGroup
{}
646 var done
= make(chan struct{})
649 conn
, err
:= l
.Accept()
651 t
.Errorf("Accept error: %v", err
)
656 tc
:= textproto
.NewConn(conn
)
657 tc
.PrintfLine("220 hello world")
658 msg
, err
:= tc
.ReadLine()
659 if msg
== "EHLO localhost" {
660 tc
.PrintfLine("250 mx.google.com at your service")
662 // for this test case, there should have no more traffic
667 err
= SendMail(l
.Addr().String(), PlainAuth("", "user", "pass", "smtp.google.com"), "test@example.com", []string{"other@example.com"}, []byte(strings
.Replace(`From: test@example.com
668 To: other@example.com
669 Subject: SendMail test
671 SendMail is working for me.
672 `, "\n", "\r\n", -1)))
674 t
.Error("SendMail: Server doesn't support AUTH, expected to get an error, but got none ")
676 if err
.Error() != "smtp: server doesn't support AUTH" {
677 t
.Errorf("Expected: smtp: server doesn't support AUTH, got: %s", err
)
683 func TestAuthFailed(t
*testing
.T
) {
684 server
:= strings
.Join(strings
.Split(authFailedServer
, "\n"), "\r\n")
685 client
:= strings
.Join(strings
.Split(authFailedClient
, "\n"), "\r\n")
686 var cmdbuf bytes
.Buffer
687 bcmdbuf
:= bufio
.NewWriter(&cmdbuf
)
689 fake
.ReadWriter
= bufio
.NewReadWriter(bufio
.NewReader(strings
.NewReader(server
)), bcmdbuf
)
690 c
, err
:= NewClient(fake
, "fake.host")
692 t
.Fatalf("NewClient: %v", err
)
697 c
.serverName
= "smtp.google.com"
698 err
= c
.Auth(PlainAuth("", "user", "pass", "smtp.google.com"))
701 t
.Error("Auth: expected error; got none")
702 } else if err
.Error() != "535 Invalid credentials\nplease see www.example.com" {
703 t
.Errorf("Auth: got error: %v, want: %s", err
, "535 Invalid credentials\nplease see www.example.com")
707 actualcmds
:= cmdbuf
.String()
708 if client
!= actualcmds
{
709 t
.Errorf("Got:\n%s\nExpected:\n%s", actualcmds
, client
)
713 var authFailedServer
= `220 hello world
714 250-mx.google.com at your service
716 535-Invalid credentials
717 535 please see www.example.com
721 var authFailedClient
= `EHLO localhost
722 AUTH PLAIN AHVzZXIAcGFzcw==
727 func TestTLSClient(t
*testing
.T
) {
728 if (runtime
.GOOS
== "freebsd" && runtime
.GOARCH
== "amd64") || runtime
.GOOS
== "js" {
729 testenv
.SkipFlaky(t
, 19229)
731 ln
:= newLocalListener(t
)
733 errc
:= make(chan error
)
735 errc
<- sendMail(ln
.Addr().String())
737 conn
, err
:= ln
.Accept()
739 t
.Fatalf("failed to accept connection: %v", err
)
742 if err
:= serverHandle(conn
, t
); err
!= nil {
743 t
.Fatalf("failed to handle connection: %v", err
)
745 if err
:= <-errc
; err
!= nil {
746 t
.Fatalf("client error: %v", err
)
750 func TestTLSConnState(t
*testing
.T
) {
751 ln
:= newLocalListener(t
)
753 clientDone
:= make(chan bool)
754 serverDone
:= make(chan bool)
756 defer close(serverDone
)
757 c
, err
:= ln
.Accept()
759 t
.Errorf("Server accept: %v", err
)
763 if err
:= serverHandle(c
, t
); err
!= nil {
764 t
.Errorf("server error: %v", err
)
768 defer close(clientDone
)
769 c
, err
:= Dial(ln
.Addr().String())
771 t
.Errorf("Client dial: %v", err
)
775 cfg
:= &tls
.Config
{ServerName
: "example.com"}
776 testHookStartTLS(cfg
) // set the RootCAs
777 if err
:= c
.StartTLS(cfg
); err
!= nil {
778 t
.Errorf("StartTLS: %v", err
)
781 cs
, ok
:= c
.TLSConnectionState()
783 t
.Errorf("TLSConnectionState returned ok == false; want true")
786 if cs
.Version
== 0 ||
!cs
.HandshakeComplete
{
787 t
.Errorf("ConnectionState = %#v; expect non-zero Version and HandshakeComplete", cs
)
794 func newLocalListener(t
*testing
.T
) net
.Listener
{
795 ln
, err
:= net
.Listen("tcp", "127.0.0.1:0")
797 ln
, err
= net
.Listen("tcp6", "[::1]:0")
805 type smtpSender
struct {
809 func (s smtpSender
) send(f
string) {
810 s
.w
.Write([]byte(f
+ "\r\n"))
813 // smtp server, finely tailored to deal with our own client only!
814 func serverHandle(c net
.Conn
, t
*testing
.T
) error
{
815 send
:= smtpSender
{c
}.send
816 send("220 127.0.0.1 ESMTP service ready")
817 s
:= bufio
.NewScanner(c
)
820 case "EHLO localhost":
821 send("250-127.0.0.1 ESMTP offers a warm hug of welcome")
826 keypair
, err
:= tls
.X509KeyPair(localhostCert
, localhostKey
)
830 config
:= &tls
.Config
{Certificates
: []tls
.Certificate
{keypair
}}
831 c
= tls
.Server(c
, config
)
833 return serverHandleTLS(c
, t
)
835 t
.Fatalf("unrecognized command: %q", s
.Text())
841 func serverHandleTLS(c net
.Conn
, t
*testing
.T
) error
{
842 send
:= smtpSender
{c
}.send
843 s
:= bufio
.NewScanner(c
)
846 case "EHLO localhost":
848 case "MAIL FROM:<joe1@example.com>":
850 case "RCPT TO:<joe2@example.com>":
853 send("354 send the mail data, end with .")
855 case "Subject: test":
860 send("221 127.0.0.1 Service closing transmission channel")
863 t
.Fatalf("unrecognized command during TLS: %q", s
.Text())
870 testRootCAs
:= x509
.NewCertPool()
871 testRootCAs
.AppendCertsFromPEM(localhostCert
)
872 testHookStartTLS
= func(config
*tls
.Config
) {
873 config
.RootCAs
= testRootCAs
877 func sendMail(hostPort
string) error
{
878 from
:= "joe1@example.com"
879 to
:= []string{"joe2@example.com"}
880 return SendMail(hostPort
, nil, from
, to
, []byte("Subject: test\n\nhowdy!"))
883 // (copied from net/http/httptest)
884 // localhostCert is a PEM-encoded TLS cert with SAN IPs
885 // "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
887 // generated from src/crypto/tls:
888 // go run generate_cert.go --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
889 var localhostCert
= []byte(`-----BEGIN CERTIFICATE-----
890 MIIBjjCCATigAwIBAgIQMon9v0s3pDFXvAMnPgelpzANBgkqhkiG9w0BAQsFADAS
891 MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
892 MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJB
893 AM0u/mNXKkhAzNsFkwKZPSpC4lZZaePQ55IyaJv3ovMM2smvthnlqaUfVKVmz7FF
894 wLP9csX6vGtvkZg1uWAtvfkCAwEAAaNoMGYwDgYDVR0PAQH/BAQDAgKkMBMGA1Ud
895 JQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhh
896 bXBsZS5jb22HBH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQAD
897 QQBOZsFVC7IwX+qibmSbt2IPHkUgXhfbq0a9MYhD6tHcj4gbDcTXh4kZCbgHCz22
898 gfSj2/G2wxzopoISVDucuncj
899 -----END CERTIFICATE-----`)
901 // localhostKey is the private key for localhostCert.
902 var localhostKey
= []byte(`-----BEGIN RSA PRIVATE KEY-----
903 MIIBOwIBAAJBAM0u/mNXKkhAzNsFkwKZPSpC4lZZaePQ55IyaJv3ovMM2smvthnl
904 qaUfVKVmz7FFwLP9csX6vGtvkZg1uWAtvfkCAwEAAQJART2qkxODLUbQ2siSx7m2
905 rmBLyR/7X+nLe8aPDrMOxj3heDNl4YlaAYLexbcY8d7VDfCRBKYoAOP0UCP1Vhuf
906 UQIhAO6PEI55K3SpNIdc2k5f0xz+9rodJCYzu51EwWX7r8ufAiEA3C9EkLiU2NuK
907 3L3DHCN5IlUSN1Nr/lw8NIt50Yorj2cCIQCDw1VbvCV6bDLtSSXzAA51B4ZzScE7
908 sHtB5EYF9Dwm9QIhAJuCquuH4mDzVjUntXjXOQPdj7sRqVGCNWdrJwOukat7AiAy
909 LXLEwb77DIPoI5ZuaXQC+MnyyJj1ExC9RFcGz+bexA==
910 -----END RSA PRIVATE KEY-----`)