zoukankan      html  css  js  c++  java
  • go smtp

    最近看了几个 用 go 写的实现 gmail 发送邮件的程序,发现代码甚是简单。

    然后仔细研究了一下 smtp 协议,已经相关技术。

    1.go code

    调研go 的 "net/smtp"包的两个函数就可以了。

    func SendMail(addr string, a Auth, from string, to []string, msg []byte) error

    SendMail connects to the server at addr, switches to TLS if possible, authenticates with the optional mechanism a if possible, and then sends an email from address from, to addresses to, with message msg.

    func PlainAuth(identity, username, password, host string) Auth

    PlainAuth returns an Auth that implements the PLAIN authentication mechanism as defined in RFC 4616. The returned Auth uses the given username and password to authenticate on TLS connections to host and act as identity. Usually identity will be left blank to act as username.

    auth := smtp.PlainAuth(
      "",
      from@gmail.com,
      mypassword,
      "smtp.gmail.com",
    )
    
    err := smtp.SendMail(
    
      "smtp.example.com:25",
      auth,
      "from@example.com",
      mailList,
      []byte(sub+content))

    当然 也有 更好的实现,有点类似socket,建立连接之后 客户端 持有 connection,  然后在 connection 上面操作。

    可以查看:https://github.com/scorredoira/email

    2.相关点

    我花了一点是件简单看了一下 smtp协议,着重理解了一下 smtp 的auth 和 TLS.

    (1) smtp 协议 类似 http 协议:http://www.rfc-editor.org/rfc/pdfrfc/rfc5321.txt.pdf

    (2) TLS  it's a protocal to encrypt you trasmitted data .

    refer to http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html

    (3) for auth

    refer to : https://qmail.jms1.net/test-auth.shtml  <--- good artical

    Once you are authenticated, you may continue with a normal SMTP conversation and the server should accept any message from you, whether you are relaying to an outside domain or not. Even if you don't authenticate, the server will still accept messages from you- it just won't relay (it will act the same as if you had never entered an AUTH command at all.)

    How to auth using TLS in code:

    auth := smtp.PlainAuth(     <------  just construct a object implementing the interface auth.
            "",
            from,
            password,
            "smtp.gmail.com",
        )
    
        conn, err := smtp.Dial("smtp.gmail.com:587")
        err = conn.StartTLS(&tls.Config{})
        err = conn.Auth(auth)
        err = conn.Mail(from@xxx)
        err = conn.Rcpt(sendto@xxx) //can add multiple receivers
        wc, err := conn.Data()
      defer wc.Close() _, err
    = wc.Write(e.Bytes()) //write data }

    this code similar to <----  may be wrong,  I will confirm it by wireshark tomorrow.  <---- confirm by wireshark

    (1) dial

    S: 220 mail.example.com ESMTP Postfix (1.1.7)
    C: EHLO example.com
    S: 250-mail.example.com
    S: 250-PIPELINING
    S: 250-SIZE 10240000
    S: 250-VRFY
    S: 250-ETRN
    S: 250-AUTH DIGEST-MD5 CRAM-MD5 GSSAPI PLAIN LOGIN
    S: 250-AUTH=DIGEST-MD5 CRAM-MD5 GSSAPI PLAIN LOGIN
    S: 250-XVERP
    S: 250 8BITMIME
    S: 250 STARTTLS

    (2) startTLS
    C: STARTTLS
    S: 220 Go ahead
    C: <starts TLS negotiation>
    S: 220 Ready to start TLS ... TLS negotiation proceeds. Further commands protected by TLS layer
    ...

    (3) auto
    SSL  transmission

    (4) send data
    SSL ...
    (5) close
    C: QUIT
    S: 221 Bye

    (3) ,(4) and (5) are encrypted by TLS.

  • 相关阅读:
    Mac系统杂项 (持续更新)
    黑苹果-IOS学习的开始
    WPF命令参数CommandParameter
    WPF使用RoutedCommand自定义命令
    解决iOS设备屏幕切换时页面造成的问题
    width100%,设置padding或border溢出解决方法
    linux下别名alias的设置
    cordova navigator app 对象
    jquery easyui combox实用方法记录
    seajs构建方法
  • 原文地址:https://www.cnblogs.com/harrysun/p/3715298.html
Copyright © 2011-2022 走看看