/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.security;
import javax.security.auth.login.Configuration;
import javax.transaction.TransactionManager;
import org.jboss.as.controller.AbstractBoottimeAddStepHandler;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.ProcessType;
import org.jboss.as.controller.ReloadRequiredRemoveStepHandler;
import org.jboss.as.controller.ReloadRequiredWriteAttributeHandler;
import org.jboss.as.controller.SimpleAttributeDefinition;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleResourceDefinition;
import org.jboss.as.controller.access.constraint.SensitivityClassification;
import org.jboss.as.controller.access.management.SensitiveTargetAccessConstraintDefinition;
import org.jboss.as.controller.capability.RuntimeCapability;
import org.jboss.as.controller.registry.ManagementResourceRegistration;
import org.jboss.as.core.security.ServerSecurityManager;
import org.jboss.as.naming.ServiceBasedNamingStore;
import org.jboss.as.naming.deployment.ContextNames;
import org.jboss.as.naming.service.BinderService;
import org.jboss.as.security.context.SecurityDomainJndiInjectable;
import org.jboss.as.security.deployment.JaccEarDeploymentProcessor;
import org.jboss.as.security.deployment.SecurityDependencyProcessor;
import org.jboss.as.security.deployment.SecurityEnablementProcessor;
import org.jboss.as.security.logging.SecurityLogger;
import org.jboss.as.security.service.JaasConfigurationService;
import org.jboss.as.security.service.SecurityBootstrapService;
import org.jboss.as.security.service.SecurityManagementService;
import org.jboss.as.security.service.SimpleSecurityManagerService;
import org.jboss.as.security.service.SubjectFactoryService;
import org.jboss.as.server.AbstractDeploymentChainStep;
import org.jboss.as.server.DeploymentProcessorTarget;
import org.jboss.as.server.Services;
import org.jboss.as.server.deployment.Phase;
import org.jboss.as.server.moduleservice.ServiceModuleLoader;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.jboss.msc.service.Service;
import org.jboss.msc.service.ServiceController;
import org.jboss.msc.service.ServiceName;
import org.jboss.msc.service.ServiceTarget;
import org.jboss.security.ISecurityManagement;
import org.jboss.security.SecurityContextAssociation;
import org.jboss.security.SubjectFactory;
import org.jboss.security.auth.callback.JBossCallbackHandler;
import org.jboss.security.auth.login.XMLLoginConfigImpl;
import org.jboss.security.authentication.JBossCachedAuthenticationManager;
import org.jboss.security.plugins.JBossAuthorizationManager;
import org.jboss.security.plugins.JBossSecuritySubjectFactory;
import org.jboss.security.plugins.audit.JBossAuditManager;
import org.jboss.security.plugins.identitytrust.JBossIdentityTrustManager;
import org.jboss.security.plugins.mapping.JBossMappingManager;
import org.wildfly.security.manager.WildFlySecurityManager;
/**
* @author Jason T. Greene
*/
public class SecuritySubsystemRootResourceDefinition extends SimpleResourceDefinition {
private static final RuntimeCapability<Void> SECURITY_SUBSYSTEM = RuntimeCapability.Builder.of("org.wildfly.legacy-security").build();
private static final RuntimeCapability<Void> SERVER_SECURITY_MANAGER = RuntimeCapability.Builder.of("org.wildfly.legacy-security.server-security-manager")
.setServiceType(ServerSecurityManager.class)
.build();
private static final RuntimeCapability<Void> SUBJECT_FACTORY_CAP = RuntimeCapability.Builder.of("org.wildfly.legacy-security.subject-factory")
.setServiceType(SubjectFactory.class)
.build();
private static final SensitiveTargetAccessConstraintDefinition MISC_SECURITY_SENSITIVITY = new SensitiveTargetAccessConstraintDefinition(
new SensitivityClassification(SecurityExtension.SUBSYSTEM_NAME, "misc-security", false, true, true));
static final SecuritySubsystemRootResourceDefinition INSTANCE = new SecuritySubsystemRootResourceDefinition();
static final SimpleAttributeDefinition DEEP_COPY_SUBJECT_MODE = new SimpleAttributeDefinitionBuilder(Constants.DEEP_COPY_SUBJECT_MODE, ModelType.BOOLEAN, true)
.setAccessConstraints(MISC_SECURITY_SENSITIVITY)
.setDefaultValue(new ModelNode(false))
.setAllowExpression(true)
.build();
static final SimpleAttributeDefinition INITIALIZE_JACC = new SimpleAttributeDefinitionBuilder(Constants.INITIALIZE_JACC, ModelType.BOOLEAN, true)
.setDefaultValue(new ModelNode(true))
.setAllowExpression(true)
.build();
private SecuritySubsystemRootResourceDefinition() {
super(new Parameters(SecurityExtension.PATH_SUBSYSTEM,
SecurityExtension.getResourceDescriptionResolver(SecurityExtension.SUBSYSTEM_NAME))
.setAddHandler(SecuritySubsystemAdd.INSTANCE)
.setRemoveHandler(ReloadRequiredRemoveStepHandler.INSTANCE)
.setCapabilities(SECURITY_SUBSYSTEM, SERVER_SECURITY_MANAGER, SUBJECT_FACTORY_CAP));
setDeprecated(SecurityExtension.DEPRECATED_SINCE);
}
@Override
public void registerAttributes(final ManagementResourceRegistration resourceRegistration) {
resourceRegistration.registerReadWriteAttribute(DEEP_COPY_SUBJECT_MODE, null, new ReloadRequiredWriteAttributeHandler(DEEP_COPY_SUBJECT_MODE));
resourceRegistration.registerReadWriteAttribute(INITIALIZE_JACC, null, new ReloadRequiredWriteAttributeHandler(INITIALIZE_JACC));
}
@Override
public void registerCapabilities(ManagementResourceRegistration resourceRegistration) {
resourceRegistration.registerCapability(SECURITY_SUBSYSTEM);
}
private static class SecuritySubsystemAdd extends AbstractBoottimeAddStepHandler {
private static final String AUTHENTICATION_MANAGER = ModuleName.PICKETBOX.getName() + ":" + ModuleName.PICKETBOX.getSlot()
+ ":" + JBossCachedAuthenticationManager.class.getName();
private static final String CALLBACK_HANDLER = ModuleName.PICKETBOX.getName() + ":" + ModuleName.PICKETBOX.getSlot() + ":"
+ JBossCallbackHandler.class.getName();
private static final String AUTHORIZATION_MANAGER = ModuleName.PICKETBOX.getName() + ":" + ModuleName.PICKETBOX.getSlot()
+ ":" + JBossAuthorizationManager.class.getName();
private static final String AUDIT_MANAGER = ModuleName.PICKETBOX.getName() + ":" + ModuleName.PICKETBOX.getSlot() + ":"
+ JBossAuditManager.class.getName();
private static final String IDENTITY_TRUST_MANAGER = ModuleName.PICKETBOX.getName() + ":" + ModuleName.PICKETBOX.getSlot()
+ ":" + JBossIdentityTrustManager.class.getName();
private static final String MAPPING_MANAGER = ModuleName.PICKETBOX.getName() + ":" + ModuleName.PICKETBOX.getSlot() + ":"
+ JBossMappingManager.class.getName();
private static final String SUBJECT_FACTORY = ModuleName.PICKETBOX.getName() + ":" + ModuleName.PICKETBOX.getSlot() + ":"
+ JBossSecuritySubjectFactory.class.getName();
public static final OperationStepHandler INSTANCE = new SecuritySubsystemAdd();
@Override
protected void populateModel(ModelNode operation, ModelNode model) throws OperationFailedException {
DEEP_COPY_SUBJECT_MODE.validateAndSet(operation, model);
INITIALIZE_JACC.validateAndSet(operation, model);
}
@Override
protected void performBoottime(OperationContext context, ModelNode operation, ModelNode model) throws OperationFailedException {
SecurityLogger.ROOT_LOGGER.activatingSecuritySubsystem();
if(context.getProcessType() != ProcessType.APPLICATION_CLIENT) {
//remove once AS7-4687 is resolved
WildFlySecurityManager.setPropertyPrivileged(SecurityContextAssociation.SECURITYCONTEXT_THREADLOCAL, "true");
}
final ServiceTarget target = context.getServiceTarget();
ModelNode initializeJaccNode = SecuritySubsystemRootResourceDefinition.INITIALIZE_JACC.resolveModelAttribute(context,model);
final SecurityBootstrapService bootstrapService = new SecurityBootstrapService(initializeJaccNode.asBoolean());
target.addService(SecurityBootstrapService.SERVICE_NAME, bootstrapService)
.addDependency(Services.JBOSS_SERVICE_MODULE_LOADER, ServiceModuleLoader.class, bootstrapService.getServiceModuleLoaderInjectedValue())
.setInitialMode(ServiceController.Mode.ACTIVE).install();
// add service to bind SecurityDomainJndiInjectable to JNDI
final SecurityDomainJndiInjectable securityDomainJndiInjectable = new SecurityDomainJndiInjectable();
final BinderService binderService = new BinderService("jaas");
target.addService(ContextNames.JBOSS_CONTEXT_SERVICE_NAME.append("jaas"), binderService)
.addInjection(binderService.getManagedObjectInjector(), securityDomainJndiInjectable)
.addDependency(ContextNames.JBOSS_CONTEXT_SERVICE_NAME, ServiceBasedNamingStore.class, binderService.getNamingStoreInjector())
.addDependency(SecurityManagementService.SERVICE_NAME, ISecurityManagement.class, securityDomainJndiInjectable.getSecurityManagementInjector())
.setInitialMode(ServiceController.Mode.ACTIVE).install();
// add security management service
ModelNode modelNode = SecuritySubsystemRootResourceDefinition.DEEP_COPY_SUBJECT_MODE.resolveModelAttribute(context,model);
final SecurityManagementService securityManagementService = new SecurityManagementService(
AUTHENTICATION_MANAGER, modelNode.isDefined() && modelNode.asBoolean(), CALLBACK_HANDLER,
AUTHORIZATION_MANAGER, AUDIT_MANAGER, IDENTITY_TRUST_MANAGER, MAPPING_MANAGER);
target.addService(SecurityManagementService.SERVICE_NAME, securityManagementService)
.addDependency(Services.JBOSS_SERVICE_MODULE_LOADER, ServiceModuleLoader.class, securityManagementService.getServiceModuleLoaderInjectedValue())
.addDependency(JaasConfigurationService.SERVICE_NAME) // We need to ensure the global JAAS Configuration has been set.
.setInitialMode(ServiceController.Mode.ACTIVE).install();
// add subject factory service
final SubjectFactoryService subjectFactoryService = new SubjectFactoryService(SUBJECT_FACTORY);
target.addService(SUBJECT_FACTORY_CAP.getCapabilityServiceName(), subjectFactoryService)
.addAliases(SubjectFactoryService.SERVICE_NAME)
.addDependency(SecurityManagementService.SERVICE_NAME, ISecurityManagement.class,
subjectFactoryService.getSecurityManagementInjector())
.setInitialMode(ServiceController.Mode.ACTIVE).install();
// add jaas configuration service
Configuration loginConfig = XMLLoginConfigImpl.getInstance();
final JaasConfigurationService jaasConfigurationService = new JaasConfigurationService(loginConfig);
target.addService(JaasConfigurationService.SERVICE_NAME, jaasConfigurationService)
.setInitialMode(ServiceController.Mode.ACTIVE).install();
//setup the transaction manager locator
if(context.hasOptionalCapability("org.wildfly.transactions", SECURITY_SUBSYSTEM.getName(), null)) {
TransactionManagerLocatorService service = new TransactionManagerLocatorService();
target.addService(TransactionManagerLocatorService.SERVICE_NAME, service)
.addDependency( ServiceName.JBOSS.append("txn", "TransactionManager"), TransactionManager.class, service.getTransactionManagerInjectedValue())
.install();
} else {
target.addService(TransactionManagerLocatorService.SERVICE_NAME, Service.NULL).install();
}
//add Simple Security Manager Service
final SimpleSecurityManagerService simpleSecurityManagerService = new SimpleSecurityManagerService();
target.addService(SERVER_SECURITY_MANAGER.getCapabilityServiceName(), simpleSecurityManagerService)
.addAliases(SimpleSecurityManagerService.SERVICE_NAME)
.addDependency(SecurityManagementService.SERVICE_NAME)
.install();
context.addStep(new AbstractDeploymentChainStep() {
@Override
protected void execute(DeploymentProcessorTarget processorTarget) {
processorTarget.addDeploymentProcessor(SecurityExtension.SUBSYSTEM_NAME, Phase.INSTALL, Phase.INSTALL_JACC_POLICY,
new JaccEarDeploymentProcessor());
processorTarget.addDeploymentProcessor(SecurityExtension.SUBSYSTEM_NAME, Phase.DEPENDENCIES, Phase.DEPENDENCIES_SECURITY,
new SecurityDependencyProcessor());
processorTarget.addDeploymentProcessor(SecurityExtension.SUBSYSTEM_NAME, Phase.PARSE, 0x0080,
new SecurityEnablementProcessor());
}
}, OperationContext.Stage.RUNTIME);
}
}
}