diff options
10 files changed, 126 insertions, 47 deletions
diff --git a/hv-collector-core/pom.xml b/hv-collector-core/pom.xml index 18657316..cf99867f 100644 --- a/hv-collector-core/pom.xml +++ b/hv-collector-core/pom.xml @@ -83,6 +83,10 @@ <artifactId>arrow-effects</artifactId> </dependency> <dependency> + <groupId>io.arrow-kt</groupId> + <artifactId>arrow-core</artifactId> + </dependency> + <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> </dependency> diff --git a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt index e9985766..61e1ebff 100644 --- a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt +++ b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/NettyTcpServer.kt @@ -19,7 +19,9 @@ */ package org.onap.dcae.collectors.veshv.impl.socket +import arrow.core.Option import arrow.effects.IO +import io.netty.handler.ssl.SslContext import org.onap.dcae.collectors.veshv.boundary.CollectorProvider import org.onap.dcae.collectors.veshv.boundary.Server import org.onap.dcae.collectors.veshv.boundary.ServerHandle @@ -54,8 +56,9 @@ internal class NettyTcpServer(private val serverConfig: ServerConfiguration, } private fun configureServer(opts: ServerOptions.Builder<*>) { + val sslContext: Option<SslContext> = sslContextFactory.createSslContext(serverConfig.securityConfiguration) + if (sslContext.isDefined()) opts.sslContext(sslContext.orNull()) opts.port(serverConfig.port) - opts.sslContext(sslContextFactory.createSslContext(serverConfig.securityConfiguration)) } private fun handleConnection(nettyInbound: NettyInbound): Mono<Void> { diff --git a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactory.kt b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactory.kt index b6fb1cf8..0dce0d61 100644 --- a/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactory.kt +++ b/hv-collector-core/src/main/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactory.kt @@ -19,6 +19,9 @@ */ package org.onap.dcae.collectors.veshv.impl.socket +import arrow.core.None +import arrow.core.Option +import arrow.core.Some import io.netty.handler.ssl.ClientAuth import io.netty.handler.ssl.SslContext import io.netty.handler.ssl.SslContextBuilder @@ -27,11 +30,15 @@ import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration internal open class SslContextFactory { - fun createSslContext(secConfig: SecurityConfiguration): SslContext = - createSslContextWithConfiguredCerts(secConfig) - .sslProvider(SslProvider.OPENSSL) - .clientAuth(ClientAuth.REQUIRE) - .build() + fun createSslContext(secConfig: SecurityConfiguration): Option<SslContext> = + if (secConfig.sslDisable) { + Option.empty() + } else { + Option.just(createSslContextWithConfiguredCerts(secConfig) + .sslProvider(SslProvider.OPENSSL) + .clientAuth(ClientAuth.REQUIRE) + .build()) + } protected open fun createSslContextWithConfiguredCerts(secConfig: SecurityConfiguration): SslContextBuilder = SslContextBuilder.forServer(secConfig.cert.toFile(), secConfig.privateKey.toFile()) diff --git a/hv-collector-core/src/test/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactoryTest.kt b/hv-collector-core/src/test/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactoryTest.kt index 26a25d33..deb4e183 100644 --- a/hv-collector-core/src/test/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactoryTest.kt +++ b/hv-collector-core/src/test/kotlin/org/onap/dcae/collectors/veshv/impl/socket/SslContextFactoryTest.kt @@ -20,15 +20,17 @@ package org.onap.dcae.collectors.veshv.impl.socket import io.netty.handler.ssl.ClientAuth -import io.netty.handler.ssl.OpenSslServerContext import io.netty.handler.ssl.ReferenceCountedOpenSslContext import io.netty.handler.ssl.SslContextBuilder import org.assertj.core.api.Assertions.assertThat import org.jetbrains.spek.api.Spek import org.jetbrains.spek.api.dsl.describe +import org.jetbrains.spek.api.dsl.given import org.jetbrains.spek.api.dsl.it +import org.jetbrains.spek.api.dsl.on import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration import java.nio.file.Paths +import kotlin.test.assertTrue /** * @author Piotr Jaszczyk <piotr.jaszczyk@nokia.com> @@ -36,43 +38,66 @@ import java.nio.file.Paths */ object SslContextFactoryTest : Spek({ describe("SslContextFactory") { - val sampleConfig = SecurityConfiguration( - privateKey = Paths.get("/", "tmp", "pk.pem"), - cert = Paths.get("/", "tmp", "cert.crt"), - trustedCert = Paths.get("/", "tmp", "clientCa.crt")) + given("config without disabled SSL") { + val sampleConfig = SecurityConfiguration( + privateKey = Paths.get("/", "tmp", "pk.pem"), + cert = Paths.get("/", "tmp", "cert.crt"), + trustedCert = Paths.get("/", "tmp", "clientCa.crt")) - val cut = object : SslContextFactory() { - var actualConfig: SecurityConfiguration? = null - override fun createSslContextWithConfiguredCerts(secConfig: SecurityConfiguration): SslContextBuilder { - actualConfig = secConfig - return SslContextBuilder.forServer(resource("/ssl/ca.crt"), resource("/ssl/server.key")) + val cut = object : SslContextFactory() { + override fun createSslContextWithConfiguredCerts(secConfig: SecurityConfiguration): SslContextBuilder { + return SslContextBuilder.forServer(resource("/ssl/ca.crt"), resource("/ssl/server.key")) + } + + private fun resource(path: String) = SslContextFactoryTest.javaClass.getResourceAsStream(path) } - private fun resource(path: String) = SslContextFactoryTest.javaClass.getResourceAsStream(path) - } + on("creation of SSL context") { + val result = cut.createSslContext(sampleConfig) - val result = cut.createSslContext(sampleConfig) + it("should be server context") { + assertTrue(result.exists { + it.isServer + }) + } - it("should be server context") { - assertThat(result.isServer).isTrue() - } + it("should use OpenSSL provider") { + assertTrue(result.isDefined()) + } - it("should use OpenSSL provider") { - assertThat(result).isInstanceOf(OpenSslServerContext::class.java) + /* + * It is too important to leave it untested on unit level. + * Because of the Netty API design we need to do it this way. + */ + it("should turn on client authentication") { + val clientAuth: ClientAuth = ReferenceCountedOpenSslContext::class.java + .getDeclaredField("clientAuth") + .run { + isAccessible = true + get(result.orNull()) as ClientAuth + } + assertThat(clientAuth).isEqualTo(ClientAuth.REQUIRE) + } + } } - /* - * It is too important to leave it untested on unit level. - * Because of the Netty API design we need to do it this way. - */ - it("should turn on client authentication") { - val clientAuth: ClientAuth = ReferenceCountedOpenSslContext::class.java - .getDeclaredField("clientAuth") - .run { - isAccessible = true - get(result) as ClientAuth - } - assertThat(clientAuth).isEqualTo(ClientAuth.REQUIRE) + given("config with SSL disabled") { + val securityConfiguration = SecurityConfiguration( + sslDisable = true, + privateKey = Paths.get("sample", "key"), + cert = Paths.get("sample", "cert"), + trustedCert = Paths.get("/", "sample", "trusted", "cert") + ) + val cut = SslContextFactory() + + on("creation of SSL context") { + val result = cut.createSslContext(securityConfiguration) + + it("should not create any SSL context ") { + assertThat(result.isDefined()).isFalse() + } + } } + } }) diff --git a/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt b/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt index 6f28b6e9..e409eb7a 100644 --- a/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt +++ b/hv-collector-domain/src/main/kotlin/org/onap/dcae/collectors/veshv/domain/SecurityConfiguration.kt @@ -26,6 +26,7 @@ import java.nio.file.Path * @since May 2018 */ data class SecurityConfiguration( + val sslDisable: Boolean = false, val privateKey: Path, val cert: Path, val trustedCert: Path) diff --git a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt index 9e4c5f2d..35ca09d8 100644 --- a/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt +++ b/hv-collector-main/src/main/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfiguration.kt @@ -42,6 +42,7 @@ internal class ArgBasedServerConfiguration : ArgBasedConfiguration<ServerConfigu LISTEN_PORT, CONSUL_CONFIG_URL, CONSUL_FIRST_REQUEST_DELAY, + SSL_DISABLE, PRIVATE_KEY_FILE, CERT_FILE, TRUST_CERT_FILE, @@ -66,11 +67,13 @@ internal class ArgBasedServerConfiguration : ArgBasedConfiguration<ServerConfigu } private fun createSecurityConfiguration(cmdLine: CommandLine): SecurityConfiguration { + val sslDisable = cmdLine.hasOption(SSL_DISABLE) val pkFile = cmdLine.stringValue(PRIVATE_KEY_FILE, DefaultValues.PRIVATE_KEY_FILE) val certFile = cmdLine.stringValue(CERT_FILE, DefaultValues.CERT_FILE) val trustCertFile = cmdLine.stringValue(TRUST_CERT_FILE, DefaultValues.TRUST_CERT_FILE) return SecurityConfiguration( + sslDisable = sslDisable, privateKey = stringPathToPath(pkFile), cert = stringPathToPath(certFile), trustedCert = stringPathToPath(trustCertFile) diff --git a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt index b56b1b1d..0498344c 100644 --- a/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt +++ b/hv-collector-main/src/test/kotlin/org/onap/dcae/collectors/veshv/main/ArgBasedServerConfigurationTest.kt @@ -59,7 +59,8 @@ object ArgBasedServerConfigurationTest : Spek({ lateinit var result: ServerConfiguration beforeEachTest { - result = parse("--listen-port", listenPort, + result = parse("--ssl-disable", + "--listen-port", listenPort, "--config-url", configurationUrl, "--first-request-delay", firstRequestDelay, "--private-key-file", pk.toFile().absolutePath, @@ -81,7 +82,7 @@ object ArgBasedServerConfigurationTest : Spek({ it("should set proper security configuration") { assertThat(result.securityConfiguration).isEqualTo( - SecurityConfiguration(pk, cert, trustCert) + SecurityConfiguration(sslDisable = true, privateKey = pk, cert = cert, trustedCert = trustCert) ) } diff --git a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt index 82711d9b..27213c95 100644 --- a/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt +++ b/hv-collector-utils/src/main/kotlin/org/onap/dcae/collectors/veshv/utils/commandline/CommandLineOption.kt @@ -75,6 +75,11 @@ enum class CommandLineOption(val option: Option) { .desc("Comma-separated Kafka topics") .build() ), + SSL_DISABLE(Option.builder("l") + .longOpt("ssl-disable") + .desc("Disable SSL encryption") + .build() + ), PRIVATE_KEY_FILE(Option.builder("k") .longOpt("private-key-file") .hasArg() diff --git a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt index 04654f8c..96e65778 100644 --- a/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt +++ b/hv-collector-xnf-simulator/src/main/kotlin/org/onap/dcae/collectors/veshv/simulators/xnf/config/ArgConfigurationProvider.kt @@ -23,12 +23,7 @@ import org.apache.commons.cli.CommandLine import org.apache.commons.cli.DefaultParser import org.onap.dcae.collectors.veshv.domain.SecurityConfiguration import org.onap.dcae.collectors.veshv.utils.commandline.ArgBasedConfiguration -import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.CERT_FILE -import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.MESSAGES_TO_SEND_AMOUNT -import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.PRIVATE_KEY_FILE -import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.TRUST_CERT_FILE -import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.VES_HV_HOST -import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.VES_HV_PORT +import org.onap.dcae.collectors.veshv.utils.commandline.CommandLineOption.* /** @@ -40,6 +35,7 @@ internal class ArgConfigurationProvider : ArgBasedConfiguration<SimulatorConfigu VES_HV_PORT, VES_HV_HOST, MESSAGES_TO_SEND_AMOUNT, + SSL_DISABLE, PRIVATE_KEY_FILE, CERT_FILE, TRUST_CERT_FILE @@ -57,10 +53,12 @@ internal class ArgConfigurationProvider : ArgBasedConfiguration<SimulatorConfigu } private fun parseSecurityConfig(cmdLine: CommandLine): SecurityConfiguration { + val sslDisable = cmdLine.hasOption(SSL_DISABLE) val pkFile = cmdLine.stringValue(PRIVATE_KEY_FILE, DefaultValues.PRIVATE_KEY_FILE) val certFile = cmdLine.stringValue(CERT_FILE, DefaultValues.CERT_FILE) val trustCertFile = cmdLine.stringValue(TRUST_CERT_FILE, DefaultValues.TRUST_CERT_FILE) return SecurityConfiguration( + sslDisable = sslDisable, privateKey = stringPathToPath(pkFile), cert = stringPathToPath(certFile), trustedCert = stringPathToPath(trustCertFile)) diff --git a/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt index f2f92fff..fccd8b5a 100644 --- a/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt +++ b/hv-collector-xnf-simulator/src/test/kotlin/org/onap/dcae/collectors/veshv/main/config/ArgConfigurationProviderTest.kt @@ -31,6 +31,7 @@ import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgConfigurationProv import org.onap.dcae.collectors.veshv.simulators.xnf.config.ArgConfigurationProvider.* import org.onap.dcae.collectors.veshv.simulators.xnf.config.SimulatorConfiguration import java.nio.file.Paths +import kotlin.test.assertTrue object ArgConfigurationProviderTest : Spek({ @@ -47,7 +48,7 @@ object ArgConfigurationProviderTest : Spek({ fun parse(vararg cmdLine: String): SimulatorConfiguration = cut.parse(cmdLine).fold( - {throw AssertionError("Parsing result should be present")}, + { throw AssertionError("Parsing result should be present") }, ::identity ) @@ -57,7 +58,8 @@ object ArgConfigurationProviderTest : Spek({ given("all parameters are present in the long form") { beforeEachTest { - result = parse("--ves-port", "6969", + result = parse("--ssl-disable", + "--ves-port", "6969", "--ves-host", vesHost, "--messages", messagesAmount.toString(), "--private-key-file", pk.toFile().absolutePath, @@ -76,7 +78,7 @@ object ArgConfigurationProviderTest : Spek({ it("should set proper security configuration") { assertThat(result.security).isEqualTo( - SecurityConfiguration(pk, cert, trustCert) + SecurityConfiguration(sslDisable = true, privateKey = pk, cert = cert, trustedCert = trustCert) ) } } @@ -122,5 +124,35 @@ object ArgConfigurationProviderTest : Spek({ } } } + + given("disabled ssl certs together with all other parameters") { + beforeEachTest { + result = parse("--ssl-disable", + "--ves-port", "888", + "--ves-host", vesHost, + "--messages", messagesAmount.toString(), + "--private-key-file", pk.toFile().absolutePath, + "--cert-file", cert.toFile().absolutePath, + "--trust-cert-file", trustCert.toFile().absolutePath) + } + + on("security config") { + val securityConfiguration = result.security + + it("should set ssl disable to true"){ + assertTrue(securityConfiguration.sslDisable) + } + + it("should set proper security configuration") { + assertThat(securityConfiguration).isEqualTo( + SecurityConfiguration( + sslDisable = true, + privateKey = pk, + cert = cert, + trustedCert = trustCert) + ) + } + } + } } }) |