| | |
| | | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.std.server.ExternalSASLMechanismHandlerCfg; |
| | | import org.opends.server.api.CertificateMapper; |
| | | import org.opends.server.api.ClientConnection; |
| | | import org.opends.server.api.ConfigurableComponent; |
| | | import org.opends.server.api.ConnectionSecurityProvider; |
| | | import org.opends.server.api.SASLMechanismHandler; |
| | | import org.opends.server.config.ConfigAttribute; |
| | | import org.opends.server.config.ConfigEntry; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.config.DNConfigAttribute; |
| | | import org.opends.server.config.MultiChoiceConfigAttribute; |
| | | import org.opends.server.config.StringConfigAttribute; |
| | | import org.opends.server.core.BindOperation; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.protocols.asn1.ASN1OctetString; |
| | |
| | | * other places to find and evaluate this external authentication information. |
| | | */ |
| | | public class ExternalSASLMechanismHandler |
| | | extends SASLMechanismHandler |
| | | implements ConfigurableComponent |
| | | extends SASLMechanismHandler<ExternalSASLMechanismHandlerCfg> |
| | | implements ConfigurationChangeListener< |
| | | ExternalSASLMechanismHandlerCfg> |
| | | { |
| | | |
| | | |
| | | |
| | | /** |
| | | * The set of value strings that may be used for the peer certificate |
| | | * validation policy. |
| | | */ |
| | | private static final HashSet<String> validationValueStrings; |
| | | |
| | | static |
| | | { |
| | | validationValueStrings = new HashSet<String>(3); |
| | | validationValueStrings.add(CertificateValidationPolicy.ALWAYS.toString()); |
| | | validationValueStrings.add(CertificateValidationPolicy.NEVER.toString()); |
| | | validationValueStrings.add( |
| | | CertificateValidationPolicy.IFPRESENT.toString()); |
| | | } |
| | | |
| | | |
| | | |
| | | // The attribute type that should hold the certificates to use for the |
| | | // validation. |
| | | private AttributeType certificateAttributeType; |
| | |
| | | // client with a certificate in the user's entry. |
| | | private CertificateValidationPolicy validationPolicy; |
| | | |
| | | // The DN of the configuration entry for the associated certificate mapper. |
| | | private DN certificateMapperDN; |
| | | |
| | | // The DN of the configuration entry for this SASL mechanism handler. |
| | | private DN configEntryDN; |
| | | |
| | | // The current configuration for this SASL mechanism handler. |
| | | private ExternalSASLMechanismHandlerCfg currentConfig; |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | public ExternalSASLMechanismHandler() |
| | | { |
| | | super(); |
| | | |
| | | } |
| | | |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | | public void initializeSASLMechanismHandler(ConfigEntry configEntry) |
| | | public void initializeSASLMechanismHandler( |
| | | ExternalSASLMechanismHandlerCfg configuration) |
| | | throws ConfigException, InitializationException |
| | | { |
| | | this.configEntryDN = configEntry.getDN(); |
| | | configuration.addExternalChangeListener(this); |
| | | |
| | | currentConfig = configuration; |
| | | configEntryDN = configuration.dn(); |
| | | |
| | | |
| | | // See if we should attempt to validate client certificates against those in |
| | | // the corresponding user's entry. |
| | | validationPolicy = CertificateValidationPolicy.NEVER; |
| | | int msgID = MSGID_SASLEXTERNAL_DESCRIPTION_VALIDATION_POLICY; |
| | | MultiChoiceConfigAttribute validateStub = |
| | | new MultiChoiceConfigAttribute(ATTR_CLIENT_CERT_VALIDATION_POLICY, |
| | | getMessage(msgID), false, false, false, |
| | | validationValueStrings); |
| | | try |
| | | switch (configuration.getCertificateValidationPolicy()) |
| | | { |
| | | MultiChoiceConfigAttribute validateAttr = |
| | | (MultiChoiceConfigAttribute) |
| | | configEntry.getConfigAttribute(validateStub); |
| | | if (validateAttr != null) |
| | | { |
| | | validationPolicy = CertificateValidationPolicy.policyForName( |
| | | validateAttr.activeValue()); |
| | | if (validationPolicy == null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_INVALID_VALIDATION_VALUE; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | validateAttr.activeValue()); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_VALIDATION_POLICY; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | case NEVER: |
| | | validationPolicy = CertificateValidationPolicy.NEVER; |
| | | break; |
| | | case IFPRESENT: |
| | | validationPolicy = CertificateValidationPolicy.IFPRESENT; |
| | | break; |
| | | case ALWAYS: |
| | | validationPolicy = CertificateValidationPolicy.ALWAYS; |
| | | break; |
| | | } |
| | | |
| | | |
| | | // Get the attribute type to use for validating the certificates. If none |
| | | // is provided, then default to the userCertificate type. |
| | | String attrTypeName = DEFAULT_VALIDATION_CERT_ATTRIBUTE; |
| | | msgID = MSGID_SASLEXTERNAL_DESCRIPTION_CERTIFICATE_ATTRIBUTE; |
| | | StringConfigAttribute certAttributeStub = |
| | | new StringConfigAttribute(ATTR_VALIDATION_CERT_ATTRIBUTE, |
| | | getMessage(msgID), false, false, false); |
| | | try |
| | | String attrTypeName = configuration.getCertificateAttribute(); |
| | | if (attrTypeName == null) |
| | | { |
| | | StringConfigAttribute certAttributeAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(certAttributeStub); |
| | | if (certAttributeAttr != null) |
| | | { |
| | | attrTypeName = toLowerCase(certAttributeAttr.activeValue()); |
| | | } |
| | | attrTypeName = DEFAULT_VALIDATION_CERT_ATTRIBUTE; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_CERT_ATTR; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | throw new InitializationException(msgID, message, e); |
| | | } |
| | | |
| | | certificateAttributeType = DirectoryServer.getAttributeType(attrTypeName); |
| | | certificateAttributeType = |
| | | DirectoryServer.getAttributeType(toLowerCase(attrTypeName), false); |
| | | if (certificateAttributeType == null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_UNKNOWN_CERT_ATTR; |
| | | int msgID = MSGID_SASLEXTERNAL_UNKNOWN_CERT_ATTR; |
| | | String message = getMessage(msgID, String.valueOf(attrTypeName), |
| | | String.valueOf(configEntryDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | |
| | | |
| | | // Get the DN of the certificate mapper to use with this handler. |
| | | msgID = MSGID_SASLEXTERNAL_DESCRIPTION_CERT_MAPPER_DN; |
| | | DNConfigAttribute certMapperStub = |
| | | new DNConfigAttribute(ATTR_CERTMAPPER_DN, getMessage(msgID), true, |
| | | false, false); |
| | | try |
| | | // Make sure that the configured certificate mapper is valid. |
| | | CertificateMapper certificateMapper = |
| | | DirectoryServer.getCertificateMapper( |
| | | configuration.getCertificateMapperDN()); |
| | | if (certificateMapper == null) |
| | | { |
| | | DNConfigAttribute certMapperAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(certMapperStub); |
| | | if (certMapperAttr == null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_NO_CERTIFICATE_MAPPER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | else |
| | | { |
| | | certificateMapperDN = certMapperAttr.activeValue(); |
| | | CertificateMapper mapper = |
| | | DirectoryServer.getCertificateMapper(certificateMapperDN); |
| | | if (mapper == null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_INVALID_CERTIFICATE_MAPPER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(certificateMapperDN)); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | } |
| | | } |
| | | catch (ConfigException ce) |
| | | { |
| | | throw ce; |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_CERT_MAPPER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | int msgID = MSGID_SASLEXTERNAL_INVALID_CERTIFICATE_MAPPER_DN; |
| | | String message = |
| | | getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(configuration.getCertificateMapperDN())); |
| | | throw new ConfigException(msgID, message); |
| | | } |
| | | |
| | | |
| | | DirectoryServer.registerSASLMechanismHandler(SASL_MECHANISM_EXTERNAL, this); |
| | | DirectoryServer.registerConfigurableComponent(this); |
| | | } |
| | | |
| | | |
| | |
| | | @Override() |
| | | public void finalizeSASLMechanismHandler() |
| | | { |
| | | DirectoryServer.deregisterConfigurableComponent(this); |
| | | currentConfig.removeExternalChangeListener(this); |
| | | DirectoryServer.deregisterSASLMechanismHandler(SASL_MECHANISM_EXTERNAL); |
| | | } |
| | | |
| | |
| | | @Override() |
| | | public void processSASLBind(BindOperation bindOperation) |
| | | { |
| | | ExternalSASLMechanismHandlerCfg config = currentConfig; |
| | | AttributeType certificateAttributeType = this.certificateAttributeType; |
| | | CertificateValidationPolicy validationPolicy = this.validationPolicy; |
| | | |
| | | |
| | | // Get the client connection used for the bind request, and get the |
| | | // security manager for that connection. If either are null, then fail. |
| | | ClientConnection clientConnection = bindOperation.getClientConnection(); |
| | |
| | | |
| | | |
| | | // Get the certificate mapper to use to map the certificate to a user entry. |
| | | DN certificateMapperDN = config.getCertificateMapperDN(); |
| | | CertificateMapper certificateMapper = |
| | | DirectoryServer.getCertificateMapper(certificateMapperDN); |
| | | if (certificateMapper == null) |
| | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the DN of the configuration entry with which this component is |
| | | * associated. |
| | | * |
| | | * @return The DN of the configuration entry with which this component is |
| | | * associated. |
| | | */ |
| | | public DN getConfigurableComponentEntryDN() |
| | | { |
| | | return configEntryDN; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | /** |
| | | * Retrieves the set of configuration attributes that are associated with this |
| | | * configurable component. |
| | | * |
| | | * @return The set of configuration attributes that are associated with this |
| | | * configurable component. |
| | | */ |
| | | public List<ConfigAttribute> getConfigurationAttributes() |
| | | { |
| | | LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>(); |
| | | |
| | | int msgID = MSGID_SASLEXTERNAL_DESCRIPTION_VALIDATION_POLICY; |
| | | attrList.add(new MultiChoiceConfigAttribute( |
| | | ATTR_CLIENT_CERT_VALIDATION_POLICY, getMessage(msgID), |
| | | false, false, false, validationValueStrings, |
| | | validationPolicy.toString())); |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_DESCRIPTION_CERTIFICATE_ATTRIBUTE; |
| | | String certTypeStr = certificateAttributeType.getNameOrOID(); |
| | | attrList.add(new StringConfigAttribute(ATTR_VALIDATION_CERT_ATTRIBUTE, |
| | | getMessage(msgID), false, false, |
| | | false, certTypeStr)); |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_DESCRIPTION_CERT_MAPPER_DN; |
| | | attrList.add(new DNConfigAttribute(ATTR_CERTMAPPER_DN, getMessage(msgID), |
| | | true, false, false, |
| | | certificateMapperDN)); |
| | | |
| | | return attrList; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Indicates whether the provided configuration entry has an acceptable |
| | | * configuration for this component. If it does not, then detailed |
| | | * information about the problem(s) should be added to the provided list. |
| | | * |
| | | * @param configEntry The configuration entry for which to make the |
| | | * determination. |
| | | * @param unacceptableReasons A list that can be used to hold messages about |
| | | * why the provided entry does not have an |
| | | * acceptable configuration. |
| | | * |
| | | * @return <CODE>true</CODE> if the provided entry has an acceptable |
| | | * configuration for this component, or <CODE>false</CODE> if not. |
| | | */ |
| | | public boolean hasAcceptableConfiguration(ConfigEntry configEntry, |
| | | List<String> unacceptableReasons) |
| | | { |
| | | // Look at the validation policy configuration. |
| | | int msgID = MSGID_SASLEXTERNAL_DESCRIPTION_VALIDATION_POLICY; |
| | | MultiChoiceConfigAttribute validateStub = |
| | | new MultiChoiceConfigAttribute(ATTR_CLIENT_CERT_VALIDATION_POLICY, |
| | | getMessage(msgID), false, false, false, |
| | | validationValueStrings); |
| | | try |
| | | { |
| | | MultiChoiceConfigAttribute validateAttr = |
| | | (MultiChoiceConfigAttribute) |
| | | configEntry.getConfigAttribute(validateStub); |
| | | if (validateAttr != null) |
| | | { |
| | | if (CertificateValidationPolicy.policyForName( |
| | | validateAttr.activeValue())== null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_INVALID_VALIDATION_VALUE; |
| | | unacceptableReasons.add(getMessage(msgID, |
| | | String.valueOf(configEntryDN), |
| | | validateAttr.activeValue())); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_VALIDATION_POLICY; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // Look at the certificate attribute type configuration. |
| | | String attrTypeName = DEFAULT_VALIDATION_CERT_ATTRIBUTE; |
| | | msgID = MSGID_SASLEXTERNAL_DESCRIPTION_CERTIFICATE_ATTRIBUTE; |
| | | StringConfigAttribute certAttributeStub = |
| | | new StringConfigAttribute(ATTR_VALIDATION_CERT_ATTRIBUTE, |
| | | getMessage(msgID), false, false, false); |
| | | try |
| | | { |
| | | StringConfigAttribute certAttributeAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(certAttributeStub); |
| | | if (certAttributeAttr != null) |
| | | { |
| | | attrTypeName = toLowerCase(certAttributeAttr.activeValue()); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_CERT_ATTR; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | return false; |
| | | } |
| | | |
| | | if (DirectoryServer.getAttributeType(attrTypeName) == null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_UNKNOWN_CERT_ATTR; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(attrTypeName), |
| | | String.valueOf(configEntryDN))); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // Look at the certificate mapper DN. |
| | | msgID = MSGID_SASLEXTERNAL_DESCRIPTION_CERT_MAPPER_DN; |
| | | DNConfigAttribute certMapperStub = |
| | | new DNConfigAttribute(ATTR_CERTMAPPER_DN, getMessage(msgID), true, |
| | | false, false); |
| | | try |
| | | { |
| | | DNConfigAttribute certMapperAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(certMapperStub); |
| | | if (certMapperAttr == null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_NO_CERTIFICATE_MAPPER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN)); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | else |
| | | { |
| | | DN certMapperDN = certMapperAttr.activeValue(); |
| | | CertificateMapper mapper = |
| | | DirectoryServer.getCertificateMapper(certMapperDN); |
| | | if (mapper == null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_INVALID_CERTIFICATE_MAPPER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(certMapperDN)); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_CERT_MAPPER_DN; |
| | | String message = getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e)); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | |
| | | |
| | | // If we've gotten to this point, then everything must be OK. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Makes a best-effort attempt to apply the configuration contained in the |
| | | * provided entry. Information about the result of this processing should be |
| | | * added to the provided message list. Information should always be added to |
| | | * this list if a configuration change could not be applied. If detailed |
| | | * results are requested, then information about the changes applied |
| | | * successfully (and optionally about parameters that were not changed) should |
| | | * also be included. |
| | | * |
| | | * @param configEntry The entry containing the new configuration to |
| | | * apply for this component. |
| | | * @param detailedResults Indicates whether detailed information about the |
| | | * processing should be added to the list. |
| | | * |
| | | * @return Information about the result of the configuration update. |
| | | */ |
| | | public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry, |
| | | boolean detailedResults) |
| | | { |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<String> messages = new ArrayList<String>(); |
| | | |
| | | |
| | | // Look at the validation policy configuration. |
| | | CertificateValidationPolicy newValidationPolicy = |
| | | CertificateValidationPolicy.NEVER; |
| | | int msgID = MSGID_SASLEXTERNAL_DESCRIPTION_VALIDATION_POLICY; |
| | | MultiChoiceConfigAttribute validateStub = |
| | | new MultiChoiceConfigAttribute(ATTR_CLIENT_CERT_VALIDATION_POLICY, |
| | | getMessage(msgID), false, false, false, |
| | | validationValueStrings); |
| | | try |
| | | { |
| | | MultiChoiceConfigAttribute validateAttr = |
| | | (MultiChoiceConfigAttribute) |
| | | configEntry.getConfigAttribute(validateStub); |
| | | if (validateAttr != null) |
| | | { |
| | | newValidationPolicy = CertificateValidationPolicy.policyForName( |
| | | validateAttr.activeValue()); |
| | | if (newValidationPolicy == null) |
| | | { |
| | | resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX; |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_INVALID_VALIDATION_VALUE; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | validateAttr.activeValue())); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX; |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_VALIDATION_POLICY; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | } |
| | | |
| | | |
| | | // Look at the certificate attribute type configuration. |
| | | String attrTypeName = DEFAULT_VALIDATION_CERT_ATTRIBUTE; |
| | | msgID = MSGID_SASLEXTERNAL_DESCRIPTION_CERTIFICATE_ATTRIBUTE; |
| | | StringConfigAttribute certAttributeStub = |
| | | new StringConfigAttribute(ATTR_VALIDATION_CERT_ATTRIBUTE, |
| | | getMessage(msgID), false, false, false); |
| | | try |
| | | { |
| | | StringConfigAttribute certAttributeAttr = |
| | | (StringConfigAttribute) |
| | | configEntry.getConfigAttribute(certAttributeStub); |
| | | if (certAttributeAttr != null) |
| | | { |
| | | attrTypeName = toLowerCase(certAttributeAttr.activeValue()); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_CERT_ATTR; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | resultCode = DirectoryServer.getServerErrorResultCode(); |
| | | } |
| | | |
| | | AttributeType newCertType = DirectoryServer.getAttributeType(attrTypeName); |
| | | if (newCertType == null) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_UNKNOWN_CERT_ATTR; |
| | | messages.add(getMessage(msgID, String.valueOf(attrTypeName), |
| | | String.valueOf(configEntryDN))); |
| | | |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX; |
| | | } |
| | | } |
| | | |
| | | |
| | | // Look at the certificate mapper DN. |
| | | DN newCertificateMapperDN = null; |
| | | msgID = MSGID_SASLEXTERNAL_DESCRIPTION_CERT_MAPPER_DN; |
| | | DNConfigAttribute certMapperStub = |
| | | new DNConfigAttribute(ATTR_CERTMAPPER_DN, getMessage(msgID), true, |
| | | false, false); |
| | | try |
| | | { |
| | | DNConfigAttribute certMapperAttr = |
| | | (DNConfigAttribute) configEntry.getConfigAttribute(certMapperStub); |
| | | if (certMapperAttr == null) |
| | | { |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.OBJECTCLASS_VIOLATION; |
| | | } |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_NO_CERTIFICATE_MAPPER_DN; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN))); |
| | | } |
| | | else |
| | | { |
| | | newCertificateMapperDN = certMapperAttr.activeValue(); |
| | | CertificateMapper mapper = |
| | | DirectoryServer.getCertificateMapper(newCertificateMapperDN); |
| | | if (mapper == null) |
| | | { |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.OBJECTCLASS_VIOLATION; |
| | | } |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_INVALID_CERTIFICATE_MAPPER_DN; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(newCertificateMapperDN))); |
| | | } |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.OBJECTCLASS_VIOLATION; |
| | | } |
| | | |
| | | msgID = MSGID_SASLEXTERNAL_CANNOT_GET_CERT_MAPPER_DN; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | stackTraceToSingleLineString(e))); |
| | | } |
| | | |
| | | |
| | | // If everything has been successful, then apply any changes that were made. |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | if (newValidationPolicy != validationPolicy) |
| | | { |
| | | validationPolicy = newValidationPolicy; |
| | | |
| | | if (detailedResults) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_UPDATED_VALIDATION_POLICY; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(validationPolicy))); |
| | | } |
| | | } |
| | | |
| | | if (! certificateAttributeType.equals(newCertType)) |
| | | { |
| | | certificateAttributeType = newCertType; |
| | | |
| | | if (detailedResults) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_UPDATED_CERT_ATTR; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | certificateAttributeType.getNameOrOID())); |
| | | } |
| | | } |
| | | |
| | | if (! newCertificateMapperDN.equals(certificateMapperDN)) |
| | | { |
| | | certificateMapperDN = newCertificateMapperDN; |
| | | |
| | | if (detailedResults) |
| | | { |
| | | msgID = MSGID_SASLEXTERNAL_UPDATED_CERT_MAPPER_DN; |
| | | messages.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(newCertificateMapperDN))); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // Return the result to the caller. |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override() |
| | |
| | | // This may be considered a secure mechanism. |
| | | return true; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public boolean isConfigurationChangeAcceptable( |
| | | ExternalSASLMechanismHandlerCfg configuration, |
| | | List<String> unacceptableReasons) |
| | | { |
| | | boolean configAcceptable = true; |
| | | |
| | | // Get the attribute type to use for validating the certificates. If none |
| | | // is provided, then default to the userCertificate type. |
| | | String attrTypeName = configuration.getCertificateAttribute(); |
| | | if (attrTypeName != null) |
| | | { |
| | | attrTypeName = DEFAULT_VALIDATION_CERT_ATTRIBUTE; |
| | | } |
| | | AttributeType newCertificateType = |
| | | DirectoryServer.getAttributeType(toLowerCase(attrTypeName), false); |
| | | if (newCertificateType == null) |
| | | { |
| | | int msgID = MSGID_SASLEXTERNAL_UNKNOWN_CERT_ATTR; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(attrTypeName), |
| | | String.valueOf(configEntryDN))); |
| | | configAcceptable = false; |
| | | } |
| | | |
| | | |
| | | // Make sure that the configured certificate mapper is valid. |
| | | CertificateMapper certificateMapper = |
| | | DirectoryServer.getCertificateMapper( |
| | | configuration.getCertificateMapperDN()); |
| | | if (certificateMapper == null) |
| | | { |
| | | int msgID = MSGID_SASLEXTERNAL_INVALID_CERTIFICATE_MAPPER_DN; |
| | | unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN), |
| | | String.valueOf(configuration.getCertificateMapperDN()))); |
| | | configAcceptable = false; |
| | | } |
| | | |
| | | |
| | | return configAcceptable; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public ConfigChangeResult applyConfigurationChange( |
| | | ExternalSASLMechanismHandlerCfg configuration) |
| | | { |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<String> messages = new ArrayList<String>(); |
| | | |
| | | |
| | | // See if we should attempt to validate client certificates against those in |
| | | // the corresponding user's entry. |
| | | CertificateValidationPolicy newValidationPolicy = |
| | | CertificateValidationPolicy.ALWAYS; |
| | | switch (configuration.getCertificateValidationPolicy()) |
| | | { |
| | | case NEVER: |
| | | newValidationPolicy = CertificateValidationPolicy.NEVER; |
| | | break; |
| | | case IFPRESENT: |
| | | newValidationPolicy = CertificateValidationPolicy.IFPRESENT; |
| | | break; |
| | | case ALWAYS: |
| | | newValidationPolicy = CertificateValidationPolicy.ALWAYS; |
| | | break; |
| | | } |
| | | |
| | | |
| | | // Get the attribute type to use for validating the certificates. If none |
| | | // is provided, then default to the userCertificate type. |
| | | String attrTypeName = configuration.getCertificateAttribute(); |
| | | if (attrTypeName == null) |
| | | { |
| | | attrTypeName = DEFAULT_VALIDATION_CERT_ATTRIBUTE; |
| | | } |
| | | AttributeType newCertificateType = |
| | | DirectoryServer.getAttributeType(toLowerCase(attrTypeName), false); |
| | | if (newCertificateType == null) |
| | | { |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | resultCode = ResultCode.NO_SUCH_ATTRIBUTE; |
| | | } |
| | | |
| | | int msgID = MSGID_SASLEXTERNAL_UNKNOWN_CERT_ATTR; |
| | | messages.add(getMessage(msgID, String.valueOf(attrTypeName), |
| | | String.valueOf(configEntryDN))); |
| | | } |
| | | |
| | | |
| | | if (resultCode == ResultCode.SUCCESS) |
| | | { |
| | | validationPolicy = newValidationPolicy; |
| | | certificateAttributeType = newCertificateType; |
| | | currentConfig = configuration; |
| | | } |
| | | |
| | | |
| | | return new ConfigChangeResult(resultCode, adminActionRequired, messages); |
| | | } |
| | | } |
| | | |