Skip to content

Commit 9643c22

Browse files
jvzvy
andauthored
Fix nullability issues in SslConfiguration (#3953)
Co-authored-by: Volkan Yazıcı <volkan@yazi.ci>
1 parent 141a54e commit 9643c22

File tree

9 files changed

+105
-22
lines changed

9 files changed

+105
-22
lines changed

log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/TlsSyslogAppenderTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ private void initServerSocketFactory() throws StoreConfigurationException {
8383
final TrustStoreConfiguration tsc = new TrustStoreConfiguration(
8484
SslKeyStoreConstants.TRUSTSTORE_LOCATION, SslKeyStoreConstants::TRUSTSTORE_PWD, null, null);
8585
sslConfiguration = SslConfiguration.createSSLConfiguration(null, ksc, tsc);
86-
serverSocketFactory = sslConfiguration.getSslContext().getServerSocketFactory();
86+
serverSocketFactory = sslConfiguration.getSslContext() != null
87+
? sslConfiguration.getSslContext().getServerSocketFactory()
88+
: (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
8789
}
8890

8991
private void initTlsTestEnvironment(final int numberOfMessages, final TlsSyslogMessageFormat messageFormat)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.log4j.core.net.ssl;
18+
19+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
20+
21+
import org.apache.logging.log4j.core.layout.PatternLayout;
22+
import org.apache.logging.log4j.core.net.SslSocketManager;
23+
import org.junit.jupiter.api.Test;
24+
import org.junitpioneer.jupiter.Issue;
25+
26+
class SslSocketManagerTest {
27+
@Issue("https://github.com/apache/logging-log4j2/issues/3947")
28+
@Test
29+
void shouldNotThrowExceptionWhenConfiguringTrustStore() {
30+
final TrustStoreConfiguration trustStoreConfiguration = assertDoesNotThrow(() -> new TrustStoreConfiguration(
31+
SslKeyStoreConstants.TRUSTSTORE_LOCATION,
32+
SslKeyStoreConstants::TRUSTSTORE_PWD,
33+
SslKeyStoreConstants.TRUSTSTORE_TYPE,
34+
null));
35+
final SslConfiguration sslConfiguration =
36+
SslConfiguration.createSSLConfiguration(null, null, trustStoreConfiguration);
37+
assertDoesNotThrow(() -> {
38+
// noinspection EmptyTryBlock (try-with-resources to close `SslSocketManager`, even on failure
39+
try (final SslSocketManager ignored = SslSocketManager.getSocketManager(
40+
sslConfiguration, "localhost", 0, 0, 0, true, PatternLayout.createDefaultLayout(), 8192, null)) {
41+
// Do nothing
42+
}
43+
});
44+
}
45+
}

log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
import java.net.HttpURLConnection;
2424
import java.net.URL;
2525
import java.nio.charset.Charset;
26+
import java.nio.charset.StandardCharsets;
2627
import java.util.Objects;
2728
import javax.net.ssl.HttpsURLConnection;
29+
import javax.net.ssl.SSLContext;
2830
import org.apache.logging.log4j.core.Layout;
2931
import org.apache.logging.log4j.core.LogEvent;
3032
import org.apache.logging.log4j.core.LoggerContext;
@@ -37,7 +39,7 @@
3739

3840
public class HttpURLConnectionManager extends HttpManager {
3941

40-
private static final Charset CHARSET = Charset.forName("US-ASCII");
42+
private static final Charset CHARSET = StandardCharsets.US_ASCII;
4143

4244
private final URL url;
4345
private final boolean isHttps;
@@ -100,8 +102,10 @@ public void send(final Layout<?> layout, final LogEvent event) throws IOExceptio
100102
header.getName(), header.evaluate(getConfiguration().getStrSubstitutor()));
101103
}
102104
if (sslConfiguration != null) {
103-
((HttpsURLConnection) urlConnection)
104-
.setSSLSocketFactory(sslConfiguration.getSslContext().getSocketFactory());
105+
final SSLContext sslContext = sslConfiguration.getSslContext();
106+
if (sslContext != null) {
107+
((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslContext.getSocketFactory());
108+
}
105109
}
106110
if (isHttps && !verifyHostname) {
107111
((HttpsURLConnection) urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);

log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import javax.mail.internet.MimeMultipart;
3636
import javax.mail.internet.MimeUtility;
3737
import javax.mail.util.ByteArrayDataSource;
38+
import javax.net.ssl.SSLContext;
3839
import javax.net.ssl.SSLSocketFactory;
3940
import org.apache.logging.log4j.LoggingException;
4041
import org.apache.logging.log4j.core.Layout;
@@ -308,9 +309,11 @@ public SmtpManager createManager(final String name, final FactoryData data) {
308309
if (smtpProtocol.equals("smtps")) {
309310
final SslConfiguration sslConfiguration = data.getSslConfiguration();
310311
if (sslConfiguration != null) {
311-
final SSLSocketFactory sslSocketFactory =
312-
sslConfiguration.getSslContext().getSocketFactory();
313-
properties.put(prefix + ".ssl.socketFactory", sslSocketFactory);
312+
final SSLContext sslContext = sslConfiguration.getSslContext();
313+
if (sslContext != null) {
314+
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
315+
properties.put(prefix + ".ssl.socketFactory", sslSocketFactory);
316+
}
314317
properties.setProperty(
315318
prefix + ".ssl.checkserveridentity", Boolean.toString(sslConfiguration.isVerifyHostName()));
316319
}

log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
import java.util.Collections;
2828
import java.util.Enumeration;
2929
import java.util.List;
30+
import java.util.Objects;
3031
import java.util.stream.Collectors;
3132
import java.util.stream.Stream;
33+
import javax.net.ssl.SSLContext;
3234
import javax.net.ssl.SSLSocket;
3335
import javax.net.ssl.SSLSocketFactory;
3436
import org.apache.logging.log4j.core.Layout;
@@ -245,6 +247,7 @@ public static SslSocketManager getSocketManager(
245247
*/
246248
private static String createSslConfigurationId(final SslConfiguration sslConfig) {
247249
return String.valueOf(Stream.of(sslConfig.getKeyStoreConfig(), sslConfig.getTrustStoreConfig())
250+
.filter(Objects::nonNull)
248251
.flatMap(keyStoreConfig -> {
249252
final Enumeration<String> aliases;
250253
try {
@@ -289,15 +292,13 @@ protected Socket createSocket(final InetSocketAddress socketAddress) throws IOEx
289292
}
290293

291294
private static SSLSocketFactory createSslSocketFactory(final SslConfiguration sslConf) {
292-
SSLSocketFactory socketFactory;
293-
294295
if (sslConf != null) {
295-
socketFactory = sslConf.getSslContext().getSocketFactory();
296-
} else {
297-
socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
296+
final SSLContext sslContext = sslConf.getSslContext();
297+
if (sslContext != null) {
298+
return sslContext.getSocketFactory();
299+
}
298300
}
299-
300-
return socketFactory;
301+
return (SSLSocketFactory) SSLSocketFactory.getDefault();
301302
}
302303

303304
private static class SslSocketManagerFactory extends TcpSocketManagerFactory<SslSocketManager, SslFactoryData> {

log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Arrays;
2929
import java.util.List;
3030
import javax.net.ssl.HttpsURLConnection;
31+
import javax.net.ssl.SSLContext;
3132
import org.apache.logging.log4j.core.config.ConfigurationFactory;
3233
import org.apache.logging.log4j.core.net.ssl.LaxHostnameVerifier;
3334
import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
@@ -120,10 +121,13 @@ public static <T extends URLConnection> T createConnection(
120121
httpURLConnection.setIfModifiedSince(lastModifiedMillis);
121122
}
122123
if (url.getProtocol().equals(HTTPS) && sslConfiguration != null) {
123-
((HttpsURLConnection) httpURLConnection)
124-
.setSSLSocketFactory(sslConfiguration.getSslContext().getSocketFactory());
124+
final SSLContext sslContext = sslConfiguration.getSslContext();
125+
final HttpsURLConnection httpsURLConnection = (HttpsURLConnection) httpURLConnection;
126+
if (sslContext != null) {
127+
httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
128+
}
125129
if (!sslConfiguration.isVerifyHostName()) {
126-
((HttpsURLConnection) httpURLConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
130+
httpsURLConnection.setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
127131
}
128132
}
129133
urlConnection = httpURLConnection;

log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public class SslConfiguration {
5454
@Nullable
5555
private final TrustStoreConfiguration trustStoreConfig;
5656

57+
@Nullable
5758
private final transient SSLContext sslContext;
5859

5960
private SslConfiguration(
@@ -88,8 +89,9 @@ public void clearSecrets() {
8889
* @deprecated Use {@link SSLContext#getSocketFactory()} on {@link #getSslContext()}
8990
*/
9091
@Deprecated
92+
@Nullable
9193
public SSLSocketFactory getSslSocketFactory() {
92-
return sslContext.getSocketFactory();
94+
return sslContext != null ? sslContext.getSocketFactory() : null;
9395
}
9496

9597
/**
@@ -99,10 +101,12 @@ public SSLSocketFactory getSslSocketFactory() {
99101
* @deprecated Use {@link SSLContext#getServerSocketFactory()} on {@link #getSslContext()}
100102
*/
101103
@Deprecated
104+
@Nullable
102105
public SSLServerSocketFactory getSslServerSocketFactory() {
103-
return sslContext.getServerSocketFactory();
106+
return sslContext != null ? sslContext.getServerSocketFactory() : null;
104107
}
105108

109+
@Nullable
106110
private static SSLContext createDefaultSslContext(final String protocol) {
107111
try {
108112
return SSLContext.getDefault();
@@ -121,6 +125,7 @@ private static SSLContext createDefaultSslContext(final String protocol) {
121125
}
122126
}
123127

128+
@Nullable
124129
private static SSLContext createSslContext(
125130
final String protocol,
126131
@Nullable final KeyStoreConfiguration keyStoreConfig,
@@ -242,14 +247,17 @@ public boolean isVerifyHostName() {
242247
return verifyHostName;
243248
}
244249

250+
@Nullable
245251
public KeyStoreConfiguration getKeyStoreConfig() {
246252
return keyStoreConfig;
247253
}
248254

255+
@Nullable
249256
public TrustStoreConfiguration getTrustStoreConfig() {
250257
return trustStoreConfig;
251258
}
252259

260+
@Nullable
253261
public SSLContext getSslContext() {
254262
return sslContext;
255263
}

log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.io.OutputStream;
3737
import java.util.Date;
3838
import java.util.Properties;
39+
import javax.net.ssl.SSLContext;
3940
import javax.net.ssl.SSLSocketFactory;
4041
import org.apache.logging.log4j.LoggingException;
4142
import org.apache.logging.log4j.core.Layout;
@@ -262,9 +263,11 @@ public SmtpManager createManager(final String name, final FactoryData data) {
262263
if (smtpProtocol.equals("smtps")) {
263264
final SslConfiguration sslConfiguration = data.getSslConfiguration();
264265
if (sslConfiguration != null) {
265-
final SSLSocketFactory sslSocketFactory =
266-
sslConfiguration.getSslContext().getSocketFactory();
267-
properties.put(prefix + ".ssl.socketFactory", sslSocketFactory);
266+
final SSLContext sslContext = sslConfiguration.getSslContext();
267+
if (sslContext != null) {
268+
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
269+
properties.put(prefix + ".ssl.socketFactory", sslSocketFactory);
270+
}
268271
properties.setProperty(
269272
prefix + ".ssl.checkserveridentity", Boolean.toString(sslConfiguration.isVerifyHostName()));
270273
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns="https://logging.apache.org/xml/ns"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="
5+
https://logging.apache.org/xml/ns
6+
https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
7+
type="fixed">
8+
<issue id="3947" link="https://github.com/apache/logging-log4j2/issues/3947"/>
9+
<issue id="3953" link="https://github.com/apache/logging-log4j2/pull/3953"/>
10+
<description format="asciidoc">
11+
Fix failures caused by null `SslConfiguration`
12+
</description>
13+
</entry>

0 commit comments

Comments
 (0)