use of org.xbill.DNS.RRset in project nhin-d by DirectProject.
the class ConfigServiceDNSStore method processCERTRecordRequest.
/**
* Processes all DNS CERT requests.
* @param name The record name. In many cases this a email address.
* @return Returns a set of record responses to the request.
* @throws DNSException
*/
@SuppressWarnings("unused")
protected RRset processCERTRecordRequest(String name) throws DNSException {
if (name.endsWith("."))
name = name.substring(0, name.length() - 1);
Certificate[] certs;
// use the certificate configuration service
try {
certs = proxy.getCertificatesForOwner(name, null);
} catch (Exception e) {
throw new DNSException(DNSError.newError(Rcode.SERVFAIL), "DNS service proxy call for certificates failed: " + e.getMessage(), e);
}
if (certs == null || certs.length == 0) {
// unless the call above was for an org level cert, it will probably always fail because the
// "name" parameter has had all instances of "@" replaced with ".". The certificate service
// stores owners using "@".
// This is horrible, but try hitting the cert service replacing each "." with "@" one by one.
// Start at the beginning of the address because this is more than likely where the "@" character
// will be.
int previousIndex = 0;
int replaceIndex = 0;
while ((replaceIndex = name.indexOf(".", previousIndex)) > -1) {
char[] chars = name.toCharArray();
chars[replaceIndex] = '@';
try {
certs = proxy.getCertificatesForOwner(String.copyValueOf(chars), null);
} catch (Exception e) {
throw new DNSException(DNSError.newError(Rcode.SERVFAIL), "DNS service proxy call for certificates failed: " + e.getMessage(), e);
}
if (certs != null && certs.length > 0)
break;
if (replaceIndex >= (name.length() - 1))
break;
previousIndex = replaceIndex + 1;
}
}
if (certs == null || certs.length == 0)
return null;
if (!name.endsWith("."))
name += ".";
RRset retVal = new RRset();
try {
for (Certificate cert : certs) {
int certRecordType = CERTRecord.PKIX;
byte[] retData = null;
X509Certificate xCert = null;
try {
// need to convert to cert container because this might be
// a certificate with wrapped private key data
final CertUtils.CertContainer cont = CertUtils.toCertContainer(cert.getData());
xCert = cont.getCert();
// check if this is a compliant certificate with the configured policy... if not, move on
if (!isCertCompliantWithPolicy(xCert))
continue;
retData = xCert.getEncoded();
} catch (CertificateConversionException e) {
// probably not a Certificate... might be a URL
}
if (xCert == null) {
// see if it's a URL
try {
retData = cert.getData();
URL url = new URL(new String(retData));
certRecordType = CERTRecord.URI;
} catch (Exception e) {
throw new DNSException(DNSError.newError(Rcode.SERVFAIL), "Failure while parsing CERT record data: " + e.getMessage(), e);
}
}
int keyTag = 0;
int alg = 0;
if (xCert != null && xCert.getPublicKey() instanceof RSAKey) {
RSAKey key = (RSAKey) xCert.getPublicKey();
byte[] modulus = key.getModulus().toByteArray();
keyTag = (modulus[modulus.length - 2] << 8) & 0xFF00;
keyTag |= modulus[modulus.length - 1] & 0xFF;
alg = 5;
}
CERTRecord rec = new CERTRecord(Name.fromString(name), DClass.IN, 86400L, certRecordType, keyTag, alg, /*public key alg, RFC 4034*/
retData);
retVal.addRR(rec);
}
} catch (Exception e) {
throw new DNSException(DNSError.newError(Rcode.SERVFAIL), "Failure while parsing CERT record data: " + e.getMessage(), e);
}
// resulting in an empty RR set
return (retVal.size() == 0) ? null : retVal;
}
use of org.xbill.DNS.RRset in project opennms by OpenNMS.
the class DNSServer method addCacheNS.
private final void addCacheNS(final Message response, final Cache cache, final Name name) {
final SetResponse sr = cache.lookupRecords(name, Type.NS, Credibility.HINT);
if (!sr.isDelegation())
return;
final RRset nsRecords = sr.getNS();
@SuppressWarnings("unchecked") final Iterator<Record> it = nsRecords.rrs();
while (it.hasNext()) {
final Record r = it.next();
response.addRecord(r, Section.AUTHORITY);
}
}
use of org.xbill.DNS.RRset in project opennms by OpenNMS.
the class DNSServer method doAXFR.
byte[] doAXFR(final Name name, final Message query, final TSIG tsig, TSIGRecord qtsig, final Socket s) {
final Zone zone = m_znames.get(name);
boolean first = true;
if (zone == null)
return errorMessage(query, Rcode.REFUSED);
@SuppressWarnings("unchecked") final Iterator<RRset> it = zone.AXFR();
try {
final DataOutputStream dataOut = new DataOutputStream(s.getOutputStream());
int id = query.getHeader().getID();
while (it.hasNext()) {
final RRset rrset = it.next();
final Message response = new Message(id);
final Header header = response.getHeader();
header.setFlag(Flags.QR);
header.setFlag(Flags.AA);
addRRset(rrset.getName(), response, rrset, Section.ANSWER, FLAG_DNSSECOK);
if (tsig != null) {
tsig.applyStream(response, qtsig, first);
qtsig = response.getTSIG();
}
first = false;
final byte[] out = response.toWire();
dataOut.writeShort(out.length);
dataOut.write(out);
}
} catch (final IOException ex) {
LOG.warn("AXFR failed", ex);
}
try {
s.close();
} catch (final IOException ex) {
LOG.warn("error closing socket", ex);
}
return null;
}
use of org.xbill.DNS.RRset in project opennms by OpenNMS.
the class DNSServer method addNS.
private final void addNS(final Message response, final Zone zone, final int flags) {
final RRset nsRecords = zone.getNS();
addRRset(nsRecords.getName(), response, nsRecords, Section.AUTHORITY, flags);
}
use of org.xbill.DNS.RRset in project opennms by OpenNMS.
the class DNSServer method addAnswer.
byte addAnswer(final Message response, final Name name, int type, int dclass, int iterations, int flags) {
SetResponse sr;
byte rcode = Rcode.NOERROR;
if (iterations > 6)
return Rcode.NOERROR;
if (type == Type.SIG || type == Type.RRSIG) {
type = Type.ANY;
flags |= FLAG_SIGONLY;
}
final Zone zone = findBestZone(name);
if (zone != null)
sr = zone.findRecords(name, type);
else {
sr = getCache(dclass).lookupRecords(name, type, Credibility.NORMAL);
}
if (sr.isUnknown()) {
addCacheNS(response, getCache(dclass), name);
}
if (sr.isNXDOMAIN()) {
response.getHeader().setRcode(Rcode.NXDOMAIN);
if (zone != null) {
addSOA(response, zone);
if (iterations == 0)
response.getHeader().setFlag(Flags.AA);
}
rcode = Rcode.NXDOMAIN;
} else if (sr.isNXRRSET()) {
if (zone != null) {
addSOA(response, zone);
if (iterations == 0)
response.getHeader().setFlag(Flags.AA);
}
} else if (sr.isDelegation()) {
final RRset nsRecords = sr.getNS();
addRRset(nsRecords.getName(), response, nsRecords, Section.AUTHORITY, flags);
} else if (sr.isCNAME()) {
final CNAMERecord cname = sr.getCNAME();
addRRset(name, response, new RRset(cname), Section.ANSWER, flags);
if (zone != null && iterations == 0)
response.getHeader().setFlag(Flags.AA);
rcode = addAnswer(response, cname.getTarget(), type, dclass, iterations + 1, flags);
} else if (sr.isDNAME()) {
final DNAMERecord dname = sr.getDNAME();
RRset rrset = new RRset(dname);
addRRset(name, response, rrset, Section.ANSWER, flags);
final Name newname;
try {
newname = name.fromDNAME(dname);
} catch (final NameTooLongException e) {
return Rcode.YXDOMAIN;
}
rrset = new RRset(new CNAMERecord(name, dclass, 0, newname));
addRRset(name, response, rrset, Section.ANSWER, flags);
if (zone != null && iterations == 0)
response.getHeader().setFlag(Flags.AA);
rcode = addAnswer(response, newname, type, dclass, iterations + 1, flags);
} else if (sr.isSuccessful()) {
final RRset[] rrsets = sr.answers();
for (int i = 0; i < rrsets.length; i++) addRRset(name, response, rrsets[i], Section.ANSWER, flags);
if (zone != null) {
addNS(response, zone, flags);
if (iterations == 0)
response.getHeader().setFlag(Flags.AA);
} else
addCacheNS(response, getCache(dclass), name);
}
return rcode;
}
Aggregations