ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akuznet...@apache.org
Subject ignite git commit: IGNITE-10189 WIP.
Date Mon, 03 Dec 2018 10:27:57 GMT
Repository: ignite
Updated Branches:
  refs/heads/ignite-10189 [created] 45263e2bb


IGNITE-10189 WIP.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/45263e2b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/45263e2b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/45263e2b

Branch: refs/heads/ignite-10189
Commit: 45263e2bb9f4bdfd77b09ccb88c510d2118bae2f
Parents: 1502494
Author: Alexey Kuznetsov <akuznetsov@apache.org>
Authored: Mon Dec 3 17:27:42 2018 +0700
Committer: Alexey Kuznetsov <akuznetsov@apache.org>
Committed: Mon Dec 3 17:27:42 2018 +0700

----------------------------------------------------------------------
 .../client/ClientSslParametersTest.java         | 338 +++++++++++++++++++
 .../client/suite/IgniteClientTestSuite.java     |   4 +
 .../client/ssl/GridSslBasicContextFactory.java  |  88 ++++-
 .../ignite/internal/commandline/Arguments.java  |  34 +-
 .../internal/commandline/CommandHandler.java    | 123 +++++--
 .../apache/ignite/ssl/SSLContextWrapper.java    |  13 +-
 .../apache/ignite/ssl/SslContextFactory.java    |  16 +-
 .../apache/ignite/client/SslParametersTest.java |  15 +-
 8 files changed, 576 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/45263e2b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientSslParametersTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientSslParametersTest.java
b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientSslParametersTest.java
new file mode 100644
index 0000000..228ce82
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/ClientSslParametersTest.java
@@ -0,0 +1,338 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.client;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.ConnectorConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.client.ssl.GridSslBasicContextFactory;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Tests cases when node connects to cluster with different set of cipher suites.
+ */
+public class ClientSslParametersTest extends GridCommonAbstractTest {
+    /** */
+    public static final String TEST_CACHE_NAME = "TEST";
+
+    /** */
+    private volatile String[] cipherSuites;
+
+    /** */
+    private volatile String[] protocols;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception
{
+        IgniteConfiguration cfg = super.getConfiguration(gridName);
+
+        ConnectorConfiguration conCfg = new ConnectorConfiguration();
+        conCfg.setSslEnabled(true);
+        conCfg.setSslClientAuth(true);
+        conCfg.setSslContextFactory(createSslFactory());
+
+        cfg.setConnectorConfiguration(conCfg);
+
+        CacheConfiguration ccfg = new CacheConfiguration(TEST_CACHE_NAME);
+
+        cfg.setCacheConfiguration(ccfg);
+
+        return cfg;
+    }
+
+    /**
+     * @return Client configuration.
+     */
+    protected GridClientConfiguration getClientConfiguration() {
+        GridClientConfiguration cfg = new GridClientConfiguration();
+
+        cfg.setServers(Collections.singleton("127.0.0.1:11211"));
+
+        cfg.setSslContextFactory(createSslFactory());
+
+        return cfg;
+    }
+
+    /**
+     * @return SSL Factory.
+     */
+    @NotNull private GridSslBasicContextFactory createSslFactory() {
+        GridSslBasicContextFactory factory = (GridSslBasicContextFactory)GridTestUtils.sslContextFactory();
+
+        factory.setCipherSuites(cipherSuites);
+        factory.setProtocols(protocols);
+
+        return factory;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        protocols = null;
+        cipherSuites = null;
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSameCipherSuite() throws Exception {
+        cipherSuites = new String[] {
+            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+            "TLS_RSA_WITH_AES_128_GCM_SHA256",
+            "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
+        };
+
+        startGrid();
+
+        checkSuccessfulClientStart(
+            new String[][] {
+                new String[] {
+                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_RSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
+                }
+            },
+            null
+        );
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testOneCommonCipherSuite() throws Exception {
+        cipherSuites = new String[] {
+            "TLS_RSA_WITH_AES_128_GCM_SHA256",
+            "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
+        };
+
+        startGrid();
+        
+        checkSuccessfulClientStart(
+            new String[][] {
+                new String[] {
+                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
+                }
+            },
+            null
+        );
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNoCommonCipherSuite() throws Exception {
+        cipherSuites = new String[] {
+            "TLS_RSA_WITH_AES_128_GCM_SHA256"
+        };
+
+        startGrid();
+        
+        checkClientStartFailure(
+            new String[][] {
+                new String[] {
+                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+                    "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
+                }
+            },
+            null
+        );
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNonExistentCipherSuite() throws Exception {
+        fail("IGNITE-10245");
+
+        cipherSuites = new String[] {
+            "TLS_RSA_WITH_AES_128_GCM_SHA256"
+        };
+
+        startGrid();
+        
+        checkClientStartFailure(
+            new String[][] {
+                new String[] {
+                    "TLC_FAKE_CIPHER",
+                    "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
+                }
+            },
+            null,
+            GridClientException.class,
+            "Unsupported ciphersuite"
+        );
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNoCommonProtocols() throws Exception {
+        protocols = new String[] {
+            "TLSv1.1",
+            "SSLv3"
+        };
+
+        startGrid();
+
+        checkClientStartFailure(
+            null,
+            new String[][] {
+                new String[] {
+                    "TLSv1",
+                    "TLSv1.2",
+                }
+            }
+        );
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNonExistentProtocol() throws Exception {
+        fail("IGNITE-10245");
+
+        protocols = new String[] {
+            "SSLv3"
+        };
+
+        startGrid();
+
+        checkClientStartFailure(
+            null,
+            new String[][] {
+                new String[] {
+                    "SSLv3",
+                    "SSLvDoesNotExist"
+                }
+            },
+            GridClientException.class,
+            "SSLvDoesNotExist"
+        );
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testSameProtocols() throws Exception {
+        protocols = new String[] {
+            "TLSv1.1",
+            "TLSv1.2",
+        };
+
+        startGrid();
+
+        checkSuccessfulClientStart(null,
+            new String[][] {
+                new String[] {
+                    "TLSv1.1",
+                    "TLSv1.2",
+                }
+            }
+        );
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testOneCommonProtocol() throws Exception {
+        protocols = new String[] {
+            "TLSv1",
+            "TLSv1.1",
+            "TLSv1.2"
+        };
+
+        startGrid();
+
+        checkSuccessfulClientStart(null,
+            new String[][] {
+                new String[] {
+                    "TLSv1.1",
+                    "SSLv3"
+                }
+            }
+        );
+    }
+
+    /**
+     * @param cipherSuites list of cipher suites
+     * @param protocols list of protocols
+     * @throws Exception If failed.
+     */
+    private void checkSuccessfulClientStart(String[][] cipherSuites, String[][] protocols)
throws Exception {
+        int n = Math.max(
+            cipherSuites != null ? cipherSuites.length : 0,
+            protocols != null ? protocols.length : 0);
+
+        for (int i = 0; i < n; i++) {
+            this.cipherSuites = cipherSuites != null && i < cipherSuites.length
? cipherSuites[i] : null;
+            this.protocols = protocols != null && i < protocols.length ? protocols[i]
: null;
+
+            GridClient client = GridClientFactory.start(getClientConfiguration());
+
+            List<GridClientNode> top = client.compute().refreshTopology(false, false);
+
+            assertEquals(1, top.size());
+
+            client.close();
+        }
+    }
+
+    /**
+     * @param cipherSuites list of cipher suites
+     * @param protocols list of protocols
+     */
+    private void checkClientStartFailure(String[][] cipherSuites, String[][] protocols) {
+        checkClientStartFailure(cipherSuites, protocols, GridClientException.class, "Latest
topology update failed.");
+    }
+
+    /**
+     * @param cipherSuites list of cipher suites
+     * @param protocols list of protocols
+     * @param ex expected exception class
+     * @param msg exception message
+     */
+    private void checkClientStartFailure(String[][] cipherSuites, String[][] protocols, Class<?
extends Throwable> ex, String msg) {
+        int n = Math.max(
+            cipherSuites != null ? cipherSuites.length : 0,
+            protocols != null ? protocols.length : 0);
+
+        for (int i = 0; i < n; i++) {
+            this.cipherSuites = cipherSuites != null && i < cipherSuites.length
? cipherSuites[i] : null;
+            this.protocols = protocols != null && i < protocols.length ? protocols[i]
: null;
+
+            GridTestUtils.assertThrows(null, new Callable<Object>() {
+                @Override public Object call() throws Exception {
+                    GridClient client = GridClientFactory.start(getClientConfiguration());
+
+                    client.compute().refreshTopology(false, false);
+
+                    return null;
+                }
+            }, ex, msg);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/45263e2b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
index d08c9a1..1ea2a1f 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/client/suite/IgniteClientTestSuite.java
@@ -21,6 +21,7 @@ import junit.framework.TestSuite;
 import org.apache.ignite.internal.TaskEventSubjectIdSelfTest;
 import org.apache.ignite.internal.client.ClientDefaultCacheSelfTest;
 import org.apache.ignite.internal.client.ClientReconnectionSelfTest;
+import org.apache.ignite.internal.client.ClientSslParametersTest;
 import org.apache.ignite.internal.client.ClientTcpMultiThreadedSelfTest;
 import org.apache.ignite.internal.client.ClientTcpSslAuthenticationSelfTest;
 import org.apache.ignite.internal.client.ClientTcpSslMultiThreadedSelfTest;
@@ -167,6 +168,9 @@ public class IgniteClientTestSuite extends TestSuite {
 
         suite.addTestSuite(ClientTcpTaskExecutionAfterTopologyRestartSelfTest.class);
 
+        // SSL params.
+        suite.addTestSuite(ClientSslParametersTest.class);
+
         return suite;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/45263e2b/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java
b/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java
index 8bf1e8d..27a32df 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/client/ssl/GridSslBasicContextFactory.java
@@ -23,17 +23,20 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.security.GeneralSecurityException;
 import java.security.KeyStore;
-import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
+import java.util.Collection;
 import javax.cache.configuration.Factory;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLParameters;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.TrustManagerFactory;
 import javax.net.ssl.X509TrustManager;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
+import org.apache.ignite.ssl.SSLContextWrapper;
 
 /**
  * Basic ssl context factory that provides ssl context configuration with specified key
@@ -87,6 +90,12 @@ public class GridSslBasicContextFactory implements GridSslContextFactory
{
     /** Trust managers. */
     private TrustManager[] trustMgrs;
 
+    /** Enabled cipher suites. */
+    private String[] cipherSuites;
+
+    /** Enabled protocols. */
+    private String[] protocols;
+
     /**
      * Gets key store type used for context creation.
      *
@@ -270,6 +279,63 @@ public class GridSslBasicContextFactory implements GridSslContextFactory
{
     }
 
     /**
+     * Gets enabled cipher suites.
+     *
+     * @return Enabled cipher suites.
+     */
+    public String[] getCipherSuites() {
+        return cipherSuites;
+    }
+
+    /**
+     * Sets enabled cipher suites.
+     *
+     * @param cipherSuites Enabled cipher suites.
+     */
+    public void setCipherSuites(String... cipherSuites) {
+        this.cipherSuites = cipherSuites;
+    }
+
+
+    /**
+     * Sets enabled cipher suites.
+     *
+     * @param cipherSuites Enabled cipher suites.
+     */
+    public void setCipherSuites(Collection<String> cipherSuites) {
+        if (!F.isEmpty(cipherSuites))
+            setCipherSuites(cipherSuites.toArray(new String[0]));
+    }
+
+    /**
+     * Gets enabled protocols.
+     *
+     * @return Enabled protocols.
+     */
+    public String[] getProtocols() {
+        return protocols;
+    }
+
+    /**
+     * Sets enabled protocols.
+     *
+     * @param protocols Enabled protocols.
+     */
+    public void setProtocols(String... protocols) {
+        this.protocols = protocols;
+    }
+
+    /**
+     * Sets enabled protocols.
+     *
+     * @param protocols Enabled protocols.
+     */
+    public void setProtocols(Collection<String> protocols) {
+        if (!F.isEmpty(protocols))
+            setProtocols(protocols.toArray(new String[0]));
+    }
+
+    /**
      * Returns an instance of trust manager that will always succeed regardless of certificate
provided.
      *
      * @return Trust manager instance.
@@ -303,6 +369,18 @@ public class GridSslBasicContextFactory implements GridSslContextFactory
{
 
             SSLContext ctx = SSLContext.getInstance(proto);
 
+            if (cipherSuites != null || protocols != null) {
+                SSLParameters sslParameters = new SSLParameters();
+
+                if (cipherSuites != null)
+                    sslParameters.setCipherSuites(cipherSuites);
+
+                if (protocols != null)
+                    sslParameters.setProtocols(protocols);
+
+                ctx = new SSLContextWrapper(ctx, sslParameters);
+            }
+
             ctx.init(keyMgrFactory.getKeyManagers(), mgrs, null);
 
             return ctx;
@@ -431,14 +509,12 @@ public class GridSslBasicContextFactory implements GridSslContextFactory
{
         private static final X509Certificate[] CERTS = new X509Certificate[0];
 
         /** {@inheritDoc} */
-        @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String
s)
-            throws CertificateException {
+        @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String
s) {
             // No-op, all clients are trusted.
         }
 
         /** {@inheritDoc} */
-        @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String
s)
-            throws CertificateException {
+        @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String
s) {
             // No-op, all servers are trusted.
         }
 
@@ -447,4 +523,4 @@ public class GridSslBasicContextFactory implements GridSslContextFactory
{
             return CERTS;
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/45263e2b/modules/core/src/main/java/org/apache/ignite/internal/commandline/Arguments.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/Arguments.java
b/modules/core/src/main/java/org/apache/ignite/internal/commandline/Arguments.java
index 07e7b10..ff04fc3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/commandline/Arguments.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/Arguments.java
@@ -80,6 +80,9 @@ public class Arguments {
     /** SSL Protocol. */
     private String sslProtocol;
 
+    /** SSL Cipher suites. */
+    private String sslCipherSuites;
+
     /** SSL Key Algorithm. */
     private String sslKeyAlgorithm;
 
@@ -117,6 +120,7 @@ public class Arguments {
      * @param pingInterval Ping interval. See {@link GridClientConfiguration#pingInterval}.
      * @param autoConfirmation Auto confirmation flag.
      * @param sslProtocol SSL Protocol.
+     * @param sslCipherSuites SSL cipher suites.
      * @param sslKeyAlgorithm SSL Key Algorithm.
      * @param sslKeyStorePath Keystore.
      * @param sslKeyStorePassword Keystore Password.
@@ -127,28 +131,40 @@ public class Arguments {
      */
     public Arguments(Command cmd, String host, String port, String user, String pwd, String
baselineAct,
         String baselineArgs, VisorTxTaskArg txArg, CacheArguments cacheArgs, String walAct,
String walArgs,
-        Long pingTimeout, Long pingInterval, boolean autoConfirmation, String sslProtocol,
String sslKeyAlgorithm,
+        Long pingTimeout, Long pingInterval, boolean autoConfirmation,
+        String sslProtocol, String sslCipherSuites, String sslKeyAlgorithm,
         String sslKeyStorePath, char[] sslKeyStorePassword, String sslKeyStoreType,
-        String sslTrustStorePath, char[] sslTrustStorePassword, String sslTrustStoreType)
{
+        String sslTrustStorePath, char[] sslTrustStorePassword, String sslTrustStoreType
+    ) {
         this.cmd = cmd;
         this.host = host;
         this.port = port;
         this.user = user;
         this.pwd = pwd;
+
         this.baselineAct = baselineAct;
         this.baselineArgs = baselineArgs;
+
         this.txArg = txArg;
         this.cacheArgs = cacheArgs;
+
         this.walAct = walAct;
         this.walArgs = walArgs;
+
         this.pingTimeout = pingTimeout;
         this.pingInterval = pingInterval;
+
         this.autoConfirmation = autoConfirmation;
+
+        this.sslEnable = sslEnable;
         this.sslProtocol = sslProtocol;
+        this.sslCipherSuites = sslCipherSuites;
+
         this.sslKeyAlgorithm = sslKeyAlgorithm;
         this.sslKeyStorePath = sslKeyStorePath;
         this.sslKeyStoreType = sslKeyStoreType;
         this.sslKeyStorePassword = sslKeyStorePassword;
+
         this.sslTrustStorePath = sslTrustStorePath;
         this.sslTrustStoreType = sslTrustStoreType;
         this.sslTrustStorePassword = sslTrustStorePassword;
@@ -271,6 +287,13 @@ public class Arguments {
     }
 
     /**
+     * @return {@code true} if SSL should be used.
+     */
+    public boolean isSslEnable() {
+        return sslEnable;
+    }
+
+    /**
      * @return SSL protocol
      */
     public String sslProtocol() {
@@ -278,6 +301,13 @@ public class Arguments {
     }
 
     /**
+     * @return SSL cipher suites.
+     */
+    public String getSslCipherSuites() {
+        return sslCipherSuites;
+    }
+
+    /**
      * @return SSL Key Algorithm
      */
     public String sslKeyAlgorithm() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/45263e2b/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
b/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
index 56f278b..076d322 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
@@ -201,9 +201,15 @@ public class CommandHandler {
     // SSL configuration section
 
     /** */
+    private static final String CMD_SSL_ENABLED = "--ssl_enabled";
+
+    /** */
     private static final String CMD_SSL_PROTOCOL = "--ssl-protocol";
 
     /** */
+    private static final String CMD_SSL_CIPHER_SUITES = "--ssl-cipher-suites";
+
+    /** */
     private static final String CMD_SSL_KEY_ALGORITHM = "--ssl-key-algorithm";
 
     /** */
@@ -229,21 +235,30 @@ public class CommandHandler {
 
     static {
         AUX_COMMANDS.add(CMD_HELP);
+
         AUX_COMMANDS.add(CMD_HOST);
         AUX_COMMANDS.add(CMD_PORT);
+
         AUX_COMMANDS.add(CMD_PASSWORD);
         AUX_COMMANDS.add(CMD_USER);
+
         AUX_COMMANDS.add(CMD_AUTO_CONFIRMATION);
+
         AUX_COMMANDS.add(CMD_PING_INTERVAL);
         AUX_COMMANDS.add(CMD_PING_TIMEOUT);
+
+        AUX_COMMANDS.add(CMD_SSL_ENABLED);
         AUX_COMMANDS.add(CMD_SSL_PROTOCOL);
+        AUX_COMMANDS.add(CMD_SSL_CIPHER_SUITES);
+
         AUX_COMMANDS.add(CMD_SSL_KEY_ALGORITHM);
+        AUX_COMMANDS.add(CMD_KEYSTORE_TYPE);
         AUX_COMMANDS.add(CMD_KEYSTORE);
         AUX_COMMANDS.add(CMD_KEYSTORE_PASSWORD);
-        AUX_COMMANDS.add(CMD_KEYSTORE_TYPE);
+
+        AUX_COMMANDS.add(CMD_TRUSTSTORE_TYPE);
         AUX_COMMANDS.add(CMD_TRUSTSTORE);
         AUX_COMMANDS.add(CMD_TRUSTSTORE_PASSWORD);
-        AUX_COMMANDS.add(CMD_TRUSTSTORE_TYPE);
     }
 
     /** Broadcast uuid. */
@@ -352,13 +367,15 @@ public class CommandHandler {
     private static final String UTILITY_NAME = "control.sh";
 
     /** Common options. */
-    private static final String COMMON_OPTIONS = String.join(" ", op(CMD_HOST, "HOST_OR_IP"),
-        op(CMD_PORT, "PORT"), op(CMD_USER, "USER"), op(CMD_PASSWORD, "PASSWORD"),
+    private static final String COMMON_OPTIONS = String.join(" ", op(CMD_HOST, "HOST_OR_IP"),
op(CMD_PORT, "PORT"),
+        op(CMD_USER, "USER"), op(CMD_PASSWORD, "PASSWORD"),
         op(CMD_PING_INTERVAL, "PING_INTERVAL"), op(CMD_PING_TIMEOUT, "PING_TIMEOUT"),
-        op(CMD_SSL_PROTOCOL, "SSL_PROTOCOL"), op(CMD_SSL_KEY_ALGORITHM, "SSL_KEY_ALGORITHM"),
-        op(CMD_KEYSTORE, "KEYSTORE"), op(CMD_KEYSTORE_TYPE, "KEYSTORE_TYPE"),
-        op(CMD_KEYSTORE_PASSWORD, "KEYSTORE_PASSWORD"), op(CMD_TRUSTSTORE, "TRUSTSTORE"),
-        op(CMD_TRUSTSTORE_TYPE, "TRUSTSTORE_TYPE"), op(CMD_TRUSTSTORE_PASSWORD, "TRUSTSTORE_PASSWORD"));
+        op(CMD_SSL_ENABLED),
+        op(CMD_SSL_PROTOCOL, "SSL_PROTOCOL[, SSL_PROTOCOL_2, ...]"),
+        op(CMD_SSL_CIPHER_SUITES, "SSL_CIPHER_1[, SSL_CIPHER_2, ...]"),
+        op(CMD_SSL_KEY_ALGORITHM, "SSL_KEY_ALGORITHM"),
+        op(CMD_KEYSTORE_TYPE, "KEYSTORE_TYPE"), op(CMD_KEYSTORE, "KEYSTORE"), op(CMD_KEYSTORE_PASSWORD,
"KEYSTORE_PASSWORD"),
+        op(CMD_TRUSTSTORE_TYPE, "TRUSTSTORE_TYPE"), op(CMD_TRUSTSTORE, "TRUSTSTORE"), op(CMD_TRUSTSTORE_PASSWORD,
"TRUSTSTORE_PASSWORD"));
 
     /** Utility name with common options. */
     private static final String UTILITY_NAME_WITH_COMMON_OPTIONS = String.join(" ", UTILITY_NAME,
COMMON_OPTIONS);
@@ -1032,10 +1049,9 @@ public class CommandHandler {
             executeTaskByNameOnNode(client, VisorCacheConfigurationCollectorTask.class.getName(),
taskArg, nodeId);
 
         Map<String, Integer> cacheToMapped =
-            viewRes.cacheInfos().stream().collect(Collectors.toMap(x -> x.getCacheName(),
x -> x.getMapped()));
+            viewRes.cacheInfos().stream().collect(Collectors.toMap(CacheInfo::getCacheName,
CacheInfo::getMapped));
 
         printCachesConfig(res, cacheArgs.outputFormat(), cacheToMapped);
-
     }
 
     /**
@@ -1818,20 +1834,24 @@ public class CommandHandler {
 
         VisorTxTaskArg txArgs = null;
 
+        boolean sslEnable = false;
+
         String sslProtocol = SslContextFactory.DFLT_SSL_PROTOCOL;
 
-        String sslKeyAlgorithm = SslContextFactory.DFLT_KEY_ALGORITHM;
+        String sslCipherSuites = "";
 
-        String sslKeyStorePath = null;
+        String sslKeyAlgorithm = SslContextFactory.DFLT_KEY_ALGORITHM;
 
         String sslKeyStoreType = SslContextFactory.DFLT_STORE_TYPE;
 
-        char sslKeyStorePassword[] = null;
+        String sslKeyStorePath = null;
 
-        String sslTrustStorePath = null;
+        char sslKeyStorePassword[] = null;
 
         String sslTrustStoreType = SslContextFactory.DFLT_STORE_TYPE;
 
+        String sslTrustStorePath = null;
+
         char sslTrustStorePassword[] = null;
 
         while (hasNextArg()) {
@@ -1946,43 +1966,52 @@ public class CommandHandler {
 
                         break;
 
+                    case CMD_SSL_ENABLED:
+                        sslEnable = true;
+
+                        break;
                     case CMD_SSL_PROTOCOL:
                         sslProtocol = nextArg("Expected SSL protocol");
 
                         break;
 
+                    case CMD_SSL_CIPHER_SUITES:
+                        sslCipherSuites = nextArg("Expected SSL cipher suites");
+
+                        break;
+
                     case CMD_SSL_KEY_ALGORITHM:
                         sslKeyAlgorithm = nextArg("Expected SSL key algorithm");
 
                         break;
 
                     case CMD_KEYSTORE:
-                        sslKeyStorePath = nextArg("Expected keystore path");
+                        sslKeyStorePath = nextArg("Expected SSL key store path");
 
                         break;
 
                     case CMD_KEYSTORE_PASSWORD:
-                        sslKeyStorePassword = nextArg("Expected keystore password").toCharArray();
+                        sslKeyStorePassword = nextArg("Expected SSL key store password").toCharArray();
 
                         break;
 
                     case CMD_KEYSTORE_TYPE:
-                        sslKeyStoreType = nextArg("Expected keystore type");
+                        sslKeyStoreType = nextArg("Expected SSL key store type");
 
                         break;
 
                     case CMD_TRUSTSTORE:
-                        sslTrustStorePath = nextArg("Expected truststore path");
+                        sslTrustStorePath = nextArg("Expected SSL trust store path");
 
                         break;
 
                     case CMD_TRUSTSTORE_PASSWORD:
-                        sslTrustStorePassword = nextArg("Expected truststore password").toCharArray();
+                        sslTrustStorePassword = nextArg("Expected SSL trust store password").toCharArray();
 
                         break;
 
                     case CMD_TRUSTSTORE_TYPE:
-                        sslTrustStoreType = nextArg("Expected truststore type");
+                        sslTrustStoreType = nextArg("Expected SSL trust store type");
 
                         break;
 
@@ -2007,9 +2036,13 @@ public class CommandHandler {
 
         Command cmd = commands.get(0);
 
-        return new Arguments(cmd, host, port, user, pwd, baselineAct, baselineArgs, txArgs,
cacheArgs, walAct, walArgs,
+        return new Arguments(cmd, host, port, user, pwd,
+            baselineAct, baselineArgs,
+            txArgs, cacheArgs,
+            walAct, walArgs,
             pingTimeout, pingInterval, autoConfirmation,
-            sslProtocol, sslKeyAlgorithm, sslKeyStorePath, sslKeyStorePassword, sslKeyStoreType,
+            sslEnable, sslProtocol, sslCipherSuites,
+            sslKeyAlgorithm, sslKeyStorePath, sslKeyStorePassword, sslKeyStoreType,
             sslTrustStorePath, sslTrustStorePassword, sslTrustStoreType);
     }
 
@@ -2492,6 +2525,23 @@ public class CommandHandler {
     }
 
     /**
+     * Split string into items.
+     *
+     * @param s String to process.
+     * @param delim Delimiter.
+     * @return List with items.
+     */
+    private List<String> split(String s, String delim) {
+        if (F.isEmpty(s))
+            return Collections.emptyList();
+
+        return Arrays.stream(s.split(delim))
+            .map(String::trim)
+            .filter(item -> !item.isEmpty())
+            .collect(Collectors.toList());
+    }
+
+    /**
      * Parse and execute command.
      *
      * @param rawArgs Arguments to parse and execute.
@@ -2537,8 +2587,8 @@ public class CommandHandler {
                 log(i("PING_TIMEOUT=" + DFLT_PING_TIMEOUT, 2));
                 log(i("SSL_PROTOCOL=" + SslContextFactory.DFLT_SSL_PROTOCOL, 2));
                 log(i("SSL_KEY_ALGORITHM=" + SslContextFactory.DFLT_KEY_ALGORITHM, 2));
-                log(i("KEYSTORE_TYPE=" + SslContextFactory.DFLT_STORE_TYPE, 2));
-                log(i("TRUSTSTORE_TYPE=" + SslContextFactory.DFLT_STORE_TYPE, 2));
+                log(i("SSL_KEY_STORE_TYPE=" + SslContextFactory.DFLT_STORE_TYPE, 2));
+                log(i("SSL_TRUST_STORE_TYPE=" + SslContextFactory.DFLT_STORE_TYPE, 2));
                 nl();
 
                 log("Exit codes:");
@@ -2575,7 +2625,7 @@ public class CommandHandler {
 
             boolean tryConnectAgain = true;
 
-            int tryConnectMaxCount=3;
+            int tryConnectMaxCount = 3;
 
             while (tryConnectAgain) {
                 tryConnectAgain = false;
@@ -2597,10 +2647,21 @@ public class CommandHandler {
                 if (!F.isEmpty(args.sslKeyStorePath())) {
                     GridSslBasicContextFactory factory = new GridSslBasicContextFactory();
 
-                    factory.setProtocol(args.sslProtocol());
+                    List<String> sslProtocols = split(args.getSslProtocol(), ",");
+
+                    String sslProtocol = F.isEmpty(sslProtocols) ? SslContextFactory.DFLT_SSL_PROTOCOL
: sslProtocols.get(0);
 
+                    factory.setProtocol(sslProtocol);
                     factory.setKeyAlgorithm(args.sslKeyAlgorithm());
 
+                    if (sslProtocols.size() > 1)
+                        factory.setProtocols(sslProtocols);
+
+                    factory.setCipherSuites(split(args.getSslCipherSuites(), ","));
+
+                    if (args.sslKeyStorePath() == null)
+                        throw new IllegalArgumentException("SSL key store location is not
specified.");
+
                     factory.setKeyStoreFilePath(args.sslKeyStorePath());
 
                     if (args.sslKeyStorePassword() != null)
@@ -2608,7 +2669,7 @@ public class CommandHandler {
 
                     factory.setKeyStoreType(args.sslKeyStoreType());
 
-                    if (F.isEmpty(args.sslTrustStorePath()))
+                    if (args.sslTrustStorePath() == null)
                         factory.setTrustManagers(GridSslBasicContextFactory.getDisabledTrustManager());
                     else {
                         factory.setTrustStoreFilePath(args.sslTrustStorePath());
@@ -2662,7 +2723,7 @@ public class CommandHandler {
                 }
                 catch (Throwable e) {
                     if (tryConnectMaxCount > 0 && isAuthError(e)) {
-                        System.out.println("Authentication error, try connection again.");
+                        log("Authentication error, try connection again.");
 
                         final Console console = System.console();
 
@@ -2675,13 +2736,13 @@ public class CommandHandler {
                         else {
                             Scanner scanner = new Scanner(System.in);
 
-                            if (F.isEmpty(args.getUserName())){
-                                System.out.println("user: ");
+                            if (F.isEmpty(args.getUserName())) {
+                                log("user: ");
 
                                 args.setUserName(scanner.next());
                             }
 
-                            System.out.println("password: ");
+                            log("password: ");
 
                             args.setPassword(scanner.next());
                         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/45263e2b/modules/core/src/main/java/org/apache/ignite/ssl/SSLContextWrapper.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/ssl/SSLContextWrapper.java b/modules/core/src/main/java/org/apache/ignite/ssl/SSLContextWrapper.java
index 901d42b..67bc834 100644
--- a/modules/core/src/main/java/org/apache/ignite/ssl/SSLContextWrapper.java
+++ b/modules/core/src/main/java/org/apache/ignite/ssl/SSLContextWrapper.java
@@ -20,10 +20,15 @@ package org.apache.ignite.ssl;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLParameters;
 
-/** */
-class SSLContextWrapper extends SSLContext {
-    /** */
-    SSLContextWrapper(SSLContext delegate, SSLParameters sslParameters) {
+/**
+ * Wrapper for {@link SSLContext} that extend source context with custom SSL parameters.
+ */
+public class SSLContextWrapper extends SSLContext {
+    /**
+     * @param delegate Wrapped SSL context.
+     * @param sslParameters Extended SSL parameters.
+     */
+    public SSLContextWrapper(SSLContext delegate, SSLParameters sslParameters) {
         super(new DelegatingSSLContextSpi(delegate, sslParameters),
             delegate.getProvider(),
             delegate.getProtocol());

http://git-wip-us.apache.org/repos/asf/ignite/blob/45263e2b/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java b/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java
index edff5c9..fb370a5 100644
--- a/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java
+++ b/modules/core/src/main/java/org/apache/ignite/ssl/SslContextFactory.java
@@ -93,7 +93,7 @@ public class SslContextFactory implements Factory<SSLContext> {
     /** Enabled cipher suites. */
     private String[] cipherSuites;
 
-    /** Enabled cipher suites. */
+    /** Enabled protocols. */
     private String[] protocols;
 
     /**
@@ -289,6 +289,7 @@ public class SslContextFactory implements Factory<SSLContext> {
 
     /**
      * Sets enabled cipher suites.
+     *
      * @param cipherSuites enabled cipher suites.
      */
     public void setCipherSuites(String... cipherSuites) {
@@ -296,7 +297,8 @@ public class SslContextFactory implements Factory<SSLContext> {
     }
 
     /**
-     * Gets enabled cipher suites
+     * Gets enabled cipher suites.
+     *
      * @return enabled cipher suites
      */
     public String[] getCipherSuites() {
@@ -304,8 +306,9 @@ public class SslContextFactory implements Factory<SSLContext> {
     }
 
     /**
-     * Gets enabled cipher suites
-     * @return enabled cipher suites
+     * Gets enabled protocols.
+     *
+     * @return Enabled protocols.
      */
     public String[] getProtocols() {
         return protocols;
@@ -313,7 +316,8 @@ public class SslContextFactory implements Factory<SSLContext> {
 
     /**
      * Sets enabled protocols.
-     * @param protocols enabled protocols.
+     *
+     * @param protocols Enabled protocols.
      */
     public void setProtocols(String... protocols) {
         this.protocols = protocols;
@@ -515,4 +519,4 @@ public class SslContextFactory implements Factory<SSLContext> {
             throw new IgniteException(e);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/45263e2b/modules/core/src/test/java/org/apache/ignite/client/SslParametersTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/client/SslParametersTest.java b/modules/core/src/test/java/org/apache/ignite/client/SslParametersTest.java
index eb577c4..20eb94c 100644
--- a/modules/core/src/test/java/org/apache/ignite/client/SslParametersTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/client/SslParametersTest.java
@@ -32,8 +32,9 @@ import org.jetbrains.annotations.NotNull;
  * Tests cases when node connects to cluster with different set of cipher suites.
  */
 public class SslParametersTest extends GridCommonAbstractTest {
-
+    /** */
     public static final String TEST_CACHE_NAME = "TEST";
+
     /** */
     private volatile String[] cipherSuites;
 
@@ -57,8 +58,10 @@ public class SslParametersTest extends GridCommonAbstractTest {
         return cfg;
     }
 
-    /** {@inheritDoc} */
-    protected ClientConfiguration getClientConfiguration() throws Exception {
+    /**
+     * @return Client config.
+     */
+    protected ClientConfiguration getClientConfiguration() {
         ClientConfiguration cfg = new ClientConfiguration();
 
         cfg.setAddresses("127.0.0.1:10800");
@@ -70,6 +73,9 @@ public class SslParametersTest extends GridCommonAbstractTest {
         return cfg;
     }
 
+    /**
+     * @return SSL factory.
+     */
     @NotNull private SslContextFactory createSslFactory() {
         SslContextFactory factory = (SslContextFactory)GridTestUtils.sslTrustedFactory(
             "node01", "trustone");
@@ -313,8 +319,6 @@ public class SslParametersTest extends GridCommonAbstractTest {
             this.cipherSuites = cipherSuites != null && i < cipherSuites.length
? cipherSuites[i] : null;
             this.protocols = protocols != null && i < protocols.length ? protocols[i]
: null;
 
-            int finalI = i;
-
             GridTestUtils.assertThrows(null, new Callable<Object>() {
                 @Override public Object call() throws Exception {
                     Ignition.startClient(getClientConfiguration());
@@ -324,5 +328,4 @@ public class SslParametersTest extends GridCommonAbstractTest {
             }, ex, msg);
         }
     }
-
 }


Mime
View raw message