mDNSlocal mStatus mDNS_RegisterProxyHost(mDNS *m, ProxyHost *p)
{
    char buffer[32];

    mDNS_SetupResourceRecord(&p->RR_A,   mDNSNULL, mDNSInterface_Any, kDNSType_A,   60, kDNSRecordTypeUnique,      AuthRecordAny, HostNameCallback, p);
    mDNS_SetupResourceRecord(&p->RR_PTR, mDNSNULL, mDNSInterface_Any, kDNSType_PTR, 60, kDNSRecordTypeKnownUnique, AuthRecordAny, HostNameCallback, p);

    p->RR_A.namestorage.c[0] = 0;
    AppendDomainLabel(&p->RR_A.namestorage, &p->hostlabel);
    AppendLiteralLabelString(&p->RR_A.namestorage, "local");

    // Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code
    mDNS_snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d.in-addr.arpa.", p->ip.b[3], p->ip.b[2], p->ip.b[1], p->ip.b[0]);
    MakeDomainNameFromDNSNameString(&p->RR_PTR.namestorage, buffer);
    p->RR_PTR.ForceMCast = mDNStrue; // This PTR points to our dot-local name, so don't ever try to write it into a uDNS server

    p->RR_A.resrec.rdata->u.ipv4 = p->ip;
    AssignDomainName(&p->RR_PTR.resrec.rdata->u.name, p->RR_A.resrec.name);

    mDNS_Register(m, &p->RR_A);
    mDNS_Register(m, &p->RR_PTR);

    debugf("Made Proxy Host Records for %##s", p->RR_A.resrec.name->c);

    return(mStatus_NoError);
}
mDNSlocal ResourceRecord *CopyNSEC3ResourceRecord(AnonymousInfo *si, const ResourceRecord *rr)
{
    int len;
    domainname *name;
    ResourceRecord *nsec3rr;

    if (rr->rdlength < MCAST_NSEC3_RDLENGTH)
    {
        LogMsg("CopyNSEC3ResourceRecord: rdlength %d smaller than MCAST_NSEC3_RDLENGTH %d", rr->rdlength, MCAST_NSEC3_RDLENGTH);
        return mDNSNULL;
    }
    // Allocate space for the name and the rdata along with the ResourceRecord
    len = DomainNameLength(rr->name);
    nsec3rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + len + sizeof(RData));
    if (!nsec3rr)
        return mDNSNULL;

    *nsec3rr = *rr;
    name = (domainname *)((mDNSu8 *)nsec3rr + sizeof(ResourceRecord));
    nsec3rr->name = (const domainname *)name;
    AssignDomainName(name, rr->name);

    nsec3rr->rdata = (RData *)((mDNSu8 *)nsec3rr->name + len);
    mDNSPlatformMemCopy(nsec3rr->rdata->u.data, rr->rdata->u.data, rr->rdlength);

    si->nsec3RR = nsec3rr;

    return nsec3rr;
}
mDNSlocal OSStatus mDNSResponderSetAvail(mDNS *m, AuthRecord *rr, ServiceRecordSet *sr)
	{
	// 1. Initialize required fields of AuthRecord
	// 2. Set name of subtype PTR record to our special subtype name denoting "available" instances
	// 3. Set target of subtype PTR record to point to our SRV record (exactly the same as the main service PTR record)
	// 4. And register it
	mDNS_SetupResourceRecord(rr, mDNSNULL, mDNSInterface_Any, kDNSType_PTR, 2*3600, kDNSRecordTypeShared, AvailCallback, &availRec2Active);
	MakeDomainNameFromDNSNameString(rr->resrec.name, "a._sub._raop._tcp.local.");
	AssignDomainName(&rr->resrec.rdata->u.name, sr->RR_SRV.resrec.name);
	return(mDNS_Register(m, rr));
	}
mDNSlocal ResourceRecord *ConstructNSEC3Record(const domainname *service, const mDNSu8 *AnonData, int len, mDNSu32 salt)
{
    ResourceRecord *rr;
    int dlen;
    domainname *name;

    // We are just allocating an RData which has StandardAuthRDSize
    if (StandardAuthRDSize < MCAST_NSEC3_RDLENGTH)
    {
        LogMsg("ConstructNSEC3Record: StandardAuthRDSize %d smaller than MCAST_NSEC3_RDLENGTH %d", StandardAuthRDSize, MCAST_NSEC3_RDLENGTH);
        return mDNSNULL;
    }

    dlen = DomainNameLength(service);
 
    // Allocate space for the name and RData. 
    rr = mDNSPlatformMemAllocate(sizeof(ResourceRecord) + dlen + sizeof(RData));
    if (!rr)
        return mDNSNULL;
    name = (domainname *)((mDNSu8 *)rr + sizeof(ResourceRecord));
    rr->RecordType        = kDNSRecordTypePacketAuth;
    rr->InterfaceID       = mDNSInterface_Any;
    rr->name              = (const domainname *)name;
    rr->rrtype            = kDNSType_NSEC3;
    rr->rrclass           = kDNSClass_IN;
    rr->rroriginalttl     = kStandardTTL;
    rr->rDNSServer        = mDNSNULL;
    rr->rdlength          = MCAST_NSEC3_RDLENGTH;
    rr->rdestimate        = MCAST_NSEC3_RDLENGTH;
    rr->rdata             = (RData *)((mDNSu8 *)rr->name + dlen);

    AssignDomainName(name, service);
    if (!InitializeNSEC3Record(rr, AnonData, len, salt))
    {
        mDNSPlatformMemFree(rr);
        return mDNSNULL;
    }
    return rr;
}
mDNSlocal void AddTrustAnchor(mDNS *const m, const domainname *zone, mDNSu16 keytag, mDNSu8 alg, mDNSu8 digestType, int diglen,
    mDNSu8 *digest)
{
    TrustAnchor *ta, *tmp;
    mDNSu32 t = (mDNSu32) time(NULL); 

    // Check for duplicates
    tmp = m->TrustAnchors;
    while (tmp)
    {
        if (SameDomainName(zone, &tmp->zone) && tmp->rds.keyTag == keytag && tmp->rds.alg == alg && tmp->rds.digestType == digestType &&
            !memcmp(tmp->rds.digest, digest, diglen))
        {
            LogMsg("AddTrustAnchors: Found a duplicate");
            return;
        }
        tmp = tmp->next;
    }

    ta = (TrustAnchor *)mDNSPlatformMemAllocate(sizeof(TrustAnchor));
    if (!ta)
    {
        LogMsg("AddTrustAnchor: malloc failure ta");
        return;
    }
    ta->rds.keyTag = keytag;
    ta->rds.alg = alg;
    ta->rds.digestType = digestType;
    ta->rds.digest = digest;
    ta->digestLen = diglen;
    ta->validFrom = t;
    ta->validUntil = t + TEST_TA_EXPIRE_INTERVAL;
    AssignDomainName(&ta->zone, zone);
    ta->next = mDNSNULL;

    LinkTrustAnchor(m, ta);
}
Exemple #6
0
mDNSlocal void StartInsecureProof(mDNS * const m, DNSSECVerifier *dv)
{
    domainname trigger;
    DNSSECVerifier *prevdv = mDNSNULL;

    // Remember the name that triggered the insecure proof
    AssignDomainName(&trigger, &dv->q.qname);
    while (dv->parent)
    {
        prevdv = dv;
        dv = dv->parent;
    }
    if (prevdv)
    {
        prevdv->parent = mDNSNULL;
        FreeDNSSECVerifier(m, prevdv);
    }
    // For Optional DNSSEC, we are opportunistically verifying dnssec. We don't care
    // if something results in bogus as we still want to deliver results to the
    // application e.g., CNAME processing results in bogus because the path is broken,
    // but we still want to follow CNAMEs so that we can deliver the final results to
    // the application.
    if (dv->ValidationRequired == DNSSEC_VALIDATION_SECURE_OPTIONAL)
    {
        LogDNSSEC("StartInsecureProof: Aborting insecure proof for %##s (%s)", dv->q.qname.c, DNSTypeName(dv->q.qtype));
        dv->DVCallback(m, dv, DNSSEC_Bogus);
        return;
    }

    LogDNSSEC("StartInsecureProof for %##s (%s)", dv->q.qname.c, DNSTypeName(dv->q.qtype));
    // Don't start the insecure proof again after we finish the one that we start here by
    // setting InsecureProofDone.
    dv->InsecureProofDone = 1;
    ProveInsecure(m, dv, mDNSNULL, &trigger);
    return;
}
Exemple #7
0
DNSServiceErrorType DNSServiceResolve
	(
	DNSServiceRef                       *sdRef,
	DNSServiceFlags                     flags,
	uint32_t                            interfaceIndex,
	const char                          *name,
	const char                          *regtype,
	const char                          *domain,
	DNSServiceResolveReply              callback,
	void                                *context  /* may be NULL */
	)
	{
	mStatus err = mStatus_NoError;
	const char *errormsg = "Unknown";
	domainlabel n;
	domainname t, d, srv;
	mDNS_DirectOP_Resolve *x;

	(void)flags;			// Unused
	(void)interfaceIndex;	// Unused

	// Check parameters
	if (!name[0]    || !MakeDomainLabelFromLiteralString(&n, name  )) { errormsg = "Bad Instance Name"; goto badparam; }
	if (!regtype[0] || !MakeDomainNameFromDNSNameString(&t, regtype)) { errormsg = "Bad Service Type";  goto badparam; }
	if (!domain[0]  || !MakeDomainNameFromDNSNameString(&d, domain )) { errormsg = "Bad Domain";        goto badparam; }
	if (!ConstructServiceName(&srv, &n, &t, &d))                      { errormsg = "Bad Name";          goto badparam; }

	// Allocate memory, and handle failure
	x = (mDNS_DirectOP_Resolve *)mDNSPlatformMemAllocate(sizeof(*x));
	if (!x) { err = mStatus_NoMemoryErr; errormsg = "No memory"; goto fail; }

	// Set up object
	x->disposefn = DNSServiceResolveDispose;
	x->callback  = callback;
	x->context   = context;
	x->SRV       = mDNSNULL;
	x->TXT       = mDNSNULL;

	x->qSRV.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
	x->qSRV.InterfaceID         = mDNSInterface_Any;
	x->qSRV.Target              = zeroAddr;
	AssignDomainName(&x->qSRV.qname, &srv);
	x->qSRV.qtype               = kDNSType_SRV;
	x->qSRV.qclass              = kDNSClass_IN;
	x->qSRV.LongLived           = mDNSfalse;
	x->qSRV.ExpectUnique        = mDNStrue;
	x->qSRV.ForceMCast          = mDNSfalse;
	x->qSRV.QuestionCallback    = FoundServiceInfo;
	x->qSRV.QuestionContext     = x;

	x->qTXT.ThisQInterval       = -1;		// So that DNSServiceResolveDispose() knows whether to cancel this question
	x->qTXT.InterfaceID         = mDNSInterface_Any;
	x->qTXT.Target              = zeroAddr;
	AssignDomainName(&x->qTXT.qname, &srv);
	x->qTXT.qtype               = kDNSType_TXT;
	x->qTXT.qclass              = kDNSClass_IN;
	x->qTXT.LongLived           = mDNSfalse;
	x->qTXT.ExpectUnique        = mDNStrue;
	x->qTXT.ForceMCast          = mDNSfalse;
	x->qTXT.QuestionCallback    = FoundServiceInfo;
	x->qTXT.QuestionContext     = x;

	err = mDNS_StartQuery(&mDNSStorage, &x->qSRV);
	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qSRV"; goto fail; }
	err = mDNS_StartQuery(&mDNSStorage, &x->qTXT);
	if (err) { DNSServiceResolveDispose((mDNS_DirectOP*)x); errormsg = "mDNS_StartQuery qTXT"; goto fail; }

	// Succeeded: Wrap up and return
	*sdRef = (DNSServiceRef)x;
	return(mStatus_NoError);

badparam:
	err = mStatus_BadParamErr;
fail:
	LogMsg("DNSServiceResolve(\"%s\", \"%s\", \"%s\") failed: %s (%ld)", name, regtype, domain, errormsg, err);
	return(err);
	}