/* Main.java -- Implementation of the keytool security tool
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.classpath.tools.keytool;

import gnu.classpath.Configuration;
import gnu.classpath.tools.common.ProviderUtil;
import gnu.classpath.tools.getopt.ClasspathToolParser;
import gnu.classpath.tools.getopt.Option;
import gnu.classpath.tools.getopt.OptionException;
import gnu.classpath.tools.getopt.OptionGroup;
import gnu.classpath.tools.getopt.Parser;
import gnu.java.security.Registry;
import gnu.javax.crypto.jce.GnuCrypto;
import gnu.javax.security.auth.callback.GnuCallbacks;

import java.util.logging.Logger;

/**
 * The GNU Classpath implementation of the keytool security tool.
 * <p>
 * Except for the <code>-identitydb</code> command, available for importing
 * JDK 1.1 <i>identities</i> into a key store, this implementation is intended
 * to be compatible with the behaviour described in the public documentation of
 * the same tool included in JDK 1.4.
 */
public class Main
{
  private static final Logger log = Logger.getLogger(Main.class.getName());
  static final String KEYTOOL_TOOL = "keytool"; //$NON-NLS-1$
  static final String GENKEY_CMD = "genkey"; //$NON-NLS-1$
  static final String IMPORT_CMD = "import"; //$NON-NLS-1$
  static final String SELFCERT_CMD = "selfcert"; //$NON-NLS-1$
  static final String IDENTITYDB_CMD = "identitydb"; //$NON-NLS-1$
  static final String CERTREQ_CMD = "certreq"; //$NON-NLS-1$
  static final String EXPORT_CMD = "export"; //$NON-NLS-1$
  static final String LIST_CMD = "list"; //$NON-NLS-1$
  static final String PRINTCERT_CMD = "printcert"; //$NON-NLS-1$
  static final String KEYCLONE_CMD = "keyclone"; //$NON-NLS-1$
  static final String STOREPASSWD_CMD = "storepasswd"; //$NON-NLS-1$
  static final String KEYPASSWD_CMD = "keypasswd"; //$NON-NLS-1$
  static final String DELETE_CMD = "delete"; //$NON-NLS-1$
  static final String CACERT_CMD = "cacert"; //$NON-NLS-1$

  static final String _GENKEY = "-" + GENKEY_CMD; //$NON-NLS-1$
  static final String _IMPORT = "-" + IMPORT_CMD; //$NON-NLS-1$
  static final String _SELFCERT = "-" + SELFCERT_CMD; //$NON-NLS-1$
  static final String _IDENTITYDB = "-" + IDENTITYDB_CMD; //$NON-NLS-1$
  static final String _CERTREQ = "-" + CERTREQ_CMD; //$NON-NLS-1$
  static final String _EXPORT = "-" + EXPORT_CMD; //$NON-NLS-1$
  static final String _LIST = "-" + LIST_CMD; //$NON-NLS-1$
  static final String _PRINTCERT = "-" + PRINTCERT_CMD; //$NON-NLS-1$
  static final String _KEYCLONE = "-" + KEYCLONE_CMD; //$NON-NLS-1$
  static final String _STOREPASSWD = "-" + STOREPASSWD_CMD; //$NON-NLS-1$
  static final String _KEYPASSWD = "-" + KEYPASSWD_CMD; //$NON-NLS-1$
  static final String _DELETE = "-" + DELETE_CMD; //$NON-NLS-1$
  static final String _HELP = "-help"; //$NON-NLS-1$
  static final String _CACERT = "-" + CACERT_CMD; //$NON-NLS-1$

  static final String ALIAS_OPT = "alias"; //$NON-NLS-1$
  static final String SIGALG_OPT = "sigalg"; //$NON-NLS-1$
  static final String KEYALG_OPT = "keyalg"; //$NON-NLS-1$
  static final String KEYSIZE_OPT = "keysize"; //$NON-NLS-1$
  static final String KEYPASS_OPT = "keypass"; //$NON-NLS-1$
  static final String VALIDITY_OPT = "validity"; //$NON-NLS-1$
  static final String STORETYPE_OPT = "storetype"; //$NON-NLS-1$
  static final String STOREPASS_OPT = "storepass"; //$NON-NLS-1$
  static final String KEYSTORE_OPT = "keystore"; //$NON-NLS-1$
  static final String PROVIDER_OPT = "provider"; //$NON-NLS-1$
  static final String FILE_OPT = "file"; //$NON-NLS-1$
  static final String VERBOSE_OPT = "v"; //$NON-NLS-1$
  static final String DEST_OPT = "dest"; //$NON-NLS-1$
  static final String NEW_OPT = "new"; //$NON-NLS-1$
  static final String RFC_OPT = "rfc"; //$NON-NLS-1$
  static final String DNAME_OPT = "dname"; //$NON-NLS-1$

  /** The Preferences key name for the last issued certificate serial nbr. */
  static final String LAST_SERIAL_NUMBER = "lastSerialNumber"; //$NON-NLS-1$
  /** Constant denoting the X.509 certificate type. */
  static final String X_509 = "X.509"; //$NON-NLS-1$

  /** Whether we have already printed the help text or not. */
  private boolean helpPrinted;
  /** The new position of GnuCRYPTO provider if it is not already installed. */
  private int gnuCryptoProviderNdx = -2;
  /** The new position of GNU Callbacks provider if it is not already installed. */
  private int gnuCallbacksNdx = -2;
  /** The command line parser. */
  private Parser cmdLineParser;
  /** The shutdown hook. */
  private ShutdownHook shutdownThread;

  private Main()
  {
    super();
    shutdownThread = new ShutdownHook();
    Runtime.getRuntime().addShutdownHook(shutdownThread);
  }

  public static final void main(String[] args)
  {
    if (Configuration.DEBUG)
      log.entering(Main.class.getName(), "main", args); //$NON-NLS-1$
    Main tool = new Main();
    int result = 1;
    try
      {
        tool.setup();
        tool.start(args);
        result = 0;
      }
    catch (OptionException x)
      {
        System.err.println(x.getMessage());
        if (tool.cmdLineParser != null)
          tool.cmdLineParser.printHelp();
      }
    catch (SecurityException x)
      {
        if (Configuration.DEBUG)
          log.throwing(Main.class.getName(), "main", x); //$NON-NLS-1$
        System.err.println(Messages.getFormattedString("Main.6", //$NON-NLS-1$
                                                       x.getMessage()));
      }
    catch (Exception x)
      {
        if (Configuration.DEBUG)
          log.throwing(Main.class.getName(), "main", x); //$NON-NLS-1$
        System.err.println(Messages.getFormattedString("Main.8", x)); //$NON-NLS-1$
      }
    finally
      {
        tool.teardown();
        if (tool.shutdownThread != null)
          Runtime.getRuntime().removeShutdownHook(tool.shutdownThread);
      }
    if (Configuration.DEBUG)
      log.exiting(Main.class.getName(), "main", Integer.valueOf(result)); //$NON-NLS-1$
    System.exit(result);
  }

  // helper methods -----------------------------------------------------------

  private void setup()
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "setup"); //$NON-NLS-1$
    cmdLineParser = getParser();
    gnuCryptoProviderNdx = ProviderUtil.addProvider(new GnuCrypto());
    gnuCallbacksNdx = ProviderUtil.addProvider(new GnuCallbacks());
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "setup"); //$NON-NLS-1$
  }

  private void start(String[] args) throws Exception
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "start"); //$NON-NLS-1$
    if (args == null || args.length == 0)
      throw new OptionException(""); //$NON-NLS-1$

    String opt;
    Command cmd;
    while (args.length > 0)
      {
        opt = args[0];
        cmd = null;
        if (_GENKEY.equals(opt))
          cmd = new GenKeyCmd();
        else if (_IMPORT.equals(opt))
          cmd = new ImportCmd();
        else if (_SELFCERT.equals(opt))
          cmd = new SelfCertCmd();
        else if (_IDENTITYDB.equals(opt))
          cmd = new IdentityDBCmd();
        else if (_CERTREQ.equals(opt))
          cmd = new CertReqCmd();
        else if (_EXPORT.equals(opt))
          cmd = new ExportCmd();
        else if (_LIST.equals(opt))
          cmd = new ListCmd();
        else if (_PRINTCERT.equals(opt))
          cmd = new PrintCertCmd();
        else if (_KEYCLONE.equals(opt))
          cmd = new KeyCloneCmd();
        else if (_STOREPASSWD.equals(opt))
          cmd = new StorePasswdCmd();
        else if (_KEYPASSWD.equals(opt))
          cmd = new KeyPasswdCmd();
        else if (_DELETE.equals(opt))
          cmd = new DeleteCmd();
        else if (_CACERT.equals(opt))
          cmd = new CACertCmd();
        else if (_HELP.equals(opt))
          throw new OptionException(""); //$NON-NLS-1$
        else
          throw new OptionException(Messages.getFormattedString("Main.18", //$NON-NLS-1$
                                                                opt));

        String[] cmdArgs = new String[args.length - 1];
        System.arraycopy(args, 1, cmdArgs, 0, cmdArgs.length);
        args = cmd.processArgs(cmdArgs);
        cmd.doCommand();
      }
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "start"); //$NON-NLS-1$
  }

  private Parser getParser()
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "getParser"); //$NON-NLS-1$
    Parser result = new ClasspathToolParser(KEYTOOL_TOOL, true);
    result.setHeader(Messages.getString("Main.19")); //$NON-NLS-1$
    result.setFooter(Messages.getString("Main.20")); //$NON-NLS-1$
    OptionGroup cmdGroup = new OptionGroup(Messages.getString("Main.21")); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(GENKEY_CMD,
                                   Messages.getString("Main.22"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(IMPORT_CMD,
                                   Messages.getString("Main.23"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(SELFCERT_CMD,
                                   Messages.getString("Main.24"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(IDENTITYDB_CMD,
                                   Messages.getString("Main.25"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(CERTREQ_CMD,
                                   Messages.getString("Main.26"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(EXPORT_CMD,
                                   Messages.getString("Main.27"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(LIST_CMD,
                                   Messages.getString("Main.28"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(PRINTCERT_CMD,
                                   Messages.getString("Main.29"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(KEYCLONE_CMD,
                                   Messages.getString("Main.30"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(STOREPASSWD_CMD,
                                   Messages.getString("Main.31"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(KEYPASSWD_CMD,
                                   Messages.getString("Main.32"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(DELETE_CMD,
                                   Messages.getString("Main.33"))); //$NON-NLS-1$
    cmdGroup.add(new NoParseOption(CACERT_CMD,
                                   Messages.getString("Main.5"))); //$NON-NLS-1$
    result.add(cmdGroup);
    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "getParser", result); //$NON-NLS-1$
    return result;
  }

  void teardown()
  {
    if (Configuration.DEBUG)
      log.entering(this.getClass().getName(), "teardown"); //$NON-NLS-1$
    // if we added our own providers remove them
    if (gnuCryptoProviderNdx > 0)
      ProviderUtil.removeProvider(Registry.GNU_CRYPTO);

    if (gnuCallbacksNdx > 0)
      ProviderUtil.removeProvider("GNU-CALLBACKS"); //$NON-NLS-1$

    if (Configuration.DEBUG)
      log.exiting(this.getClass().getName(), "teardown"); //$NON-NLS-1$
  }

  private void printHelp()
  {
    if (helpPrinted)
      return;

    helpPrinted = true;
  }

  // Inner class(es)
  // ==========================================================================

  private class NoParseOption
      extends Option
  {
    public NoParseOption(String name, String description)
    {
      super(name, description);
    }

    public NoParseOption(String name, String description, String param)
    {
      super(name, description, param);
    }

    public void parsed(String argument) throws OptionException
    {
      // do nothing
    }
  }

  private class ShutdownHook
      extends Thread
  {
    public void run()
    {
      teardown();
    }
  }
}
