diff --git a/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java b/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java index 58a317f..84b27c6 100644 --- a/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java +++ b/gbcs-api/src/main/java/net/woggioni/gbcs/api/Configuration.java @@ -91,11 +91,14 @@ public class Configuration { boolean verifyClients; } + public enum ClientCertificate { + REQUIRED, OPTIONAL + } + @Value public static class Tls { KeyStore keyStore; TrustStore trustStore; - boolean verifyClients; } @Value @@ -111,6 +114,7 @@ public class Configuration { Path file; String password; boolean checkCertificateStatus; + boolean requireClientCertificate; } @Value diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt index e5072a4..648d651 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/GradleBuildCacheServer.kt @@ -208,15 +208,15 @@ class GradleBuildCacheServer(private val cfg: Configuration) { .map { it as X509Certificate } .toArray { size -> Array(size) { null } } SslContextBuilder.forServer(serverKey, *serverCert).apply { - if (tls.isVerifyClients) { - clientAuth(ClientAuth.OPTIONAL) - tls.trustStore?.let { trustStore -> - val ts = loadKeystore(trustStore.file, trustStore.password) - trustManager( - ClientCertificateValidator.getTrustManager(ts, trustStore.isCheckCertificateStatus) - ) - } - } + val clientAuth = tls.trustStore?.let { trustStore -> + val ts = loadKeystore(trustStore.file, trustStore.password) + trustManager( + ClientCertificateValidator.getTrustManager(ts, trustStore.isCheckCertificateStatus) + ) + if(trustStore.isRequireClientCertificate) ClientAuth.REQUIRE + else ClientAuth.OPTIONAL + } ?: ClientAuth.NONE + clientAuth(clientAuth) }.build() } } diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt index 7052f52..172c2f5 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Parser.kt @@ -142,10 +142,9 @@ object Parser { } "tls" -> { - val verifyClients = child.renderAttribute("verify-clients") - ?.let(String::toBoolean) ?: false var keyStore: KeyStore? = null var trustStore: TrustStore? = null + for (granChild in child.asIterable()) { when (granChild.localName) { "keystore" -> { @@ -167,15 +166,19 @@ object Parser { val checkCertificateStatus = granChild.renderAttribute("check-certificate-status") ?.let(String::toBoolean) ?: false + val requireClientCertificate = child.renderAttribute("require-client-certificate") + ?.let(String::toBoolean) ?: false + trustStore = TrustStore( trustStoreFile, trustStorePassword, - checkCertificateStatus + checkCertificateStatus, + requireClientCertificate ) } } } - tls = Tls(keyStore, trustStore, verifyClients) + tls = Tls(keyStore, trustStore) } } } diff --git a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt index bde42d9..febb0fa 100644 --- a/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt +++ b/gbcs-server/src/main/kotlin/net/woggioni/gbcs/server/configuration/Serializer.kt @@ -154,9 +154,6 @@ object Serializer { conf.tls?.let { tlsConfiguration -> node("tls") { - if(tlsConfiguration.isVerifyClients) { - attr("verify-clients", "true") - } tlsConfiguration.keyStore?.let { keyStore -> node("keystore") { attr("file", keyStore.file.toString()) @@ -177,6 +174,7 @@ object Serializer { attr("password", password) } attr("check-certificate-status", trustStore.isCheckCertificateStatus.toString()) + attr("require-client-certificate", trustStore.isRequireClientCertificate.toString()) } } } diff --git a/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd b/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd index cade632..d5c15b1 100644 --- a/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd +++ b/gbcs-server/src/main/resources/net/woggioni/gbcs/server/schema/gbcs.xsd @@ -183,7 +183,6 @@ - @@ -197,6 +196,7 @@ + diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt index 5c90385..b2ec910 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/AbstractTlsServerTest.kt @@ -171,9 +171,8 @@ abstract class AbstractTlsServerTest : AbstractServerTest() { ), Configuration.Tls( Configuration.KeyStore(this.serverKeyStoreFile, null, SERVER_CERTIFICATE_ENTRY, PASSWORD), - Configuration.TrustStore(this.trustStoreFile, null, false), - true - ), + Configuration.TrustStore(this.trustStoreFile, null, false, false), + ) ) Xml.write(Serializer.serialize(cfg), System.out) } diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/ConfigurationTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/ConfigurationTest.kt index 5206987..2a63b10 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/ConfigurationTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/ConfigurationTest.kt @@ -20,6 +20,7 @@ class ConfigurationTest { "classpath:net/woggioni/gbcs/server/test/valid/gbcs-default.xml", "classpath:net/woggioni/gbcs/server/test/valid/gbcs-memcached.xml", "classpath:net/woggioni/gbcs/server/test/valid/gbcs-tls.xml", + "classpath:net/woggioni/gbcs/server/test/valid/gbcs-memcached-tls.xml", ] ) @ParameterizedTest diff --git a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/TlsServerTest.kt b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/TlsServerTest.kt index e753a53..c0d0902 100644 --- a/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/TlsServerTest.kt +++ b/gbcs-server/src/test/kotlin/net/woggioni/gbcs/server/test/TlsServerTest.kt @@ -7,6 +7,7 @@ import org.bouncycastle.asn1.x500.X500Name import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Order import org.junit.jupiter.api.Test +import org.junit.jupiter.params.provider.ArgumentsSource import java.net.http.HttpClient import java.net.http.HttpRequest import java.net.http.HttpResponse diff --git a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-memcached-tls.xml b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-memcached-tls.xml new file mode 100644 index 0000000..84a7fb7 --- /dev/null +++ b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-memcached-tls.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-tls.xml b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-tls.xml index cda0103..b3642df 100644 --- a/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-tls.xml +++ b/gbcs-server/src/test/resources/net/woggioni/gbcs/server/test/valid/gbcs-tls.xml @@ -60,8 +60,8 @@ - + - + \ No newline at end of file