[BACK]Return to res_sendsigned.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libresolv

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>