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; 025 026import javax.net.ssl.SSLSocket; 027import javax.net.ssl.SSLSocketFactory; 028 029import org.apache.logging.log4j.core.Layout; 030import org.apache.logging.log4j.core.net.ssl.SslConfiguration; 031import org.apache.logging.log4j.util.Strings; 032 033/** 034 * 035 */ 036public class SslSocketManager extends TcpSocketManager { 037 public static final int DEFAULT_PORT = 6514; 038 private static final SslSocketManagerFactory FACTORY = new SslSocketManagerFactory(); 039 private final SslConfiguration sslConfig; 040 041 /** 042 * 043 * 044 * @param name The unique name of this connection. 045 * @param os The OutputStream. 046 * @param sock The Socket. 047 * @param inetAddress The Internet address of the host. 048 * @param host The name of the host. 049 * @param port The port number on the host. 050 * @param connectTimeoutMillis the connect timeout in milliseconds. 051 * @param reconnectionDelayMillis Reconnection interval. 052 * @param immediateFail 053 * @param layout The Layout. 054 * @param bufferSize The buffer size. 055 * @deprecated Use {@link #SslSocketManager(String, OutputStream, Socket, SslConfiguration, InetAddress, String, int, int, int, boolean, Layout, int, SocketOptions)}. 056 */ 057 @Deprecated 058 public SslSocketManager(final String name, final OutputStream os, final Socket sock, 059 final SslConfiguration sslConfig, final InetAddress inetAddress, final String host, final int port, 060 final int connectTimeoutMillis, final int reconnectionDelayMillis, final boolean immediateFail, 061 final Layout<? extends Serializable> layout, final int bufferSize) { 062 super(name, os, sock, inetAddress, host, port, connectTimeoutMillis, reconnectionDelayMillis, immediateFail, layout, bufferSize, null); 063 this.sslConfig = sslConfig; 064 } 065 066 /** 067 * 068 * 069 * @param name The unique name of this connection. 070 * @param os The OutputStream. 071 * @param sock The Socket. 072 * @param inetAddress The Internet address of the host. 073 * @param host The name of the host. 074 * @param port The port number on the host. 075 * @param connectTimeoutMillis the connect timeout in milliseconds. 076 * @param reconnectionDelayMillis Reconnection interval. 077 * @param immediateFail 078 * @param layout The Layout. 079 * @param bufferSize The buffer size. 080 */ 081 public SslSocketManager(final String name, final OutputStream os, final Socket sock, 082 final SslConfiguration sslConfig, final InetAddress inetAddress, final String host, final int port, 083 final int connectTimeoutMillis, final int reconnectionDelayMillis, final boolean immediateFail, 084 final Layout<? extends Serializable> layout, final int bufferSize, final SocketOptions socketOptions) { 085 super(name, os, sock, inetAddress, host, port, connectTimeoutMillis, reconnectionDelayMillis, immediateFail, layout, bufferSize, socketOptions); 086 this.sslConfig = sslConfig; 087 } 088 089 private static class SslFactoryData extends FactoryData { 090 protected SslConfiguration sslConfiguration; 091 092 public SslFactoryData(final SslConfiguration sslConfiguration, final String host, final int port, 093 final int connectTimeoutMillis, final int reconnectDelayMillis, final boolean immediateFail, 094 final Layout<? extends Serializable> layout, final int bufferSize, final SocketOptions socketOptions) { 095 super(host, port, connectTimeoutMillis, reconnectDelayMillis, immediateFail, layout, bufferSize, 096 socketOptions); 097 this.sslConfiguration = sslConfiguration; 098 } 099 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, 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 return SslSocketManager.createSocket(data.host, data.port, data.connectTimeoutMillis, data.sslConfiguration, 171 data.socketOptions); 172 } 173 } 174 175 static Socket createSocket(final String host, final int port, final int connectTimeoutMillis, 176 final SslConfiguration sslConfiguration, final 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}