通过未加密的连接发送电子邮件

huangapple go评论82阅读模式
英文:

Send email through unencrypted connection

问题

我有一个不使用加密连接的SMTP帐户。我可以使用相同的帐户在C#和Python中发送电子邮件而没有问题,但是在Go中,我遇到了错误:
未加密的连接

这是我正在使用的代码:

package main

import (
        "log"
        "net/smtp"
)

func main() {
        // 设置身份验证信息。
        auth := smtp.PlainAuth(
                "",
                "user@example.com",
                "password",
                "mail.example.com",
        )
        // 连接到服务器,进行身份验证,设置发件人和收件人,
        // 并一次性发送电子邮件。
        err := smtp.SendMail(
                "mail.example.com:25",
                auth,
                "sender@example.org",
                []string{"recipient@example.net"},
                []byte("This is the email body."),
        )
        if err != nil {
                log.Fatal(err)
        }
}
英文:

I have a SMTP account that does not use encrypted connection. I can use the same account to send emails from C# and Python without problems but with Go I get the error:
unencrypted connection

This is the code I am using:

package main

import (
        "log"
        "net/smtp"
)

func main() {
        // Set up authentication information.
        auth := smtp.PlainAuth(
                "",
                "user@example.com",
                "password",
                "mail.example.com",
        )
        // Connect to the server, authenticate, set the sender and recipient,
        // and send the email all in one step.
        err := smtp.SendMail(
                "mail.example.com:25",
                auth,
                "sender@example.org",
                []string{"recipient@example.net"},
                []byte("This is the email body."),
        )
        if err != nil {
                log.Fatal(err)
        }
}

答案1

得分: 24

问题在于smtp.PlainAuth拒绝在未加密的连接上发送密码。这是为了保护您自己。像smtp.CRAMMD5Auth这样的东西会是一个更好的选择。使用CRAM-MD5时,即使在未加密的连接上,您的密码也不会被暴露。

如果您仍然想使用明文身份验证,您需要创建自己的smtp.PlainAuth版本。幸运的是,这是一件非常容易的事情。只需从标准库中复制大约20行代码,并删除以下内容:

if !server.TLS {
    return "", nil, errors.New("unencrypted connection")
}

http://golang.org/src/pkg/net/smtp/auth.go?s=1820:1882#L41 包含了这段代码。

如果您不想复制代码,可以通过在函数返回的smtp.Auth上包装自己的类型来重用标准库的实现。这样,您就可以拦截*smtp.ServerInfo并欺骗实际的Auth机制(来自标准库),让它认为有一个加密的连接。请确保进行详细的注释,以清楚说明您为什么要这样做。类似下面的代码(未经测试):

type unencryptedAuth struct {
    smtp.Auth
}

func (a unencryptedAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
    s := *server
    s.TLS = true
    return a.Auth.Start(&s)
}

auth := unencryptedAuth {
    smtp.PlainAuth(
        "",
        "user@example.com",
        "password",
        "mail.example.com",
    ),
}
英文:

The issue here is that smtp.PlainAuth refuses to send your password over an unencrypted connection. This is for your own protection. Something like smtp.CRAMMD5Auth would be a much better choice. When using CRAM-MD5, even over an unencrypted connection, your password is not exposed.

If you want to use plain authentication anyways, you would need to make your own version of smtp.PlainAuth. Luckily, this is a very easy thing to do. Just copy the 20 lines or so from the standard library and remove:

if !server.TLS {
    return "", nil, errors.New("unencrypted connection")
}

http://golang.org/src/pkg/net/smtp/auth.go?s=1820:1882#L41 contains the code.

If you do not wish to copy code, you can reuse the standard library implementation by wrapping the smtp.Auth returned by the function in your own type. This way you intercept the *smtp.ServerInfo and trick the actual Auth mechanism (from the standard library) that there is an encrypted connection. Make sure to heavily comment to make it clear why you are doing what you are doing. Something like this (untested):

type unencryptedAuth struct {
    smtp.Auth
}

func (a unencryptedAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
    s := *server
    s.TLS = true
    return a.Auth.Start(&s)
}

auth := unencryptedAuth {
    smtp.PlainAuth(
        "",
        "user@example.com",
        "password",
        "mail.example.com",
    ),
}

huangapple
  • 本文由 发表于 2012年6月17日 02:14:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/11065913.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定