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

matthew_swift
23.26.2007 feb5d90ec016c99712f19c5485cf7633cd38f111
opends/src/server/org/opends/server/extensions/FingerprintCertificateMapper.java
@@ -33,19 +33,13 @@
import java.security.cert.X509Certificate;
import javax.security.auth.x500.X500Principal;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.FingerprintCertificateMapperCfg;
import org.opends.server.api.CertificateMapper;
import org.opends.server.api.ConfigurableComponent;
import org.opends.server.config.ConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.config.DNConfigAttribute;
import org.opends.server.config.MultiChoiceConfigAttribute;
import org.opends.server.config.StringConfigAttribute;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
@@ -61,7 +55,6 @@
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchScope;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import org.opends.server.types.DebugLogLevel;
@@ -78,43 +71,24 @@
 * exactly one matching user entry for the mapping to be successful.
 */
public class FingerprintCertificateMapper
       extends CertificateMapper
       implements ConfigurableComponent
       extends CertificateMapper<FingerprintCertificateMapperCfg>
       implements ConfigurationChangeListener<
                       FingerprintCertificateMapperCfg>
{
  /**
   * The set of allowed fingerprint algorithms.
   */
  private static final Set<String> FINGERPRINT_ALGORITHMS;
  // The attribute type that will be used to map the certificate's fingerprint.
  private AttributeType fingerprintAttributeType;
  // The DN of the configuration entry for this certificate mapper.
  private DN configEntryDN;
  // The set of base DNs below which the search will be performed.
  private DN[] baseDNs;
  // The current configuration for this certificate mapper.
  private FingerprintCertificateMapperCfg currentConfig;
  // The algorithm that will be used to generate the fingerprint.
  private String fingerprintAlgorithm;
  static
  {
    LinkedHashSet<String> algorithmSet = new LinkedHashSet<String>(2);
    algorithmSet.add("md5");
    algorithmSet.add("sha1");
    FINGERPRINT_ALGORITHMS = algorithmSet;
  }
  /**
   * Creates a new instance of this certificate mapper.  Note that all actual
   * initialization should be done in the
@@ -123,7 +97,6 @@
  public FingerprintCertificateMapper()
  {
    super();
  }
@@ -131,128 +104,39 @@
  /**
   * {@inheritDoc}
   */
  public void initializeCertificateMapper(ConfigEntry configEntry)
  public void initializeCertificateMapper(
                   FingerprintCertificateMapperCfg configuration)
         throws ConfigException, InitializationException
  {
    this.configEntryDN = configEntry.getDN();
    configuration.addFingerprintChangeListener(this);
    currentConfig = configuration;
    configEntryDN = configuration.dn();
    // Get the attribute type that will be used to hold the fingerprint.
    int msgID = MSGID_FCM_DESCRIPTION_FINGERPRINT_ATTR;
    StringConfigAttribute attrStub =
         new StringConfigAttribute(ATTR_CERTIFICATE_FINGERPRINT_ATTR,
                                   getMessage(msgID), true, false, false);
    try
    String attrName = configuration.getFingerprintAttribute();
    fingerprintAttributeType =
         DirectoryServer.getAttributeType(toLowerCase(attrName), false);
    if (fingerprintAttributeType == null)
    {
      StringConfigAttribute attrAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(attrStub);
      if (attrAttr == null)
      {
        msgID = MSGID_FCM_NO_FINGERPRINT_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    ATTR_CERTIFICATE_FINGERPRINT_ATTR);
        throw new ConfigException(msgID, message);
      }
      else
      {
        String attrName  = attrAttr.pendingValue();
        String lowerName = toLowerCase(attrName);
        fingerprintAttributeType =
             DirectoryServer.getAttributeType(lowerName, false);
        if (fingerprintAttributeType == null)
        {
          msgID = MSGID_FCM_NO_SUCH_ATTR;
          String message = getMessage(msgID, String.valueOf(configEntryDN),
                                      attrName);
          throw new ConfigException(msgID, message);
        }
      }
    }
    catch (ConfigException ce)
    {
      throw ce;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FCM_CANNOT_GET_FINGERPRINT_ATTR;
      int    msgID   = MSGID_FCM_NO_SUCH_ATTR;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  stackTraceToSingleLineString(e));
      throw new InitializationException(msgID, message, e);
                                  attrName);
      throw new ConfigException(msgID, message);
    }
    // Get the fingerprint algorithm.
    msgID = MSGID_FCM_DESCRIPTION_FINGERPRINT_ALGORITHM;
    MultiChoiceConfigAttribute algorithmStub =
         new MultiChoiceConfigAttribute(ATTR_CERTIFICATE_FINGERPRINT_ALGORITHM,
                                        getMessage(msgID), true, false, false,
                                        FINGERPRINT_ALGORITHMS);
    try
    // Get the algorithm that will be used to generate the fingerprint.
    switch (configuration.getFingerprintAlgorithm())
    {
      MultiChoiceConfigAttribute algorithmAttr =
           (MultiChoiceConfigAttribute)
           configEntry.getConfigAttribute(algorithmStub);
      if (algorithmAttr == null)
      {
        msgID = MSGID_FCM_NO_FINGERPRINT_ALGORITHM;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    ATTR_CERTIFICATE_FINGERPRINT_ALGORITHM);
        throw new ConfigException(msgID, message);
      }
      else
      {
        fingerprintAlgorithm = algorithmAttr.pendingValue();
      }
      case MD5:
        fingerprintAlgorithm = "MD5";
        break;
      case SHA1:
        fingerprintAlgorithm = "SHA1";
        break;
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FCM_CANNOT_GET_FINGERPRINT_ALGORITHM;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  stackTraceToSingleLineString(e));
      throw new InitializationException(msgID, message, e);
    }
    // Get the set of base DNs below which to perform the searches.
    baseDNs = null;
    msgID = MSGID_FCM_DESCRIPTION_BASE_DN;
    DNConfigAttribute baseStub =
         new DNConfigAttribute(ATTR_CERTIFICATE_SUBJECT_BASEDN,
                               getMessage(msgID), false, true, false);
    try
    {
      DNConfigAttribute baseAttr =
           (DNConfigAttribute) configEntry.getConfigAttribute(baseStub);
      if (baseAttr != null)
      {
        List<DN> dnList = baseAttr.activeValues();
        baseDNs = new DN[dnList.size()];
        dnList.toArray(baseDNs);
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FCM_CANNOT_GET_BASE_DN;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  stackTraceToSingleLineString(e));
      throw new InitializationException(msgID, message, e);
    }
    DirectoryServer.registerConfigurableComponent(this);
  }
@@ -262,7 +146,7 @@
   */
  public void finalizeCertificateMapper()
  {
    DirectoryServer.deregisterConfigurableComponent(this);
    currentConfig.removeFingerprintChangeListener(this);
  }
@@ -273,6 +157,10 @@
  public Entry mapCertificateToUser(Certificate[] certificateChain)
         throws DirectoryException
  {
    FingerprintCertificateMapperCfg config = currentConfig;
    AttributeType fingerprintAttributeType = this.fingerprintAttributeType;
    String fingerprintAlgorithm = this.fingerprintAlgorithm;
    // Make sure that a peer certificate was provided.
    if ((certificateChain == null) || (certificateChain.length == 0))
    {
@@ -340,11 +228,10 @@
    // If we have an explicit set of base DNs, then use it.  Otherwise, use the
    // set of public naming contexts in the server.
    DN[] bases = baseDNs;
    if (bases == null)
    Collection<DN> baseDNs = config.getUserBaseDN();
    if ((baseDNs == null) || baseDNs.isEmpty())
    {
      bases = new DN[0];
      bases = DirectoryServer.getPublicNamingContexts().keySet().toArray(bases);
      baseDNs = DirectoryServer.getPublicNamingContexts().keySet();
    }
@@ -353,7 +240,7 @@
    Entry userEntry = null;
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    for (DN baseDN : bases)
    for (DN baseDN : baseDNs)
    {
      InternalSearchOperation searchOperation =
           conn.processSearch(baseDN, SearchScope.WHOLE_SUBTREE, filter);
@@ -384,201 +271,24 @@
  /**
   * 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(
                      FingerprintCertificateMapperCfg configuration,
                      List<String> unacceptableReasons)
  {
    return configEntryDN;
  }
  /**
   * Retrieves the set of configuration attributes that are associated
   * with this configurable component.
   *
   * @return  The set of configuration attributes that are associated
   *          with this configurable component.
   */
  public List<ConfigAttribute> getConfigurationAttributes()
  {
    LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>();
    int msgID = MSGID_FCM_DESCRIPTION_FINGERPRINT_ATTR;
    attrList.add(new StringConfigAttribute(ATTR_CERTIFICATE_SUBJECT_ATTR,
                          getMessage(msgID), true, false, false,
                          fingerprintAttributeType.getNameOrOID()));
    msgID = MSGID_FCM_DESCRIPTION_FINGERPRINT_ALGORITHM;
    attrList.add(new MultiChoiceConfigAttribute(
                          ATTR_CERTIFICATE_FINGERPRINT_ALGORITHM,
                          getMessage(msgID), true, false, false,
                          FINGERPRINT_ALGORITHMS, fingerprintAlgorithm));
    LinkedList<DN> dnList = new LinkedList<DN>();
    if (baseDNs != null)
    {
      for (DN baseDN : baseDNs)
      {
        dnList.add(baseDN);
      }
    }
    msgID = MSGID_FCM_DESCRIPTION_BASE_DN;
    attrList.add(new DNConfigAttribute(ATTR_CERTIFICATE_SUBJECT_BASEDN,
                                       getMessage(msgID), false, true, false,
                                       dnList));
    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();
    boolean configAcceptable = true;
    // Get the attribute type that will be used to hold the fingerprint.
    AttributeType newFingerprintType = null;
    int msgID = MSGID_FCM_DESCRIPTION_FINGERPRINT_ATTR;
    StringConfigAttribute attrStub =
         new StringConfigAttribute(ATTR_CERTIFICATE_FINGERPRINT_ATTR,
                                   getMessage(msgID), true, false, false);
    try
    // Make sure that the fingerprint attribute is defined in the server schema.
    String attrName = configuration.getFingerprintAttribute();
    AttributeType newFingerprintType =
                       DirectoryServer.getAttributeType(toLowerCase(attrName),
                                       false);
    if (newFingerprintType == null)
    {
      StringConfigAttribute attrAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(attrStub);
      if (attrAttr == null)
      {
        msgID = MSGID_FCM_NO_FINGERPRINT_ATTR;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    ATTR_CERTIFICATE_FINGERPRINT_ATTR);
        unacceptableReasons.add(message);
        configAcceptable = false;
      }
      else
      {
        String attrName  = attrAttr.pendingValue();
        String lowerName = toLowerCase(attrName);
        newFingerprintType =
             DirectoryServer.getAttributeType(lowerName, false);
        if (newFingerprintType == null)
        {
          msgID = MSGID_FCM_NO_SUCH_ATTR;
          String message = getMessage(msgID, String.valueOf(configEntryDN),
                                      attrName);
        unacceptableReasons.add(message);
        configAcceptable = false;
        }
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FCM_CANNOT_GET_FINGERPRINT_ATTR;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  stackTraceToSingleLineString(e));
      unacceptableReasons.add(message);
      configAcceptable = false;
    }
    // Get the fingerprint algorithm.
    String newFingerprintAlgorithm = null;
    msgID = MSGID_FCM_DESCRIPTION_FINGERPRINT_ALGORITHM;
    MultiChoiceConfigAttribute algorithmStub =
         new MultiChoiceConfigAttribute(ATTR_CERTIFICATE_FINGERPRINT_ALGORITHM,
                                        getMessage(msgID), true, false, false,
                                        FINGERPRINT_ALGORITHMS);
    try
    {
      MultiChoiceConfigAttribute algorithmAttr =
           (MultiChoiceConfigAttribute)
           configEntry.getConfigAttribute(algorithmStub);
      if (algorithmAttr == null)
      {
        msgID = MSGID_FCM_NO_FINGERPRINT_ALGORITHM;
        String message = getMessage(msgID, String.valueOf(configEntryDN),
                                    ATTR_CERTIFICATE_FINGERPRINT_ALGORITHM);
        unacceptableReasons.add(message);
        configAcceptable = false;
      }
      else
      {
        newFingerprintAlgorithm = algorithmAttr.pendingValue();
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FCM_CANNOT_GET_FINGERPRINT_ALGORITHM;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  stackTraceToSingleLineString(e));
      unacceptableReasons.add(message);
      configAcceptable = false;
    }
    // Get the set of base DNs below which to perform the searches.
    DN[] newBaseDNs = null;
    msgID = MSGID_FCM_DESCRIPTION_BASE_DN;
    DNConfigAttribute baseStub =
         new DNConfigAttribute(ATTR_CERTIFICATE_SUBJECT_BASEDN,
                               getMessage(msgID), false, true, false);
    try
    {
      DNConfigAttribute baseAttr =
           (DNConfigAttribute) configEntry.getConfigAttribute(baseStub);
      if (baseAttr != null)
      {
        List<DN> dnList = baseAttr.activeValues();
        newBaseDNs = new DN[dnList.size()];
        dnList.toArray(newBaseDNs);
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      msgID = MSGID_FCM_CANNOT_GET_BASE_DN;
      String message = getMessage(msgID, String.valueOf(configEntryDN),
                                  stackTraceToSingleLineString(e));
      unacceptableReasons.add(message);
      unacceptableReasons.add(getMessage(MSGID_FCM_NO_SUCH_ATTR,
                                         String.valueOf(configEntryDN),
                                         attrName));
      configAcceptable = false;
    }
@@ -589,170 +299,43 @@
  /**
   * 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(
              FingerprintCertificateMapperCfg configuration)
  {
    DN                configEntryDN       = configEntry.getDN();
    ResultCode        resultCode          = ResultCode.SUCCESS;
    ArrayList<String> messages            = new ArrayList<String>();
    boolean           adminActionRequired = false;
    ArrayList<String> messages            = new ArrayList<String>();
    // Get the attribute type that will be used to hold the fingerprint.
    AttributeType newFingerprintType = null;
    int msgID = MSGID_FCM_DESCRIPTION_FINGERPRINT_ATTR;
    StringConfigAttribute attrStub =
         new StringConfigAttribute(ATTR_CERTIFICATE_FINGERPRINT_ATTR,
                                   getMessage(msgID), true, false, false);
    try
    // Make sure that the fingerprint attribute is defined in the server schema.
    String attrName = configuration.getFingerprintAttribute();
    AttributeType newFingerprintType =
                       DirectoryServer.getAttributeType(toLowerCase(attrName),
                                       false);
    if (newFingerprintType == null)
    {
      StringConfigAttribute attrAttr =
           (StringConfigAttribute) configEntry.getConfigAttribute(attrStub);
      if (attrAttr == null)
      {
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = ResultCode.OBJECTCLASS_VIOLATION;
        }
        msgID = MSGID_FCM_NO_FINGERPRINT_ATTR;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                ATTR_CERTIFICATE_FINGERPRINT_ATTR));
      }
      else
      {
        String attrName  = attrAttr.pendingValue();
        String lowerName = toLowerCase(attrName);
        newFingerprintType =
             DirectoryServer.getAttributeType(lowerName, false);
        if (newFingerprintType == null)
        {
          if (resultCode == ResultCode.SUCCESS)
          {
            resultCode = ResultCode.NO_SUCH_ATTRIBUTE;
          }
          msgID = MSGID_FCM_NO_SUCH_ATTR;
          messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                  attrName));
        }
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
        resultCode = ResultCode.NO_SUCH_ATTRIBUTE;
      }
      msgID = MSGID_FCM_CANNOT_GET_FINGERPRINT_ATTR;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              stackTraceToSingleLineString(e)));
      messages.add(getMessage(MSGID_FCM_NO_SUCH_ATTR,
                              String.valueOf(configEntryDN), attrName));
    }
    // Get the fingerprint algorithm.
    // Get the algorithm that will be used to generate the fingerprint.
    String newFingerprintAlgorithm = null;
    msgID = MSGID_FCM_DESCRIPTION_FINGERPRINT_ALGORITHM;
    MultiChoiceConfigAttribute algorithmStub =
         new MultiChoiceConfigAttribute(ATTR_CERTIFICATE_FINGERPRINT_ALGORITHM,
                                        getMessage(msgID), true, false, false,
                                        FINGERPRINT_ALGORITHMS);
    try
    switch (configuration.getFingerprintAlgorithm())
    {
      MultiChoiceConfigAttribute algorithmAttr =
           (MultiChoiceConfigAttribute)
           configEntry.getConfigAttribute(algorithmStub);
      if (algorithmAttr == null)
      {
        if (resultCode == ResultCode.SUCCESS)
        {
          resultCode = ResultCode.OBJECTCLASS_VIOLATION;
        }
        msgID = MSGID_FCM_NO_FINGERPRINT_ALGORITHM;
        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                                ATTR_CERTIFICATE_FINGERPRINT_ALGORITHM));
      }
      else
      {
        newFingerprintAlgorithm = algorithmAttr.pendingValue();
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
      }
      msgID = MSGID_FCM_CANNOT_GET_FINGERPRINT_ALGORITHM;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              stackTraceToSingleLineString(e)));
    }
    // Get the set of base DNs below which to perform the searches.
    DN[] newBaseDNs = null;
    msgID = MSGID_FCM_DESCRIPTION_BASE_DN;
    DNConfigAttribute baseStub =
         new DNConfigAttribute(ATTR_CERTIFICATE_SUBJECT_BASEDN,
                               getMessage(msgID), false, true, false);
    try
    {
      DNConfigAttribute baseAttr =
           (DNConfigAttribute) configEntry.getConfigAttribute(baseStub);
      if (baseAttr != null)
      {
        List<DN> dnList = baseAttr.activeValues();
        newBaseDNs = new DN[dnList.size()];
        dnList.toArray(newBaseDNs);
      }
    }
    catch (Exception e)
    {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = DirectoryServer.getServerErrorResultCode();
      }
      msgID = MSGID_FCM_CANNOT_GET_BASE_DN;
      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
                              stackTraceToSingleLineString(e)));
      case MD5:
        newFingerprintAlgorithm = "MD5";
        break;
      case SHA1:
        newFingerprintAlgorithm = "SHA1";
        break;
    }
@@ -760,10 +343,11 @@
    {
      fingerprintAttributeType = newFingerprintType;
      fingerprintAlgorithm     = newFingerprintAlgorithm;
      baseDNs                  = newBaseDNs;
      currentConfig            = configuration;
    }
    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
   return new ConfigChangeResult(resultCode, adminActionRequired, messages);
  }
}