Add -N option for calculating original ownernames for NSEC3 RRs

git-svn-id: https://svn.verisignlabs.com/jdnssec/tools/trunk@226 4cbd57fe-54e5-0310-bd9a-f30fe5ea5e6e
This commit is contained in:
David Blacka 2011-02-02 19:36:14 +00:00
parent 04d751ae56
commit 1616d07fe6
2 changed files with 73 additions and 14 deletions

View File

@ -1,6 +1,8 @@
2011-01-11 Blacka <davidb@verisignlabs.com> 2011-01-11 Blacka <davidb@verisignlabs.com>
* jdnssec-zoneformat: add a -m option for formatting as multiline. * jdnssec-zoneformat: add a -m option for formatting as
multiline. Add a -N option for determining the original
ownernames for NSEC3 signed zones.
2010-12-14 Blacka <davidb@verisignlabs.com> 2010-12-14 Blacka <davidb@verisignlabs.com>

View File

@ -31,18 +31,15 @@ package com.verisignlabs.dnssec.cl;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.security.NoSuchAlgorithmException;
import java.util.Collections; import java.util.*;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.apache.commons.cli.*; import org.apache.commons.cli.*;
import org.xbill.DNS.Master; import org.xbill.DNS.*;
import org.xbill.DNS.Options; import org.xbill.DNS.Options;
import org.xbill.DNS.Record; import org.xbill.DNS.utils.base32;
import org.xbill.DNS.Section;
import com.verisignlabs.dnssec.security.RecordComparator; import com.verisignlabs.dnssec.security.RecordComparator;
@ -66,6 +63,7 @@ public class ZoneFormat
{ {
private org.apache.commons.cli.Options opts; private org.apache.commons.cli.Options opts;
public String file; public String file;
public boolean assignNSEC3;
public CLIState() public CLIState()
{ {
@ -82,6 +80,7 @@ public class ZoneFormat
if (cli.hasOption('h')) usage(); if (cli.hasOption('h')) usage();
if (cli.hasOption('m')) Options.set("multiline"); if (cli.hasOption('m')) Options.set("multiline");
if (cli.hasOption('N')) assignNSEC3 = true;
if (cli.hasOption('v')) if (cli.hasOption('v'))
{ {
@ -125,14 +124,15 @@ public class ZoneFormat
// boolean options // boolean options
opts.addOption("h", "help", false, "Print this message."); opts.addOption("h", "help", false, "Print this message.");
opts.addOption("m", "multiline", false, "Use a multiline format"); 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 // Argument options
OptionBuilder.hasOptionalArg(); OptionBuilder.hasOptionalArg();
OptionBuilder.withLongOpt("verbose"); OptionBuilder.withLongOpt("verbose");
OptionBuilder.withArgName("level"); OptionBuilder.withArgName("level");
OptionBuilder.withDescription("verbosity level -- 0 is silence, " OptionBuilder.withDescription("verbosity level -- 0 is silence, "
+ "5 is debug information, 6 is trace information.\n" + "5 is debug information, 6 is trace information.\n" + "default is level 5.");
+ "default is level 5.");
opts.addOption(OptionBuilder.create('v')); opts.addOption(OptionBuilder.create('v'));
} }
@ -144,9 +144,8 @@ public class ZoneFormat
PrintWriter out = new PrintWriter(System.err); PrintWriter out = new PrintWriter(System.err);
// print our own usage statement: // print our own usage statement:
f.printHelp(out, 75, "jdnssec-zoneformat [..options..] zonefile", null, f.printHelp(out, 75, "jdnssec-zoneformat [..options..] zonefile", null, opts,
opts, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_LEFT_PAD, HelpFormatter.DEFAULT_DESC_PAD, null);
HelpFormatter.DEFAULT_DESC_PAD, null);
out.flush(); out.flush();
System.exit(64); System.exit(64);
@ -210,9 +209,67 @@ public class ZoneFormat
} }
} }
private static void execute(CLIState state) throws IOException private static void determineNSEC3Owners(List zone) throws NoSuchAlgorithmException
{
// Put the zone into a consistent (name and RR type) order.
Collections.sort(zone, new RecordComparator());
// first, find the NSEC3PARAM record -- this is an inefficient linear
// search.
NSEC3PARAMRecord nsec3param = null;
HashMap map = new HashMap();
base32 b32 = new base32(base32.Alphabet.BASE32HEX, false, true);
for (Iterator i = zone.iterator(); i.hasNext();)
{
Record r = (Record) i.next();
if (r.getType() == Type.NSEC3PARAM)
{
nsec3param = (NSEC3PARAMRecord) r;
break;
}
}
// If there wasn't one, we have nothing to do.
if (nsec3param == null) return;
// Next pass, calculate a mapping between ownernames and hashnames
Name last_name = null;
for (Iterator i = zone.iterator(); i.hasNext();)
{
Record r = (Record) i.next();
if (r.getName().equals(last_name)) continue;
if (r.getType() == Type.NSEC3) continue;
byte[] hash = nsec3param.hashName(r.getName());
String hashname = b32.toString(hash);
map.put(hashname, r.getName().toString().toLowerCase());
last_name = r.getName();
}
// Final pass, assign the names if we can
for (ListIterator i = zone.listIterator(); i.hasNext();)
{
Record r = (Record) i.next();
if (r.getType() != Type.NSEC3) continue;
NSEC3Record nsec3 = (NSEC3Record) r;
String hashname = nsec3.getName().getLabelString(0).toLowerCase();
String ownername = (String) map.get(hashname);
NSEC3Record new_nsec3 = new NSEC3Record(nsec3.getName(), nsec3.getDClass(),
nsec3.getTTL(), nsec3.getHashAlgorithm(),
nsec3.getFlags(), nsec3.getIterations(),
nsec3.getSalt(), nsec3.getNext(),
nsec3.getTypes(), ownername);
i.set(new_nsec3);
}
}
private static void execute(CLIState state) throws IOException,
NoSuchAlgorithmException
{ {
List z = readZoneFile(state.file); List z = readZoneFile(state.file);
if (state.assignNSEC3) determineNSEC3Owners(z);
formatZone(z); formatZone(z);
} }