mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

neil_a_wilson
29.54.2007 68ceb8ea8c8d2c2745f1c2449635764f4a51a993
opends/src/admin/defn/org/opends/server/admin/std/FileBasedTrustManagerConfiguration.xml
New file
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
 ! CDDL HEADER START
 !
 ! The contents of this file are subject to the terms of the
 ! Common Development and Distribution License, Version 1.0 only
 ! (the "License").  You may not use this file except in compliance
 ! with the License.
 !
 ! You can obtain a copy of the license at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
 ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 ! See the License for the specific language governing permissions
 ! and limitations under the License.
 !
 ! When distributing Covered Code, include this CDDL HEADER in each
 ! file and include the License file at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 ! add the following below this CDDL HEADER, with the fields enclosed
 ! by brackets "[]" replaced with your own identifying information:
 !      Portions Copyright [yyyy] [name of copyright owner]
 !
 ! CDDL HEADER END
 !
 !
 !      Portions Copyright 2007 Sun Microsystems, Inc.
 ! -->
<adm:managed-object name="file-based-trust-manager"
  plural-name="file-based-trust-managers"
  package="org.opends.server.admin.std" extends="trust-manager"
  xmlns:adm="http://www.opends.org/admin"
  xmlns:ldap="http://www.opends.org/admin-ldap">
  <adm:TODO>
    Some trust managers may require access to a PIN.  In such cases, it will
    look in property, then an environment variable, then a file, and finally
    in a configuration attribute. At least one must be present. Can we
    express this ordering and this "at least one" constraint? Perhaps
    support a "one-of" element which can be used to group a set of
    properties.
  </adm:TODO>
  <adm:synopsis>
    The
    <adm:user-friendly-name />
    provider accesses key information in a file on the local filesystem.
    Multiple file formats may be supported, depending on the providers
    supported by the underlying Java runtime.
  </adm:synopsis>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:oid>1.3.6.1.4.1.26027.1.2.52</ldap:oid>
      <ldap:name>ds-cfg-file-based-trust-manager-provider</ldap:name>
      <ldap:superior>ds-cfg-trust-manager-provider</ldap:superior>
    </ldap:object-class>
  </adm:profile>
  <adm:property-override name="java-implementation-class">
    <adm:default-behavior>
      <adm:defined>
        <adm:value>
          org.opends.server.extensions.FileBasedTrustManagerProvider
        </adm:value>
      </adm:defined>
    </adm:default-behavior>
  </adm:property-override>
  <adm:property name="trust-store-file" mandatory="true">
    <adm:TODO>Should use a file-based property definition?</adm:TODO>
    <adm:synopsis>
      Specifies the path to the file containing the trust
      information. It may be an absolute path, or a path that is
      relative to the
      <adm:product-name />
      instance root.
    </adm:synopsis>
    <adm:description>
      Changes to this configuration attribute will take effect the next
      time that the trust manager is accessed.
    </adm:description>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.129</ldap:oid>
        <ldap:name>ds-cfg-trust-store-file</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="trust-store-type">
    <adm:TODO>
      Can we restrict this to an enumeration? How can the client guess
      which values are possible? What is the default value?
    </adm:TODO>
    <adm:synopsis>
      Specifies the format for the data in the trust store file.
    </adm:synopsis>
    <adm:description>
      Valid values should always include 'JKS' and 'PKCS12', but
      different implementations may allow other values as well. If no
      value is provided, then the JVM-default value will be used.
      Changes to this configuration attribute will take effect the next
      time that the trust manager is accessed.
    </adm:description>
    <adm:default-behavior>
      <adm:undefined />
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.134</ldap:oid>
        <ldap:name>ds-cfg-trust-store-type</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property-reference name="trust-store-pin" />
  <adm:property-reference name="trust-store-pin-property" />
  <adm:property-reference name="trust-store-pin-environment-variable" />
  <adm:property-reference name="trust-store-pin-file" />
</adm:managed-object>
opends/src/admin/defn/org/opends/server/admin/std/KeyManagerConfiguration.xml
@@ -27,7 +27,7 @@
 ! -->
<adm:managed-object name="key-manager" plural-name="key-managers"
  package="org.opends.server.admin.std" abstract="true"
  package="org.opends.server.admin.std" abstract="false"
  xmlns:adm="http://www.opends.org/admin"
  xmlns:ldap="http://www.opends.org/admin-ldap">
  <adm:synopsis>
opends/src/admin/defn/org/opends/server/admin/std/Package.xml
@@ -130,9 +130,7 @@
      </adm:none>
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:defined>
        <adm:value>jks</adm:value>
      </adm:defined>
      <adm:undefined />
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
@@ -267,6 +265,127 @@
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="trust-store-pin">
    <adm:synopsis>
      Specifies the clear-text PIN needed to access the
      <adm:user-friendly-name />
      .
    </adm:synopsis>
    <adm:requires-admin-action>
      <adm:none>
        <adm:synopsis>
          Changes to this property will take effect the next time that
          the
          <adm:user-friendly-name />
          is accessed.
        </adm:synopsis>
      </adm:none>
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:undefined />
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.130</ldap:oid>
        <ldap:name>ds-cfg-trust-store-pin</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="trust-store-pin-property">
    <adm:TODO>Better syntax for property name?</adm:TODO>
    <adm:synopsis>
      Specifies the name of the Java property that contains the
      clear-text PIN needed to access the
      <adm:user-friendly-name />
      .
    </adm:synopsis>
    <adm:requires-admin-action>
      <adm:none>
        <adm:synopsis>
          Changes to this property will take effect the next time that
          the
          <adm:user-friendly-name />
          is accessed.
        </adm:synopsis>
      </adm:none>
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:undefined />
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.133</ldap:oid>
        <ldap:name>ds-cfg-trust-store-pin-property</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="trust-store-pin-environment-variable">
    <adm:synopsis>
      Specifies the name of the environment variable that contains the
      clear-text PIN needed to access the
      <adm:user-friendly-name />
      .
    </adm:synopsis>
    <adm:requires-admin-action>
      <adm:none>
        <adm:synopsis>
          Changes to this property will take effect the next time that
          the
          <adm:user-friendly-name />
          is accessed.
        </adm:synopsis>
      </adm:none>
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:undefined />
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.131</ldap:oid>
        <ldap:name>ds-cfg-trust-store-pin-environment-variable</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="trust-store-pin-file">
    <adm:TODO>Should use a file-based property definition?</adm:TODO>
    <adm:synopsis>
      Specifies the path to the text file whose only contents should be
      a single line containing the clear-text PIN needed to access the
      <adm:user-friendly-name />
      .
    </adm:synopsis>
    <adm:requires-admin-action>
      <adm:none>
        <adm:synopsis>
          Changes to this property will take effect the next time that
          the
          <adm:user-friendly-name />
          is accessed.
        </adm:synopsis>
      </adm:none>
    </adm:requires-admin-action>
    <adm:default-behavior>
      <adm:undefined />
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.132</ldap:oid>
        <ldap:name>ds-cfg-trust-store-pin-file</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="trust-manager-provider-dn">
    <adm:synopsis>
      Specifies the DN of the configuration entry for the trust manager
opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
@@ -360,6 +360,32 @@
      </cli:relation>
    </adm:profile>
  </adm:relation>
  <adm:relation name="key-manager">
    <adm:one-to-many />
    <adm:profile name="ldap">
      <ldap:rdn-sequence>
        cn=Key Manager Providers,cn=config
      </ldap:rdn-sequence>
    </adm:profile>
    <adm:profile name="cli">
      <cli:relation>
        <cli:default-property name="enabled" />
      </cli:relation>
    </adm:profile>
  </adm:relation>
  <adm:relation name="trust-manager">
    <adm:one-to-many />
    <adm:profile name="ldap">
      <ldap:rdn-sequence>
        cn=Trust Manager Providers,cn=config
      </ldap:rdn-sequence>
    </adm:profile>
    <adm:profile name="cli">
      <cli:relation>
        <cli:default-property name="enabled" />
      </cli:relation>
    </adm:profile>
  </adm:relation>
  <adm:relation name="work-queue">
    <adm:one-to-one />
    <adm:profile name="ldap">
opends/src/admin/defn/org/opends/server/admin/std/TrustManagerConfiguration.xml
New file
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
 ! CDDL HEADER START
 !
 ! The contents of this file are subject to the terms of the
 ! Common Development and Distribution License, Version 1.0 only
 ! (the "License").  You may not use this file except in compliance
 ! with the License.
 !
 ! You can obtain a copy of the license at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE
 ! or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 ! See the License for the specific language governing permissions
 ! and limitations under the License.
 !
 ! When distributing Covered Code, include this CDDL HEADER in each
 ! file and include the License file at
 ! trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 ! add the following below this CDDL HEADER, with the fields enclosed
 ! by brackets "[]" replaced with your own identifying information:
 !      Portions Copyright [yyyy] [name of copyright owner]
 !
 ! CDDL HEADER END
 !
 !
 !      Portions Copyright 2007 Sun Microsystems, Inc.
 ! -->
<adm:managed-object name="trust-manager" plural-name="trust-managers"
  package="org.opends.server.admin.std" abstract="false"
  xmlns:adm="http://www.opends.org/admin"
  xmlns:ldap="http://www.opends.org/admin-ldap">
  <adm:synopsis>
    <adm:user-friendly-plural-name />
    are responsible for determining whether to trust presented certificates.
  </adm:synopsis>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:oid>1.3.6.1.4.1.26027.1.2.51</ldap:oid>
      <ldap:name>ds-cfg-trust-manager-provider</ldap:name>
      <ldap:superior>top</ldap:superior>
    </ldap:object-class>
  </adm:profile>
  <adm:property name="enabled" mandatory="true">
    <adm:synopsis>
      Indicate whether the
      <adm:user-friendly-name />
      is enabled for use.
    </adm:synopsis>
    <adm:syntax>
      <adm:boolean />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.128</ldap:oid>
        <ldap:name>ds-cfg-trust-manager-provider-enabled</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="java-implementation-class" mandatory="true">
    <adm:synopsis>
      The fully-qualified name of the Java class that should to provide
      the
      <adm:user-friendly-name />
      implementation.
    </adm:synopsis>
    <adm:syntax>
      <adm:java-class>
        <adm:instance-of>
          org.opends.server.api.TrustManagerProvider
        </adm:instance-of>
      </adm:java-class>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.127</ldap:oid>
        <ldap:name>ds-cfg-trust-manager-provider-class</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opends/src/server/org/opends/server/api/KeyManagerProvider.java
@@ -31,7 +31,6 @@
import javax.net.ssl.KeyManager;
import org.opends.server.admin.std.server.KeyManagerCfg;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
@@ -52,30 +51,6 @@
{
  /**
   * Initializes this key manager provider based on the information in
   * the provided configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the
   *                      information to use to initialize this key
   *                      manager provider.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in
   *                           the process of performing the
   *                           initialization as a result of the
   *                           server configuration.
   *
   * @throws  InitializationException  If a problem occurs during
   *                                   initialization that is not
   *                                   related to the server
   *                                   configuration.
   */
  public abstract void initializeKeyManagerProvider(
                            ConfigEntry configEntry)
         throws ConfigException, InitializationException;
  /**
   * Initializes this key manager provider based on the information in
   * the provided key manager provider configuration.
   *
   * @param configuration
opends/src/server/org/opends/server/api/TrustManagerProvider.java
@@ -30,7 +30,7 @@
import javax.net.ssl.TrustManager;
import org.opends.server.config.ConfigEntry;
import org.opends.server.admin.std.server.TrustManagerCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
@@ -41,16 +41,18 @@
 * This class defines an API that may be used to obtain a set of
 * {@code javax.net.ssl.TrustManager} objects for use when performing
 * SSL/StartTLS negotiation.
 *
 * @param  <T>  The type of trust manager provider configuration
 *              handled by this trust manager provider implementation.
 */
public abstract class TrustManagerProvider
public abstract class TrustManagerProvider<T extends TrustManagerCfg>
{
  /**
   * Initializes this trust manager provider based on the information
   * in the provided configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the
   *                      information to use to initialize this trust
   *                      manager provider.
   * @param  configuration  The configuration to use for this trust
   *                        manager provider.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in
   *                           the process of performing the
@@ -63,7 +65,7 @@
   *                                   configuration.
   */
  public abstract void initializeTrustManagerProvider(
                            ConfigEntry configEntry)
                            T configuration)
         throws ConfigException, InitializationException;
opends/src/server/org/opends/server/core/KeyManagerProviderConfigManager.java
@@ -28,22 +28,21 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.opends.server.api.ConfigAddListener;
import org.opends.server.api.ConfigChangeListener;
import org.opends.server.api.ConfigDeleteListener;
import org.opends.server.api.ConfigHandler;
import org.opends.server.api.ConfigurableComponent;
import org.opends.server.admin.ClassPropertyDefinition;
import org.opends.server.admin.server.ConfigurationAddListener;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ConfigurationDeleteListener;
import org.opends.server.admin.std.meta.KeyManagerCfgDefn;
import org.opends.server.admin.std.server.KeyManagerCfg;
import org.opends.server.admin.std.server.RootCfg;
import org.opends.server.admin.server.ServerManagementContext;
import org.opends.server.api.KeyManagerProvider;
import org.opends.server.config.BooleanConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.config.StringConfigAttribute;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.ErrorLogCategory;
@@ -51,42 +50,30 @@
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import static org.opends.server.config.ConfigConstants.*;
import org.opends.server.types.DebugLogLevel;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.messages.ConfigMessages.*;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines a utility that will be used to manage the set of
 * key manager providers defined in the Directory Server.  It will initialize
 * the providers when the server starts, and then will manage any additions,
 * removals, or modifications of any key manager providers while the server is
 * running.
 * This class defines a utility that will be used to manage the set of key
 * manager providers defined in the Directory Server.  It will initialize the
 * key manager providers when the server starts, and then will manage any
 * additions, removals, or modifications to any key manager providers while
 * the server is running.
 */
public class KeyManagerProviderConfigManager
       implements ConfigChangeListener, ConfigAddListener, ConfigDeleteListener
       implements ConfigurationChangeListener<KeyManagerCfg>,
                  ConfigurationAddListener<KeyManagerCfg>,
                  ConfigurationDeleteListener<KeyManagerCfg>
{
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
  // A mapping between the DNs of the config entries and the associated
  // key manager providers.
  // A mapping between the DNs of the config entries and the associated key
  // manager providers.
  private ConcurrentHashMap<DN,KeyManagerProvider> providers;
  // The configuration handler for the Directory Server.
  private ConfigHandler configHandler;
  /**
@@ -94,8 +81,7 @@
   */
  public KeyManagerProviderConfigManager()
  {
    configHandler = DirectoryServer.getConfigHandler();
    providers     = new ConcurrentHashMap<DN,KeyManagerProvider>();
    providers = new ConcurrentHashMap<DN,KeyManagerProvider>();
  }
@@ -105,8 +91,8 @@
   * Server configuration.  This should only be called at Directory Server
   * startup.
   *
   * @throws  ConfigException  If a configuration problem causes the key manager
   *                           provider initialization process to fail.
   * @throws  ConfigException  If a configuration problem causes the key
   *                           manager provider initialization process to fail.
   *
   * @throws  InitializationException  If a problem occurs while initializing
   *                                   the key manager providers that is not
@@ -115,854 +101,309 @@
  public void initializeKeyManagerProviders()
         throws ConfigException, InitializationException
  {
    // First, get the configuration base entry.
    ConfigEntry baseEntry;
    try
    // Get the root configuration object.
    ServerManagementContext managementContext =
         ServerManagementContext.getInstance();
    RootCfg rootConfiguration =
         managementContext.getRootConfiguration();
    // Register as an add and delete listener with the root configuration so we
    // can be notified if any key manager provider entries are added or removed.
    rootConfiguration.addKeyManagerAddListener(this);
    rootConfiguration.addKeyManagerDeleteListener(this);
    //Initialize the existing key manager providers.
    for (String name : rootConfiguration.listKeyManagers())
    {
      DN providerBase = DN.decode(DN_KEYMANAGER_PROVIDER_CONFIG_BASE);
      baseEntry = configHandler.getConfigEntry(providerBase);
    }
    catch (Exception e)
    {
      if (debugEnabled())
      KeyManagerCfg providerConfig = rootConfiguration.getKeyManager(name);
      providerConfig.addChangeListener(this);
      if (providerConfig.isEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int    msgID   = MSGID_CONFIG_KEYMANAGER_CANNOT_GET_BASE;
      String message = getMessage(msgID, String.valueOf(e));
      throw new ConfigException(msgID, message, e);
    }
    if (baseEntry == null)
    {
      // The key manager provider base entry does not exist.  This is not
      // acceptable, so throw an exception.
      int    msgID   = MSGID_CONFIG_KEYMANAGER_BASE_DOES_NOT_EXIST;
      String message = getMessage(msgID);
      throw new ConfigException(msgID, message);
    }
    // Register add and delete listeners with the key manager provider base
    // entry.  We don't care about modifications to it.
    baseEntry.registerAddListener(this);
    baseEntry.registerDeleteListener(this);
    // See if the base entry has any children.  If not, then we don't need to do
    // anything else.
    if (! baseEntry.hasChildren())
    {
      return;
    }
    // Iterate through the child entries and process them as key manager
    // provider configuration entries.
    for (ConfigEntry childEntry : baseEntry.getChildren().values())
    {
      childEntry.registerChangeListener(this);
      StringBuilder unacceptableReason = new StringBuilder();
      if (! configAddIsAcceptable(childEntry, unacceptableReason))
      {
        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
                 MSGID_CONFIG_KEYMANAGER_ENTRY_UNACCEPTABLE,
                 childEntry.getDN().toString(), unacceptableReason.toString());
        continue;
      }
      try
      {
        ConfigChangeResult result = applyConfigurationAdd(childEntry);
        if (result.getResultCode() != ResultCode.SUCCESS)
        String className = providerConfig.getJavaImplementationClass();
        try
        {
          StringBuilder buffer = new StringBuilder();
          List<String> resultMessages = result.getMessages();
          if ((resultMessages == null) || (resultMessages.isEmpty()))
          {
            buffer.append(getMessage(MSGID_CONFIG_UNKNOWN_UNACCEPTABLE_REASON));
          }
          else
          {
            Iterator<String> iterator = resultMessages.iterator();
            buffer.append(iterator.next());
            while (iterator.hasNext())
            {
              buffer.append(EOL);
              buffer.append(iterator.next());
            }
          }
          KeyManagerProvider provider =
               loadProvider(className, providerConfig);
          providers.put(providerConfig.dn(), provider);
          DirectoryServer.registerKeyManagerProvider(providerConfig.dn(),
                                                     provider);
        }
        catch (InitializationException ie)
        {
          logError(ErrorLogCategory.CONFIGURATION,
                   ErrorLogSeverity.SEVERE_ERROR,
                   MSGID_CONFIG_KEYMANAGER_CANNOT_CREATE_PROVIDER,
                   childEntry.getDN().toString(), buffer.toString());
                   ie.getMessage(), ie.getMessageID());
          continue;
        }
      }
      catch (Exception e)
      {
        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
                 MSGID_CONFIG_KEYMANAGER_CANNOT_CREATE_PROVIDER,
                 childEntry.getDN().toString(), String.valueOf(e));
      }
    }
  }
  /**
   * Indicates whether the configuration entry that will result from a proposed
   * modification is acceptable to this change listener.
   *
   * @param  configEntry         The configuration entry that will result from
   *                             the requested update.
   * @param  unacceptableReason  A buffer to which this method can append a
   *                             human-readable message explaining why the
   *                             proposed change is not acceptable.
   *
   * @return  <CODE>true</CODE> if the proposed entry contains an acceptable
   *          configuration, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  public boolean configChangeIsAcceptable(ConfigEntry configEntry,
                                          StringBuilder unacceptableReason)
  public boolean isConfigurationAddAcceptable(KeyManagerCfg configuration,
                                              List<String> unacceptableReasons)
  {
    // Make sure that the entry has an appropriate objectclass for a key manager
    // provider.
    if (! configEntry.hasObjectClass(OC_KEY_MANAGER_PROVIDER))
    if (configuration.isEnabled())
    {
      int    msgID   = MSGID_CONFIG_KEYMANAGER_INVALID_OBJECTCLASS;
      String message = getMessage(msgID, configEntry.getDN().toString());
      unacceptableReason.append(message);
      return false;
    }
    // Make sure that the entry specifies the provider class name.
    StringConfigAttribute classNameAttr;
    try
    {
      StringConfigAttribute classStub =
           new StringConfigAttribute(ATTR_KEYMANAGER_CLASS,
                    getMessage(MSGID_CONFIG_KEYMANAGER_DESCRIPTION_CLASS),
                    true, false, true);
      classNameAttr = (StringConfigAttribute)
                      configEntry.getConfigAttribute(classStub);
      if (classNameAttr == null)
      // Get the name of the class and make sure we can instantiate it as a
      // key manager provider.
      String className = configuration.getJavaImplementationClass();
      try
      {
        int    msgID   = MSGID_CONFIG_KEYMANAGER_NO_CLASS_NAME;
        String message = getMessage(msgID, configEntry.getDN().toString());
        unacceptableReason.append(message);
        loadProvider(className, null);
      }
      catch (InitializationException ie)
      {
        unacceptableReasons.add(ie.getMessage());
        return false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int    msgID   = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS_NAME;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    Class providerClass;
    try
    {
      providerClass = DirectoryServer.loadClass(classNameAttr.pendingValue());
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int    msgID   = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS_NAME;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    try
    {
      providerClass.newInstance();
    }
    catch(Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int    msgID   = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS;
      String message = getMessage(msgID, providerClass.getName(),
                                  String.valueOf(configEntry.getDN()),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    // See if this key manager provider should be enabled.
    BooleanConfigAttribute enabledAttr;
    try
    {
      BooleanConfigAttribute enabledStub =
           new BooleanConfigAttribute(ATTR_KEYMANAGER_ENABLED,
                    getMessage(MSGID_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED),
                               false);
      enabledAttr = (BooleanConfigAttribute)
                    configEntry.getConfigAttribute(enabledStub);
      if (enabledAttr == null)
      {
        int    msgID   = MSGID_CONFIG_KEYMANAGER_NO_ENABLED_ATTR;
        String message = getMessage(msgID, configEntry.getDN().toString());
        unacceptableReason.append(message);
        return false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_ENABLED_VALUE;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    // If we've gotten here then the key manager provider entry appears to be
    // acceptable.
    // If we've gotten here, then it's fine.
    return true;
  }
  /**
   * Attempts to apply a new configuration to this Directory Server component
   * based on the provided changed entry.
   *
   * @param  configEntry  The configuration entry that containing the updated
   *                      configuration for this component.
   *
   * @return  Information about the result of processing the configuration
   *          change.
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationChange(ConfigEntry configEntry)
  public ConfigChangeResult applyConfigurationAdd(KeyManagerCfg configuration)
  {
    DN                configEntryDN       = configEntry.getDN();
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    configuration.addChangeListener(this);
    // Make sure that the entry has an appropriate objectclass for a key manager
    // provider.
    if (! configEntry.hasObjectClass(OC_KEY_MANAGER_PROVIDER))
    if (! configuration.isEnabled())
    {
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
      resultCode = ResultCode.UNWILLING_TO_PERFORM;
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    KeyManagerProvider provider = null;
    // Get the corresponding key manager provider if it is active.
    KeyManagerProvider provider = providers.get(configEntryDN);
    // See if this provider should be enabled or disabled.
    boolean needsEnabled = false;
    BooleanConfigAttribute enabledAttr;
    // Get the name of the class and make sure we can instantiate it as a key
    // manager provider.
    String className = configuration.getJavaImplementationClass();
    try
    {
      BooleanConfigAttribute enabledStub =
           new BooleanConfigAttribute(ATTR_KEYMANAGER_ENABLED,
                    getMessage(MSGID_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED),
                    false);
      enabledAttr = (BooleanConfigAttribute)
                    configEntry.getConfigAttribute(enabledStub);
      if (enabledAttr == null)
      {
        int msgID = MSGID_CONFIG_KEYMANAGER_NO_ENABLED_ATTR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
        resultCode = ResultCode.UNWILLING_TO_PERFORM;
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      if (enabledAttr.activeValue())
      {
        if (provider == null)
        {
          needsEnabled = true;
        }
        else
        {
          // The provider is already active, so no action is required.
        }
      }
      else
      {
        if (provider == null)
        {
          // The provider is already disabled, so no action is required and we
          // can short-circuit out of this processing.
          return new ConfigChangeResult(resultCode, adminActionRequired,
                                        messages);
        }
        else
        {
          // The provider is active, so it needs to be disabled.  Do this and
          // return that we were successful.
          providers.remove(configEntryDN);
          DirectoryServer.deregisterKeyManagerProvider(configEntryDN);
          provider.finalizeKeyManagerProvider();
          return new ConfigChangeResult(resultCode, adminActionRequired,
                                        messages);
        }
      }
      provider = loadProvider(className, configuration);
    }
    catch (Exception e)
    catch (InitializationException ie)
    {
      if (debugEnabled())
      if (resultCode == ResultCode.SUCCESS)
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_ENABLED_VALUE;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Make sure that the entry specifies the provider class name.  If it has
    // changed, then we will not try to dynamically apply it.
    String className;
    try
    {
      StringConfigAttribute classStub =
           new StringConfigAttribute(ATTR_KEYMANAGER_CLASS,
                    getMessage(MSGID_CONFIG_KEYMANAGER_DESCRIPTION_CLASS),
                    true, false, true);
      StringConfigAttribute classNameAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
      if (classNameAttr == null)
      {
        int msgID = MSGID_CONFIG_KEYMANAGER_NO_CLASS_NAME;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
        resultCode = ResultCode.OBJECTCLASS_VIOLATION;
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      className = classNameAttr.pendingValue();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS_NAME;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    boolean classChanged = false;
    String  oldClassName = null;
    if (provider != null)
    {
      oldClassName = provider.getClass().getName();
      classChanged = (! className.equals(oldClassName));
    }
    if (classChanged)
    {
      // This will not be applied dynamically.  Add a message to the response
      // and indicate that admin action is required.
      adminActionRequired = true;
      messages.add(getMessage(MSGID_CONFIG_KEYMANAGER_CLASS_ACTION_REQUIRED,
                              String.valueOf(oldClassName),
                              String.valueOf(className),
                              String.valueOf(configEntryDN)));
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    if (needsEnabled)
    {
      try
      {
        Class providerClass = DirectoryServer.loadClass(className);
        provider = (KeyManagerProvider) providerClass.newInstance();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS;
        messages.add(getMessage(msgID, className,
                                String.valueOf(configEntryDN),
                                String.valueOf(e)));
        resultCode = DirectoryServer.getServerErrorResultCode();
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      try
      {
        provider.initializeKeyManagerProvider(configEntry);
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        int msgID = MSGID_CONFIG_KEYMANAGER_INITIALIZATION_FAILED;
        messages.add(getMessage(msgID, className,
                                String.valueOf(configEntryDN),
                                String.valueOf(e)));
        resultCode = DirectoryServer.getServerErrorResultCode();
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      providers.put(configEntryDN, provider);
      DirectoryServer.registerKeyManagerProvider(configEntryDN, provider);
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
      messages.add(ie.getMessage());
    }
    if (resultCode == ResultCode.SUCCESS)
    {
      providers.put(configuration.dn(), provider);
      DirectoryServer.registerKeyManagerProvider(configuration.dn(), provider);
    }
    // If we've gotten here, then there haven't been any changes to anything
    // that we care about.
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
  /**
   * Indicates whether the configuration entry that will result from a proposed
   * add is acceptable to this add listener.
   *
   * @param  configEntry         The configuration entry that will result from
   *                             the requested add.
   * @param  unacceptableReason  A buffer to which this method can append a
   *                             human-readable message explaining why the
   *                             proposed entry is not acceptable.
   *
   * @return  <CODE>true</CODE> if the proposed entry contains an acceptable
   *          configuration, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  public boolean configAddIsAcceptable(ConfigEntry configEntry,
                                       StringBuilder unacceptableReason)
  public boolean isConfigurationDeleteAcceptable(KeyManagerCfg configuration,
                      List<String> unacceptableReasons)
  {
    // Make sure that no entry already exists with the specified DN.
    DN configEntryDN = configEntry.getDN();
    if (providers.containsKey(configEntryDN))
    {
      int    msgID   = MSGID_CONFIG_KEYMANAGER_EXISTS;
      String message = getMessage(msgID, String.valueOf(configEntryDN));
      unacceptableReason.append(message);
      return false;
    }
    // Make sure that the entry has an appropriate objectclass for a key manager
    // provider.
    if (! configEntry.hasObjectClass(OC_KEY_MANAGER_PROVIDER))
    {
      int    msgID   = MSGID_CONFIG_KEYMANAGER_INVALID_OBJECTCLASS;
      String message = getMessage(msgID, configEntry.getDN().toString());
      unacceptableReason.append(message);
      return false;
    }
    // Make sure that the entry specifies the key manager provider class.
    StringConfigAttribute classNameAttr;
    try
    {
      StringConfigAttribute classStub =
           new StringConfigAttribute(ATTR_KEYMANAGER_CLASS,
                    getMessage(MSGID_CONFIG_KEYMANAGER_DESCRIPTION_CLASS),
                    true, false, true);
      classNameAttr = (StringConfigAttribute)
                      configEntry.getConfigAttribute(classStub);
      if (classNameAttr == null)
      {
        int msgID = MSGID_CONFIG_KEYMANAGER_NO_CLASS_NAME;
        String message = getMessage(msgID, configEntry.getDN().toString());
        unacceptableReason.append(message);
        return false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS_NAME;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    Class providerClass;
    try
    {
      providerClass = DirectoryServer.loadClass(classNameAttr.pendingValue());
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS_NAME;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    KeyManagerProvider provider;
    try
    {
      provider = (KeyManagerProvider) providerClass.newInstance();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS;
      String message = getMessage(msgID, providerClass.getName(),
                                  String.valueOf(configEntryDN),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    // See if this provider should be enabled.
    BooleanConfigAttribute enabledAttr;
    try
    {
      BooleanConfigAttribute enabledStub =
           new BooleanConfigAttribute(ATTR_KEYMANAGER_ENABLED,
                    getMessage(MSGID_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED),
                               false);
      enabledAttr = (BooleanConfigAttribute)
                    configEntry.getConfigAttribute(enabledStub);
      if (enabledAttr == null)
      {
        int msgID = MSGID_CONFIG_KEYMANAGER_NO_ENABLED_ATTR;
        String message = getMessage(msgID, configEntry.getDN().toString());
        unacceptableReason.append(message);
        return false;
      }
      else if (! enabledAttr.pendingValue())
      {
        // The key manager provider is not enabled, so we don't need to do any
        // further validation.
        return true;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_ENABLED_VALUE;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    // If the provider is a configurable component, then make sure that its
    // configuration is valid.
    if (provider instanceof ConfigurableComponent)
    {
      ConfigurableComponent cc = (ConfigurableComponent) provider;
      LinkedList<String> errorMessages = new LinkedList<String>();
      if (! cc.hasAcceptableConfiguration(configEntry, errorMessages))
      {
        if (errorMessages.isEmpty())
        {
          int msgID = MSGID_CONFIG_KEYMANAGER_UNACCEPTABLE_CONFIG;
          unacceptableReason.append(getMessage(msgID,
                                               String.valueOf(configEntryDN)));
        }
        else
        {
          Iterator<String> iterator = errorMessages.iterator();
          unacceptableReason.append(iterator.next());
          while (iterator.hasNext())
          {
            unacceptableReason.append("  ");
            unacceptableReason.append(iterator.next());
          }
        }
        return false;
      }
    }
    // If we've gotten here then the provider entry appears to be acceptable.
    // FIXME -- We should try to perform some check to determine whether the
    // provider is in use.
    return true;
  }
  /**
   * Attempts to apply a new configuration based on the provided added entry.
   *
   * @param  configEntry  The new configuration entry that contains the
   *                      configuration to apply.
   *
   * @return  Information about the result of processing the configuration
   *          change.
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationAdd(ConfigEntry configEntry)
  public ConfigChangeResult applyConfigurationDelete(
                                 KeyManagerCfg configuration)
  {
    DN                configEntryDN       = configEntry.getDN();
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    DirectoryServer.deregisterKeyManagerProvider(configuration.dn());
    // Make sure that the entry has an appropriate objectclass for a key manager
    // provider.
    if (! configEntry.hasObjectClass(OC_KEY_MANAGER_PROVIDER))
    {
      int    msgID   = MSGID_CONFIG_KEYMANAGER_INVALID_OBJECTCLASS;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
      resultCode = ResultCode.UNWILLING_TO_PERFORM;
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // See if this provider should be enabled or disabled.
    BooleanConfigAttribute enabledAttr;
    try
    {
      BooleanConfigAttribute enabledStub =
           new BooleanConfigAttribute(ATTR_KEYMANAGER_ENABLED,
                    getMessage(MSGID_CONFIG_KEYMANAGER_DESCRIPTION_ENABLED),
                               false);
      enabledAttr = (BooleanConfigAttribute)
                    configEntry.getConfigAttribute(enabledStub);
      if (enabledAttr == null)
      {
        // The attribute doesn't exist, so it will be disabled by default.
        int msgID = MSGID_CONFIG_KEYMANAGER_NO_ENABLED_ATTR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
        resultCode = ResultCode.SUCCESS;
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      else if (! enabledAttr.activeValue())
      {
        // It is explicitly configured as disabled, so we don't need to do
        // anything.
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_ENABLED_VALUE;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Make sure that the entry specifies the provider class name.
    String className;
    try
    {
      StringConfigAttribute classStub =
           new StringConfigAttribute(ATTR_KEYMANAGER_CLASS,
                    getMessage(MSGID_CONFIG_KEYMANAGER_DESCRIPTION_CLASS),
                    true, false, true);
      StringConfigAttribute classNameAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
      if (classNameAttr == null)
      {
        int msgID = MSGID_CONFIG_KEYMANAGER_NO_CLASS_NAME;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
        resultCode = ResultCode.OBJECTCLASS_VIOLATION;
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      className = classNameAttr.pendingValue();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS_NAME;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Load and initialize the provider class, and register it with the
    // Directory Server.
    KeyManagerProvider provider;
    try
    {
      Class providerClass = DirectoryServer.loadClass(className);
      provider = (KeyManagerProvider) providerClass.newInstance();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INVALID_CLASS;
      messages.add(getMessage(msgID, className, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    try
    {
      provider.initializeKeyManagerProvider(configEntry);
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_KEYMANAGER_INITIALIZATION_FAILED;
      messages.add(getMessage(msgID, className, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    providers.put(configEntryDN, provider);
    DirectoryServer.registerKeyManagerProvider(configEntryDN, provider);
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
  /**
   * Indicates whether it is acceptable to remove the provided configuration
   * entry.
   *
   * @param  configEntry         The configuration entry that will be removed
   *                             from the configuration.
   * @param  unacceptableReason  A buffer to which this method can append a
   *                             human-readable message explaining why the
   *                             proposed delete is not acceptable.
   *
   * @return  <CODE>true</CODE> if the proposed entry may be removed from the
   *          configuration, or <CODE>false</CODE> if not.
   */
  public boolean configDeleteIsAcceptable(ConfigEntry configEntry,
                                          StringBuilder unacceptableReason)
  {
    // A delete should always be acceptable, so just return true.
    return true;
  }
  /**
   * Attempts to apply a new configuration based on the provided deleted entry.
   *
   * @param  configEntry  The new configuration entry that has been deleted.
   *
   * @return  Information about the result of processing the configuration
   *          change.
   */
  public ConfigChangeResult applyConfigurationDelete(ConfigEntry configEntry)
  {
    DN         configEntryDN       = configEntry.getDN();
    ResultCode resultCode          = ResultCode.SUCCESS;
    boolean    adminActionRequired = false;
    // See if the entry is registered as a key manager provider.  If so,
    // deregister it and stop the provider.
    KeyManagerProvider provider = providers.remove(configEntryDN);
    KeyManagerProvider provider = providers.remove(configuration.dn());
    if (provider != null)
    {
      DirectoryServer.deregisterKeyManagerProvider(configEntryDN);
      provider.finalizeKeyManagerProvider();
    }
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
    return new ConfigChangeResult(resultCode, adminActionRequired);
  /**
   * {@inheritDoc}
   */
  public boolean isConfigurationChangeAcceptable(KeyManagerCfg configuration,
                      List<String> unacceptableReasons)
  {
    if (configuration.isEnabled())
    {
      // Get the name of the class and make sure we can instantiate it as a key
      // manager provider.
      String className = configuration.getJavaImplementationClass();
      try
      {
        loadProvider(className, null);
      }
      catch (InitializationException ie)
      {
        unacceptableReasons.add(ie.getMessage());
        return false;
      }
    }
    // If we've gotten here, then it's fine.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationChange(
                                 KeyManagerCfg configuration)
  {
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    // Get the existing provider if it's already enabled.
    KeyManagerProvider existingProvider = providers.get(configuration.dn());
    // If the new configuration has the provider disabled, then disable it if it
    // is enabled, or do nothing if it's already disabled.
    if (! configuration.isEnabled())
    {
      if (existingProvider != null)
      {
        DirectoryServer.deregisterKeyManagerProvider(configuration.dn());
        KeyManagerProvider provider = providers.remove(configuration.dn());
        if (provider != null)
        {
          provider.finalizeKeyManagerProvider();
        }
      }
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Get the class for the key manager provider.  If the provider is already
    // enabled, then we shouldn't do anything with it although if the class has
    // changed then we'll at least need to indicate that administrative action
    // is required.  If the provider is disabled, then instantiate the class and
    // initialize and register it as a key manager provider.
    String className = configuration.getJavaImplementationClass();
    if (existingProvider != null)
    {
      if (! className.equals(existingProvider.getClass().getName()))
      {
        adminActionRequired = true;
      }
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    KeyManagerProvider provider = null;
    try
    {
      provider = loadProvider(className, configuration);
    }
    catch (InitializationException ie)
    {
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
      }
      messages.add(ie.getMessage());
    }
    if (resultCode == ResultCode.SUCCESS)
    {
      providers.put(configuration.dn(), provider);
      DirectoryServer.registerKeyManagerProvider(configuration.dn(), provider);
    }
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
  /**
   * Loads the specified class, instantiates it as a key manager provider, and
   * optionally initializes that instance.
   *
   * @param  className      The fully-qualified name of the key manager
   *                        provider class to load, instantiate, and initialize.
   * @param  configuration  The configuration to use to initialize the key
   *                        manager provider, or {@code null} if the provider
   *                        should not be initialized.
   *
   * @return  The possibly initialized key manager provider.
   *
   * @throws  InitializationException  If a problem occurred while attempting to
   *                                   initialize the key manager provider.
   */
  private KeyManagerProvider loadProvider(String className,
                                          KeyManagerCfg configuration)
          throws InitializationException
  {
    try
    {
      KeyManagerCfgDefn definition = KeyManagerCfgDefn.getInstance();
      ClassPropertyDefinition propertyDefinition =
           definition.getJavaImplementationClassPropertyDefinition();
      Class<? extends KeyManagerProvider> providerClass =
           propertyDefinition.loadClass(className, KeyManagerProvider.class);
      KeyManagerProvider provider = providerClass.newInstance();
      if (configuration != null)
      {
        Method method =
             provider.getClass().getMethod("initializeKeyManagerProvider",
                  configuration.definition().getServerConfigurationClass());
        method.invoke(provider, configuration);
      }
      return provider;
    }
    catch (Exception e)
    {
      int msgID = MSGID_CONFIG_KEYMANAGER_INITIALIZATION_FAILED;
      String message = getMessage(msgID, className,
                                  String.valueOf(configuration.dn()),
                                  stackTraceToSingleLineString(e));
      throw new InitializationException(msgID, message, e);
    }
  }
}
opends/src/server/org/opends/server/core/TrustManagerProviderConfigManager.java
@@ -28,22 +28,21 @@
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.opends.server.api.ConfigAddListener;
import org.opends.server.api.ConfigChangeListener;
import org.opends.server.api.ConfigDeleteListener;
import org.opends.server.api.ConfigHandler;
import org.opends.server.api.ConfigurableComponent;
import org.opends.server.admin.ClassPropertyDefinition;
import org.opends.server.admin.server.ConfigurationAddListener;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ConfigurationDeleteListener;
import org.opends.server.admin.std.meta.TrustManagerCfgDefn;
import org.opends.server.admin.std.server.TrustManagerCfg;
import org.opends.server.admin.std.server.RootCfg;
import org.opends.server.admin.server.ServerManagementContext;
import org.opends.server.api.TrustManagerProvider;
import org.opends.server.config.BooleanConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.config.StringConfigAttribute;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.ErrorLogCategory;
@@ -51,42 +50,30 @@
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import static org.opends.server.config.ConfigConstants.*;
import org.opends.server.types.DebugLogLevel;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.messages.ConfigMessages.*;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class defines a utility that will be used to manage the set of
 * trust manager providers defined in the Directory Server.  It will initialize
 * the providers when the server starts, and then will manage any additions,
 * removals, or modifications of any trust manager providers while the server is
 * running.
 * This class defines a utility that will be used to manage the set of trust
 * manager providers defined in the Directory Server.  It will initialize the
 * trust manager providers when the server starts, and then will manage any
 * additions, removals, or modifications to any trust manager providers while
 * the server is running.
 */
public class TrustManagerProviderConfigManager
       implements ConfigChangeListener, ConfigAddListener, ConfigDeleteListener
       implements ConfigurationChangeListener<TrustManagerCfg>,
                  ConfigurationAddListener<TrustManagerCfg>,
                  ConfigurationDeleteListener<TrustManagerCfg>
{
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
  // A mapping between the DNs of the config entries and the associated
  // trust manager providers.
  // A mapping between the DNs of the config entries and the associated trust
  // manager providers.
  private ConcurrentHashMap<DN,TrustManagerProvider> providers;
  // The configuration handler for the Directory Server.
  private ConfigHandler configHandler;
  /**
@@ -94,8 +81,7 @@
   */
  public TrustManagerProviderConfigManager()
  {
    configHandler = DirectoryServer.getConfigHandler();
    providers     = new ConcurrentHashMap<DN,TrustManagerProvider>();
    providers = new ConcurrentHashMap<DN,TrustManagerProvider>();
  }
@@ -115,855 +101,312 @@
  public void initializeTrustManagerProviders()
         throws ConfigException, InitializationException
  {
    // First, get the configuration base entry.
    ConfigEntry baseEntry;
    try
    // Get the root configuration object.
    ServerManagementContext managementContext =
         ServerManagementContext.getInstance();
    RootCfg rootConfiguration =
         managementContext.getRootConfiguration();
    // Register as an add and delete listener with the root configuration so we
    // can be notified if any trust manager provider entries are added or
    // removed.
    rootConfiguration.addTrustManagerAddListener(this);
    rootConfiguration.addTrustManagerDeleteListener(this);
    //Initialize the existing trust manager providers.
    for (String name : rootConfiguration.listTrustManagers())
    {
      DN providerBase = DN.decode(DN_TRUSTMANAGER_PROVIDER_CONFIG_BASE);
      baseEntry = configHandler.getConfigEntry(providerBase);
    }
    catch (Exception e)
    {
      if (debugEnabled())
      TrustManagerCfg providerConfig = rootConfiguration.getTrustManager(name);
      providerConfig.addChangeListener(this);
      if (providerConfig.isEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_CANNOT_GET_BASE;
      String message = getMessage(msgID, String.valueOf(e));
      throw new ConfigException(msgID, message, e);
    }
    if (baseEntry == null)
    {
      // The trust manager provider base entry does not exist.  This is not
      // acceptable, so throw an exception.
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_BASE_DOES_NOT_EXIST;
      String message = getMessage(msgID);
      throw new ConfigException(msgID, message);
    }
    // Register add and delete listeners with the trust manager provider base
    // entry.  We don't care about modifications to it.
    baseEntry.registerAddListener(this);
    baseEntry.registerDeleteListener(this);
    // See if the base entry has any children.  If not, then we don't need to do
    // anything else.
    if (! baseEntry.hasChildren())
    {
      return;
    }
    // Iterate through the child entries and process them as trust manager
    // provider configuration entries.
    for (ConfigEntry childEntry : baseEntry.getChildren().values())
    {
      childEntry.registerChangeListener(this);
      StringBuilder unacceptableReason = new StringBuilder();
      if (! configAddIsAcceptable(childEntry, unacceptableReason))
      {
        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
                 MSGID_CONFIG_TRUSTMANAGER_ENTRY_UNACCEPTABLE,
                 childEntry.getDN().toString(), unacceptableReason.toString());
        continue;
      }
      try
      {
        ConfigChangeResult result = applyConfigurationAdd(childEntry);
        if (result.getResultCode() != ResultCode.SUCCESS)
        String className = providerConfig.getJavaImplementationClass();
        try
        {
          StringBuilder buffer = new StringBuilder();
          List<String> resultMessages = result.getMessages();
          if ((resultMessages == null) || (resultMessages.isEmpty()))
          {
            buffer.append(getMessage(MSGID_CONFIG_UNKNOWN_UNACCEPTABLE_REASON));
          }
          else
          {
            Iterator<String> iterator = resultMessages.iterator();
            buffer.append(iterator.next());
            while (iterator.hasNext())
            {
              buffer.append(EOL);
              buffer.append(iterator.next());
            }
          }
          TrustManagerProvider provider =
               loadProvider(className, providerConfig);
          providers.put(providerConfig.dn(), provider);
          DirectoryServer.registerTrustManagerProvider(providerConfig.dn(),
                                                       provider);
        }
        catch (InitializationException ie)
        {
          logError(ErrorLogCategory.CONFIGURATION,
                   ErrorLogSeverity.SEVERE_ERROR,
                   MSGID_CONFIG_TRUSTMANAGER_CANNOT_CREATE_PROVIDER,
                   childEntry.getDN().toString(), buffer.toString());
                   ie.getMessage(), ie.getMessageID());
          continue;
        }
      }
      catch (Exception e)
      {
        logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
                 MSGID_CONFIG_TRUSTMANAGER_CANNOT_CREATE_PROVIDER,
                 childEntry.getDN().toString(), String.valueOf(e));
      }
    }
  }
  /**
   * Indicates whether the configuration entry that will result from a proposed
   * modification is acceptable to this change listener.
   *
   * @param  configEntry         The configuration entry that will result from
   *                             the requested update.
   * @param  unacceptableReason  A buffer to which this method can append a
   *                             human-readable message explaining why the
   *                             proposed change is not acceptable.
   *
   * @return  <CODE>true</CODE> if the proposed entry contains an acceptable
   *          configuration, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  public boolean configChangeIsAcceptable(ConfigEntry configEntry,
                                          StringBuilder unacceptableReason)
  public boolean isConfigurationAddAcceptable(TrustManagerCfg configuration,
                                              List<String> unacceptableReasons)
  {
    // Make sure that the entry has an appropriate objectclass for a trust
    // manager provider.
    if (! configEntry.hasObjectClass(OC_TRUST_MANAGER_PROVIDER))
    if (configuration.isEnabled())
    {
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_INVALID_OBJECTCLASS;
      String message = getMessage(msgID, configEntry.getDN().toString());
      unacceptableReason.append(message);
      return false;
    }
    // Make sure that the entry specifies the provider class name.
    StringConfigAttribute classNameAttr;
    try
    {
      StringConfigAttribute classStub =
           new StringConfigAttribute(ATTR_TRUSTMANAGER_CLASS,
                    getMessage(MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_CLASS),
                    true, false, true);
      classNameAttr = (StringConfigAttribute)
                      configEntry.getConfigAttribute(classStub);
      if (classNameAttr == null)
      // Get the name of the class and make sure we can instantiate it as a
      // trust manager provider.
      String className = configuration.getJavaImplementationClass();
      try
      {
        int    msgID   = MSGID_CONFIG_TRUSTMANAGER_NO_CLASS_NAME;
        String message = getMessage(msgID, configEntry.getDN().toString());
        unacceptableReason.append(message);
        loadProvider(className, null);
      }
      catch (InitializationException ie)
      {
        unacceptableReasons.add(ie.getMessage());
        return false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS_NAME;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    Class providerClass;
    try
    {
      providerClass = DirectoryServer.loadClass(classNameAttr.pendingValue());
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS_NAME;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    try
    {
      TrustManagerProvider provider =
           (TrustManagerProvider) providerClass.newInstance();
    }
    catch(Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS;
      String message = getMessage(msgID, providerClass.getName(),
                                  String.valueOf(configEntry.getDN()),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    // See if this trust manager provider should be enabled.
    BooleanConfigAttribute enabledAttr;
    try
    {
      BooleanConfigAttribute enabledStub =
           new BooleanConfigAttribute(ATTR_TRUSTMANAGER_ENABLED,
                    getMessage(MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_ENABLED),
                               false);
      enabledAttr = (BooleanConfigAttribute)
                    configEntry.getConfigAttribute(enabledStub);
      if (enabledAttr == null)
      {
        int    msgID   = MSGID_CONFIG_TRUSTMANAGER_NO_ENABLED_ATTR;
        String message = getMessage(msgID, configEntry.getDN().toString());
        unacceptableReason.append(message);
        return false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_ENABLED_VALUE;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    // If we've gotten here then the trust manager provider entry appears to be
    // acceptable.
    // If we've gotten here, then it's fine.
    return true;
  }
  /**
   * Attempts to apply a new configuration to this Directory Server component
   * based on the provided changed entry.
   *
   * @param  configEntry  The configuration entry that containing the updated
   *                      configuration for this component.
   *
   * @return  Information about the result of processing the configuration
   *          change.
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationChange(ConfigEntry configEntry)
  public ConfigChangeResult applyConfigurationAdd(TrustManagerCfg configuration)
  {
    DN                configEntryDN       = configEntry.getDN();
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    configuration.addChangeListener(this);
    // Make sure that the entry has an appropriate objectclass for a trust
    if (! configuration.isEnabled())
    {
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    TrustManagerProvider provider = null;
    // Get the name of the class and make sure we can instantiate it as a trust
    // manager provider.
    if (! configEntry.hasObjectClass(OC_TRUST_MANAGER_PROVIDER))
    {
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
      resultCode = ResultCode.UNWILLING_TO_PERFORM;
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Get the corresponding trust manager provider if it is active.
    TrustManagerProvider provider = providers.get(configEntryDN);
    // See if this provider should be enabled or disabled.
    boolean needsEnabled = false;
    BooleanConfigAttribute enabledAttr;
    String className = configuration.getJavaImplementationClass();
    try
    {
      BooleanConfigAttribute enabledStub =
           new BooleanConfigAttribute(ATTR_TRUSTMANAGER_ENABLED,
                    getMessage(MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_ENABLED),
                    false);
      enabledAttr = (BooleanConfigAttribute)
                    configEntry.getConfigAttribute(enabledStub);
      if (enabledAttr == null)
      {
        int msgID = MSGID_CONFIG_TRUSTMANAGER_NO_ENABLED_ATTR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
        resultCode = ResultCode.UNWILLING_TO_PERFORM;
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      if (enabledAttr.activeValue())
      {
        if (provider == null)
        {
          needsEnabled = true;
        }
        else
        {
          // The provider is already active, so no action is required.
        }
      }
      else
      {
        if (provider == null)
        {
          // The provider is already disabled, so no action is required and we
          // can short-circuit out of this processing.
          return new ConfigChangeResult(resultCode, adminActionRequired,
                                        messages);
        }
        else
        {
          // The provider is active, so it needs to be disabled.  Do this and
          // return that we were successful.
          providers.remove(configEntryDN);
          DirectoryServer.deregisterTrustManagerProvider(configEntryDN);
          provider.finalizeTrustManagerProvider();
          return new ConfigChangeResult(resultCode, adminActionRequired,
                                        messages);
        }
      }
      provider = loadProvider(className, configuration);
    }
    catch (Exception e)
    catch (InitializationException ie)
    {
      if (debugEnabled())
      if (resultCode == ResultCode.SUCCESS)
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_ENABLED_VALUE;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Make sure that the entry specifies the provider class name.  If it has
    // changed, then we will not try to dynamically apply it.
    String className;
    try
    {
      StringConfigAttribute classStub =
           new StringConfigAttribute(ATTR_TRUSTMANAGER_CLASS,
                    getMessage(MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_CLASS),
                    true, false, true);
      StringConfigAttribute classNameAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
      if (classNameAttr == null)
      {
        int msgID = MSGID_CONFIG_TRUSTMANAGER_NO_CLASS_NAME;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
        resultCode = ResultCode.OBJECTCLASS_VIOLATION;
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      className = classNameAttr.pendingValue();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS_NAME;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    boolean classChanged = false;
    String  oldClassName = null;
    if (provider != null)
    {
      oldClassName = provider.getClass().getName();
      classChanged = (! className.equals(oldClassName));
    }
    if (classChanged)
    {
      // This will not be applied dynamically.  Add a message to the response
      // and indicate that admin action is required.
      adminActionRequired = true;
      messages.add(getMessage(MSGID_CONFIG_TRUSTMANAGER_CLASS_ACTION_REQUIRED,
                              String.valueOf(oldClassName),
                              String.valueOf(className),
                              String.valueOf(configEntryDN)));
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    if (needsEnabled)
    {
      try
      {
        Class providerClass = DirectoryServer.loadClass(className);
        provider = (TrustManagerProvider) providerClass.newInstance();
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS;
        messages.add(getMessage(msgID, className,
                                String.valueOf(configEntryDN),
                                String.valueOf(e)));
        resultCode = DirectoryServer.getServerErrorResultCode();
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      try
      {
        provider.initializeTrustManagerProvider(configEntry);
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        int msgID = MSGID_CONFIG_TRUSTMANAGER_INITIALIZATION_FAILED;
        messages.add(getMessage(msgID, className,
                                String.valueOf(configEntryDN),
                                String.valueOf(e)));
        resultCode = DirectoryServer.getServerErrorResultCode();
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      providers.put(configEntryDN, provider);
      DirectoryServer.registerTrustManagerProvider(configEntryDN, provider);
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
      messages.add(ie.getMessage());
    }
    if (resultCode == ResultCode.SUCCESS)
    {
      providers.put(configuration.dn(), provider);
      DirectoryServer.registerTrustManagerProvider(configuration.dn(),
                                                   provider);
    }
    // If we've gotten here, then there haven't been any changes to anything
    // that we care about.
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
  /**
   * Indicates whether the configuration entry that will result from a proposed
   * add is acceptable to this add listener.
   *
   * @param  configEntry         The configuration entry that will result from
   *                             the requested add.
   * @param  unacceptableReason  A buffer to which this method can append a
   *                             human-readable message explaining why the
   *                             proposed entry is not acceptable.
   *
   * @return  <CODE>true</CODE> if the proposed entry contains an acceptable
   *          configuration, or <CODE>false</CODE> if it does not.
   * {@inheritDoc}
   */
  public boolean configAddIsAcceptable(ConfigEntry configEntry,
                                       StringBuilder unacceptableReason)
  public boolean isConfigurationDeleteAcceptable(TrustManagerCfg configuration,
                      List<String> unacceptableReasons)
  {
    // Make sure that no entry already exists with the specified DN.
    DN configEntryDN = configEntry.getDN();
    if (providers.containsKey(configEntryDN))
    {
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_EXISTS;
      String message = getMessage(msgID, String.valueOf(configEntryDN));
      unacceptableReason.append(message);
      return false;
    }
    // Make sure that the entry has an appropriate objectclass for a trust
    // manager provider.
    if (! configEntry.hasObjectClass(OC_TRUST_MANAGER_PROVIDER))
    {
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_INVALID_OBJECTCLASS;
      String message = getMessage(msgID, configEntry.getDN().toString());
      unacceptableReason.append(message);
      return false;
    }
    // Make sure that the entry specifies the trust manager provider class.
    StringConfigAttribute classNameAttr;
    try
    {
      StringConfigAttribute classStub =
           new StringConfigAttribute(ATTR_TRUSTMANAGER_CLASS,
                    getMessage(MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_CLASS),
                    true, false, true);
      classNameAttr = (StringConfigAttribute)
                      configEntry.getConfigAttribute(classStub);
      if (classNameAttr == null)
      {
        int msgID = MSGID_CONFIG_TRUSTMANAGER_NO_CLASS_NAME;
        String message = getMessage(msgID, configEntry.getDN().toString());
        unacceptableReason.append(message);
        return false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS_NAME;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    Class providerClass;
    try
    {
      providerClass = DirectoryServer.loadClass(classNameAttr.pendingValue());
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS_NAME;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    TrustManagerProvider provider;
    try
    {
      provider = (TrustManagerProvider) providerClass.newInstance();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS;
      String message = getMessage(msgID, providerClass.getName(),
                                  String.valueOf(configEntryDN),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    // See if this provider should be enabled.
    BooleanConfigAttribute enabledAttr;
    try
    {
      BooleanConfigAttribute enabledStub =
           new BooleanConfigAttribute(ATTR_TRUSTMANAGER_ENABLED,
                    getMessage(MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_ENABLED),
                               false);
      enabledAttr = (BooleanConfigAttribute)
                    configEntry.getConfigAttribute(enabledStub);
      if (enabledAttr == null)
      {
        int msgID = MSGID_CONFIG_TRUSTMANAGER_NO_ENABLED_ATTR;
        String message = getMessage(msgID, configEntry.getDN().toString());
        unacceptableReason.append(message);
        return false;
      }
      else if (! enabledAttr.pendingValue())
      {
        // The trust manager provider is not enabled, so we don't need to do any
        // further validation.
        return true;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_ENABLED_VALUE;
      String message = getMessage(msgID, configEntry.getDN().toString(),
                                  String.valueOf(e));
      unacceptableReason.append(message);
      return false;
    }
    // If the provider is a configurable component, then make sure that its
    // configuration is valid.
    if (provider instanceof ConfigurableComponent)
    {
      ConfigurableComponent cc = (ConfigurableComponent) provider;
      LinkedList<String> errorMessages = new LinkedList<String>();
      if (! cc.hasAcceptableConfiguration(configEntry, errorMessages))
      {
        if (errorMessages.isEmpty())
        {
          int msgID = MSGID_CONFIG_TRUSTMANAGER_UNACCEPTABLE_CONFIG;
          unacceptableReason.append(getMessage(msgID,
                                               String.valueOf(configEntryDN)));
        }
        else
        {
          Iterator<String> iterator = errorMessages.iterator();
          unacceptableReason.append(iterator.next());
          while (iterator.hasNext())
          {
            unacceptableReason.append("  ");
            unacceptableReason.append(iterator.next());
          }
        }
        return false;
      }
    }
    // If we've gotten here then the provider entry appears to be acceptable.
    // FIXME -- We should try to perform some check to determine whether the
    // provider is in use.
    return true;
  }
  /**
   * Attempts to apply a new configuration based on the provided added entry.
   *
   * @param  configEntry  The new configuration entry that contains the
   *                      configuration to apply.
   *
   * @return  Information about the result of processing the configuration
   *          change.
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationAdd(ConfigEntry configEntry)
  public ConfigChangeResult applyConfigurationDelete(
                                 TrustManagerCfg configuration)
  {
    DN                configEntryDN       = configEntry.getDN();
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    DirectoryServer.deregisterTrustManagerProvider(configuration.dn());
    // Make sure that the entry has an appropriate objectclass for a trust
    // manager provider.
    if (! configEntry.hasObjectClass(OC_TRUST_MANAGER_PROVIDER))
    {
      int    msgID   = MSGID_CONFIG_TRUSTMANAGER_INVALID_OBJECTCLASS;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
      resultCode = ResultCode.UNWILLING_TO_PERFORM;
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // See if this provider should be enabled or disabled.
    BooleanConfigAttribute enabledAttr;
    try
    {
      BooleanConfigAttribute enabledStub =
           new BooleanConfigAttribute(ATTR_TRUSTMANAGER_ENABLED,
                    getMessage(MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_ENABLED),
                               false);
      enabledAttr = (BooleanConfigAttribute)
                    configEntry.getConfigAttribute(enabledStub);
      if (enabledAttr == null)
      {
        // The attribute doesn't exist, so it will be disabled by default.
        int msgID = MSGID_CONFIG_TRUSTMANAGER_NO_ENABLED_ATTR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
        resultCode = ResultCode.SUCCESS;
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      else if (! enabledAttr.activeValue())
      {
        // It is explicitly configured as disabled, so we don't need to do
        // anything.
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_ENABLED_VALUE;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Make sure that the entry specifies the provider class name.
    String className;
    try
    {
      StringConfigAttribute classStub =
           new StringConfigAttribute(ATTR_TRUSTMANAGER_CLASS,
                    getMessage(MSGID_CONFIG_TRUSTMANAGER_DESCRIPTION_CLASS),
                    true, false, true);
      StringConfigAttribute classNameAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
      if (classNameAttr == null)
      {
        int msgID = MSGID_CONFIG_TRUSTMANAGER_NO_CLASS_NAME;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
        resultCode = ResultCode.OBJECTCLASS_VIOLATION;
        return new ConfigChangeResult(resultCode, adminActionRequired,
                                      messages);
      }
      className = classNameAttr.pendingValue();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS_NAME;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Load and initialize the provider class, and register it with the
    // Directory Server.
    TrustManagerProvider provider;
    try
    {
      Class providerClass = DirectoryServer.loadClass(className);
      provider = (TrustManagerProvider) providerClass.newInstance();
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INVALID_CLASS;
      messages.add(getMessage(msgID, className, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    try
    {
      provider.initializeTrustManagerProvider(configEntry);
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INITIALIZATION_FAILED;
      messages.add(getMessage(msgID, className, String.valueOf(configEntryDN),
                              String.valueOf(e)));
      resultCode = DirectoryServer.getServerErrorResultCode();
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    providers.put(configEntryDN, provider);
    DirectoryServer.registerTrustManagerProvider(configEntryDN, provider);
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
  /**
   * Indicates whether it is acceptable to remove the provided configuration
   * entry.
   *
   * @param  configEntry         The configuration entry that will be removed
   *                             from the configuration.
   * @param  unacceptableReason  A buffer to which this method can append a
   *                             human-readable message explaining why the
   *                             proposed delete is not acceptable.
   *
   * @return  <CODE>true</CODE> if the proposed entry may be removed from the
   *          configuration, or <CODE>false</CODE> if not.
   */
  public boolean configDeleteIsAcceptable(ConfigEntry configEntry,
                                          StringBuilder unacceptableReason)
  {
    // A delete should always be acceptable, so just return true.
    return true;
  }
  /**
   * Attempts to apply a new configuration based on the provided deleted entry.
   *
   * @param  configEntry  The new configuration entry that has been deleted.
   *
   * @return  Information about the result of processing the configuration
   *          change.
   */
  public ConfigChangeResult applyConfigurationDelete(ConfigEntry configEntry)
  {
    DN         configEntryDN       = configEntry.getDN();
    ResultCode resultCode          = ResultCode.SUCCESS;
    boolean    adminActionRequired = false;
    // See if the entry is registered as a trust manager provider.  If so,
    // deregister it and stop the provider.
    TrustManagerProvider provider = providers.remove(configEntryDN);
    TrustManagerProvider provider = providers.remove(configuration.dn());
    if (provider != null)
    {
      DirectoryServer.deregisterTrustManagerProvider(configEntryDN);
      provider.finalizeTrustManagerProvider();
    }
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
    return new ConfigChangeResult(resultCode, adminActionRequired);
  /**
   * {@inheritDoc}
   */
  public boolean isConfigurationChangeAcceptable(TrustManagerCfg configuration,
                      List<String> unacceptableReasons)
  {
    if (configuration.isEnabled())
    {
      // Get the name of the class and make sure we can instantiate it as a
      // trust manager provider.
      String className = configuration.getJavaImplementationClass();
      try
      {
        loadProvider(className, null);
      }
      catch (InitializationException ie)
      {
        unacceptableReasons.add(ie.getMessage());
        return false;
      }
    }
    // If we've gotten here, then it's fine.
    return true;
  }
  /**
   * {@inheritDoc}
   */
  public ConfigChangeResult applyConfigurationChange(
                                 TrustManagerCfg configuration)
  {
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    // Get the existing provider if it's already enabled.
    TrustManagerProvider existingProvider = providers.get(configuration.dn());
    // If the new configuration has the provider disabled, then disable it if it
    // is enabled, or do nothing if it's already disabled.
    if (! configuration.isEnabled())
    {
      if (existingProvider != null)
      {
        DirectoryServer.deregisterTrustManagerProvider(configuration.dn());
        TrustManagerProvider provider = providers.remove(configuration.dn());
        if (provider != null)
        {
          provider.finalizeTrustManagerProvider();
        }
      }
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    // Get the class for the trust manager provider.  If the provider is already
    // enabled, then we shouldn't do anything with it although if the class has
    // changed then we'll at least need to indicate that administrative action
    // is required.  If the provider is disabled, then instantiate the class and
    // initialize and register it as a trust manager provider.
    String className = configuration.getJavaImplementationClass();
    if (existingProvider != null)
    {
      if (! className.equals(existingProvider.getClass().getName()))
      {
        adminActionRequired = true;
      }
      return new ConfigChangeResult(resultCode, adminActionRequired, messages);
    }
    TrustManagerProvider provider = null;
    try
    {
      provider = loadProvider(className, configuration);
    }
    catch (InitializationException ie)
    {
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
      }
      messages.add(ie.getMessage());
    }
    if (resultCode == ResultCode.SUCCESS)
    {
      providers.put(configuration.dn(), provider);
      DirectoryServer.registerTrustManagerProvider(configuration.dn(),
                                                   provider);
    }
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
  /**
   * Loads the specified class, instantiates it as a trust manager provider, and
   * optionally initializes that instance.
   *
   * @param  className      The fully-qualified name of the trust manager
   *                        provider class to load, instantiate, and initialize.
   * @param  configuration  The configuration to use to initialize the trust
   *                        manager provider, or {@code null} if the provider
   *                        should not be initialized.
   *
   * @return  The possibly initialized trust manager provider.
   *
   * @throws  InitializationException  If a problem occurred while attempting to
   *                                   initialize the trust manager provider.
   */
  private TrustManagerProvider loadProvider(String className,
                                            TrustManagerCfg configuration)
          throws InitializationException
  {
    try
    {
      TrustManagerCfgDefn definition = TrustManagerCfgDefn.getInstance();
      ClassPropertyDefinition propertyDefinition =
           definition.getJavaImplementationClassPropertyDefinition();
      Class<? extends TrustManagerProvider> providerClass =
           propertyDefinition.loadClass(className, TrustManagerProvider.class);
      TrustManagerProvider provider = providerClass.newInstance();
      if (configuration != null)
      {
        Method method =
             provider.getClass().getMethod("initializeTrustManagerProvider",
                  configuration.definition().getServerConfigurationClass());
        method.invoke(provider, configuration);
      }
      return provider;
    }
    catch (Exception e)
    {
      int msgID = MSGID_CONFIG_TRUSTMANAGER_INITIALIZATION_FAILED;
      String message = getMessage(msgID, className,
                                  String.valueOf(configuration.dn()),
                                  stackTraceToSingleLineString(e));
      throw new InitializationException(msgID, message, e);
    }
  }
}
opends/src/server/org/opends/server/extensions/BlindTrustManagerProvider.java
@@ -32,8 +32,8 @@
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.opends.server.admin.std.server.TrustManagerCfg;
import org.opends.server.api.TrustManagerProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
@@ -50,7 +50,7 @@
 * trustworthy.
 */
public class BlindTrustManagerProvider
       extends TrustManagerProvider
       extends TrustManagerProvider<TrustManagerCfg>
       implements X509TrustManager
{
@@ -69,21 +69,10 @@
  /**
   * Initializes this trust manager provider based on the information in the
   * provided configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the information
   *                      to use to initialize this trust manager provider.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in the
   *                           process of performing the initialization as a
   *                           result of the server configuration.
   *
   * @throws  InitializationException  If a problem occurs during initialization
   *                                   that is not related to the server
   *                                   configuration.
   * {@inheritDoc}
   */
  public void initializeTrustManagerProvider(ConfigEntry configEntry)
  @Override()
  public void initializeTrustManagerProvider(TrustManagerCfg configuration)
         throws ConfigException, InitializationException
  {
    // No implementation is required.
@@ -95,6 +84,7 @@
   * Performs any finalization that may be necessary for this trust manager
   * provider.
   */
  @Override()
  public void finalizeTrustManagerProvider()
  {
    // No implementation is required.
@@ -103,15 +93,9 @@
  /**
   * Retrieves a <CODE>TrustManager</CODE> object that may be used for
   * interactions requiring access to a trust manager.
   *
   * @return  A <CODE>TrustManager</CODE> object that may be used for
   *          interactions requiring access to a trust manager.
   *
   * @throws  DirectoryException  If a problem occurs while attempting to obtain
   *                              the set of trust managers.
   * {@inheritDoc}
   */
  @Override()
  public TrustManager[] getTrustManagers()
         throws DirectoryException
  {
opends/src/server/org/opends/server/extensions/FileBasedKeyManagerProvider.java
@@ -36,19 +36,14 @@
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.FileBasedKeyManagerCfg;
import org.opends.server.api.ConfigurableComponent;
import org.opends.server.api.KeyManagerProvider;
import org.opends.server.config.ConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.config.StringConfigAttribute;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DirectoryException;
@@ -72,7 +67,7 @@
 */
public class FileBasedKeyManagerProvider
       extends KeyManagerProvider<FileBasedKeyManagerCfg>
       implements ConfigurableComponent
       implements ConfigurationChangeListener<FileBasedKeyManagerCfg>
{
  /**
   * The tracer object for the debug logger.
@@ -81,25 +76,18 @@
  // The DN of the configuration entry for this key manager provider.
  private DN configEntryDN;
  // The PIN needed to access the keystore.
  private char[] keyStorePIN;
  // The configuration for this key manager provider.
  private FileBasedKeyManagerCfg currentConfig;
  // The path to the key store backing file.
  private String keyStoreFile;
  // The name of the environment variable containing the keystore PIN.
  private String keyStorePINEnVar;
  // The path to the file containing the keystore PIN.
  private String keyStorePINFile;
  // The name of the Java property containing the keystore PIN.
  private String keyStorePINProperty;
  // The key store type to use.
  private String keyStoreType;
@@ -118,388 +106,18 @@
  /**
   * Initializes this key manager provider based on the information in the
   * provided configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the information
   *                      to use to initialize this key manager provider.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in the
   *                           process of performing the initialization as a
   *                           result of the server configuration.
   *
   * @throws  InitializationException  If a problem occurs during initialization
   *                                   that is not related to the server
   *                                   configuration.
   */
  public void initializeKeyManagerProvider(ConfigEntry configEntry)
         throws ConfigException, InitializationException
  {
    // Store the DN of the configuration entry.
    configEntryDN = configEntry.getDN();
    // Get the path to the key store file.
    int msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_FILE;
    StringConfigAttribute fileStub =
         new StringConfigAttribute(ATTR_KEYSTORE_FILE, getMessage(msgID), true,
                                   false, false);
    try
    {
      StringConfigAttribute fileAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(fileStub);
      if ((fileAttr == null) ||
          ((keyStoreFile = fileAttr.activeValue()) == null))
      {
        msgID = MSGID_FILE_KEYMANAGER_NO_FILE_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN));
        throw new ConfigException(msgID, message);
      }
      File f = getFileForPath(keyStoreFile);
      if (! (f.exists() && f.isFile()))
      {
        msgID = MSGID_FILE_KEYMANAGER_NO_SUCH_FILE;
        String message = getMessage(msgID, String.valueOf(keyStoreFile),
                                    String.valueOf(configEntryDN));
        throw new InitializationException(msgID, message);
      }
    }
    catch (ConfigException ce)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }
      throw ce;
    }
    catch (InitializationException ie)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ie);
      }
      throw ie;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_FILE;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  getExceptionMessage(e));
      throw new InitializationException(msgID, message, e);
    }
    // Get the keystore type.  If none is specified, then use the default type.
    keyStoreType = KeyStore.getDefaultType();
    msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_TYPE;
    StringConfigAttribute typeStub =
         new StringConfigAttribute(ATTR_KEYSTORE_TYPE, getMessage(msgID),
                                   false, false, false);
    try
    {
      StringConfigAttribute typeAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(typeStub);
      if (typeAttr != null)
      {
        // A keystore type was specified, so make sure it is valid.
        String typeStr = typeAttr.activeValue();
        try
        {
          KeyStore.getInstance(typeStr);
          keyStoreType = typeStr;
        }
        catch (KeyStoreException kse)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, kse);
          }
          msgID = MSGID_FILE_KEYMANAGER_INVALID_TYPE;
          String message = getMessage(msgID, String.valueOf(typeStr),
                                      String.valueOf(configEntryDN),
                                      getExceptionMessage(kse));
          throw new InitializationException(msgID, message);
        }
      }
    }
    catch (InitializationException ie)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ie);
      }
      throw ie;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_TYPE;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  getExceptionMessage(e));
      throw new InitializationException(msgID, message, e);
    }
    // Get the PIN needed to access the contents of the keystore file.  We will
    // offer several places to look for the PIN, and we will do so in the
    // following order:
    // - In a specified Java property
    // - In a specified environment variable
    // - In a specified file on the server filesystem.
    // - As the value of a configuration attribute.
    // In any case, the PIN must be in the clear.
    keyStorePIN         = null;
    keyStorePINEnVar    = null;
    keyStorePINFile     = null;
    keyStorePINProperty = null;
pinSelection:
    {
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_PROPERTY_NOT_SET;
            String message = getMessage(msgID, String.valueOf(propertyName),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
          }
          else
          {
            keyStorePIN         = pinStr.toCharArray();
            keyStorePINProperty = propertyName;
            break pinSelection;
          }
        }
      }
      catch (InitializationException ie)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_ENVAR, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_ENVAR_NOT_SET;
            String message = getMessage(msgID, String.valueOf(enVarName),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
          }
          else
          {
            keyStorePIN      = pinStr.toCharArray();
            keyStorePINEnVar = enVarName;
            break pinSelection;
          }
        }
      }
      catch (InitializationException ie)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_FILE, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          if (! pinFile.exists())
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_NO_SUCH_FILE;
            String message = getMessage(msgID, String.valueOf(fileName),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
          }
          else
          {
            String pinStr;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_CANNOT_READ;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN),
                                          getExceptionMessage(ioe));
              throw new InitializationException(msgID, message, ioe);
            }
            if (pinStr == null)
            {
              msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_EMPTY;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN));
              throw new InitializationException(msgID, message);
            }
            else
            {
              keyStorePIN     = pinStr.toCharArray();
              keyStorePINFile = fileName;
              break pinSelection;
            }
          }
        }
      }
      catch (InitializationException ie)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_FILE;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        {
          keyStorePIN = pinAttr.activeValue().toCharArray();
          break pinSelection;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
    }
    if (keyStorePIN == null)
    {
      msgID = MSGID_FILE_KEYMANAGER_NO_PIN;
      String message = getMessage(msgID, String.valueOf(configEntryDN));
      throw new ConfigException(msgID, message);
    }
    DirectoryServer.registerConfigurableComponent(this);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void initializeKeyManagerProvider(
      FileBasedKeyManagerCfg configuration)
      throws ConfigException, InitializationException {
    // Store the DN of the configuration entry.
    // Store the DN of the configuration entry and register as a change
    // listener.
    currentConfig = configuration;
    configEntryDN = configuration.dn();
    configuration.addFileBasedChangeListener(this);
    // Get the path to the key store file.
    keyStoreFile = configuration.getKeyStoreFile();
@@ -557,9 +175,6 @@
    //
    // In any case, the PIN must be in the clear.
    keyStorePIN = null;
    keyStorePINEnVar = null;
    keyStorePINFile = null;
    keyStorePINProperty = null;
    if (configuration.getKeyStorePinProperty() != null) {
      String propertyName = configuration.getKeyStorePinProperty();
@@ -573,7 +188,6 @@
      }
      keyStorePIN = pinStr.toCharArray();
      keyStorePINProperty = propertyName;
    } else if (configuration.getKeyStorePinEnvironmentVariable() != null) {
      String enVarName = configuration
          .getKeyStorePinEnvironmentVariable();
@@ -587,7 +201,6 @@
      }
      keyStorePIN = pinStr.toCharArray();
      keyStorePINEnVar = enVarName;
    } else if (configuration.getKeyStorePinFile() != null) {
      String fileName = configuration.getKeyStorePinFile();
      File pinFile = getFileForPath(fileName);
@@ -620,7 +233,6 @@
      }
      keyStorePIN = pinStr.toCharArray();
      keyStorePINFile = fileName;
    } else if (configuration.getKeyStorePin() != null) {
      keyStorePIN = configuration.getKeyStorePin().toCharArray();
    } else {
@@ -630,8 +242,6 @@
          .valueOf(configEntryDN));
      throw new ConfigException(msgID, message);
    }
    DirectoryServer.registerConfigurableComponent(this);
  }
@@ -642,7 +252,7 @@
   */
  public void finalizeKeyManagerProvider()
  {
    DirectoryServer.deregisterConfigurableComponent(this);
    currentConfig.removeFileBasedChangeListener(this);
  }
@@ -709,487 +319,186 @@
  /**
   * 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.
   * {@inheritDoc}
   */
  public DN getConfigurableComponentEntryDN()
  public boolean isConfigurationChangeAcceptable(
                      FileBasedKeyManagerCfg configuration,
                      List<String> unacceptableReasons)
  {
    return configEntryDN;
  }
    boolean configAcceptable = true;
  /**
   * 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_FILE_KEYMANAGER_DESCRIPTION_FILE;
    StringConfigAttribute fileAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_FILE, getMessage(msgID), true,
                                   false, false, keyStoreFile);
    attrList.add(fileAttr);
    msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_TYPE;
    StringConfigAttribute typeAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_TYPE, getMessage(msgID), true,
                                   false, false, keyStoreType);
    attrList.add(typeAttr);
    msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_PROPERTY;
    StringConfigAttribute pinPropertyAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_PIN_PROPERTY,
                                   getMessage(msgID), false, false, false,
                                   keyStorePINProperty);
    attrList.add(pinPropertyAttr);
    msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_ENVAR;
    StringConfigAttribute pinEnvVarAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_PIN_ENVAR,
                                   getMessage(msgID), false, false, false,
                                   keyStorePINEnVar);
    attrList.add(pinEnvVarAttr);
    msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_FILE;
    StringConfigAttribute pinFileAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_PIN_FILE,
                                   getMessage(msgID), false, false, false,
                                   keyStorePINFile);
    attrList.add(pinFileAttr);
    String pinString;
    if ((keyStorePINProperty == null) && (keyStorePINEnVar == null) &&
        (keyStorePINFile == null))
    // Get the path to the key store file.
    String newKeyStoreFile = configuration.getKeyStoreFile();
    try
    {
      pinString = new String(keyStorePIN);
      File f = getFileForPath(newKeyStoreFile);
      if (!(f.exists() && f.isFile()))
      {
        int msgID = MSGID_FILE_KEYMANAGER_NO_SUCH_FILE;
        unacceptableReasons.add(getMessage(msgID,
                                           String.valueOf(newKeyStoreFile),
                                           String.valueOf(configEntryDN)));
        configAcceptable = false;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_FILE;
      unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN),
                                         getExceptionMessage(e)));
      configAcceptable = false;
    }
    // Get the keystore type. If none is specified, then use the default type.
    if (configuration.getKeyStoreType() != null)
    {
      try
      {
        KeyStore.getInstance(configuration.getKeyStoreType());
      }
      catch (KeyStoreException kse)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, kse);
        }
        int msgID = MSGID_FILE_KEYMANAGER_INVALID_TYPE;
        unacceptableReasons.add(getMessage(msgID,
             String.valueOf(configuration.getKeyStoreType()),
             String.valueOf(configEntryDN), getExceptionMessage(kse)));
        configAcceptable = false;
      }
    }
    // Get the PIN needed to access the contents of the keystore file.
    //
    // We will offer several places to look for the PIN, and we will
    // do so in the following order:
    //
    // - In a specified Java property
    // - In a specified environment variable
    // - In a specified file on the server filesystem.
    // - As the value of a configuration attribute.
    //
    // In any case, the PIN must be in the clear.
    if (configuration.getKeyStorePinProperty() != null)
    {
      String propertyName = configuration.getKeyStorePinProperty();
      String pinStr = System.getProperty(propertyName);
      if (pinStr == null)
      {
        int msgID = MSGID_FILE_KEYMANAGER_PIN_PROPERTY_NOT_SET;
        unacceptableReasons.add(getMessage(msgID, String.valueOf(propertyName),
                                           String.valueOf(configEntryDN)));
        configAcceptable = false;
      }
    }
    else if (configuration.getKeyStorePinEnvironmentVariable() != null)
    {
      String enVarName = configuration.getKeyStorePinEnvironmentVariable();
      String pinStr    = System.getenv(enVarName);
      if (pinStr == null)
      {
        int msgID = MSGID_FILE_KEYMANAGER_PIN_ENVAR_NOT_SET;
        unacceptableReasons.add(getMessage(msgID, String.valueOf(enVarName),
                                           String.valueOf(configEntryDN)));
        configAcceptable = false;
      }
    }
    else if (configuration.getKeyStorePinFile() != null)
    {
      String fileName = configuration.getKeyStorePinFile();
      File   pinFile  = getFileForPath(fileName);
      if (!pinFile.exists())
      {
        int msgID = MSGID_FILE_KEYMANAGER_PIN_NO_SUCH_FILE;
        unacceptableReasons.add(getMessage(msgID, String.valueOf(fileName),
                                           String.valueOf(configEntryDN)));
        configAcceptable = false;
      }
      else
      {
        String pinStr = null;
        BufferedReader br = null;
        try {
          br = new BufferedReader(new FileReader(pinFile));
          pinStr = br.readLine();
        }
        catch (IOException ioe)
        {
          int msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_CANNOT_READ;
          unacceptableReasons.add(getMessage(msgID, String.valueOf(fileName),
                                             String.valueOf(configEntryDN),
                                             getExceptionMessage(ioe)));
          configAcceptable = false;
        }
        finally
        {
          try
          {
            br.close();
          } catch (Exception e) {}
        }
        if (pinStr == null)
        {
          int msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_EMPTY;
          unacceptableReasons.add(getMessage(msgID, String.valueOf(fileName),
                                             String.valueOf(configEntryDN)));
          configAcceptable = false;
        }
      }
    }
    else if (configuration.getKeyStorePin() != null)
    {
      configuration.getKeyStorePin().toCharArray();
    }
    else
    {
      pinString = null;
      // Pin wasn't defined anywhere.
      int msgID = MSGID_FILE_KEYMANAGER_NO_PIN;
      unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN)));
      configAcceptable = false;
    }
    msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_ATTR;
    StringConfigAttribute pinAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_PIN, getMessage(msgID), false,
                                   false, false, pinString);
    attrList.add(pinAttr);
    return attrList;
    return configAcceptable;
  }
  /**
   * 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.
   * {@inheritDoc}
   */
  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
                                            List<String> unacceptableReasons)
  {
    DN configEntryDN = configEntry.getDN();
    // Make sure that a keystore file was provided.
    int msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_FILE;
    StringConfigAttribute fileStub =
         new StringConfigAttribute(ATTR_KEYSTORE_FILE, getMessage(msgID), true,
                                   false, false);
    try
    {
      String newKeyStoreFile = null;
      StringConfigAttribute fileAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(fileStub);
      if ((fileAttr == null) ||
          ((newKeyStoreFile = fileAttr.activeValue()) == null))
      {
        msgID = MSGID_FILE_KEYMANAGER_NO_FILE_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN));
        throw new ConfigException(msgID, message);
      }
      File f = getFileForPath(newKeyStoreFile);
      if (! (f.exists() && f.isFile()))
      {
        msgID = MSGID_FILE_KEYMANAGER_NO_SUCH_FILE;
        String message = getMessage(msgID, String.valueOf(newKeyStoreFile),
                                    String.valueOf(configEntryDN));
        unacceptableReasons.add(message);
        return false;
      }
    }
    catch (ConfigException ce)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }
      unacceptableReasons.add(ce.getMessage());
      return false;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_FILE;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  getExceptionMessage(e));
      unacceptableReasons.add(message);
      return false;
    }
    // See if a keystore type was provided.  It is optional, but if one was
    // provided, then it must be a valid type.
    msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_TYPE;
    StringConfigAttribute typeStub =
         new StringConfigAttribute(ATTR_KEYSTORE_TYPE, getMessage(msgID),
                                   false, false, false);
    try
    {
      StringConfigAttribute typeAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(typeStub);
      if (typeAttr != null)
      {
        // A keystore type was specified, so make sure it is valid.
        String typeStr = typeAttr.activeValue();
        try
        {
          KeyStore.getInstance(typeStr);
        }
        catch (KeyStoreException kse)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, kse);
          }
          msgID = MSGID_FILE_KEYMANAGER_INVALID_TYPE;
          String message = getMessage(msgID, String.valueOf(typeStr),
                                      String.valueOf(configEntryDN),
                                      getExceptionMessage(kse));
          unacceptableReasons.add(message);
          return false;
        }
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_TYPE;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  getExceptionMessage(e));
      unacceptableReasons.add(message);
      return false;
    }
    // Make sure that there is some way to determine the PIN.  Look for the PIN
    // in a property, environment variable, file, or configuration attribute, in
    // that order.
    char[] keyStorePIN = null;
pinSelection:
    {
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_PROPERTY_NOT_SET;
            String message = getMessage(msgID, String.valueOf(propertyName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            keyStorePIN = pinStr.toCharArray();
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_ENVAR, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_ENVAR_NOT_SET;
            String message = getMessage(msgID, String.valueOf(enVarName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            keyStorePIN = pinStr.toCharArray();
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_FILE, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          if (! pinFile.exists())
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_NO_SUCH_FILE;
            String message = getMessage(msgID, String.valueOf(fileName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            String pinStr;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_CANNOT_READ;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN),
                                          getExceptionMessage(ioe));
              unacceptableReasons.add(message);
              return false;
            }
            if (pinStr == null)
            {
              msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_EMPTY;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN));
              unacceptableReasons.add(message);
              return false;
            }
            else
            {
              keyStorePIN = pinStr.toCharArray();
              break pinSelection;
            }
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_FILE;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        {
          keyStorePIN = pinAttr.pendingValue().toCharArray();
          break pinSelection;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
    }
    if (keyStorePIN == null)
    {
      msgID = MSGID_FILE_KEYMANAGER_NO_PIN;
      String message = getMessage(msgID, String.valueOf(configEntryDN));
      unacceptableReasons.add(message);
      return false;
    }
    // If we've gotten here, then everything looks 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)
  public ConfigChangeResult applyConfigurationChange(
                                 FileBasedKeyManagerCfg configuration)
  {
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    // Make sure that a keystore file was provided.
    String newKeyStoreFile = null;
    int msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_FILE;
    StringConfigAttribute fileStub =
         new StringConfigAttribute(ATTR_KEYSTORE_FILE, getMessage(msgID), true,
                                   false, false);
    // Get the path to the key store file.
    String newKeyStoreFile = configuration.getKeyStoreFile();
    try
    {
      StringConfigAttribute fileAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(fileStub);
      if ((fileAttr == null) ||
          ((newKeyStoreFile = fileAttr.activeValue()) == null))
      {
        msgID = MSGID_FILE_KEYMANAGER_NO_FILE_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN));
        throw new ConfigException(msgID, message);
      }
      File f = getFileForPath(newKeyStoreFile);
      if (! (f.exists() && f.isFile()))
      if (!(f.exists() && f.isFile()))
      {
        msgID = MSGID_FILE_KEYMANAGER_NO_SUCH_FILE;
        resultCode = DirectoryServer.getServerErrorResultCode();
        int msgID = MSGID_FILE_KEYMANAGER_NO_SUCH_FILE;
        messages.add(getMessage(msgID, String.valueOf(newKeyStoreFile),
                                String.valueOf(configEntryDN)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = ResultCode.CONSTRAINT_VIOLATION;
        }
      }
    }
    catch (ConfigException ce)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = ResultCode.CONSTRAINT_VIOLATION;
      }
    }
    catch (Exception e)
@@ -1199,370 +508,160 @@
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_FILE;
      resultCode = DirectoryServer.getServerErrorResultCode();
      int msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_FILE;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              getExceptionMessage(e)));
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
      }
    }
    // See if a keystore type was provided.  It is optional, but if one was
    // provided, then it must be a valid type.
    // Get the keystore type. If none is specified, then use the default type.
    String newKeyStoreType = KeyStore.getDefaultType();
    msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_TYPE;
    StringConfigAttribute typeStub =
         new StringConfigAttribute(ATTR_KEYSTORE_TYPE, getMessage(msgID),
                                   false, false, false);
    try
    if (configuration.getKeyStoreType() != null)
    {
      StringConfigAttribute typeAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(typeStub);
      if (typeAttr != null)
      try
      {
        // A keystore type was specified, so make sure it is valid.
        newKeyStoreType = typeAttr.activeValue();
        try
        KeyStore.getInstance(configuration.getKeyStoreType());
        newKeyStoreType = configuration.getKeyStoreType();
      }
      catch (KeyStoreException kse)
      {
        if (debugEnabled())
        {
          KeyStore.getInstance(newKeyStoreType);
          TRACER.debugCaught(DebugLogLevel.ERROR, kse);
        }
        catch (KeyStoreException kse)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, kse);
          }
          msgID = MSGID_FILE_KEYMANAGER_INVALID_TYPE;
          messages.add(getMessage(msgID, String.valueOf(newKeyStoreType),
                                  String.valueOf(configEntryDN),
                                  getExceptionMessage(kse)));
        resultCode = DirectoryServer.getServerErrorResultCode();
          if (resultCode == ResultCode.SUCCESS)
          {
            resultCode = ResultCode.CONSTRAINT_VIOLATION;
          }
        }
        int msgID = MSGID_FILE_KEYMANAGER_INVALID_TYPE;
        messages.add(getMessage(msgID,
                                String.valueOf(configuration.getKeyStoreType()),
                                String.valueOf(configEntryDN),
                                getExceptionMessage(kse)));
      }
    }
    catch (Exception e)
    // Get the PIN needed to access the contents of the keystore file.
    //
    // We will offer several places to look for the PIN, and we will
    // do so in the following order:
    //
    // - In a specified Java property
    // - In a specified environment variable
    // - In a specified file on the server filesystem.
    // - As the value of a configuration attribute.
    //
    // In any case, the PIN must be in the clear.
    char[] newPIN = null;
    if (configuration.getKeyStorePinProperty() != null)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      String propertyName = configuration.getKeyStorePinProperty();
      String pinStr = System.getProperty(propertyName);
      msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_TYPE;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              getExceptionMessage(e)));
      if (resultCode == ResultCode.SUCCESS)
      if (pinStr == null)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
        int msgID = MSGID_FILE_KEYMANAGER_PIN_PROPERTY_NOT_SET;
        messages.add(getMessage(msgID, String.valueOf(propertyName),
                                String.valueOf(configEntryDN)));
      }
      else
      {
        newPIN = pinStr.toCharArray();
      }
    }
    // Make sure that there is some way to determine the PIN.  Look for the PIN
    // in a property, environment variable, file, or configuration attribute, in
    // that order.
    char[] newKeyStorePIN         = null;
    String newKeyStorePINEnVar    = null;
    String newKeyStorePINFile     = null;
    String newKeyStorePINProperty = null;
pinSelection:
    else if (configuration.getKeyStorePinEnvironmentVariable() != null)
    {
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      String enVarName = configuration.getKeyStorePinEnvironmentVariable();
      String pinStr    = System.getenv(enVarName);
      if (pinStr == null)
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_PROPERTY_NOT_SET;
            messages.add(getMessage(msgID, String.valueOf(propertyName),
                                    String.valueOf(configEntryDN)));
        resultCode = DirectoryServer.getServerErrorResultCode();
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
          }
          else
          {
            newKeyStorePIN         = pinStr.toCharArray();
            newKeyStorePINProperty = propertyName;
            break pinSelection;
          }
        }
        int msgID = MSGID_FILE_KEYMANAGER_PIN_ENVAR_NOT_SET;
        messages.add(getMessage(msgID, String.valueOf(enVarName),
                                String.valueOf(configEntryDN)));
      }
      catch (Exception e)
      else
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_ENVAR, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_ENVAR_NOT_SET;
            messages.add(getMessage(msgID, String.valueOf(enVarName),
                                    String.valueOf(configEntryDN)));
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
          }
          else
          {
            newKeyStorePIN      = pinStr.toCharArray();
            newKeyStorePINEnVar = enVarName;
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_FILE, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          if (! pinFile.exists())
          {
            msgID = MSGID_FILE_KEYMANAGER_PIN_NO_SUCH_FILE;
            messages.add(getMessage(msgID, String.valueOf(fileName),
                                    String.valueOf(configEntryDN)));
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
          }
          else
          {
            String pinStr;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_CANNOT_READ;
              messages.add(getMessage(msgID, String.valueOf(fileName),
                                      String.valueOf(configEntryDN),
                                      getExceptionMessage(ioe)));
              if (resultCode == ResultCode.SUCCESS)
              {
                resultCode = DirectoryServer.getServerErrorResultCode();
              }
              break pinSelection;
            }
            if (pinStr == null)
            {
              msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_EMPTY;
              messages.add(getMessage(msgID, String.valueOf(fileName),
                                      String.valueOf(configEntryDN)));
              if (resultCode == ResultCode.SUCCESS)
              {
                resultCode = ResultCode.CONSTRAINT_VIOLATION;
              }
              break pinSelection;
            }
            else
            {
              newKeyStorePIN     = pinStr.toCharArray();
              newKeyStorePINFile = fileName;
              break pinSelection;
            }
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_FILE;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
      }
      msgID = MSGID_FILE_KEYMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        {
          newKeyStorePIN = pinAttr.activeValue().toCharArray();
          break pinSelection;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
        newPIN = pinStr.toCharArray();
      }
    }
    if (newKeyStorePIN == null)
    else if (configuration.getKeyStorePinFile() != null)
    {
      msgID = MSGID_FILE_KEYMANAGER_NO_PIN;
      String fileName = configuration.getKeyStorePinFile();
      File   pinFile  = getFileForPath(fileName);
      if (!pinFile.exists())
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
        int msgID = MSGID_FILE_KEYMANAGER_PIN_NO_SUCH_FILE;
        messages.add(getMessage(msgID, String.valueOf(fileName),
                                String.valueOf(configEntryDN)));
      }
      else
      {
        String pinStr = null;
        BufferedReader br = null;
        try {
          br = new BufferedReader(new FileReader(pinFile));
          pinStr = br.readLine();
        }
        catch (IOException ioe)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
          int msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_CANNOT_READ;
          messages.add(getMessage(msgID, String.valueOf(fileName),
                                  String.valueOf(configEntryDN),
                                  getExceptionMessage(ioe)));
        }
        finally
        {
          try
          {
            br.close();
          } catch (Exception e) {}
        }
        if (pinStr == null)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
          int msgID = MSGID_FILE_KEYMANAGER_PIN_FILE_EMPTY;
          messages.add(getMessage(msgID, String.valueOf(fileName),
                                  String.valueOf(configEntryDN)));
        }
        else
        {
          newPIN = pinStr.toCharArray();
        }
      }
    }
    else if (configuration.getKeyStorePin() != null)
    {
      newPIN = configuration.getKeyStorePin().toCharArray();
    }
    else
    {
      // Pin wasn't defined anywhere.
      resultCode = DirectoryServer.getServerErrorResultCode();
      int msgID = MSGID_FILE_KEYMANAGER_NO_PIN;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = ResultCode.CONSTRAINT_VIOLATION;
      }
    }
    // If everything looks successful, then apply the changes.
    if (resultCode == ResultCode.SUCCESS)
    {
      if (! keyStoreFile.equals(newKeyStoreFile))
      {
        keyStoreFile = newKeyStoreFile;
        if (detailedResults)
        {
          msgID = MSGID_FILE_KEYMANAGER_UPDATED_FILE;
          messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                  String.valueOf(newKeyStoreFile)));
        }
      }
      if (! keyStoreType.equals(newKeyStoreType))
      {
        keyStoreType = newKeyStoreType;
        if (detailedResults)
        {
          msgID = MSGID_FILE_KEYMANAGER_UPDATED_TYPE;
          messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                  String.valueOf(newKeyStoreType)));
        }
      }
      if (! Arrays.equals(keyStorePIN, newKeyStorePIN))
      {
        keyStorePIN = newKeyStorePIN;
        keyStorePINProperty = newKeyStorePINProperty;
        keyStorePINEnVar    = newKeyStorePINEnVar;
        keyStorePINFile     = newKeyStorePINFile;
        if (detailedResults)
        {
          msgID = MSGID_FILE_KEYMANAGER_UPDATED_PIN;
          messages.add(getMessage(msgID));
        }
      }
      currentConfig = configuration;
      keyStorePIN   = newPIN;
      keyStoreFile  = newKeyStoreFile;
      keyStoreType  = newKeyStoreType;
    }
opends/src/server/org/opends/server/extensions/FileBasedTrustManagerProvider.java
@@ -28,25 +28,21 @@
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.security.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.opends.server.api.ConfigurableComponent;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.FileBasedTrustManagerCfg;
import org.opends.server.api.TrustManagerProvider;
import org.opends.server.config.ConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.config.StringConfigAttribute;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DirectoryException;
@@ -54,7 +50,6 @@
import org.opends.server.types.InitializationException;
import org.opends.server.types.ResultCode;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.types.DebugLogLevel;
@@ -69,8 +64,8 @@
 * stored in a file located on the Directory Server filesystem.
 */
public class FileBasedTrustManagerProvider
       extends TrustManagerProvider
       implements ConfigurableComponent
       extends TrustManagerProvider<FileBasedTrustManagerCfg>
       implements ConfigurationChangeListener<FileBasedTrustManagerCfg>
{
  /**
   * The tracer object for the debug logger.
@@ -86,18 +81,12 @@
  // The PIN needed to access the trust store.
  private char[] trustStorePIN;
  // The handle to the configuration for this trust manager.
  private FileBasedTrustManagerCfg currentConfig;
  // The path to the trust store backing file.
  private String trustStoreFile;
  // The name of the environment variable containing the trust store PIN.
  private String trustStorePINEnVar;
  // The path to the file containing the trust store PIN.
  private String trustStorePINFile;
  // The name of the Java property containing the trust store PIN.
  private String trustStorePINProperty;
  // The trust store type to use.
  private String trustStoreType;
@@ -116,141 +105,56 @@
  /**
   * Initializes this trust manager provider based on the information in the
   * provided configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the information
   *                      to use to initialize this trust manager provider.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in the
   *                           process of performing the initialization as a
   *                           result of the server configuration.
   *
   * @throws  InitializationException  If a problem occurs during initialization
   *                                   that is not related to the server
   *                                   configuration.
   * {@inheritDoc}
   */
  public void initializeTrustManagerProvider(ConfigEntry configEntry)
  @Override()
  public void initializeTrustManagerProvider(
                   FileBasedTrustManagerCfg configuration)
         throws ConfigException, InitializationException
  {
    // Store the DN of the configuration entry.
    configEntryDN = configEntry.getDN();
    // Store the DN of the configuration entry and register to listen for any
    // changes to the configuration entry.
    currentConfig = configuration;
    configEntryDN = configuration.dn();
    configuration.addFileBasedChangeListener(this);
    // Get the path to the trust store file.
    int msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_FILE;
    StringConfigAttribute fileStub =
         new StringConfigAttribute(ATTR_TRUSTSTORE_FILE, getMessage(msgID),
                                   true, false, false);
    try
    trustStoreFile = configuration.getTrustStoreFile();
    File f = getFileForPath(trustStoreFile);
    if (! (f.exists() && f.isFile()))
    {
      StringConfigAttribute fileAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(fileStub);
      if ((fileAttr == null) ||
          ((trustStoreFile = fileAttr.activeValue()) == null))
      {
        msgID = MSGID_FILE_TRUSTMANAGER_NO_FILE_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN));
        throw new ConfigException(msgID, message);
      }
      File f = getFileForPath(trustStoreFile);
      if (! (f.exists() && f.isFile()))
      {
        msgID = MSGID_FILE_TRUSTMANAGER_NO_SUCH_FILE;
        String message = getMessage(msgID, String.valueOf(trustStoreFile),
                                    String.valueOf(configEntryDN));
        throw new InitializationException(msgID, message);
      }
    }
    catch (ConfigException ce)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }
      throw ce;
    }
    catch (InitializationException ie)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ie);
      }
      throw ie;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_FILE;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  getExceptionMessage(e));
      throw new InitializationException(msgID, message, e);
      int    msgID   = MSGID_FILE_TRUSTMANAGER_NO_SUCH_FILE;
      String message = getMessage(msgID, String.valueOf(trustStoreFile),
                                  String.valueOf(configEntryDN));
      throw new InitializationException(msgID, message);
    }
    // Get the trust store type.  If none is specified, then use the default
    // type.
    trustStoreType = KeyStore.getDefaultType();
    msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_TYPE;
    StringConfigAttribute typeStub =
         new StringConfigAttribute(ATTR_TRUSTSTORE_TYPE, getMessage(msgID),
                                   false, false, false);
    trustStoreType = configuration.getTrustStoreType();
    if (trustStoreType == null)
    {
      trustStoreType = KeyStore.getDefaultType();
    }
    try
    {
      StringConfigAttribute typeAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(typeStub);
      if (typeAttr != null)
      {
        // A trust store type was specified, so make sure it is valid.
        String typeStr = typeAttr.activeValue();
        try
        {
          KeyStore.getInstance(typeStr);
          trustStoreType = typeStr;
        }
        catch (KeyStoreException kse)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, kse);
          }
          msgID = MSGID_FILE_TRUSTMANAGER_INVALID_TYPE;
          String message = getMessage(msgID, String.valueOf(typeStr),
                                      String.valueOf(configEntryDN),
                                      getExceptionMessage(kse));
          throw new InitializationException(msgID, message);
        }
      }
      KeyStore.getInstance(trustStoreType);
    }
    catch (InitializationException ie)
    catch (KeyStoreException kse)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        TRACER.debugCaught(DebugLogLevel.ERROR, kse);
      }
      throw ie;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_TYPE;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  getExceptionMessage(e));
      throw new InitializationException(msgID, message, e);
      int    msgID   = MSGID_FILE_TRUSTMANAGER_INVALID_TYPE;
      String message = getMessage(msgID, String.valueOf(trustStoreType),
                                  String.valueOf(configEntryDN),
                                  getExceptionMessage(kse));
      throw new InitializationException(msgID, message);
    }
@@ -264,130 +168,33 @@
    // In any case, the PIN must be in the clear.  If no PIN is provided, then
    // it will be assumed that none is required to access the information in the
    // trust store.
    trustStorePIN         = null;
    trustStorePINEnVar    = null;
    trustStorePINFile     = null;
    trustStorePINProperty = null;
pinSelection:
    String pinProperty = configuration.getTrustStorePinProperty();
    if (pinProperty == null)
    {
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      String pinEnVar = configuration.getTrustStorePinEnvironmentVariable();
      if (pinEnVar == null)
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        String pinFilePath = configuration.getTrustStorePinFile();
        if (pinFilePath == null)
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          String pinStr = configuration.getTrustStorePin();
          if (pinStr == null)
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET;
            String message = getMessage(msgID, String.valueOf(propertyName),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
            trustStorePIN = null;
          }
          else
          {
            trustStorePIN         = pinStr.toCharArray();
            trustStorePINProperty = propertyName;
            break pinSelection;
            trustStorePIN = pinStr.toCharArray();
          }
        }
      }
      catch (InitializationException ie)
      {
        if (debugEnabled())
        else
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_ENVAR,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET;
            String message = getMessage(msgID, String.valueOf(enVarName),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
          }
          else
          {
            trustStorePIN      = pinStr.toCharArray();
            trustStorePINEnVar = enVarName;
            break pinSelection;
          }
        }
      }
      catch (InitializationException ie)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_FILE,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          File pinFile = getFileForPath(pinFilePath);
          if (! pinFile.exists())
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE;
            String message = getMessage(msgID, String.valueOf(fileName),
            int    msgID    = MSGID_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE;
            String message = getMessage(msgID,
                                        String.valueOf(pinFilePath),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
          }
@@ -395,115 +202,96 @@
          {
            String pinStr;
            BufferedReader br = null;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ;
              String message = getMessage(msgID, String.valueOf(fileName),
              int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ;
              String message = getMessage(msgID,
                                          String.valueOf(pinFilePath),
                                          String.valueOf(configEntryDN),
                                          getExceptionMessage(ioe));
              throw new InitializationException(msgID, message, ioe);
            }
            finally
            {
              try
              {
                br.close();
              } catch (Exception e) {}
            }
            if (pinStr == null)
            {
              msgID = MSGID_FILE_TRUSTMANAGER_PIN_FILE_EMPTY;
              String message = getMessage(msgID, String.valueOf(fileName),
              int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_FILE_EMPTY;
              String message = getMessage(msgID,
                                          String.valueOf(pinFilePath),
                                          String.valueOf(configEntryDN));
              throw new InitializationException(msgID, message);
            }
            else
            {
              trustStorePIN     = pinStr.toCharArray();
              trustStorePINFile = fileName;
              break pinSelection;
            }
          }
        }
      }
      catch (InitializationException ie)
      else
      {
        if (debugEnabled())
        String pinStr = System.getenv(pinEnVar);
        if (pinStr == null)
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
          int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET;
          String message = getMessage(msgID,
                                      String.valueOf(pinProperty),
                                      String.valueOf(configEntryDN));
          throw new InitializationException(msgID, message);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        else
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
          trustStorePIN = pinStr.toCharArray();
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_FILE;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        {
          trustStorePIN = pinAttr.activeValue().toCharArray();
          break pinSelection;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
    }
    DirectoryServer.registerConfigurableComponent(this);
    else
    {
      String pinStr = System.getProperty(pinProperty);
      if (pinStr == null)
      {
        int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET;
        String message = getMessage(msgID,
                                    String.valueOf(pinProperty),
                                    String.valueOf(configEntryDN));
        throw new InitializationException(msgID, message);
      }
      else
      {
        trustStorePIN = pinStr.toCharArray();
      }
    }
  }
  /**
   * Performs any finalization that may be necessary for this trust manager
   * provider.
   * {@inheritDoc}
   */
  @Override()
  public void finalizeTrustManagerProvider()
  {
    DirectoryServer.deregisterConfigurableComponent(this);
    currentConfig.removeFileBasedChangeListener(this);
  }
  /**
   * Retrieves a set of <CODE>TrustManager</CODE> objects that may be used for
   * interactions requiring access to a trust manager.
   *
   * @return  A set of <CODE>TrustManager</CODE> objects that may be used for
   *          interactions requiring access to a trust manager.
   *
   * @throws  DirectoryException  If a problem occurs while attempting to obtain
   *                              the set of trust managers.
   * {@inheritDoc}
   */
  @Override()
  public TrustManager[] getTrustManagers()
         throws DirectoryException
  {
@@ -555,837 +343,303 @@
    }
  }
  /**
   * 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.
   * {@inheritDoc}
   */
  public DN getConfigurableComponentEntryDN()
  public boolean isConfigurationChangeAcceptable(
                      FileBasedTrustManagerCfg configuration,
                      List<String> unacceptableReasons)
  {
    return configEntryDN;
  }
    boolean configAcceptable = true;
  /**
   * 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_FILE_TRUSTMANAGER_DESCRIPTION_FILE;
    StringConfigAttribute fileAttr =
         new StringConfigAttribute(ATTR_TRUSTSTORE_FILE, getMessage(msgID),
                                   true, false, false, trustStoreFile);
    attrList.add(fileAttr);
    msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_TYPE;
    StringConfigAttribute typeAttr =
         new StringConfigAttribute(ATTR_TRUSTSTORE_TYPE, getMessage(msgID),
                                   true, false, false, trustStoreType);
    attrList.add(typeAttr);
    msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_PROPERTY;
    StringConfigAttribute pinPropertyAttr =
         new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_PROPERTY,
                                   getMessage(msgID), false, false, false,
                                   trustStorePINProperty);
    attrList.add(pinPropertyAttr);
    msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_ENVAR;
    StringConfigAttribute pinEnvVarAttr =
         new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_ENVAR,
                                   getMessage(msgID), false, false, false,
                                   trustStorePINEnVar);
    attrList.add(pinEnvVarAttr);
    msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_FILE;
    StringConfigAttribute pinFileAttr =
         new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_FILE,
                                   getMessage(msgID), false, false, false,
                                   trustStorePINFile);
    attrList.add(pinFileAttr);
    String pinString;
    if ((trustStorePINProperty == null) && (trustStorePINEnVar == null) &&
        (trustStorePINFile == null))
    // Check to see if the trust store type is acceptable.
    String storeType = configuration.getTrustStoreType();
    if (storeType != null)
    {
      pinString = new String(trustStorePIN);
    }
    else
    {
      pinString = null;
    }
    msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_ATTR;
    StringConfigAttribute pinAttr =
         new StringConfigAttribute(ATTR_TRUSTSTORE_PIN, getMessage(msgID),
                                   false, false, false, pinString);
    attrList.add(pinAttr);
    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)
  {
    // Make sure that a trust store file was provided.
    int msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_FILE;
    StringConfigAttribute fileStub =
         new StringConfigAttribute(ATTR_TRUSTSTORE_FILE, getMessage(msgID),
                                   true, false, false);
    try
    {
      String newTrustStoreFile = null;
      StringConfigAttribute fileAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(fileStub);
      if ((fileAttr == null) ||
          ((newTrustStoreFile = fileAttr.activeValue()) == null))
      try
      {
        msgID = MSGID_FILE_TRUSTMANAGER_NO_FILE_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN));
        throw new ConfigException(msgID, message);
        KeyStore.getInstance(storeType);
      }
      File f = getFileForPath(newTrustStoreFile);
      if (! (f.exists() && f.isFile()))
      catch (KeyStoreException kse)
      {
        msgID = MSGID_FILE_TRUSTMANAGER_NO_SUCH_FILE;
        String message = getMessage(msgID, String.valueOf(newTrustStoreFile),
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, kse);
        }
        int    msgID   = MSGID_FILE_TRUSTMANAGER_INVALID_TYPE;
        String message = getMessage(msgID, String.valueOf(storeType),
                                    String.valueOf(configEntryDN),
                                    getExceptionMessage(kse));
        unacceptableReasons.add(message);
        configAcceptable = false;
      }
    }
    // If there is a PIN property, then make sure the corresponding
    // property is set.
    String pinProp = configuration.getTrustStorePinProperty();
    if (pinProp != null)
    {
      if (System.getProperty(pinProp) == null)
      {
        int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET;
        String message = getMessage(msgID, String.valueOf(pinProp),
                                    String.valueOf(configEntryDN));
        unacceptableReasons.add(message);
        return false;
        configAcceptable = false;
      }
    }
    catch (ConfigException ce)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }
      unacceptableReasons.add(ce.getMessage());
      return false;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_FILE;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  getExceptionMessage(e));
      unacceptableReasons.add(message);
      return false;
    // If there is a PIN environment variable, then make sure the corresponding
    // environment variable is set.
    String pinEnVar = configuration.getTrustStorePinEnvironmentVariable();
    if (pinEnVar != null)
    {
      if (System.getenv(pinEnVar) == null)
      {
        int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET;
        String message = getMessage(msgID, String.valueOf(pinEnVar),
                                    String.valueOf(configEntryDN));
        unacceptableReasons.add(message);
        configAcceptable = false;
      }
    }
    // See if a trust store type was provided.  It is optional, but if one was
    // provided, then it must be a valid type.
    msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_TYPE;
    StringConfigAttribute typeStub =
         new StringConfigAttribute(ATTR_TRUSTSTORE_TYPE, getMessage(msgID),
                                   false, false, false);
    try
    // If there is a PIN file, then make sure the file exists and is readable.
    String pinFile = configuration.getTrustStorePinFile();
    if (pinFile != null)
    {
      StringConfigAttribute typeAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(typeStub);
      if (typeAttr != null)
      File f = new File(pinFile);
      if (f.exists())
      {
        // A trust store type was specified, so make sure it is valid.
        String typeStr = typeAttr.activeValue();
        String pinStr = null;
        BufferedReader br = null;
        try
        {
          KeyStore.getInstance(typeStr);
          br = new BufferedReader(new FileReader(pinFile));
          pinStr = br.readLine();
        }
        catch (KeyStoreException kse)
        catch (IOException ioe)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, kse);
          }
          msgID = MSGID_FILE_TRUSTMANAGER_INVALID_TYPE;
          String message = getMessage(msgID, String.valueOf(typeStr),
          int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ;
          String message = getMessage(msgID, String.valueOf(pinFile),
                                      String.valueOf(configEntryDN),
                                      getExceptionMessage(kse));
                                      getExceptionMessage(ioe));
          unacceptableReasons.add(message);
          return false;
          configAcceptable = false;
        }
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_TYPE;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  getExceptionMessage(e));
      unacceptableReasons.add(message);
      return false;
    }
    // Make sure that there is some way to determine the PIN.  Look for the PIN
    // in a property, environment variable, file, or configuration attribute, in
    // that order.
pinSelection:
    {
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        finally
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          if (pinStr == null)
          try
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET;
            String message = getMessage(msgID, String.valueOf(propertyName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
            br.close();
          } catch (Exception e) {}
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        if (pinStr == null)
        {
          int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_FILE_EMPTY;
          String message =  getMessage(msgID, String.valueOf(pinFile),
                                       String.valueOf(configEntryDN));
          unacceptableReasons.add(message);
          configAcceptable = false;
        }
      }
      else
      {
        int    msgID   = MSGID_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE;
        String message = getMessage(msgID, String.valueOf(pinFile),
                                    String.valueOf(configEntryDN));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_ENVAR,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET;
            String message = getMessage(msgID, String.valueOf(enVarName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_FILE,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          if (! pinFile.exists())
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE;
            String message = getMessage(msgID, String.valueOf(fileName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            String pinStr;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN),
                                          getExceptionMessage(ioe));
              unacceptableReasons.add(message);
              return false;
            }
            if (pinStr == null)
            {
              msgID = MSGID_FILE_TRUSTMANAGER_PIN_FILE_EMPTY;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN));
              unacceptableReasons.add(message);
              return false;
            }
            else
            {
              break pinSelection;
            }
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_FILE;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        {
          break pinSelection;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
        configAcceptable = false;
      }
    }
    // If we've gotten here, then everything looks OK.
    return true;
    return configAcceptable;
  }
  /**
   * 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.
   * {@inheritDoc}
   */
  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
                                                  boolean detailedResults)
  public ConfigChangeResult applyConfigurationChange(
                                 FileBasedTrustManagerCfg configuration)
  {
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    // Make sure that a trust store file was provided.
    String newTrustStoreFile = null;
    int msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_FILE;
    StringConfigAttribute fileStub =
         new StringConfigAttribute(ATTR_TRUSTSTORE_FILE, getMessage(msgID),
                                   true, false, false);
    // Get the path to the trust store file.
    String newTrustStoreFile = configuration.getTrustStoreFile();
    File f = getFileForPath(newTrustStoreFile);
    if (! (f.exists() && f.isFile()))
    {
      resultCode = DirectoryServer.getServerErrorResultCode();
      int msgID = MSGID_FILE_TRUSTMANAGER_NO_SUCH_FILE;
      messages.add(getMessage(msgID, String.valueOf(newTrustStoreFile),
                              String.valueOf(configEntryDN)));
    }
    // Get the trust store type.  If none is specified, then use the default
    // type.
    String newTrustStoreType = configuration.getTrustStoreType();
    if (newTrustStoreType == null)
    {
      newTrustStoreType = KeyStore.getDefaultType();
    }
    try
    {
      StringConfigAttribute fileAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(fileStub);
      if ((fileAttr == null) ||
          ((newTrustStoreFile = fileAttr.activeValue()) == null))
      {
        msgID = MSGID_FILE_TRUSTMANAGER_NO_FILE_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN));
        throw new ConfigException(msgID, message);
      }
      File f = getFileForPath(newTrustStoreFile);
      if (! (f.exists() && f.isFile()))
      {
        msgID = MSGID_FILE_TRUSTMANAGER_NO_SUCH_FILE;
        messages.add(getMessage(msgID, String.valueOf(newTrustStoreFile),
                                String.valueOf(configEntryDN)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = ResultCode.CONSTRAINT_VIOLATION;
        }
      }
      KeyStore.getInstance(newTrustStoreType);
    }
    catch (ConfigException ce)
    catch (KeyStoreException kse)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
        TRACER.debugCaught(DebugLogLevel.ERROR, kse);
      }
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = ResultCode.CONSTRAINT_VIOLATION;
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      int msgID = MSGID_FILE_TRUSTMANAGER_INVALID_TYPE;
      messages.add(getMessage(msgID, String.valueOf(newTrustStoreType),
                              String.valueOf(configEntryDN),
                              getExceptionMessage(kse)));
      msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_FILE;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              getExceptionMessage(e)));
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
      }
      resultCode = DirectoryServer.getServerErrorResultCode();
    }
    // See if a trust store type was provided.  It is optional, but if one was
    // provided, then it must be a valid type.
    String newTrustStoreType = KeyStore.getDefaultType();
    msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_TYPE;
    StringConfigAttribute typeStub =
         new StringConfigAttribute(ATTR_TRUSTSTORE_TYPE, getMessage(msgID),
                                   false, false, false);
    try
    // Get the PIN needed to access the contents of the trust store file.  We
    // will offer several places to look for the PIN, and we will do so in the
    // following order:
    // - In a specified Java property
    // - In a specified environment variable
    // - In a specified file on the server filesystem.
    // - As the value of a configuration attribute.
    // In any case, the PIN must be in the clear.  If no PIN is provided, then
    // it will be assumed that none is required to access the information in the
    // trust store.
    char[] newPIN = null;
    String newPINProperty = configuration.getTrustStorePinProperty();
    if (newPINProperty == null)
    {
      StringConfigAttribute typeAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(typeStub);
      if (typeAttr != null)
      String newPINEnVar = configuration.getTrustStorePinEnvironmentVariable();
      if (newPINEnVar == null)
      {
        // A trust store type was specified, so make sure it is valid.
        newTrustStoreType = typeAttr.activeValue();
        try
        String newPINFile = configuration.getTrustStorePinFile();
        if (newPINFile == null)
        {
          KeyStore.getInstance(newTrustStoreType);
        }
        catch (KeyStoreException kse)
        {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, kse);
          }
          msgID = MSGID_FILE_TRUSTMANAGER_INVALID_TYPE;
          messages.add(getMessage(msgID, String.valueOf(newTrustStoreType),
                                  String.valueOf(configEntryDN),
                                  getExceptionMessage(kse)));
          if (resultCode == ResultCode.SUCCESS)
          {
            resultCode = ResultCode.CONSTRAINT_VIOLATION;
          }
        }
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_TYPE;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              getExceptionMessage(e)));
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
      }
    }
    // Make sure that there is some way to determine the PIN.  Look for the PIN
    // in a property, environment variable, file, or configuration attribute, in
    // that order.
    char[] newTrustStorePIN         = null;
    String newTrustStorePINEnVar    = null;
    String newTrustStorePINFile     = null;
    String newTrustStorePINProperty = null;
pinSelection:
    {
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          String pinStr = configuration.getTrustStorePin();
          if (pinStr == null)
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET;
            messages.add(getMessage(msgID, String.valueOf(propertyName),
                                    String.valueOf(configEntryDN)));
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
            newPIN = null;
          }
          else
          {
            newTrustStorePIN         = pinStr.toCharArray();
            newTrustStorePINProperty = propertyName;
            break pinSelection;
            newPIN = pinStr.toCharArray();
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        else
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_ENVAR,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET;
            messages.add(getMessage(msgID, String.valueOf(enVarName),
                                    String.valueOf(configEntryDN)));
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
          }
          else
          {
            newTrustStorePIN      = pinStr.toCharArray();
            newTrustStorePINEnVar = enVarName;
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN_FILE,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          File pinFile = getFileForPath(newPINFile);
          if (! pinFile.exists())
          {
            msgID = MSGID_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE;
            messages.add(getMessage(msgID, String.valueOf(fileName),
            resultCode = DirectoryServer.getServerErrorResultCode();
            int msgID = MSGID_FILE_TRUSTMANAGER_PIN_NO_SUCH_FILE;
            messages.add(getMessage(msgID, String.valueOf(newPINFile),
                                    String.valueOf(configEntryDN)));
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
          }
          else
          {
            String pinStr;
            String pinStr = null;
            BufferedReader br = null;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ;
              messages.add(getMessage(msgID, String.valueOf(fileName),
              resultCode = DirectoryServer.getServerErrorResultCode();
              int msgID = MSGID_FILE_TRUSTMANAGER_PIN_FILE_CANNOT_READ;
              messages.add(getMessage(msgID, String.valueOf(newPINFile),
                                      String.valueOf(configEntryDN),
                                      getExceptionMessage(ioe)));
              if (resultCode == ResultCode.SUCCESS)
            }
            finally
            {
              try
              {
                resultCode = DirectoryServer.getServerErrorResultCode();
              }
              break pinSelection;
                br.close();
              } catch (Exception e) {}
            }
            if (pinStr == null)
            {
              msgID = MSGID_FILE_TRUSTMANAGER_PIN_FILE_EMPTY;
              messages.add(getMessage(msgID, String.valueOf(fileName),
              resultCode = DirectoryServer.getServerErrorResultCode();
              int msgID = MSGID_FILE_TRUSTMANAGER_PIN_FILE_EMPTY;
              messages.add(getMessage(msgID, String.valueOf(newPINFile),
                                      String.valueOf(configEntryDN)));
              if (resultCode == ResultCode.SUCCESS)
              {
                resultCode = ResultCode.CONSTRAINT_VIOLATION;
              }
              break pinSelection;
            }
            else
            {
              newTrustStorePIN     = pinStr.toCharArray();
              newTrustStorePINFile = fileName;
              break pinSelection;
              newPIN = pinStr.toCharArray();
            }
          }
        }
      }
      catch (Exception e)
      else
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_FILE;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        String pinStr = System.getenv(newPINEnVar);
        if (pinStr == null)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
          int msgID = MSGID_FILE_TRUSTMANAGER_PIN_ENVAR_NOT_SET;
          messages.add(getMessage(msgID, String.valueOf(newPINEnVar),
                                  String.valueOf(configEntryDN)));
        }
        break pinSelection;
      }
      msgID = MSGID_FILE_TRUSTMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_TRUSTSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        else
        {
          newTrustStorePIN = pinAttr.activeValue().toCharArray();
          break pinSelection;
          newPIN = pinStr.toCharArray();
        }
      }
      catch (Exception e)
    }
    else
    {
      String pinStr = System.getProperty(newPINProperty);
      if (pinStr == null)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        resultCode = DirectoryServer.getServerErrorResultCode();
        msgID = MSGID_FILE_TRUSTMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
        int msgID = MSGID_FILE_TRUSTMANAGER_PIN_PROPERTY_NOT_SET;
        messages.add(getMessage(msgID, String.valueOf(newPINProperty),
                                String.valueOf(configEntryDN)));
      }
      else
      {
        newPIN = pinStr.toCharArray();
      }
    }
    // If everything looks successful, then apply the changes.
    if (resultCode == ResultCode.SUCCESS)
    {
      if (! trustStoreFile.equals(newTrustStoreFile))
      {
        trustStoreFile = newTrustStoreFile;
        if (detailedResults)
        {
          msgID = MSGID_FILE_TRUSTMANAGER_UPDATED_FILE;
          messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                  String.valueOf(newTrustStoreFile)));
        }
      }
      if (! trustStoreType.equals(newTrustStoreType))
      {
        trustStoreType = newTrustStoreType;
        if (detailedResults)
        {
          msgID = MSGID_FILE_TRUSTMANAGER_UPDATED_TYPE;
          messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                  String.valueOf(newTrustStoreType)));
        }
      }
      if (! (((trustStorePIN == null) && (newTrustStorePIN == null)) ||
             Arrays.equals(trustStorePIN, newTrustStorePIN)))
      {
        trustStorePIN = newTrustStorePIN;
        trustStorePINProperty = newTrustStorePINProperty;
        trustStorePINEnVar    = newTrustStorePINEnVar;
        trustStorePINFile     = newTrustStorePINFile;
        if (detailedResults)
        {
          msgID = MSGID_FILE_TRUSTMANAGER_UPDATED_PIN;
          messages.add(getMessage(msgID));
        }
      }
      trustStoreFile = newTrustStoreFile;
      trustStoreType = newTrustStoreType;
      trustStorePIN  = newPIN;
      currentConfig  = configuration;
    }
opends/src/server/org/opends/server/extensions/NullKeyManagerProvider.java
@@ -32,7 +32,6 @@
import org.opends.server.admin.std.server.KeyManagerCfg;
import org.opends.server.api.KeyManagerProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
@@ -46,8 +45,7 @@
 * other key manager provider has been defined in the server configuration.
 */
public class NullKeyManagerProvider
       extends KeyManagerProvider
{
       extends KeyManagerProvider<KeyManagerCfg>{
@@ -64,29 +62,6 @@
  /**
   * Initializes this key manager provider based on the information in the
   * provided configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the information
   *                      to use to initialize this key manager provider.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in the
   *                           process of performing the initialization as a
   *                           result of the server configuration.
   *
   * @throws  InitializationException  If a problem occurs during initialization
   *                                   that is not related to the server
   *                                   configuration.
   */
  public void initializeKeyManagerProvider(ConfigEntry configEntry)
         throws ConfigException, InitializationException
  {
    // No implementation is required.
  }
  /**
   * {@inheritDoc}
   */
  @Override
opends/src/server/org/opends/server/extensions/NullTrustManagerProvider.java
@@ -30,8 +30,8 @@
import javax.net.ssl.TrustManager;
import org.opends.server.admin.std.server.TrustManagerCfg;
import org.opends.server.api.TrustManagerProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.InitializationException;
@@ -46,11 +46,8 @@
 * configuration.
 */
public class NullTrustManagerProvider
       extends TrustManagerProvider
       extends TrustManagerProvider<TrustManagerCfg>
{
  /**
   * Creates a new instance of this null trust manager provider.  The
   * <CODE>initializeTrustManagerProvider</CODE> method must be called on the
@@ -64,21 +61,9 @@
  /**
   * Initializes this trust manager provider based on the information in the
   * provided configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the information
   *                      to use to initialize this trust manager provider.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in the
   *                           process of performing the initialization as a
   *                           result of the server configuration.
   *
   * @throws  InitializationException  If a problem occurs during initialization
   *                                   that is not related to the server
   *                                   configuration.
   * {@inheritDoc}
   */
  public void initializeTrustManagerProvider(ConfigEntry configEntry)
  public void initializeTrustManagerProvider(TrustManagerCfg configuration)
         throws ConfigException, InitializationException
  {
    // No implementation is required.
opends/src/server/org/opends/server/extensions/PKCS11KeyManagerProvider.java
@@ -34,19 +34,14 @@
import java.io.IOException;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.PKCS11KeyManagerCfg;
import org.opends.server.api.ConfigurableComponent;
import org.opends.server.api.KeyManagerProvider;
import org.opends.server.config.ConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.config.StringConfigAttribute;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DirectoryException;
@@ -69,9 +64,9 @@
 * PKCS#11 device.  It will use the Java PKCS#11 interface, which may need to be
 * configured on the underlying system.
 */
public class PKCS11KeyManagerProvider extends
    KeyManagerProvider<PKCS11KeyManagerCfg> implements
    ConfigurableComponent
public class PKCS11KeyManagerProvider
    extends KeyManagerProvider<PKCS11KeyManagerCfg>
    implements ConfigurationChangeListener<PKCS11KeyManagerCfg>
{
  /**
   * The tracer object for the debug logger.
@@ -80,7 +75,6 @@
  /**
   * The keystore type to use when accessing the PKCS#11 keystore.
   */
@@ -94,14 +88,8 @@
  // The PIN needed to access the keystore.
  private char[] keyStorePIN;
  // The name of the environment variable containing the keystore PIN.
  private String keyStorePINEnVar;
  // The path to the file containing the keystore PIN.
  private String keyStorePINFile;
  // The name of the Java property containing the keystore PIN.
  private String keyStorePINProperty;
  // The current configuration for this key manager provider.
  private PKCS11KeyManagerCfg currentConfig;
@@ -118,271 +106,17 @@
  /**
   * Initializes this key manager provider based on the information in the
   * provided configuration entry.
   *
   * @param  configEntry  The configuration entry that contains the information
   *                      to use to initialize this key manager provider.
   *
   * @throws  ConfigException  If an unrecoverable problem arises in the
   *                           process of performing the initialization as a
   *                           result of the server configuration.
   *
   * @throws  InitializationException  If a problem occurs during initialization
   *                                   that is not related to the server
   *                                   configuration.
   */
  public void initializeKeyManagerProvider(ConfigEntry configEntry)
         throws ConfigException, InitializationException
  {
    // Store the DN of the configuration entry.
    configEntryDN = configEntry.getDN();
    // Get the PIN needed to access the contents of the PKCS#11 keystore.  We
    // will offer several places to look for the PIN, and we will do so in the
    // following order:
    // - In a specified Java property
    // - In a specified environment variable
    // - In a specified file on the server filesystem.
    // - As the value of a configuration attribute.
    // In any case, the PIN must be in the clear.
    keyStorePIN         = null;
    keyStorePINEnVar    = null;
    keyStorePINFile     = null;
    keyStorePINProperty = null;
pinSelection:
    {
      int msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          if (pinStr == null)
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET;
            String message = getMessage(msgID, String.valueOf(propertyName),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
          }
          else
          {
            keyStorePIN         = pinStr.toCharArray();
            keyStorePINProperty = propertyName;
            break pinSelection;
          }
        }
      }
      catch (InitializationException ie)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_ENVAR, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET;
            String message = getMessage(msgID, String.valueOf(enVarName),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
          }
          else
          {
            keyStorePIN      = pinStr.toCharArray();
            keyStorePINEnVar = enVarName;
            break pinSelection;
          }
        }
      }
      catch (InitializationException ie)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_FILE, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          if (! pinFile.exists())
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE;
            String message = getMessage(msgID, String.valueOf(fileName),
                                        String.valueOf(configEntryDN));
            throw new InitializationException(msgID, message);
          }
          else
          {
            String pinStr;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN),
                                          getExceptionMessage(ioe));
              throw new InitializationException(msgID, message, ioe);
            }
            if (pinStr == null)
            {
              msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_EMPTY;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN));
              throw new InitializationException(msgID, message);
            }
            else
            {
              keyStorePIN     = pinStr.toCharArray();
              keyStorePINFile = fileName;
              break pinSelection;
            }
          }
        }
      }
      catch (InitializationException ie)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, ie);
        }
        throw ie;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_FILE;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        {
          keyStorePIN = pinAttr.activeValue().toCharArray();
          break pinSelection;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        throw new InitializationException(msgID, message, e);
      }
    }
    if (keyStorePIN == null)
    {
      int msgID = MSGID_PKCS11_KEYMANAGER_NO_PIN;
      String message = getMessage(msgID, String.valueOf(configEntryDN));
      throw new ConfigException(msgID, message);
    }
    DirectoryServer.registerConfigurableComponent(this);
  }
  /**
   * {@inheritDoc}
   */
  @Override
  public void initializeKeyManagerProvider(
      PKCS11KeyManagerCfg configuration)
      throws ConfigException, InitializationException {
    // Store the DN of the configuration entry.
  public void initializeKeyManagerProvider(PKCS11KeyManagerCfg configuration)
         throws ConfigException, InitializationException
  {
    // Store the DN of the configuration entry and register to be notified of
    // configuration changes.
    currentConfig = configuration;
    configEntryDN = configuration.dn();
    configuration.addPKCS11ChangeListener(this);
    // Get the PIN needed to access the contents of the PKCS#11
    // keystore. We will offer several places to look for the PIN, and
@@ -395,9 +129,6 @@
    //
    // In any case, the PIN must be in the clear.
    keyStorePIN = null;
    keyStorePINEnVar = null;
    keyStorePINFile = null;
    keyStorePINProperty = null;
    if (configuration.getKeyStorePinProperty() != null) {
      String propertyName = configuration.getKeyStorePinProperty();
@@ -411,7 +142,6 @@
      }
      keyStorePIN = pinStr.toCharArray();
      keyStorePINProperty = propertyName;
    } else if (configuration.getKeyStorePinEnvironmentVariable() != null) {
      String enVarName = configuration
          .getKeyStorePinEnvironmentVariable();
@@ -425,7 +155,6 @@
      }
      keyStorePIN = pinStr.toCharArray();
      keyStorePINEnVar = enVarName;
    } else if (configuration.getKeyStorePinFile() != null) {
      String fileName = configuration.getKeyStorePinFile();
      File pinFile = getFileForPath(fileName);
@@ -463,18 +192,14 @@
      }
      keyStorePIN = pinStr.toCharArray();
      keyStorePINFile = fileName;
    } else if (configuration.getKeyStorePin() != null) {
      keyStorePIN = configuration.getKeyStorePin().toCharArray();
    } else {
      // Pin wasn't defined anywhere.
      int msgID = MSGID_PKCS11_KEYMANAGER_NO_PIN;
      String message = getMessage(msgID, String
          .valueOf(configEntryDN));
      String message = getMessage(msgID, String.valueOf(configEntryDN));
      throw new ConfigException(msgID, message);
    }
    DirectoryServer.registerConfigurableComponent(this);
  }
@@ -485,7 +210,7 @@
   */
  public void finalizeKeyManagerProvider()
  {
    DirectoryServer.deregisterConfigurableComponent(this);
    currentConfig.removePKCS11ChangeListener(this);
  }
@@ -548,600 +273,244 @@
  /**
   * 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.
   * {@inheritDoc}
   */
  public DN getConfigurableComponentEntryDN()
  public boolean isConfigurationChangeAcceptable(
                      PKCS11KeyManagerCfg configuration,
                      List<String> unacceptableReasons)
  {
    return configEntryDN;
  }
    boolean configAcceptable = true;
  /**
   * 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_PKCS11_KEYMANAGER_DESCRIPTION_PIN_PROPERTY;
    StringConfigAttribute pinPropertyAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_PIN_PROPERTY,
                                   getMessage(msgID), false, false, false,
                                   keyStorePINProperty);
    attrList.add(pinPropertyAttr);
    msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_ENVAR;
    StringConfigAttribute pinEnvVarAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_PIN_ENVAR,
                                   getMessage(msgID), false, false, false,
                                   keyStorePINEnVar);
    attrList.add(pinEnvVarAttr);
    msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_FILE;
    StringConfigAttribute pinFileAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_PIN_FILE,
                                   getMessage(msgID), false, false, false,
                                   keyStorePINFile);
    attrList.add(pinFileAttr);
    String pinString;
    if ((keyStorePINProperty == null) && (keyStorePINEnVar == null) &&
        (keyStorePINFile == null))
    // Get the PIN needed to access the contents of the keystore file.
    //
    // We will offer several places to look for the PIN, and we will
    // do so in the following order:
    //
    // - In a specified Java property
    // - In a specified environment variable
    // - In a specified file on the server filesystem.
    // - As the value of a configuration attribute.
    //
    // In any case, the PIN must be in the clear.
    if (configuration.getKeyStorePinProperty() != null)
    {
      pinString = new String(keyStorePIN);
      String propertyName = configuration.getKeyStorePinProperty();
      String pinStr = System.getProperty(propertyName);
      if (pinStr == null)
      {
        int msgID = MSGID_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET;
        unacceptableReasons.add(getMessage(msgID, String.valueOf(propertyName),
                                           String.valueOf(configEntryDN)));
        configAcceptable = false;
      }
    }
    else if (configuration.getKeyStorePinEnvironmentVariable() != null)
    {
      String enVarName = configuration.getKeyStorePinEnvironmentVariable();
      String pinStr    = System.getenv(enVarName);
      if (pinStr == null)
      {
        int msgID = MSGID_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET;
        unacceptableReasons.add(getMessage(msgID, String.valueOf(enVarName),
                                           String.valueOf(configEntryDN)));
        configAcceptable = false;
      }
    }
    else if (configuration.getKeyStorePinFile() != null)
    {
      String fileName = configuration.getKeyStorePinFile();
      File   pinFile  = getFileForPath(fileName);
      if (!pinFile.exists())
      {
        int msgID = MSGID_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE;
        unacceptableReasons.add(getMessage(msgID, String.valueOf(fileName),
                                           String.valueOf(configEntryDN)));
        configAcceptable = false;
      }
      else
      {
        String pinStr = null;
        BufferedReader br = null;
        try {
          br = new BufferedReader(new FileReader(pinFile));
          pinStr = br.readLine();
        }
        catch (IOException ioe)
        {
          int msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ;
          unacceptableReasons.add(getMessage(msgID, String.valueOf(fileName),
                                             String.valueOf(configEntryDN),
                                             getExceptionMessage(ioe)));
          configAcceptable = false;
        }
        finally
        {
          try
          {
            br.close();
          } catch (Exception e) {}
        }
        if (pinStr == null)
        {
          int msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_EMPTY;
          unacceptableReasons.add(getMessage(msgID, String.valueOf(fileName),
                                             String.valueOf(configEntryDN)));
          configAcceptable = false;
        }
      }
    }
    else if (configuration.getKeyStorePin() != null)
    {
      configuration.getKeyStorePin().toCharArray();
    }
    else
    {
      pinString = null;
    }
    msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_ATTR;
    StringConfigAttribute pinAttr =
         new StringConfigAttribute(ATTR_KEYSTORE_PIN, getMessage(msgID), false,
                                   false, false, pinString);
    attrList.add(pinAttr);
    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)
  {
    DN configEntryDN = configEntry.getDN();
    // Make sure that there is some way to determine the PIN.  Look for the PIN
    // in a property, environment variable, file, or configuration attribute, in
    // that order.
    char[] keyStorePIN = null;
pinSelection:
    {
      int msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          if (pinStr == null)
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET;
            String message = getMessage(msgID, String.valueOf(propertyName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            keyStorePIN = pinStr.toCharArray();
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_ENVAR, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET;
            String message = getMessage(msgID, String.valueOf(enVarName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            keyStorePIN = pinStr.toCharArray();
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_FILE, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          if (! pinFile.exists())
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE;
            String message = getMessage(msgID, String.valueOf(fileName),
                                        String.valueOf(configEntryDN));
            unacceptableReasons.add(message);
            return false;
          }
          else
          {
            String pinStr;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN),
                                          getExceptionMessage(ioe));
              unacceptableReasons.add(message);
              return false;
            }
            if (pinStr == null)
            {
              msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_EMPTY;
              String message = getMessage(msgID, String.valueOf(fileName),
                                          String.valueOf(configEntryDN));
              unacceptableReasons.add(message);
              return false;
            }
            else
            {
              keyStorePIN = pinStr.toCharArray();
              break pinSelection;
            }
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_FILE;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        {
          keyStorePIN = pinAttr.pendingValue().toCharArray();
          break pinSelection;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    getExceptionMessage(e));
        unacceptableReasons.add(message);
        return false;
      }
    }
    if (keyStorePIN == null)
    {
      // Pin wasn't defined anywhere.
      int msgID = MSGID_PKCS11_KEYMANAGER_NO_PIN;
      String message = getMessage(msgID, String.valueOf(configEntryDN));
      unacceptableReasons.add(message);
      return false;
      unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN)));
      configAcceptable = false;
    }
    // If we've gotten here, then everything looks OK.
    return true;
    return configAcceptable;
  }
  /**
   * 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.
   * {@inheritDoc}
   */
  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
                                                  boolean detailedResults)
  public ConfigChangeResult applyConfigurationChange(
                                 PKCS11KeyManagerCfg configuration)
  {
    ResultCode        resultCode          = ResultCode.SUCCESS;
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    // Make sure that there is some way to determine the PIN.  Look for the PIN
    // in a property, environment variable, file, or configuration attribute, in
    // that order.
    char[] newKeyStorePIN         = null;
    String newKeyStorePINEnVar    = null;
    String newKeyStorePINFile     = null;
    String newKeyStorePINProperty = null;
pinSelection:
    // Get the PIN needed to access the contents of the keystore file.
    //
    // We will offer several places to look for the PIN, and we will
    // do so in the following order:
    //
    // - In a specified Java property
    // - In a specified environment variable
    // - In a specified file on the server filesystem.
    // - As the value of a configuration attribute.
    //
    // In any case, the PIN must be in the clear.
    char[] newPIN = null;
    if (configuration.getKeyStorePinProperty() != null)
    {
      int msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_PROPERTY;
      StringConfigAttribute pinPropertyStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_PROPERTY,
                                     getMessage(msgID), false, false, false);
      try
      String propertyName = configuration.getKeyStorePinProperty();
      String pinStr = System.getProperty(propertyName);
      if (pinStr == null)
      {
        StringConfigAttribute pinPropertyAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinPropertyStub);
        if (pinPropertyAttr != null)
        {
          String propertyName = pinPropertyAttr.activeValue();
          String pinStr       = System.getProperty(propertyName);
          if (pinStr == null)
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET;
            messages.add(getMessage(msgID, String.valueOf(propertyName),
                                    String.valueOf(configEntryDN)));
        resultCode = DirectoryServer.getServerErrorResultCode();
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
          }
          else
          {
            newKeyStorePIN         = pinStr.toCharArray();
            newKeyStorePINProperty = propertyName;
            break pinSelection;
          }
        }
        int msgID = MSGID_PKCS11_KEYMANAGER_PIN_PROPERTY_NOT_SET;
        messages.add(getMessage(msgID, String.valueOf(propertyName),
                                String.valueOf(configEntryDN)));
      }
      catch (Exception e)
      else
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_PROPERTY;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_ENVAR;
      StringConfigAttribute pinEnVarStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_ENVAR, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinEnVarAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinEnVarStub);
        if (pinEnVarAttr != null)
        {
          String enVarName = pinEnVarAttr.activeValue();
          String pinStr    = System.getenv(enVarName);
          if (pinStr == null)
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET;
            messages.add(getMessage(msgID, String.valueOf(enVarName),
                                    String.valueOf(configEntryDN)));
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
          }
          else
          {
            newKeyStorePIN      = pinStr.toCharArray();
            newKeyStorePINEnVar = enVarName;
            break pinSelection;
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_ENVAR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_FILE;
      StringConfigAttribute pinFileStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN_FILE, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinFileAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinFileStub);
        if (pinFileAttr != null)
        {
          String fileName = pinFileAttr.activeValue();
          File pinFile = getFileForPath(fileName);
          if (! pinFile.exists())
          {
            msgID = MSGID_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE;
            messages.add(getMessage(msgID, String.valueOf(fileName),
                                    String.valueOf(configEntryDN)));
            if (resultCode == ResultCode.SUCCESS)
            {
              resultCode = ResultCode.CONSTRAINT_VIOLATION;
            }
            break pinSelection;
          }
          else
          {
            String pinStr;
            try
            {
              BufferedReader br = new BufferedReader(new FileReader(pinFile));
              pinStr = br.readLine();
              br.close();
            }
            catch (IOException ioe)
            {
              msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ;
              messages.add(getMessage(msgID, String.valueOf(fileName),
                                      String.valueOf(configEntryDN),
                                      getExceptionMessage(ioe)));
              if (resultCode == ResultCode.SUCCESS)
              {
                resultCode = DirectoryServer.getServerErrorResultCode();
              }
              break pinSelection;
            }
            if (pinStr == null)
            {
              msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_EMPTY;
              messages.add(getMessage(msgID, String.valueOf(fileName),
                                      String.valueOf(configEntryDN)));
              if (resultCode == ResultCode.SUCCESS)
              {
                resultCode = ResultCode.CONSTRAINT_VIOLATION;
              }
              break pinSelection;
            }
            else
            {
              newKeyStorePIN     = pinStr.toCharArray();
              newKeyStorePINFile = fileName;
              break pinSelection;
            }
          }
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_FILE;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
      }
      msgID = MSGID_PKCS11_KEYMANAGER_DESCRIPTION_PIN_ATTR;
      StringConfigAttribute pinStub =
           new StringConfigAttribute(ATTR_KEYSTORE_PIN, getMessage(msgID),
                                     false, false, false);
      try
      {
        StringConfigAttribute pinAttr =
             (StringConfigAttribute)
             configEntry.getConfigAttribute(pinStub);
        if (pinAttr != null)
        {
          newKeyStorePIN = pinAttr.activeValue().toCharArray();
          break pinSelection;
        }
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
        msgID = MSGID_PKCS11_KEYMANAGER_CANNOT_DETERMINE_PIN_FROM_ATTR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                getExceptionMessage(e)));
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
        }
        break pinSelection;
        newPIN = pinStr.toCharArray();
      }
    }
    if (newKeyStorePIN == null)
    else if (configuration.getKeyStorePinEnvironmentVariable() != null)
    {
      String enVarName = configuration.getKeyStorePinEnvironmentVariable();
      String pinStr    = System.getenv(enVarName);
      if (pinStr == null)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
        int msgID = MSGID_PKCS11_KEYMANAGER_PIN_ENVAR_NOT_SET;
        messages.add(getMessage(msgID, String.valueOf(enVarName),
                                String.valueOf(configEntryDN)));
      }
      else
      {
        newPIN = pinStr.toCharArray();
      }
    }
    else if (configuration.getKeyStorePinFile() != null)
    {
      String fileName = configuration.getKeyStorePinFile();
      File   pinFile  = getFileForPath(fileName);
      if (!pinFile.exists())
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
        int msgID = MSGID_PKCS11_KEYMANAGER_PIN_NO_SUCH_FILE;
        messages.add(getMessage(msgID, String.valueOf(fileName),
                                String.valueOf(configEntryDN)));
      }
      else
      {
        String pinStr = null;
        BufferedReader br = null;
        try {
          br = new BufferedReader(new FileReader(pinFile));
          pinStr = br.readLine();
        }
        catch (IOException ioe)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
          int msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_CANNOT_READ;
          messages.add(getMessage(msgID, String.valueOf(fileName),
                                  String.valueOf(configEntryDN),
                                  getExceptionMessage(ioe)));
        }
        finally
        {
          try
          {
            br.close();
          } catch (Exception e) {}
        }
        if (pinStr == null)
        {
          resultCode = DirectoryServer.getServerErrorResultCode();
          int msgID = MSGID_PKCS11_KEYMANAGER_PIN_FILE_EMPTY;
          messages.add(getMessage(msgID, String.valueOf(fileName),
                                  String.valueOf(configEntryDN)));
        }
        else
        {
          newPIN = pinStr.toCharArray();
        }
      }
    }
    else if (configuration.getKeyStorePin() != null)
    {
      newPIN = configuration.getKeyStorePin().toCharArray();
    }
    else
    {
      // Pin wasn't defined anywhere.
      resultCode = DirectoryServer.getServerErrorResultCode();
      int msgID = MSGID_PKCS11_KEYMANAGER_NO_PIN;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = ResultCode.CONSTRAINT_VIOLATION;
      }
    }
    // If everything looks successful, then apply the changes.
    if (resultCode == ResultCode.SUCCESS)
    {
      if (! Arrays.equals(keyStorePIN, newKeyStorePIN))
      {
        keyStorePIN = newKeyStorePIN;
        keyStorePINProperty = newKeyStorePINProperty;
        keyStorePINEnVar    = newKeyStorePINEnVar;
        keyStorePINFile     = newKeyStorePINFile;
        if (detailedResults)
        {
          int msgID = MSGID_PKCS11_KEYMANAGER_UPDATED_PIN;
          messages.add(getMessage(msgID));
        }
      }
      currentConfig = configuration;
      keyStorePIN   = newPIN;
    }
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/FileBasedKeyManagerProviderTestCase.java
@@ -38,6 +38,9 @@
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.server.AdminTestCaseUtils;
import org.opends.server.admin.std.meta.FileBasedKeyManagerCfgDefn;
import org.opends.server.admin.std.server.FileBasedKeyManagerCfg;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
@@ -175,12 +178,12 @@
  public void testVvalidConfigs(Entry e)
         throws Exception
  {
    DN parentDN = DN.decode("cn=SSL,cn=config");
    ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
    ConfigEntry configEntry = new ConfigEntry(e, parentEntry);
    FileBasedKeyManagerCfg configuration =
         AdminTestCaseUtils.getConfiguration(
              FileBasedKeyManagerCfgDefn.getInstance(), e);
    FileBasedKeyManagerProvider provider = new FileBasedKeyManagerProvider();
    provider.initializeKeyManagerProvider(configEntry);
    provider.initializeKeyManagerProvider(configuration);
    provider.finalizeKeyManagerProvider();
  }
@@ -197,7 +200,7 @@
         throws Exception
  {
    List<Entry> entries = TestCaseUtils.makeEntries(
         "dn: cn=Key Manager Provider,cn=SSL,cn=config",
         "dn: cn=No Key Store File,cn=SSL,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-key-manager-provider",
         "objectClass: ds-cfg-file-based-key-manager-provider",
@@ -207,7 +210,7 @@
         "ds-cfg-key-manager-provider-enabled: true",
         "ds-cfg-key-store-pin: password",
         "",
         "dn: cn=Key Manager Provider,cn=SSL,cn=config",
         "dn: cn=Nonexistent Key Store File,cn=SSL,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-key-manager-provider",
         "objectClass: ds-cfg-file-based-key-manager-provider",
@@ -218,7 +221,7 @@
         "ds-cfg-key-store-file: config/nosuchfile",
         "ds-cfg-key-store-pin: password",
         "",
         "dn: cn=Key Manager Provider,cn=SSL,cn=config",
         "dn: cn=No Key Store PIN,cn=SSL,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-key-manager-provider",
         "objectClass: ds-cfg-file-based-key-manager-provider",
@@ -228,7 +231,7 @@
         "ds-cfg-key-manager-provider-enabled: true",
         "ds-cfg-key-store-file: config/server.keystore",
         "",
         "dn: cn=Key Manager Provider,cn=SSL,cn=config",
         "dn: cn=Nonexistent Key Store PIN File,cn=SSL,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-key-manager-provider",
         "objectClass: ds-cfg-file-based-key-manager-provider",
@@ -239,7 +242,7 @@
         "ds-cfg-key-store-file: config/server.keystore",
         "ds-cfg-key-store-pin-file: config/nosuchfile",
         "",
         "dn: cn=Key Manager Provider,cn=SSL,cn=config",
         "dn: cn=Empty Key Store PIN File,cn=SSL,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-key-manager-provider",
         "objectClass: ds-cfg-file-based-key-manager-provider",
@@ -250,7 +253,7 @@
         "ds-cfg-key-store-file: config/server.keystore",
         "ds-cfg-key-store-pin-file: config/empty",
         "",
         "dn: cn=Key Manager Provider,cn=SSL,cn=config",
         "dn: cn=Nonexistent Key Store PIN Property,cn=SSL,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-key-manager-provider",
         "objectClass: ds-cfg-file-based-key-manager-provider",
@@ -261,7 +264,7 @@
         "ds-cfg-key-store-file: config/server.keystore",
         "ds-cfg-key-store-pin-property: nosuchproperty",
         "",
         "dn: cn=Key Manager Provider,cn=SSL,cn=config",
         "dn: cn=Nonexistent Key Store PIN Env Variable,cn=SSL,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-key-manager-provider",
         "objectClass: ds-cfg-file-based-key-manager-provider",
@@ -272,7 +275,7 @@
         "ds-cfg-key-store-file: config/server.keystore",
         "ds-cfg-key-store-pin-environment-variable: nosuchenv",
         "",
         "dn: cn=Key Manager Provider,cn=SSL,cn=config",
         "dn: cn=Invalid Key Store Type,cn=SSL,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-key-manager-provider",
         "objectClass: ds-cfg-file-based-key-manager-provider",
@@ -310,12 +313,13 @@
  public void testInvalidConfigs(Entry e)
         throws Exception
  {
    DN parentDN = DN.decode("cn=SSL,cn=config");
    ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
    ConfigEntry configEntry = new ConfigEntry(e, parentEntry);
    FileBasedKeyManagerCfg configuration =
         AdminTestCaseUtils.getConfiguration(
              FileBasedKeyManagerCfgDefn.getInstance(), e);
    FileBasedKeyManagerProvider provider = new FileBasedKeyManagerProvider();
    provider.initializeKeyManagerProvider(configEntry);
    provider.initializeKeyManagerProvider(configuration);
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/FileBasedTrustManagerProviderTestCase.java
@@ -38,6 +38,9 @@
import org.testng.annotations.Test;
import org.opends.server.TestCaseUtils;
import org.opends.server.admin.server.AdminTestCaseUtils;
import org.opends.server.admin.std.meta.FileBasedTrustManagerCfgDefn;
import org.opends.server.admin.std.server.FileBasedTrustManagerCfg;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
@@ -173,12 +176,12 @@
  public void testVvalidConfigs(Entry e)
         throws Exception
  {
    DN parentDN = DN.decode("cn=SSL,cn=config");
    ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
    ConfigEntry configEntry = new ConfigEntry(e, parentEntry);
    FileBasedTrustManagerCfg configuration =
         AdminTestCaseUtils.getConfiguration(
              FileBasedTrustManagerCfgDefn.getInstance(), e);
    FileBasedTrustManagerProvider provider = new FileBasedTrustManagerProvider();
    provider.initializeTrustManagerProvider(configEntry);
    provider.initializeTrustManagerProvider(configuration);
    provider.finalizeTrustManagerProvider();
  }
@@ -298,13 +301,13 @@
  public void testInvalidConfigs(Entry e)
         throws Exception
  {
    DN parentDN = DN.decode("cn=SSL,cn=config");
    ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
    ConfigEntry configEntry = new ConfigEntry(e, parentEntry);
    FileBasedTrustManagerCfg configuration =
         AdminTestCaseUtils.getConfiguration(
              FileBasedTrustManagerCfgDefn.getInstance(), e);
    FileBasedTrustManagerProvider provider =
         new FileBasedTrustManagerProvider();
    provider.initializeTrustManagerProvider(configEntry);
    provider.initializeTrustManagerProvider(configuration);
    for (StringBuilder sb : e.toLDIF())
    {
      System.err.println(sb.toString());
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/NullKeyManagerProviderTestCase.java
@@ -68,7 +68,7 @@
         throws Exception
  {
    NullKeyManagerProvider provider = new NullKeyManagerProvider();
    provider.initializeKeyManagerProvider((ConfigEntry) null);
    provider.initializeKeyManagerProvider(null);
    assertNotNull(provider.getKeyManagers());
    provider.finalizeKeyManagerProvider();
  }