From b3e3932696d420b6944732be185f250d0fb1e181 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Tue, 16 Sep 2014 14:54:39 +0000
Subject: [PATCH] OPENDJ-1544 encode-password tool fails with java.lang.NullPointerException 

---
 opends/src/server/org/opends/server/tools/EncodePassword.java |  278 +++++++++++++++++++++---------------------------------
 1 files changed, 109 insertions(+), 169 deletions(-)

diff --git a/opends/src/server/org/opends/server/tools/EncodePassword.java b/opends/src/server/org/opends/server/tools/EncodePassword.java
index 4ab89bd..4decb86 100644
--- a/opends/src/server/org/opends/server/tools/EncodePassword.java
+++ b/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;
     }
-
   }
 
 }

--
Gitblit v1.10.0