示例#1
0
文件: tsig.c 项目: execunix/vinos
isc_result_t
dns_tsigkey_find(dns_tsigkey_t **tsigkey, dns_name_t *name,
		 dns_name_t *algorithm, dns_tsig_keyring_t *ring)
{
	dns_tsigkey_t *key;
	isc_stdtime_t now;
	isc_result_t result;

	REQUIRE(tsigkey != NULL);
	REQUIRE(*tsigkey == NULL);
	REQUIRE(name != NULL);
	REQUIRE(ring != NULL);

	RWLOCK(&ring->lock, isc_rwlocktype_write);
	cleanup_ring(ring);
	RWUNLOCK(&ring->lock, isc_rwlocktype_write);

	isc_stdtime_get(&now);
	RWLOCK(&ring->lock, isc_rwlocktype_read);
	key = NULL;
	result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key);
	if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) {
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		return (ISC_R_NOTFOUND);
	}
	if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) {
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		return (ISC_R_NOTFOUND);
	}
	if (key->inception != key->expire && isc_serial_lt(key->expire, now)) {
		/*
		 * The key has expired.
		 */
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		RWLOCK(&ring->lock, isc_rwlocktype_write);
		remove_fromring(key);
		RWUNLOCK(&ring->lock, isc_rwlocktype_write);
		return (ISC_R_NOTFOUND);
	}
#if 0
	/*
	 * MPAXXX We really should look at the inception time.
	 */
	if (key->inception != key->expire &&
	    isc_serial_lt(key->inception, now)) {
		RWUNLOCK(&ring->lock, isc_rwlocktype_read);
		adjust_lru(key);
		return (ISC_R_NOTFOUND);
	}
#endif
	isc_refcount_increment(&key->refs, NULL);
	RWUNLOCK(&ring->lock, isc_rwlocktype_read);
	adjust_lru(key);
	*tsigkey = key;
	return (ISC_R_SUCCESS);
}
示例#2
0
文件: serial_test.c 项目: 274914765/C
int main ()
{
    isc_uint32_t a, b;

    char buf[1024];

    char *s, *e;

    while (fgets (buf, sizeof (buf), stdin) != NULL)
    {
        buf[sizeof (buf) - 1] = '\0';
        s = buf;
        a = strtoul (s, &e, 0);
        if (s == e)
            continue;
        s = e;
        b = strtoul (s, &e, 0);
        if (s == e)
            continue;
        fprintf (stdout, "%u %u gt:%d lt:%d ge:%d le:%d eq:%d ne:%d\n",
                 a, b,
                 isc_serial_gt (a, b), isc_serial_lt (a, b),
                 isc_serial_ge (a, b), isc_serial_le (a, b), isc_serial_eq (a, b), isc_serial_ne (a, b));
    }
    return (0);
}
示例#3
0
文件: tsig.c 项目: execunix/vinos
static isc_result_t
restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) {
	dst_key_t *dstkey = NULL;
	char namestr[1024];
	char creatorstr[1024];
	char algorithmstr[1024];
	char keystr[4096];
	unsigned int inception, expire;
	int n;
	isc_buffer_t b;
	dns_name_t *name, *creator, *algorithm;
	dns_fixedname_t fname, fcreator, falgorithm;
	isc_result_t result;
	unsigned int dstalg;

	n = fscanf(fp, "%1023s %1023s %u %u %1023s %4095s\n", namestr,
		   creatorstr, &inception, &expire, algorithmstr, keystr);
	if (n == EOF)
		return (ISC_R_NOMORE);
	if (n != 6)
		return (ISC_R_FAILURE);

	if (isc_serial_lt(expire, now))
		return (DNS_R_EXPIRED);

	dns_fixedname_init(&fname);
	name = dns_fixedname_name(&fname);
	isc_buffer_init(&b, namestr, strlen(namestr));
	isc_buffer_add(&b, strlen(namestr));
	result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS)
		return (result);

	dns_fixedname_init(&fcreator);
	creator = dns_fixedname_name(&fcreator);
	isc_buffer_init(&b, creatorstr, strlen(creatorstr));
	isc_buffer_add(&b, strlen(creatorstr));
	result = dns_name_fromtext(creator, &b, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS)
		return (result);

	dns_fixedname_init(&falgorithm);
	algorithm = dns_fixedname_name(&falgorithm);
	isc_buffer_init(&b, algorithmstr, strlen(algorithmstr));
	isc_buffer_add(&b, strlen(algorithmstr));
	result = dns_name_fromtext(algorithm, &b, dns_rootname, 0, NULL);
	if (result != ISC_R_SUCCESS)
		return (result);

	dstalg = dst_alg_fromname(algorithm);
	if (dstalg == 0)
		return (DNS_R_BADALG);

	result = dst_key_restore(name, dstalg, DNS_KEYOWNER_ENTITY,
				 DNS_KEYPROTO_DNSSEC, dns_rdataclass_in,
				 ring->mctx, keystr, &dstkey);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = dns_tsigkey_createfromkey(name, algorithm, dstkey,
					   ISC_TRUE, creator, inception,
					   expire, ring->mctx, ring, NULL);
	if (dstkey != NULL)
		dst_key_free(&dstkey);
	return (result);
}
示例#4
0
文件: dnssec.c 项目: OPSF/uClinux
isc_result_t
dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
			 dst_key_t *key)
{
	dns_rdata_sig_t sig;	/* SIG(0) */
	unsigned char header[DNS_MESSAGE_HEADERLEN];
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_region_t r, source_r, sig_r, header_r;
	isc_stdtime_t now;
	dst_context_t *ctx = NULL;
	isc_mem_t *mctx;
	isc_result_t result;
	isc_uint16_t addcount;
	isc_boolean_t signeedsfree = ISC_FALSE;

	REQUIRE(source != NULL);
	REQUIRE(msg != NULL);
	REQUIRE(key != NULL);

	mctx = msg->mctx;

	msg->verify_attempted = 1;

	if (is_response(msg)) {
		if (msg->query.base == NULL)
			return (DNS_R_UNEXPECTEDTSIG);
	}

	isc_buffer_usedregion(source, &source_r);

	RETERR(dns_rdataset_first(msg->sig0));
	dns_rdataset_current(msg->sig0, &rdata);

	RETERR(dns_rdata_tostruct(&rdata, &sig, NULL));
	signeedsfree = ISC_TRUE;

	if (sig.labels != 0) {
		result = DNS_R_SIGINVALID;
		goto failure;
	}

	if (isc_serial_lt(sig.timeexpire, sig.timesigned)) {
		result = DNS_R_SIGINVALID;
		msg->sig0status = dns_tsigerror_badtime;
		goto failure;
	}

	isc_stdtime_get(&now);
	if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) {
		result = DNS_R_SIGFUTURE;
		msg->sig0status = dns_tsigerror_badtime;
		goto failure;
	}
	else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) {
		result = DNS_R_SIGEXPIRED;
		msg->sig0status = dns_tsigerror_badtime;
		goto failure;
	}

	if (!dns_name_equal(dst_key_name(key), &sig.signer)) {
		result = DNS_R_SIGINVALID;
		msg->sig0status = dns_tsigerror_badkey;
		goto failure;
	}

	RETERR(dst_context_create(key, mctx, &ctx));

	/*
 	 * Digest the SIG(0) record, except for the signature.
	 */
	dns_rdata_toregion(&rdata, &r);
	r.length -= sig.siglen;
	RETERR(dst_context_adddata(ctx, &r));

	/*
	 * If this is a response, digest the query.
	 */
	if (is_response(msg))
		RETERR(dst_context_adddata(ctx, &msg->query));

	/*
	 * Extract the header.
	 */
	memcpy(header, source_r.base, DNS_MESSAGE_HEADERLEN);

	/*
	 * Decrement the additional field counter.
	 */
	memcpy(&addcount, &header[DNS_MESSAGE_HEADERLEN - 2], 2);
	addcount = htons((isc_uint16_t)(ntohs(addcount) - 1));
	memcpy(&header[DNS_MESSAGE_HEADERLEN - 2], &addcount, 2);

	/*
	 * Digest the modified header.
	 */
	header_r.base = (unsigned char *) header;
	header_r.length = DNS_MESSAGE_HEADERLEN;
	RETERR(dst_context_adddata(ctx, &header_r));

	/*
	 * Digest all non-SIG(0) records.
	 */
	r.base = source_r.base + DNS_MESSAGE_HEADERLEN;
	r.length = msg->sigstart - DNS_MESSAGE_HEADERLEN;
	RETERR(dst_context_adddata(ctx, &r));

	sig_r.base = sig.signature;
	sig_r.length = sig.siglen;
	result = dst_context_verify(ctx, &sig_r);
	if (result != ISC_R_SUCCESS) {
		msg->sig0status = dns_tsigerror_badsig;
		goto failure;
	}

	msg->verified_sig = 1;

	dst_context_destroy(&ctx);
	dns_rdata_freestruct(&sig);

	return (ISC_R_SUCCESS);

failure:
	if (signeedsfree)
		dns_rdata_freestruct(&sig);
	if (ctx != NULL)
		dst_context_destroy(&ctx);

	return (result);
}
示例#5
0
文件: dnssec.c 项目: OPSF/uClinux
isc_result_t
dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
		   isc_boolean_t ignoretime, isc_mem_t *mctx,
		   dns_rdata_t *sigrdata, dns_name_t *wild)
{
	dns_rdata_rrsig_t sig;
	dns_fixedname_t fnewname;
	isc_region_t r;
	isc_buffer_t envbuf;
	dns_rdata_t *rdatas;
	int nrdatas, i;
	isc_stdtime_t now;
	isc_result_t ret;
	unsigned char data[300];
	dst_context_t *ctx = NULL;
	int labels = 0;
	isc_uint32_t flags;

	REQUIRE(name != NULL);
	REQUIRE(set != NULL);
	REQUIRE(key != NULL);
	REQUIRE(mctx != NULL);
	REQUIRE(sigrdata != NULL && sigrdata->type == dns_rdatatype_rrsig);

	ret = dns_rdata_tostruct(sigrdata, &sig, NULL);
	if (ret != ISC_R_SUCCESS)
		return (ret);

	if (isc_serial_lt(sig.timeexpire, sig.timesigned))
		return (DNS_R_SIGINVALID);

	if (!ignoretime) {
		isc_stdtime_get(&now);

		/*
		 * Is SIG temporally valid?
		 */
		if (isc_serial_lt((isc_uint32_t)now, sig.timesigned))
			return (DNS_R_SIGFUTURE);
		else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now))
			return (DNS_R_SIGEXPIRED);
	}

	/*
	 * Is the key allowed to sign data?
	 */
	flags = dst_key_flags(key);
	if (flags & DNS_KEYTYPE_NOAUTH)
		return (DNS_R_KEYUNAUTHORIZED);
	if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE)
		return (DNS_R_KEYUNAUTHORIZED);

	ret = dst_context_create(key, mctx, &ctx);
	if (ret != ISC_R_SUCCESS)
		goto cleanup_struct;

	/*
	 * Digest the SIG rdata (not including the signature).
	 */
	ret = digest_sig(ctx, sigrdata, &sig);
	if (ret != ISC_R_SUCCESS)
		goto cleanup_context;

	/*
	 * If the name is an expanded wildcard, use the wildcard name.
	 */
	dns_fixedname_init(&fnewname);
	labels = dns_name_countlabels(name) - 1;
	RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname),
				        NULL) == ISC_R_SUCCESS);
	if (labels - sig.labels > 0)
		dns_name_split(dns_fixedname_name(&fnewname), sig.labels + 1,
			       NULL, dns_fixedname_name(&fnewname));

	dns_name_toregion(dns_fixedname_name(&fnewname), &r);

	/*
	 * Create an envelope for each rdata: <name|type|class|ttl>.
	 */
	isc_buffer_init(&envbuf, data, sizeof(data));
	if (labels - sig.labels > 0) {
		isc_buffer_putuint8(&envbuf, 1);
		isc_buffer_putuint8(&envbuf, '*');
		memcpy(data + 2, r.base, r.length);
	}
	else
		memcpy(data, r.base, r.length);
	isc_buffer_add(&envbuf, r.length);
	isc_buffer_putuint16(&envbuf, set->type);
	isc_buffer_putuint16(&envbuf, set->rdclass);
	isc_buffer_putuint32(&envbuf, sig.originalttl);

	ret = rdataset_to_sortedarray(set, mctx, &rdatas, &nrdatas);
	if (ret != ISC_R_SUCCESS)
		goto cleanup_context;

	isc_buffer_usedregion(&envbuf, &r);

	for (i = 0; i < nrdatas; i++) {
		isc_uint16_t len;
		isc_buffer_t lenbuf;
		isc_region_t lenr;

		/*
		 * Skip duplicates.
		 */
		if (i > 0 && dns_rdata_compare(&rdatas[i], &rdatas[i-1]) == 0)
		    continue;

		/*
		 * Digest the envelope.
		 */
		ret = dst_context_adddata(ctx, &r);
		if (ret != ISC_R_SUCCESS)
			goto cleanup_array;

		/*
		 * Digest the rdata length.
		 */
		isc_buffer_init(&lenbuf, &len, sizeof(len));
		INSIST(rdatas[i].length < 65536);
		isc_buffer_putuint16(&lenbuf, (isc_uint16_t)rdatas[i].length);
		isc_buffer_usedregion(&lenbuf, &lenr);

		/*
		 * Digest the rdata.
		 */
		ret = dst_context_adddata(ctx, &lenr);
		if (ret != ISC_R_SUCCESS)
			goto cleanup_array;
		ret = dns_rdata_digest(&rdatas[i], digest_callback, ctx);
		if (ret != ISC_R_SUCCESS)
			goto cleanup_array;
	}

	r.base = sig.signature;
	r.length = sig.siglen;
	ret = dst_context_verify(ctx, &r);
	if (ret == DST_R_VERIFYFAILURE)
		ret = DNS_R_SIGINVALID;

cleanup_array:
	isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t));
cleanup_context:
	dst_context_destroy(&ctx);
cleanup_struct:
	dns_rdata_freestruct(&sig);

	if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) {
		if (wild != NULL) 
			RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname,
					         dns_fixedname_name(&fnewname),
						 wild, NULL) == ISC_R_SUCCESS);
		ret = DNS_R_FROMWILDCARD;
	}
	return (ret);
}
示例#6
0
isc_boolean_t
isc_serial_le(isc_uint32_t a, isc_uint32_t b) {
	return ((a == b) ? ISC_TRUE : isc_serial_lt(a, b));
}