org.signserver.admin.cli.defaultimpl.WSAuditorsCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.signserver.admin.cli.defaultimpl.WSAuditorsCommand.java

Source

/*************************************************************************
 *                                                                       *
 *  SignServer: The OpenSource Automated Signing Server                  *
 *                                                                       *
 *  This software is free software; you can redistribute it and/or       *
 *  modify it under the terms of the GNU Lesser General Public           *
 *  License as published by the Free Software Foundation; either         *
 *  version 2.1 of the License, or any later version.                    *
 *                                                                       *
 *  See terms of license at gnu.org.                                     *
 *                                                                       *
 *************************************************************************/
package org.signserver.admin.cli.defaultimpl;

import java.security.cert.X509Certificate;
import java.util.LinkedList;
import java.util.List;
import javax.ejb.EJBException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.ejbca.util.CertTools;
import org.signserver.cli.spi.CommandFailureException;
import org.signserver.cli.spi.IllegalCommandArgumentsException;
import org.signserver.cli.spi.UnexpectedCommandFailureException;
import org.signserver.common.GlobalConfiguration;
import org.signserver.common.SignServerUtil;

/**
 * Command for managing the list of authorized WS auditors.
 *
 * @version $Id$
 */
public class WSAuditorsCommand extends AbstractAdminCommand {

    public static final String ADD = "add";
    public static final String REMOVE = "remove";
    public static final String LIST = "list";
    public static final String CERTSERIALNO = "certserialno";
    public static final String ISSUERDN = "issuerdn";
    public static final String CERT = "cert";

    /** The command line options. */
    private static final Options OPTIONS;

    private static final String USAGE = "Usage: signserver wsauditors -add -certserialno <certificate serial number> -issuerdn <issuer DN>\n"
            + "Usage: signserver wsauditors -add -cert <PEM or DER file>\n"
            + "Usage: signserver wsauditors -remove -certserialno <certificate serial number> -issuerdn <issuer DN>\n"
            + "Usage: signserver wsauditors -list\n"
            + "Example 1: signserver wsauditors -add -certserialno 0123ABCDEF -issuerdn \"CN=Neo Morpheus, C=SE\"\n"
            + "Example 2: signserver wsauditors -add -cert wsauditor.pem\n"
            + "Example 3: signserver wsauditors -remove -certserialno 0123ABCDEF -issuerdn \"CN=Neo Morpheus, C=SE\"\n"
            + "Example 4: signserver wsauditors -list";

    static {
        OPTIONS = new Options();
        OPTIONS.addOption(ADD, false, "Add a new WS auditor");
        OPTIONS.addOption(REMOVE, false, "Remove a WS auditor");
        OPTIONS.addOption(LIST, false, "List all WS auditors");

        OPTIONS.addOption(CERTSERIALNO, true, "Subject certificate serial number");
        OPTIONS.addOption(ISSUERDN, true, "Issuer distinguished name");
        OPTIONS.addOption(CERT, true, "Certificate file");
    }

    private String operation;
    private String certSerialNo;
    private String issuerDN;
    private String cert;

    @Override
    public String getDescription() {
        return "Manages authorizations for WS auditors";
    }

    @Override
    public String getUsages() {
        return USAGE;
    }

    /**
     * Reads all the options from the command line.
     *
     * @param line The command line to read from
     */
    private void parseCommandLine(final CommandLine line) {
        certSerialNo = line.getOptionValue(CERTSERIALNO, null);
        issuerDN = line.getOptionValue(ISSUERDN, null);
        cert = line.getOptionValue(CERT, null);
        if (line.hasOption(ADD)) {
            operation = ADD;
        } else if (line.hasOption(REMOVE)) {
            operation = REMOVE;
        } else if (line.hasOption(LIST)) {
            operation = LIST;
        }
    }

    /**
     * Checks that all mandatory options are given.
     */
    private void validateOptions() throws IllegalCommandArgumentsException {
        if (operation == null) {
            throw new IllegalCommandArgumentsException("Missing operation: -add, -remove or -list");
        } else if (!operation.equals(LIST)) {
            if (cert != null) {
                // don't allow -cert option in combination with -certserialno and -issuerdn
                if (certSerialNo != null || issuerDN != null) {
                    throw new IllegalCommandArgumentsException(
                            "Can't use the option -cert at the same time as -certserialno and -issuerdn");
                }
            } else {
                if (certSerialNo == null) {
                    throw new IllegalCommandArgumentsException("Missing option: -certserialno");
                } else if (issuerDN == null) {
                    throw new IllegalCommandArgumentsException("Missing option: -issuerdn");
                }
            }
        }
    }

    @Override
    public int execute(String... args)
            throws IllegalCommandArgumentsException, CommandFailureException, UnexpectedCommandFailureException {
        try {
            // Parse the command line
            parseCommandLine(new GnuParser().parse(OPTIONS, args));
        } catch (ParseException ex) {
            throw new IllegalCommandArgumentsException(ex.getMessage());
        }
        validateOptions();

        try {
            final String admins = getGlobalConfigurationSession().getGlobalConfiguration()
                    .getProperty(GlobalConfiguration.SCOPE_GLOBAL, "WSAUDITORS");
            final List<Entry> entries = parseAdmins(admins);

            if (LIST.equals(operation)) {
                final StringBuilder buff = new StringBuilder();
                buff.append("Authorized auditors:");
                buff.append("\n");
                for (Entry entry : entries) {
                    buff.append(String.format("%-20s %s", entry.getCertSerialNo(), entry.getIssuerDN()));
                    buff.append("\n");
                }
                getOutputStream().println(buff.toString());
            } else if (ADD.equals(operation)) {
                if (cert == null) {
                    // serial number and issuer DN was entered manually
                    entries.add(new Entry(certSerialNo, issuerDN));
                } else {
                    // read serial number and issuer DN from cert file
                    X509Certificate certificate = SignServerUtil.getCertFromFile(cert);
                    String sn = certificate.getSerialNumber().toString(16);
                    String dn = certificate.getIssuerX500Principal().getName();

                    CertTools.BasicX509NameTokenizer tok = new CertTools.BasicX509NameTokenizer(dn);
                    StringBuilder buf = new StringBuilder();

                    while (tok.hasMoreTokens()) {
                        final String token = tok.nextToken();
                        buf.append(token);
                        if (tok.hasMoreTokens()) {
                            buf.append(", ");
                        }
                    }

                    entries.add(new Entry(sn, buf.toString()));
                }
                getGlobalConfigurationSession().setProperty(GlobalConfiguration.SCOPE_GLOBAL, "WSAUDITORS",
                        serializeAdmins(entries));
                getOutputStream().println("Auditor added");
            } else if (REMOVE.equals(operation)) {
                if (entries.remove(new Entry(certSerialNo, issuerDN))) {
                    getGlobalConfigurationSession().setProperty(GlobalConfiguration.SCOPE_GLOBAL, "WSAUDITORS",
                            serializeAdmins(entries));
                    getOutputStream().println("Auditor removed");
                } else {
                    getErrorStream().println("No such auditor");
                }
            }
            return 0;
        } catch (EJBException eJBException) {
            if (eJBException.getCausedByException() instanceof IllegalArgumentException) {
                getErrorStream().println(eJBException.getMessage());
                return -2;
            } else {
                throw new UnexpectedCommandFailureException(eJBException);
            }
        } catch (Exception e) {
            throw new UnexpectedCommandFailureException(e);
        }
    }

    private static List<Entry> parseAdmins(final String admins) {
        final List<Entry> entries = new LinkedList<Entry>();
        if (admins != null && admins.contains(";")) {
            for (String entry : admins.split(";")) {
                final String[] parts = entry.split(",", 2);
                entries.add(new Entry(parts[0], parts[1]));
            }
        }
        return entries;
    }

    private static String serializeAdmins(final List<Entry> entries) {
        final StringBuilder buff = new StringBuilder();
        for (Entry entry : entries) {
            buff.append(entry.getCertSerialNo());
            buff.append(",");
            buff.append(entry.getIssuerDN());
            buff.append(";");
        }
        return buff.toString();
    }

    private static class Entry {

        private String certSerialNo;
        private String issuerDN;

        public Entry(String certSerialNo, String issuerDN) {
            this.certSerialNo = certSerialNo;
            this.issuerDN = issuerDN;
        }

        public String getCertSerialNo() {
            return certSerialNo;
        }

        public String getIssuerDN() {
            return issuerDN;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Entry other = (Entry) obj;
            if ((this.certSerialNo == null) ? (other.certSerialNo != null)
                    : !this.certSerialNo.equals(other.certSerialNo)) {
                return false;
            }
            if ((this.issuerDN == null) ? (other.issuerDN != null) : !this.issuerDN.equals(other.issuerDN)) {
                return false;
            }
            return true;
        }

        @Override
        public int hashCode() {
            int hash = 7;
            hash = 89 * hash + (this.certSerialNo != null ? this.certSerialNo.hashCode() : 0);
            hash = 89 * hash + (this.issuerDN != null ? this.issuerDN.hashCode() : 0);
            return hash;
        }
    }
}