~ubuntu-branches/ubuntu/oneiric/isc-dhcp/oneiric-security

« back to all changes in this revision

Viewing changes to minires/res_sendsigned.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Pollock
  • Date: 2009-09-02 22:34:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090902223425-nypo7bkftxffq41m
Tags: upstream-4.1.0
ImportĀ upstreamĀ versionĀ 4.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2004,2007 by Internet Systems Consortium, Inc. ("ISC")
 
3
 * Copyright (c) 1995-2003 by Internet Software Consortium
 
4
 *
 
5
 * Permission to use, copy, modify, and distribute this software for any
 
6
 * purpose with or without fee is hereby granted, provided that the above
 
7
 * copyright notice and this permission notice appear in all copies.
 
8
 *
 
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
 
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 
11
 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
 
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 
15
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
16
 *
 
17
 *   Internet Systems Consortium, Inc.
 
18
 *   950 Charter Street
 
19
 *   Redwood City, CA 94063
 
20
 *   <info@isc.org>
 
21
 *   http://www.isc.org/
 
22
 */
 
23
 
 
24
#include <sys/types.h>
 
25
#include <sys/param.h>
 
26
 
 
27
#include <netinet/in.h>
 
28
#include <arpa/inet.h>
 
29
#include <sys/socket.h>
 
30
 
 
31
#include <errno.h>
 
32
#include <netdb.h>
 
33
#include <stdio.h>
 
34
#include <stdlib.h>
 
35
#include <string.h>
 
36
#include <unistd.h>
 
37
 
 
38
#include "minires/minires.h"
 
39
#include "arpa/nameser.h"
 
40
 
 
41
#include <isc-dhcp/dst.h>
 
42
 
 
43
/* res_nsendsigned */
 
44
isc_result_t
 
45
res_nsendsigned(res_state statp,
 
46
                double *msg, unsigned msglen, ns_tsig_key *key,
 
47
                double *answer, unsigned anslen, unsigned *anssize)
 
48
{
 
49
        res_state nstatp;
 
50
        DST_KEY *dstkey;
 
51
        int usingTCP = 0;
 
52
        double *newmsg;
 
53
        unsigned newmsglen;
 
54
        unsigned bufsize, siglen;
 
55
        u_char sig[64];
 
56
        HEADER *hp;
 
57
        time_t tsig_time;
 
58
        unsigned ret;
 
59
        isc_result_t rcode;
 
60
 
 
61
        dst_init();
 
62
 
 
63
        nstatp = (res_state) malloc(sizeof(*statp));
 
64
        if (nstatp == NULL)
 
65
                return ISC_R_NOMEMORY;
 
66
        memcpy(nstatp, statp, sizeof(*statp));
 
67
 
 
68
        bufsize = msglen + 1024;
 
69
        newmsg = (double *) malloc(bufsize);
 
70
        if (newmsg == NULL) {
 
71
                free(nstatp);
 
72
                return ISC_R_NOMEMORY;
 
73
        }
 
74
        memcpy(newmsg, msg, msglen);
 
75
        newmsglen = msglen;
 
76
 
 
77
        if (ns_samename(key->alg, NS_TSIG_ALG_HMAC_MD5) != 1)
 
78
                dstkey = NULL;
 
79
        else
 
80
                dstkey = dst_buffer_to_key(key->name, KEY_HMAC_MD5,
 
81
                                           NS_KEY_TYPE_AUTH_ONLY,
 
82
                                           NS_KEY_PROT_ANY,
 
83
                                           key->data, key->len);
 
84
        if (dstkey == NULL) {
 
85
                free(nstatp);
 
86
                free(newmsg);
 
87
                return ISC_R_BADKEY;
 
88
        }
 
89
 
 
90
        nstatp->nscount = 1;
 
91
        siglen = sizeof(sig);
 
92
        rcode = ns_sign((u_char *)newmsg, &newmsglen, bufsize,
 
93
                        NOERROR, dstkey, NULL, 0,
 
94
                        sig, &siglen, 0);
 
95
        if (rcode != ISC_R_SUCCESS) {
 
96
                dst_free_key(dstkey);
 
97
                free (nstatp);
 
98
                free (newmsg);
 
99
                return rcode;
 
100
        }
 
101
 
 
102
        if (newmsglen > PACKETSZ || (nstatp->options & RES_IGNTC))
 
103
                usingTCP = 1;
 
104
        if (usingTCP == 0)
 
105
                nstatp->options |= RES_IGNTC;
 
106
        else
 
107
                nstatp->options |= RES_USEVC;
 
108
 
 
109
retry:
 
110
 
 
111
        rcode = res_nsend(nstatp, newmsg, newmsglen, answer, anslen, &ret);
 
112
        if (rcode != ISC_R_SUCCESS) {
 
113
                dst_free_key(dstkey);
 
114
                free (nstatp);
 
115
                free (newmsg);
 
116
                return rcode;
 
117
        }
 
118
 
 
119
        anslen = ret;
 
120
        rcode = ns_verify((u_char *)answer, &anslen, dstkey, sig, siglen,
 
121
                          NULL, NULL, &tsig_time,
 
122
                          (nstatp->options & RES_KEEPTSIG) ? 1 : 0);
 
123
        if (rcode != ISC_R_SUCCESS) {
 
124
                Dprint(nstatp->pfcode & RES_PRF_REPLY,
 
125
                       (stdout, ";; TSIG invalid (%s)\n", p_rcode(ret)));
 
126
                dst_free_key(dstkey);
 
127
                free (nstatp);
 
128
                free (newmsg);
 
129
                return rcode;
 
130
        }
 
131
        Dprint(nstatp->pfcode & RES_PRF_REPLY, (stdout, ";; TSIG ok\n"));
 
132
 
 
133
        hp = (HEADER *) answer;
 
134
        if (hp->tc && usingTCP == 0) {
 
135
                nstatp->options &= ~RES_IGNTC;
 
136
                usingTCP = 1;
 
137
                goto retry;
 
138
        }
 
139
 
 
140
        dst_free_key(dstkey);
 
141
        free (nstatp);
 
142
        free (newmsg);
 
143
        *anssize = anslen;
 
144
        return ISC_R_SUCCESS;
 
145
}