All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.subethamail.smtp.command.StartTLSCommand Maven / Gradle / Ivy

There is a newer version: 3.1.7
Show newest version
package org.subethamail.smtp.command;

import java.io.IOException;
import java.net.Socket;
import java.util.Locale;
import java.security.cert.Certificate;

import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLPeerUnverifiedException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.subethamail.smtp.server.BaseCommand;
import org.subethamail.smtp.server.Session;

/**
 * @author Michael Wildpaner <[email protected]>
 * @author Jeff Schnitzer
 */
public class StartTLSCommand extends BaseCommand
{
	private final static Logger log = LoggerFactory.getLogger(StartTLSCommand.class);

	/** */
	public StartTLSCommand()
	{
		super("STARTTLS", "The starttls command");
	}

	/** */
	@Override
	public void execute(String commandString, Session sess) throws IOException
	{
		if (!commandString.trim().toUpperCase(Locale.ENGLISH).equals(this.getName()))
		{
			sess.sendResponse("501 Syntax error (no parameters allowed)");
			return;
		}

		try
		{
			Socket socket = sess.getSocket();
			if (socket instanceof SSLSocket)
			{
				sess.sendResponse("454 TLS not available due to temporary reason: TLS already active");
				return;
			}

			sess.sendResponse("220 Ready to start TLS");

			SSLSocket s = sess.getServer().createSSLSocket(socket);
			s.startHandshake();

			sess.setSocket(s);
			sess.resetMessageState(); // clean slate
			sess.setTlsStarted(true);

			if (s.getNeedClientAuth())
			{
				try
				{
					Certificate[] peerCertificates = s.getSession().getPeerCertificates();
					sess.setTlsPeerCertificates(peerCertificates);
				}
				catch (SSLPeerUnverifiedException e)
				{
					// IGNORE, just leave the certificate chain null
				}
			}
		}
		catch (SSLHandshakeException ex)
		{
			// "no cipher suites in common" is common and puts a lot of crap in the logs.
			// This will at least limit it to a single WARN line and not a whole stacktrace.
			// Unfortunately it might catch some other types of SSLHandshakeException (if
			// in fact other types exist), but oh well.
			log.warn("startTLS() failed: " + ex);
		}
		catch (IOException ex)
		{
			log.warn("startTLS() failed: " + ex.getMessage(), ex);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy