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