void runFailure7() {
    u_char msg[10];
    int msglen = 0;
    u_char query[10];
    int querylen = 20;
    u_char sig[10];
    int siglen = 10;
    void* k;

    ns_sign(msg, &msglen, 10, anyint(), k, query, querylen, sig, &siglen, anyint());
}
void testValues() {
    f = 2;
    
    u_char msg[10];
    int msglen = 0;
    u_char query[10];
    int querylen = 10;
    u_char sig[10];
    int siglen = 10;
    void* k;

    ns_sign(msg, &msglen, 10, anyint(), k, query, querylen, sig, &siglen, anyint());

    //@ assert f == 2;
    //@ assert vacuous: \false;
}
Ejemplo n.º 3
0
/* res_nsendsigned */
int
res_nsendsigned(res_state statp, const u_char *msg, int msglen,
		ns_tsig_key *key, u_char *answer, int anslen)
{
	res_state nstatp;
	DST_KEY *dstkey;
	int usingTCP = 0;
	u_char *newmsg;
	int newmsglen, bufsize, siglen;
	u_char sig[64];
	HEADER *hp;
	time_t tsig_time;
	int ret;

	dst_init();

	nstatp = (res_state) malloc(sizeof(*statp));
	if (nstatp == NULL) {
		errno = ENOMEM;
		return (-1);
	}
	memcpy(nstatp, statp, sizeof(*statp));

	bufsize = msglen + 1024;
	newmsg = (u_char *) malloc(bufsize);
	if (newmsg == NULL) {
		errno = ENOMEM;
		return (-1);
	}
	memcpy(newmsg, msg, msglen);
	newmsglen = msglen;

	if (ns_samename(key->alg, NS_TSIG_ALG_HMAC_MD5) != 1)
		dstkey = NULL;
	else
		dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5,
					   NS_KEY_TYPE_AUTH_ONLY,
					   NS_KEY_PROT_ANY,
					   key->data, key->len);
	if (dstkey == NULL) {
		errno = EINVAL;
		free(nstatp);
		free(newmsg);
		return (-1);
	}

	nstatp->nscount = 1;
	siglen = sizeof(sig);
	ret = ns_sign(newmsg, &newmsglen, bufsize, ns_r_noerror, dstkey, NULL, 0,
		      sig, &siglen, 0);
	if (ret < 0) {
		free (nstatp);
		free (newmsg);
		dst_free_key(dstkey);
		if (ret == NS_TSIG_ERROR_NO_SPACE)
			errno  = EMSGSIZE;
		else if (ret == -1)
			errno  = EINVAL;
		return (ret);
	}

	if (newmsglen > NS_PACKETSZ || (nstatp->options & RES_IGNTC))
		usingTCP = 1;
	if (usingTCP == 0)
		nstatp->options |= RES_IGNTC;
	else
		nstatp->options |= RES_USEVC;

retry:

	ret = res_nsend(nstatp, newmsg, newmsglen, answer, anslen);
	if (ret < 0) {
		free (nstatp);
		free (newmsg);
		dst_free_key(dstkey);
		return (ret);
	}

	anslen = ret;
	ret = ns_verify(answer, &anslen, dstkey, sig, siglen,
			NULL, NULL, &tsig_time, nstatp->options & RES_KEEPTSIG);
	if (ret != 0) {
		Dprint(nstatp->pfcode & RES_PRF_REPLY,
		       (stdout, ";; TSIG invalid (%s)\n", p_rcode(ret)));
		free (nstatp);
		free (newmsg);
		dst_free_key(dstkey);
		if (ret == -1)
			errno = EINVAL;
		else
			errno = ENOTTY;
		return (-1);
	}
	Dprint(nstatp->pfcode & RES_PRF_REPLY, (stdout, ";; TSIG ok\n"));

	hp = (HEADER *) answer;
	if (hp->tc && usingTCP == 0) {
		nstatp->options &= ~RES_IGNTC;
		usingTCP = 1;
		goto retry;
	}

	free (nstatp);
	free (newmsg);
	dst_free_key(dstkey);
	return (anslen);
}
Ejemplo n.º 4
0
/*% res_nsendsigned */
int
res_nsendsigned(res_state statp, const u_char *msg, int msglen,
		ns_tsig_key *key, u_char *answer, int anslen)
{
	res_state nstatp;
	DST_KEY *dstkey;
	int usingTCP = 0;
	u_char *newmsg;
	int newmsglen, bufsize, siglen;
	u_char sig[64];
	HEADER *hp;
	time_t tsig_time;
	int ret;
	int len;

	dst_init();

	nstatp = (res_state) malloc(sizeof(*statp));
	if (nstatp == NULL) {
		errno = ENOMEM;
		return (-1);
	}
	memcpy(nstatp, statp, sizeof(*statp));

	bufsize = msglen + 1024;
	newmsg = (u_char *) malloc(bufsize);
	if (newmsg == NULL) {
		free(nstatp);
		errno = ENOMEM;
		return (-1);
	}
	memcpy(newmsg, msg, msglen);
	newmsglen = msglen;

	if (ns_samename(key->alg, NS_TSIG_ALG_HMAC_MD5) != 1)
		dstkey = NULL;
	else
		dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5,
					   NS_KEY_TYPE_AUTH_ONLY,
					   NS_KEY_PROT_ANY,
					   key->data, key->len);
	if (dstkey == NULL) {
		errno = EINVAL;
		free(nstatp);
		free(newmsg);
		return (-1);
	}

	nstatp->nscount = 1;
	siglen = sizeof(sig);
	ret = ns_sign(newmsg, &newmsglen, bufsize, NOERROR, dstkey, NULL, 0,
		      sig, &siglen, 0);
	if (ret < 0) {
		free (nstatp);
		free (newmsg);
		dst_free_key(dstkey);
		if (ret == NS_TSIG_ERROR_NO_SPACE)
			errno  = EMSGSIZE;
		else if (ret == -1)
			errno  = EINVAL;
		return (ret);
	}

	if (newmsglen > PACKETSZ || nstatp->options & RES_USEVC)
		usingTCP = 1;
	if (usingTCP == 0)
		nstatp->options |= RES_IGNTC;
	else
		nstatp->options |= RES_USEVC;
	/*
	 * Stop res_send printing the answer.
	 */
	nstatp->options &= ~RES_DEBUG;
	nstatp->pfcode &= ~RES_PRF_REPLY;

retry:

	len = res_nsend(nstatp, newmsg, newmsglen, answer, anslen);
	if (len < 0) {
		free (nstatp);
		free (newmsg);
		dst_free_key(dstkey);
		return (len);
	}

	ret = ns_verify(answer, &len, dstkey, sig, siglen,
			NULL, NULL, &tsig_time, nstatp->options & RES_KEEPTSIG);
	if (ret != 0) {
		Dprint((statp->options & RES_DEBUG) ||
		       ((statp->pfcode & RES_PRF_REPLY) &&
			(statp->pfcode & RES_PRF_HEAD1)),
		       (stdout, ";; got answer:\n"));

		DprintQ((statp->options & RES_DEBUG) ||
			(statp->pfcode & RES_PRF_REPLY),
			(stdout, "%s", ""),
			answer, (anslen > len) ? len : anslen);

		if (ret > 0) {
			Dprint(statp->pfcode & RES_PRF_REPLY,
			       (stdout, ";; server rejected TSIG (%s)\n",
				p_rcode(ret)));
		} else {
			Dprint(statp->pfcode & RES_PRF_REPLY,
			       (stdout, ";; TSIG invalid (%s)\n",
				p_rcode(-ret)));
		}

		free (nstatp);
		free (newmsg);
		dst_free_key(dstkey);
		if (ret == -1)
			errno = EINVAL;
		else
			errno = ENOTTY;
		return (-1);
	}

	hp = (HEADER *) answer;
	if (hp->tc && !usingTCP && (statp->options & RES_IGNTC) == 0U) {
		nstatp->options &= ~RES_IGNTC;
		usingTCP = 1;
		goto retry;
	}
	Dprint((statp->options & RES_DEBUG) ||
	       ((statp->pfcode & RES_PRF_REPLY) &&
		(statp->pfcode & RES_PRF_HEAD1)),
	       (stdout, ";; got answer:\n"));

	DprintQ((statp->options & RES_DEBUG) ||
		(statp->pfcode & RES_PRF_REPLY),
		(stdout, "%s", ""),
		answer, (anslen > len) ? len : anslen);

	Dprint(statp->pfcode & RES_PRF_REPLY, (stdout, ";; TSIG ok\n"));

	free (nstatp);
	free (newmsg);
	dst_free_key(dstkey);
	return (len);
}
Ejemplo n.º 5
0
isc_result_t
ns_sign_tcp(u_char *msg, unsigned *msglen, unsigned msgsize, int error,
	    ns_tcp_tsig_state *state, int done)
{
	u_char *cp, *eob, *lenp;
	u_char buf[MAXDNAME], *cp2;
	HEADER *hp = (HEADER *)msg;
	time_t timesigned;
	int n;

	if (msg == NULL || msglen == NULL || state == NULL)
		return ISC_R_INVALIDARG;

	state->counter++;
	if (state->counter == 0)
		return ns_sign(msg, msglen, msgsize, error, state->key,
			       state->sig, state->siglen,
			       state->sig, &state->siglen, 0);

	if (state->siglen > 0) {
		u_int16_t siglen_n = htons(state->siglen);
		dst_sign_data(SIG_MODE_INIT, state->key, &state->ctx,
			      NULL, 0, NULL, 0);
		dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
			      (u_char *)&siglen_n, INT16SZ, NULL, 0);
		dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
			      state->sig, state->siglen, NULL, 0);
		state->siglen = 0;
	}

	dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx, msg, *msglen,
		      NULL, 0);

	if (done == 0 && (state->counter % 100 != 0))
		return ISC_R_SUCCESS;

	cp = msg + *msglen;
	eob = msg + msgsize;

	/* Name. */
	n = dn_comp(state->key->dk_key_name,
		    cp, (unsigned)(eob - cp), NULL, NULL);
	if (n < 0)
		return ISC_R_NOSPACE;
	cp += n;

	/* Type, class, ttl, length (not filled in yet). */
	BOUNDS_CHECK(cp, INT16SZ + INT16SZ + INT32SZ + INT16SZ);
	PUTSHORT(ns_t_tsig, cp);
	PUTSHORT(ns_c_any, cp);
	PUTLONG(0, cp);		/* TTL */
	lenp = cp;
	cp += 2;

	/* Alg. */
	n = dn_comp(NS_TSIG_ALG_HMAC_MD5,
		    cp, (unsigned)(eob - cp), NULL, NULL);
	if (n < 0)
		return ISC_R_NOSPACE;
	cp += n;
	
	/* Time. */
	BOUNDS_CHECK(cp, INT16SZ + INT32SZ + INT16SZ);
	PUTSHORT(0, cp);
	timesigned = time(NULL);
	PUTLONG(timesigned, cp);
	PUTSHORT(NS_TSIG_FUDGE, cp);

	/*
	 * Compute the signature.
	 */

	/* Digest the time signed and fudge. */
	cp2 = buf;
	PUTSHORT(0, cp2);	/* Top 16 bits of time */
	PUTLONG(timesigned, cp2);
	PUTSHORT(NS_TSIG_FUDGE, cp2);

	dst_sign_data(SIG_MODE_UPDATE, state->key, &state->ctx,
		      buf, (unsigned)(cp2 - buf), NULL, 0);

	n = dst_sign_data(SIG_MODE_FINAL, state->key, &state->ctx, NULL, 0,
			  state->sig, sizeof(state->sig));
	if (n < 0)
		return ISC_R_BADKEY;
	state->siglen = n;

	/* Add the signature. */
	BOUNDS_CHECK(cp, INT16SZ + state->siglen);
	PUTSHORT(state->siglen, cp);
	memcpy(cp, state->sig, state->siglen);
	cp += state->siglen;

	/* The original message ID & error. */
	BOUNDS_CHECK(cp, INT16SZ + INT16SZ);
	PUTSHORT(ntohs(hp->id), cp);	/* already in network order */
	PUTSHORT(error, cp);

	/* Other data. */
	BOUNDS_CHECK(cp, INT16SZ);
	PUTSHORT(0, cp);

	/* Go back and fill in the length. */
	PUTSHORT(cp - lenp - INT16SZ, lenp);

	hp->arcount = htons(ntohs(hp->arcount) + 1);
	*msglen = (cp - msg);
	return ISC_R_SUCCESS;
}
Ejemplo n.º 6
0
static int
printZone(ns_type xfr, const char *zone, const struct sockaddr_in *sin,
	  ns_tsig_key *key)
{
	static u_char *answer = NULL;
	static int answerLen = 0;

	querybuf buf;
	int msglen, amtToRead, numRead, result, sockFD, len;
	int count, type, rlen, done, n;
	int numAnswers, numRecords, soacnt;
	u_char *cp, tmp[NS_INT16SZ];
	char dname[2][NS_MAXDNAME];
	enum { NO_ERRORS, ERR_READING_LEN, ERR_READING_MSG, ERR_PRINTING }
		error;
	pid_t zpid = -1;
	u_char *newmsg;
	int newmsglen;
	ns_tcp_tsig_state tsig_state;
	int tsig_ret, tsig_required, tsig_present;

	switch (xfr) {
	case ns_t_axfr:
	case ns_t_zxfr:
		break;
	default:
		fprintf(stderr, ";; %s - transfer type not supported\n",
			p_type(xfr));
		return (ERROR);
	}

	/*
	 *  Create a query packet for the requested zone name.
	 */
	msglen = res_nmkquery(&res, ns_o_query, zone,
			      queryClass, ns_t_axfr, NULL,
			      0, 0, buf.qb2, sizeof buf);
	if (msglen < 0) {
		if (res.options & RES_DEBUG)
			fprintf(stderr, ";; res_nmkquery failed\n");
		return (ERROR);
	}

	/*
	 * Sign the message if a key was sent
	 */
	if (key == NULL) {
		newmsg = (u_char *)&buf;
		newmsglen = msglen;
	} else {
		DST_KEY *dstkey;
		int bufsize, siglen;
		u_char sig[64];
		int ret;
		
		/* ns_sign() also calls dst_init(), but there is no harm
		 * doing it twice
		 */
		dst_init();
		
		bufsize = msglen + 1024;
		newmsg = (u_char *) malloc(bufsize);
		if (newmsg == NULL) {
			errno = ENOMEM;
			return (-1);
		}
		memcpy(newmsg, (u_char *)&buf, msglen);
		newmsglen = msglen;
		
		if (strcmp(key->alg, NS_TSIG_ALG_HMAC_MD5) != 0)
			dstkey = NULL;
		else
			dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5,
							NS_KEY_TYPE_AUTH_ONLY,
							NS_KEY_PROT_ANY,
							key->data, key->len);
		if (dstkey == NULL) {
			errno = EINVAL;
			if (key)
				free(newmsg);
			return (-1);
		}
		
		siglen = sizeof(sig);
/* newmsglen++; */
		ret = ns_sign(newmsg, &newmsglen, bufsize, NOERROR, dstkey, NULL, 0,
		      sig, &siglen, 0);
		if (ret < 0) {
			if (key)
				free (newmsg);
			if (ret == NS_TSIG_ERROR_NO_SPACE)
				errno  = EMSGSIZE;
			else if (ret == -1)
				errno  = EINVAL;
			return (ret);
		}
		ns_verify_tcp_init(dstkey, sig, siglen, &tsig_state);
	}

	/*
	 *  Set up a virtual circuit to the server.
	 */
	if ((sockFD = socket(sin->sin_family, SOCK_STREAM, 0)) < 0) {
		int e = errno;

		perror(";; socket");
		return (e);
	}
	
	switch (sin->sin_family) {
	case AF_INET:
		if (bind(sockFD, (struct sockaddr *)&myaddress,
			 sizeof myaddress) < 0){
			int e = errno;

			fprintf(stderr, ";; bind(%s port %u): %s\n",
				inet_ntoa(myaddress.sin_addr),
				ntohs(myaddress.sin_port),
				strerror(e));
			(void) close(sockFD);
			sockFD = -1;
			return (e);
		}
		if (connect(sockFD, (const struct sockaddr *)sin,
			    sizeof *sin) < 0) {
			int e = errno;

			perror(";; connect");
			(void) close(sockFD);
			sockFD = -1;
			return (e);
		}
		break;
	case AF_INET6:
		if (bind(sockFD, (struct sockaddr *)&myaddress6,
			 sizeof myaddress6) < 0){
			int e = errno;
			char buf[80];

			fprintf(stderr, ";; bind(%s port %u): %s\n",
				inet_ntop(AF_INET6, &myaddress6.sin6_addr,
					  buf, sizeof(buf)),
				ntohs(myaddress6.sin6_port),
				strerror(e));
			(void) close(sockFD);
			sockFD = -1;
			return (e);
		}
		if (connect(sockFD, (const struct sockaddr *)sin,
			    sizeof(struct sockaddr_in6)) < 0) {
			int e = errno;

			perror(";; connect");
			(void) close(sockFD);
			sockFD = -1;
			return (e);
		}
		break;
	}

	/*
	 * Send length & message for zone transfer
	 */

	ns_put16(newmsglen, tmp);
        if (write(sockFD, (char *)tmp, NS_INT16SZ) != NS_INT16SZ ||
            write(sockFD, (char *)newmsg, newmsglen) != newmsglen) {
		int e = errno;
		if (key)
			free (newmsg);
		perror(";; write");
		(void) close(sockFD);
		sockFD = -1;
		return (e);
	} else if (key)
		free (newmsg);

	/*
	 * If we're compressing, push a gzip into the pipeline.
	 */
	if (xfr == ns_t_zxfr) {
		enum { rd = 0, wr = 1 };
		int z[2];

		if (pipe(z) < 0) {
			int e = errno;

			perror(";; pipe");
			(void) close(sockFD);
			sockFD = -1;
			return (e);
		}
		zpid = vfork();
		if (zpid < 0) {
			int e = errno;

			perror(";; fork");
			(void) close(sockFD);
			sockFD = -1;
			return (e);
		} else if (zpid == 0) {
			/* Child. */
			(void) close(z[rd]);
			(void) dup2(sockFD, STDIN_FILENO);
			(void) close(sockFD);
			(void) dup2(z[wr], STDOUT_FILENO);
			(void) close(z[wr]);
			execlp("gzip", "gzip", "-d", "-v", NULL);
			perror(";; child: execlp(gunzip)");
			_exit(1);
		}
		/* Parent. */
		(void) close(z[wr]);
		(void) dup2(z[rd], sockFD);
		(void) close(z[rd]);
	}
	result = 0;
	numAnswers = 0;
	numRecords = 0;
	soacnt = 0;
	error = NO_ERRORS;
	numRead = 0;

	dname[0][0] = '\0';
	for (done = 0; !done; (void)NULL) {
		/*
		 * Read the length of the response.
		 */

		cp = tmp;
		amtToRead = INT16SZ;
		while (amtToRead > 0 &&
		   (numRead = read(sockFD, cp, amtToRead)) > 0) {
			cp += numRead;
			amtToRead -= numRead;
		}
		if (numRead <= 0) {
			error = ERR_READING_LEN;
			break;
		}

		len = ns_get16(tmp);
		if (len == 0)
			break;	/* nothing left to read */

		/*
		 * The server sent too much data to fit the existing buffer --
		 * allocate a new one.
		 */
		if (len > answerLen) {
			if (answerLen != 0)
				free(answer);
			answerLen = len;
			answer = (u_char *)malloc(answerLen);
		}

		/*
		 * Read the response.
		 */

		amtToRead = len;
		cp = answer;
		while (amtToRead > 0 &&
		       (numRead = read(sockFD, cp, amtToRead)) > 0) {
			cp += numRead;
			amtToRead -= numRead;
		}
		if (numRead <= 0) {
			error = ERR_READING_MSG;
			break;
		}

		result = print_axfr(stdout, answer, len);
		if (result != 0) {
			error = ERR_PRINTING;
			break;
		}
		numRecords += htons(((HEADER *)answer)->ancount);
		numAnswers++;

		/* Header. */
		cp = answer + HFIXEDSZ;
		/* Question. */
		for (count = ntohs(((HEADER *)answer)->qdcount);	
		     count > 0;
		     count--) {
			n = dn_skipname(cp, answer + len);
			if (n < 0) {
				error = ERR_PRINTING;
				done++;
				break;
			}
			cp += n + QFIXEDSZ;
			if (cp > answer + len) {
				error = ERR_PRINTING;
				done++;
				break;
			}
		}
		/* Answer. */
		for (count = ntohs(((HEADER *)answer)->ancount);
		     count > 0 && !done;
		     count--) {
			n = dn_expand(answer, answer + len, cp,
				      dname[soacnt], sizeof dname[0]);
			if (n < 0) {
				error = ERR_PRINTING;
				done++;
				break;
			}
			cp += n;
			if (cp + 3 * INT16SZ + INT32SZ > answer + len) {
				error = ERR_PRINTING;
				done++;
				break;
			}
			GETSHORT(type, cp);
			cp += INT16SZ;
			cp += INT32SZ;	/* ttl */
			GETSHORT(rlen, cp);
			cp += rlen;
			if (cp > answer + len) {
				error = ERR_PRINTING;
				done++;
				break;
			}
			if (type == T_SOA && soacnt++ &&
			    ns_samename(dname[0], dname[1]) == 1) {
				done++;
				break;
			}
		}

		/*
		 * Verify the TSIG
		 */

		if (key) {
			if (ns_find_tsig(answer, answer + len) != NULL)
				tsig_present = 1;
			else
				tsig_present = 0;
			if (numAnswers == 1 || soacnt > 1)
				tsig_required = 1;
			else
				tsig_required = 0;
			tsig_ret = ns_verify_tcp(answer, &len, &tsig_state,
						 tsig_required);
			if (tsig_ret == 0) {
				if (tsig_present)
					printf("; TSIG ok\n");
			}
			else
				printf("; TSIG invalid\n");
		}

	}

	printf(";; Received %d answer%s (%d record%s).\n",
	       numAnswers, (numAnswers != 1) ? "s" : "",
	       numRecords, (numRecords != 1) ? "s" : "");

	(void) close(sockFD);
	sockFD = -1;

	/*
	 * If we were uncompressing, reap the uncompressor.
	 */
	if (xfr == ns_t_zxfr) {
		pid_t pid;
		int status = 0;

		pid = wait(&status);
		if (pid < 0) {
			int e = errno;

			perror(";; wait");
			return (e);
		}
		if (pid != zpid) {
			fprintf(stderr, ";; wrong pid (%lu != %lu)\n",
				(u_long)pid, (u_long)zpid);
			return (ERROR);
		}
		printf(";; pid %lu: exit %d, signal %d, core %c\n",
		       (u_long)pid, WEXITSTATUS(status),
		       WIFSIGNALED(status) ? WTERMSIG(status) : 0,
		       WCOREDUMP(status) ? 't' : 'f');
	}

	switch (error) {
	case NO_ERRORS:
		return (0);

	case ERR_READING_LEN:
		return (EMSGSIZE);

	case ERR_PRINTING:
		return (result);

	case ERR_READING_MSG:
		return (EMSGSIZE);

	default:
		return (EFAULT);
	}
}