You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2025/10/10 18:32:28 UTC
(logging-log4j2) 01/01: Fix nullability issues in `SslConfiguration`
This is an automated email from the ASF dual-hosted git repository.
mattsicker pushed a commit to branch fix/2.x/syslog-truststore
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit d19c9f9f8bd490de10615ea6bf7fb5c9785757df
Author: Matt Sicker <ms...@apple.com>
AuthorDate: Fri Oct 10 13:27:40 2025 -0500
Fix nullability issues in `SslConfiguration`
As discovered in issue #3947, an NPE can be thrown when an `SslConfiguration` returns `null` for its keystore, truststore, or `SSLContext`, in particular, in `SslSocketManager`.
---
.../log4j/core/appender/TlsSyslogAppenderTest.java | 4 +++-
.../log4j/core/appender/HttpURLConnectionManager.java | 10 +++++++---
.../org/apache/logging/log4j/core/net/SmtpManager.java | 9 ++++++---
.../apache/logging/log4j/core/net/SslSocketManager.java | 15 ++++++++-------
.../logging/log4j/core/net/UrlConnectionFactory.java | 10 +++++++---
.../logging/log4j/core/net/ssl/SslConfiguration.java | 12 ++++++++++--
.../java/org/apache/logging/log4j/smtp/SmtpManager.java | 9 ++++++---
.../.2.x.x/3947_fix_SslSocketManager_null_keystore.xml | 14 ++++++++++++++
8 files changed, 61 insertions(+), 22 deletions(-)
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/TlsSyslogAppenderTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/TlsSyslogAppenderTest.java
index b18673e4be..5c6adf8f71 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/TlsSyslogAppenderTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/TlsSyslogAppenderTest.java
@@ -83,7 +83,9 @@ class TlsSyslogAppenderTest extends SyslogAppenderTest {
final TrustStoreConfiguration tsc = new TrustStoreConfiguration(
SslKeyStoreConstants.TRUSTSTORE_LOCATION, SslKeyStoreConstants::TRUSTSTORE_PWD, null, null);
sslConfiguration = SslConfiguration.createSSLConfiguration(null, ksc, tsc);
- serverSocketFactory = sslConfiguration.getSslContext().getServerSocketFactory();
+ serverSocketFactory = sslConfiguration.getSslContext() != null
+ ? sslConfiguration.getSslContext().getServerSocketFactory()
+ : (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
}
private void initTlsTestEnvironment(final int numberOfMessages, final TlsSyslogMessageFormat messageFormat)
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
index a4e9858431..6a49f181c4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
@@ -23,8 +23,10 @@ import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.Objects;
import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.LoggerContext;
@@ -37,7 +39,7 @@ import org.apache.logging.log4j.core.util.IOUtils;
public class HttpURLConnectionManager extends HttpManager {
- private static final Charset CHARSET = Charset.forName("US-ASCII");
+ private static final Charset CHARSET = StandardCharsets.US_ASCII;
private final URL url;
private final boolean isHttps;
@@ -100,8 +102,10 @@ public class HttpURLConnectionManager extends HttpManager {
header.getName(), header.evaluate(getConfiguration().getStrSubstitutor()));
}
if (sslConfiguration != null) {
- ((HttpsURLConnection) urlConnection)
- .setSSLSocketFactory(sslConfiguration.getSslContext().getSocketFactory());
+ final SSLContext sslContext = sslConfiguration.getSslContext();
+ if (sslContext != null) {
+ ((HttpsURLConnection) urlConnection).setSSLSocketFactory(sslContext.getSocketFactory());
+ }
}
if (isHttps && !verifyHostname) {
((HttpsURLConnection) urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
index f129b80fe4..f44132df6d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
@@ -35,6 +35,7 @@ import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.util.ByteArrayDataSource;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import org.apache.logging.log4j.LoggingException;
import org.apache.logging.log4j.core.Layout;
@@ -308,9 +309,11 @@ public class SmtpManager extends MailManager {
if (smtpProtocol.equals("smtps")) {
final SslConfiguration sslConfiguration = data.getSslConfiguration();
if (sslConfiguration != null) {
- final SSLSocketFactory sslSocketFactory =
- sslConfiguration.getSslContext().getSocketFactory();
- properties.put(prefix + ".ssl.socketFactory", sslSocketFactory);
+ final SSLContext sslContext = sslConfiguration.getSslContext();
+ if (sslContext != null) {
+ final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+ properties.put(prefix + ".ssl.socketFactory", sslSocketFactory);
+ }
properties.setProperty(
prefix + ".ssl.checkserveridentity", Boolean.toString(sslConfiguration.isVerifyHostName()));
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
index 4f28e57502..994f11bbce 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
@@ -27,8 +27,10 @@ import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import org.apache.logging.log4j.core.Layout;
@@ -245,6 +247,7 @@ public class SslSocketManager extends TcpSocketManager {
*/
private static String createSslConfigurationId(final SslConfiguration sslConfig) {
return String.valueOf(Stream.of(sslConfig.getKeyStoreConfig(), sslConfig.getTrustStoreConfig())
+ .filter(Objects::nonNull)
.flatMap(keyStoreConfig -> {
final Enumeration<String> aliases;
try {
@@ -289,15 +292,13 @@ public class SslSocketManager extends TcpSocketManager {
}
private static SSLSocketFactory createSslSocketFactory(final SslConfiguration sslConf) {
- SSLSocketFactory socketFactory;
-
if (sslConf != null) {
- socketFactory = sslConf.getSslContext().getSocketFactory();
- } else {
- socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ final SSLContext sslContext = sslConf.getSslContext();
+ if (sslContext != null) {
+ return sslContext.getSocketFactory();
+ }
}
-
- return socketFactory;
+ return (SSLSocketFactory) SSLSocketFactory.getDefault();
}
private static class SslSocketManagerFactory extends TcpSocketManagerFactory<SslSocketManager, SslFactoryData> {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
index e98d3d9a9d..fe57d821d9 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
@@ -28,6 +28,7 @@ import java.net.URLConnection;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
import org.apache.logging.log4j.core.net.ssl.LaxHostnameVerifier;
import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
@@ -120,10 +121,13 @@ public class UrlConnectionFactory {
httpURLConnection.setIfModifiedSince(lastModifiedMillis);
}
if (url.getProtocol().equals(HTTPS) && sslConfiguration != null) {
- ((HttpsURLConnection) httpURLConnection)
- .setSSLSocketFactory(sslConfiguration.getSslContext().getSocketFactory());
+ final SSLContext sslContext = sslConfiguration.getSslContext();
+ final HttpsURLConnection httpsURLConnection = (HttpsURLConnection) httpURLConnection;
+ if (sslContext != null) {
+ httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
+ }
if (!sslConfiguration.isVerifyHostName()) {
- ((HttpsURLConnection) httpURLConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
+ httpsURLConnection.setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
}
}
urlConnection = httpURLConnection;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
index cb24113bd9..41e2fc1031 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
@@ -54,6 +54,7 @@ public class SslConfiguration {
@Nullable
private final TrustStoreConfiguration trustStoreConfig;
+ @Nullable
private final transient SSLContext sslContext;
private SslConfiguration(
@@ -88,8 +89,9 @@ public class SslConfiguration {
* @deprecated Use {@link SSLContext#getSocketFactory()} on {@link #getSslContext()}
*/
@Deprecated
+ @Nullable
public SSLSocketFactory getSslSocketFactory() {
- return sslContext.getSocketFactory();
+ return sslContext != null ? sslContext.getSocketFactory() : null;
}
/**
@@ -99,10 +101,12 @@ public class SslConfiguration {
* @deprecated Use {@link SSLContext#getServerSocketFactory()} on {@link #getSslContext()}
*/
@Deprecated
+ @Nullable
public SSLServerSocketFactory getSslServerSocketFactory() {
- return sslContext.getServerSocketFactory();
+ return sslContext != null ? sslContext.getServerSocketFactory() : null;
}
+ @Nullable
private static SSLContext createDefaultSslContext(final String protocol) {
try {
return SSLContext.getDefault();
@@ -121,6 +125,7 @@ public class SslConfiguration {
}
}
+ @Nullable
private static SSLContext createSslContext(
final String protocol,
@Nullable final KeyStoreConfiguration keyStoreConfig,
@@ -242,14 +247,17 @@ public class SslConfiguration {
return verifyHostName;
}
+ @Nullable
public KeyStoreConfiguration getKeyStoreConfig() {
return keyStoreConfig;
}
+ @Nullable
public TrustStoreConfiguration getTrustStoreConfig() {
return trustStoreConfig;
}
+ @Nullable
public SSLContext getSslContext() {
return sslContext;
}
diff --git a/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java b/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
index ab1963ea23..f98457a410 100644
--- a/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
+++ b/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
@@ -36,6 +36,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.Properties;
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import org.apache.logging.log4j.LoggingException;
import org.apache.logging.log4j.core.Layout;
@@ -262,9 +263,11 @@ public class SmtpManager extends MailManager {
if (smtpProtocol.equals("smtps")) {
final SslConfiguration sslConfiguration = data.getSslConfiguration();
if (sslConfiguration != null) {
- final SSLSocketFactory sslSocketFactory =
- sslConfiguration.getSslContext().getSocketFactory();
- properties.put(prefix + ".ssl.socketFactory", sslSocketFactory);
+ final SSLContext sslContext = sslConfiguration.getSslContext();
+ if (sslContext != null) {
+ final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+ properties.put(prefix + ".ssl.socketFactory", sslSocketFactory);
+ }
properties.setProperty(
prefix + ".ssl.checkserveridentity", Boolean.toString(sslConfiguration.isVerifyHostName()));
}
diff --git a/src/changelog/.2.x.x/3947_fix_SslSocketManager_null_keystore.xml b/src/changelog/.2.x.x/3947_fix_SslSocketManager_null_keystore.xml
new file mode 100644
index 0000000000..3b0610d403
--- /dev/null
+++ b/src/changelog/.2.x.x/3947_fix_SslSocketManager_null_keystore.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+ type="fixed">
+ <issue id="3947" link="https://github.com/apache/logging-log4j2/issues/3947"/>
+ <description format="asciidoc">
+ Corrected nullability annotations in `SslConfiguration` which lead to nullability problems in consuming code.
+ In particular, when configuring a syslog appender, if only a truststore is defined, an exception is thrown during configuration time.
+ This fixes that error along with various other potential null errors in related code.
+ </description>
+</entry>