You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/11/09 02:35:47 UTC

[dubbo] branch master updated: [Master]Fix netty ssl file leak (#9197)

This is an automated email from the ASF dual-hosted git repository.

albumenj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new 44ae001  [Master]Fix netty ssl file leak (#9197)
44ae001 is described below

commit 44ae0016b2171a83397d101551cca1a3c24f8da9
Author: haoyann <10...@qq.com>
AuthorDate: Tue Nov 9 10:35:32 2021 +0800

    [Master]Fix netty ssl file leak (#9197)
    
    * fix netty ssl file leak
    
    * remove useless code
---
 .../remoting/transport/netty4/SslContexts.java     | 43 +++++++++++++++++----
 .../dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java  | 44 ++++++++++++++++++----
 2 files changed, 72 insertions(+), 15 deletions(-)

diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/SslContexts.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/SslContexts.java
index c4d3598..b74e15b 100644
--- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/SslContexts.java
+++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/SslContexts.java
@@ -30,6 +30,7 @@ import io.netty.handler.ssl.SslContextBuilder;
 import io.netty.handler.ssl.SslProvider;
 
 import javax.net.ssl.SSLException;
+import java.io.IOException;
 import java.io.InputStream;
 import java.security.Provider;
 import java.security.Security;
@@ -43,14 +44,18 @@ public class SslContexts {
         SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!"));
 
         SslContextBuilder sslClientContextBuilder = null;
+        InputStream serverKeyCertChainPathStream = null;
+        InputStream serverPrivateKeyPathStream = null;
         try {
+            serverKeyCertChainPathStream = sslConfig.getServerKeyCertChainPathStream();
+            serverPrivateKeyPathStream = sslConfig.getServerPrivateKeyPathStream();
             String password = sslConfig.getServerKeyPassword();
             if (password != null) {
-                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),
-                        sslConfig.getServerPrivateKeyPathStream(), password);
+                sslClientContextBuilder = SslContextBuilder.forServer(serverKeyCertChainPathStream,
+                        serverPrivateKeyPathStream, password);
             } else {
-                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),
-                        sslConfig.getServerPrivateKeyPathStream());
+                sslClientContextBuilder = SslContextBuilder.forServer(serverKeyCertChainPathStream,
+                        serverPrivateKeyPathStream);
             }
 
             if (sslConfig.getServerTrustCertCollectionPathStream() != null) {
@@ -66,6 +71,9 @@ public class SslContexts {
 
         } catch (Exception e) {
             throw new IllegalArgumentException("Could not find certificate file or the certificate is invalid.", e);
+        }finally {
+            safeCloseStream(serverKeyCertChainPathStream);
+            safeCloseStream(serverPrivateKeyPathStream);
         }
         try {
             return sslClientContextBuilder.sslProvider(findSslProvider()).build();
@@ -79,13 +87,17 @@ public class SslContexts {
         SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!"));
 
         SslContextBuilder builder = SslContextBuilder.forClient();
+        InputStream clientTrustCertCollectionPath = null;
+        InputStream clientCertChainFilePath = null;
+        InputStream clientPrivateKeyFilePath = null;
         try {
-            if (sslConfig.getClientTrustCertCollectionPathStream() != null) {
-                builder.trustManager(sslConfig.getClientTrustCertCollectionPathStream());
+            clientTrustCertCollectionPath = sslConfig.getClientTrustCertCollectionPathStream();
+            if (clientTrustCertCollectionPath != null) {
+                builder.trustManager(clientTrustCertCollectionPath);
             }
 
-            InputStream clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();
-            InputStream clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();
+            clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();
+            clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();
             if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {
                 String password = sslConfig.getClientKeyPassword();
                 if (password != null) {
@@ -102,6 +114,10 @@ public class SslContexts {
             }
         } catch (Exception e) {
             throw new IllegalArgumentException("Could not find certificate file or find invalid certificate.", e);
+        } finally {
+            safeCloseStream(clientTrustCertCollectionPath);
+            safeCloseStream(clientCertChainFilePath);
+            safeCloseStream(clientPrivateKeyFilePath);
         }
         try {
             return builder.sslProvider(findSslProvider()).build();
@@ -131,4 +147,15 @@ public class SslContexts {
         return (jdkProviders != null && jdkProviders.length > 0);
     }
 
+    private static void safeCloseStream(InputStream stream) {
+        if (stream == null) {
+            return;
+        }
+        try {
+            stream.close();
+        } catch (IOException e) {
+            logger.warn("Failed to close a stream.", e);
+        }
+    }
+
 }
diff --git a/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java b/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java
index d1b1cda..8035ae1 100644
--- a/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java
+++ b/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java
@@ -18,6 +18,8 @@ package org.apache.dubbo.rpc.protocol.grpc;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.threadpool.ThreadPool;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.config.SslConfig;
@@ -39,6 +41,7 @@ import io.netty.handler.ssl.SslContext;
 import io.netty.handler.ssl.SslContextBuilder;
 
 import javax.net.ssl.SSLException;
+import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -63,6 +66,8 @@ import static org.apache.dubbo.rpc.protocol.grpc.GrpcConstants.TRANSPORT_FILTERS
  */
 public class GrpcOptionsUtils {
 
+    private static final Logger logger = LoggerFactory.getLogger(GrpcOptionsUtils.class);
+
     static ServerBuilder buildServerBuilder(URL url, NettyServerBuilder builder) {
 
         int maxInboundMessageSize = url.getParameter(MAX_INBOUND_MESSAGE_SIZE, 0);
@@ -157,14 +162,18 @@ public class GrpcOptionsUtils {
         SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException("Ssl enabled, but no ssl cert information provided!"));
 
         SslContextBuilder sslClientContextBuilder = null;
+        InputStream serverKeyCertChainPathStream = null;
+        InputStream serverPrivateKeyPathStream = null;
         try {
+            serverKeyCertChainPathStream = sslConfig.getServerKeyCertChainPathStream();
+            serverPrivateKeyPathStream = sslConfig.getServerPrivateKeyPathStream();
             String password = sslConfig.getServerKeyPassword();
             if (password != null) {
-                sslClientContextBuilder = GrpcSslContexts.forServer(sslConfig.getServerKeyCertChainPathStream(),
-                        sslConfig.getServerPrivateKeyPathStream(), password);
+                sslClientContextBuilder = GrpcSslContexts.forServer(serverKeyCertChainPathStream,
+                        serverPrivateKeyPathStream, password);
             } else {
-                sslClientContextBuilder = GrpcSslContexts.forServer(sslConfig.getServerKeyCertChainPathStream(),
-                        sslConfig.getServerPrivateKeyPathStream());
+                sslClientContextBuilder = GrpcSslContexts.forServer(serverKeyCertChainPathStream,
+                        serverPrivateKeyPathStream);
             }
 
             InputStream trustCertCollectionFilePath = sslConfig.getServerTrustCertCollectionPathStream();
@@ -174,6 +183,9 @@ public class GrpcOptionsUtils {
             }
         } catch (Exception e) {
             throw new IllegalArgumentException("Could not find certificate file or the certificate is invalid.", e);
+        }finally {
+            safeCloseStream(serverKeyCertChainPathStream);
+            safeCloseStream(serverPrivateKeyPathStream);
         }
         try {
             return sslClientContextBuilder.build();
@@ -188,13 +200,16 @@ public class GrpcOptionsUtils {
 
 
         SslContextBuilder builder = GrpcSslContexts.forClient();
+        InputStream trustCertCollectionFilePath = null;
+        InputStream clientCertChainFilePath = null;
+        InputStream clientPrivateKeyFilePath = null;
         try {
-            InputStream trustCertCollectionFilePath = sslConfig.getClientTrustCertCollectionPathStream();
+            trustCertCollectionFilePath = sslConfig.getClientTrustCertCollectionPathStream();
             if (trustCertCollectionFilePath != null) {
                 builder.trustManager(trustCertCollectionFilePath);
             }
-            InputStream clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();
-            InputStream clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();
+            clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();
+            clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();
             if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {
                 String password = sslConfig.getClientKeyPassword();
                 if (password != null) {
@@ -205,6 +220,10 @@ public class GrpcOptionsUtils {
             }
         } catch (Exception e) {
             throw new IllegalArgumentException("Could not find certificate file or find invalid certificate.", e);
+        } finally {
+            safeCloseStream(trustCertCollectionFilePath);
+            safeCloseStream(clientCertChainFilePath);
+            safeCloseStream(clientPrivateKeyFilePath);
         }
         try {
             return builder.build();
@@ -222,4 +241,15 @@ public class GrpcOptionsUtils {
         }
         return Optional.empty();
     }
+
+    private static void safeCloseStream(InputStream stream) {
+        if (stream == null) {
+            return;
+        }
+        try {
+            stream.close();
+        } catch (IOException e) {
+            logger.warn("Failed to close a stream.", e);
+        }
+    }
 }