diff options
Diffstat (limited to 'src/org/xbill/DNS/TSIGRecord.java')
-rw-r--r-- | src/org/xbill/DNS/TSIGRecord.java | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/org/xbill/DNS/TSIGRecord.java b/src/org/xbill/DNS/TSIGRecord.java new file mode 100644 index 0000000..c7ce9ed --- /dev/null +++ b/src/org/xbill/DNS/TSIGRecord.java @@ -0,0 +1,220 @@ +// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) + +package org.xbill.DNS; + +import java.io.*; +import java.util.*; +import org.xbill.DNS.utils.*; + +/** + * Transaction Signature - this record is automatically generated by the + * resolver. TSIG records provide transaction security between the + * sender and receiver of a message, using a shared key. + * @see Resolver + * @see TSIG + * + * @author Brian Wellington + */ + +public class TSIGRecord extends Record { + +private static final long serialVersionUID = -88820909016649306L; + +private Name alg; +private Date timeSigned; +private int fudge; +private byte [] signature; +private int originalID; +private int error; +private byte [] other; + +TSIGRecord() {} + +Record +getObject() { + return new TSIGRecord(); +} + +/** + * Creates a TSIG Record from the given data. This is normally called by + * the TSIG class + * @param alg The shared key's algorithm + * @param timeSigned The time that this record was generated + * @param fudge The fudge factor for time - if the time that the message is + * received is not in the range [now - fudge, now + fudge], the signature + * fails + * @param signature The signature + * @param originalID The message ID at the time of its generation + * @param error The extended error field. Should be 0 in queries. + * @param other The other data field. Currently used only in BADTIME + * responses. + * @see TSIG + */ +public +TSIGRecord(Name name, int dclass, long ttl, Name alg, Date timeSigned, + int fudge, byte [] signature, int originalID, int error, + byte other[]) +{ + super(name, Type.TSIG, dclass, ttl); + this.alg = checkName("alg", alg); + this.timeSigned = timeSigned; + this.fudge = checkU16("fudge", fudge); + this.signature = signature; + this.originalID = checkU16("originalID", originalID); + this.error = checkU16("error", error); + this.other = other; +} + +void +rrFromWire(DNSInput in) throws IOException { + alg = new Name(in); + + long timeHigh = in.readU16(); + long timeLow = in.readU32(); + long time = (timeHigh << 32) + timeLow; + timeSigned = new Date(time * 1000); + fudge = in.readU16(); + + int sigLen = in.readU16(); + signature = in.readByteArray(sigLen); + + originalID = in.readU16(); + error = in.readU16(); + + int otherLen = in.readU16(); + if (otherLen > 0) + other = in.readByteArray(otherLen); + else + other = null; +} + +void +rdataFromString(Tokenizer st, Name origin) throws IOException { + throw st.exception("no text format defined for TSIG"); +} + +/** Converts rdata to a String */ +String +rrToString() { + StringBuffer sb = new StringBuffer(); + sb.append(alg); + sb.append(" "); + if (Options.check("multiline")) + sb.append("(\n\t"); + + sb.append (timeSigned.getTime() / 1000); + sb.append (" "); + sb.append (fudge); + sb.append (" "); + sb.append (signature.length); + if (Options.check("multiline")) { + sb.append ("\n"); + sb.append (base64.formatString(signature, 64, "\t", false)); + } else { + sb.append (" "); + sb.append (base64.toString(signature)); + } + sb.append (" "); + sb.append (Rcode.TSIGstring(error)); + sb.append (" "); + if (other == null) + sb.append (0); + else { + sb.append (other.length); + if (Options.check("multiline")) + sb.append("\n\n\n\t"); + else + sb.append(" "); + if (error == Rcode.BADTIME) { + if (other.length != 6) { + sb.append("<invalid BADTIME other data>"); + } else { + long time = ((long)(other[0] & 0xFF) << 40) + + ((long)(other[1] & 0xFF) << 32) + + ((other[2] & 0xFF) << 24) + + ((other[3] & 0xFF) << 16) + + ((other[4] & 0xFF) << 8) + + ((other[5] & 0xFF) ); + sb.append("<server time: "); + sb.append(new Date(time * 1000)); + sb.append(">"); + } + } else { + sb.append("<"); + sb.append(base64.toString(other)); + sb.append(">"); + } + } + if (Options.check("multiline")) + sb.append(" )"); + return sb.toString(); +} + +/** Returns the shared key's algorithm */ +public Name +getAlgorithm() { + return alg; +} + +/** Returns the time that this record was generated */ +public Date +getTimeSigned() { + return timeSigned; +} + +/** Returns the time fudge factor */ +public int +getFudge() { + return fudge; +} + +/** Returns the signature */ +public byte [] +getSignature() { + return signature; +} + +/** Returns the original message ID */ +public int +getOriginalID() { + return originalID; +} + +/** Returns the extended error */ +public int +getError() { + return error; +} + +/** Returns the other data */ +public byte [] +getOther() { + return other; +} + +void +rrToWire(DNSOutput out, Compression c, boolean canonical) { + alg.toWire(out, null, canonical); + + long time = timeSigned.getTime() / 1000; + int timeHigh = (int) (time >> 32); + long timeLow = (time & 0xFFFFFFFFL); + out.writeU16(timeHigh); + out.writeU32(timeLow); + out.writeU16(fudge); + + out.writeU16(signature.length); + out.writeByteArray(signature); + + out.writeU16(originalID); + out.writeU16(error); + + if (other != null) { + out.writeU16(other.length); + out.writeByteArray(other); + } + else + out.writeU16(0); +} + +} |