Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security realms ssl truststore commands #116

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package org.wildfly.extras.creaper.commands.security.realms;

import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform;
import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree;
import org.wildfly.extras.creaper.core.offline.OfflineCommandContext;
import org.wildfly.extras.creaper.core.online.OnlineCommandContext;
import org.wildfly.extras.creaper.core.online.operations.Address;
import org.wildfly.extras.creaper.core.online.operations.Operations;
import org.wildfly.extras.creaper.core.online.operations.Values;
import org.wildfly.extras.creaper.core.online.operations.admin.Administration;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class AddSslServerIdentity extends AbstractAddSecurityRealmSubElement {
// keystore
private final String keystorePassword;
private final String alias;
private final List<String> enabledCipherSuites;
private final List<String> enabledProtocols;
private final String keyPassword;
private final String keystorePath;
private final String keystoreProvider;
private final String keystoreRelativeTo;
private final String protocol;

public AddSslServerIdentity(Builder builder) {
super(builder);
this.keystorePassword = builder.keystorePassword;
this.alias = builder.alias;
this.enabledCipherSuites = builder.enabledCipherSuites;
this.enabledProtocols = builder.enabledProtocols;
this.keyPassword = builder.keyPassword;
this.keystorePath = builder.keystorePath;
this.keystoreProvider = builder.keystoreProvider;
this.keystoreRelativeTo = builder.keystoreRelativeTo;
this.protocol = builder.protocol;
}

@Override
public final void apply(OfflineCommandContext ctx) throws Exception {
ctx.client.apply(GroovyXmlTransform.of(AddSslServerIdentity.class)
.subtree("management", Subtree.management())
.parameter("realmName", securityRealmName)
.parameter("alias", alias)
.parameter("enabledCipherSuites", enabledCipherSuites)
.parameter("enabledProtocols", enabledProtocols)
.parameter("keyPassword", keyPassword)
.parameter("keystorePassword", keystorePassword)
.parameter("keystorePath", keystorePath)
.parameter("keystoreProvider", keystoreProvider)
.parameter("keystoreRelativeTo", keystoreRelativeTo)
.parameter("protocol", protocol)
.parameter("replaceExisting", replaceExisting)
.build());
}

@Override
public final void apply(OnlineCommandContext ctx) throws Exception {
Address sslServerIdentitiesAddress = securityRealmAddress.and("server-identity", "ssl");

Operations ops = new Operations(ctx.client);

if (replaceExisting) {
boolean secretServerIdentityExists = ops.exists(sslServerIdentitiesAddress);
if (secretServerIdentityExists) {
ops.remove(sslServerIdentitiesAddress);
}
new Administration(ctx.client).reloadIfRequired();
}

ops.add(securityRealmAddress.and("server-identity", "ssl"), Values.empty()
.andOptional("alias", alias)
.andListOptional(String.class, "enabled-cipher-suites", enabledCipherSuites)
.andListOptional(String.class, "enabled-protocols", enabledProtocols)
.andOptional("key-password", keyPassword)
.and("keystore-password", keystorePassword)
.andOptional("keystore-path", keystorePath)
.andOptional("keystore-provider", keystoreProvider)
.andOptional("keystore-relative-to", keystoreRelativeTo)
.andOptional("protocol", protocol));
}


public static final class Builder extends AbstractAddSecurityRealmSubElement.Builder<Builder> {

private String keystorePassword;
private String alias;
private List<String> enabledCipherSuites;
private List<String> enabledProtocols;
private String keyPassword;
private String keystorePath;
private String keystoreProvider;
private String keystoreRelativeTo;
private String protocol;

public Builder(String securityRealmName) {
super(securityRealmName);
}

/**
* The alias of the entry to use from the keystore.
*/
public Builder alias(String alias) {
this.alias = alias;
return this;
}

/**
* Adds ciphers which should be set as enabled on the underlying SSLEngine.
*/
public Builder cipherSuitesToEnable(String... cipherSuitesToEnable) {
if (this.enabledCipherSuites == null && cipherSuitesToEnable != null) {
this.enabledCipherSuites = new ArrayList<String>();
}
if (cipherSuitesToEnable != null) {
this.enabledCipherSuites.addAll(Arrays.asList(cipherSuitesToEnable));
}
return this;
}

/**
* Adds protocols which should be set as enabled on the underlying SSLEngine.
*/
public Builder protocolsToEnable(String... protocolsToEnable) {
if (this.enabledProtocols == null && protocolsToEnable != null) {
this.enabledProtocols = new ArrayList<String>();
}
if (protocolsToEnable != null) {
this.enabledProtocols.addAll(Arrays.asList(protocolsToEnable));
}
return this;
}

/**
* Defines the password to open the keystore. This is mandatory parameter which needs to be set.
*/
public Builder keystorePassword(String keystorePassword) {
this.keystorePassword = keystorePassword;
return this;
}

/**
* Defines the password to obtain the key from the keystore.
*/
public Builder keyPassword(String keyPassword) {
this.keyPassword = keyPassword;
return this;
}

/**
* Defines the path of the keystore, will be ignored if the keystore provider is anything other than JKS.
*/
public Builder keystorePath(String keystorePath) {
this.keystorePath = keystorePath;
return this;
}

/**
* The provider for loading the keystore, defaults to JKS.
*/
public Builder keystoreProvider(String keystoreProvider) {
this.keystoreProvider = keystoreProvider;
return this;
}

/**
* Defines name of another previously named path, or of one of the standard paths provided by the system.
* If 'relative-to' is provided, the value of the 'path' attribute is treated as relative to the path specified
* by this attribute.
*/
public Builder keystoreRelativeTo(String keystoreRelativeTo) {
this.keystoreRelativeTo = keystoreRelativeTo;
return this;
}

/**
* Defines the protocol to use when creating the SSLContext.
*/
public Builder protocol(String protocol) {
this.protocol = protocol;
return this;
}


@Override
public AddSslServerIdentity build() {
if (keystorePassword == null) {
throw new IllegalArgumentException("keystorePassword is manadatory");
}
return new AddSslServerIdentity(this);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package org.wildfly.extras.creaper.commands.security.realms;

import org.wildfly.extras.creaper.commands.foundation.offline.xml.GroovyXmlTransform;
import org.wildfly.extras.creaper.commands.foundation.offline.xml.Subtree;
import org.wildfly.extras.creaper.core.offline.OfflineCommandContext;
import org.wildfly.extras.creaper.core.online.OnlineCommandContext;
import org.wildfly.extras.creaper.core.online.operations.Address;
import org.wildfly.extras.creaper.core.online.operations.Operations;
import org.wildfly.extras.creaper.core.online.operations.Values;
import org.wildfly.extras.creaper.core.online.operations.admin.Administration;

public class AddTruststoreAuthentication extends AbstractAddSecurityRealmSubElement {
private final String truststorePassword;
private String truststorePath;
private String truststoreProvider;
private String truststoreRelativeTo;

public AddTruststoreAuthentication(Builder builder) {
super(builder);
this.truststorePassword = builder.truststorePassword;
this.truststorePath = builder.truststorePath;
this.truststoreProvider = builder.truststoreProvider;
this.truststoreRelativeTo = builder.truststoreRelativeTo;
}

@Override
public final void apply(OfflineCommandContext ctx) throws Exception {
ctx.client.apply(GroovyXmlTransform.of(AddTruststoreAuthentication.class)
.subtree("management", Subtree.management())
.parameter("realmName", securityRealmName)
.parameter("truststorePassword", truststorePassword)
.parameter("truststorePath", truststorePath)
.parameter("truststoreProvider", truststoreProvider)
.parameter("truststoreRelativeTo", truststoreRelativeTo)
.parameter("replaceExisting", replaceExisting)
.build());
}

@Override
public final void apply(OnlineCommandContext ctx) throws Exception {
Address truststoreAuthAddress = securityRealmAddress.and("authentication", "truststore");

Operations ops = new Operations(ctx.client);

if (replaceExisting) {
boolean truststoreAuthExist = ops.exists(truststoreAuthAddress);
if (truststoreAuthExist) {
ops.remove(truststoreAuthAddress);
}
new Administration(ctx.client).reloadIfRequired();
}

ops.add(truststoreAuthAddress, Values.empty()
.and("keystore-password", truststorePassword)
.andOptional("keystore-path", truststorePath)
.andOptional("keystore-provider", truststoreProvider)
.andOptional("keystore-relative-to", truststoreRelativeTo));
}


public static final class Builder extends AbstractAddSecurityRealmSubElement.Builder<Builder> {

private String truststorePassword;
private String truststorePath;
private String truststoreProvider;
private String truststoreRelativeTo;

public Builder(String securityRealmName) {
super(securityRealmName);
}

/**
* Defines the password to open the truststore. It is mandatory parameter when also defining truststore
*/
public Builder truststorePassword(String truststorePassword) {
this.truststorePassword = truststorePassword;
return this;
}

/**
* Defines the path of the trustore, will be ignored if the truststore provider is anything other than JKS.
* If not defined, truststore is not defined for the server.
*/
public Builder truststorePath(String truststorePath) {
this.truststorePath = truststorePath;
return this;
}

/**
* Defines the provider for loading the truststore, defaults to JKS.
*/
public Builder truststoreProvider(String truststoreProvider) {
this.truststoreProvider = truststoreProvider;
return this;
}

/**
* Define name of another previously named path, or of one of the standard paths provided by the system.
* If 'relative-to' is provided, the value of the 'path' attribute is treated as relative to the path
* specified by this attribute.
*/
public Builder truststoreRelativeTo(String truststoreRelativeTo) {
this.truststoreRelativeTo = truststoreRelativeTo;
return this;
}

@Override
public AddTruststoreAuthentication build() {
if (truststorePassword == null) {
throw new IllegalArgumentException("truststorePassword is manadatory when defining the truststore");
}
return new AddTruststoreAuthentication(this);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
def securityRealm = management.'security-realms'.'security-realm'
def isSecurityRealmExist = securityRealm.any { it.'@name' == realmName }
if (!isSecurityRealmExist) {
throw new IllegalStateException("Security realm with name $realmName does not exist.")
}

def engineAttrs = [:]
if (enabledCipherSuites != null) engineAttrs['enabled-cipher-suites'] = ((List)enabledCipherSuites).join(" ")
if (enabledProtocols != null) engineAttrs['enabled-protocols'] = ((List)enabledProtocols).join(" ")

def keystoreAttrs = [:]
if (alias != null) keystoreAttrs['alias'] = alias
if (keyPassword != null) keystoreAttrs['key-password'] = keyPassword
if (keystorePassword != null) keystoreAttrs['keystore-password'] = keystorePassword
if (keystorePath != null) keystoreAttrs['path'] = keystorePath
if (keystoreProvider != null) keystoreAttrs['provider'] = keystoreProvider
if (keystoreRelativeTo != null) keystoreAttrs['relative-to'] = keystoreRelativeTo
if (protocol != null) keystoreAttrs['protocol'] = protocol

def sslDefinition = {
'ssl' {
if (!engineAttrs.isEmpty()) {
'engine'(engineAttrs)
}
if (!keystoreAttrs.isEmpty()) {
'keystore'(keystoreAttrs)
}
}
}

def usedSecurityRealm = securityRealm.find { it.'@name' == realmName }

def serverIdentities = usedSecurityRealm.'server-identities'
def isExistingServerIdentities = serverIdentities.any { it.name() == 'server-identities' }
if (isExistingServerIdentities) {
def isExistingSecret = serverIdentities.ssl.any { it.name() == 'ssl' }
if (isExistingSecret && !replaceExisting) {
throw new IllegalStateException("SSL server identity already exists in security realm with name $realmName.")
} else {
if (isExistingSecret) {
serverIdentities.ssl.find().replaceNode sslDefinition
} else {
serverIdentities.appendNode sslDefinition
}
}
} else {
usedSecurityRealm.appendNode {
'server-identities'(sslDefinition)
}
}
Loading