add error_file, count options; configure log4j so it stops whining; eclipse formattin...
authordavidb <davidb@verisign.com>
Thu, 10 Jun 2010 18:54:39 +0000 (14:54 -0400)
committerdavidb <davidb@verisign.com>
Thu, 10 Jun 2010 18:54:39 +0000 (14:54 -0400)
.settings/org.eclipse.jdt.core.prefs
build.xml
lib/log4j.properties [new file with mode: 0644]
src/com/verisign/cl/DNSSECReconciler.java

index ed721ef..1c73ace 100644 (file)
@@ -1,11 +1,11 @@
-#Mon May 31 12:14:23 EDT 2010
+#Thu Jun 10 13:45:36 EDT 2010
 eclipse.preferences.version=1
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=0
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
-org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=0
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=0
 org.eclipse.jdt.core.formatter.alignment_for_assignment=0
 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
@@ -15,7 +15,7 @@ org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
-org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=0
 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
index c403b78..9723e53 100644 (file)
--- a/build.xml
+++ b/build.xml
@@ -45,7 +45,7 @@
 
       <zipfileset src="${lib.dir}/dnsjava-2.0.8-vrsn-2.jar" />
       <zipfileset src="${lib.dir}/log4j-1.2.15.jar" />
-
+      <zipfileset dir="${lib.dir}" prefix="lib" includes="**/*.properties" />
       <manifest>
         <attribute name="Main-Class"
                    value="com.verisign.cl.DNSSECReconciler" />
diff --git a/lib/log4j.properties b/lib/log4j.properties
new file mode 100644 (file)
index 0000000..ebcdfba
--- /dev/null
@@ -0,0 +1,24 @@
+
+####################################################################
+#
+#            L O G 4 j            A P P E N D E R s
+# 
+###################################################################
+
+###################
+# Write Output to Console (aka TTY)
+#
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+####################################################################
+#
+#           R O O T     D E B U G G I N G     L E V E L 
+# 
+###################################################################
+
+######################
+# Set root logger level to an (Appender)
+#
+log4j.rootLogger=FATAL, console
index 9740880..64a3f05 100644 (file)
@@ -1,15 +1,15 @@
 package com.verisign.cl;
 
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
+import java.io.*;
 import java.net.SocketTimeoutException;
 import java.util.*;
 
+import org.apache.log4j.PropertyConfigurator;
 import org.xbill.DNS.*;
 
 import com.verisign.tat.dnssec.CaptiveValidator;
 import com.verisign.tat.dnssec.SecurityStatus;
+import com.verisign.tat.dnssec.Util;
 
 public class DNSSECReconciler {
 
@@ -21,6 +21,7 @@ public class DNSSECReconciler {
     private SimpleResolver resolver;
 
     private BufferedReader queryStream;
+    private PrintStream errorStream;
     private Set<Name> zoneNames;
 
     // Options
@@ -29,6 +30,8 @@ public class DNSSECReconciler {
     public String queryFile;
     public String dnskeyFile;
     public List<String> dnskeyNames;
+    public String errorFile;
+    public long count = 0;
 
     DNSSECReconciler() {
         validator = new CaptiveValidator();
@@ -62,6 +65,7 @@ public class DNSSECReconciler {
         for (int i = 1; i < tokens.length; i++) {
             if (tokens[i].startsWith("+")) {
                 // For now, we ignore flags as uninteresting
+                // All queries will get the DO bit anyway
                 continue;
             }
 
@@ -83,8 +87,7 @@ public class DNSSECReconciler {
             qclass = DClass.IN;
         }
 
-        Message query = Message
-                .newQuery(Record.newRecord(qname, qtype, qclass));
+        Message query = Message.newQuery(Record.newRecord(qname, qtype, qclass));
 
         return query;
     }
@@ -125,7 +128,7 @@ public class DNSSECReconciler {
      * 
      * @param query
      * @return a zone name
-     * @throws IOException 
+     * @throws IOException
      */
     private Name zoneFromQuery(Message query) throws IOException {
 
@@ -134,39 +137,43 @@ public class DNSSECReconciler {
             for (String key : validator.listTrustedKeys()) {
                 String[] components = key.split("/");
                 Name keyname = Name.fromString(components[0]);
-                if (! keyname.isAbsolute()) {
+                if (!keyname.isAbsolute()) {
                     keyname = Name.concatenate(keyname, Name.root);
                 }
                 zoneNames.add(keyname);
             }
         }
-        
+
         Name qname = query.getQuestion().getName();
         for (Name n : zoneNames) {
             if (qname.subdomain(n)) {
                 return n;
             }
         }
-        
+
         return null;
     }
 
     private Message resolve(Message query) {
-        
+
         try {
             return resolver.send(query);
         } catch (SocketTimeoutException e) {
-            System.err.println("Error: timed out querying " + server + " for " + queryToString(query));
+            System.err.println("Error: timed out querying " + server + " for "
+                    + queryToString(query));
         } catch (IOException e) {
-            System.err.println("Error: error querying " + server + " for " + queryToString(query) + ":" + e.getMessage());
+            System.err.println("Error: error querying " + server + " for "
+                    + queryToString(query) + ":" + e.getMessage());
         }
         return null;
     }
-    
+
     private String queryToString(Message query) {
-        if (query == null) return null;
+        if (query == null)
+            return null;
         Record question = query.getQuestion();
-        return question.getName() + "/" + Type.string(question.getType()) + "/" + DClass.string(question.getDClass());
+        return question.getName() + "/" + Type.string(question.getType()) + "/"
+                + DClass.string(question.getDClass());
     }
 
     public void execute() throws IOException {
@@ -174,6 +181,13 @@ public class DNSSECReconciler {
         resolver = new SimpleResolver(server);
         resolver.setEDNS(0, 4096, Flags.DO, null);
 
+        // Create our DNSSEC error stream
+        if (errorFile != null) {
+            errorStream = new PrintStream(new FileOutputStream(errorFile, true));
+        } else {
+            errorStream = System.out;
+        }
+
         // Prime the validator
         if (dnskeyFile != null) {
             validator.addTrustedKeysFromFile(dnskeyFile);
@@ -192,16 +206,18 @@ public class DNSSECReconciler {
 
         // Iterate over all queries
         Message query = nextQuery();
-        long count = 0;
+        long total = 0;
+        long validCount = 0;
+        long errorCount = 0;
 
         while (query != null) {
-            
+
             Name zone = zoneFromQuery(query);
             // Skip queries in zones that we don't have keys for
             if (zone == null) {
                 continue;
             }
-            
+
             Message response = resolve(query);
             if (response == null) {
                 continue;
@@ -211,53 +227,63 @@ public class DNSSECReconciler {
             switch (result) {
             case SecurityStatus.BOGUS:
             case SecurityStatus.INVALID:
-                System.out.println("BOGUS Answer:");
-                System.out.println("Query: " + queryToString(query));
-                System.out.println("Response:\n" + response);
+                errorStream.println("BOGUS Answer:");
+                errorStream.println("Query: " + queryToString(query));
+                errorStream.println("Response:\n" + response);
                 for (String err : validator.getErrorList()) {
-                    System.out.println("Error: " + err);
+                    errorStream.println("Error: " + err);
                 }
-                System.out.println("");
+                errorStream.println("");
+                errorCount++;
                 break;
             case SecurityStatus.INSECURE:
             case SecurityStatus.INDETERMINATE:
             case SecurityStatus.UNCHECKED:
-                System.out.println("Insecure Answer:");
-                System.out.println("Query: " + queryToString(query));
-                System.out.println("Response:\n" + response);
+                errorStream.println("Insecure Answer:");
+                errorStream.println("Query: " + queryToString(query));
+                errorStream.println("Response:\n" + response);
                 for (String err : validator.getErrorList()) {
-                    System.out.println("Error: " + err);
+                    errorStream.println("Error: " + err);
                 }
+                errorCount++;
                 break;
             case SecurityStatus.SECURE:
+                validCount++;
                 break;
             }
-            
-            if (++count % 1000 == 0) {
-                System.out.println("Completed " + count + " queries.");
+
+            if (++total % 1000 == 0) {
+                System.out.println("Completed " + total + " queries: "
+                        + validCount + " valid, " + errorCount + " errors.");
+            }
+         
+            if (count > 0 && total >= count) {
+                break;
             }
             
             query = nextQuery();
         }
-        
-        System.out.println("Completed " + count + (count > 1 ? " queries" : " query"));
+
+        System.out.println("Completed " + total
+                + (total > 1 ? " queries" : " query") +
+                ": " + validCount + " valid, " + errorCount + " errors.");
     }
 
     private static void usage() {
-        System.err
-                .println("usage: java -jar dnssecreconiler.jar [..options..]");
+        System.err.println("usage: java -jar dnssecreconiler.jar [..options..]");
         System.err.println("       server: the DNS server to query.");
         System.err.println("       query: a name [type [flags]] string.");
-        System.err
-                .println("       query_file: a list of queries, one query per line.");
-        System.err
-                .println("       dnskey_file: a file containing DNSKEY RRs to trust.");
-        System.err
-                .println("       dnskey_query: query 'server' for DNSKEY at given name to trust, may repeat");
+        System.err.println("       query_file: a list of queries, one query per line.");
+        System.err.println("       count: send up to'count' queries, then stop.");
+        System.err.println("       dnskey_file: a file containing DNSKEY RRs to trust.");
+        System.err.println("       dnskey_query: query 'server' for DNSKEY at given name to trust, may repeat");
+        System.err.println("       error_file: write DNSSEC validation failure details to this file");
     }
 
     public static void main(String[] argv) {
 
+        PropertyConfigurator.configure("lib/log4j.properties");
+
         DNSSECReconciler dr = new DNSSECReconciler();
 
         try {
@@ -280,6 +306,10 @@ public class DNSSECReconciler {
                     dr.query = optarg;
                 } else if (opt.equals("query_file")) {
                     dr.queryFile = optarg;
+                } else if (opt.equals("count")) {
+                    dr.count = Util.parseInt(optarg, 0);
+                } else if (opt.equals("error_file")) {
+                    dr.errorFile = optarg;
                 } else if (opt.equals("dnskey_file")) {
                     dr.dnskeyFile = optarg;
                 } else if (opt.equals("dnskey_query")) {
@@ -301,14 +331,12 @@ public class DNSSECReconciler {
                 System.exit(1);
             }
             if (dr.query == null && dr.queryFile == null) {
-                System.err
-                        .println("Either 'query' or 'query_file' must be specified");
+                System.err.println("Either 'query' or 'query_file' must be specified");
                 usage();
                 System.exit(1);
             }
             if (dr.dnskeyFile == null && dr.dnskeyNames == null) {
-                System.err
-                        .println("Either 'dnskey_file' or 'dnskey_query' must be specified");
+                System.err.println("Either 'dnskey_file' or 'dnskey_query' must be specified");
                 usage();
                 System.exit(1);
             }