Skip to content

Commit

Permalink
Adding commands to manager trusted certificates
Browse files Browse the repository at this point in the history
  • Loading branch information
spyrkob committed Oct 17, 2024
1 parent 0eb32eb commit 0154a29
Show file tree
Hide file tree
Showing 11 changed files with 534 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.core.instmgr;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ATTACHED_STREAMS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FILESYSTEM_PATH;

import java.io.InputStream;
import java.nio.file.Path;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationDefinition;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
import org.jboss.as.controller.registry.OperationEntry;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.wildfly.installationmanager.MavenOptions;
import org.wildfly.installationmanager.spi.InstallationManager;
import org.wildfly.installationmanager.spi.InstallationManagerFactory;

/**
* Operation handler to get the history of the installation manager changes, either artifacts or configuration metadata as
* channel changes.
*/
public class InstMgrCertificateImportHandler extends InstMgrOperationStepHandler {
public static final String OPERATION_NAME = "certificate-import";

protected static final AttributeDefinition CERT_FILE = SimpleAttributeDefinitionBuilder.create(InstMgrConstants.CERT_FILE, ModelType.INT)
.setStorageRuntime()
.setRequired(true)
.addArbitraryDescriptor(FILESYSTEM_PATH, ModelNode.TRUE)
.addArbitraryDescriptor(ATTACHED_STREAMS, ModelNode.TRUE)
.build();

public static final OperationDefinition DEFINITION = new SimpleOperationDefinitionBuilder(OPERATION_NAME, InstMgrResolver.RESOLVER)
.withFlags(OperationEntry.Flag.HOST_CONTROLLER_ONLY)
.setReplyType(ModelType.OBJECT)
.setRuntimeOnly()
.setReplyValueType(ModelType.OBJECT)
.addParameter(CERT_FILE)
.build();

InstMgrCertificateImportHandler(InstMgrService imService, InstallationManagerFactory imf) {
super(imService, imf);
}

@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
context.addStep(new OperationStepHandler() {
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
try {
Path serverHome = imService.getHomeDir();
MavenOptions mavenOptions = new MavenOptions(null, false);
InstallationManager installationManager = imf.create(serverHome, mavenOptions);

try (InputStream is = context.getAttachmentStream(CERT_FILE.resolveModelAttribute(context, operation).asInt())) {
installationManager.acceptTrustedCertificates(is);
}
} catch (OperationFailedException | RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, OperationContext.Stage.RUNTIME);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.core.instmgr;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ATTACHED_STREAMS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FILESYSTEM_PATH;
import static org.wildfly.core.instmgr.InstMgrConstants.CERT_DESCRIPTION;
import static org.wildfly.core.instmgr.InstMgrConstants.CERT_FINGERPRINT;
import static org.wildfly.core.instmgr.InstMgrConstants.CERT_KEY_ID;
import static org.wildfly.core.instmgr.InstMgrConstants.CERT_STATUS;

import java.io.InputStream;
import java.nio.file.Path;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationDefinition;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
import org.jboss.as.controller.registry.OperationEntry;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.wildfly.installationmanager.MavenOptions;
import org.wildfly.installationmanager.TrustCertificate;
import org.wildfly.installationmanager.spi.InstallationManager;
import org.wildfly.installationmanager.spi.InstallationManagerFactory;

/**
* Operation handler to get the history of the installation manager changes, either artifacts or configuration metadata as
* channel changes.
*/
public class InstMgrCertificateParseHandler extends InstMgrOperationStepHandler {
public static final String OPERATION_NAME = "certificate-parse";

protected static final AttributeDefinition CERT_FILE = SimpleAttributeDefinitionBuilder.create(InstMgrConstants.CERT_FILE, ModelType.INT)
.setStorageRuntime()
.setRequired(true)
.addArbitraryDescriptor(FILESYSTEM_PATH, ModelNode.TRUE)
.addArbitraryDescriptor(ATTACHED_STREAMS, ModelNode.TRUE)
.build();

public static final OperationDefinition DEFINITION = new SimpleOperationDefinitionBuilder(OPERATION_NAME, InstMgrResolver.RESOLVER)
.withFlags(OperationEntry.Flag.HOST_CONTROLLER_ONLY)
.setReplyType(ModelType.OBJECT)
.setRuntimeOnly()
.setReplyValueType(ModelType.OBJECT)
.addParameter(CERT_FILE)
.build();

InstMgrCertificateParseHandler(InstMgrService imService, InstallationManagerFactory imf) {
super(imService, imf);
}

@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
context.addStep(new OperationStepHandler() {
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
try {
Path serverHome = imService.getHomeDir();
MavenOptions mavenOptions = new MavenOptions(null, false);
InstallationManager installationManager = imf.create(serverHome, mavenOptions);

try (InputStream is = context.getAttachmentStream(CERT_FILE.resolveModelAttribute(context, operation).asInt())) {
TrustCertificate tc = installationManager.parseCA(is);

ModelNode entry = new ModelNode();
entry.get(CERT_KEY_ID).set(tc.getKeyID());
entry.get(CERT_FINGERPRINT).set(tc.getFingerprint());
entry.get(CERT_DESCRIPTION).set(tc.getDescription());
entry.get(CERT_STATUS).set(tc.getStatus());
context.getResult().set(entry);
}
} catch (OperationFailedException | RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, OperationContext.Stage.RUNTIME);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright The WildFly Authors
* SPDX-License-Identifier: Apache-2.0
*/

package org.wildfly.core.instmgr;

import static org.wildfly.core.instmgr.InstMgrConstants.CERT_KEY_ID;

import java.nio.file.Path;

import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationDefinition;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
import org.jboss.as.controller.registry.OperationEntry;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.wildfly.installationmanager.MavenOptions;
import org.wildfly.installationmanager.spi.InstallationManager;
import org.wildfly.installationmanager.spi.InstallationManagerFactory;

/**
* Operation handler to get the history of the installation manager changes, either artifacts or configuration metadata as
* channel changes.
*/
public class InstMgrCertificateRemoveHandler extends InstMgrOperationStepHandler {
public static final String OPERATION_NAME = "certificate-remove";

protected static final AttributeDefinition KEY_ID = SimpleAttributeDefinitionBuilder.create(CERT_KEY_ID, ModelType.STRING)
.setStorageRuntime()
.setRequired(true)
.build();

public static final OperationDefinition DEFINITION = new SimpleOperationDefinitionBuilder(OPERATION_NAME, InstMgrResolver.RESOLVER)
.withFlags(OperationEntry.Flag.HOST_CONTROLLER_ONLY)
.setReplyType(ModelType.OBJECT)
.setRuntimeOnly()
.setReplyValueType(ModelType.OBJECT)
.addParameter(KEY_ID)
.build();

InstMgrCertificateRemoveHandler(InstMgrService imService, InstallationManagerFactory imf) {
super(imService, imf);
}

@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
final String keyId = KEY_ID.resolveModelAttribute(context, operation).asString();
context.addStep(new OperationStepHandler() {
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
try {
Path serverHome = imService.getHomeDir();
MavenOptions mavenOptions = new MavenOptions(null, false);
InstallationManager installationManager = imf.create(serverHome, mavenOptions);

installationManager.revokeTrustedCertificate(keyId);
} catch (OperationFailedException | RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, OperationContext.Stage.RUNTIME);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ public interface InstMgrConstants {
Path PREPARED_SERVER_SUBPATH = Paths.get("installation-manager")
.resolve("prepared-server");

String CERT_DESCRIPTION = "description";
String CERT_FINGERPRINT = "fingerprint";
String CERT_KEY_ID = "key-id";
String CERT_STATUS = "status";
String CERT_FILE = "cert-file";
String CERTIFICATES = "certificates";
String CHANNEL = "channel";
String CHANNELS = "channels";
String CHANNEL_NAME = "name";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.wildfly.installationmanager.Channel;
import org.wildfly.installationmanager.MavenOptions;
import org.wildfly.installationmanager.Repository;
import org.wildfly.installationmanager.TrustCertificate;
import org.wildfly.installationmanager.spi.InstallationManager;
import org.wildfly.installationmanager.spi.InstallationManagerFactory;

Expand Down Expand Up @@ -86,6 +87,12 @@ class InstMgrResourceDefinition extends SimpleResourceDefinition {
.setRequired(true)
.build();

private static final AttributeDefinition KEY_ID = new SimpleAttributeDefinitionBuilder(InstMgrConstants.CERT_KEY_ID, ModelType.STRING)
.setStorageRuntime()
.setRuntimeServiceNotRequired()
.setRequired(true)
.build();

private static final AttributeDefinition MANIFEST_GAV = new SimpleAttributeDefinitionBuilder(InstMgrConstants.MANIFEST_GAV, ModelType.STRING)
.setAlternatives(InstMgrConstants.MANIFEST_URL)
.setStorageRuntime()
Expand Down Expand Up @@ -115,11 +122,23 @@ class InstMgrResourceDefinition extends SimpleResourceDefinition {
.setSuffix("channel")
.build();

private static final ObjectTypeAttributeDefinition CERTIFICATE = ObjectTypeAttributeDefinition.create("certificate", KEY_ID)
// .setValidator(new ChannelValidator())
.setStorageRuntime()
.setRuntimeServiceNotRequired()
.setRequired(true)
.setSuffix("certificate")
.build();

private static final AttributeDefinition CHANNELS = ObjectListAttributeDefinition.Builder.of(InstMgrConstants.CHANNELS, CHANNEL)
.setStorageRuntime()
.setRuntimeServiceNotRequired()
.build();

private static final AttributeDefinition CERTIFICATES = ObjectListAttributeDefinition.Builder.of("certificates", CERTIFICATE)
.setStorageRuntime()
.setRuntimeServiceNotRequired()
.build();
public static PathElement getPath(String name) {
return PathElement.pathElement(CORE_SERVICE, name);
}
Expand Down Expand Up @@ -167,11 +186,21 @@ public void registerOperations(ManagementResourceRegistration resourceRegistrati

InstMgrCustomPatchRemoveHandler customPatchRemoveHandler = new InstMgrCustomPatchRemoveHandler(imService, imf);
resourceRegistration.registerOperationHandler(customPatchRemoveHandler.DEFINITION, customPatchRemoveHandler);

InstMgrCertificateParseHandler certificateParseHandler = new InstMgrCertificateParseHandler(imService, imf);
resourceRegistration.registerOperationHandler(InstMgrCertificateParseHandler.DEFINITION, certificateParseHandler);

InstMgrCertificateImportHandler certificateImportHandler = new InstMgrCertificateImportHandler(imService, imf);
resourceRegistration.registerOperationHandler(InstMgrCertificateImportHandler.DEFINITION, certificateImportHandler);

InstMgrCertificateRemoveHandler certificateRemoveHandler = new InstMgrCertificateRemoveHandler(imService, imf);
resourceRegistration.registerOperationHandler(InstMgrCertificateRemoveHandler.DEFINITION, certificateRemoveHandler);
}

@Override
public void registerAttributes(ManagementResourceRegistration resourceRegistration) {
resourceRegistration.registerReadWriteAttribute(CHANNELS, new ReadHandler(), new WriteHandler());
resourceRegistration.registerReadOnlyAttribute(CERTIFICATES, new CertReadHandler());
}

private class WriteHandler implements OperationStepHandler {
Expand Down Expand Up @@ -364,4 +393,38 @@ public void validateParameter(String parameterName, ModelNode value) throws Oper
}
}
}

private class CertReadHandler implements OperationStepHandler {
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
context.addStep(new OperationStepHandler() {
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
try {
final ModelNode result = context.getResult();
Path serverHome = imService.getHomeDir();

MavenOptions mavenOptions = new MavenOptions(null, false);
InstallationManager installationManager = imf.create(serverHome, mavenOptions);

ModelNode mCertificates = new ModelNode().addEmptyList();
Collection<TrustCertificate> trustedCertificates = installationManager.listCA();
for (TrustCertificate tc : trustedCertificates) {
ModelNode entry = new ModelNode();
entry.get(InstMgrConstants.CERT_KEY_ID).set(tc.getKeyID());
entry.get(InstMgrConstants.CERT_FINGERPRINT).set(tc.getFingerprint());
entry.get(InstMgrConstants.CERT_DESCRIPTION).set(tc.getDescription());
entry.get(InstMgrConstants.CERT_STATUS).set(tc.getStatus());
mCertificates.add(entry);
}
result.set(mCertificates);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}, OperationContext.Stage.RUNTIME);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ public abstract class AbstractInstMgrCommand implements Command<CLICommandInvoca
* @throws CommandException If the operation was not success or an error occurred.
*/
protected ModelNode executeOp(CommandContext ctx, String host) throws CommandException {
return executeOp(buildOperation(), ctx, host);
}

protected ModelNode executeOp(Operation request, CommandContext ctx, String host) throws CommandException {
if (host != null && !ctx.isDomainMode()) {
throw new CommandException("The --host option is not available in the current context. "
+ "Connection to the controller might be unavailable or not running in domain mode.");
Expand All @@ -75,7 +79,6 @@ protected ModelNode executeOp(CommandContext ctx, String host) throws CommandExc
address = createStandalone();
}

final Operation request = buildOperation();
request.getOperation().get(ADDRESS).set(address.toModelNode());

ModelNode response;
Expand Down
Loading

0 comments on commit 0154a29

Please sign in to comment.