2011-07-01 28 views
5

Tôi đang cố viết một bài kiểm tra sẽ sử dụng JavaMail SMTP hoặc SMTPS để gửi thư qua SSL và xác thực tới máy chủ Greenmail mà tôi đang chạy.Sử dụng Javamail và Greenmail cho SMTPS/SSL

Tôi đã viết một tiểu ít nhanh chóng mà nên thực hiện chính xác những gì tôi muốn:

import java.util.Properties; 

import javax.mail.Session; 
import javax.mail.Transport; 

import com.icegreen.greenmail.user.GreenMailUser; 
import com.icegreen.greenmail.util.GreenMail; 

public class MailTest { 
    public static void main(String[] args) throws Exception { 
     GreenMail greenmail = new GreenMail(); 
     try { 
      greenmail.start(); 

      String email = "[email protected]"; 
      String userid = "user"; 
      String password = "pa$$word"; 
      GreenMailUser setUser = greenmail.setUser(email, userid, password); 
      setUser.create(); 
      GreenMailUser user = greenmail.getManagers().getUserManager().getUser(userid); 
      System.out.println("User created:" + user.getEmail() + ":" + user.getLogin() + ":" + user.getPassword()); 

      int portSmtps = greenmail.getSmtps().getPort(); 
      System.out.println("Smtps started on port:" + portSmtps); 

      Properties props = new Properties(); 
      props.put("mail.smtp.starttls.enable", "true"); 
      props.put("mail.smtp.auth", "true"); 
      props.put("mail.smtp.host", "localhost"); 
      props.put("mail.smtp.socketFactory.port", portSmtps); 
      props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
      props.put("mail.smtp.socketFactory.fallback", "false"); 
      Session session = Session.getInstance(props); 
      Transport transport = session.getTransport("smtp"); 
      transport.connect("localhost", portSmtps, userid, password); 
      System.out.println("Transport is connected: " + transport.isConnected()); 
     } finally { 
      greenmail.stop(); 
     } 
    } 
} 

Vấn đề của tôi là tôi có được một vài trường hợp ngoại lệ:

Exception in thread "Thread-7" java.lang.RuntimeException: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown 
    at com.icegreen.greenmail.smtp.SmtpHandler.run(Unknown Source) 
Caused by: javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.checkEOF(SSLSocketImpl.java:1293) 
    at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:65) 
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264) 
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306) 
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158) 
    at java.io.InputStreamReader.read(InputStreamReader.java:167) 
    at java.io.BufferedReader.fill(BufferedReader.java:136) 
    at java.io.BufferedReader.readLine(BufferedReader.java:299) 
    at java.io.BufferedReader.readLine(BufferedReader.java:362) 
    at com.icegreen.greenmail.smtp.SmtpConnection.readLine(Unknown Source) 
    at com.icegreen.greenmail.smtp.SmtpHandler.handleCommand(Unknown Source) 
    ... 1 more 
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown 
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) 
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1720) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:954) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632) 
    at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59) 
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202) 
    at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272) 
    at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276) 
    at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122) 
    at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212) 
    at java.io.BufferedWriter.flush(BufferedWriter.java:236) 
    at java.io.PrintWriter.flush(PrintWriter.java:276) 
    at com.icegreen.greenmail.util.InternetPrintWriter.println(Unknown Source) 
    at com.icegreen.greenmail.util.InternetPrintWriter.println(Unknown Source) 
    at com.icegreen.greenmail.smtp.SmtpConnection.println(Unknown Source) 
    at com.icegreen.greenmail.smtp.SmtpHandler.sendGreetings(Unknown Source) 
    ... 1 more 
Exception in thread "main" javax.mail.MessagingException: Could not connect to SMTP host: localhost, port: 3465; 
    nested exception is: 
    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1934) 
    at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:638) 
    at javax.mail.Service.connect(Service.java:295) 
    at MailTest.main(MailTest.java:35) 
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649) 
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241) 
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235) 
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206) 
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136) 
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593) 
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165) 
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1149) 
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:507) 
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:238) 
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1900) 
    ... 3 more 
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323) 
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217) 
    at sun.security.validator.Validator.validate(Validator.java:218) 
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126) 
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209) 
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) 
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1185) 
    ... 13 more 
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174) 
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238) 
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318) 
    ... 19 more 

tôi đã cố gắng tìm kiếm tại một vài câu trả lời khác ở đây, nhưng tôi phải thiếu một cái gì đó:

Xin lỗi cho đăng bài dài và cảm ơn trước cho lời khuyên nào.

+0

SSL có một mô hình tin tưởng chắc chắn rằng nó sử dụng để xác thực dựa trên chứng chỉ. Những gì bạn có thể cho chúng tôi biết về chứng chỉ máy chủ SMTPS? Có lẽ nó là tự ký? –

Trả lời

12

Bạn nên bắt đầu máy chủ GreenMail của bạn như thế này:

Security.setProperty("ssl.SocketFactory.provider", DummySSLSocketFactory.class.getName()); 
GreenMail mailServer = new GreenMail(ServerSetupTest.SMTPS); 
mailServer.start(); 
+1

Tuyệt vời! Điều đó làm việc cho tôi. – Sunny

1

Chứng chỉ SSL được sử dụng trên máy chủ Greenmail phải được ký bởi cơ quan cấp chứng chỉ "đã biết" HOẶC bạn phải thêm chứng chỉ CA đã được sử dụng để ký chứng nhận vào kho khóa của Java. Không có cách nào để yêu cầu Java không xác thực chuỗi chứng chỉ lên đến một CA đã biết.

Các vấn đề liên quan