Search in sources :

Example 6 with RRset

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;
}
Also used : RSAKey(java.security.interfaces.RSAKey) RRset(org.xbill.DNS.RRset) CertificateConversionException(org.nhindirect.config.model.exceptions.CertificateConversionException) CertificateConversionException(org.nhindirect.config.model.exceptions.CertificateConversionException) X509Certificate(java.security.cert.X509Certificate) URL(java.net.URL) ConfigServiceURL(org.nhindirect.dns.annotation.ConfigServiceURL) CertUtils(org.nhindirect.config.model.utils.CertUtils) CERTRecord(org.xbill.DNS.CERTRecord) X509Certificate(java.security.cert.X509Certificate) Certificate(org.nhind.config.Certificate)

Example 7 with RRset

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);
    }
}
Also used : SetResponse(org.xbill.DNS.SetResponse) RRset(org.xbill.DNS.RRset) CNAMERecord(org.xbill.DNS.CNAMERecord) TSIGRecord(org.xbill.DNS.TSIGRecord) OPTRecord(org.xbill.DNS.OPTRecord) Record(org.xbill.DNS.Record) DNAMERecord(org.xbill.DNS.DNAMERecord)

Example 8 with RRset

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;
}
Also used : Message(org.xbill.DNS.Message) Header(org.xbill.DNS.Header) Zone(org.xbill.DNS.Zone) DataOutputStream(java.io.DataOutputStream) RRset(org.xbill.DNS.RRset) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException)

Example 9 with RRset

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);
}
Also used : RRset(org.xbill.DNS.RRset)

Example 10 with RRset

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;
}
Also used : SetResponse(org.xbill.DNS.SetResponse) CNAMERecord(org.xbill.DNS.CNAMERecord) NameTooLongException(org.xbill.DNS.NameTooLongException) DNAMERecord(org.xbill.DNS.DNAMERecord) Zone(org.xbill.DNS.Zone) RRset(org.xbill.DNS.RRset) Name(org.xbill.DNS.Name)

Aggregations

RRset (org.xbill.DNS.RRset)11 Message (org.xbill.DNS.Message)4 Record (org.xbill.DNS.Record)4 SetResponse (org.xbill.DNS.SetResponse)4 ArrayList (java.util.ArrayList)3 CertificateConversionException (org.nhindirect.config.model.exceptions.CertificateConversionException)3 CERTRecord (org.xbill.DNS.CERTRecord)3 CNAMERecord (org.xbill.DNS.CNAMERecord)3 Name (org.xbill.DNS.Name)3 Zone (org.xbill.DNS.Zone)3 DnsRecord (org.nhind.config.DnsRecord)2 DNAMERecord (org.xbill.DNS.DNAMERecord)2 Header (org.xbill.DNS.Header)2 DataOutputStream (java.io.DataOutputStream)1 IOException (java.io.IOException)1 InterruptedIOException (java.io.InterruptedIOException)1 URL (java.net.URL)1 X509Certificate (java.security.cert.X509Certificate)1 RSAKey (java.security.interfaces.RSAKey)1 Collection (java.util.Collection)1