org.mule.transport.ldap.util.DSManager.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.transport.ldap.util.DSManager.java

Source

package org.mule.transport.ldap.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.Security;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;

import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.directory.server.constants.ServerDNConstants;
import org.apache.directory.server.core.CoreSession;
import org.apache.directory.server.core.DefaultDirectoryService;
import org.apache.directory.server.core.DirectoryService;
import org.apache.directory.server.core.entry.DefaultServerEntry;
import org.apache.directory.server.core.entry.ServerEntry;
import org.apache.directory.server.core.interceptor.context.AddOperationContext;
import org.apache.directory.server.core.jndi.CoreContextFactory;
import org.apache.directory.server.core.partition.Partition;
import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
import org.apache.directory.server.core.security.TlsKeyGenerator;
import org.apache.directory.server.ldap.LdapService;
import org.apache.directory.server.ldap.handlers.bind.MechanismHandler;
import org.apache.directory.server.ldap.handlers.bind.cramMD5.CramMd5MechanismHandler;
import org.apache.directory.server.ldap.handlers.bind.digestMD5.DigestMd5MechanismHandler;
import org.apache.directory.server.ldap.handlers.bind.gssapi.GssapiMechanismHandler;
import org.apache.directory.server.ldap.handlers.bind.ntlm.NtlmMechanismHandler;
import org.apache.directory.server.ldap.handlers.bind.plain.PlainMechanismHandler;
import org.apache.directory.server.ldap.handlers.extended.StartTlsHandler;
import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
import org.apache.directory.server.ldap.handlers.ssl.ServerX509TrustManager;
import org.apache.directory.server.protocol.shared.SocketAcceptor;
import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.apache.directory.shared.ldap.exception.LdapConfigurationException;
import org.apache.directory.shared.ldap.ldif.LdifEntry;
import org.apache.directory.shared.ldap.ldif.LdifReader;
import org.apache.directory.shared.ldap.name.LdapDN;
import org.apache.mina.common.DefaultIoFilterChainBuilder;
import org.apache.mina.common.IoFilterChainBuilder;
import org.apache.mina.filter.SSLFilter;
import org.mule.util.IOUtils;

public final class DSManager {
    /*
     * Licensed to the Apache Software Foundation (ASF) under one or more
     * contributor license agreements. See the NOTICE file distributed with this
     * work for additional information regarding copyright ownership. The ASF
     * licenses this file to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance with the
     * License. You may obtain a copy of the License at
     * 
     * http://www.apache.org/licenses/LICENSE-2.0
     * 
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     * License for the specific language governing permissions and limitations
     * under the License.
     * 
     */

    /**
     * logger used by this class
     */
    protected static final Log logger = LogFactory.getLog(DSManager.class);

    /**
     * A simple testcase for testing JNDI provider functionality.
     * 
     * @author <a href="mailto:dev@directory.apache.org">Apache Directory
     *         Project</a>
     * @version $Rev: 502690 $
     */

    private static final DSManager instance = new DSManager();

    // private static final String CTX_FACTORY =
    // "com.sun.jndi.ldap.LdapCtxFactory";

    /** the context root for the system partition */
    protected LdapContext sysRoot;

    /** the context root for the system partition */
    protected LdapContext exampleRoot;

    protected LdapContext root;

    /** The RootDSE is a standard attribute */
    protected CoreSession rootDSE;

    protected LdapContext schemaRoot;

    /** flag whether to delete database files for each test or not */
    protected boolean doDelete = true;

    protected int port = -1;

    protected volatile boolean running;

    protected DirectoryService directoryService;
    protected SocketAcceptor socketAcceptor;
    protected LdapService ldapService;
    protected LdapService ldapSService;

    /*
     * static{ try {
     * 
     * //new BouncyCastleProvider(); // TlsKeyGenerator.
     * 
     * System.setProperty (
     * "javax.net.ssl.trustStore","/home/hsaly/devel/projects/mule-transport-ldap/trunk/src/test/resources/ldaps-server-cert.jks" ); //
     * System.setProperty (
     * "javax.net.ssl.keyStore","/home/hsaly/devel/projects/mule-transport-ldap/trunk/src/test/resources/ldaps-server-cert.jks" ); //
     * System.setProperty ( "javax.net.ssl.keyStorePassword", "changeit" );
     * logger.debug(KeyStore.getDefaultType()); KeyStore ks =
     * KeyStore.getInstance(KeyStore.getDefaultType());
     * 
     * logger.debug(new File(".").getAbsolutePath());
     * 
     * ks.load(new FileInputStream(
     * "/home/hsaly/devel/projects/mule-transport-ldap/trunk/src/test/resources/ldaps-server-cert.jks"),
     * "changeit".toCharArray());
     * 
     * logger.debug(ks.getCertificateChain("test").toString());
     * 
     * //DSManager.init(ks); } catch (KeyStoreException e) { // TODO
     * Auto-generated catch block e.printStackTrace(); } catch
     * (NoSuchAlgorithmException e) { // TODO Auto-generated catch block
     * e.printStackTrace(); } catch (CertificateException e) { // TODO
     * Auto-generated catch block e.printStackTrace(); } catch
     * (FileNotFoundException e) { // TODO Auto-generated catch block
     * e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated
     * catch block e.printStackTrace(); } catch (Exception e) { // TODO
     * Auto-generated catch block e.printStackTrace(); } }
     */

    public boolean isRunning() {
        return running;
    }

    private DSManager() {
        logger.debug("DSManager instantiated");
    }

    public static DSManager getInstance() {
        return instance;
    }

    /**
     * Get's the initial context factory for the provider's ou=system context
     * root.
     * 
     * @see junit.framework.TestCase#setUp()
     */

    public synchronized void start() throws Exception {
        start(false);
    }

    public synchronized void start(final boolean allowAnon) throws Exception {
        if (running) {

            logger.debug("start() called while already running");

            if (checkSocketNotConnected()) {
                logger.debug("start() forced");
            } else {
                logger.debug("DS is already running, stop it, then start it.");

                try {
                    stop();

                } catch (final Exception e) {
                    // TODO: handle exception
                }

                // throw new IllegalStateException("DS already running on port "
                // + port);
            }

        }

        logger.debug("DS is starting ...");

        port = 10389;

        directoryService = new DefaultDirectoryService();
        directoryService.setShutdownHookEnabled(false);
        // directoryService.getChangeLog().setEnabled(true);
        directoryService.setAllowAnonymousAccess(allowAnon);

        socketAcceptor = new SocketAcceptor(null);
        ldapService = new LdapService();
        ldapService.setSocketAcceptor(socketAcceptor);
        ldapService.setDirectoryService(directoryService);
        ldapService.setIpPort(port);
        // ldapService.setIpAddress("gkar.kerb.de");

        // ldapService.setAccessControlEnabled(false);
        // ldapService.setShutdownHookEnabled(false);
        ldapService.setAllowAnonymousAccess(allowAnon);

        // ldapService.getLdapsConfiguration().setIpPort(10636);
        // ldapService.getLdapsConfiguration().setEnabled(true);
        // ldapService.getLdapsConfiguration().setLdapsCertificateFile(new
        // File("src/test/resources/ldaps-server-cert.jks"));
        // ldapService.getLdapsConfiguration().setIpPort(10636);

        setupSaslMechanisms(ldapService);

        // S
        ldapSService = new LdapService();
        ldapSService.setSocketAcceptor(socketAcceptor);
        ldapSService.setDirectoryService(directoryService);
        ldapSService.setIpPort(10636);
        ldapSService.setEnableLdaps(true);

        setupSaslMechanisms(ldapSService);

        // ldapSService.setConfidentialityRequired(true);
        ldapSService.setConfidentialityRequired(true);
        // ldapService.setIpAddress("gkar.kerb.de");

        // ldapService.setAccessControlEnabled(false);
        // ldapService.setShutdownHookEnabled(false);
        ldapSService.setAllowAnonymousAccess(allowAnon);

        // ldapService.getLdapsConfiguration().setIpPort(10636);
        // ldapService.getLdapsConfiguration().setEnabled(true);
        // ldapService.getLdapsConfiguration().setLdapsCertificateFile(new
        // File("src/test/resources/ldaps-server-cert.jks"));
        // ldapService.getLdapsConfiguration().setIpPort(10636);

        setupSaslMechanisms(ldapSService);

        doDelete(directoryService.getWorkingDirectory());

        directoryService.startup();

        // java.security.cert.X509Certificate cert =
        // TlsKeyGenerator.getCertificate(directoryService.getAdminSession().lookup(new
        // LdapDN("uid=admin,ou=system")).getOriginalEntry());

        final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(new FileInputStream("src/test/resources/truststore_2.jks"), "changeit".toCharArray());

        // java.security.cert.X509Certificate testcert =
        // (java.security.cert.X509Certificate) ks.getCertificate("test");
        // logger.debug(testcert);
        // directoryService.getAdminSession().lookup(new
        // LdapDN("uid=admin,ou=system")).getOriginalEntry().put("userCertificate",testcert.getEncoded());

        // logger.debug("type: "+testcert.getType());
        final java.security.cert.X509Certificate cert = TlsKeyGenerator.getCertificate(
                directoryService.getAdminSession().lookup(new LdapDN("uid=admin,ou=system")).getOriginalEntry());

        ks.setCertificateEntry("apachetmp", cert);

        final File tmpKs = new File("target/truststore_tmp.jks");
        if (tmpKs.exists()) {
            boolean del = tmpKs.delete();

            if (!del) {
                logger.error("Unable to delete " + tmpKs.getAbsolutePath());
                // throw new Exception("Unable to delete
                // "+tmpKs.getAbsolutePath());
            }
        }

        ks.store(new FileOutputStream("target/truststore_tmp.jks"), "changeit".toCharArray());

        logger.debug(cert);

        // TODO shouldn't this be before calling configureLdapServer() ???
        ldapService.addExtendedOperationHandler(new StartTlsHandler());
        ldapService.addExtendedOperationHandler(new StoredProcedureExtendedOperationHandler());

        ldapService.start();

        ldapSService.addExtendedOperationHandler(new StartTlsHandler());
        // ldapSService.add( new LdapsInitializer() );
        ldapSService.addExtendedOperationHandler(new StoredProcedureExtendedOperationHandler());

        ldapSService.start();

        // dn: uid=admin,ou=system
        setContexts(ServerDNConstants.ADMIN_SYSTEM_DN, "secret");

        setUpPartition();

        importLdif(IOUtils.getResourceAsStream("examplecom.ldif", this.getClass()));

        final Attributes attrs = new BasicAttributes();
        attrs.put(new BasicAttribute("userCertificate", ""));

        // sysRoot.modifyAttributes("uid=admin",LdapContext.REPLACE_ATTRIBUTE,attrs);
        logger.debug(rootDSE.getAuthenticatedPrincipal());
        logger.debug(rootDSE.getAuthenticationLevel());
        logger.debug(rootDSE.getEffectivePrincipal());
        logger.debug(rootDSE.toString());

        running = true;

        logger.debug("DS now started!");
    }

    private void setupSaslMechanisms(final LdapService server) {
        final Map<String, MechanismHandler> mechanismHandlerMap = new HashMap<String, MechanismHandler>();

        mechanismHandlerMap.put(SupportedSaslMechanisms.PLAIN, new PlainMechanismHandler());

        final CramMd5MechanismHandler cramMd5MechanismHandler = new CramMd5MechanismHandler();
        mechanismHandlerMap.put(SupportedSaslMechanisms.CRAM_MD5, cramMd5MechanismHandler);

        final DigestMd5MechanismHandler digestMd5MechanismHandler = new DigestMd5MechanismHandler();
        mechanismHandlerMap.put(SupportedSaslMechanisms.DIGEST_MD5, digestMd5MechanismHandler);

        final GssapiMechanismHandler gssapiMechanismHandler = new GssapiMechanismHandler();
        mechanismHandlerMap.put(SupportedSaslMechanisms.GSSAPI, gssapiMechanismHandler);

        final NtlmMechanismHandler ntlmMechanismHandler = new NtlmMechanismHandler();
        // TODO - set some sort of default NtlmProvider implementation here
        // ntlmMechanismHandler.setNtlmProvider( provider );
        // TODO - or set FQCN of some sort of default NtlmProvider
        // implementation here
        // ntlmMechanismHandler.setNtlmProviderFqcn( "com.foo.BarNtlmProvider"
        // );
        mechanismHandlerMap.put(SupportedSaslMechanisms.NTLM, ntlmMechanismHandler);
        mechanismHandlerMap.put(SupportedSaslMechanisms.GSS_SPNEGO, ntlmMechanismHandler);

        server.setSaslMechanismHandlers(mechanismHandlerMap);
        server.setSaslHost("localhost");

        // List<String> realms = new ArrayList<String>();
        // realms.add("system");
        // ldapService.setSaslRealms(realms);
    }

    private void setUpPartition() throws Exception {
        // Add partition 'sevenSeas'

        Partition pcfg = new JdbmPartition();
        // FIXME name
        pcfg.setId("sevenSeas");
        // dn o=sevenseas
        pcfg.setSuffix("o=sevenseas");

        directoryService.addPartition(pcfg);

        logger.debug("suffix:" + pcfg.getSuffix());

        LdapDN suffixDn = new LdapDN("o=sevenseas");
        suffixDn.normalize(directoryService.getRegistries().getAttributeTypeRegistry().getNormalizerMapping());
        logger.debug(suffixDn.toString());
        ServerEntry ctxEntry = new DefaultServerEntry(directoryService.getRegistries(), suffixDn);
        ctxEntry.put("objectClass", "top");
        ctxEntry.get("objectClass").add("organizationalUnit");
        ctxEntry.put("o", "sevenseas");

        logger.debug(ctxEntry);
        pcfg.add(new AddOperationContext(directoryService.getAdminSession(), ctxEntry));

        pcfg = new JdbmPartition();
        // FIXME name
        pcfg.setId("example");
        // dn o=sevenseas
        pcfg.setSuffix("dc=example,dc=com");

        directoryService.addPartition(pcfg);

        logger.debug("suffix:" + pcfg.getSuffix());

        suffixDn = new LdapDN("dc=example,dc=com");
        suffixDn.normalize(directoryService.getRegistries().getAttributeTypeRegistry().getNormalizerMapping());
        logger.debug(suffixDn.toString());
        ctxEntry = new DefaultServerEntry(directoryService.getRegistries(), suffixDn);
        ctxEntry.put("dc", "example");
        ctxEntry.put("objectClass", "top");
        ctxEntry.get("objectClass").add("domain");
        // ctxEntry.put( "ou", "users" );
        // ctxEntry.put( "objectClass", "organizationalUntit" );

        logger.debug(ctxEntry);
        pcfg.add(new AddOperationContext(directoryService.getAdminSession(), ctxEntry));
    }

    /*
     * Set<Partition> partitions = new HashSet<Partition>(); JdbmPartition
     * partition = new JdbmPartition(); partition.setId( "example" );
     * partition.setSuffix( "dc=example,dc=com" );
     * 
     * Set<Index<?,ServerEntry>> indexedAttrs = new HashSet<Index<?,ServerEntry>>();
     * indexedAttrs.add( new JdbmIndex<String,ServerEntry>( "ou" ) );
     * indexedAttrs.add( new JdbmIndex<String,ServerEntry>( "dc" ) );
     * indexedAttrs.add( new JdbmIndex<String,ServerEntry>( "objectClass" ) );
     * partition.setIndexedAttributes( indexedAttrs );
     * 
     * 
     * suffixDn = new LdapDN( "dc=example,dc=com" ); suffixDn.normalize(
     * directoryService.getRegistries().getAttributeTypeRegistry().getNormalizerMapping() );
     * logger.debug(suffixDn.toString()); ctxEntry = new DefaultServerEntry(
     * directoryService.getRegistries()); ctxEntry.put( "dc", "example" );
     * ctxEntry.put( "objectClass", "top" ); ctxEntry.get( "objectClass" ).add(
     * "domain" ); //ctxEntry.put( "ou", "users" ); //ctxEntry.put(
     * "objectClass", "organizationalUntit" );
     * 
     * logger.debug(ctxEntry);
     * 
     * 
     * 
     * 
     * partitions.add( partition ); directoryService.setPartitions( partitions );
     * 
     * partition.add( new AddOperationContext(
     * directoryService.getAdminSession(), ctxEntry ) ); ( }
     * 
     * /** Deletes the Eve working directory.
     */
    protected void doDelete(final File wkdir) throws IOException {
        if (doDelete) {
            if (wkdir.exists()) {
                FileUtils.deleteDirectory(wkdir);
            }
            if (wkdir.exists()) {
                throw new IOException("Failed to delete: " + wkdir);
            }
        }
    }

    protected void setContexts(final Hashtable<String, Object> env) throws Exception {
        final Hashtable<String, Object> envFinal = new Hashtable<String, Object>(env);
        // envFinal.put( Context.PROVIDER_URL, "dc=example,dc=com" );
        // exampleRoot = new InitialLdapContext( envFinal, null );

        // Hashtable<String, Object> envFinal = new Hashtable<String, Object>(
        // env );
        envFinal.put(Context.PROVIDER_URL, ServerDNConstants.SYSTEM_DN);
        sysRoot = new InitialLdapContext(envFinal, null);

        envFinal.put(Context.PROVIDER_URL, "");
        rootDSE = directoryService.getAdminSession();
        root = new InitialLdapContext(envFinal, null);

        envFinal.put(Context.PROVIDER_URL, ServerDNConstants.OU_SCHEMA_DN);
        schemaRoot = new InitialLdapContext(envFinal, null);
    }

    protected void setContexts(final String user, final String passwd) throws Exception {
        final Hashtable<String, Object> env = new Hashtable<String, Object>();
        env.put(DirectoryService.JNDI_KEY, directoryService);
        env.put(Context.SECURITY_PRINCIPAL, user);
        env.put(Context.SECURITY_CREDENTIALS, passwd);
        env.put(Context.SECURITY_AUTHENTICATION, "none");
        env.put(Context.INITIAL_CONTEXT_FACTORY, CoreContextFactory.class.getName());
        setContexts(env);
    }

    /*
     * protected LdapContext getWiredContext( String bindPrincipalDn, String
     * password ) throws Exception { // if ( ! apacheDS.isStarted() ) // { //
     * throw new ConfigurationException( "The server is not online! Cannot
     * connect to it." ); // }
     * 
     * Hashtable<String, String> env = new Hashtable<String, String>();
     * env.put( Context.INITIAL_CONTEXT_FACTORY, CTX_FACTORY ); env.put(
     * Context.PROVIDER_URL, "ldap://localhost:" + port ); env.put(
     * Context.SECURITY_PRINCIPAL, bindPrincipalDn ); env.put(
     * Context.SECURITY_CREDENTIALS, password ); env.put(
     * Context.SECURITY_AUTHENTICATION, "simple" ); return new
     * InitialLdapContext( env, null ); }
     * 
     * protected LdapContext getWiredContext() throws Exception { return
     * getWiredContext( ServerDNConstants.ADMIN_SYSTEM_DN, "secret" ); }
     */
    /**
     * Sets the system context root to null.
     * 
     * @see junit.framework.TestCase#tearDown()
     */
    public synchronized void stop() throws Exception {
        logger.debug("DS is stopping ...");

        if (!running) {
            logger.debug("stop() called while is not running");

            if (checkSocketNotConnected()) {
                return;
            } else {
                logger.debug("stop() forced");
            }
        }

        ldapService.stop();
        ldapSService.stop();

        directoryService.shutdown();

        doDelete(directoryService.getWorkingDirectory());

        sysRoot = null;
        this.rootDSE = null;

        logger.debug("DS waiting for socket release ...");

        // wait for shutdown
        int i = 0;

        while ((i < 20) && !checkSocketNotConnected()) {
            Thread.sleep(2000);
            i++;
            logger.debug("Try " + i);
        }

        if (!checkSocketNotConnected()) {
            throw new Exception("Shutdown of DS not successfull, server socket was not freed");
        }

        logger.debug("DS now stopped!");
        running = false;

    }

    /**
     * Imports the LDIF entries packaged with the Eve JNDI provider jar into the
     * newly created system partition to prime it up for operation. Note that
     * only ou=system entries will be added - entries for other partitions
     * cannot be imported and will blow chunks.
     * 
     * @throws NamingException
     *             if there are problems reading the ldif file and adding those
     *             entries to the system partition
     */
    protected void importLdif(final InputStream in) throws NamingException {
        if (in == null) {
            throw new NullPointerException("in must not be null");
        }

        try {
            final Iterator<LdifEntry> iterator = new LdifReader(in).iterator();

            while (iterator.hasNext()) {
                final LdifEntry entry = iterator.next();

                final LdapDN dn = new LdapDN(entry.getDn());
                // dn.remove(0);
                // dn.remove(0);

                final Attributes attr = new BasicAttributes();

                final Iterator<EntryAttribute> iea = entry.getEntry().iterator();

                for (; iea.hasNext();) {
                    final EntryAttribute ea = iea.next();

                    attr.put(ea.getId(), ea.get().get());

                    logger.debug("id " + ea.getId() + "//" + ea.get().get());
                    logger.debug("size:" + ea.size());
                }

                logger.debug(" for dn:" + dn);

                root.createSubcontext(dn, attr);
            }
        } catch (final Exception e) {
            final String msg = "failed while trying to parse system ldif file";
            final NamingException ne = new LdapConfigurationException(msg);
            ne.setRootCause(e);
            throw ne;
        }
    }

    public static boolean checkSocketNotConnected() {

        try {
            final Socket s = new Socket("localhost", 10389);

            if (s.isConnected()) {
                logger.debug("client socket is connected (server socket bound)");
            }
            s.close();
            return false;
        } catch (final Exception e) {

            logger.debug("client Socket not connected " + e.toString());

        }

        try {
            final ServerSocket s = new ServerSocket(10389);
            if (s.isBound()) {
                logger.debug("server socket is bound (=was therefore free)");
            }
            s.close();
            return true;
        } catch (final Exception e) {
            logger.debug("Server socket already bound " + e.toString());
            // e.printStackTrace();
            return false;
        }

    }

    public static void main(final String[] args) throws Exception {
        final DSManager m = DSManager.getInstance();
        m.start(true);

        System.out.println("Enter s and Enter to stop: ");

        while (System.in.read() != 115) {
            ;
            // logger.debug.println(i);
        }

        m.stop();

        System.out.println("main() finished");
    }

    public int getPort() {
        return port;
    }

    public static IoFilterChainBuilder init(final KeyStore ks) throws NamingException {
        SSLContext sslCtx;
        try {
            // Set up key manager factory to use our key store
            String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm");
            if (algorithm == null) {
                algorithm = "SunX509";
            }
            final KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
            kmf.init(ks, "changeit".toCharArray());

            // Initialize the SSLContext to work with our key managers.
            sslCtx = SSLContext.getInstance("TLS");
            sslCtx.init(kmf.getKeyManagers(), new TrustManager[] { new ServerX509TrustManager() },
                    new SecureRandom());

            logger.debug("ssl set");
        } catch (final Exception e) {
            throw (NamingException) new NamingException("Failed to create a SSL context.").initCause(e);
        }

        final DefaultIoFilterChainBuilder chain = new DefaultIoFilterChainBuilder();
        chain.addLast("sslFilter", new SSLFilter(sslCtx));
        return chain;
    }

}