英文:
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",
),
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论