Exemplo n.º 1
0
ATF_TC_BODY(symbol_lookup, tc)
{
	GElf_Sym main_sym, r_debug_state_sym;
	struct proc_handle *phdl;
	proc_breakpoint_t saved;
	int error;

	phdl = start_prog(tc, false);

	error = proc_name2sym(phdl, target_prog_file, "main", &main_sym, NULL);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main'");

	error = proc_name2sym(phdl, ldelf_object, r_debug_state,
	    &r_debug_state_sym, NULL);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up '%s'", r_debug_state);

	set_bkpt(phdl, (uintptr_t)r_debug_state_sym.st_value, &saved);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
	verify_bkpt(phdl, &r_debug_state_sym, r_debug_state, ldelf_object);
	remove_bkpt(phdl, (uintptr_t)r_debug_state_sym.st_value, &saved);

	set_bkpt(phdl, (uintptr_t)main_sym.st_value, &saved);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
	verify_bkpt(phdl, &main_sym, "main", target_prog_file);
	remove_bkpt(phdl, (uintptr_t)main_sym.st_value, &saved);

	ATF_CHECK_EQ_MSG(proc_detach(phdl, PRELEASE_HANG), 0, "failed to detach");

	proc_free(phdl);
}
Exemplo n.º 2
0
ATF_TC_BODY(symbol_lookup, tc)
{
	GElf_Sym main_sym, r_debug_state_sym;
	struct proc_handle *phdl;
	u_long saved;
	int error;

	phdl = start_prog(tc, false);

	error = proc_name2sym(phdl, target_prog_file, "main", &main_sym, NULL);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main'");

	error = proc_name2sym(phdl, ldelf_object, "r_debug_state",
	    &r_debug_state_sym, NULL);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'r_debug_state'");

	set_bkpt(phdl, r_debug_state_sym.st_value, &saved);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
	verify_bkpt(phdl, &r_debug_state_sym, "r_debug_state", ldelf_object);
	remove_bkpt(phdl, r_debug_state_sym.st_value, saved);

	set_bkpt(phdl, main_sym.st_value, &saved);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
	verify_bkpt(phdl, &main_sym, "main", target_prog_file);
	remove_bkpt(phdl, main_sym.st_value, saved);

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Exemplo n.º 3
0
static void*
test_pipe_reader(void* args)
{
	test_pipe_thread_data_t* td = args;
	char rcvbuf[td->pktsize];
	char comparebuf[td->pktsize];
	ssize_t rsize;
	int i, d;

	for(i=0; i < td->numpkts; i++) {
		memset(comparebuf, i, td->pktsize);
		rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL);
		if (rsize < 0) {
			perror("recv");
			atf_tc_fail("recv returned < 0");
		}
		ATF_CHECK_EQ_MSG(td->pktsize, rsize,
		    		 "expected %zd=send(...) but got %zd",
				 td->pktsize, rsize);
		d = memcmp(comparebuf, rcvbuf, td->pktsize);
		ATF_CHECK_EQ_MSG(0, d, 
		    		 "Received data miscompare on packet %d", i);
	}
	return (0);
}
Exemplo n.º 4
0
ATF_TC_BODY(signal_forward, tc)
{
	struct proc_handle *phdl;
	int state, status;

	phdl = start_prog(tc, true);
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	/* The process should have been interrupted by a signal. */
	state = proc_wstatus(phdl);
	ATF_REQUIRE_EQ_MSG(state, PS_STOP, "process has unexpected state %d",
	    state);

	/* Continue execution and allow the signal to be delivered. */
	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	/*
	 * Make sure the process exited with status 0. If it didn't receive the
	 * SIGUSR1 that it sent to itself, it'll exit with a non-zero exit
	 * status, causing the test to fail.
	 */
	state = proc_wstatus(phdl);
	ATF_REQUIRE_EQ_MSG(state, PS_UNDEAD, "process has unexpected state %d",
	    state);

	status = proc_getwstat(phdl);
	ATF_REQUIRE(status >= 0);
	ATF_REQUIRE(WIFEXITED(status));
	ATF_REQUIRE_EQ(WEXITSTATUS(status), 0);

	proc_free(phdl);
}
Exemplo n.º 5
0
ATF_TC_BODY(rcvbuf_oversized, tc)
{
	int i;
	int sv[2];
	const ssize_t pktsize = 1024;
	const size_t sndbufsize = 8192;
	const size_t rcvbufsize = 131072;
	const size_t geometric_mean_bufsize = 32768;
	const int numpkts = geometric_mean_bufsize / pktsize;
	char sndbuf[pktsize];
	char recv_buf[pktsize];
	ssize_t ssize, rsize;

	/* setup the socket pair */
	do_socketpair_nonblocking(sv);
	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
	    sizeof(sndbufsize)));
	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
	    sizeof(rcvbufsize)));

	/* 
	 * Send and receive packets that are collectively greater than the send
	 * buffer, but less than the receive buffer
	 */
	for (i=0; i < numpkts; i++) {
		/* Fill the buffer */
		memset(sndbuf, i, pktsize);

		/* send the packet */
		ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
		if (ssize < 0) {
			perror("send");
			atf_tc_fail("send returned < 0");
		}
		ATF_CHECK_EQ_MSG(pktsize, ssize,
		    "expected %zd=send(...) but got %zd", pktsize, ssize);

		/* Receive it */

		rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
		if (rsize < 0) {
			perror("recv");
			atf_tc_fail("recv returned < 0");
		}
		ATF_CHECK_EQ_MSG(pktsize, rsize,
		    "expected %zd=send(...) but got %zd", pktsize, rsize);

		/* Verify the contents */
		ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), 
		    "Received data miscompare");
	}

	/* Trying to receive again should return EAGAIN */
	rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
	ATF_CHECK_EQ(EAGAIN, errno);
	ATF_CHECK_EQ(-1, rsize);
}
Exemplo n.º 6
0
ATF_TC_BODY(cast_ulong2, tc)
{
	double dv = 1.9;
	long double ldv = dv;
	unsigned long l1 = dv;
	unsigned long l2 = ldv;

	ATF_CHECK_EQ_MSG(l1, 1,
	    "double 1.9 casted to unsigned long should be 1, but is %lu", l1);

	ATF_CHECK_EQ_MSG(l2, 1,
	    "long double 1.9 casted to unsigned long should be 1, but is %lu",
	    l2);
}
Exemplo n.º 7
0
ATF_TC_BODY(map_alias_name2sym, tc)
{
	GElf_Sym sym1, sym2;
	prsyminfo_t si1, si2;
	struct proc_handle *phdl;
	int error;

	phdl = start_prog(tc, false);

	/* Initialize the rtld_db handle. */
	(void)proc_rdagent(phdl);

	/*
	 * Make sure that "target_prog:main" and "a.out:main" return the same
	 * symbol.
	 */
	error = proc_name2sym(phdl, target_prog_file, "main", &sym1, &si1);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main' via %s",
	    target_prog_file);
	error = proc_name2sym(phdl, aout_object, "main", &sym2, &si2);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up 'main' via %s",
	    aout_object);

	ATF_CHECK_EQ(memcmp(&sym1, &sym2, sizeof(sym1)), 0);
	ATF_CHECK_EQ(si1.prs_id, si2.prs_id);

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Exemplo n.º 8
0
ATF_TC_BODY(send_recv_nonblocking, tc)
{
	int s;
	int sv[2];
	const int bufsize = 64;
	const char *data = "data";
	char recv_buf[bufsize];
	size_t datalen;
	ssize_t ssize, rsize;

	/* setup the socket pair */
	do_socketpair_nonblocking(sv);

	/* Verify that there is nothing to receive */
	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
	ATF_CHECK_EQ(EAGAIN, errno);
	ATF_CHECK_EQ(-1, rsize);

	/* send and receive a small packet */
	datalen = strlen(data) + 1;	/* +1 for the null */
	ssize = send(sv[0], data, datalen, MSG_EOR);
	if (ssize < 0) {
		perror("send");
		atf_tc_fail("send returned < 0");
	}
	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
	    datalen, ssize);

	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
	ATF_CHECK_EQ(datalen, rsize);
}
Exemplo n.º 9
0
ATF_TC_BODY(send_recv_with_connect, tc)
{
	const char* path;
	int sv[2];
	const int bufsize = 64;
	const char *data = "data";
	char recv_buf[bufsize];
	size_t datalen;
	ssize_t ssize, rsize;

	mk_pair_of_sockets(sv);

	/* send and receive a small packet */
	datalen = strlen(data) + 1;	/* +1 for the null */
	ssize = send(sv[0], data, datalen, MSG_EOR);
	if (ssize < 0) {
		perror("send");
		atf_tc_fail("send returned < 0");
	}
	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
	    datalen, ssize);

	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
	ATF_CHECK_EQ(datalen, rsize);
}
Exemplo n.º 10
0
ATF_TC_BODY(symbol_lookup_fail, tc)
{
	char symname[32];
	GElf_Sym sym;
	struct proc_handle *phdl;
	prmap_t *map;
	int error;

	phdl = start_prog(tc, false);

	/* Initialize the rtld_db handle. */
	(void)proc_rdagent(phdl);

	map = proc_name2map(phdl, target_prog_file);
	ATF_REQUIRE_MSG(map != NULL, "failed to look up map for '%s'",
	    target_prog_file);

	/*
	 * We shouldn't be able to find symbols at the beginning of a mapped
	 * file.
	 */
	error = proc_addr2sym(phdl, map->pr_vaddr, symname, sizeof(symname),
	    &sym);
	ATF_REQUIRE_MSG(error != 0, "unexpectedly found a symbol");

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Exemplo n.º 11
0
ATF_TC_BODY(cast_ulong, tc)
{
	double nv;
	unsigned long uv;

	nv = 5.6;
	uv = (unsigned long)nv;

	ATF_CHECK_EQ_MSG(uv, 5,
	    "%.3f casted to unsigned long is %lu", nv, uv);
}
Exemplo n.º 12
0
void
test_sendrecv_symmetric_buffers(size_t bufsize, int blocking) {
	int s;
	int sv[2];
	const size_t pktsize = bufsize / 2;
	char sndbuf[pktsize];
	char recv_buf[pktsize];
	ssize_t ssize, rsize;

	/* setup the socket pair */
	if (blocking)
		do_socketpair(sv);
	else
		do_socketpair_nonblocking(sv);

	/* Setup the buffers */
	s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
	ATF_REQUIRE_EQ(0, s);
	s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize));
	ATF_REQUIRE_EQ(0, s);

	/* Fill the send buffer */
	bzero(sndbuf, pktsize);

	/* send and receive the packet */
	ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
	if (ssize < 0) {
		perror("send");
		atf_tc_fail("send returned < 0");
	}
	ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd",
	    pktsize, ssize);

	rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
	if (rsize < 0) {
		perror("recv");
		atf_tc_fail("recv returned < 0");
	}
	ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd",
	    pktsize, rsize);
}
Exemplo n.º 13
0
/*
 * Wait for the specified process to hit a breakpoint at the specified symbol.
 */
static void
verify_bkpt(struct proc_handle *phdl, GElf_Sym *sym, const char *symname,
    const char *mapname)
{
	char mapbname[MAXPATHLEN], *name;
	GElf_Sym tsym;
	prmap_t *map;
	size_t namesz;
	u_long addr;
	int error, state;

	state = proc_wstatus(phdl);
	ATF_REQUIRE_EQ_MSG(state, PS_STOP, "process has state %d", state);

	/* Get the program counter and decrement it. */
	error = proc_regget(phdl, REG_PC, &addr);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to obtain PC for '%s'",
	    target_prog_file);
	proc_bkptregadj(&addr);

	/*
	 * Make sure the PC matches the expected value obtained from the symbol
	 * definition we looked up earlier.
	 */
	ATF_CHECK_EQ_MSG(addr, sym->st_value,
	    "program counter 0x%lx doesn't match expected value 0x%jx",
	    addr, (uintmax_t)sym->st_value);

	/*
	 * Ensure we can look up the r_debug_state symbol using its starting
	 * address and that the resulting symbol matches the one we found using
	 * a name lookup.
	 */
	namesz = strlen(symname) + 1;
	name = malloc(namesz);
	ATF_REQUIRE(name != NULL);

	error = proc_addr2sym(phdl, addr, name, namesz, &tsym);
	ATF_REQUIRE_EQ_MSG(error, 0, "failed to look up symbol at 0x%lx", addr);
	ATF_REQUIRE_EQ(memcmp(sym, &tsym, sizeof(*sym)), 0);
	ATF_REQUIRE_EQ_MSG(strcmp(symname, name), 0,
	    "expected symbol name '%s' doesn't match '%s'", symname, name);
	free(name);

	map = proc_addr2map(phdl, addr);
	ATF_REQUIRE_MSG(map != NULL, "failed to look up map for address 0x%lx",
	    addr);
	basename_r(map->pr_mapname, mapbname);
	ATF_REQUIRE_EQ_MSG(strcmp(mapname, mapbname), 0,
	    "expected map name '%s' doesn't match '%s'", mapname, mapbname);
}
Exemplo n.º 14
0
ATF_TC_BODY(sendto_recvfrom, tc)
{
	const char* path;
	struct sockaddr_storage from;
	int s;
	int sv[2];
	const int bufsize = 64;
	const char *data = "data";
	char recv_buf[bufsize];
	size_t datalen;
	ssize_t ssize, rsize;
	socklen_t fromlen;

	/* setup the socket pair */
	path = mk_pair_of_sockets(sv);

	/* send and receive a small packet */
	datalen = strlen(data) + 1;	/* +1 for the null */
	ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0);
	if (ssize < 0) {
		perror("send");
		atf_tc_fail("send returned < 0");
	}
	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
	    datalen, ssize);

	fromlen = sizeof(from);
	rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL,
	    (struct sockaddr*)&from, &fromlen);
	if (ssize < 0) {
		perror("recvfrom");
		atf_tc_fail("recvfrom returned < 0");
	}
	ATF_CHECK_EQ(datalen, rsize);

	/* 
	 * FreeBSD does not currently provide the source address for SEQ_PACKET
	 * AF_UNIX sockets, and POSIX does not require it, so these two checks
	 * are disabled.  If FreeBSD gains that feature in the future, then
	 * these checks may be reenabled
	 */
	/* ATF_CHECK_EQ(PF_LOCAL, from.ss_family); */
	/* ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path); */
}
Exemplo n.º 15
0
static void
checked_mmap(int prot, int flags, int fd, int error, const char *msg)
{
	void *p;

	p = mmap(NULL, getpagesize(), prot, flags, fd, 0);
	if (p == MAP_FAILED) {
		if (error == 0)
			ATF_CHECK_MSG(0, "%s failed with errno %d", msg,
			    errno);
		else
			ATF_CHECK_EQ_MSG(error, errno,
			    "%s failed with wrong errno %d (expected %d)", msg,
			    errno, error);
	} else {
		ATF_CHECK_MSG(error == 0, "%s succeeded", msg);
		munmap(p, getpagesize());
	}
}
Exemplo n.º 16
0
static void*
test_pipe_writer(void* args)
{
	test_pipe_thread_data_t* td = args;
	char sndbuf[td->pktsize];
	ssize_t ssize;
	int i;

	for(i=0; i < td->numpkts; i++) {
			memset(sndbuf, i, td->pktsize);
			ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR);
			if (ssize < 0) {
				perror("send");
				atf_tc_fail("send returned < 0");
			}
			ATF_CHECK_EQ_MSG(td->pktsize, ssize,
			    		 "expected %zd=send(...) but got %zd",
			    		  td->pktsize, ssize);
	}
	return (0);
}
Exemplo n.º 17
0
ATF_TC_BODY(map_prefix_name2map, tc)
{
	struct proc_handle *phdl;
	prmap_t *map1, *map2;

	phdl = start_prog(tc, false);

	/* Initialize the rtld_db handle. */
	(void)proc_rdagent(phdl);

	/* Make sure that "ld-elf" and "ld-elf.so" return the same map. */
	map1 = proc_name2map(phdl, "ld-elf");
	ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for 'ld-elf'");
	map2 = proc_name2map(phdl, "ld-elf.so");
	ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for 'ld-elf.so'");
	ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0);

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Exemplo n.º 18
0
ATF_TC_BODY(map_alias_name2map, tc)
{
	struct proc_handle *phdl;
	prmap_t *map1, *map2;

	phdl = start_prog(tc, false);

	/* Initialize the rtld_db handle. */
	(void)proc_rdagent(phdl);

	/* Ensure that "target_prog" and "a.out" return the same map. */
	map1 = proc_name2map(phdl, target_prog_file);
	ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for '%s'",
	    target_prog_file);
	map2 = proc_name2map(phdl, aout_object);
	ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for '%s'",
	    aout_object);
	ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0);

	ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");

	proc_free(phdl);
}
Exemplo n.º 19
0
void
test_pipe_simulator(size_t sndbufsize, size_t rcvbufsize)
{
	int s, num_sent, num_received;
	int sv[2];
	const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
	int numpkts;
	char sndbuf[pktsize];
	char rcvbuf[pktsize];
	char comparebuf[pktsize];
	ssize_t ssize, rsize;
	bool currently_sending = true;

	/* setup the socket pair */
	do_socketpair_nonblocking(sv);
	/* Setup the buffers */
	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
	    sizeof(sndbufsize)));
	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
	    sizeof(rcvbufsize)));

	/* Send a total amount of data comfortably greater than the buffers */
	numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize;
	for (num_sent=0, num_received=0;
	     num_sent < numpkts || num_received < numpkts; ) {
		if (currently_sending && num_sent < numpkts) {
			/* The simulated sending process */
			/* fill the buffer */
			memset(sndbuf, num_sent, pktsize);
			ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
			if (ssize < 0) {
				/* 
				 * XXX: This is bug-compatible with the kernel.
				 * The kernel returns EMSGSIZE when it should
				 * return EAGAIN
				 */
				if (errno == EAGAIN || errno == EMSGSIZE)
					currently_sending = false;
				else {
					perror("send");
					atf_tc_fail("send failed");
				}
			} else  {
				ATF_CHECK_EQ_MSG(pktsize, ssize,
				    "expected %zd=send(...) but got %zd",
				    pktsize, ssize);
				num_sent++;
			}
		} else {
			/* The simulated receiving process */
			rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL);
			if (rsize < 0) {
				if (errno == EAGAIN) {
					currently_sending = true;
					ATF_REQUIRE_MSG(num_sent < numpkts,
					    "Packets were lost!");
				}
				else {
					perror("recv");
					atf_tc_fail("recv failed");
				}
			} else  {
				ATF_CHECK_EQ_MSG(pktsize, rsize,
				    "expected %zd=recv(...) but got %zd",
				    pktsize, rsize);
				memset(comparebuf, num_received, pktsize);
				ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf,
				    			   pktsize), 
				    "Received data miscompare");
				num_received++;
			}
		}
	}
}
Exemplo n.º 20
0
ATF_TC_BODY(tsig_tcp, tc) {
	const dns_name_t *tsigowner = NULL;
	dns_fixedname_t fkeyname;
	dns_message_t *msg = NULL;
	dns_name_t *keyname;
	dns_tsig_keyring_t *ring = NULL;
	dns_tsigkey_t *key = NULL;
	isc_buffer_t *buf = NULL;
	isc_buffer_t *querytsig = NULL;
	isc_buffer_t *tsigin = NULL;
	isc_buffer_t *tsigout = NULL;
	isc_result_t result;
	unsigned char secret[16] = { 0 };
	dst_context_t *tsigctx = NULL;
	dst_context_t *outctx = NULL;

	UNUSED(tc);

	result = dns_test_begin(stderr, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/* isc_log_setdebuglevel(lctx, 99); */

	dns_fixedname_init(&fkeyname);
	keyname = dns_fixedname_name(&fkeyname);
	result = dns_name_fromstring(keyname, "test", 0, NULL);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_tsigkeyring_create(mctx, &ring);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_tsigkey_create(keyname, dns_tsig_hmacsha256_name,
				    secret, sizeof(secret), ISC_FALSE,
				    NULL, 0, 0, mctx, ring, &key);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/*
	 * Create request.
	 */
	result = isc_buffer_allocate(mctx, &buf, 65535);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	render(buf, 0, key, &tsigout, &querytsig, NULL);
	isc_buffer_free(&buf);

	/*
	 * Create response message 1.
	 */
	result = isc_buffer_allocate(mctx, &buf, 65535);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	render(buf, DNS_MESSAGEFLAG_QR, key, &querytsig, &tsigout, NULL);

	/*
	 * Process response message 1.
	 */
	result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_create: %s",
			 dns_result_totext(result));

	result = dns_message_settsigkey(msg, key);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_settsigkey: %s",
			 dns_result_totext(result));

	result = dns_message_parse(msg, buf, 0);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_parse: %s",
			 dns_result_totext(result));

	printmessage(msg);

	result = dns_message_setquerytsig(msg, querytsig);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_setquerytsig: %s",
			 dns_result_totext(result));

	result = dns_tsig_verify(buf, msg, NULL, NULL);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_tsig_verify: %s",
			 dns_result_totext(result));
	ATF_CHECK_EQ(msg->verified_sig, 1);
	ATF_CHECK_EQ(msg->tsigstatus, dns_rcode_noerror);

	/*
	 * Check that we have a TSIG in the first message.
	 */
	ATF_REQUIRE(dns_message_gettsig(msg, &tsigowner) != NULL);

	result = dns_message_getquerytsig(msg, mctx, &tsigin);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_getquerytsig: %s",
			 dns_result_totext(result));

	tsigctx = msg->tsigctx;
	msg->tsigctx = NULL;
	isc_buffer_free(&buf);
	dns_message_destroy(&msg);

	result = dst_context_create3(key->key, mctx, DNS_LOGCATEGORY_DNSSEC,
				     ISC_FALSE, &outctx);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/*
	 * Start digesting.
	 */
	result = add_mac(outctx, tsigout);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/*
	 * Create response message 2.
	 */
	result = isc_buffer_allocate(mctx, &buf, 65535);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	render(buf, DNS_MESSAGEFLAG_QR, key, &tsigout, &tsigout, outctx);

	/*
	 * Process response message 2.
	 */
	result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_create: %s",
			 dns_result_totext(result));

	msg->tcp_continuation = 1;
	msg->tsigctx = tsigctx;
	tsigctx = NULL;

	result = dns_message_settsigkey(msg, key);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_settsigkey: %s",
			 dns_result_totext(result));

	result = dns_message_parse(msg, buf, 0);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_parse: %s",
			 dns_result_totext(result));

	printmessage(msg);

	result = dns_message_setquerytsig(msg, tsigin);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_setquerytsig: %s",
			 dns_result_totext(result));

	result = dns_tsig_verify(buf, msg, NULL, NULL);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_tsig_verify: %s",
			 dns_result_totext(result));
	ATF_CHECK_EQ(msg->verified_sig, 1);
	ATF_CHECK_EQ(msg->tsigstatus, dns_rcode_noerror);

	/*
	 * Check that we don't have a TSIG in the second message.
	 */
	tsigowner = NULL;
	ATF_REQUIRE(dns_message_gettsig(msg, &tsigowner) == NULL);

	tsigctx = msg->tsigctx;
	msg->tsigctx = NULL;
	isc_buffer_free(&buf);
	dns_message_destroy(&msg);

	/*
	 * Create response message 3.
	 */
	result = isc_buffer_allocate(mctx, &buf, 65535);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
	render(buf, DNS_MESSAGEFLAG_QR, key, &tsigout, &tsigout, outctx);

	result = add_tsig(outctx, key, buf);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "add_tsig: %s",
			 dns_result_totext(result));

	/*
	 * Process response message 3.
	 */
	result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &msg);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_create: %s",
			 dns_result_totext(result));

	msg->tcp_continuation = 1;
	msg->tsigctx = tsigctx;
	tsigctx = NULL;

	result = dns_message_settsigkey(msg, key);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_settsigkey: %s",
			 dns_result_totext(result));

	result = dns_message_parse(msg, buf, 0);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_parse: %s",
			 dns_result_totext(result));

	printmessage(msg);

	/*
	 * Check that we had a TSIG in the third message.
	 */
	ATF_REQUIRE(dns_message_gettsig(msg, &tsigowner) != NULL);

	result = dns_message_setquerytsig(msg, tsigin);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_setquerytsig: %s",
			 dns_result_totext(result));

	result = dns_tsig_verify(buf, msg, NULL, NULL);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_tsig_verify: %s",
			 dns_result_totext(result));
	ATF_CHECK_EQ(msg->verified_sig, 1);
	ATF_CHECK_EQ(msg->tsigstatus, dns_rcode_noerror);

	if (tsigin != NULL)
		isc_buffer_free(&tsigin);

	result = dns_message_getquerytsig(msg, mctx, &tsigin);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_getquerytsig: %s",
			 dns_result_totext(result));

	isc_buffer_free(&buf);
	dns_message_destroy(&msg);

	if (outctx != NULL)
		dst_context_destroy(&outctx);
	if (querytsig != NULL)
		isc_buffer_free(&querytsig);
	if (tsigin != NULL)
		isc_buffer_free(&tsigin);
	if (tsigout != NULL)
		isc_buffer_free(&tsigout);
	if (buf != NULL)
		isc_buffer_free(&buf);
	if (msg != NULL)
		dns_message_destroy(&msg);
	if (key != NULL)
		dns_tsigkey_detach(&key);
	if (ring != NULL)
		dns_tsigkeyring_detach(&ring);
	dns_test_end();
}
Exemplo n.º 21
0
static void
render(isc_buffer_t *buf, unsigned flags, dns_tsigkey_t *key,
       isc_buffer_t **tsigin, isc_buffer_t **tsigout,
       dst_context_t *tsigctx)
{
	dns_message_t *msg = NULL;
	dns_compress_t cctx;
	isc_result_t result;

	result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &msg);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_create: %s",
			 dns_result_totext(result));

	msg->id = 50;
	msg->rcode = dns_rcode_noerror;
	msg->flags = flags;

	if (tsigin == tsigout)
		msg->tcp_continuation = 1;

	if (tsigctx == NULL) {
		result = dns_message_settsigkey(msg, key);
		ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
				 "dns_message_settsigkey: %s",
				 dns_result_totext(result));

		result = dns_message_setquerytsig(msg, *tsigin);
		ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
				 "dns_message_setquerytsig: %s",
				 dns_result_totext(result));
	}

	result = dns_compress_init(&cctx, -1, mctx);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_compress_init: %s",
			 dns_result_totext(result));

	result = dns_message_renderbegin(msg, &cctx, buf);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_renderbegin: %s",
			 dns_result_totext(result));

	result = dns_message_renderend(msg);
	ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
			 "dns_message_renderend: %s",
			 dns_result_totext(result));

	if (tsigctx != NULL) {
		isc_region_t r;

		isc_buffer_usedregion(buf, &r);
		result = dst_context_adddata(tsigctx, &r);
	} else {
		if (tsigin == tsigout && *tsigin != NULL)
			isc_buffer_free(tsigin);

		result = dns_message_getquerytsig(msg, mctx, tsigout);
		ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
				 "dns_message_getquerytsig: %s",
				 dns_result_totext(result));
	}

	dns_compress_invalidate(&cctx);
	dns_message_destroy(&msg);
}