~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to libisc/netaddr.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-01-05 21:10:03 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20090105211003-mh6zc3um4k1uhsj7
Tags: 1:4.2.4p4+dfsg-8
It did not properly check the return value of EVP_VerifyFinal
which results in an malformed DSA signature being treated as
a good signature rather than as an error.  (CVE-2009-0021)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
 
3
 * Copyright (C) 1999-2002  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 WITH
 
10
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 
11
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 
12
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 
13
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 
14
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
15
 * PERFORMANCE OF THIS SOFTWARE.
 
16
 */
 
17
 
 
18
/* $Id: netaddr.c,v 1.18.12.9 2004/05/15 03:46:12 jinmei Exp $ */
 
19
 
 
20
#include <config.h>
 
21
 
 
22
#define ISC_ONLY_IPV6
 
23
 
 
24
#include <stdio.h>
 
25
 
 
26
#include <isc/buffer.h>
 
27
#include <isc/msgs.h>
 
28
#include <isc/net.h>
 
29
#include <isc/netaddr.h>
 
30
#include <isc/print.h>
 
31
#include <isc/sockaddr.h>
 
32
#include <isc/string.h>
 
33
#include <isc/util.h>
 
34
 
 
35
isc_boolean_t
 
36
isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) {
 
37
        REQUIRE(a != NULL && b != NULL);
 
38
 
 
39
        if (a->family != b->family)
 
40
                return (ISC_FALSE);
 
41
 
 
42
        if (a->zone != b->zone)
 
43
                return (ISC_FALSE);
 
44
 
 
45
        switch (a->family) {
 
46
        case AF_INET:
 
47
                if (a->type.in.s_addr != b->type.in.s_addr)
 
48
                        return (ISC_FALSE);
 
49
                break;
 
50
        case AF_INET6:
 
51
                if (memcmp(&a->type.in6, &b->type.in6,
 
52
                           sizeof(a->type.in6)) != 0 ||
 
53
                    a->zone != b->zone)
 
54
                        return (ISC_FALSE);
 
55
                break;
 
56
        default:
 
57
                return (ISC_FALSE);
 
58
        }
 
59
        return (ISC_TRUE);
 
60
}
 
61
 
 
62
isc_boolean_t
 
63
isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b,
 
64
                     unsigned int prefixlen)
 
65
{
 
66
        const unsigned char *pa, *pb;
 
67
        unsigned int ipabytes; /* Length of whole IP address in bytes */
 
68
        unsigned int nbytes;   /* Number of significant whole bytes */
 
69
        unsigned int nbits;    /* Number of significant leftover bits */
 
70
 
 
71
        REQUIRE(a != NULL && b != NULL);
 
72
 
 
73
        if (a->family != b->family)
 
74
                return (ISC_FALSE);
 
75
 
 
76
        if (a->zone != b->zone)
 
77
                return (ISC_FALSE);
 
78
 
 
79
        switch (a->family) {
 
80
        case AF_INET:
 
81
                pa = (const unsigned char *) &a->type.in;
 
82
                pb = (const unsigned char *) &b->type.in;
 
83
                ipabytes = 4;
 
84
                break;
 
85
        case AF_INET6:
 
86
                pa = (const unsigned char *) &a->type.in6;
 
87
                pb = (const unsigned char *) &b->type.in6;
 
88
                ipabytes = 16;
 
89
                break;
 
90
        default:
 
91
                pa = pb = NULL; /* Avoid silly compiler warning. */
 
92
                ipabytes = 0; /* Ditto. */
 
93
                return (ISC_FALSE);
 
94
        }
 
95
 
 
96
        /*
 
97
         * Don't crash if we get a pattern like 10.0.0.1/9999999.
 
98
         */
 
99
        if (prefixlen > ipabytes * 8)
 
100
                prefixlen = ipabytes * 8;
 
101
 
 
102
        nbytes = prefixlen / 8;
 
103
        nbits = prefixlen % 8;
 
104
 
 
105
        if (nbytes > 0) {
 
106
                if (memcmp(pa, pb, nbytes) != 0)
 
107
                        return (ISC_FALSE);
 
108
        }
 
109
        if (nbits > 0) {
 
110
                unsigned int bytea, byteb, mask;
 
111
                INSIST(nbytes < ipabytes);
 
112
                INSIST(nbits < 8);
 
113
                bytea = pa[nbytes];
 
114
                byteb = pb[nbytes];
 
115
                mask = (0xFF << (8-nbits)) & 0xFF;
 
116
                if ((bytea & mask) != (byteb & mask))
 
117
                        return (ISC_FALSE);
 
118
        }
 
119
        return (ISC_TRUE);
 
120
}
 
121
 
 
122
isc_result_t
 
123
isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target) {
 
124
        char abuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
 
125
        char zbuf[sizeof("%4294967295")];
 
126
        unsigned int alen;
 
127
        int zlen;
 
128
        const char *r;
 
129
        const void *type;
 
130
 
 
131
        REQUIRE(netaddr != NULL);
 
132
 
 
133
        switch (netaddr->family) {
 
134
        case AF_INET:
 
135
                type = &netaddr->type.in;
 
136
                break;
 
137
        case AF_INET6:
 
138
                type = &netaddr->type.in6;
 
139
                break;
 
140
        default:
 
141
                return (ISC_R_FAILURE);
 
142
        }
 
143
        r = inet_ntop(netaddr->family, type, abuf, sizeof(abuf));
 
144
        if (r == NULL)
 
145
                return (ISC_R_FAILURE);
 
146
 
 
147
        alen = strlen(abuf);
 
148
        INSIST(alen < sizeof(abuf));
 
149
 
 
150
        zlen = 0;
 
151
        if (netaddr->family == AF_INET6 && netaddr->zone != 0) {
 
152
                zlen = snprintf(zbuf, sizeof(zbuf), "%%%u", netaddr->zone);
 
153
                if (zlen < 0)
 
154
                        return (ISC_R_FAILURE);
 
155
                INSIST((unsigned int)zlen < sizeof(zbuf));
 
156
        }
 
157
 
 
158
        if (alen + zlen > isc_buffer_availablelength(target))
 
159
                return (ISC_R_NOSPACE);
 
160
 
 
161
        isc_buffer_putmem(target, (unsigned char *)abuf, alen);
 
162
        isc_buffer_putmem(target, (unsigned char *)zbuf, zlen);
 
163
 
 
164
        return (ISC_R_SUCCESS);
 
165
}
 
166
 
 
167
void
 
168
isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size) {
 
169
        isc_result_t result;
 
170
        isc_buffer_t buf;
 
171
 
 
172
        isc_buffer_init(&buf, array, size);
 
173
        result = isc_netaddr_totext(na, &buf);
 
174
 
 
175
        /*
 
176
         * Null terminate.
 
177
         */
 
178
        if (result == ISC_R_SUCCESS) {
 
179
                if (isc_buffer_availablelength(&buf) >= 1)
 
180
                        isc_buffer_putuint8(&buf, 0);
 
181
                else
 
182
                        result = ISC_R_NOSPACE;
 
183
        }
 
184
 
 
185
        if (result != ISC_R_SUCCESS) {
 
186
                snprintf(array, size,
 
187
                         isc_msgcat_get(isc_msgcat, ISC_MSGSET_NETADDR,
 
188
                                        ISC_MSG_UNKNOWNADDR,
 
189
                                        "<unknown address, family %u>"),
 
190
                         na->family);
 
191
                array[size - 1] = '\0';
 
192
        }
 
193
}
 
194
 
 
195
isc_result_t
 
196
isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp) {
 
197
        unsigned int nbits, nbytes, ipbytes, i;
 
198
        const unsigned char *p;
 
199
 
 
200
        switch (s->family) {
 
201
        case AF_INET:
 
202
                p = (const unsigned char *) &s->type.in;
 
203
                ipbytes = 4;
 
204
                break;
 
205
        case AF_INET6:
 
206
                p = (const unsigned char *) &s->type.in6;
 
207
                ipbytes = 16;
 
208
                break;
 
209
        default:
 
210
                ipbytes = 0;
 
211
                return (ISC_R_NOTIMPLEMENTED);
 
212
        }
 
213
        nbytes = nbits = 0;
 
214
        for (i = 0; i < ipbytes; i++) {
 
215
                if (p[i] != 0xFF)
 
216
                        break;
 
217
        }
 
218
        nbytes = i;
 
219
        if (i < ipbytes) {
 
220
                unsigned int c = p[nbytes];
 
221
                while ((c & 0x80) != 0 && nbits < 8) {
 
222
                        c <<= 1; nbits++;
 
223
                }
 
224
                if ((c & 0xFF) != 0)
 
225
                        return (ISC_R_MASKNONCONTIG);
 
226
                i++;
 
227
        }
 
228
        for (; i < ipbytes; i++) {
 
229
                if (p[i] != 0)
 
230
                        return (ISC_R_MASKNONCONTIG);
 
231
                i++;
 
232
        }
 
233
        *lenp = nbytes * 8 + nbits;
 
234
        return (ISC_R_SUCCESS);
 
235
}
 
236
 
 
237
void
 
238
isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina) {
 
239
        memset(netaddr, 0, sizeof(*netaddr));
 
240
        netaddr->family = AF_INET;
 
241
        netaddr->type.in = *ina;
 
242
}
 
243
 
 
244
void
 
245
isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6) {
 
246
        memset(netaddr, 0, sizeof(*netaddr));
 
247
        netaddr->family = AF_INET6;
 
248
        netaddr->type.in6 = *ina6;
 
249
}
 
250
 
 
251
void
 
252
isc_netaddr_setzone(isc_netaddr_t *netaddr, isc_uint32_t zone) {
 
253
        /* we currently only support AF_INET6. */
 
254
        REQUIRE(netaddr->family == AF_INET6);
 
255
 
 
256
        netaddr->zone = zone;
 
257
}
 
258
 
 
259
isc_uint32_t
 
260
isc_netaddr_getzone(const isc_netaddr_t *netaddr) {
 
261
        return (netaddr->zone);
 
262
}
 
263
 
 
264
void
 
265
isc_netaddr_fromsockaddr(isc_netaddr_t *t, const isc_sockaddr_t *s) {
 
266
        int family = s->type.sa.sa_family;
 
267
        t->family = family;
 
268
        switch (family) {
 
269
        case AF_INET:
 
270
                t->type.in = s->type.sin.sin_addr;
 
271
                t->zone = 0;
 
272
                break;
 
273
        case AF_INET6:
 
274
                memcpy(&t->type.in6, &s->type.sin6.sin6_addr, 16);
 
275
#ifdef ISC_PLATFORM_HAVESCOPEID
 
276
                t->zone = s->type.sin6.sin6_scope_id;
 
277
#else
 
278
                t->zone = 0;
 
279
#endif
 
280
                break;
 
281
        default:
 
282
                INSIST(0);
 
283
        }
 
284
}
 
285
 
 
286
void
 
287
isc_netaddr_any(isc_netaddr_t *netaddr) {
 
288
        memset(netaddr, 0, sizeof(*netaddr));
 
289
        netaddr->family = AF_INET;
 
290
        netaddr->type.in.s_addr = INADDR_ANY;
 
291
}
 
292
 
 
293
#ifdef ISC_PLATFORM_HAVEIPV6
 
294
void
 
295
isc_netaddr_any6(isc_netaddr_t *netaddr) {
 
296
        memset(netaddr, 0, sizeof(*netaddr));
 
297
        netaddr->family = AF_INET6;
 
298
        netaddr->type.in6 = in6addr_any;
 
299
}
 
300
#endif
 
301
 
 
302
isc_boolean_t
 
303
isc_netaddr_ismulticast(isc_netaddr_t *na) {
 
304
        switch (na->family) {
 
305
        case AF_INET:
 
306
                return (ISC_TF(ISC_IPADDR_ISMULTICAST(na->type.in.s_addr)));
 
307
        case AF_INET6:
 
308
                return (ISC_TF(IN6_IS_ADDR_MULTICAST(&na->type.in6)));
 
309
        default:
 
310
                return (ISC_FALSE);  /* XXXMLG ? */
 
311
        }
 
312
}
 
313
 
 
314
isc_boolean_t
 
315
isc_netaddr_isexperimental(isc_netaddr_t *na) {
 
316
        switch (na->family) {
 
317
        case AF_INET:
 
318
                return (ISC_TF(ISC_IPADDR_ISEXPERIMENTAL(na->type.in.s_addr)));
 
319
        default:
 
320
                return (ISC_FALSE);  /* XXXMLG ? */
 
321
        }
 
322
}
 
323
 
 
324
isc_boolean_t
 
325
isc_netaddr_islinklocal(isc_netaddr_t *na) {
 
326
        switch (na->family) {
 
327
        case AF_INET:
 
328
                return (ISC_FALSE);
 
329
        case AF_INET6:
 
330
                return (ISC_TF(IN6_IS_ADDR_LINKLOCAL(&na->type.in6)));
 
331
        default:
 
332
                return (ISC_FALSE);
 
333
        }
 
334
}
 
335
 
 
336
isc_boolean_t
 
337
isc_netaddr_issitelocal(isc_netaddr_t *na) {
 
338
        switch (na->family) {
 
339
        case AF_INET:
 
340
                return (ISC_FALSE);
 
341
        case AF_INET6:
 
342
                return (ISC_TF(IN6_IS_ADDR_SITELOCAL(&na->type.in6)));
 
343
        default:
 
344
                return (ISC_FALSE);
 
345
        }
 
346
}
 
347
 
 
348
#ifdef ISC_PLATFORM_HAVEIPV6
 
349
void
 
350
isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) {
 
351
        isc_netaddr_t *src;
 
352
 
 
353
        DE_CONST(s, src);       /* Must come before IN6_IS_ADDR_V4MAPPED. */
 
354
 
 
355
        REQUIRE(s->family == AF_INET6);
 
356
        REQUIRE(IN6_IS_ADDR_V4MAPPED(&src->type.in6));
 
357
 
 
358
        memset(t, 0, sizeof(*t));
 
359
        t->family = AF_INET;
 
360
        memcpy(&t->type.in, (char *)&src->type.in6 + 12, 4);
 
361
        return;
 
362
}
 
363
#endif