+ /**
+ * Fetch the next query from either the command line or the query file
+ *
+ * @return a query Message, or null if the query list is exhausted
+ * @throws IOException
+ */
+ private Message nextQuery() throws IOException {
+ if (query != null) {
+ Message res = queryFromString(query);
+ query = null;
+ return res;
+ }
+
+ if (queryStream == null && queryFile != null) {
+ queryStream = new BufferedReader(new FileReader(queryFile));
+ }
+
+ if (queryStream != null) {
+ String line = queryStream.readLine();
+
+ if (line == null)
+ return null;
+
+ return queryFromString(line);
+ }
+
+ return null;
+
+ }
+
+ /**
+ * Figure out the correct zone from the query by comparing the qname to the
+ * list of trusted DNSKEY owner names.
+ *
+ * @param query
+ * @return a zone name
+ * @throws IOException
+ */
+ private Name zoneFromQuery(Message query) throws IOException {
+
+ if (zoneNames == null) {
+ zoneNames = new HashSet<Name>();
+ for (String key : validator.listTrustedKeys()) {
+ String[] components = key.split("/");
+ Name keyname = Name.fromString(components[0]);
+ 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;
+ }
+
+ public void execute() throws IOException {
+ // Configure our resolver
+ resolver = new SimpleResolver(server);
+ resolver.setEDNS(0, 4096, Flags.DO, null);
+
+ // Prime the validator
+ if (dnskeyFile != null) {
+ validator.addTrustedKeysFromFile(dnskeyFile);
+ } else {
+ for (String name : dnskeyNames) {
+ Message query = queryFromString(name + " DNSKEY");
+ Message response = resolver.send(query);
+ validator.addTrustedKeysFromResponse(response);
+ }
+ }
+
+ // Log our set of trusted keys
+ for (String key : validator.listTrustedKeys()) {
+ System.out.println("Trusted Key: " + key);
+ }
+
+ // Iterate over all queries
+ Message query = nextQuery();
+
+ while (query != null) {
+ Message response = resolver.send(query);
+ if (response == null) {
+ continue;
+ }
+
+ Name zone = zoneFromQuery(query);
+ byte result = validator.validateMessage(response, zone.toString());
+
+ switch (result) {
+ case SecurityStatus.BOGUS:
+ case SecurityStatus.INVALID:
+ System.out.println("BOGUS Answer:");
+ System.out.println("Query: " + query.getQuestion());
+ System.out.println("Response:\n" + response);
+ for (String err : validator.getErrorList()) {
+ System.out.println("Error: " + err);
+ }
+ System.out.println("");
+ break;
+ case SecurityStatus.INSECURE:
+ case SecurityStatus.INDETERMINATE:
+ case SecurityStatus.UNCHECKED:
+ System.out.println("Insecure Answer:");
+ System.out.println("Query: " + query.getQuestion());
+ System.out.println("Response:\n" + response);
+ for (String err : validator.getErrorList()) {
+ System.out.println("Error: " + err);
+ }
+ break;
+ case SecurityStatus.SECURE:
+ break;
+ }
+
+ query = nextQuery();
+ }