Annotation of src/lib/libresolv/res_sendsigned.c, Revision 1.1
1.1 ! christos 1: /* $NetBSD: res_sendsigned.c,v 1.1.1.1 2009/04/12 15:33:58 christos Exp $ */
! 2: #include <sys/cdefs.h>
! 3: __RCSID("$NetBSD$");
! 4:
! 5: #include "port_before.h"
! 6: #include "fd_setsize.h"
! 7:
! 8: #include <sys/types.h>
! 9: #include <sys/param.h>
! 10:
! 11: #include <netinet/in.h>
! 12: #include <arpa/nameser.h>
! 13: #include <arpa/inet.h>
! 14:
! 15: #include <isc/dst.h>
! 16:
! 17: #include <errno.h>
! 18: #include <netdb.h>
! 19: #include <resolv.h>
! 20: #include <stdio.h>
! 21: #include <stdlib.h>
! 22: #include <string.h>
! 23: #include <unistd.h>
! 24:
! 25: #include "port_after.h"
! 26:
! 27: #include "res_debug.h"
! 28:
! 29:
! 30: /*% res_nsendsigned */
! 31: int
! 32: res_nsendsigned(res_state statp, const u_char *msg, int msglen,
! 33: ns_tsig_key *key, u_char *answer, int anslen)
! 34: {
! 35: res_state nstatp;
! 36: DST_KEY *dstkey;
! 37: int usingTCP = 0;
! 38: u_char *newmsg;
! 39: int newmsglen, bufsize, siglen;
! 40: u_char sig[64];
! 41: HEADER *hp;
! 42: time_t tsig_time;
! 43: int ret;
! 44: int len;
! 45:
! 46: dst_init();
! 47:
! 48: nstatp = (res_state) malloc(sizeof(*statp));
! 49: if (nstatp == NULL) {
! 50: errno = ENOMEM;
! 51: return (-1);
! 52: }
! 53: memcpy(nstatp, statp, sizeof(*statp));
! 54:
! 55: bufsize = msglen + 1024;
! 56: newmsg = (u_char *) malloc(bufsize);
! 57: if (newmsg == NULL) {
! 58: free(nstatp);
! 59: errno = ENOMEM;
! 60: return (-1);
! 61: }
! 62: memcpy(newmsg, msg, msglen);
! 63: newmsglen = msglen;
! 64:
! 65: if (ns_samename(key->alg, NS_TSIG_ALG_HMAC_MD5) != 1)
! 66: dstkey = NULL;
! 67: else
! 68: dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5,
! 69: NS_KEY_TYPE_AUTH_ONLY,
! 70: NS_KEY_PROT_ANY,
! 71: key->data, key->len);
! 72: if (dstkey == NULL) {
! 73: errno = EINVAL;
! 74: free(nstatp);
! 75: free(newmsg);
! 76: return (-1);
! 77: }
! 78:
! 79: nstatp->nscount = 1;
! 80: siglen = sizeof(sig);
! 81: ret = ns_sign(newmsg, &newmsglen, bufsize, NOERROR, dstkey, NULL, 0,
! 82: sig, &siglen, 0);
! 83: if (ret < 0) {
! 84: free (nstatp);
! 85: free (newmsg);
! 86: dst_free_key(dstkey);
! 87: if (ret == NS_TSIG_ERROR_NO_SPACE)
! 88: errno = EMSGSIZE;
! 89: else if (ret == -1)
! 90: errno = EINVAL;
! 91: return (ret);
! 92: }
! 93:
! 94: if (newmsglen > PACKETSZ || nstatp->options & RES_USEVC)
! 95: usingTCP = 1;
! 96: if (usingTCP == 0)
! 97: nstatp->options |= RES_IGNTC;
! 98: else
! 99: nstatp->options |= RES_USEVC;
! 100: /*
! 101: * Stop res_send printing the answer.
! 102: */
! 103: nstatp->options &= ~RES_DEBUG;
! 104: nstatp->pfcode &= ~RES_PRF_REPLY;
! 105:
! 106: retry:
! 107:
! 108: len = res_nsend(nstatp, newmsg, newmsglen, answer, anslen);
! 109: if (len < 0) {
! 110: free (nstatp);
! 111: free (newmsg);
! 112: dst_free_key(dstkey);
! 113: return (len);
! 114: }
! 115:
! 116: ret = ns_verify(answer, &len, dstkey, sig, siglen,
! 117: NULL, NULL, &tsig_time, (nstatp->options & RES_KEEPTSIG) != 0);
! 118: if (ret != 0) {
! 119: Dprint((statp->options & RES_DEBUG) ||
! 120: ((statp->pfcode & RES_PRF_REPLY) &&
! 121: (statp->pfcode & RES_PRF_HEAD1)),
! 122: (stdout, ";; got answer:\n"));
! 123:
! 124: DprintQ((statp->options & RES_DEBUG) ||
! 125: (statp->pfcode & RES_PRF_REPLY),
! 126: (stdout, "%s", ""),
! 127: answer, (anslen > len) ? len : anslen);
! 128:
! 129: if (ret > 0) {
! 130: Dprint(statp->pfcode & RES_PRF_REPLY,
! 131: (stdout, ";; server rejected TSIG (%s)\n",
! 132: p_rcode(ret)));
! 133: } else {
! 134: Dprint(statp->pfcode & RES_PRF_REPLY,
! 135: (stdout, ";; TSIG invalid (%s)\n",
! 136: p_rcode(-ret)));
! 137: }
! 138:
! 139: free (nstatp);
! 140: free (newmsg);
! 141: dst_free_key(dstkey);
! 142: if (ret == -1)
! 143: errno = EINVAL;
! 144: else
! 145: errno = ENOTTY;
! 146: return (-1);
! 147: }
! 148:
! 149: hp = (HEADER *)(void *)answer;
! 150: if (hp->tc && !usingTCP && (statp->options & RES_IGNTC) == 0U) {
! 151: nstatp->options &= ~RES_IGNTC;
! 152: usingTCP = 1;
! 153: goto retry;
! 154: }
! 155: Dprint((statp->options & RES_DEBUG) ||
! 156: ((statp->pfcode & RES_PRF_REPLY) &&
! 157: (statp->pfcode & RES_PRF_HEAD1)),
! 158: (stdout, ";; got answer:\n"));
! 159:
! 160: DprintQ((statp->options & RES_DEBUG) ||
! 161: (statp->pfcode & RES_PRF_REPLY),
! 162: (stdout, "%s", ""),
! 163: answer, (anslen > len) ? len : anslen);
! 164:
! 165: Dprint(statp->pfcode & RES_PRF_REPLY, (stdout, ";; TSIG ok\n"));
! 166:
! 167: free (nstatp);
! 168: free (newmsg);
! 169: dst_free_key(dstkey);
! 170: return (len);
! 171: }
! 172:
! 173: /*! \file */
CVSweb <webmaster@jp.NetBSD.org>