View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.net;
18  
19  import java.io.IOException;
20  import java.io.OutputStream;
21  import java.io.Serializable;
22  import java.net.InetAddress;
23  import java.net.InetSocketAddress;
24  import java.net.Socket;
25  
26  import javax.net.ssl.SSLSocket;
27  import javax.net.ssl.SSLSocketFactory;
28  
29  import org.apache.logging.log4j.core.Layout;
30  import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
31  import org.apache.logging.log4j.util.Strings;
32  
33  /**
34   *
35   */
36  public class SslSocketManager extends TcpSocketManager {
37      public static final int DEFAULT_PORT = 6514;
38      private static final SslSocketManagerFactory FACTORY = new SslSocketManagerFactory();
39      private final SslConfiguration sslConfig;
40  
41      /**
42      *
43      *
44      * @param name          The unique name of this connection.
45      * @param os            The OutputStream.
46      * @param sock          The Socket.
47      * @param inetAddress          The Internet address of the host.
48      * @param host          The name of the host.
49      * @param port          The port number on the host.
50      * @param connectTimeoutMillis the connect timeout in milliseconds.
51      * @param reconnectionDelayMillis         Reconnection interval.
52      * @param immediateFail
53      * @param layout        The Layout.
54      * @param bufferSize The buffer size.
55      * @deprecated Use {@link #SslSocketManager(String, OutputStream, Socket, SslConfiguration, InetAddress, String, int, int, int, boolean, Layout, int, SocketOptions)}.
56      */
57     @Deprecated
58     public SslSocketManager(final String name, final OutputStream os, final Socket sock,
59             final SslConfiguration sslConfig, final InetAddress inetAddress, final String host, final int port,
60             final int connectTimeoutMillis, final int reconnectionDelayMillis, final boolean immediateFail,
61             final Layout<? extends Serializable> layout, final int bufferSize) {
62         super(name, os, sock, inetAddress, host, port, connectTimeoutMillis, reconnectionDelayMillis, immediateFail, layout, bufferSize, null);
63         this.sslConfig = sslConfig;
64     }
65  
66     /**
67     *
68     *
69     * @param name          The unique name of this connection.
70     * @param os            The OutputStream.
71     * @param sock          The Socket.
72     * @param inetAddress          The Internet address of the host.
73     * @param host          The name of the host.
74     * @param port          The port number on the host.
75     * @param connectTimeoutMillis the connect timeout in milliseconds.
76     * @param reconnectionDelayMillis         Reconnection interval.
77     * @param immediateFail
78     * @param layout        The Layout.
79     * @param bufferSize The buffer size.
80     */
81    public SslSocketManager(final String name, final OutputStream os, final Socket sock,
82            final SslConfiguration sslConfig, final InetAddress inetAddress, final String host, final int port,
83            final int connectTimeoutMillis, final int reconnectionDelayMillis, final boolean immediateFail,
84            final Layout<? extends Serializable> layout, final int bufferSize, final SocketOptions socketOptions) {
85        super(name, os, sock, inetAddress, host, port, connectTimeoutMillis, reconnectionDelayMillis, immediateFail, layout, bufferSize, socketOptions);
86        this.sslConfig = sslConfig;
87    }
88  
89      private static class SslFactoryData extends FactoryData {
90          protected SslConfiguration sslConfiguration;
91  
92          public SslFactoryData(final SslConfiguration sslConfiguration, final String host, final int port,
93                  final int connectTimeoutMillis, final int reconnectDelayMillis, final boolean immediateFail,
94                  final Layout<? extends Serializable> layout, final int bufferSize, final SocketOptions socketOptions) {
95              super(host, port, connectTimeoutMillis, reconnectDelayMillis, immediateFail, layout, bufferSize,
96                      socketOptions);
97              this.sslConfiguration = sslConfiguration;
98          }
99  
100         @Override
101         public String toString() {
102             return "SslFactoryData [sslConfiguration=" + sslConfiguration + ", host=" + host + ", port=" + port
103                     + ", connectTimeoutMillis=" + connectTimeoutMillis + ", reconnectDelayMillis="
104                     + reconnectDelayMillis + ", immediateFail=" + immediateFail + ", layout=" + layout + ", bufferSize="
105                     + bufferSize + ", socketOptions=" + socketOptions + "]";
106         }
107     }
108 
109     /**
110      * @deprecated Use {@link SslSocketManager#getSocketManager(SslConfiguration, String, int, int, int, boolean, Layout, int, SocketOptions)}.
111      */
112     @Deprecated
113     public static SslSocketManager getSocketManager(final SslConfiguration sslConfig, final String host, final int port,
114             final int connectTimeoutMillis, final int reconnectDelayMillis, final boolean immediateFail,
115             final Layout<? extends Serializable> layout, final int bufferSize) {
116         return getSocketManager(sslConfig, host, port, connectTimeoutMillis, reconnectDelayMillis, immediateFail, layout, bufferSize, null);
117     }
118 
119     public static SslSocketManager getSocketManager(final SslConfiguration sslConfig, final String host, int port,
120             final int connectTimeoutMillis, int reconnectDelayMillis, final boolean immediateFail,
121             final Layout<? extends Serializable> layout, final int bufferSize, final SocketOptions socketOptions) {
122         if (Strings.isEmpty(host)) {
123             throw new IllegalArgumentException("A host name is required");
124         }
125         if (port <= 0) {
126             port = DEFAULT_PORT;
127         }
128         if (reconnectDelayMillis == 0) {
129             reconnectDelayMillis = DEFAULT_RECONNECTION_DELAY_MILLIS;
130         }
131         final String name = "TLS:" + host + ':' + port;
132         return (SslSocketManager) getManager(name, new SslFactoryData(sslConfig, host, port, connectTimeoutMillis,
133                 reconnectDelayMillis, immediateFail, layout, bufferSize, socketOptions), FACTORY);
134     }
135 
136     @Override
137     protected Socket createSocket(final String host, final int port) throws IOException {
138         final SSLSocketFactory socketFactory = createSslSocketFactory(sslConfig);
139         final InetSocketAddress address = new InetSocketAddress(host, port);
140         final Socket newSocket = socketFactory.createSocket();
141         newSocket.connect(address, getConnectTimeoutMillis());
142         return newSocket;
143     }
144 
145     private static SSLSocketFactory createSslSocketFactory(final SslConfiguration sslConf) {
146         SSLSocketFactory socketFactory;
147 
148         if (sslConf != null) {
149             socketFactory = sslConf.getSslSocketFactory();
150         } else {
151             socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
152         }
153 
154         return socketFactory;
155     }
156 
157 
158     private static class SslSocketManagerFactory extends TcpSocketManagerFactory<SslSocketManager, SslFactoryData> {
159 
160         @Override
161         SslSocketManager createManager(final String name, OutputStream os, Socket socket, InetAddress inetAddress,
162                 final SslFactoryData data) {
163             return new SslSocketManager(name, os, socket, data.sslConfiguration, inetAddress, data.host, data.port,
164                     data.connectTimeoutMillis, data.reconnectDelayMillis, data.immediateFail, data.layout, data.bufferSize,
165                     data.socketOptions);
166         }
167         
168         @Override
169         Socket createSocket(final SslFactoryData data) throws IOException {
170             return SslSocketManager.createSocket(data.host, data.port, data.connectTimeoutMillis, data.sslConfiguration,
171                     data.socketOptions);
172         }
173     }
174 
175     static Socket createSocket(final String host, int port, int connectTimeoutMillis,
176             final SslConfiguration sslConfiguration, SocketOptions socketOptions) throws IOException {
177         final SSLSocketFactory socketFactory = createSslSocketFactory(sslConfiguration);
178         final SSLSocket socket = (SSLSocket) socketFactory.createSocket();
179         if (socketOptions != null) {
180             // Not sure which options must be applied before or after the connect() call.
181             socketOptions.apply(socket);
182         }
183         socket.connect(new InetSocketAddress(host, port), connectTimeoutMillis);
184         if (socketOptions != null) {
185             // Not sure which options must be applied before or after the connect() call.
186             socketOptions.apply(socket);
187         }
188         return socket;
189     }
190 }