From: melserngawy Date: Fri, 18 Nov 2016 14:47:25 +0000 (-0500) Subject: Bug 5306: Enable the SSL connection for ovs manager X-Git-Tag: release/carbon~41 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=818ee6e6bb4e220ba4dd3f1306d7149a7f04e1de;p=ovsdb.git Bug 5306: Enable the SSL connection for ovs manager Use the aaa-cert feature to manage the TLS connection certificates and add configuration to the southbound-impl to allow SSL communication. Change-Id: I1354644b7a4cb30493ce2bc5b33a2d1d504aaae0 Signed-off-by: melserngawy --- diff --git a/library/features/pom.xml b/library/features/pom.xml index bb6cc12cb..76d69031b 100644 --- a/library/features/pom.xml +++ b/library/features/pom.xml @@ -24,6 +24,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL 0.10.0-SNAPSHOT 1.5.0-SNAPSHOT 1.1.0-SNAPSHOT + 0.5.0-SNAPSHOT etc/opendaylight/karaf @@ -36,6 +37,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL pom import + + org.opendaylight.aaa + features-aaa + ${aaa.version} + pom + import + @@ -47,6 +55,13 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL xml runtime + + org.opendaylight.aaa + features-aaa + ${aaa.version} + xml + features + org.opendaylight.controller features-mdsal diff --git a/library/features/src/main/features/features.xml b/library/features/src/main/features/features.xml index 36995ad0e..dc4d3549b 100644 --- a/library/features/src/main/features/features.xml +++ b/library/features/src/main/features/features.xml @@ -13,9 +13,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features + mvn:org.opendaylight.aaa/features-aaa/{{VERSION}}/xml/features + odl-mdsal-broker odl-mdsal-models + odl-aaa-cert mvn:org.opendaylight.ovsdb/library/{{VERSION}} mvn:org.opendaylight.ovsdb/utils.servicehelper/{{VERSION}} diff --git a/library/impl/pom.xml b/library/impl/pom.xml index 9f8c92484..e1ed7988a 100644 --- a/library/impl/pom.xml +++ b/library/impl/pom.xml @@ -66,6 +66,11 @@ and is available at http://www.eclipse.org/legal/epl-v10.html org.opendaylight.controller sal-binding-api + + org.opendaylight.aaa + aaa-cert + 0.5.0-SNAPSHOT + diff --git a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/OvsdbConnection.java b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/OvsdbConnection.java index 6d5a35269..adbe99bbf 100644 --- a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/OvsdbConnection.java +++ b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/OvsdbConnection.java @@ -33,7 +33,7 @@ public interface OvsdbConnection { * @param port Layer 4 port on which the remote ovsdb server is listening on. * @return OvsDBClient The primary Client interface for the ovsdb connection. */ - OvsdbClient connect(InetAddress address, int port); + OvsdbClient connect(final InetAddress address, final int port); /** * connect API can be used by the applications to initiate Active ssl @@ -43,7 +43,8 @@ public interface OvsdbConnection { * @param sslContext Netty sslContext for channel configuration * @return OvsDBClient The primary Client interface for the ovsdb connection. */ - OvsdbClient connectWithSsl(InetAddress address, int port, SSLContext sslContext); + OvsdbClient connectWithSsl(final InetAddress address, final int port, + final SSLContext sslContext); /** * Method to disconnect an existing connection. @@ -54,12 +55,13 @@ public interface OvsdbConnection { /** * Method to start ovsdb server for passive connection. */ - boolean startOvsdbManager(int ovsdbListenPort); + boolean startOvsdbManager(final int ovsdbListenPort); /** * Method to start ovsdb server for passive connection with SSL. */ - boolean startOvsdbManagerWithSsl(int ovsdbListenPort, SSLContext sslContext); + boolean startOvsdbManagerWithSsl(final int ovsdbListenPort, + final SSLContext sslContext, String[] protocols, String[] cipherSuites); /** * Method to register a Passive Connection Listener with the ConnectionService. diff --git a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbConnectionService.java b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbConnectionService.java index 0191b5c43..76e43cf8a 100644 --- a/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbConnectionService.java +++ b/library/impl/src/main/java/org/opendaylight/ovsdb/lib/impl/OvsdbConnectionService.java @@ -53,6 +53,7 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLPeerUnverifiedException; +import org.opendaylight.aaa.cert.api.ICertificateManager; import org.opendaylight.ovsdb.lib.OvsdbClient; import org.opendaylight.ovsdb.lib.OvsdbConnection; import org.opendaylight.ovsdb.lib.OvsdbConnectionInfo.ConnectionType; @@ -102,6 +103,9 @@ public class OvsdbConnectionService implements AutoCloseable, OvsdbConnection { private static final int IDLE_READER_TIMEOUT = 30; private static final int READ_TIMEOUT = 180; private static final String OVSDB_RPC_TASK_TIMEOUT_PARAM = "ovsdb-rpc-task-timeout"; + private static final String USE_SSL = "use-ssl"; + private static boolean useSSL = false; + private static ICertificateManager certManagerSrv = null; private static final StalePassiveConnectionService STALE_PASSIVE_CONNECTION_SERVICE = new StalePassiveConnectionService(executorService); @@ -116,9 +120,21 @@ public class OvsdbConnectionService implements AutoCloseable, OvsdbConnection { return connectionService; } + /** + * If the SSL flag is enabled, the method internally will establish TLS communication using the default + * ODL certificateManager SSLContext and attributes. + */ @Override public OvsdbClient connect(final InetAddress address, final int port) { - return connectWithSsl(address, port, null /* SslContext */); + if (useSSL) { + if (certManagerSrv == null) { + LOG.error("Certificate Manager service is not available cannot establish the SSL communication."); + return null; + } + return connectWithSsl(address, port, certManagerSrv.getServerContext()); + } else { + return connectWithSsl(address, port, null /* SslContext */); + } } @Override @@ -245,12 +261,12 @@ public class OvsdbConnectionService implements AutoCloseable, OvsdbConnection { */ @Override public synchronized boolean startOvsdbManagerWithSsl(final int ovsdbListenPort, - final SSLContext sslContext) { + final SSLContext sslContext, String[] protocols, String[] cipherSuites) { if (!singletonCreated) { new Thread() { @Override public void run() { - ovsdbManagerWithSsl(ovsdbListenPort, sslContext); + ovsdbManagerWithSsl(ovsdbListenPort, sslContext, protocols, cipherSuites); } }.start(); singletonCreated = true; @@ -263,16 +279,28 @@ public class OvsdbConnectionService implements AutoCloseable, OvsdbConnection { /** * OVSDB Passive listening thread that uses Netty ServerBootstrap to open * passive connection handle channel callbacks. + * If the SSL flag is enabled, the method internally will establish TLS communication using the default + * ODL certificateManager SSLContext and attributes. */ private static void ovsdbManager(int port) { - ovsdbManagerWithSsl(port, null /* SslContext */); + if (useSSL) { + if (certManagerSrv == null) { + LOG.error("Certificate Manager service is not available cannot establish the SSL communication."); + return; + } + ovsdbManagerWithSsl(port, certManagerSrv.getServerContext(), certManagerSrv.getTlsProtocols(), + certManagerSrv.getCipherSuites()); + } else { + ovsdbManagerWithSsl(port, null /* SslContext */, null, null); + } } /** * OVSDB Passive listening thread that uses Netty ServerBootstrap to open * passive connection with Ssl and handle channel callbacks. */ - private static void ovsdbManagerWithSsl(int port, final SSLContext sslContext) { + private static void ovsdbManagerWithSsl(int port, final SSLContext sslContext, final String[] protocols, + final String[] cipherSuites) { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { @@ -290,23 +318,20 @@ public class OvsdbConnectionService implements AutoCloseable, OvsdbConnection { SSLEngine engine = sslContext.createSSLEngine(); engine.setUseClientMode(false); // work in a server mode engine.setNeedClientAuth(true); // need client authentication - //Disable SSLv3, TLSv1 and enable all other supported protocols - String[] protocols = {"SSLv2Hello", "TLSv1.1", "TLSv1.2"}; - LOG.debug("Set enable protocols {}", Arrays.toString(protocols)); - engine.setEnabledProtocols(protocols); - LOG.debug("Supported ssl protocols {}", - Arrays.toString(engine.getSupportedProtocols())); - LOG.debug("Enabled ssl protocols {}", - Arrays.toString(engine.getEnabledProtocols())); - //Set cipher suites - String[] cipherSuites = {"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", - "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA256"}; - engine.setEnabledCipherSuites(cipherSuites); - LOG.debug("Enabled cipher suites {}", - Arrays.toString(engine.getEnabledCipherSuites())); + if (protocols != null && protocols.length > 0) { + //Set supported protocols + engine.setEnabledProtocols(protocols); + LOG.debug("Supported ssl protocols {}", + Arrays.toString(engine.getSupportedProtocols())); + LOG.debug("Enabled ssl protocols {}", + Arrays.toString(engine.getEnabledProtocols())); + } + if (cipherSuites != null && cipherSuites.length > 0) { + //Set supported cipher suites + engine.setEnabledCipherSuites(cipherSuites); + LOG.debug("Enabled cipher suites {}", + Arrays.toString(engine.getEnabledCipherSuites())); + } channel.pipeline().addLast("ssl", new SslHandler(engine)); } @@ -521,15 +546,32 @@ public class OvsdbConnectionService implements AutoCloseable, OvsdbConnection { JsonRpcEndpoint.setReaperInterval(timeout); } + /** + * Set useSSL flag. + * + * @param flag boolean for using ssl + */ + public void setUseSsl(boolean flag) { + useSSL = flag; + } + + /** + * Set default Certificate manager service. + * + * @param certificateManagerSrv reference + */ + public void setCertificatManager(ICertificateManager certificateManagerSrv) { + certManagerSrv = certificateManagerSrv; + } + public void updateConfigParameter(Map configParameters) { LOG.debug("Config parameters received : {}", configParameters.entrySet()); if (configParameters != null && !configParameters.isEmpty()) { for (Map.Entry paramEntry : configParameters.entrySet()) { if (paramEntry.getKey().equalsIgnoreCase(OVSDB_RPC_TASK_TIMEOUT_PARAM)) { setOvsdbRpcTaskTimeout(Integer.parseInt((String)paramEntry.getValue())); - - //Please remove the break if you add more config nobs. - break; + } else if (paramEntry.getKey().equalsIgnoreCase(USE_SSL)) { + useSSL = Boolean.parseBoolean(paramEntry.getValue().toString()); } } } diff --git a/library/impl/src/main/resources/initial/library.cfg b/library/impl/src/main/resources/initial/library.cfg index 79ba8a77e..7622593f7 100644 --- a/library/impl/src/main/resources/initial/library.cfg +++ b/library/impl/src/main/resources/initial/library.cfg @@ -1,4 +1,6 @@ #Timeout value (in millisecond) after which OVSDB rpc task will be cancelled. #Default value is set to 1000ms, please uncomment and override the value if requires #Changing the value don't require controller restart. -#ovsdb-rpc-task-timeout = 1000 \ No newline at end of file +# ovsdb-rpc-task-timeout = 1000 +#This flag will be enforced across all the connection's (passive and active) if set to true +# use-ssl = false diff --git a/library/impl/src/main/resources/org/opendaylight/blueprint/library.xml b/library/impl/src/main/resources/org/opendaylight/blueprint/library.xml index 3f73ab0cf..29ca7d924 100644 --- a/library/impl/src/main/resources/org/opendaylight/blueprint/library.xml +++ b/library/impl/src/main/resources/org/opendaylight/blueprint/library.xml @@ -11,11 +11,18 @@ specify the property in library.cfg file--> + + + + + @@ -23,6 +30,7 @@ + ${nexus.site.url}/${project.artifactId}/ - + \ No newline at end of file diff --git a/southbound/southbound-features/src/main/features/features.xml b/southbound/southbound-features/src/main/features/features.xml index 50cab4db6..27f49a3a0 100644 --- a/southbound/southbound-features/src/main/features/features.xml +++ b/southbound/southbound-features/src/main/features/features.xml @@ -51,4 +51,4 @@ and is available at http://www.eclipse.org/legal/epl-v10.html mvn:org.opendaylight.ovsdb/utils.southbound-utils/{{VERSION}} mvn:org.opendaylight.ovsdb/southbound-impl/{{VERSION}}/cfg/config - + \ No newline at end of file diff --git a/southbound/southbound-impl/pom.xml b/southbound/southbound-impl/pom.xml index a451ca2ee..1504f96a0 100644 --- a/southbound/southbound-impl/pom.xml +++ b/southbound/southbound-impl/pom.xml @@ -185,4 +185,4 @@ and is available at http://www.eclipse.org/legal/epl-v10.html ${nexus.site.url}/${project.artifactId}/ - + \ No newline at end of file diff --git a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java index b7964afde..cfad32d3f 100644 --- a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java +++ b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManager.java @@ -650,4 +650,4 @@ public class OvsdbConnectionManager implements OvsdbConnectionListener, AutoClos */ ON_DISCONNECT } -} +} \ No newline at end of file diff --git a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java index 4fff92754..d4a342884 100644 --- a/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java +++ b/southbound/southbound-impl/src/main/java/org/opendaylight/ovsdb/southbound/SouthboundProvider.java @@ -186,4 +186,4 @@ public class SouthboundProvider implements AutoCloseable { SouthboundConstants.SKIP_COLUMN_FROM_TABLE.get("Manager").remove("status"); } } -} +} \ No newline at end of file diff --git a/southbound/southbound-impl/src/main/resources/initial/southbound.cfg b/southbound/southbound-impl/src/main/resources/initial/southbound.cfg index 1299870ae..576d50148 100644 --- a/southbound/southbound-impl/src/main/resources/initial/southbound.cfg +++ b/southbound/southbound-impl/src/main/resources/initial/southbound.cfg @@ -11,4 +11,4 @@ # setup. So please use this option when you are running OVSDB # southbound plugin in single node and want to achieve better # performance. -#skip-monitoring-manager-status = false +#skip-monitoring-manager-status = false \ No newline at end of file diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManagerTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManagerTest.java index cc0b71f0a..3a44a306c 100644 --- a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManagerTest.java +++ b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbConnectionManagerTest.java @@ -376,4 +376,4 @@ public class OvsdbConnectionManagerTest { Whitebox.invokeMethod(ovsdbConnManager, "handleOwnershipChanged", ownershipChange); PowerMockito.verifyPrivate(ovsdbConnManager, times(1)).invoke("putConnectionInstance", key, ovsdbConnInstance); } -} +} \ No newline at end of file diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListenerTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListenerTest.java index f66ee09e7..09df071b4 100644 --- a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListenerTest.java +++ b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/OvsdbDataTreeChangeListenerTest.java @@ -72,4 +72,4 @@ public class OvsdbDataTreeChangeListenerTest extends AbstractDataBrokerTest { // Then the listener tries to open a connection Mockito.verify(ovsdbConnection).connect(inetAddress, port); } -} +} \ No newline at end of file diff --git a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java index d9ac63a9a..8990f54a0 100644 --- a/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java +++ b/southbound/southbound-impl/src/test/java/org/opendaylight/ovsdb/southbound/SouthboundProviderTest.java @@ -141,4 +141,4 @@ public class SouthboundProviderTest extends AbstractDataBrokerTest { topologyIid).checkedGet().isPresent()); } } -} +} \ No newline at end of file