예제 #1
0
mDNSexport void NSEC3NameErrorProof(mDNS *const m, DNSSECVerifier *dv, CacheRecord *ncr)
{
    CacheRecord *closerEncloser;
    CacheRecord *closestEncloser;
    CacheRecord *wildcard;
    const domainname *ce = mDNSNULL;
    domainname wild;

    if (!NSEC3ClosestEncloserProof(m, ncr, &dv->q.qname, &closestEncloser, &closerEncloser, &ce, dv->q.qtype))
    {
        goto error;
    }
    LogDNSSEC("NSEC3NameErrorProof: ClosestEncloser %s, ce %##s", CRDisplayString(m, closestEncloser), ce->c);
    LogDNSSEC("NSEC3NameErrorProof: CloserEncloser %s", CRDisplayString(m, closerEncloser));

    // *.closestEncloser should be covered by some nsec3 which would then prove
    // that the wildcard does not exist
    wild.c[0] = 1;
    wild.c[1] = '*';
    wild.c[2] = 0;
    if (!AppendDomainName(&wild, ce))
    {
        LogMsg("NSEC3NameErrorProof: Can't append domainname to closest encloser name %##s", ce->c);
        goto error;
    }
    if (!NSEC3Find(m, NSEC3Covers, ncr, &wild, mDNSNULL, &wildcard, mDNSNULL, dv->q.qtype))
    {
        LogMsg("NSEC3NameErrorProof: Cannot find encloser for wildcard");
        goto error;
    }
    else
    {
        LogDNSSEC("NSEC3NameErrorProof: Wildcard %##s covered by %s", wild.c, CRDisplayString(m, wildcard));
        if (wildcard == closestEncloser)
        {
            LogDNSSEC("NSEC3NameErrorProof: ClosestEncloser matching Wildcard %s", CRDisplayString(m, wildcard));
        }
    }
    if (NSEC3OptOut(closerEncloser))
    {
        dv->flags |= NSEC3_OPT_OUT;
    }
    if (!VerifyNSEC3(m, dv, ncr, closestEncloser, closerEncloser, wildcard, NameErrorNSECCallback))
        goto error;
    else
        return;

error:
    dv->DVCallback(m, dv, DNSSEC_Bogus);
}
예제 #2
0
mDNSlocal mDNSBool NSECNoWildcard(mDNS *const m, ResourceRecord *rr, domainname *qname, mDNSu16 qtype)
{
    const domainname *ce;
    domainname wild;

    // If the query name is c.x.w.example and if the name does not exist, we should get
    // get a nsec back that looks something like this:
    //
    //      w.example NSEC a.w.example
    //
    // First, we need to get the closest encloser which in this case is w.example. Wild
    // card synthesis works by finding the closest encloser first and then look for
    // a "*" label (assuming * label does not appear in the question). If it does not
    // exists, it would return the NSEC at that name. And the wildcard name at the
    // closest encloser "*.w.example" would be covered by such an NSEC. (Appending "*"
    // makes it bigger than w.example and "* is smaller than "a" for the above NSEC)
    //
    ce = NSECClosestEncloser(rr, qname);
    if (!ce) { LogMsg("NSECNoWildcard: No closest encloser for rr %s, qname %##s (%s)", qname->c, DNSTypeName(qtype)); return mDNSfalse; }

    wild.c[0] = 1;
    wild.c[1] = '*';
    wild.c[2] = 0;
    if (!AppendDomainName(&wild, ce))
    {
        LogMsg("NSECNoWildcard: ERROR!! Can't append domainname closest encloser name %##s, qname %##s (%s)", ce->c, qname->c, DNSTypeName(qtype));
        return mDNSfalse;
    }
    if (NSECNameExists(m, rr, &wild, qtype) != 0)
    {
        LogDNSSEC("NSECNoWildcard: Wildcard name %##s exists or not valid qname %##s (%s)", wild.c, qname->c, DNSTypeName(qtype));
        return mDNSfalse;
    }
    LogDNSSEC("NSECNoWildcard: Wildcard name %##s does not exist for record %s, qname %##s (%s)", wild.c,
              RRDisplayString(m, rr), qname->c, DNSTypeName(qtype));
    return mDNStrue;
}
예제 #3
0
mDNSexport void NSEC3NoDataProof(mDNS *const m, DNSSECVerifier *dv, CacheRecord *ncr)
{
    CacheRecord *closerEncloser = mDNSNULL;
    CacheRecord *closestEncloser = mDNSNULL;
    CacheRecord *wildcard = mDNSNULL;
    const domainname *ce = mDNSNULL;
    domainname wild;

    // Section 8.5, 8.6 of RFC 5155
    if (NSEC3NoDataError(m, ncr, &dv->q.qname, dv->q.qtype, &closestEncloser))
    {
        goto verify;
    }
    // Section 8.6, 8.7: if we can't find the NSEC3 RR, verify the closest encloser proof
    // for QNAME and the "next closer" should have the opt out
    if (!NSEC3ClosestEncloserProof(m, ncr, &dv->q.qname, &closestEncloser, &closerEncloser, &ce, dv->q.qtype))
    {
        goto error;
    }

    // Section 8.7: find a matching NSEC3 for *.closestEncloser
    wild.c[0] = 1;
    wild.c[1] = '*';
    wild.c[2] = 0;
    if (!AppendDomainName(&wild, ce))
    {
        LogMsg("NSEC3NameErrorProof: Can't append domainname to closest encloser name %##s", ce->c);
        goto error;
    }
    if (!NSEC3Find(m, NSEC3ClosestEncloser, ncr, &wild, &wildcard, mDNSNULL, &ce, dv->q.qtype))
    {
        // Not a wild card case. Section 8.6 second para applies.
        LogDNSSEC("NSEC3NoDataProof: Cannot find encloser for wildcard, perhaps not a wildcard case");
        if (!NSEC3OptOut(closerEncloser))
        {
            LogDNSSEC("NSEC3DataProof: opt out not set for %##s (%s), bogus", dv->q.qname.c, DNSTypeName(dv->q.qtype));
            goto error;
        }
        LogDNSSEC("NSEC3DataProof: opt out set, proof complete for %##s (%s)", dv->q.qname.c, DNSTypeName(dv->q.qtype));
        dv->flags |= NSEC3_OPT_OUT;
    }
    else
    {
        int bmaplen;
        mDNSu8 *bmap;
        NSEC3Parse(&wildcard->resrec, mDNSNULL, mDNSNULL, mDNSNULL, &bmaplen, &bmap);
        if (BitmapTypeCheck(bmap, bmaplen, dv->q.qtype) || BitmapTypeCheck(bmap, bmaplen, kDNSType_CNAME))
        {
            LogDNSSEC("NSEC3NoDataProof: qtype %s exists in %s", DNSTypeName(dv->q.qtype), CRDisplayString(m, wildcard));
            goto error;
        }
        if (dv->q.qtype == kDNSType_DS && BitmapTypeCheck(bmap, bmaplen, kDNSType_SOA))
        {
            LogDNSSEC("NSEC3NoDataProof: Child side wildcard NSEC3 %s, can't use for parent qname %##s (%s)",
                CRDisplayString(m, wildcard), dv->q.qname.c, DNSTypeName(dv->q.qtype));
            goto error;
        }
        else if (dv->q.qtype != kDNSType_DS && !BitmapTypeCheck(bmap, bmaplen, kDNSType_SOA) &&
            BitmapTypeCheck(bmap, bmaplen, kDNSType_NS))
        {
            // Don't use the parent side record for this
            LogDNSSEC("NSEC3NoDataProof: Parent side wildcard NSEC3 %s, can't use for child qname %##s (%s)",
                CRDisplayString(m, wildcard), dv->q.qname.c, DNSTypeName(dv->q.qtype));
            goto error;
        }
        LogDNSSEC("NSEC3NoDataProof: Wildcard %##s matched by %s", wild.c, CRDisplayString(m, wildcard));
    }
verify:

    if (!VerifyNSEC3(m, dv, ncr, closestEncloser, closerEncloser, wildcard, NoDataNSECCallback))
        goto error;
    else
        return;
error:
    dv->DVCallback(m, dv, DNSSEC_Bogus);
}