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

Matthew Swift
22.08.2015 16204ee68758e8a08375c605390d633ca915f824
OPENDJ-2516: improve configuration validation for tamper proof logging

This is a partial fix for OPENDJ-2516 since it traps most configuration
mistakes:

* verify that the key store file and pin properties are specified when
tamper evident logging is enabled
* verify that the key store file and pin file are readable and not
empty.

This change does not validate the content of the keystore which should
really be the responsibility of CAUD. However, the error reporting in
this case does not seem to be working very well, hence this change is
just a partial fix.
3 files modified
110 ■■■■■ changed files
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/CsvFileAccessLogPublisherConfiguration.xml 22 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/loggers/CsvFileAccessLogPublisher.java 78 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/messages/org/opends/messages/logger.properties 10 ●●●● patch | view | raw | blame | history
opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/CsvFileAccessLogPublisherConfiguration.xml
@@ -33,6 +33,26 @@
    <adm:user-friendly-plural-name />
    publish access messages to CSV files.
  </adm:synopsis>
  <adm:constraint>
    <adm:synopsis>
      A key store file and PIN must be specified when this
      <adm:user-friendly-name />
      is enabled and it is configured to perform tamper
      evident logging.
    </adm:synopsis>
    <adm:condition>
      <adm:implies>
        <adm:and>
          <adm:contains property="enabled" value="true" />
          <adm:contains property="tamper-evident" value="true" />
        </adm:and>
        <adm:and>
          <adm:is-present property="key-store-file" />
          <adm:is-present property="key-store-pin-file" />
        </adm:and>
      </adm:implies>
    </adm:condition>
  </adm:constraint>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:name>ds-cfg-csv-file-access-log-publisher</ldap:name>
@@ -256,7 +276,7 @@
            A path to an existing file that is readable by the server.
          </adm:synopsis>
        </adm:pattern>
      </adm:string>
      </adm:string>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
opendj-server-legacy/src/main/java/org/opends/server/loggers/CsvFileAccessLogPublisher.java
@@ -25,12 +25,21 @@
 */
package org.opends.server.loggers;
import static org.opends.messages.LoggerMessages.*;
import static org.opends.server.util.StaticUtils.getFileForPath;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.List;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.LocalizableMessageDescriptor;
import org.forgerock.opendj.config.server.ConfigChangeResult;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.CsvFileAccessLogPublisherCfg;
import org.opends.server.types.DN;
/**
 * Common Audit publisher which publishes access events to CSV files.
@@ -54,10 +63,77 @@
  }
  @Override
  public boolean isConfigurationAcceptable(final CsvFileAccessLogPublisherCfg configuration,
                                           final List<LocalizableMessage> unacceptableReasons)
  {
    return super.isConfigurationAcceptable(configuration, unacceptableReasons)
            && isTamperEvidentConfigurationAcceptable(configuration, unacceptableReasons);
  }
  @Override
  public boolean isConfigurationChangeAcceptable(final CsvFileAccessLogPublisherCfg config,
      final List<LocalizableMessage> unacceptableReasons)
  {
    return true;
    return isTamperEvidentConfigurationAcceptable(config, unacceptableReasons);
  }
  private boolean isTamperEvidentConfigurationAcceptable(final CsvFileAccessLogPublisherCfg config,
                                                         final List<LocalizableMessage> unacceptableReasons)
  {
    return !config.isTamperEvident()
            || (isKeyStoreFileAcceptable(config, unacceptableReasons)
                && isKeyStorePinFileAcceptable(config, unacceptableReasons));
  }
  private boolean isKeyStorePinFileAcceptable(
          final CsvFileAccessLogPublisherCfg config, final List<LocalizableMessage> unacceptableReasons)
  {
    return isFileAcceptable(config.getKeyStorePinFile(),
                config.dn(),
                ERR_COMMON_AUDIT_KEYSTORE_PIN_FILE_MISSING,
                ERR_COMMON_AUDIT_KEYSTORE_PIN_FILE_CONTAINS_EMPTY_PIN,
                ERR_COMMON_AUDIT_ERROR_READING_KEYSTORE_PIN_FILE,
                unacceptableReasons);
  }
  private boolean isKeyStoreFileAcceptable(
          final CsvFileAccessLogPublisherCfg config, final List<LocalizableMessage> unacceptableReasons)
  {
    return isFileAcceptable(config.getKeyStoreFile(),
                    config.dn(),
                    ERR_COMMON_AUDIT_KEYSTORE_FILE_MISSING,
                    ERR_COMMON_AUDIT_KEYSTORE_FILE_IS_EMPTY,
                    ERR_COMMON_AUDIT_ERROR_READING_KEYSTORE_FILE,
                    unacceptableReasons);
  }
  private boolean isFileAcceptable(
          final String fileName,
          final DN dn,
          final LocalizableMessageDescriptor.Arg2<Object, Object> missingMsg,
          final LocalizableMessageDescriptor.Arg2<Object, Object> emptyMsg,
          final LocalizableMessageDescriptor.Arg3<Object, Object, Object> ioErrorMsg,
          final List<LocalizableMessage> unacceptableReasons)
  {
    final File file = getFileForPath(fileName);
    if (!file.isFile())
    {
      unacceptableReasons.add(missingMsg.get(dn, file));
      return false;
    }
    try
    {
      if (Files.size(file.toPath()) == 0)
      {
        unacceptableReasons.add(emptyMsg.get(dn, file));
        return false;
      }
      return true;
    }
    catch (IOException e)
    {
      unacceptableReasons.add(ioErrorMsg.get(dn, file, stackTraceToSingleLineString(e)));
      return false;
    }
  }
}
opendj-server-legacy/src/messages/org/opends/messages/logger.properties
@@ -70,7 +70,7 @@
ERR_LOGGER_ERROR_ENFORCING_RETENTION_POLICY_12=Error occurred while \
 enforcing retention policy %s for logger %s: %s
ERR_COMMON_AUDIT_CREATE_13=Error occurred while creating common audit \
 facility: %s
 facility: %s
ERR_COMMON_AUDIT_ADD_OR_UPDATE_LOG_PUBLISHER_14=Error while creating \
 or updating common audit log publisher %s: %s
ERR_COMMON_AUDIT_REMOVE_LOG_PUBLISHER_15=Error while removing common audit log \
@@ -105,4 +105,10 @@
ERR_COMMON_AUDIT_ERROR_READING_KEYSTORE_PIN_FILE_29=Error while processing \
 common audit log publisher %s, the keystore pin file %s could not be read: %s
ERR_COMMON_AUDIT_KEYSTORE_PIN_FILE_CONTAINS_EMPTY_PIN_30=Error while processing \
 common audit log publisher %s, the keystore pin file %s contains an empty pin
 common audit log publisher %s, the keystore pin file %s contains an empty pin
ERR_COMMON_AUDIT_KEYSTORE_FILE_MISSING_31=Error while processing \
 common audit log publisher %s, the keystore file %s is missing
ERR_COMMON_AUDIT_ERROR_READING_KEYSTORE_FILE_32=Error while processing \
 common audit log publisher %s, the keystore file %s could not be read: %s
ERR_COMMON_AUDIT_KEYSTORE_FILE_IS_EMPTY_33=Error while processing \
 common audit log publisher %s, the keystore file %s is empty