the detail of net/smtp as follows:

SendMail

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
func SendMail(addr string, a Auth, from string, to []string, msg []byte) error {
//validateLine checks to see if a line has CR or LF
//if it has, then return an error
if err := validateLine(from); err != nil {
return err
}
for _, recp := range to {
if err := validateLine(recp); err != nil {
return err
}
}
//Dial returns a new Client connected to an SMTP server at addr. The addr must include a port, as in "mail.example.com:smtp"
c, err := Dial(addr)
if err != nil {
return err
}
// close the connection.
defer c.Close()
//Hello sends a HELO or EHLO to the server as the given host name.
if err = c.hello(); err != nil {
return err
}
//Extension reports whether an extension is support by the server
// the StartTLS extension
if ok, _ := c.Extension("STARTTLS"); ok {
config := &tls.Config{ServerName: c.serverName}
if testHookStartTLS != nil {
testHookStartTLS(config)
}
if err = c.StartTLS(config); err != nil {
return err
}
}
if a != nil && c.ext != nil {
if _, ok := c.ext["AUTH"]; !ok {
return errors.New("smtp: server doesn't support AUTH")
}
//Auth authenticates a client using the provided authentication mechanism.
if err = c.Auth(a); err != nil {
return err
}
}
//Mail issues a MAIL command to the server using the provided email address.
if err = c.Mail(from); err != nil {
return err
}
for _, addr := range to {
//Rcpt issues a RCPT command to the server using the provided email address.
if err = c.Rcpt(addr); err != nil {
return err
}
}
//Data issues a DATA command to the server and returns a writer that can be used to write the mail headers and body.
w, err := c.Data()
if err != nil {
return err
}
_, err = w.Write(msg)
if err != nil {
return err
}
err = w.Close()
if err != nil {
return err
}
//Quit sends the QUIT command and closes the connection to the server.
return c.Quit()
}

Auth

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// Auth is implemented by an SMTP authentication mechanism.
type Auth interface {
// Start begins an authentication with a server.
// It returns the name of the authentication protocol and optionally data to include in the initial AUTH message sent to the server.
Start(server *ServerInfo) (proto string, toServer []byte, err error)

// Next continues the authentication. The server has just sent the fromServer data. If more is true, the server expects a response, which Next should return as toServer;
Next(fromServer []byte, more bool) (toServer []byte, err error)
}

type plainAuth struct {
identity, username, password string
host string
}
//PlainAuth will only send the credentials if the connection is using TLS or is connected to localhost.
func PlainAuth(identity, username, password, host string) Auth {
return &plainAuth{identity, username, password, host}
}

func (a *plainAuth) Start(server *ServerInfo) (string, []byte, error) {
// Must have TLS, or else localhost server.
// Note: If TLS is not true, then we can't trust ANYTHING in ServerInfo.
if !server.TLS && !isLocalhost(server.Name) {
return "", nil, errors.New("unencrypted connection")
}
if server.Name != a.host {
return "", nil, errors.New("wrong host name")
}
resp := []byte(a.identity + "\x00" + a.username + "\x00" + a.password)
return "PLAIN", resp, nil
}


I made a simple application of smtp to send email :

Collapssar/TXmail: A simple application sending qqEmail through smtp protocol, which is achieved by go net/smtp (github.com)