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

Jean-Noel Rouvignac
16.54.2014 b3e3932696d420b6944732be185f250d0fb1e181
OPENDJ-1544 encode-password tool fails with java.lang.NullPointerException 

DirectoryServer.java
Extracted initializeAuthenticatedUsers().

EncodePassword.java:
In initializeServerComponents(), called DirectoryServer.initializeAuthenticatedUsers() to initialize DirectoryServer.authenticatedUsers and avoid the NPE.
Extracted method listPasswordStorageSchemes().
Code cleanup.
2 files modified
285 ■■■■■ changed files
opends/src/server/org/opends/server/core/DirectoryServer.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/EncodePassword.java 278 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -1373,7 +1373,7 @@
      rootDNConfigManager = new RootDNConfigManager();
      rootDNConfigManager.initializeRootDNs();
      directoryServer.authenticatedUsers = new AuthenticatedUsers();
      initializeAuthenticatedUsers();
      // initialize both subentry manager and group manager for this backend.
      initializeSubentryManager();
      initializeGroupManager();
@@ -1529,6 +1529,11 @@
    }
  }
  /** Initializes authenticated users. */
  public void initializeAuthenticatedUsers()
  {
    directoryServer.authenticatedUsers = new AuthenticatedUsers();
  }
  /**
opends/src/server/org/opends/server/tools/EncodePassword.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011-2013 ForgeRock AS.
 *      Portions copyright 2011-2014 ForgeRock AS.
 */
package org.opends.server.tools;
@@ -31,8 +31,7 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import org.opends.messages.Message;
@@ -43,7 +42,6 @@
import org.opends.server.admin.std.server.TrustStoreBackendCfg;
import org.opends.server.api.Backend;
import org.opends.server.api.PasswordStorageScheme;
import org.opends.server.api.plugin.PluginType;
import org.opends.server.config.ConfigConstants;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
@@ -79,9 +77,7 @@
public class EncodePassword
{
  /**
   * The tracer object for the debug logger.
   */
  /** The tracer object for the debug logger. */
  private static final DebugTracer TRACER = getTracer();
@@ -335,18 +331,15 @@
    // If we are not going to just list the storage schemes, then the clear-text
    // password must have been provided.  If we're going to encode a password,
    // then the scheme must have also been provided.
    ByteString clearPW = null;
    if (! listSchemes.isPresent())
    if (!listSchemes.isPresent()
        && !encodedPassword.isPresent()
        && !encodedPasswordFile.isPresent()
        && !schemeName.isPresent())
    {
      if ((! encodedPassword.isPresent()) && (! encodedPasswordFile.isPresent())
           && (! schemeName.isPresent()))
      {
        Message message =
                ERR_ENCPW_NO_SCHEME.get(schemeName.getLongIdentifier());
        err.println(wrapText(message, MAX_LINE_WIDTH));
        err.println(argParser.getUsage());
        return OPERATIONS_ERROR;
      }
      final Message message = ERR_ENCPW_NO_SCHEME.get(schemeName.getLongIdentifier());
      err.println(wrapText(message, MAX_LINE_WIDTH));
      err.println(argParser.getUsage());
      return OPERATIONS_ERROR;
    }
@@ -464,7 +457,9 @@
      if(!initializeServerComponents(directoryServer, err))
          return -1;
      {
        return -1;
      }
      // Initialize the password storage schemes.
      try
@@ -503,71 +498,19 @@
    {
      if (authPasswordSyntax.isPresent())
      {
        ConcurrentHashMap<String,PasswordStorageScheme> storageSchemes =
             DirectoryServer.getAuthPasswordStorageSchemes();
        if (storageSchemes.isEmpty())
        {
          Message message = ERR_ENCPW_NO_STORAGE_SCHEMES.get();
          err.println(wrapText(message, MAX_LINE_WIDTH));
        }
        else
        {
          int size = storageSchemes.size();
          ArrayList<String> nameList = new ArrayList<String>(size);
          for (PasswordStorageScheme s : storageSchemes.values())
          {
            nameList.add(s.getAuthPasswordSchemeName());
          }
          String[] nameArray = new String[size];
          nameList.toArray(nameArray);
          Arrays.sort(nameArray);
          for (String storageSchemeName : nameArray)
          {
            out.println(storageSchemeName);
          }
        }
        return SUCCESS;
        listPasswordStorageSchemes(out, err, DirectoryServer.getAuthPasswordStorageSchemes(), true);
      }
      else
      {
        ConcurrentHashMap<String,PasswordStorageScheme> storageSchemes =
             DirectoryServer.getPasswordStorageSchemes();
        if (storageSchemes.isEmpty())
        {
          Message message = ERR_ENCPW_NO_STORAGE_SCHEMES.get();
          err.println(wrapText(message, MAX_LINE_WIDTH));
        }
        else
        {
          int size = storageSchemes.size();
          ArrayList<String> nameList = new ArrayList<String>(size);
          for (PasswordStorageScheme s : storageSchemes.values())
          {
            nameList.add(s.getStorageSchemeName());
          }
          String[] nameArray = new String[size];
          nameList.toArray(nameArray);
          Arrays.sort(nameArray);
          for (String storageSchemeName : nameArray)
          {
            out.println(storageSchemeName);
          }
        }
        return SUCCESS;
        listPasswordStorageSchemes(out, err, DirectoryServer.getPasswordStorageSchemes(), false);
      }
      return SUCCESS;
    }
    // Either encode the clear-text password using the provided scheme, or
    // compare the clear-text password against the encoded password.
    ByteString clearPW = null;
    if (compareMode)
    {
      // Check to see if the provided password value was encoded.  If so, then
@@ -808,6 +751,37 @@
  private static void listPasswordStorageSchemes(PrintStream out, PrintStream err,
      ConcurrentHashMap<String, PasswordStorageScheme> storageSchemes, boolean authPasswordSchemeName)
  {
    if (storageSchemes.isEmpty())
    {
      Message message = ERR_ENCPW_NO_STORAGE_SCHEMES.get();
      err.println(wrapText(message, MAX_LINE_WIDTH));
    }
    else
    {
      ArrayList<String> nameList = new ArrayList<String>(storageSchemes.size());
      for (PasswordStorageScheme<?> s : storageSchemes.values())
      {
        if (authPasswordSchemeName)
        {
          nameList.add(s.getAuthPasswordSchemeName());
        }
        else
        {
          nameList.add(s.getStorageSchemeName());
        }
      }
      Collections.sort(nameList);
      for (String storageSchemeName : nameList)
      {
        out.println(storageSchemeName);
      }
    }
  }
  private static Message getOutputMessage(boolean passwordMatches)
  {
    if (passwordMatches)
@@ -819,10 +793,8 @@
  private static boolean
          initializeServerComponents(DirectoryServer directoryServer,
                                     PrintStream err) {
  private static boolean initializeServerComponents(DirectoryServer directoryServer, PrintStream err)
  {
      // Initialize the Directory Server crypto manager.
      try
      {
@@ -853,19 +825,13 @@
      //secret keys from the trust store backend (3DES, BLOWFISH, AES, RC4) via
      //the crypto-manager.
      try {
          // Initialize the root DNs.
          directoryServer.initializeRootDNConfigManager();
          //Initialize plugins.
          HashSet<PluginType> pluginTypes = new HashSet<PluginType>(1);
          directoryServer.initializePlugins(pluginTypes);
          //Initialize Trust Backend.
          directoryServer.initializePlugins(Collections.EMPTY_SET);
          initializeServerBackends(directoryServer);
          // Initialize the subentry manager.
          directoryServer.initializeSubentryManager();
          //Initialize PWD policy components.
          directoryServer.initializeAuthenticationPolicyComponents();
          //Load the crypto-manager key cache among other things.
         new CryptoManagerSync();
          directoryServer.initializeAuthenticatedUsers();
          new CryptoManagerSync();
    } catch (InitializationException ie) {
        Message message = ERR_ENCPW_CANNOT_INITIALIZE_SERVER_COMPONENTS.get(
                getExceptionMessage(ie));
@@ -904,57 +870,51 @@
    for (String name : root.listBackends()) {
      BackendCfg backendCfg = root.getBackend(name);
      String backendID = backendCfg.getBackendId();
      if(backendCfg instanceof TrustStoreBackendCfg ||
          backendCfg instanceof LDIFBackendCfg) {
        if(backendCfg.isEnabled()) {
          String className = backendCfg.getJavaClass();
          Class backendClass;
          Backend backend;
          try {
            backendClass = DirectoryServer.loadClass(className);
            backend = (Backend) backendClass.newInstance();
          } catch (Exception e) {
            if (debugEnabled()) {
              TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
            Message message =
              ERR_CONFIG_BACKEND_CANNOT_INSTANTIATE.get(
                  String.valueOf(className),
                  String.valueOf(backendCfg.dn()),
                  stackTraceToSingleLineString(e));
            logError(message);
            continue;
      if((backendCfg instanceof TrustStoreBackendCfg
          || backendCfg instanceof LDIFBackendCfg)
          && backendCfg.isEnabled())
      {
        String className = backendCfg.getJavaClass();
        Class<?> backendClass;
        Backend<BackendCfg> backend;
        try {
          backendClass = DirectoryServer.loadClass(className);
          backend = (Backend<BackendCfg>) backendClass.newInstance();
        } catch (Exception e) {
          if (debugEnabled()) {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
          backend.setBackendID(backendID);
          backend.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
          try {
            backend.configureBackend(backendCfg);
            backend.initializeBackend();
          } catch (Exception e) {
            if (debugEnabled())
            {
              TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
            Message message =
              ERR_CONFIG_BACKEND_CANNOT_INITIALIZE.get(
                  String.valueOf(className),
                  String.valueOf(backendCfg.dn()),
                  stackTraceToSingleLineString(e));
            logError(message);
          }
          try {
            DirectoryServer.registerBackend(backend);
          } catch (Exception e)
          logError(ERR_CONFIG_BACKEND_CANNOT_INSTANTIATE.get(
              String.valueOf(className),
              String.valueOf(backendCfg.dn()),
              stackTraceToSingleLineString(e)));
          continue;
        }
        backend.setBackendID(backendID);
        backend.setWritabilityMode(WritabilityMode.INTERNAL_ONLY);
        try {
          backend.configureBackend(backendCfg);
          backend.initializeBackend();
        } catch (Exception e) {
          if (debugEnabled())
          {
            if (debugEnabled()) {
              TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
            Message message =
              WARN_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND.get(
                  backendCfg.getBackendId(),
                  getExceptionMessage(e));
            logError(message);
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
          logError(ERR_CONFIG_BACKEND_CANNOT_INITIALIZE.get(
              String.valueOf(className),
              String.valueOf(backendCfg.dn()),
              stackTraceToSingleLineString(e)));
        }
        try {
          DirectoryServer.registerBackend(backend);
        } catch (Exception e)
        {
          if (debugEnabled()) {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
          logError(WARN_CONFIG_BACKEND_CANNOT_REGISTER_BACKEND.get(
              backendCfg.getBackendId(),
              getExceptionMessage(e)));
        }
      }
    }
@@ -966,7 +926,7 @@
   * @param err The error output.
   * @param argParser The argument parser.
   * @param clearPassword the clear password
   * @param clearPasswordFile the fil in which the password in stored
   * @param clearPasswordFile the file in which the password in stored
   * @param interactivePassword indicate if the password should be asked
   *        interactively.
   * @return the password or null if an error occurs.
@@ -975,29 +935,24 @@
      ArgumentParser argParser, StringArgument clearPassword,
      FileBasedArgument clearPasswordFile, BooleanArgument interactivePassword)
  {
    ByteString clearPW = null;
    if (clearPassword.hasValue())
    {
      clearPW = ByteString.valueOf(clearPassword.getValue());
      return ByteString.valueOf(clearPassword.getValue());
    }
    else if (clearPasswordFile.hasValue())
    {
      clearPW = ByteString.valueOf(clearPasswordFile.getValue());
      return ByteString.valueOf(clearPasswordFile.getValue());
    }
    else if (interactivePassword.isPresent())
    {
      EncodePassword encodePassword = new EncodePassword() ;
      try
      {
        String pwd1, pwd2;
        Message msg = INFO_ENCPW_INPUT_PWD_1.get();
        pwd1 = encodePassword.getPassword(out, msg.toString());
        msg = INFO_ENCPW_INPUT_PWD_2.get();
        pwd2 = encodePassword.getPassword(out,msg.toString());
        EncodePassword encodePassword = new EncodePassword();
        String pwd1 = encodePassword.getPassword(INFO_ENCPW_INPUT_PWD_1.get().toString());
        String pwd2 = encodePassword.getPassword(INFO_ENCPW_INPUT_PWD_2.get().toString());
        if (pwd1.equals(pwd2))
        {
          clearPW = ByteString.valueOf(pwd1);
          return ByteString.valueOf(pwd1);
        }
        else
        {
@@ -1012,7 +967,6 @@
        err.println(wrapText(message, MAX_LINE_WIDTH));
        return null;
      }
    }
    else
    {
@@ -1023,38 +977,32 @@
      err.println(argParser.getUsage());
      return null;
    }
    return clearPW;
  }
  /**
   * Get the password from JDK6 console or from masked password.
   * @param out The output
   * @param prompt The message to print out.
   * @return the password
   * @throws IOException if an issue occurs when reading the password
   *         from the input
   */
  private String getPassword(PrintStream out, String prompt)
      throws IOException
  private String getPassword(String prompt) throws IOException
  {
    String password;
    try
    {
      Console console = System.console();
      if (console != null)
      {
        password = new String(console.readPassword(prompt));
      }
      else
      if (console == null)
      {
        throw new IOException("No console");
      }
      password = new String(console.readPassword(prompt));
    }
    catch (Exception e)
    {
      // Try the fallback to the old trick method.
      // Create the thread that will erase chars
      ErasingThread erasingThread = new ErasingThread(out, prompt);
      ErasingThread erasingThread = new ErasingThread(prompt);
      erasingThread.start();
      password = "";
@@ -1072,10 +1020,6 @@
          {
            break;
          }
          else
          {
            continue;
          }
        }
        else if (c == '\n')
        {
@@ -1094,22 +1038,19 @@
  /**
   * Thread that mask user input.
   *
   */
  private class ErasingThread extends Thread
  {
    private boolean stop = false;
    private boolean stop;
    private String prompt;
    /**
     * The class will mask the user input.
     * @param out
     *          the output
     * @param prompt
     *          The prompt displayed to the user
     */
    public ErasingThread(PrintStream out, String prompt)
    public ErasingThread(String prompt)
    {
      this.prompt = prompt;
    }
@@ -1146,7 +1087,6 @@
    {
      this.stop = true;
    }
  }
}