From dd35d92f8384e111b97e59abe5a0ff6154a35352 Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Tue, 23 Apr 2013 11:38:24 -0400
Subject: [PATCH] Added Client CLI module.

A new CLI module has been added to manage certificates in client
security database.

Ticket #491
---
 .classpath                                         |   1 +
 base/java-tools/pki                                |   1 +
 base/java-tools/src/CMakeLists.txt                 |   9 +-
 .../src/com/netscape/cmstools/cli/MainCLI.java     |   2 +
 .../com/netscape/cmstools/client/ClientCLI.java    |  99 ++++++++++++++++++
 .../cmstools/client/ClientFindCertCLI.java         |  85 ++++++++++++++++
 .../cmstools/client/ClientImportCertCLI.java       | 112 +++++++++++++++++++++
 .../cmstools/client/ClientRemoveCertCLI.java       |  66 ++++++++++++
 specs/pki-core.spec                                |   6 +-
 9 files changed, 379 insertions(+), 2 deletions(-)
 create mode 100644 base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/client/ClientFindCertCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/client/ClientImportCertCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/client/ClientRemoveCertCLI.java

diff --git a/.classpath b/.classpath
index 28dddffc296146b7c6bda79bf4dbf41561c359db..244624c1350dadf17c72bcf7c36db99e7c4e6b73 100644
--- a/.classpath
+++ b/.classpath
@@ -45,5 +45,6 @@
 	<classpathentry kind="lib" path="/usr/share/java/resteasy/resteasy-atom-provider.jar"/>
 	<classpathentry kind="lib" path="/usr/share/java/tomcat/catalina.jar"/>
 	<classpathentry kind="lib" path="/usr/share/java/tomcat/tomcat-util.jar"/>
+	<classpathentry kind="lib" path="/usr/share/java/commons-io.jar"/>
 	<classpathentry kind="output" path="build/classes"/>
 </classpath>
diff --git a/base/java-tools/pki b/base/java-tools/pki
index 07eb4ee28f998685ab80fe4d6c786e2a55aeb8c6..b7d9bfe26beb5a4e27fe794f2f54669cd7cca555 100755
--- a/base/java-tools/pki
+++ b/base/java-tools/pki
@@ -83,6 +83,7 @@ $ENV{CLASSPATH} = "/usr/share/java/${PRODUCT}/pki-certsrv.jar:"
                 . "/usr/share/java/apache-commons-lang.jar:"
                 . "/usr/share/java/apache-commons-logging.jar:"
                 . "/usr/share/java/commons-httpclient.jar:"
+                . "/usr/share/java/commons-io.jar:"
                 . "/usr/share/java/httpcomponents/httpclient.jar:"
                 . "/usr/share/java/httpcomponents/httpcore.jar:"
                 . "/usr/share/java/jaxb-api.jar:"
diff --git a/base/java-tools/src/CMakeLists.txt b/base/java-tools/src/CMakeLists.txt
index 6ea69cae91b8fa5f2d072360ea879e29479ff095..7c0b695282b4a784a677a4d33b0f9ee3ce6a06c5 100644
--- a/base/java-tools/src/CMakeLists.txt
+++ b/base/java-tools/src/CMakeLists.txt
@@ -29,6 +29,13 @@ find_file(COMMONS_CODEC_JAR
         /usr/share/java
 )
 
+find_file(COMMONS_IO_JAR
+    NAMES
+        commons-io.jar
+    PATHS
+        /usr/share/java
+)
+
 find_file(XALAN_JAR
     NAMES
         xalan-j2.jar
@@ -87,7 +94,7 @@ javac(pki-tools-classes
     CLASSPATH
         ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR} ${PKI_CERTSRV_JAR}
         ${XALAN_JAR} ${XERCES_JAR}
-        ${JSS_JAR} ${COMMONS_CODEC_JAR}
+        ${JSS_JAR} ${COMMONS_CODEC_JAR} ${COMMONS_IO_JAR}
         ${APACHE_COMMONS_CLI_JAR} ${APACHE_COMMONS_LANG_JAR}
         ${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR} ${RESTEASY_ATOM_PROVIDER_JAR}
         ${HTTPCLIENT_JAR} ${HTTPCORE_JAR}
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
index 1510cc7af07f316fbd1cfa68bdf141d27c123b3f..8a9f544c28f4383d4c75ec12610a75316528e2ed 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -40,6 +40,7 @@ import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIClient;
 import com.netscape.certsrv.client.PKIConnection;
 import com.netscape.cmstools.cert.CertCLI;
+import com.netscape.cmstools.client.ClientCLI;
 import com.netscape.cmstools.group.GroupCLI;
 import com.netscape.cmstools.key.KeyCLI;
 import com.netscape.cmstools.system.KRAConnectorCLI;
@@ -66,6 +67,7 @@ public class MainCLI extends CLI {
         super("pki", "PKI command-line interface");
 
         addModule(new CertCLI(this));
+        addModule(new ClientCLI(this));
         addModule(new GroupCLI(this));
         addModule(new KeyCLI(this));
         addModule(new KRAConnectorCLI(this));
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..34d09f33ca442d888285e00703c6016084ab76bc
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
@@ -0,0 +1,99 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program 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; version 2 of the License.
+//
+// This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmstools.client;
+
+import java.util.Arrays;
+
+import org.apache.commons.lang.StringUtils;
+import org.mozilla.jss.crypto.X509Certificate;
+
+import com.netscape.certsrv.dbs.certdb.CertId;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class ClientCLI extends CLI {
+
+    public MainCLI parent;
+
+    public ClientCLI(MainCLI parent) {
+        super("client", "Client management commands");
+        this.parent = parent;
+
+        addModule(new ClientFindCertCLI(this));
+        addModule(new ClientImportCertCLI(this));
+        addModule(new ClientRemoveCertCLI(this));
+    }
+
+    public void printHelp() {
+
+        System.out.println("Commands:");
+
+        int leftPadding = 1;
+        int rightPadding = 25;
+
+        for (CLI module : modules.values()) {
+            String label = name + "-" + module.getName();
+
+            int padding = rightPadding - leftPadding - label.length();
+            if (padding < 1)
+                padding = 1;
+
+            System.out.print(StringUtils.repeat(" ", leftPadding));
+            System.out.print(label);
+            System.out.print(StringUtils.repeat(" ", padding));
+            System.out.println(module.getDescription());
+        }
+    }
+
+    public void execute(String[] args) throws Exception {
+
+        if (args.length == 0) {
+            printHelp();
+            System.exit(1);
+        }
+
+        String command = args[0];
+        String[] commandArgs = Arrays.copyOfRange(args, 1, args.length);
+
+        if (command == null) {
+            printHelp();
+            System.exit(1);
+        }
+
+        CLI module = getModule(command);
+        if (module != null) {
+            module.execute(commandArgs);
+
+        } else {
+            System.err.println("Error: Invalid command \"" + command + "\"");
+            printHelp();
+            System.exit(1);
+        }
+    }
+
+    public static void printCertInfo(X509Certificate cert) {
+        System.out.println("  Serial Number: "+new CertId(cert.getSerialNumber()).toHexString());
+        System.out.println("  Nickname: "+cert.getNickname());
+        System.out.println("  Subject DN: "+cert.getSubjectDN());
+        System.out.println("  Issuer DN: "+cert.getIssuerDN());
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientFindCertCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientFindCertCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..80690b7d09874740ee96b818a6c9258eee067565
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientFindCertCLI.java
@@ -0,0 +1,85 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program 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; version 2 of the License.
+//
+// This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmstools.client;
+
+import org.apache.commons.cli.CommandLine;
+import org.mozilla.jss.crypto.X509Certificate;
+
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class ClientFindCertCLI extends CLI {
+
+    public ClientCLI parent;
+
+    public ClientFindCertCLI(ClientCLI parent) {
+        super("find-cert", "Find certificates in client security database");
+        this.parent = parent;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(parent.name + "-" + name + " [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) throws Exception {
+
+        options.addOption(null, "ca", false, "Find CA certificates only");
+
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (Exception e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(1);
+        }
+
+        X509Certificate[] certs;
+        if (cmd.hasOption("ca")) {
+            certs = parent.parent.client.getCACerts();
+        } else {
+            certs = parent.parent.client.getCerts();
+        }
+
+        if (certs == null || certs.length == 0) {
+            MainCLI.printMessage("No certificates found");
+            System.exit(0); // valid result
+        }
+
+        MainCLI.printMessage(certs.length + " certificate(s) found");
+
+        boolean first = true;
+
+        for (X509Certificate cert : certs) {
+            if (first) {
+                first = false;
+            } else {
+                System.out.println();
+            }
+
+            ClientCLI.printCertInfo(cert);
+        }
+
+        MainCLI.printMessage("Number of entries returned " + certs.length);
+   }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientImportCertCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientImportCertCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..ed7309b1ad233aa0d9769a1dd9c958feed395979
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientImportCertCLI.java
@@ -0,0 +1,112 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program 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; version 2 of the License.
+//
+// This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmstools.client;
+
+import java.io.File;
+import java.net.URI;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.io.FileUtils;
+import org.mozilla.jss.crypto.X509Certificate;
+
+import com.netscape.certsrv.client.ClientConfig;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class ClientImportCertCLI extends CLI {
+
+    public ClientCLI parent;
+
+    public ClientImportCertCLI(ClientCLI parent) {
+        super("import-cert", "Import certificate into client security database");
+        this.parent = parent;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(parent.name + "-" + name + " [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) throws Exception {
+
+        Option option = new Option(null, "cert", true, "Import certificate file");
+        option.setArgName("path");
+        options.addOption(option);
+
+        option = new Option(null, "ca-cert", true, "Import CA certificate file");
+        option.setArgName("path");
+        options.addOption(option);
+
+        options.addOption(null, "ca-server", false, "Import CA certificate from CA server");
+
+        CommandLine cmd = null;
+
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (Exception e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(1);
+        }
+
+        byte[] bytes = null;
+        X509Certificate cert = null;
+
+        String certPath = cmd.getOptionValue("cert");
+        String caCertPath = cmd.getOptionValue("ca-cert");
+        boolean importCACert = cmd.hasOption("ca-server");
+
+        if (certPath != null) {
+            if (verbose) System.out.println("Loading certificate from " + certPath + ".");
+            bytes = FileUtils.readFileToByteArray(new File(certPath));
+
+            if (verbose) System.out.println("Importing certificate.");
+            cert = parent.parent.client.importCertPackage(bytes, parent.parent.client.config.getCertNickname());
+
+        } else if (caCertPath != null) {
+            if (verbose) System.out.println("Loading CA certificate from " + caCertPath + ".");
+            bytes = FileUtils.readFileToByteArray(new File(caCertPath));
+
+            if (verbose) System.out.println("Importing CA certificate.");
+            cert = parent.parent.client.importCACertPackage(bytes);
+
+        } else if (importCACert) {
+            ClientConfig config = parent.parent.config;
+            String caServerURI = "http://" + config.getServerURI().getHost() + ":8080/ca";
+
+            if (verbose) System.out.println("Downloading CA certificate from " + caServerURI + ".");
+            bytes = parent.parent.client.downloadCACertChain(new URI(caServerURI));
+
+            if (verbose) System.out.println("Importing CA certificate.");
+            cert = parent.parent.client.importCACertPackage(bytes);
+
+        } else {
+            System.err.println("Error: Missing certificate to import");
+            printHelp();
+            System.exit(1);
+        }
+
+        MainCLI.printMessage("Imported certificate \"" + cert.getNickname() + "\"");
+        ClientCLI.printCertInfo(cert);
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientRemoveCertCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientRemoveCertCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..fab4296314243c21ad6f718452d357c4dec1799f
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientRemoveCertCLI.java
@@ -0,0 +1,66 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program 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; version 2 of the License.
+//
+// This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmstools.client;
+
+import org.apache.commons.cli.CommandLine;
+
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class ClientRemoveCertCLI extends CLI {
+
+    public ClientCLI parent;
+
+    public ClientRemoveCertCLI(ClientCLI parent) {
+        super("remove-cert", "Remove certificate from client security database");
+        this.parent = parent;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(parent.name + "-" + name + " <nickname>", options);
+    }
+
+    public void execute(String[] args) throws Exception {
+
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (Exception e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(1);
+        }
+
+        String[] cmdArgs = cmd.getArgs();
+
+        if (cmdArgs.length != 1) {
+            printHelp();
+            System.exit(1);
+        }
+
+        String nickname = cmdArgs[0];
+        parent.parent.client.removeCert(nickname);
+
+        MainCLI.printMessage("Removed certificate \"" + nickname + "\"");
+   }
+}
diff --git a/specs/pki-core.spec b/specs/pki-core.spec
index fff49563ef390ace67cf04421d84ffbe04410a85..9560200c639ff0942f9af7eb0606fde7004327c1 100644
--- a/specs/pki-core.spec
+++ b/specs/pki-core.spec
@@ -5,7 +5,7 @@ distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
 
 Name:             pki-core
 Version:          10.0.2
-Release:          0.5%{?dist}
+Release:          0.6%{?dist}
 Summary:          Certificate System - PKI Core Components
 URL:              http://pki.fedoraproject.org/
 License:          GPLv2
@@ -185,6 +185,7 @@ Obsoletes:        pki-util < %{version}-%{release}
 
 Conflicts:        freeipa-server < 3.0.0
 Requires:         apache-commons-codec
+Requires:         apache-commons-io
 Requires:         apache-commons-lang
 Requires:         apache-commons-logging
 Requires:         java >= 1:1.6.0
@@ -1016,6 +1017,9 @@ fi
 
 
 %changelog
+* Tue Apr 23 2013 Endi S. Dewata <edewata@redhat.com> 10.0.2-0.6
+- Added dependency on commons-io.
+
 * Mon Apr 22 2013 Ade Lee <alee@redhat.com> 10.0.2-0.5
 - Add /var/log/pki and /var/lib/pki directories
 
-- 
1.8.1.4

