我正在尝试使用 STARTTLS 命令发送电子邮件。我在 Gmail 中设置了一个测试帐户,并将其设置为仅接受带有 TLS 连接的入站电子邮件。
由于我不想进入的原因,我不能使用 JavaMail 或其他电子邮件库。
我已经能够使用 openssl 向这个测试帐户发送电子邮件。所以我知道该帐户已正确设置。
有效的示例:openssl s_client -starttls smtp -crlf -connect aspmx.l.google.com:25
我还能够使用包含 TLS 的 .Net 应用程序向此电子邮件帐户发送电子邮件。
我知道我的示例(如下)不是发送电子邮件的正确方法,因为我没有对服务器的响应做出反应,但我认为这是创建示例来演示问题的好/短方法。
我已经尝试了一段时间来让它发挥作用。我尝试连接不同的端口(465、587、25),结果相似。我得到的错误是在命令“AUTH LOGIN”上,但在我之前的命令“EHLO aspmx.l.google.com”上,我已经没有从服务器得到任何响应。
我得到的错误是:“错误:软件导致连接中止:套接字写入错误”。
我是否在协商 TLS 连接以传输电子邮件的正确路径,还是我遗漏了一些明显的东西?
任何帮助都感激不尽。
例子:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.xml.bind.DatatypeConverter;
public class SendEmailWithTLSConnectionTest {
private static DataOutputStream dos;
private static BufferedReader out = null;
public static void main(String[] args) throws Exception
{
try
{
int delay = 1000;
String username = DatatypeConverter.printBase64Binary("leo@tls.calcium.co.nz".getBytes());
String password = DatatypeConverter.printBase64Binary("2wsxZAQ!".getBytes());
Socket sock = new Socket("aspmx.l.google.com", 25);
out = new BufferedReader(new InputStreamReader(sock.getInputStream()));
(new Thread(new Runnable()
{
public void run()
{
while(true)
{
try
{
if(out != null)
{
String line;
while((line = out.readLine()) != null)
{
System.out.println("SERVER: "+line);
}
}
}
catch (IOException e)
{
System.out.println("IOException SERVER! Error: " + e);
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
})).start();
dos = new DataOutputStream(sock.getOutputStream());
send("EHLO aspmx.l.google.com\r\n");
Thread.sleep(delay * 5);
send("STARTTLS\r\n");
Thread.sleep(delay * 5);
SSLSocket sslSocket = (SSLSocket) ((SSLSocketFactory) SSLSocketFactory.getDefault()).createSocket(
sock,
sock.getInetAddress().getHostAddress(),
587,
true);
sslSocket.setUseClientMode(true);
sslSocket.setEnableSessionCreation(true);
// Thread.sleep(delay * 5);
// sslSocket.startHandshake();
send("EHLO aspmx.l.google.com\r\n");
Thread.sleep(delay * 5);
send("AUTH LOGIN\r\n");
Thread.sleep(delay * 5);
send(username + "\r\n");
Thread.sleep(delay * 5);
send(password + "\r\n");
Thread.sleep(delay * 5);
send("MAIL FROM: <leo@tls.calcium.co.nz>\r\n");
Thread.sleep(delay * 5);
send("RCPT TO: <leo@tls.calcium.co.nz>\r\n");
Thread.sleep(delay * 5);
send("DATA\r\n");
Thread.sleep(delay * 5);
send("Test 1 2 3");
Thread.sleep(delay * 5);
send("\r\n.\r\n");
Thread.sleep(delay * 5);
send("QUIT\r\n");
}
catch(Exception ex)
{
System.out.println("Exception when sending out test. Error: " + ex.getMessage());
}
}
private static void send(String s) throws Exception
{
dos.writeBytes(s);
System.out.println("CLIENT: "+s);
}
}
输出:
SERVER: 220 mx.google.com ESMTP on10si24036122pac.132 - gsmtp
CLIENT: EHLO aspmx.l.google.com
SERVER: 250-mx.google.com at your service, [103.23.17.19]
SERVER: 250-SIZE 35882577
SERVER: 250-8BITMIME
SERVER: 250-STARTTLS
SERVER: 250-ENHANCEDSTATUSCODES
SERVER: 250-PIPELINING
SERVER: 250-CHUNKING
SERVER: 250 SMTPUTF8
CLIENT: STARTTLS
SERVER: 220 2.0.0 Ready to start TLS
CLIENT: EHLO aspmx.l.google.com
Exception when sending out test. Error: Software caused connection abort: socket write error