1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.net;
18
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.io.OutputStream;
22 import java.io.Serializable;
23 import java.net.InetAddress;
24 import java.net.InetSocketAddress;
25 import java.net.Socket;
26 import java.net.UnknownHostException;
27
28 import javax.net.ssl.SSLSocket;
29 import javax.net.ssl.SSLSocketFactory;
30
31 import org.apache.logging.log4j.Level;
32 import org.apache.logging.log4j.core.Layout;
33 import org.apache.logging.log4j.core.appender.ManagerFactory;
34 import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
35 import org.apache.logging.log4j.util.Strings;
36
37
38
39
40 public class SslSocketManager extends TcpSocketManager {
41 public static final int DEFAULT_PORT = 6514;
42 private static final SslSocketManagerFactory FACTORY = new SslSocketManagerFactory();
43 private final SslConfiguration sslConfig;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public SslSocketManager(final String name, final OutputStream os, final Socket sock,
60 final SslConfiguration sslConfig, final InetAddress inetAddress, final String host, final int port,
61 int connectTimeoutMillis, final int delay, final boolean immediateFail,
62 final Layout<? extends Serializable> layout) {
63 super(name, os, sock, inetAddress, host, port, connectTimeoutMillis, delay, immediateFail, layout);
64 this.sslConfig = sslConfig;
65 }
66
67 private static class SslFactoryData {
68 protected SslConfiguration sslConfig;
69 private final String host;
70 private final int port;
71 private final int connectTimeoutMillis;
72 private final int delayMillis;
73 private final boolean immediateFail;
74 private final Layout<? extends Serializable> layout;
75
76 public SslFactoryData(final SslConfiguration sslConfig, final String host, final int port,
77 int connectTimeoutMillis, final int delayMillis, final boolean immediateFail,
78 final Layout<? extends Serializable> layout) {
79 this.host = host;
80 this.port = port;
81 this.connectTimeoutMillis = connectTimeoutMillis;
82 this.delayMillis = delayMillis;
83 this.immediateFail = immediateFail;
84 this.layout = layout;
85 this.sslConfig = sslConfig;
86 }
87 }
88
89 public static SslSocketManager getSocketManager(final SslConfiguration sslConfig, final String host, int port,
90 int connectTimeoutMillis, int delayMillis, final boolean immediateFail,
91 final Layout<? extends Serializable> layout) {
92 if (Strings.isEmpty(host)) {
93 throw new IllegalArgumentException("A host name is required");
94 }
95 if (port <= 0) {
96 port = DEFAULT_PORT;
97 }
98 if (delayMillis == 0) {
99 delayMillis = DEFAULT_RECONNECTION_DELAY_MILLIS;
100 }
101 return (SslSocketManager) getManager("TLS:" + host + ':' + port, new SslFactoryData(sslConfig, host, port,
102 connectTimeoutMillis, delayMillis, immediateFail, layout), FACTORY);
103 }
104
105 @Override
106 protected Socket createSocket(final String host, final int port) throws IOException {
107 final SSLSocketFactory socketFactory = createSslSocketFactory(sslConfig);
108 final InetSocketAddress address = new InetSocketAddress(host, port);
109 final Socket newSocket = socketFactory.createSocket();
110 newSocket.connect(address, getConnectTimeoutMillis());
111 return newSocket;
112 }
113
114 private static SSLSocketFactory createSslSocketFactory(final SslConfiguration sslConf) {
115 SSLSocketFactory socketFactory;
116
117 if (sslConf != null) {
118 socketFactory = sslConf.getSslSocketFactory();
119 } else {
120 socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
121 }
122
123 return socketFactory;
124 }
125
126
127 private static class SslSocketManagerFactory implements ManagerFactory<SslSocketManager, SslFactoryData> {
128
129 private class TlsSocketManagerFactoryException extends Exception {
130
131 private static final long serialVersionUID = 1L;
132 }
133
134 @Override
135 public SslSocketManager createManager(final String name, final SslFactoryData data) {
136 InetAddress inetAddress = null;
137 OutputStream os = null;
138 Socket socket = null;
139
140 try {
141 inetAddress = resolveAddress(data.host);
142 socket = createSocket(data);
143 os = socket.getOutputStream();
144 checkDelay(data.delayMillis, os);
145 }
146 catch (final IOException e) {
147 LOGGER.error("SslSocketManager ({})", name, e);
148 os = new ByteArrayOutputStream();
149 }
150 catch (final TlsSocketManagerFactoryException e) {
151 LOGGER.catching(Level.DEBUG, e);
152 return null;
153 }
154 return new SslSocketManager(name, os, socket, data.sslConfig, inetAddress, data.host, data.port, 0,
155 data.delayMillis, data.immediateFail, data.layout);
156 }
157
158 private InetAddress resolveAddress(final String hostName) throws TlsSocketManagerFactoryException {
159 InetAddress address;
160
161 try {
162 address = InetAddress.getByName(hostName);
163 } catch (final UnknownHostException ex) {
164 LOGGER.error("Could not find address of {}", hostName, ex);
165 throw new TlsSocketManagerFactoryException();
166 }
167
168 return address;
169 }
170
171 private void checkDelay(final int delay, final OutputStream os) throws TlsSocketManagerFactoryException {
172 if (delay == 0 && os == null) {
173 throw new TlsSocketManagerFactoryException();
174 }
175 }
176
177 private Socket createSocket(final SslFactoryData data) throws IOException {
178 SSLSocketFactory socketFactory;
179 SSLSocket socket;
180
181 socketFactory = createSslSocketFactory(data.sslConfig);
182 socket = (SSLSocket) socketFactory.createSocket(data.host, data.port);
183 return socket;
184 }
185 }
186 }