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 org.apache.logging.log4j.core.Layout; 020import org.apache.logging.log4j.core.appender.ManagerFactory; 021import org.apache.logging.log4j.core.helpers.Strings; 022import org.apache.logging.log4j.core.net.ssl.SSLConfiguration; 023 024import javax.net.ssl.SSLSocket; 025import javax.net.ssl.SSLSocketFactory; 026import java.io.ByteArrayOutputStream; 027import java.io.IOException; 028import java.io.OutputStream; 029import java.net.InetAddress; 030import java.net.Socket; 031import java.net.UnknownHostException; 032 033/** 034 * 035 */ 036public class TLSSocketManager extends TCPSocketManager { 037 public static final int DEFAULT_PORT = 6514; 038 private static final TLSSocketManagerFactory FACTORY = new TLSSocketManagerFactory(); 039 private 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 addr 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 delay Reconnection interval. 051 * @param immediateFail 052 * @param layout The Layout. 053 */ 054 public TLSSocketManager(String name, OutputStream os, Socket sock, SSLConfiguration sslConfig, InetAddress addr, 055 String host, int port, int delay, boolean immediateFail, Layout layout) { 056 super(name, os, sock, addr, host, port, delay, immediateFail, layout); 057 this.sslConfig = sslConfig; 058 } 059 060 private static class TLSFactoryData { 061 protected SSLConfiguration sslConfig; 062 private final String host; 063 private final int port; 064 private final int delay; 065 private final boolean immediateFail; 066 private final Layout layout; 067 068 public TLSFactoryData(SSLConfiguration sslConfig, String host, int port, int delay, boolean immediateFail, 069 Layout layout) { 070 this.host = host; 071 this.port = port; 072 this.delay = delay; 073 this.immediateFail = immediateFail; 074 this.layout = layout; 075 this.sslConfig = sslConfig; 076 } 077 } 078 079 public static TLSSocketManager getSocketManager(final SSLConfiguration sslConfig, final String host, int port, 080 int delay, final boolean immediateFail, final Layout layout ) { 081 if (Strings.isEmpty(host)) { 082 throw new IllegalArgumentException("A host name is required"); 083 } 084 if (port <= 0) { 085 port = DEFAULT_PORT; 086 } 087 if (delay == 0) { 088 delay = DEFAULT_RECONNECTION_DELAY; 089 } 090 return (TLSSocketManager) getManager("TLS:" + host + ":" + port, 091 new TLSFactoryData(sslConfig, host, port, delay, immediateFail, layout), FACTORY); 092 } 093 094 @Override 095 protected Socket createSocket(String host, int port) throws IOException { 096 SSLSocketFactory socketFactory = createSSLSocketFactory(sslConfig); 097 return socketFactory.createSocket(host, port); 098 } 099 100 private static SSLSocketFactory createSSLSocketFactory(SSLConfiguration sslConf) { 101 SSLSocketFactory socketFactory; 102 103 if (sslConf != null) { 104 socketFactory = sslConf.getSSLSocketFactory(); 105 } else { 106 socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 107 } 108 109 return socketFactory; 110 } 111 112 113 private static class TLSSocketManagerFactory implements ManagerFactory<TLSSocketManager, TLSFactoryData> { 114 115 private class TLSSocketManagerFactoryException extends Exception { 116 117 private static final long serialVersionUID = 1L; 118 } 119 120 @Override 121 public TLSSocketManager createManager(final String name, final TLSFactoryData data) { 122 InetAddress address = null; 123 OutputStream os = null; 124 Socket socket = null; 125 126 try { 127 address = resolveAddress(data.host); 128 socket = createSocket(data); 129 os = socket.getOutputStream(); 130 checkDelay(data.delay, os); 131 } 132 catch (IOException e) { 133 LOGGER.error("TLSSocketManager (" + name + ") " + e); 134 os = new ByteArrayOutputStream(); 135 } 136 catch (TLSSocketManagerFactoryException e) { 137 return null; 138 } 139 return createManager(name, os, socket, data.sslConfig, address, data.host, data.port, data.delay, data.immediateFail, data.layout); 140 } 141 142 private InetAddress resolveAddress(String hostName) throws TLSSocketManagerFactoryException { 143 InetAddress address; 144 145 try { 146 address = InetAddress.getByName(hostName); 147 } catch (final UnknownHostException ex) { 148 LOGGER.error("Could not find address of " + hostName, ex); 149 throw new TLSSocketManagerFactoryException(); 150 } 151 152 return address; 153 } 154 155 private void checkDelay(int delay, OutputStream os) throws TLSSocketManagerFactoryException { 156 if (delay == 0 && os == null) { 157 throw new TLSSocketManagerFactoryException(); 158 } 159 } 160 161 private Socket createSocket(TLSFactoryData data) throws IOException { 162 SSLSocketFactory socketFactory; 163 SSLSocket socket; 164 165 socketFactory = createSSLSocketFactory(data.sslConfig); 166 socket = (SSLSocket) socketFactory.createSocket(data.host, data.port); 167 return socket; 168 } 169 170 private TLSSocketManager createManager(String name, OutputStream os, Socket socket, SSLConfiguration sslConfig, InetAddress address, String host, int port, int delay, boolean immediateFail, Layout layout) { 171 return new TLSSocketManager(name, os, socket, sslConfig, address, host, port, delay, immediateFail, layout); 172 } 173 } 174}