001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.tools;
028    import org.opends.messages.Message;
029    
030    
031    
032    import java.io.OutputStream;
033    import java.io.PrintStream;
034    import java.util.ArrayList;
035    import java.util.Arrays;
036    import java.util.concurrent.ConcurrentHashMap;
037    
038    import org.opends.server.api.PasswordStorageScheme;
039    import org.opends.server.config.ConfigException;
040    import org.opends.server.core.CoreConfigManager;
041    import org.opends.server.core.DirectoryServer;
042    import org.opends.server.core.PasswordStorageSchemeConfigManager;
043    import org.opends.server.extensions.ConfigFileHandler;
044    import org.opends.server.protocols.asn1.ASN1OctetString;
045    import org.opends.server.protocols.ldap.LDAPResultCode;
046    import org.opends.server.schema.AuthPasswordSyntax;
047    import org.opends.server.schema.UserPasswordSyntax;
048    import org.opends.server.types.ByteString;
049    import org.opends.server.types.DirectoryException;
050    import org.opends.server.types.InitializationException;
051    import org.opends.server.types.NullOutputStream;
052    import org.opends.server.util.args.ArgumentException;
053    import org.opends.server.util.args.ArgumentParser;
054    import org.opends.server.util.args.BooleanArgument;
055    import org.opends.server.util.args.FileBasedArgument;
056    import org.opends.server.util.args.StringArgument;
057    
058    import static org.opends.messages.ToolMessages.*;
059    import static org.opends.server.util.ServerConstants.*;
060    import static org.opends.server.util.StaticUtils.*;
061    import static org.opends.server.tools.ToolConstants.*;
062    
063    
064    
065    /**
066     * This program provides a utility that may be used to interact with the
067     * password storage schemes defined in the Directory Server.  In particular,
068     * it can encode a clear-text password using a specified scheme, and it can also
069     * determine whether a given encoded password is the encoded representation of a
070     * given clear-text password.  Alternately, it can be used to obtain a list of
071     * the available password storage scheme names.
072     */
073    public class EncodePassword
074    {
075      /**
076       * Processes the command-line arguments and performs the requested action.
077       *
078       * @param  args  The command-line arguments provided to this program.
079       */
080      public static void main(String[] args)
081      {
082        int returnCode = encodePassword(args, true, System.out, System.err);
083        if (returnCode != 0)
084        {
085          System.exit(filterExitCode(returnCode));
086        }
087      }
088    
089    
090    
091      /**
092       * Processes the command-line arguments and performs the requested action.
093       *
094       * @param  args  The command-line arguments provided to this program.
095       *
096       * @return  An integer value that indicates whether processing was successful.
097       */
098      public static int encodePassword(String[] args)
099      {
100        return encodePassword(args, true, System.out, System.err);
101      }
102    
103    
104    
105      /**
106       * Processes the command-line arguments and performs the requested action.
107       *
108       * @param  args              The command-line arguments provided to this
109       *                           program.
110       * @param  initializeServer  Indicates whether to initialize the server.
111       * @param  outStream         The output stream to use for standard output, or
112       *                           <CODE>null</CODE> if standard output is not
113       *                           needed.
114       * @param  errStream         The output stream to use for standard error, or
115       *                           <CODE>null</CODE> if standard error is not
116       *                           needed.
117       *
118       * @return  An integer value that indicates whether processing was successful.
119       */
120      public static int encodePassword(String[] args, boolean initializeServer,
121                                       OutputStream outStream,
122                                       OutputStream errStream)
123      {
124        PrintStream out;
125        if (outStream == null)
126        {
127          out = NullOutputStream.printStream();
128        }
129        else
130        {
131          out = new PrintStream(outStream);
132        }
133    
134        PrintStream err;
135        if (errStream == null)
136        {
137          err = NullOutputStream.printStream();
138        }
139        else
140        {
141          err = new PrintStream(errStream);
142        }
143    
144        // Define the command-line arguments that may be used with this program.
145        BooleanArgument   authPasswordSyntax   = null;
146        BooleanArgument   useCompareResultCode = null;
147        BooleanArgument   listSchemes          = null;
148        BooleanArgument   showUsage            = null;
149        StringArgument    clearPassword        = null;
150        FileBasedArgument clearPasswordFile    = null;
151        StringArgument    encodedPassword      = null;
152        FileBasedArgument encodedPasswordFile  = null;
153        StringArgument    configClass          = null;
154        StringArgument    configFile           = null;
155        StringArgument    schemeName           = null;
156    
157    
158        // Create the command-line argument parser for use with this program.
159        Message toolDescription = INFO_ENCPW_TOOL_DESCRIPTION.get();
160        ArgumentParser argParser =
161             new ArgumentParser("org.opends.server.tools.EncodePassword",
162                                toolDescription, false);
163    
164    
165        // Initialize all the command-line argument types and register them with the
166        // parser.
167        try
168        {
169          listSchemes = new BooleanArgument(
170                  "listschemes", 'l', "listSchemes",
171                  INFO_ENCPW_DESCRIPTION_LISTSCHEMES.get());
172          argParser.addArgument(listSchemes);
173    
174    
175          clearPassword = new StringArgument("clearpw", 'c', "clearPassword", false,
176                                             false, true, INFO_CLEAR_PWD.get(),
177                                             null, null,
178                                             INFO_ENCPW_DESCRIPTION_CLEAR_PW.get());
179          argParser.addArgument(clearPassword);
180    
181    
182          clearPasswordFile =
183               new FileBasedArgument("clearpwfile", 'f', "clearPasswordFile", false,
184                                     false, INFO_FILE_PLACEHOLDER.get(), null, null,
185                                     INFO_ENCPW_DESCRIPTION_CLEAR_PW_FILE.get());
186          argParser.addArgument(clearPasswordFile);
187    
188    
189          encodedPassword = new StringArgument(
190                  "encodedpw", 'e', "encodedPassword",
191                  false, false, true, INFO_ENCODED_PWD_PLACEHOLDER.get(),
192                  null, null,
193                  INFO_ENCPW_DESCRIPTION_ENCODED_PW.get());
194          argParser.addArgument(encodedPassword);
195    
196    
197          encodedPasswordFile =
198               new FileBasedArgument("encodedpwfile", 'E', "encodedPasswordFile",
199                                     false, false, INFO_FILE_PLACEHOLDER.get(),
200                                     null, null,
201                                     INFO_ENCPW_DESCRIPTION_ENCODED_PW_FILE.get());
202          argParser.addArgument(encodedPasswordFile);
203    
204    
205          configClass = new StringArgument("configclass", OPTION_SHORT_CONFIG_CLASS,
206                                           OPTION_LONG_CONFIG_CLASS,
207                                           true, false, true,
208                                           INFO_CONFIGCLASS_PLACEHOLDER.get(),
209                                           ConfigFileHandler.class.getName(), null,
210                                           INFO_DESCRIPTION_CONFIG_CLASS.get());
211          configClass.setHidden(true);
212          argParser.addArgument(configClass);
213    
214    
215          configFile = new StringArgument("configfile", 'F', "configFile",
216                                          true, false, true,
217                                          INFO_CONFIGFILE_PLACEHOLDER.get(), null,
218                                          null,
219                                          INFO_DESCRIPTION_CONFIG_FILE.get());
220          configFile.setHidden(true);
221          argParser.addArgument(configFile);
222    
223    
224          schemeName = new StringArgument("scheme", 's', "storageScheme", false,
225                                          false, true,
226                                          INFO_STORAGE_SCHEME_PLACEHOLDER.get(),
227                                          null, null,
228                                          INFO_ENCPW_DESCRIPTION_SCHEME.get());
229          argParser.addArgument(schemeName);
230    
231    
232          authPasswordSyntax = new BooleanArgument(
233                  "authpasswordsyntax", 'a',
234                  "authPasswordSyntax",
235                  INFO_ENCPW_DESCRIPTION_AUTHPW.get());
236          argParser.addArgument(authPasswordSyntax);
237    
238    
239          useCompareResultCode =
240               new BooleanArgument("usecompareresultcode", 'r',
241                                   "useCompareResultCode",
242                                   INFO_ENCPW_DESCRIPTION_USE_COMPARE_RESULT.get());
243          argParser.addArgument(useCompareResultCode);
244    
245    
246          showUsage = new BooleanArgument("usage", OPTION_SHORT_HELP,
247                                          OPTION_LONG_HELP,
248                                          INFO_DESCRIPTION_USAGE.get());
249          argParser.addArgument(showUsage);
250          argParser.setUsageArgument(showUsage, out);
251        }
252        catch (ArgumentException ae)
253        {
254          Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
255    
256          err.println(wrapText(message, MAX_LINE_WIDTH));
257          return 1;
258        }
259    
260    
261        // Parse the command-line arguments provided to this program.
262        try
263        {
264          argParser.parseArguments(args);
265        }
266        catch (ArgumentException ae)
267        {
268          Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage());
269    
270          err.println(wrapText(message, MAX_LINE_WIDTH));
271          err.println(argParser.getUsage());
272          return 1;
273        }
274    
275    
276        // If we should just display usage or version information,
277        // then we've already done it so just return without doing anything else.
278        if (argParser.usageOrVersionDisplayed())
279        {
280          return 0;
281        }
282    
283    
284        // Check for conflicting arguments.
285        if (clearPassword.isPresent() && clearPasswordFile.isPresent())
286        {
287          Message message =
288                  ERR_TOOL_CONFLICTING_ARGS.get(clearPassword.getLongIdentifier(),
289                                      clearPasswordFile.getLongIdentifier());
290          err.println(wrapText(message, MAX_LINE_WIDTH));
291          return 1;
292        }
293    
294        if (encodedPassword.isPresent() && encodedPasswordFile.isPresent())
295        {
296          Message message =
297                  ERR_TOOL_CONFLICTING_ARGS.get(encodedPassword.getLongIdentifier(),
298                                      encodedPasswordFile.getLongIdentifier());
299          err.println(wrapText(message, MAX_LINE_WIDTH));
300          return 1;
301        }
302    
303    
304        // If we are not going to just list the storage schemes, then the clear-text
305        // password must have been provided.  If we're going to encode a password,
306        // then the scheme must have also been provided.
307        ASN1OctetString clearPW = null;
308        if (! listSchemes.isPresent())
309        {
310          if (clearPassword.hasValue())
311          {
312            clearPW = new ASN1OctetString(clearPassword.getValue());
313          }
314          else if (clearPasswordFile.hasValue())
315          {
316            clearPW = new ASN1OctetString(clearPasswordFile.getValue());
317          }
318          else
319          {
320            Message message =
321                    ERR_ENCPW_NO_CLEAR_PW.get(clearPassword.getLongIdentifier(),
322                    clearPasswordFile.getLongIdentifier());
323            err.println(wrapText(message, MAX_LINE_WIDTH));
324            err.println(argParser.getUsage());
325            return 1;
326          }
327    
328          if ((! encodedPassword.isPresent()) && (! encodedPasswordFile.isPresent())
329               && (! schemeName.isPresent()))
330          {
331            Message message =
332                    ERR_ENCPW_NO_SCHEME.get(schemeName.getLongIdentifier());
333            err.println(wrapText(message, MAX_LINE_WIDTH));
334            err.println(argParser.getUsage());
335            return 1;
336          }
337        }
338    
339    
340        // Determine whether we're encoding the clear-text password or comparing it
341        // against an already-encoded password.
342        boolean compareMode;
343        ByteString encodedPW = null;
344        if (encodedPassword.hasValue())
345        {
346          compareMode = true;
347          encodedPW = new ASN1OctetString(encodedPassword.getValue());
348        }
349        else if (encodedPasswordFile.hasValue())
350        {
351          compareMode = true;
352          encodedPW = new ASN1OctetString(encodedPasswordFile.getValue());
353        }
354        else
355        {
356          compareMode = false;
357        }
358    
359    
360        // Perform the initial bootstrap of the Directory Server and process the
361        // configuration.
362        DirectoryServer directoryServer = DirectoryServer.getInstance();
363    
364        if (initializeServer)
365        {
366          try
367          {
368            directoryServer.bootstrapClient();
369            directoryServer.initializeJMX();
370          }
371          catch (Exception e)
372          {
373            Message message =
374                    ERR_SERVER_BOOTSTRAP_ERROR.get(getExceptionMessage(e));
375            err.println(wrapText(message, MAX_LINE_WIDTH));
376            return 1;
377          }
378    
379          try
380          {
381            directoryServer.initializeConfiguration(configClass.getValue(),
382                                                    configFile.getValue());
383          }
384          catch (InitializationException ie)
385          {
386            Message message = ERR_CANNOT_LOAD_CONFIG.get(ie.getMessage());
387            err.println(wrapText(message, MAX_LINE_WIDTH));
388            return 1;
389          }
390          catch (Exception e)
391          {
392            Message message = ERR_CANNOT_LOAD_CONFIG.get(getExceptionMessage(e));
393            err.println(wrapText(message, MAX_LINE_WIDTH));
394            return 1;
395          }
396    
397    
398    
399          // Initialize the Directory Server schema elements.
400          try
401          {
402            directoryServer.initializeSchema();
403          }
404          catch (ConfigException ce)
405          {
406            Message message = ERR_CANNOT_LOAD_SCHEMA.get(ce.getMessage());
407            err.println(wrapText(message, MAX_LINE_WIDTH));
408            return 1;
409          }
410          catch (InitializationException ie)
411          {
412            Message message = ERR_CANNOT_LOAD_SCHEMA.get(ie.getMessage());
413            err.println(wrapText(message, MAX_LINE_WIDTH));
414            return 1;
415          }
416          catch (Exception e)
417          {
418            Message message = ERR_CANNOT_LOAD_SCHEMA.get(getExceptionMessage(e));
419            err.println(wrapText(message, MAX_LINE_WIDTH));
420            return 1;
421          }
422    
423    
424          // Initialize the Directory Server core configuration.
425          try
426          {
427            CoreConfigManager coreConfigManager = new CoreConfigManager();
428            coreConfigManager.initializeCoreConfig();
429          }
430          catch (ConfigException ce)
431          {
432            Message message =
433                    ERR_CANNOT_INITIALIZE_CORE_CONFIG.get(ce.getMessage());
434            err.println(wrapText(message, MAX_LINE_WIDTH));
435            return 1;
436          }
437          catch (InitializationException ie)
438          {
439            Message message =
440                    ERR_CANNOT_INITIALIZE_CORE_CONFIG.get(ie.getMessage());
441            err.println(wrapText(message, MAX_LINE_WIDTH));
442            return 1;
443          }
444          catch (Exception e)
445          {
446            Message message =
447                    ERR_CANNOT_INITIALIZE_CORE_CONFIG.get(getExceptionMessage(e));
448            err.println(wrapText(message, MAX_LINE_WIDTH));
449            return 1;
450          }
451    
452    
453          // Initialize the password storage schemes.
454          try
455          {
456            PasswordStorageSchemeConfigManager storageSchemeConfigManager =
457                 new PasswordStorageSchemeConfigManager();
458            storageSchemeConfigManager.initializePasswordStorageSchemes();
459          }
460          catch (ConfigException ce)
461          {
462            Message message =
463                    ERR_ENCPW_CANNOT_INITIALIZE_STORAGE_SCHEMES.get(
464                            ce.getMessage());
465            err.println(wrapText(message, MAX_LINE_WIDTH));
466            return 1;
467          }
468          catch (InitializationException ie)
469          {
470            Message message = ERR_ENCPW_CANNOT_INITIALIZE_STORAGE_SCHEMES.get(
471                    ie.getMessage());
472            err.println(wrapText(message, MAX_LINE_WIDTH));
473            return 1;
474          }
475          catch (Exception e)
476          {
477            Message message = ERR_ENCPW_CANNOT_INITIALIZE_STORAGE_SCHEMES.get(
478                    getExceptionMessage(e));
479            err.println(wrapText(message, MAX_LINE_WIDTH));
480            return 1;
481          }
482        }
483    
484    
485        // If we are only trying to list the available schemes, then do so and exit.
486        if (listSchemes.isPresent())
487        {
488          if (authPasswordSyntax.isPresent())
489          {
490            ConcurrentHashMap<String,PasswordStorageScheme> storageSchemes =
491                 DirectoryServer.getAuthPasswordStorageSchemes();
492            if (storageSchemes.isEmpty())
493            {
494              Message message = ERR_ENCPW_NO_STORAGE_SCHEMES.get();
495              err.println(wrapText(message, MAX_LINE_WIDTH));
496            }
497            else
498            {
499              int size = storageSchemes.size();
500    
501              ArrayList<String> nameList = new ArrayList<String>(size);
502              for (PasswordStorageScheme s : storageSchemes.values())
503              {
504                nameList.add(s.getAuthPasswordSchemeName());
505              }
506    
507              String[] nameArray = new String[size];
508              nameList.toArray(nameArray);
509              Arrays.sort(nameArray);
510    
511              for (String storageSchemeName : nameArray)
512              {
513                out.println(storageSchemeName);
514              }
515            }
516    
517            return 0;
518          }
519          else
520          {
521            ConcurrentHashMap<String,PasswordStorageScheme> storageSchemes =
522                 DirectoryServer.getPasswordStorageSchemes();
523            if (storageSchemes.isEmpty())
524            {
525              Message message = ERR_ENCPW_NO_STORAGE_SCHEMES.get();
526              err.println(wrapText(message, MAX_LINE_WIDTH));
527            }
528            else
529            {
530              int size = storageSchemes.size();
531    
532              ArrayList<String> nameList = new ArrayList<String>(size);
533              for (PasswordStorageScheme s : storageSchemes.values())
534              {
535                nameList.add(s.getStorageSchemeName());
536              }
537    
538              String[] nameArray = new String[size];
539              nameList.toArray(nameArray);
540              Arrays.sort(nameArray);
541    
542              for (String storageSchemeName : nameArray)
543              {
544                out.println(storageSchemeName);
545              }
546            }
547    
548            return 0;
549          }
550        }
551    
552    
553        // Either encode the clear-text password using the provided scheme, or
554        // compare the clear-text password against the encoded password.
555        if (compareMode)
556        {
557          // Check to see if the provided password value was encoded.  If so, then
558          // break it down into its component parts and use that to perform the
559          // comparison.  Otherwise, the user must have provided the storage scheme.
560          if (authPasswordSyntax.isPresent())
561          {
562            String scheme;
563            String authInfo;
564            String authValue;
565    
566            try
567            {
568              StringBuilder[] authPWElements =
569                   AuthPasswordSyntax.decodeAuthPassword(encodedPW.stringValue());
570              scheme    = authPWElements[0].toString();
571              authInfo  = authPWElements[1].toString();
572              authValue = authPWElements[2].toString();
573            }
574            catch (DirectoryException de)
575            {
576              Message message = ERR_ENCPW_INVALID_ENCODED_AUTHPW.get(
577                      de.getMessageObject());
578              err.println(wrapText(message, MAX_LINE_WIDTH));
579              return 1;
580            }
581            catch (Exception e)
582            {
583              Message message = ERR_ENCPW_INVALID_ENCODED_AUTHPW.get(
584                      String.valueOf(e));
585              err.println(wrapText(message, MAX_LINE_WIDTH));
586              return 1;
587            }
588    
589            PasswordStorageScheme storageScheme =
590                 DirectoryServer.getAuthPasswordStorageScheme(scheme);
591            if (storageScheme == null)
592            {
593              Message message = ERR_ENCPW_NO_SUCH_AUTH_SCHEME.get(
594                      scheme);
595              err.println(wrapText(message, MAX_LINE_WIDTH));
596              return 1;
597            }
598    
599            if (storageScheme.authPasswordMatches(clearPW, authInfo, authValue))
600            {
601              Message message = INFO_ENCPW_PASSWORDS_MATCH.get();
602              out.println(message);
603    
604              if (useCompareResultCode.isPresent())
605              {
606                return LDAPResultCode.COMPARE_TRUE;
607              }
608              else
609              {
610                return 0;
611              }
612            }
613            else
614            {
615              Message message = INFO_ENCPW_PASSWORDS_DO_NOT_MATCH.get();
616              out.println(message);
617    
618              if (useCompareResultCode.isPresent())
619              {
620                return LDAPResultCode.COMPARE_FALSE;
621              }
622              else
623              {
624                return 0;
625              }
626            }
627          }
628          else
629          {
630            PasswordStorageScheme storageScheme;
631            String                encodedPWString;
632    
633            if (UserPasswordSyntax.isEncoded(encodedPW))
634            {
635              try
636              {
637                String[] userPWElements =
638                     UserPasswordSyntax.decodeUserPassword(encodedPW.stringValue());
639                encodedPWString = userPWElements[1];
640    
641                storageScheme =
642                     DirectoryServer.getPasswordStorageScheme(userPWElements[0]);
643                if (storageScheme == null)
644                {
645                  Message message = ERR_ENCPW_NO_SUCH_SCHEME.get(userPWElements[0]);
646                  err.println(wrapText(message, MAX_LINE_WIDTH));
647                  return 1;
648                }
649              }
650              catch (DirectoryException de)
651              {
652                Message message = ERR_ENCPW_INVALID_ENCODED_USERPW.get(
653                        de.getMessageObject());
654                err.println(wrapText(message, MAX_LINE_WIDTH));
655                return 1;
656              }
657              catch (Exception e)
658              {
659                Message message = ERR_ENCPW_INVALID_ENCODED_USERPW.get(
660                        String.valueOf(e));
661                err.println(wrapText(message, MAX_LINE_WIDTH));
662                return 1;
663              }
664            }
665            else
666            {
667              if (! schemeName.isPresent())
668              {
669                Message message = ERR_ENCPW_NO_SCHEME.get(
670                        schemeName.getLongIdentifier());
671                err.println(wrapText(message, MAX_LINE_WIDTH));
672                return 1;
673              }
674    
675              encodedPWString = encodedPW.toString();
676    
677              String scheme = toLowerCase(schemeName.getValue());
678              storageScheme = directoryServer.getPasswordStorageScheme(scheme);
679              if (storageScheme == null)
680              {
681                Message message = ERR_ENCPW_NO_SUCH_SCHEME.get(scheme);
682                err.println(wrapText(message, MAX_LINE_WIDTH));
683                return 1;
684              }
685            }
686    
687            if (storageScheme.passwordMatches(clearPW,
688                                              new ASN1OctetString(encodedPWString)))
689            {
690              Message message = INFO_ENCPW_PASSWORDS_MATCH.get();
691              out.println(message);
692    
693              if (useCompareResultCode.isPresent())
694              {
695                return LDAPResultCode.COMPARE_TRUE;
696              }
697              else
698              {
699                return 0;
700              }
701            }
702            else
703            {
704              Message message = INFO_ENCPW_PASSWORDS_DO_NOT_MATCH.get();
705              out.println(message);
706    
707              if (useCompareResultCode.isPresent())
708              {
709                return LDAPResultCode.COMPARE_FALSE;
710              }
711              else
712              {
713                return 0;
714              }
715            }
716          }
717        }
718        else
719        {
720          // Try to get a reference to the requested password storage scheme.
721          PasswordStorageScheme storageScheme;
722          if (authPasswordSyntax.isPresent())
723          {
724            String scheme = schemeName.getValue();
725            storageScheme = DirectoryServer.getAuthPasswordStorageScheme(scheme);
726            if (storageScheme == null)
727            {
728              Message message = ERR_ENCPW_NO_SUCH_AUTH_SCHEME.get(scheme);
729              err.println(wrapText(message, MAX_LINE_WIDTH));
730              return 1;
731            }
732          }
733          else
734          {
735            String scheme = toLowerCase(schemeName.getValue());
736            storageScheme = DirectoryServer.getPasswordStorageScheme(scheme);
737            if (storageScheme == null)
738            {
739              Message message = ERR_ENCPW_NO_SUCH_SCHEME.get(scheme);
740              err.println(wrapText(message, MAX_LINE_WIDTH));
741              return 1;
742            }
743          }
744    
745          if (authPasswordSyntax.isPresent())
746          {
747            try
748            {
749              encodedPW = storageScheme.encodeAuthPassword(clearPW);
750    
751              Message message = ERR_ENCPW_ENCODED_PASSWORD.get(
752                      encodedPW.stringValue());
753              out.println(message);
754            }
755            catch (DirectoryException de)
756            {
757              Message message = ERR_ENCPW_CANNOT_ENCODE.get(de.getMessageObject());
758              err.println(wrapText(message, MAX_LINE_WIDTH));
759              return 1;
760            }
761            catch (Exception e)
762            {
763              Message message = ERR_ENCPW_CANNOT_ENCODE.get(getExceptionMessage(e));
764              err.println(wrapText(message, MAX_LINE_WIDTH));
765              return 1;
766            }
767          }
768          else
769          {
770            try
771            {
772              encodedPW = storageScheme.encodePasswordWithScheme(clearPW);
773    
774              Message message =
775                      ERR_ENCPW_ENCODED_PASSWORD.get(encodedPW.stringValue());
776              out.println(message);
777            }
778            catch (DirectoryException de)
779            {
780              Message message = ERR_ENCPW_CANNOT_ENCODE.get(de.getMessageObject());
781              err.println(wrapText(message, MAX_LINE_WIDTH));
782              return 1;
783            }
784            catch (Exception e)
785            {
786              Message message = ERR_ENCPW_CANNOT_ENCODE.get(getExceptionMessage(e));
787              err.println(wrapText(message, MAX_LINE_WIDTH));
788              return 1;
789            }
790          }
791        }
792    
793        // If we've gotten here, then all processing completed successfully.
794        return 0;
795      }
796    }
797