diff --git a/ChangeLog b/ChangeLog index e678cca..4caaba7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2011-02-12 David Blacka + + * Update commons-cli to version 1.2. + * Refactor all of the command line classes. A new command line + base class has been created to eliminate much of the duplicated + code. + 2011-02-09 Blacka * Enable reading and writing from stdin/stdout for most tools. To diff --git a/lib/commons-cli-1.1.jar b/lib/commons-cli-1.1.jar deleted file mode 100644 index e633afb..0000000 Binary files a/lib/commons-cli-1.1.jar and /dev/null differ diff --git a/lib/commons-cli-1.2.jar b/lib/commons-cli-1.2.jar new file mode 100644 index 0000000..ce4b9ff Binary files /dev/null and b/lib/commons-cli-1.2.jar differ diff --git a/licenses/commons-cli-LICENSE.txt b/licenses/commons-cli-LICENSE.txt index 58c4c55..57bc88a 100644 --- a/licenses/commons-cli-LICENSE.txt +++ b/licenses/commons-cli-LICENSE.txt @@ -1,60 +1,202 @@ -/* - * $Header: /home/radcvs/dnssec_pilot/sectools/licenses/commons-cli-LICENSE.txt,v 1.1 2003/04/02 22:40:49 davidb Exp $ - * $Revision: 1.1 $ - * $Date: 2003/04/02 22:40:49 $ - * - * ==================================================================== - * - * The Apache Software License, Version 1.1 - * - * Copyright (c) 1999-2001 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, if - * any, must include the following acknowlegement: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowlegement may appear in the software itself, - * if and wherever such third-party acknowlegements normally appear. - * - * 4. The names "The Jakarta Project", "Commons", and "Apache Software - * Foundation" must not be used to endorse or promote products derived - * from this software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache" - * nor may "Apache" appear in their names without prior written - * permission of the Apache Group. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/src/com/verisignlabs/dnssec/cl/CLBase.java b/src/com/verisignlabs/dnssec/cl/CLBase.java new file mode 100644 index 0000000..e8b3ed4 --- /dev/null +++ b/src/com/verisignlabs/dnssec/cl/CLBase.java @@ -0,0 +1,325 @@ +package com.verisignlabs.dnssec.cl; + +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import org.apache.commons.cli.AlreadySelectedException; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.apache.commons.cli.UnrecognizedOptionException; + +import com.verisignlabs.dnssec.security.DnsKeyAlgorithm; + +/** + * This is a base class for jdnssec command line tools. Each command line tool + * should inherit from this class, create a subclass of CLIStateBase (overriding + * setupOptions and processOptions), and implement the execute() method. + * Subclasses also have their own main() methods, which should just create the + * subclass variant of the CLIState and call run(). + */ +public abstract class CLBase +{ + protected static Logger log; + + /** + * This is a very simple log formatter that simply outputs the log level and + * log string. + */ + public static class BareLogFormatter extends Formatter + { + @Override + public String format(LogRecord arg0) + { + StringBuilder out = new StringBuilder(); + String lvl = arg0.getLevel().getName(); + + out.append(lvl); + out.append(": "); + out.append(arg0.getMessage()); + out.append("\n"); + + return out.toString(); + } + } + + /** + * This is a base class for command line parsing state. Subclasses should + * override setupOptions and processOptions. + */ + public static class CLIStateBase + { + protected Options opts; + protected String usageStr; + + /** + * The base constructor. This will setup the command line options. + * + * @param usage + * The command line usage string (e.g., + * "jdnssec-foo [..options..] zonefile") + */ + public CLIStateBase(String usage) + { + usageStr = usage; + setup(); + } + + /** This is the base set of command line options provided to all subclasses. */ + private void setup() + { + // Set up the standard set of options that all jdnssec command line tools will implement. + opts = new Options(); + + // boolean options + opts.addOption("h", "help", false, "Print this message."); + opts.addOption("m", "multiline", false, + "Output DNS records using 'multiline' format"); + + OptionBuilder.hasOptionalArg(); + OptionBuilder.withLongOpt("verbose"); + OptionBuilder.withArgName("level"); + OptionBuilder.withDescription("verbosity level -- 0 is silence, 3 is info, " + + "5 is debug information, 6 is trace information. default is level 2 (warning)"); + opts.addOption(OptionBuilder.create('v')); + + OptionBuilder.hasArg(); + OptionBuilder.withArgName("alias:original:mnemonic"); + OptionBuilder.withLongOpt("alg-alias"); + OptionBuilder.withDescription("Define an alias for an algorithm"); + opts.addOption(OptionBuilder.create('A')); + + setupOptions(opts); + } + + /** + * This is an overridable method for subclasses to add their own command + * line options. + * + * @param opts + * the options object to add (via OptionBuilder, typically) new + * options to. + */ + protected void setupOptions(Options opts) + { + // Subclasses generally override this. + } + + /** + * This is the main method for parsing the command line arguments. + * Subclasses generally override processOptions() rather than this method. + * This method create the parsing objects and processes the standard + * options. + * + * @param args + * The command line arguments. + * @throws ParseException + */ + public void parseCommandLine(String args[]) throws ParseException + { + CommandLineParser cli_parser = new PosixParser(); + CommandLine cli = cli_parser.parse(opts, args); + + if (cli.hasOption('h')) usage(); + + Logger rootLogger = Logger.getLogger(""); + int value = parseInt(cli.getOptionValue('v'), -1); + + switch (value) + { + case 0: + rootLogger.setLevel(Level.OFF); + break; + case 1: + rootLogger.setLevel(Level.SEVERE); + break; + case 2: + default: + rootLogger.setLevel(Level.WARNING); + break; + case 3: + rootLogger.setLevel(Level.INFO); + break; + case 4: + rootLogger.setLevel(Level.CONFIG); + case 5: + rootLogger.setLevel(Level.FINE); + break; + case 6: + rootLogger.setLevel(Level.ALL); + break; + } + + // I hate java.util.logging, btw. + for (Handler h : rootLogger.getHandlers()) + { + h.setLevel(rootLogger.getLevel()); + h.setFormatter(new BareLogFormatter()); + } + + if (cli.hasOption('m')) + { + org.xbill.DNS.Options.set("multiline"); + } + + String[] optstrs = null; + if ((optstrs = cli.getOptionValues('A')) != null) + { + for (int i = 0; i < optstrs.length; i++) + { + addArgAlias(optstrs[i]); + } + } + + processOptions(cli); + } + + /** + * Process additional tool-specific options. Subclasses generally override + * this. + * + * @param cli + * The {@link CommandLine} object containing the parsed command + * line state. + */ + protected void processOptions(CommandLine cli) throws ParseException + { + // Subclasses generally override this. + } + + /** Print out the usage and help statements, then quit. */ + public void usage() + { + HelpFormatter f = new HelpFormatter(); + + PrintWriter out = new PrintWriter(System.err); + + // print our own usage statement: + f.printHelp(out, 75, usageStr, null, opts, HelpFormatter.DEFAULT_LEFT_PAD, + HelpFormatter.DEFAULT_DESC_PAD, null); + + out.flush(); + System.exit(64); + + } + + protected void addArgAlias(String s) + { + if (s == null) return; + + DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance(); + + String[] v = s.split(":"); + if (v.length < 2) return; + + int alias = parseInt(v[0], -1); + if (alias <= 0) return; + int orig = parseInt(v[1], -1); + if (orig <= 0) return; + String mn = null; + if (v.length > 2) mn = v[2]; + + algs.addAlias(alias, mn, orig); + } + } + + public static int parseInt(String s, int def) + { + try + { + int v = Integer.parseInt(s); + return v; + } + catch (NumberFormatException e) + { + return def; + } + } + + /** + * Calculate a date/time from a command line time/offset duration string. + * + * @param start + * the start time to calculate offsets from. + * @param duration + * the time/offset string to parse. + * @return the calculated time. + */ + public static Date convertDuration(Date start, String duration) throws ParseException + { + if (start == null) start = new Date(); + if (duration.startsWith("now")) + { + start = new Date(); + if (duration.indexOf("+") < 0) return start; + + duration = duration.substring(3); + } + + if (duration.startsWith("+")) + { + long offset = (long) parseInt(duration.substring(1), 0) * 1000; + return new Date(start.getTime() + offset); + } + + SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss"); + dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT")); + try + { + return dateFormatter.parse(duration); + } + catch (java.text.ParseException e) + { + throw new ParseException(e.getMessage()); + } + } + + public abstract void execute() throws Exception; + + public void run(CLIStateBase state, String[] args) + { + try + { + state.parseCommandLine(args); + } + catch (UnrecognizedOptionException e) + { + System.err.println("error: unknown option encountered: " + e.getMessage()); + state.usage(); + } + catch (AlreadySelectedException e) + { + System.err.println("error: mutually exclusive options have " + + "been selected:\n " + e.getMessage()); + state.usage(); + } + catch (Exception e) + { + System.err.println("error: unknown command line parsing exception:"); + e.printStackTrace(); + state.usage(); + } + + log = Logger.getLogger(this.getClass().toString()); + + try + { + execute(); + } + catch (Exception e) + { + e.printStackTrace(); + } + } +} diff --git a/src/com/verisignlabs/dnssec/cl/DSTool.java b/src/com/verisignlabs/dnssec/cl/DSTool.java index f9b3ee5..444af8e 100644 --- a/src/com/verisignlabs/dnssec/cl/DSTool.java +++ b/src/com/verisignlabs/dnssec/cl/DSTool.java @@ -1,6 +1,4 @@ -// $Id: KeyGen.java 1954 2005-08-14 17:05:50Z davidb $ -// -// Copyright (C) 2001-2003 VeriSign, Inc. +// Copyright (C) 2001-2003, 2011 VeriSign, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -21,9 +19,6 @@ package com.verisignlabs.dnssec.cl; import java.io.FileWriter; import java.io.PrintWriter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; import org.apache.commons.cli.*; import org.xbill.DNS.DLVRecord; @@ -36,29 +31,26 @@ import com.verisignlabs.dnssec.security.*; /** * This class forms the command line implementation of a DNSSEC DS/DLV generator * - * @author David Blacka (original) - * @author $Author: davidb $ - * @version $Revision: 1954 $ + * @author David Blacka */ -public class DSTool +public class DSTool extends CLBase { - private static Logger log; + private CLIState state; /** * This is a small inner class used to hold all of the command line option * state. */ - private static class CLIState + protected static class CLIState extends CLIStateBase { - private Options opts; - public boolean createDLV = false; - public String outputfile = null; - public String keyname = null; - public int digest_id = DSRecord.SHA1_DIGEST_ID; + public boolean createDLV = false; + public String outputfile = null; + public String keyname = null; + public int digest_id = DSRecord.SHA1_DIGEST_ID; public CLIState() { - setupCLI(); + super("jdnssec-dstool [..options..] keyfile"); } /** @@ -66,25 +58,12 @@ public class DSTool * * @return a set of command line options. */ - private void setupCLI() + protected void setupOptions(Options opts) { - opts = new Options(); - - // boolean options - opts.addOption("h", "help", false, "Print this message."); - OptionBuilder.withLongOpt("dlv"); OptionBuilder.withDescription("Generate a DLV record instead."); opts.addOption(OptionBuilder.create()); - OptionBuilder.hasOptionalArg(); - OptionBuilder.withLongOpt("verbose"); - OptionBuilder.withArgName("level"); - OptionBuilder.withDescription("verbosity level -- 0 is silence, 5 is debug information, 6 is trace information.\n" - + "default is level 5."); - // Argument options - opts.addOption(OptionBuilder.create('v')); - OptionBuilder.hasArg(); OptionBuilder.withLongOpt("digest"); OptionBuilder.withArgName("id"); @@ -92,49 +71,9 @@ public class DSTool opts.addOption(OptionBuilder.create('d')); } - public void parseCommandLine(String[] args) + protected void processOptions(CommandLine cli) throws org.apache.commons.cli.ParseException { - CommandLineParser cli_parser = new PosixParser(); - CommandLine cli = cli_parser.parse(opts, args); - - if (cli.hasOption('h')) usage(); - - Logger rootLogger = Logger.getLogger(""); - - int value = parseInt(cli.getOptionValue('v'), -1); - switch (value) - { - case 0: - rootLogger.setLevel(Level.OFF); - break; - case 1: - rootLogger.setLevel(Level.SEVERE); - break; - case 2: - default: - rootLogger.setLevel(Level.WARNING); - break; - case 3: - rootLogger.setLevel(Level.INFO); - break; - case 4: - rootLogger.setLevel(Level.CONFIG); - case 5: - rootLogger.setLevel(Level.FINE); - break; - case 6: - rootLogger.setLevel(Level.ALL); - break; - } - - // I hate java.util.logging, btw. - for (Handler h : rootLogger.getHandlers()) - { - h.setLevel(rootLogger.getLevel()); - h.setFormatter(new BareLogFormatter()); - } - outputfile = cli.getOptionValue('f'); createDLV = cli.hasOption("dlv"); String optstr = cli.getOptionValue('d'); @@ -151,47 +90,10 @@ public class DSTool keyname = cl_args[0]; } - /** Print out the usage and help statements, then quit. */ - private void usage() - { - HelpFormatter f = new HelpFormatter(); - - PrintWriter out = new PrintWriter(System.err); - - // print our own usage statement: - f.printHelp(out, 75, "jdnssec-dstool [..options..] keyfile", null, opts, - HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null); - - out.flush(); - System.exit(64); - } } - /** - * This is just a convenience method for parsing integers from strings. - * - * @param s - * the string to parse. - * @param def - * the default value, if the string doesn't parse. - * @return the parsed integer, or the default. - */ - private static int parseInt(String s, int def) + public void execute() throws Exception { - try - { - int v = Integer.parseInt(s); - return v; - } - catch (NumberFormatException e) - { - return def; - } - } - - public static void execute(CLIState state) throws Exception - { - DnsKeyPair key = BINDKeyUtils.loadKey(state.keyname, null); DNSKEYRecord dnskey = key.getDNSKEYRecord(); @@ -226,39 +128,9 @@ public class DSTool public static void main(String[] args) { - CLIState state = new CLIState(); + DSTool tool = new DSTool(); + tool.state = new CLIState(); - try - { - state.parseCommandLine(args); - } - catch (UnrecognizedOptionException e) - { - System.err.println("error: unknown option encountered: " + e.getMessage()); - state.usage(); - } - catch (AlreadySelectedException e) - { - System.err.println("error: mutually exclusive options have been selected:\n " - + e.getMessage()); - state.usage(); - } - catch (Exception e) - { - System.err.println("error: unknown command line parsing exception:"); - e.printStackTrace(); - state.usage(); - } - - log = Logger.getLogger(DSTool.class.toString()); - - try - { - execute(state); - } - catch (Exception e) - { - e.printStackTrace(); - } + tool.run(tool.state, args); } } diff --git a/src/com/verisignlabs/dnssec/cl/KeyGen.java b/src/com/verisignlabs/dnssec/cl/KeyGen.java index d21c1ba..aa888b1 100644 --- a/src/com/verisignlabs/dnssec/cl/KeyGen.java +++ b/src/com/verisignlabs/dnssec/cl/KeyGen.java @@ -1,6 +1,4 @@ -// $Id$ -// -// Copyright (C) 2001-2003 VeriSign, Inc. +// Copyright (C) 2001-2003, 2011 VeriSign, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,10 +18,6 @@ package com.verisignlabs.dnssec.cl; import java.io.File; -import java.io.PrintWriter; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; import org.apache.commons.cli.*; import org.xbill.DNS.DClass; @@ -35,21 +29,18 @@ import com.verisignlabs.dnssec.security.*; /** * This class forms the command line implementation of a DNSSEC key generator * - * @author David Blacka (original) - * @author $Author$ - * @version $Revision$ + * @author David Blacka */ -public class KeyGen +public class KeyGen extends CLBase { - private static Logger log; + private CLIState state; /** * This is a small inner class used to hold all of the command line option * state. */ - private static class CLIState + protected static class CLIState extends CLIStateBase { - private Options opts; public int algorithm = 8; public int keylength = 1024; public boolean useLargeE = true; @@ -62,20 +53,15 @@ public class KeyGen public CLIState() { - setupCLI(); + super("jdnssec-keygen [..options..] name"); } /** * Set up the command line options. - * - * @return a set of command line options. */ - private void setupCLI() + protected void setupOptions(Options opts) { - opts = new Options(); - // boolean options - opts.addOption("h", "help", false, "Print this message."); opts.addOption("k", "kskflag", false, "Key is a key-signing-key (sets the SEP flag)."); opts.addOption("e", "large-exponent", false, "Use large RSA exponent (default)"); @@ -88,13 +74,6 @@ public class KeyGen OptionBuilder.withDescription("ZONE | OTHER (default ZONE)"); opts.addOption(OptionBuilder.create('n')); - OptionBuilder.hasOptionalArg(); - OptionBuilder.withLongOpt("verbose"); - OptionBuilder.withArgName("level"); - OptionBuilder.withDescription("verbosity level -- 0 is silence, " - + "5 is debug information, 6 is trace information.\n" + "default is level 5."); - opts.addOption(OptionBuilder.create('v')); - OptionBuilder.hasArg(); OptionBuilder.withArgName("algorithm"); OptionBuilder.withDescription("RSA | RSASHA1 | RSAMD5 | DH | DSA " @@ -119,61 +98,16 @@ public class KeyGen OptionBuilder.withArgName("dir"); OptionBuilder.withDescription("place generated key files in this " + "directory"); opts.addOption(OptionBuilder.create('d')); - - OptionBuilder.hasArg(); - OptionBuilder.withLongOpt("alg-alias"); - OptionBuilder.withArgName("alias:original:mnemonic"); - OptionBuilder.withDescription("define an alias for an algorithm"); opts.addOption(OptionBuilder.create('A')); } - public void parseCommandLine(String[] args) + protected void processOptions(CommandLine cli) throws org.apache.commons.cli.ParseException { - CommandLineParser cli_parser = new PosixParser(); - CommandLine cli = cli_parser.parse(opts, args); - String optstr = null; - - if (cli.hasOption('h')) usage(); - - Logger rootLogger = Logger.getLogger(""); - - int value = parseInt(cli.getOptionValue('v'), -1); - switch (value) - { - case 0: - rootLogger.setLevel(Level.OFF); - break; - case 1: - rootLogger.setLevel(Level.SEVERE); - break; - case 2: - default: - rootLogger.setLevel(Level.WARNING); - break; - case 3: - rootLogger.setLevel(Level.INFO); - break; - case 4: - rootLogger.setLevel(Level.CONFIG); - case 5: - rootLogger.setLevel(Level.FINE); - break; - case 6: - rootLogger.setLevel(Level.ALL); - break; - } - - // I hate java.util.logging, btw. - for (Handler h : rootLogger.getHandlers()) - { - h.setLevel(rootLogger.getLevel()); - h.setFormatter(new BareLogFormatter()); - } - + String[] optstrs = null; + if (cli.hasOption('k')) kskFlag = true; - if (cli.hasOption('e')) useLargeE = true; outputfile = cli.getOptionValue('f'); @@ -191,7 +125,6 @@ public class KeyGen } } - String[] optstrs; if ((optstrs = cli.getOptionValues('A')) != null) { for (int i = 0; i < optstrs.length; i++) @@ -225,63 +158,8 @@ public class KeyGen owner = cl_args[0]; } - - private void addArgAlias(String s) - { - if (s == null) return; - - DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance(); - - String[] v = s.split(":"); - if (v.length < 2) return; - - int alias = parseInt(v[0], -1); - if (alias <= 0) return; - int orig = parseInt(v[1], -1); - if (orig <= 0) return; - String mn = null; - if (v.length > 2) mn = v[2]; - - algs.addAlias(alias, mn, orig); - } - - /** Print out the usage and help statements, then quit. */ - private void usage() - { - HelpFormatter f = new HelpFormatter(); - - PrintWriter out = new PrintWriter(System.err); - - // print our own usage statement: - f.printHelp(out, 75, "jdnssec-keygen [..options..] name", null, opts, - HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null); - - out.flush(); - System.exit(64); - } } - /** - * This is just a convenience method for parsing integers from strings. - * - * @param s - * the string to parse. - * @param def - * the default value, if the string doesn't parse. - * @return the parsed integer, or the default. - */ - private static int parseInt(String s, int def) - { - try - { - int v = Integer.parseInt(s); - return v; - } - catch (NumberFormatException e) - { - return def; - } - } private static int parseAlg(String s) { @@ -293,7 +171,7 @@ public class KeyGen return algs.stringToAlgorithm(s); } - public static void execute(CLIState state) throws Exception + public void execute() throws Exception { JCEDnsSecSigner signer = new JCEDnsSecSigner(); @@ -331,39 +209,9 @@ public class KeyGen public static void main(String[] args) { - CLIState state = new CLIState(); - - try - { - state.parseCommandLine(args); - } - catch (UnrecognizedOptionException e) - { - System.err.println("error: unknown option encountered: " + e.getMessage()); - state.usage(); - } - catch (AlreadySelectedException e) - { - System.err.println("error: mutually exclusive options have " - + "been selected:\n " + e.getMessage()); - state.usage(); - } - catch (Exception e) - { - System.err.println("error: unknown command line parsing exception:"); - e.printStackTrace(); - state.usage(); - } - - log = Logger.getLogger(KeyGen.class.toString()); - - try - { - execute(state); - } - catch (Exception e) - { - e.printStackTrace(); - } + KeyGen tool = new KeyGen(); + tool.state = new CLIState(); + + tool.run(tool.state, args); } } diff --git a/src/com/verisignlabs/dnssec/cl/KeyInfoTool.java b/src/com/verisignlabs/dnssec/cl/KeyInfoTool.java index 08b989e..3eead2a 100644 --- a/src/com/verisignlabs/dnssec/cl/KeyInfoTool.java +++ b/src/com/verisignlabs/dnssec/cl/KeyInfoTool.java @@ -1,6 +1,4 @@ -// $Id: KeyGen.java 1954 2005-08-14 17:05:50Z davidb $ -// -// Copyright (C) 2001-2003 VeriSign, Inc. +// Copyright (C) 2001-2003, 2011 VeriSign, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -19,12 +17,8 @@ package com.verisignlabs.dnssec.cl; -import java.io.PrintWriter; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.RSAPublicKey; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; import org.apache.commons.cli.*; import org.xbill.DNS.DNSKEYRecord; @@ -34,105 +28,35 @@ import com.verisignlabs.dnssec.security.*; /** * This class forms the command line implementation of a key introspection tool. * - * @author David Blacka (original) - * @author $Author: davidb $ - * @version $Revision: 1954 $ + * @author David Blacka */ -public class KeyInfoTool +public class KeyInfoTool extends CLBase { + private CLIState state; /** * This is a small inner class used to hold all of the command line option * state. */ - private static class CLIState + protected static class CLIState extends CLIStateBase { - private Options opts; public String[] keynames = null; public CLIState() { - setupCLI(); + super("jdnssec-keyinfo [..options..] keyfile"); } /** * Set up the command line options. - * - * @return a set of command line options. */ - private void setupCLI() + protected void setupOptions(Options opts) { - opts = new Options(); - - // boolean options - opts.addOption("h", "help", false, "Print this message."); - - OptionBuilder.hasOptionalArg(); - OptionBuilder.withLongOpt("verbose"); - OptionBuilder.withArgName("level"); - OptionBuilder.withDescription("verbosity level -- 0 is silence, " - + "5 is debug information, 6 is trace information.\n" + "default is level 5."); - // Argument options - opts.addOption(OptionBuilder.create('v')); - - OptionBuilder.hasArg(); - OptionBuilder.withLongOpt("alg-alias"); - OptionBuilder.withArgName("alias:original:mnemonic"); - OptionBuilder.withDescription("define an alias for an algorithm"); - opts.addOption(OptionBuilder.create('A')); + // no special options at the moment. } - public void parseCommandLine(String[] args) - throws org.apache.commons.cli.ParseException + protected void processOptions(CommandLine cli) throws ParseException { - CommandLineParser cli_parser = new PosixParser(); - CommandLine cli = cli_parser.parse(opts, args); - - if (cli.hasOption('h')) usage(); - - Logger rootLogger = Logger.getLogger(""); - - int value = parseInt(cli.getOptionValue('v'), -1); - switch (value) - { - case 0: - rootLogger.setLevel(Level.OFF); - break; - case 1: - rootLogger.setLevel(Level.SEVERE); - break; - case 2: - default: - rootLogger.setLevel(Level.WARNING); - break; - case 3: - rootLogger.setLevel(Level.INFO); - break; - case 4: - rootLogger.setLevel(Level.CONFIG); - case 5: - rootLogger.setLevel(Level.FINE); - break; - case 6: - rootLogger.setLevel(Level.ALL); - break; - } - - // I hate java.util.logging, btw. - for (Handler h : rootLogger.getHandlers()) - { - h.setLevel(rootLogger.getLevel()); - h.setFormatter(new BareLogFormatter()); - } - - String[] optstrs; - if ((optstrs = cli.getOptionValues('A')) != null) - { - for (int i = 0; i < optstrs.length; i++) - { - addArgAlias(optstrs[i]); - } - } keynames = cli.getArgs(); if (keynames.length < 1) @@ -141,67 +65,10 @@ public class KeyInfoTool usage(); } } - - /** Print out the usage and help statements, then quit. */ - private void usage() - { - HelpFormatter f = new HelpFormatter(); - - PrintWriter out = new PrintWriter(System.err); - - // print our own usage statement: - f.printHelp(out, 75, "jdnssec-keyinfo [..options..] keyfile", null, opts, - HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null); - - out.flush(); - System.exit(64); - } } - /** - * This is just a convenience method for parsing integers from strings. - * - * @param s - * the string to parse. - * @param def - * the default value, if the string doesn't parse. - * @return the parsed integer, or the default. - */ - private static int parseInt(String s, int def) + public void execute() throws Exception { - try - { - int v = Integer.parseInt(s); - return v; - } - catch (NumberFormatException e) - { - return def; - } - } - - private static void addArgAlias(String s) - { - if (s == null) return; - - DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance(); - - String[] v = s.split(":"); - if (v.length < 2) return; - - int alias = parseInt(v[0], -1); - if (alias <= 0) return; - int orig = parseInt(v[1], -1); - if (orig <= 0) return; - String mn = null; - if (v.length > 2) mn = v[2]; - - algs.addAlias(alias, mn, orig); - } - - public static void execute(CLIState state) throws Exception - { - for (int i = 0; i < state.keynames.length; ++i) { String keyname = state.keynames[i]; @@ -246,37 +113,9 @@ public class KeyInfoTool public static void main(String[] args) { - CLIState state = new CLIState(); + KeyInfoTool tool = new KeyInfoTool(); + tool.state = new CLIState(); - try - { - state.parseCommandLine(args); - } - catch (UnrecognizedOptionException e) - { - System.err.println("error: unknown option encountered: " + e.getMessage()); - state.usage(); - } - catch (AlreadySelectedException e) - { - System.err.println("error: mutually exclusive options have " - + "been selected:\n " + e.getMessage()); - state.usage(); - } - catch (Exception e) - { - System.err.println("error: unknown command line parsing exception:"); - e.printStackTrace(); - state.usage(); - } - - try - { - execute(state); - } - catch (Exception e) - { - e.printStackTrace(); - } + tool.run(tool.state, args); } } diff --git a/src/com/verisignlabs/dnssec/cl/SignKeyset.java b/src/com/verisignlabs/dnssec/cl/SignKeyset.java index 978a169..ec7d201 100644 --- a/src/com/verisignlabs/dnssec/cl/SignKeyset.java +++ b/src/com/verisignlabs/dnssec/cl/SignKeyset.java @@ -1,6 +1,4 @@ -// $Id: SignZone.java 2235 2009-02-07 20:37:29Z davidb $ -// -// Copyright (C) 2001-2003, 2009 VeriSign, Inc. +// Copyright (C) 2001-2003, 2011 VeriSign, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -22,26 +20,15 @@ package com.verisignlabs.dnssec.cl; import java.io.File; import java.io.FileFilter; import java.io.IOException; -import java.io.PrintWriter; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; -import java.util.TimeZone; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.apache.commons.cli.AlreadySelectedException; + import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; -import org.apache.commons.cli.PosixParser; -import org.apache.commons.cli.UnrecognizedOptionException; import org.xbill.DNS.DNSSEC; import org.xbill.DNS.Name; import org.xbill.DNS.RRset; @@ -55,21 +42,18 @@ import com.verisignlabs.dnssec.security.*; * Instead of being able to sign an entire zone, it will just sign a given * DNSKEY RRset. * - * @author David Blacka (original) - * @author $Author: davidb $ - * @version $Revision: 2235 $ + * @author David Blacka */ -public class SignKeyset +public class SignKeyset extends CLBase { - private static Logger log; + private CLIState state; /** * This is an inner class used to hold all of the command line option state. */ - private static class CLIState + protected static class CLIState extends CLIStateBase { - private Options opts; - private File keyDirectory = null; + public File keyDirectory = null; public String[] keyFiles = null; public Date start = null; public Date expire = null; @@ -79,29 +63,18 @@ public class SignKeyset public CLIState() { - setupCLI(); + super("jdnssec-signkeyset [..options..] dnskeyset_file [key_file ...]"); } /** * Set up the command line options. - * - * @return a set of command line options. */ - private void setupCLI() + protected void setupOptions(Options opts) { - opts = new Options(); - // boolean options - opts.addOption("h", "help", false, "Print this message."); opts.addOption("a", "verify", false, "verify generated signatures>"); - OptionBuilder.hasOptionalArg(); - OptionBuilder.withLongOpt("verbose"); - OptionBuilder.withArgName("level"); - OptionBuilder.withDescription("verbosity level."); // Argument options - opts.addOption(OptionBuilder.create('v')); - OptionBuilder.hasArg(); OptionBuilder.withArgName("dir"); OptionBuilder.withLongOpt("key-directory"); @@ -126,49 +99,9 @@ public class SignKeyset opts.addOption(OptionBuilder.create('f')); } - public void parseCommandLine(String[] args) - throws org.apache.commons.cli.ParseException, ParseException, IOException + protected void processOptions(CommandLine cli) throws org.apache.commons.cli.ParseException { - CommandLineParser cli_parser = new PosixParser(); - CommandLine cli = cli_parser.parse(opts, args); - String optstr = null; - if (cli.hasOption('h')) usage(); - - Logger rootLogger = Logger.getLogger(""); - - int value = parseInt(cli.getOptionValue('v'), -1); - switch (value) - { - case 0: - rootLogger.setLevel(Level.OFF); - break; - case 1: - rootLogger.setLevel(Level.SEVERE); - break; - case 2: - default: - rootLogger.setLevel(Level.WARNING); - break; - case 3: - rootLogger.setLevel(Level.INFO); - break; - case 4: - rootLogger.setLevel(Level.CONFIG); - case 5: - rootLogger.setLevel(Level.FINE); - break; - case 6: - rootLogger.setLevel(Level.ALL); - break; - } - - // I hate java.util.logging, btw. - for (Handler h : rootLogger.getHandlers()) - { - h.setLevel(rootLogger.getLevel()); - h.setFormatter(new BareLogFormatter()); - } if (cli.hasOption('a')) verifySigs = true; @@ -218,46 +151,6 @@ public class SignKeyset System.arraycopy(files, 1, keyFiles, 0, files.length - 1); } } - - /** Print out the usage and help statements, then quit. */ - private void usage() - { - HelpFormatter f = new HelpFormatter(); - - PrintWriter out = new PrintWriter(System.err); - - // print our own usage statement: - f.printHelp(out, 75, "jdnssec-signkeyset [..options..] " - + "dnskeyset_file [key_file ...]", null, opts, - HelpFormatter.DEFAULT_LEFT_PAD, - HelpFormatter.DEFAULT_DESC_PAD, - "\ntime/offset = YYYYMMDDHHmmss|+offset|\"now\"+offset\n"); - - out.flush(); - System.exit(64); - } - } - - /** - * This is just a convenience method for parsing integers from strings. - * - * @param s - * the string to parse. - * @param def - * the default value, if the string doesn't parse. - * @return the parsed integer, or the default. - */ - private static int parseInt(String s, int def) - { - try - { - int v = Integer.parseInt(s); - return v; - } - catch (NumberFormatException e) - { - return def; - } } /** @@ -378,38 +271,7 @@ public class SignKeyset return null; } - /** - * Calculate a date/time from a command line time/offset duration string. - * - * @param start - * the start time to calculate offsets from. - * @param duration - * the time/offset string to parse. - * @return the calculated time. - */ - private static Date convertDuration(Date start, String duration) throws ParseException - { - if (start == null) start = new Date(); - if (duration.startsWith("now")) - { - start = new Date(); - if (duration.indexOf("+") < 0) return start; - - duration = duration.substring(3); - } - - if (duration.startsWith("+")) - { - long offset = (long) parseInt(duration.substring(1), 0) * 1000; - return new Date(start.getTime() + offset); - } - - SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss"); - dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT")); - return dateFormatter.parse(duration); - } - - public static void execute(CLIState state) throws Exception + public void execute() throws Exception { // Read in the zone List records = ZoneUtils.readZoneFile(state.inputfile, null); @@ -524,38 +386,9 @@ public class SignKeyset public static void main(String[] args) { - CLIState state = new CLIState(); - try - { - state.parseCommandLine(args); - } - catch (UnrecognizedOptionException e) - { - System.err.println("error: unknown option encountered: " + e.getMessage()); - state.usage(); - } - catch (AlreadySelectedException e) - { - System.err.println("error: mutually exclusive options have " - + "been selected:\n " + e.getMessage()); - state.usage(); - } - catch (Exception e) - { - System.err.println("error: unknown command line parsing exception:"); - e.printStackTrace(); - state.usage(); - } - - log = Logger.getLogger(SignKeyset.class.toString()); - - try - { - execute(state); - } - catch (Exception e) - { - e.printStackTrace(); - } + SignKeyset tool = new SignKeyset(); + tool.state = new CLIState(); + + tool.run(tool.state, args); } } diff --git a/src/com/verisignlabs/dnssec/cl/SignRRset.java b/src/com/verisignlabs/dnssec/cl/SignRRset.java index a4fe6bc..ca80344 100644 --- a/src/com/verisignlabs/dnssec/cl/SignRRset.java +++ b/src/com/verisignlabs/dnssec/cl/SignRRset.java @@ -1,6 +1,4 @@ -// $Id: SignZone.java 2235 2009-02-07 20:37:29Z davidb $ -// -// Copyright (C) 2001-2003, 2009 VeriSign, Inc. +// Copyright (C) 2001-2003, 2011 VeriSign, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -21,26 +19,15 @@ package com.verisignlabs.dnssec.cl; import java.io.File; import java.io.IOException; -import java.io.PrintWriter; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; -import java.util.TimeZone; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.apache.commons.cli.AlreadySelectedException; import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; -import org.apache.commons.cli.PosixParser; -import org.apache.commons.cli.UnrecognizedOptionException; + import org.xbill.DNS.DNSSEC; import org.xbill.DNS.Name; import org.xbill.DNS.RRset; @@ -56,20 +43,17 @@ import com.verisignlabs.dnssec.security.*; * consideration of whether or not the RRset *should* be signed in the context * of a zone. * - * @author David Blacka (original) - * @author $Author: davidb $ - * @version $Revision: 2235 $ + * @author David Blacka */ -public class SignRRset +public class SignRRset extends CLBase { - private static Logger log; + private CLIState state; /** * This is an inner class used to hold all of the command line option state. */ - private static class CLIState + protected static class CLIState extends CLIStateBase { - private Options opts; private File keyDirectory = null; public String[] keyFiles = null; public Date start = null; @@ -80,29 +64,16 @@ public class SignRRset public CLIState() { - setupCLI(); + super("jdnssec-signrrset [..options..] rrset_file key_file [key_file ...]"); } /** * Set up the command line options. - * - * @return a set of command line options. */ - private void setupCLI() + protected void setupOptions(Options opts) { - opts = new Options(); - // boolean options - opts.addOption("h", "help", false, "Print this message."); opts.addOption("a", "verify", false, "verify generated signatures>"); - opts.addOption("m", "multiline", false, "Use a multiline format"); - - OptionBuilder.hasOptionalArg(); - OptionBuilder.withLongOpt("verbose"); - OptionBuilder.withArgName("level"); - OptionBuilder.withDescription("verbosity level."); - // Argument options - opts.addOption(OptionBuilder.create('v')); OptionBuilder.hasArg(); OptionBuilder.withArgName("dir"); @@ -128,52 +99,11 @@ public class SignRRset opts.addOption(OptionBuilder.create('f')); } - public void parseCommandLine(String[] args) - throws org.apache.commons.cli.ParseException, ParseException, IOException + protected void processOptions(CommandLine cli) throws org.apache.commons.cli.ParseException { - CommandLineParser cli_parser = new PosixParser(); - CommandLine cli = cli_parser.parse(opts, args); - String optstr = null; - if (cli.hasOption('h')) usage(); - - Logger rootLogger = Logger.getLogger(""); - - int value = parseInt(cli.getOptionValue('v'), -1); - switch (value) - { - case 0: - rootLogger.setLevel(Level.OFF); - break; - case 1: - rootLogger.setLevel(Level.SEVERE); - break; - case 2: - default: - rootLogger.setLevel(Level.WARNING); - break; - case 3: - rootLogger.setLevel(Level.INFO); - break; - case 4: - rootLogger.setLevel(Level.CONFIG); - case 5: - rootLogger.setLevel(Level.FINE); - break; - case 6: - rootLogger.setLevel(Level.ALL); - break; - } - - // I hate java.util.logging, btw. - for (Handler h : rootLogger.getHandlers()) - { - h.setLevel(rootLogger.getLevel()); - h.setFormatter(new BareLogFormatter()); - } if (cli.hasOption('a')) verifySigs = true; - if (cli.hasOption('m')) org.xbill.DNS.Options.set("multiline"); if ((optstr = cli.getOptionValue('D')) != null) { @@ -221,45 +151,6 @@ public class SignRRset System.arraycopy(files, 1, keyFiles, 0, files.length - 1); } } - - /** Print out the usage and help statements, then quit. */ - private void usage() - { - HelpFormatter f = new HelpFormatter(); - - PrintWriter out = new PrintWriter(System.err); - - // print our own usage statement: - f.printHelp(out, 75, "jdnssec-signrrset [..options..] " - + "rrset_file key_file [key_file ...]", null, opts, - HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, - "\ntime/offset = YYYYMMDDHHmmss|+offset|\"now\"+offset\n"); - - out.flush(); - System.exit(64); - } - } - - /** - * This is just a convenience method for parsing integers from strings. - * - * @param s - * the string to parse. - * @param def - * the default value, if the string doesn't parse. - * @return the parsed integer, or the default. - */ - private static int parseInt(String s, int def) - { - try - { - int v = Integer.parseInt(s); - return v; - } - catch (NumberFormatException e) - { - return def; - } } /** @@ -339,38 +230,7 @@ public class SignRRset return keys; } - /** - * Calculate a date/time from a command line time/offset duration string. - * - * @param start - * the start time to calculate offsets from. - * @param duration - * the time/offset string to parse. - * @return the calculated time. - */ - private static Date convertDuration(Date start, String duration) throws ParseException - { - if (start == null) start = new Date(); - if (duration.startsWith("now")) - { - start = new Date(); - if (duration.indexOf("+") < 0) return start; - - duration = duration.substring(3); - } - - if (duration.startsWith("+")) - { - long offset = (long) parseInt(duration.substring(1), 0) * 1000; - return new Date(start.getTime() + offset); - } - - SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss"); - dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT")); - return dateFormatter.parse(duration); - } - - public static void execute(CLIState state) throws Exception + public void execute() throws Exception { // Read in the zone List records = ZoneUtils.readZoneFile(state.inputfile, null); @@ -495,38 +355,9 @@ public class SignRRset public static void main(String[] args) { - CLIState state = new CLIState(); - try - { - state.parseCommandLine(args); - } - catch (UnrecognizedOptionException e) - { - System.err.println("error: unknown option encountered: " + e.getMessage()); - state.usage(); - } - catch (AlreadySelectedException e) - { - System.err.println("error: mutually exclusive options have " - + "been selected:\n " + e.getMessage()); - state.usage(); - } - catch (Exception e) - { - System.err.println("error: unknown command line parsing exception:"); - e.printStackTrace(); - state.usage(); - } - - log = Logger.getLogger(SignRRset.class.toString()); - - try - { - execute(state); - } - catch (Exception e) - { - e.printStackTrace(); - } + SignRRset tool = new SignRRset(); + tool.state = new CLIState(); + + tool.run(tool.state, args); } } diff --git a/src/com/verisignlabs/dnssec/cl/SignZone.java b/src/com/verisignlabs/dnssec/cl/SignZone.java index ae1cfc9..45b971b 100644 --- a/src/com/verisignlabs/dnssec/cl/SignZone.java +++ b/src/com/verisignlabs/dnssec/cl/SignZone.java @@ -1,6 +1,4 @@ -// $Id$ -// -// Copyright (C) 2001-2003, 2009 VeriSign, Inc. +// Copyright (C) 2001-2003, 2011 VeriSign, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -24,27 +22,17 @@ import java.io.File; import java.io.FileFilter; import java.io.FileReader; import java.io.IOException; -import java.io.PrintWriter; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Random; -import java.util.TimeZone; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.apache.commons.cli.AlreadySelectedException; import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; -import org.apache.commons.cli.PosixParser; -import org.apache.commons.cli.UnrecognizedOptionException; +import org.apache.commons.cli.ParseException; + import org.xbill.DNS.DNSKEYRecord; import org.xbill.DNS.DNSSEC; import org.xbill.DNS.DSRecord; @@ -55,26 +43,28 @@ import org.xbill.DNS.TextParseException; import org.xbill.DNS.Type; import org.xbill.DNS.utils.base16; -import com.verisignlabs.dnssec.security.*; +import com.verisignlabs.dnssec.security.BINDKeyUtils; +import com.verisignlabs.dnssec.security.DnsKeyPair; +import com.verisignlabs.dnssec.security.DnsSecVerifier; +import com.verisignlabs.dnssec.security.JCEDnsSecSigner; +import com.verisignlabs.dnssec.security.SignUtils; +import com.verisignlabs.dnssec.security.ZoneUtils; /** * This class forms the command line implementation of a DNSSEC zone signer. * - * @author David Blacka (original) - * @author $Author$ - * @version $Revision$ + * @author David Blacka */ -public class SignZone +public class SignZone extends CLBase { - private static Logger log; + private CLIState state; /** * This is an inner class used to hold all of the command line option state. */ - private static class CLIState + private static class CLIState extends CLIStateBase { - private Options opts; - private File keyDirectory = null; + public File keyDirectory = null; public File keysetDirectory = null; public String[] kskFiles = null; public String[] keyFiles = null; @@ -95,34 +85,18 @@ public class SignZone public CLIState() { - setupCLI(); + super("jdnssec-signzone [..options..] zone_file [key_file ...]"); } - /** - * Set up the command line options. - * - * @return a set of command line options. - */ - private void setupCLI() + protected void setupOptions(Options opts) { - opts = new Options(); - // boolean options - opts.addOption("h", "help", false, "Print this message."); opts.addOption("a", "verify", false, "verify generated signatures>"); opts.addOption("F", "fully-sign-keyset", false, "sign the zone apex keyset with all available keys."); opts.addOption("V", "verbose-signing", false, "Display verbose signing activity."); - opts.addOption("m", "multiline", false, "Use a multiline format"); // Argument options - OptionBuilder.hasOptionalArg(); - OptionBuilder.withLongOpt("verbose"); - OptionBuilder.withArgName("level"); - OptionBuilder.withDescription("verbosity level -- 0 is silence, 3 is info, " - + "5 is debug information, 6 is trace information. default is level 2 (warning)"); - opts.addOption(OptionBuilder.create('v')); - OptionBuilder.hasArg(); OptionBuilder.withArgName("dir"); OptionBuilder.withLongOpt("keyset-directory"); @@ -193,12 +167,6 @@ public class SignZone OptionBuilder.withDescription("use this value for the NSEC3PARAM RR ttl"); opts.addOption(OptionBuilder.create()); - OptionBuilder.hasArg(); - OptionBuilder.withArgName("alias:original:mnemonic"); - OptionBuilder.withLongOpt("alg-alias"); - OptionBuilder.withDescription("Define an alias for an algorithm (may repeat)."); - opts.addOption(OptionBuilder.create('A')); - OptionBuilder.hasArg(); OptionBuilder.withArgName("id"); OptionBuilder.withLongOpt("ds-digest"); @@ -206,57 +174,15 @@ public class SignZone opts.addOption(OptionBuilder.create()); } - public void parseCommandLine(String[] args) - throws org.apache.commons.cli.ParseException, ParseException, IOException + protected void processOptions(CommandLine cli) throws ParseException { - CommandLineParser cli_parser = new PosixParser(); - CommandLine cli = cli_parser.parse(opts, args); - - String optstr = null; - String[] optstrs = null; - - if (cli.hasOption('h')) usage(); - - Logger rootLogger = Logger.getLogger(""); - - int value = parseInt(cli.getOptionValue('v'), -1); - switch (value) - { - case 0: - rootLogger.setLevel(Level.OFF); - break; - case 1: - rootLogger.setLevel(Level.SEVERE); - break; - case 2: - default: - rootLogger.setLevel(Level.WARNING); - break; - case 3: - rootLogger.setLevel(Level.INFO); - break; - case 4: - rootLogger.setLevel(Level.CONFIG); - case 5: - rootLogger.setLevel(Level.FINE); - break; - case 6: - rootLogger.setLevel(Level.ALL); - break; - } - - // I hate java.util.logging, btw. - for (Handler h : rootLogger.getHandlers()) - { - h.setLevel(rootLogger.getLevel()); - h.setFormatter(new BareLogFormatter()); - } + String optstr; + String[] optstrs; if (cli.hasOption('a')) verifySigs = true; if (cli.hasOption('3')) useNsec3 = true; if (cli.hasOption('O')) useOptOut = true; if (cli.hasOption('V')) verboseSigning = true; - if (cli.hasOption('m')) org.xbill.DNS.Options.set("multiline"); if (useOptOut && !useNsec3) { @@ -264,14 +190,6 @@ public class SignZone useOptOut = false; } - if ((optstrs = cli.getOptionValues('A')) != null) - { - for (int i = 0; i < optstrs.length; i++) - { - addArgAlias(optstrs[i]); - } - } - if (cli.hasOption('F')) fullySignKeyset = true; if ((optstr = cli.getOptionValue('d')) != null) @@ -297,7 +215,7 @@ public class SignZone if ((optstr = cli.getOptionValue('s')) != null) { - start = convertDuration(null, optstr); + start = CLBase.convertDuration(null, optstr); } else { @@ -307,11 +225,11 @@ public class SignZone if ((optstr = cli.getOptionValue('e')) != null) { - expire = convertDuration(start, optstr); + expire = CLBase.convertDuration(start, optstr); } else { - expire = convertDuration(start, "+2592000"); // 30 days + expire = CLBase.convertDuration(start, "+2592000"); // 30 days } outputfile = cli.getOptionValue('f'); @@ -321,7 +239,14 @@ public class SignZone if ((optstr = cli.getOptionValue('I')) != null) { File includeNamesFile = new File(optstr); - includeNames = getNameList(includeNamesFile); + try + { + includeNames = getNameList(includeNamesFile); + } + catch (IOException e) + { + throw new ParseException(e.getMessage()); + } } if ((optstr = cli.getOptionValue('S')) != null) @@ -385,64 +310,6 @@ public class SignZone System.arraycopy(files, 1, keyFiles, 0, files.length - 1); } } - - private void addArgAlias(String s) - { - if (s == null) return; - - DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance(); - - String[] v = s.split(":"); - if (v.length < 2) return; - - int alias = parseInt(v[0], -1); - if (alias <= 0) return; - int orig = parseInt(v[1], -1); - if (orig <= 0) return; - String mn = null; - if (v.length > 2) mn = v[2]; - - algs.addAlias(alias, mn, orig); - } - - /** Print out the usage and help statements, then quit. */ - private void usage() - { - HelpFormatter f = new HelpFormatter(); - - PrintWriter out = new PrintWriter(System.err); - - // print our own usage statement: - f.printHelp(out, 75, - "jdnssec-signzone [..options..] " + "zone_file [key_file ...]", null, - opts, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, - "\ntime/offset = YYYYMMDDHHmmss|+offset|\"now\"+offset\n"); - - out.flush(); - System.exit(64); - } - } - - /** - * This is just a convenience method for parsing integers from strings. - * - * @param s - * the string to parse. - * @param def - * the default value, if the string doesn't parse. - * @return the parsed integer, or the default. - */ - private static int parseInt(String s, int def) - { - try - { - int v = Integer.parseInt(s); - return v; - } - catch (NumberFormatException e) - { - return def; - } } /** @@ -497,7 +364,8 @@ public class SignZone * a string array containing the base names or paths of the keys to * be loaded. * @param start_index - * the starting index of keyfiles string array to use. This allows us + * the starting index of keyfiles string array to use. This allows + * us * to use the straight command line argument array. * @param inDirectory * the directory to look in (may be null). @@ -602,12 +470,15 @@ public class SignZone * Load keysets (which contain delegation point security info). * * @param inDirectory - * the directory to look for the keyset files (may be null, in which + * the directory to look for the keyset files (may be null, in + * which * case it defaults to looking in the current working directory). * @param zonename - * the name of the zone we are signing, so we can ignore keysets that + * the name of the zone we are signing, so we can ignore keysets + * that * do not belong in the zone. - * @return a list of {@link org.xbill.DNS.Record}s found in the keyset files. + * @return a list of {@link org.xbill.DNS.Record}s found in the keyset + * files. */ private static List getKeysets(File inDirectory, Name zonename) throws IOException { @@ -677,44 +548,14 @@ public class SignZone return res; } - /** - * Calculate a date/time from a command line time/offset duration string. - * - * @param start - * the start time to calculate offsets from. - * @param duration - * the time/offset string to parse. - * @return the calculated time. - */ - private static Date convertDuration(Date start, String duration) throws ParseException - { - if (start == null) start = new Date(); - if (duration.startsWith("now")) - { - start = new Date(); - if (duration.indexOf("+") < 0) return start; - - duration = duration.substring(3); - } - - if (duration.startsWith("+")) - { - long offset = (long) parseInt(duration.substring(1), 0) * 1000; - return new Date(start.getTime() + offset); - } - - SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss"); - dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT")); - return dateFormatter.parse(duration); - } - /** * Determine if the given keypairs can be used to sign the zone. * * @param zonename * the zone origin. * @param keypairs - * a list of {@link DnsKeyPair} objects that will be used to sign the + * a list of {@link DnsKeyPair} objects that will be used to sign + * the * zone. * @return true if the keypairs valid. */ @@ -735,7 +576,7 @@ public class SignZone return true; } - public static void execute(CLIState state) throws Exception + public void execute() throws Exception { // Read in the zone List records = ZoneUtils.readZoneFile(state.zonefile, null); @@ -904,38 +745,9 @@ public class SignZone public static void main(String[] args) { - CLIState state = new CLIState(); - try - { - state.parseCommandLine(args); - } - catch (UnrecognizedOptionException e) - { - System.err.println("error: unknown option encountered: " + e.getMessage()); - state.usage(); - } - catch (AlreadySelectedException e) - { - System.err.println("error: mutually exclusive options have " - + "been selected:\n " + e.getMessage()); - state.usage(); - } - catch (Exception e) - { - System.err.println("error: unknown command line parsing exception:"); - e.printStackTrace(); - state.usage(); - } + SignZone tool = new SignZone(); + tool.state = new CLIState(); - log = Logger.getLogger(SignZone.class.toString()); - - try - { - execute(state); - } - catch (Exception e) - { - e.printStackTrace(); - } + tool.run(tool.state, args); } } diff --git a/src/com/verisignlabs/dnssec/cl/VerifyZone.java b/src/com/verisignlabs/dnssec/cl/VerifyZone.java index 223643e..35a958e 100644 --- a/src/com/verisignlabs/dnssec/cl/VerifyZone.java +++ b/src/com/verisignlabs/dnssec/cl/VerifyZone.java @@ -1,6 +1,4 @@ -// $Id$ -// -// Copyright (C) 2001-2003 VeriSign, Inc. +// Copyright (C) 2011 VeriSign, Inc. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -19,41 +17,31 @@ package com.verisignlabs.dnssec.cl; -import java.io.PrintWriter; import java.util.List; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.apache.commons.cli.AlreadySelectedException; import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; -import org.apache.commons.cli.PosixParser; -import org.apache.commons.cli.UnrecognizedOptionException; -import com.verisignlabs.dnssec.security.*; +import com.verisignlabs.dnssec.security.ZoneUtils; +import com.verisignlabs.dnssec.security.ZoneVerifier; /** * This class forms the command line implementation of a DNSSEC zone validator. * - * @author David Blacka (original) - * @author $Author$ - * @version $Revision$ + * @author David Blacka */ -public class VerifyZone +public class VerifyZone extends CLBase { - private static Logger log; - + + private CLIState state; + /** * This is a small inner class used to hold all of the command line option * state. */ - private static class CLIState + protected static class CLIState extends CLIStateBase { - private Options opts; public String zonefile = null; public String[] keyfiles = null; public int startfudge = 0; @@ -62,35 +50,11 @@ public class VerifyZone public CLIState() { - setupCLI(); + super("jdnssec-verifyzone [..options..] zonefile"); } - /** - * Set up the command line options. - * - * @return a set of command line options. - */ - private void setupCLI() + protected void setupOptions(Options opts) { - opts = new Options(); - - // boolean options - opts.addOption("h", "help", false, "Print this message."); - opts.addOption("m", "multiline", false, "log DNS records using 'multiline' format"); - - OptionBuilder.hasOptionalArg(); - OptionBuilder.withLongOpt("verbose"); - OptionBuilder.withArgName("level"); - OptionBuilder.withDescription("verbosity level -- 0 is silence, 3 is info, " - + "5 is debug information, 6 is trace information. default is level 2 (warning)"); - opts.addOption(OptionBuilder.create('v')); - - OptionBuilder.hasArg(); - OptionBuilder.withArgName("alias:original:mnemonic"); - OptionBuilder.withLongOpt("alg-alias"); - OptionBuilder.withDescription("Define an alias for an algorithm"); - opts.addOption(OptionBuilder.create('A')); - OptionBuilder.hasOptionalArg(); OptionBuilder.withLongOpt("sig-start-fudge"); OptionBuilder.withArgName("seconds"); @@ -107,55 +71,9 @@ public class VerifyZone OptionBuilder.withDescription("Ignore RRSIG inception and expiration time errors."); opts.addOption(OptionBuilder.create()); } - - public void parseCommandLine(String[] args) - throws org.apache.commons.cli.ParseException + + protected void processOptions(CommandLine cli) { - CommandLineParser cli_parser = new PosixParser(); - CommandLine cli = cli_parser.parse(opts, args); - - if (cli.hasOption('h')) usage(); - - Logger rootLogger = Logger.getLogger(""); - int value = parseInt(cli.getOptionValue('v'), -1); - - switch (value) - { - case 0: - rootLogger.setLevel(Level.OFF); - break; - case 1: - rootLogger.setLevel(Level.SEVERE); - break; - case 2: - default: - rootLogger.setLevel(Level.WARNING); - break; - case 3: - rootLogger.setLevel(Level.INFO); - break; - case 4: - rootLogger.setLevel(Level.CONFIG); - case 5: - rootLogger.setLevel(Level.FINE); - break; - case 6: - rootLogger.setLevel(Level.ALL); - break; - } - - // I hate java.util.logging, btw. - for (Handler h : rootLogger.getHandlers()) - { - h.setLevel(rootLogger.getLevel()); - h.setFormatter(new BareLogFormatter()); - } - - if (cli.hasOption('m')) - { - org.xbill.DNS.Options.set("multiline"); - } - if (cli.hasOption("ignore-time")) { ignoreTime = true; @@ -197,69 +115,11 @@ public class VerifyZone System.arraycopy(cl_args, 1, keyfiles, 0, keyfiles.length); } } - - private void addArgAlias(String s) - { - if (s == null) return; - - DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance(); - - String[] v = s.split(":"); - if (v.length < 2) return; - - int alias = parseInt(v[0], -1); - if (alias <= 0) return; - int orig = parseInt(v[1], -1); - if (orig <= 0) return; - String mn = null; - if (v.length > 2) mn = v[2]; - - algs.addAlias(alias, mn, orig); - } - - /** Print out the usage and help statements, then quit. */ - public void usage() - { - HelpFormatter f = new HelpFormatter(); - - PrintWriter out = new PrintWriter(System.err); - - // print our own usage statement: - f.printHelp(out, 75, "jdnssec-verifyzone [..options..] zonefile " - + "[keyfile [keyfile...]]", null, opts, - HelpFormatter.DEFAULT_LEFT_PAD, - HelpFormatter.DEFAULT_DESC_PAD, null); - - out.flush(); - System.exit(64); - - } - - /** - * This is just a convenience method for parsing integers from strings. - * - * @param s - * the string to parse. - * @param def - * the default value, if the string doesn't parse. - * @return the parsed integer, or the default. - */ - private static int parseInt(String s, int def) - { - try - { - int v = Integer.parseInt(s); - return v; - } - catch (NumberFormatException e) - { - return def; - } - } - } - public static void execute(CLIState state) throws Exception + + + public void execute() throws Exception { ZoneVerifier zoneverifier = new ZoneVerifier(); zoneverifier.getVerifier().setStartFudge(state.startfudge); @@ -286,39 +146,9 @@ public class VerifyZone public static void main(String[] args) { - CLIState state = new CLIState(); - - try - { - state.parseCommandLine(args); - } - catch (UnrecognizedOptionException e) - { - System.err.println("error: unknown option encountered: " + e.getMessage()); - state.usage(); - } - catch (AlreadySelectedException e) - { - System.err.println("error: mutually exclusive options have " - + "been selected:\n " + e.getMessage()); - state.usage(); - } - catch (Exception e) - { - System.err.println("error: unknown command line parsing exception:"); - e.printStackTrace(); - state.usage(); - } - - log = Logger.getLogger(VerifyZone.class.toString()); - - try - { - execute(state); - } - catch (Exception e) - { - e.printStackTrace(); - } + VerifyZone tool = new VerifyZone(); + tool.state = new CLIState(); + + tool.run(tool.state, args); } } diff --git a/src/com/verisignlabs/dnssec/cl/ZoneFormat.java b/src/com/verisignlabs/dnssec/cl/ZoneFormat.java index aea0040..594171c 100644 --- a/src/com/verisignlabs/dnssec/cl/ZoneFormat.java +++ b/src/com/verisignlabs/dnssec/cl/ZoneFormat.java @@ -1,31 +1,19 @@ -/* - * $Id$ - * - * Copyright (c) 2005 VeriSign. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. 2. Redistributions in - * binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. 3. The name of the author may not - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ +// Copyright (C) 2011 VeriSign, Inc. +// +// This library 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 (at your option) any later version. +// +// This library 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 +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA package com.verisignlabs.dnssec.cl; @@ -38,11 +26,10 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.cli.*; +import org.apache.commons.cli.Options; import org.xbill.DNS.*; -import org.xbill.DNS.Options; import org.xbill.DNS.utils.base32; -import com.verisignlabs.dnssec.security.BareLogFormatter; import com.verisignlabs.dnssec.security.RecordComparator; /** @@ -53,72 +40,34 @@ import com.verisignlabs.dnssec.security.RecordComparator; * @author $Author: davidb $ * @version $Revision: 2218 $ */ -public class ZoneFormat +public class ZoneFormat extends CLBase { - // private static Logger log; + private CLIState state; /** * This is a small inner class used to hold all of the command line option * state. */ - private static class CLIState + protected static class CLIState extends CLIStateBase { - private org.apache.commons.cli.Options opts; - public String file; - public boolean assignNSEC3; + public String file; + public boolean assignNSEC3; public CLIState() { - setupCLI(); + super("jdnssec-zoneformat [..options..] zonefile"); } - public void parseCommandLine(String[] args) - throws org.apache.commons.cli.ParseException + protected void setupOptions(Options opts) { - CommandLineParser cli_parser = new PosixParser(); - CommandLine cli = cli_parser.parse(opts, args); + opts.addOption("N", "nsec3", false, + "attempt to determine the original ownernames for NSEC3 RRs."); + } - // String optstr = null; - - if (cli.hasOption('h')) usage(); - if (cli.hasOption('m')) Options.set("multiline"); + protected void processOptions(CommandLine cli) throws ParseException + { if (cli.hasOption('N')) assignNSEC3 = true; - Logger rootLogger = Logger.getLogger(""); - - int value = parseInt(cli.getOptionValue('v'), -1); - switch (value) - { - case 0: - rootLogger.setLevel(Level.OFF); - break; - case 1: - rootLogger.setLevel(Level.SEVERE); - break; - case 2: - default: - rootLogger.setLevel(Level.WARNING); - break; - case 3: - rootLogger.setLevel(Level.INFO); - break; - case 4: - rootLogger.setLevel(Level.CONFIG); - case 5: - rootLogger.setLevel(Level.FINE); - break; - case 6: - rootLogger.setLevel(Level.ALL); - break; - } - - // I hate java.util.logging, btw. - for (Handler h : rootLogger.getHandlers()) - { - h.setLevel(rootLogger.getLevel()); - h.setFormatter(new BareLogFormatter()); - } - String[] cl_args = cli.getArgs(); if (cl_args.length < 1) @@ -129,69 +78,6 @@ public class ZoneFormat file = cl_args[0]; } - - /** - * Set up the command line options. - * - * @return a set of command line options. - */ - private void setupCLI() - { - opts = new org.apache.commons.cli.Options(); - - // boolean options - opts.addOption("h", "help", false, "Print this message."); - opts.addOption("m", "multiline", false, "Use a multiline format"); - opts.addOption("N", "nsec3", false, - "attempt to determine the original ownernames for NSEC3 RRs."); - - // Argument options - OptionBuilder.hasOptionalArg(); - OptionBuilder.withLongOpt("verbose"); - OptionBuilder.withArgName("level"); - OptionBuilder.withDescription("verbosity level -- 0 is silence, " - + "5 is debug information, 6 is trace information.\n" + "default is level 5."); - opts.addOption(OptionBuilder.create('v')); - } - - /** Print out the usage and help statements, then quit. */ - public void usage() - { - HelpFormatter f = new HelpFormatter(); - - PrintWriter out = new PrintWriter(System.err); - - // print our own usage statement: - f.printHelp(out, 75, "jdnssec-zoneformat [..options..] zonefile", null, opts, - HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null); - - out.flush(); - System.exit(64); - - } - - /** - * This is just a convenience method for parsing integers from strings. - * - * @param s - * the string to parse. - * @param def - * the default value, if the string doesn't parse. - * @return the parsed integer, or the default. - */ - private static int parseInt(String s, int def) - { - try - { - int v = Integer.parseInt(s); - return v; - } - catch (NumberFormatException e) - { - return def; - } - } - } private static List readZoneFile(String filename) throws IOException @@ -283,8 +169,7 @@ public class ZoneFormat } } - private static void execute(CLIState state) throws IOException, - NoSuchAlgorithmException + public void execute() throws IOException, NoSuchAlgorithmException { List z = readZoneFile(state.file); if (state.assignNSEC3) determineNSEC3Owners(z); @@ -293,40 +178,10 @@ public class ZoneFormat public static void main(String[] args) { - CLIState state = new CLIState(); - - try - { - state.parseCommandLine(args); - } - catch (UnrecognizedOptionException e) - { - System.err.println("error: unknown option encountered: " + e.getMessage()); - state.usage(); - } - catch (AlreadySelectedException e) - { - System.err.println("error: mutually exclusive options have " - + "been selected:\n " + e.getMessage()); - state.usage(); - } - catch (Exception e) - { - System.err.println("error: unknown command line parsing exception:"); - e.printStackTrace(); - state.usage(); - } - - // log = Logger.getLogger(VerifyZone.class.toString()); - - try - { - execute(state); - } - catch (Exception e) - { - e.printStackTrace(); - } + ZoneFormat tool = new ZoneFormat(); + tool.state = new CLIState(); + + tool.run(tool.state, args); } }