001/*
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2026, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v2.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic.net;
015
016import java.security.NoSuchAlgorithmException;
017
018import javax.net.ServerSocketFactory;
019import javax.net.ssl.SSLContext;
020
021import ch.qos.logback.classic.LoggerContext;
022import ch.qos.logback.classic.joran.JoranConfigurator;
023import ch.qos.logback.core.net.ssl.ConfigurableSSLServerSocketFactory;
024import ch.qos.logback.core.net.ssl.SSLParametersConfiguration;
025
026/**
027 * A {@link SimpleSocketServer} that supports SSL.
028 * 
029 * <pre>
030 *      &lt;b&gt;Usage:&lt;/b&gt; java ch.qos.logback.classic.net.SimpleSSLSocketServer port configFile
031 *                     allowedAddress [allowedAddress ...]
032 * </pre>
033 * 
034 * where <em>port</em> is a port number where the server listens,
035 * <em>configFile</em> is an XML configuration file fed to
036 * {@link JoranConfigurator}, and each <em>allowedAddress</em> is a client IP
037 * or CIDR range that is permitted to connect (e.g. {@code 192.168.1.10} or
038 * {@code 192.168.1.0/24}). At least one allowed address must be specified on
039 * the command line.
040 * 
041 * <p>
042 * Client IP whitelisting configured via
043 * {@link SimpleSocketServer#addAllowedClientAddress(String)} is mandatory and
044 * applies here as well when the server is embedded programmatically. An empty
045 * whitelist means no clients are allowed.
046 * </p>
047 * 
048 * When running the SimpleSSLServerFactory as shown above, it is necessary to
049 * configure JSSE system properties using {@code -Dname=value} on the
050 * command-line when starting the server. In particular, you will probably
051 * want/need to configure the following system properties:
052 * <ul>
053 * <li>javax.net.ssl.keyStore</li>
054 * <li>javax.net.ssl.keyStorePassword</li>
055 * <li>javax.net.ssl.keyStoreType</li>
056 * <li>javax.net.ssl.trustStore</li>
057 * <li>javax.net.ssl.trustStorePassword</li>
058 * <li>javax.net.ssl.trustStoreType</li>
059 * </ul>
060 * <p>
061 * See the <a href=
062 * "http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#InstallationAndCustomization">
063 * Customizing the JSSE</a> in the JSSE Reference Guide for details on how to
064 * set these system properties.
065 * 
066 * @author Carl Harris
067 */
068public class SimpleSSLSocketServer extends SimpleSocketServer {
069
070    private final ServerSocketFactory socketFactory;
071
072    public static void main(String argv[]) throws Exception {
073        doMain(SimpleSSLSocketServer.class, argv);
074    }
075
076    /**
077     * Creates a new server using the default SSL context.
078     * 
079     * @param lc   logger context for received events
080     * @param port port on which the server is to listen
081     * @throws NoSuchAlgorithmException if the default SSL context cannot be created
082     */
083    public SimpleSSLSocketServer(LoggerContext lc, int port) throws NoSuchAlgorithmException {
084        this(lc, port, SSLContext.getDefault());
085    }
086
087    /**
088     * Creates a new server using a custom SSL context.
089     * 
090     * @param lc         logger context for received events
091     * @param port       port on which the server is to listen
092     * @param sslContext custom SSL context
093     */
094    public SimpleSSLSocketServer(LoggerContext lc, int port, SSLContext sslContext) {
095        super(lc, port);
096        if (sslContext == null) {
097            throw new NullPointerException("SSL context required");
098        }
099        SSLParametersConfiguration parameters = new SSLParametersConfiguration();
100
101        parameters.setContext(lc);
102        this.socketFactory = new ConfigurableSSLServerSocketFactory(parameters, sslContext.getServerSocketFactory());
103    }
104
105    @Override
106    protected ServerSocketFactory getServerSocketFactory() {
107        return socketFactory;
108    }
109
110}