xref: /titanic_50/usr/src/lib/libresolv2/common/resolv/res_sendsigned.c (revision 9525b14bcdeb5b5f6f95ab27c2f48f18bd2ec829)
17c478bd9Sstevel@tonic-gate #include "port_before.h"
27c478bd9Sstevel@tonic-gate #include "fd_setsize.h"
37c478bd9Sstevel@tonic-gate 
47c478bd9Sstevel@tonic-gate #include <sys/types.h>
57c478bd9Sstevel@tonic-gate #include <sys/param.h>
67c478bd9Sstevel@tonic-gate 
77c478bd9Sstevel@tonic-gate #include <netinet/in.h>
87c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
97c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
107c478bd9Sstevel@tonic-gate 
117c478bd9Sstevel@tonic-gate #include <isc/dst.h>
127c478bd9Sstevel@tonic-gate 
137c478bd9Sstevel@tonic-gate #include <errno.h>
147c478bd9Sstevel@tonic-gate #include <netdb.h>
157c478bd9Sstevel@tonic-gate #include <resolv.h>
167c478bd9Sstevel@tonic-gate #include <stdio.h>
177c478bd9Sstevel@tonic-gate #include <stdlib.h>
187c478bd9Sstevel@tonic-gate #include <string.h>
197c478bd9Sstevel@tonic-gate #include <unistd.h>
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate #include "port_after.h"
227c478bd9Sstevel@tonic-gate 
237c478bd9Sstevel@tonic-gate #define DEBUG
247c478bd9Sstevel@tonic-gate #include "res_debug.h"
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate 
27*9525b14bSRao Shoaib /*% res_nsendsigned */
287c478bd9Sstevel@tonic-gate int
res_nsendsigned(res_state statp,const u_char * msg,int msglen,ns_tsig_key * key,u_char * answer,int anslen)297c478bd9Sstevel@tonic-gate res_nsendsigned(res_state statp, const u_char *msg, int msglen,
307c478bd9Sstevel@tonic-gate 		ns_tsig_key *key, u_char *answer, int anslen)
317c478bd9Sstevel@tonic-gate {
327c478bd9Sstevel@tonic-gate 	res_state nstatp;
337c478bd9Sstevel@tonic-gate 	DST_KEY *dstkey;
347c478bd9Sstevel@tonic-gate 	int usingTCP = 0;
357c478bd9Sstevel@tonic-gate 	u_char *newmsg;
367c478bd9Sstevel@tonic-gate 	int newmsglen, bufsize, siglen;
377c478bd9Sstevel@tonic-gate 	u_char sig[64];
387c478bd9Sstevel@tonic-gate 	HEADER *hp;
397c478bd9Sstevel@tonic-gate 	time_t tsig_time;
407c478bd9Sstevel@tonic-gate 	int ret;
41*9525b14bSRao Shoaib 	int len;
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate 	dst_init();
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate 	nstatp = (res_state) malloc(sizeof(*statp));
467c478bd9Sstevel@tonic-gate 	if (nstatp == NULL) {
477c478bd9Sstevel@tonic-gate 		errno = ENOMEM;
487c478bd9Sstevel@tonic-gate 		return (-1);
497c478bd9Sstevel@tonic-gate 	}
507c478bd9Sstevel@tonic-gate 	memcpy(nstatp, statp, sizeof(*statp));
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate 	bufsize = msglen + 1024;
537c478bd9Sstevel@tonic-gate 	newmsg = (u_char *) malloc(bufsize);
547c478bd9Sstevel@tonic-gate 	if (newmsg == NULL) {
55*9525b14bSRao Shoaib 		free(nstatp);
567c478bd9Sstevel@tonic-gate 		errno = ENOMEM;
577c478bd9Sstevel@tonic-gate 		return (-1);
587c478bd9Sstevel@tonic-gate 	}
597c478bd9Sstevel@tonic-gate 	memcpy(newmsg, msg, msglen);
607c478bd9Sstevel@tonic-gate 	newmsglen = msglen;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	if (ns_samename(key->alg, NS_TSIG_ALG_HMAC_MD5) != 1)
637c478bd9Sstevel@tonic-gate 		dstkey = NULL;
647c478bd9Sstevel@tonic-gate 	else
657c478bd9Sstevel@tonic-gate 		dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5,
667c478bd9Sstevel@tonic-gate 					   NS_KEY_TYPE_AUTH_ONLY,
677c478bd9Sstevel@tonic-gate 					   NS_KEY_PROT_ANY,
687c478bd9Sstevel@tonic-gate 					   key->data, key->len);
697c478bd9Sstevel@tonic-gate 	if (dstkey == NULL) {
707c478bd9Sstevel@tonic-gate 		errno = EINVAL;
717c478bd9Sstevel@tonic-gate 		free(nstatp);
727c478bd9Sstevel@tonic-gate 		free(newmsg);
737c478bd9Sstevel@tonic-gate 		return (-1);
747c478bd9Sstevel@tonic-gate 	}
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 	nstatp->nscount = 1;
777c478bd9Sstevel@tonic-gate 	siglen = sizeof(sig);
787c478bd9Sstevel@tonic-gate 	ret = ns_sign(newmsg, &newmsglen, bufsize, NOERROR, dstkey, NULL, 0,
797c478bd9Sstevel@tonic-gate 		      sig, &siglen, 0);
807c478bd9Sstevel@tonic-gate 	if (ret < 0) {
817c478bd9Sstevel@tonic-gate 		free (nstatp);
827c478bd9Sstevel@tonic-gate 		free (newmsg);
837c478bd9Sstevel@tonic-gate 		dst_free_key(dstkey);
847c478bd9Sstevel@tonic-gate 		if (ret == NS_TSIG_ERROR_NO_SPACE)
857c478bd9Sstevel@tonic-gate 			errno  = EMSGSIZE;
867c478bd9Sstevel@tonic-gate 		else if (ret == -1)
877c478bd9Sstevel@tonic-gate 			errno  = EINVAL;
887c478bd9Sstevel@tonic-gate 		return (ret);
897c478bd9Sstevel@tonic-gate 	}
907c478bd9Sstevel@tonic-gate 
91*9525b14bSRao Shoaib 	if (newmsglen > PACKETSZ || nstatp->options & RES_USEVC)
927c478bd9Sstevel@tonic-gate 		usingTCP = 1;
937c478bd9Sstevel@tonic-gate 	if (usingTCP == 0)
947c478bd9Sstevel@tonic-gate 		nstatp->options |= RES_IGNTC;
957c478bd9Sstevel@tonic-gate 	else
967c478bd9Sstevel@tonic-gate 		nstatp->options |= RES_USEVC;
97*9525b14bSRao Shoaib 	/*
98*9525b14bSRao Shoaib 	 * Stop res_send printing the answer.
99*9525b14bSRao Shoaib 	 */
100*9525b14bSRao Shoaib 	nstatp->options &= ~RES_DEBUG;
101*9525b14bSRao Shoaib 	nstatp->pfcode &= ~RES_PRF_REPLY;
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate retry:
1047c478bd9Sstevel@tonic-gate 
105*9525b14bSRao Shoaib 	len = res_nsend(nstatp, newmsg, newmsglen, answer, anslen);
106*9525b14bSRao Shoaib 	if (len < 0) {
1077c478bd9Sstevel@tonic-gate 		free (nstatp);
1087c478bd9Sstevel@tonic-gate 		free (newmsg);
1097c478bd9Sstevel@tonic-gate 		dst_free_key(dstkey);
110*9525b14bSRao Shoaib 		return (len);
1117c478bd9Sstevel@tonic-gate 	}
1127c478bd9Sstevel@tonic-gate 
113*9525b14bSRao Shoaib 	ret = ns_verify(answer, &len, dstkey, sig, siglen,
1147c478bd9Sstevel@tonic-gate 			NULL, NULL, &tsig_time, nstatp->options & RES_KEEPTSIG);
1157c478bd9Sstevel@tonic-gate 	if (ret != 0) {
116*9525b14bSRao Shoaib 		Dprint((statp->options & RES_DEBUG) ||
117*9525b14bSRao Shoaib 		       ((statp->pfcode & RES_PRF_REPLY) &&
118*9525b14bSRao Shoaib 			(statp->pfcode & RES_PRF_HEAD1)),
119*9525b14bSRao Shoaib 		       (stdout, ";; got answer:\n"));
120*9525b14bSRao Shoaib 
121*9525b14bSRao Shoaib 		DprintQ((statp->options & RES_DEBUG) ||
122*9525b14bSRao Shoaib 			(statp->pfcode & RES_PRF_REPLY),
123*9525b14bSRao Shoaib 			(stdout, "%s", ""),
124*9525b14bSRao Shoaib 			answer, (anslen > len) ? len : anslen);
125*9525b14bSRao Shoaib 
126*9525b14bSRao Shoaib 		if (ret > 0) {
127*9525b14bSRao Shoaib 			Dprint(statp->pfcode & RES_PRF_REPLY,
128*9525b14bSRao Shoaib 			       (stdout, ";; server rejected TSIG (%s)\n",
129*9525b14bSRao Shoaib 				p_rcode(ret)));
130*9525b14bSRao Shoaib 		} else {
131*9525b14bSRao Shoaib 			Dprint(statp->pfcode & RES_PRF_REPLY,
132*9525b14bSRao Shoaib 			       (stdout, ";; TSIG invalid (%s)\n",
133*9525b14bSRao Shoaib 				p_rcode(-ret)));
134*9525b14bSRao Shoaib 		}
135*9525b14bSRao Shoaib 
1367c478bd9Sstevel@tonic-gate 		free (nstatp);
1377c478bd9Sstevel@tonic-gate 		free (newmsg);
1387c478bd9Sstevel@tonic-gate 		dst_free_key(dstkey);
1397c478bd9Sstevel@tonic-gate 		if (ret == -1)
1407c478bd9Sstevel@tonic-gate 			errno = EINVAL;
1417c478bd9Sstevel@tonic-gate 		else
1427c478bd9Sstevel@tonic-gate 			errno = ENOTTY;
1437c478bd9Sstevel@tonic-gate 		return (-1);
1447c478bd9Sstevel@tonic-gate 	}
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate 	hp = (HEADER *) answer;
147*9525b14bSRao Shoaib 	if (hp->tc && !usingTCP && (statp->options & RES_IGNTC) == 0U) {
1487c478bd9Sstevel@tonic-gate 		nstatp->options &= ~RES_IGNTC;
1497c478bd9Sstevel@tonic-gate 		usingTCP = 1;
1507c478bd9Sstevel@tonic-gate 		goto retry;
1517c478bd9Sstevel@tonic-gate 	}
152*9525b14bSRao Shoaib 	Dprint((statp->options & RES_DEBUG) ||
153*9525b14bSRao Shoaib 	       ((statp->pfcode & RES_PRF_REPLY) &&
154*9525b14bSRao Shoaib 		(statp->pfcode & RES_PRF_HEAD1)),
155*9525b14bSRao Shoaib 	       (stdout, ";; got answer:\n"));
156*9525b14bSRao Shoaib 
157*9525b14bSRao Shoaib 	DprintQ((statp->options & RES_DEBUG) ||
158*9525b14bSRao Shoaib 		(statp->pfcode & RES_PRF_REPLY),
159*9525b14bSRao Shoaib 		(stdout, "%s", ""),
160*9525b14bSRao Shoaib 		answer, (anslen > len) ? len : anslen);
161*9525b14bSRao Shoaib 
162*9525b14bSRao Shoaib 	Dprint(statp->pfcode & RES_PRF_REPLY, (stdout, ";; TSIG ok\n"));
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate 	free (nstatp);
1657c478bd9Sstevel@tonic-gate 	free (newmsg);
1667c478bd9Sstevel@tonic-gate 	dst_free_key(dstkey);
167*9525b14bSRao Shoaib 	return (len);
1687c478bd9Sstevel@tonic-gate }
169*9525b14bSRao Shoaib 
170*9525b14bSRao Shoaib /*! \file */
171