package org.mailster.smtp.core.commands.impl; import java.io.IOException; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.ssl.SslFilter; import org.mailster.smtp.core.SMTPContext; import org.mailster.smtp.core.commands.AbstractCommand; import org.mailster.smtp.util.DummySSLSocketFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The STARTLS command implementation. * * @author De Oliveira Edouard <doe_wanted@yahoo.fr> */ public class StartTLSCommand extends AbstractCommand { private static final Logger LOG = LoggerFactory.getLogger(StartTLSCommand.class); private static SslFilter sslFilter; static { try { DummySSLSocketFactory socketFactory = new DummySSLSocketFactory(); sslFilter = new SslFilter(socketFactory.getSSLContext()); } catch (Exception e) { e.printStackTrace(); } } public StartTLSCommand() { super("STARTTLS", "The STARTTLS command starts a secured connection for the current\nSMTP session"); } /** * Ability to override the SSLFilter * @param filter */ public static void setSSLFilter(SslFilter filter) { if (filter == null) throw new IllegalArgumentException("filter argument can't be null"); sslFilter = filter; } public void execute(String commandString, IoSession ioSession, SMTPContext ctx) throws IOException { if (commandString.trim().indexOf(" ") > 0) { sendResponse(ioSession, "501 Syntax error (no parameters allowed)"); return; } try { if (sslFilter.isSslStarted(ioSession)) { sendResponse(ioSession, "454 TLS not available due to temporary reason: TLS already active"); return; } // Insert SSLFilter to get ready for handshaking ioSession.getFilterChain().addFirst("SSLfilter", sslFilter); // Disable encryption temporarily. // This attribute will be removed by SSLFilter // inside the Session.write() call below. ioSession.setAttribute(SslFilter.DISABLE_ENCRYPTION_ONCE, Boolean.TRUE); // Write StartTLSResponse which won't be encrypted. sendResponse(ioSession, "220 Ready to start TLS"); // Now DISABLE_ENCRYPTION_ONCE attribute is cleared. assert ioSession.getAttribute(SslFilter.DISABLE_ENCRYPTION_ONCE) == null; ctx.getSMTPState().resetAll(); // clean state ctx.getDeliveryHandler().resetMessageState(); } catch (Exception e) { LOG.debug("startTLS() failed: {}", e.getMessage()); LOG.trace("startTLS() failure stack trace", e); } } }