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

« back to all changes in this revision

Viewing changes to libisc/inet_pton.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) 1996-2003  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
#if defined(LIBC_SCCS) && !defined(lint)
 
19
static char rcsid[] =
 
20
        "$Id: inet_pton.c,v 1.10.2.4.2.1 2004/03/06 08:14:31 marka Exp $";
 
21
#endif /* LIBC_SCCS and not lint */
 
22
 
 
23
#include <config.h>
 
24
 
 
25
#include <errno.h>
 
26
#include <string.h>
 
27
 
 
28
#include <isc/net.h>
 
29
 
 
30
#define NS_INT16SZ       2
 
31
#define NS_INADDRSZ      4
 
32
#define NS_IN6ADDRSZ    16
 
33
 
 
34
/*
 
35
 * WARNING: Don't even consider trying to compile this on a system where
 
36
 * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
 
37
 */
 
38
 
 
39
static int inet_pton4(const char *src, unsigned char *dst);
 
40
static int inet_pton6(const char *src, unsigned char *dst);
 
41
 
 
42
/* int
 
43
 * isc_net_pton(af, src, dst)
 
44
 *      convert from presentation format (which usually means ASCII printable)
 
45
 *      to network format (which is usually some kind of binary format).
 
46
 * return:
 
47
 *      1 if the address was valid for the specified address family
 
48
 *      0 if the address wasn't valid (`dst' is untouched in this case)
 
49
 *      -1 if some other error occurred (`dst' is untouched in this case, too)
 
50
 * author:
 
51
 *      Paul Vixie, 1996.
 
52
 */
 
53
int
 
54
isc_net_pton(int af, const char *src, void *dst) {
 
55
        switch (af) {
 
56
        case AF_INET:
 
57
                return (inet_pton4(src, dst));
 
58
        case AF_INET6:
 
59
                return (inet_pton6(src, dst));
 
60
        default:
 
61
                errno = EAFNOSUPPORT;
 
62
                return (-1);
 
63
        }
 
64
        /* NOTREACHED */
 
65
}
 
66
 
 
67
/* int
 
68
 * inet_pton4(src, dst)
 
69
 *      like inet_aton() but without all the hexadecimal and shorthand.
 
70
 * return:
 
71
 *      1 if `src' is a valid dotted quad, else 0.
 
72
 * notice:
 
73
 *      does not touch `dst' unless it's returning 1.
 
74
 * author:
 
75
 *      Paul Vixie, 1996.
 
76
 */
 
77
static int
 
78
inet_pton4(const char *src, unsigned char *dst) {
 
79
        static const char digits[] = "0123456789";
 
80
        int saw_digit, octets, ch;
 
81
        unsigned char tmp[NS_INADDRSZ], *tp;
 
82
 
 
83
        saw_digit = 0;
 
84
        octets = 0;
 
85
        *(tp = tmp) = 0;
 
86
        while ((ch = *src++) != '\0') {
 
87
                const char *pch;
 
88
 
 
89
                if ((pch = strchr(digits, ch)) != NULL) {
 
90
                        unsigned int new = *tp * 10 + (pch - digits);
 
91
 
 
92
                        if (saw_digit && *tp == 0)
 
93
                                return (0);
 
94
                        if (new > 255)
 
95
                                return (0);
 
96
                        *tp = (unsigned char) new;
 
97
                        if (!saw_digit) {
 
98
                                if (++octets > 4)
 
99
                                        return (0);
 
100
                                saw_digit = 1;
 
101
                        }
 
102
                } else if (ch == '.' && saw_digit) {
 
103
                        if (octets == 4)
 
104
                                return (0);
 
105
                        *++tp = 0;
 
106
                        saw_digit = 0;
 
107
                } else
 
108
                        return (0);
 
109
        }
 
110
        if (octets < 4)
 
111
                return (0);
 
112
        memcpy(dst, tmp, NS_INADDRSZ);
 
113
        return (1);
 
114
}
 
115
 
 
116
/* int
 
117
 * inet_pton6(src, dst)
 
118
 *      convert presentation level address to network order binary form.
 
119
 * return:
 
120
 *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
 
121
 * notice:
 
122
 *      (1) does not touch `dst' unless it's returning 1.
 
123
 *      (2) :: in a full address is silently ignored.
 
124
 * credit:
 
125
 *      inspired by Mark Andrews.
 
126
 * author:
 
127
 *      Paul Vixie, 1996.
 
128
 */
 
129
static int
 
130
inet_pton6(const char *src, unsigned char *dst) {
 
131
        static const char xdigits_l[] = "0123456789abcdef",
 
132
                          xdigits_u[] = "0123456789ABCDEF";
 
133
        unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
 
134
        const char *xdigits, *curtok;
 
135
        int ch, saw_xdigit;
 
136
        unsigned int val;
 
137
 
 
138
        memset((tp = tmp), '\0', NS_IN6ADDRSZ);
 
139
        endp = tp + NS_IN6ADDRSZ;
 
140
        colonp = NULL;
 
141
        /* Leading :: requires some special handling. */
 
142
        if (*src == ':')
 
143
                if (*++src != ':')
 
144
                        return (0);
 
145
        curtok = src;
 
146
        saw_xdigit = 0;
 
147
        val = 0;
 
148
        while ((ch = *src++) != '\0') {
 
149
                const char *pch;
 
150
 
 
151
                if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
 
152
                        pch = strchr((xdigits = xdigits_u), ch);
 
153
                if (pch != NULL) {
 
154
                        val <<= 4;
 
155
                        val |= (pch - xdigits);
 
156
                        if (val > 0xffff)
 
157
                                return (0);
 
158
                        saw_xdigit = 1;
 
159
                        continue;
 
160
                }
 
161
                if (ch == ':') {
 
162
                        curtok = src;
 
163
                        if (!saw_xdigit) {
 
164
                                if (colonp)
 
165
                                        return (0);
 
166
                                colonp = tp;
 
167
                                continue;
 
168
                        }
 
169
                        if (tp + NS_INT16SZ > endp)
 
170
                                return (0);
 
171
                        *tp++ = (unsigned char) ((val >> 8) & 0xff);
 
172
                        *tp++ = (unsigned char) (val & 0xff);
 
173
                        saw_xdigit = 0;
 
174
                        val = 0;
 
175
                        continue;
 
176
                }
 
177
                if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
 
178
                    inet_pton4(curtok, tp) > 0) {
 
179
                        tp += NS_INADDRSZ;
 
180
                        saw_xdigit = 0;
 
181
                        break;  /* '\0' was seen by inet_pton4(). */
 
182
                }
 
183
                return (0);
 
184
        }
 
185
        if (saw_xdigit) {
 
186
                if (tp + NS_INT16SZ > endp)
 
187
                        return (0);
 
188
                *tp++ = (unsigned char) ((val >> 8) & 0xff);
 
189
                *tp++ = (unsigned char) (val & 0xff);
 
190
        }
 
191
        if (colonp != NULL) {
 
192
                /*
 
193
                 * Since some memmove()'s erroneously fail to handle
 
194
                 * overlapping regions, we'll do the shift by hand.
 
195
                 */
 
196
                const int n = tp - colonp;
 
197
                int i;
 
198
 
 
199
                if (tp == endp)
 
200
                        return (0);
 
201
                for (i = 1; i <= n; i++) {
 
202
                        endp[- i] = colonp[n - i];
 
203
                        colonp[n - i] = 0;
 
204
                }
 
205
                tp = endp;
 
206
        }
 
207
        if (tp != endp)
 
208
                return (0);
 
209
        memcpy(dst, tmp, NS_IN6ADDRSZ);
 
210
        return (1);
 
211
}