001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.core.net; 018 019import java.io.IOException; 020import java.io.OutputStream; 021import java.io.Serializable; 022import java.net.InetAddress; 023import java.net.InetSocketAddress; 024import java.net.Socket; 025import java.util.List; 026 027import javax.net.ssl.SSLSocket; 028import javax.net.ssl.SSLSocketFactory; 029 030import org.apache.logging.log4j.core.Layout; 031import org.apache.logging.log4j.core.net.ssl.SslConfiguration; 032import org.apache.logging.log4j.util.Strings; 033 034/** 035 * 036 */ 037public class SslSocketManager extends TcpSocketManager { 038 public static final int DEFAULT_PORT = 6514; 039 private static final SslSocketManagerFactory FACTORY = new SslSocketManagerFactory(); 040 private final SslConfiguration sslConfig; 041 042 /** 043 * 044 * 045 * @param name The unique name of this connection. 046 * @param os The OutputStream. 047 * @param sock The Socket. 048 * @param inetAddress The Internet address of the host. 049 * @param host The name of the host. 050 * @param port The port number on the host. 051 * @param connectTimeoutMillis the connect timeout in milliseconds. 052 * @param reconnectionDelayMillis Reconnection interval. 053 * @param immediateFail 054 * @param layout The Layout. 055 * @param bufferSize The buffer size. 056 * @deprecated Use {@link #SslSocketManager(String, OutputStream, Socket, SslConfiguration, InetAddress, String, int, int, int, boolean, Layout, int, SocketOptions)}. 057 */ 058 @Deprecated 059 public SslSocketManager(final String name, final OutputStream os, final Socket sock, 060 final SslConfiguration sslConfig, final InetAddress inetAddress, final String host, final int port, 061 final int connectTimeoutMillis, final int reconnectionDelayMillis, final boolean immediateFail, 062 final Layout<? extends Serializable> layout, final int bufferSize) { 063 super(name, os, sock, inetAddress, host, port, connectTimeoutMillis, reconnectionDelayMillis, immediateFail, layout, bufferSize, null); 064 this.sslConfig = sslConfig; 065 } 066 067 /** 068 * 069 * 070 * @param name The unique name of this connection. 071 * @param os The OutputStream. 072 * @param sock The Socket. 073 * @param inetAddress The Internet address of the host. 074 * @param host The name of the host. 075 * @param port The port number on the host. 076 * @param connectTimeoutMillis the connect timeout in milliseconds. 077 * @param reconnectionDelayMillis Reconnection interval. 078 * @param immediateFail 079 * @param layout The Layout. 080 * @param bufferSize The buffer size. 081 */ 082 public SslSocketManager(final String name, final OutputStream os, final Socket sock, 083 final SslConfiguration sslConfig, final InetAddress inetAddress, final String host, final int port, 084 final int connectTimeoutMillis, final int reconnectionDelayMillis, final boolean immediateFail, 085 final Layout<? extends Serializable> layout, final int bufferSize, final SocketOptions socketOptions) { 086 super(name, os, sock, inetAddress, host, port, connectTimeoutMillis, reconnectionDelayMillis, immediateFail, layout, bufferSize, socketOptions); 087 this.sslConfig = sslConfig; 088 } 089 090 private static class SslFactoryData extends FactoryData { 091 protected SslConfiguration sslConfiguration; 092 093 public SslFactoryData(final SslConfiguration sslConfiguration, final String host, final int port, 094 final int connectTimeoutMillis, final int reconnectDelayMillis, final boolean immediateFail, 095 final Layout<? extends Serializable> layout, final int bufferSize, final SocketOptions socketOptions) { 096 super(host, port, connectTimeoutMillis, reconnectDelayMillis, immediateFail, layout, bufferSize, 097 socketOptions); 098 this.sslConfiguration = sslConfiguration; 099 } 100 101 @Override 102 public String toString() { 103 return "SslFactoryData [sslConfiguration=" + sslConfiguration + ", host=" + host + ", port=" + port 104 + ", connectTimeoutMillis=" + connectTimeoutMillis + ", reconnectDelayMillis=" 105 + reconnectDelayMillis + ", immediateFail=" + immediateFail + ", layout=" + layout + ", bufferSize=" 106 + bufferSize + ", socketOptions=" + socketOptions + "]"; 107 } 108 } 109 110 /** 111 * @deprecated Use {@link SslSocketManager#getSocketManager(SslConfiguration, String, int, int, int, boolean, Layout, int, SocketOptions)}. 112 */ 113 @Deprecated 114 public static SslSocketManager getSocketManager(final SslConfiguration sslConfig, final String host, final int port, 115 final int connectTimeoutMillis, final int reconnectDelayMillis, final boolean immediateFail, 116 final Layout<? extends Serializable> layout, final int bufferSize) { 117 return getSocketManager(sslConfig, host, port, connectTimeoutMillis, reconnectDelayMillis, immediateFail, layout, bufferSize, null); 118 } 119 120 public static SslSocketManager getSocketManager(final SslConfiguration sslConfig, final String host, int port, 121 final int connectTimeoutMillis, int reconnectDelayMillis, final boolean immediateFail, 122 final Layout<? extends Serializable> layout, final int bufferSize, final SocketOptions socketOptions) { 123 if (Strings.isEmpty(host)) { 124 throw new IllegalArgumentException("A host name is required"); 125 } 126 if (port <= 0) { 127 port = DEFAULT_PORT; 128 } 129 if (reconnectDelayMillis == 0) { 130 reconnectDelayMillis = DEFAULT_RECONNECTION_DELAY_MILLIS; 131 } 132 final String name = "TLS:" + host + ':' + port; 133 return (SslSocketManager) getManager(name, new SslFactoryData(sslConfig, host, port, connectTimeoutMillis, 134 reconnectDelayMillis, immediateFail, layout, bufferSize, socketOptions), FACTORY); 135 } 136 137 @Override 138 protected Socket createSocket(final InetSocketAddress socketAddress) throws IOException { 139 final SSLSocketFactory socketFactory = createSslSocketFactory(sslConfig); 140 final Socket newSocket = socketFactory.createSocket(); 141 newSocket.connect(socketAddress, 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, final OutputStream os, final Socket socket, final 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 List<InetSocketAddress> socketAddresses = resolver.resolveHost(data.host, data.port); 171 IOException ioe = null; 172 for (InetSocketAddress socketAddress : socketAddresses) { 173 try { 174 return SslSocketManager.createSocket(socketAddress, data.connectTimeoutMillis, 175 data.sslConfiguration, data.socketOptions); 176 } catch (IOException ex) { 177 ioe = ex; 178 } 179 } 180 throw new IOException(errorMessage(data, socketAddresses) , ioe); 181 } 182 } 183 184 static Socket createSocket(final InetSocketAddress socketAddress, final int connectTimeoutMillis, 185 final SslConfiguration sslConfiguration, final SocketOptions socketOptions) throws IOException { 186 final SSLSocketFactory socketFactory = createSslSocketFactory(sslConfiguration); 187 final SSLSocket socket = (SSLSocket) socketFactory.createSocket(); 188 if (socketOptions != null) { 189 // Not sure which options must be applied before or after the connect() call. 190 socketOptions.apply(socket); 191 } 192 socket.connect(socketAddress, connectTimeoutMillis); 193 if (socketOptions != null) { 194 // Not sure which options must be applied before or after the connect() call. 195 socketOptions.apply(socket); 196 } 197 return socket; 198 } 199}