Magellan Linux

Annotation of /trunk/proftpd/patches/proftpd-1.3.0a-ipv6_cidr_warn.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 265 - (hide annotations) (download)
Wed Jul 11 23:16:10 2007 UTC (16 years, 11 months ago) by niro
File size: 11008 byte(s)
- proftpd-1.3.0a-r1

1 niro 265 # ipv6_cidr_warn.dpatch by Francesco Paolo Lovergine <frankie@debian.org>
2    
3     diff -urNad proftpd-1.3.0~/modules/mod_core.c proftpd-1.3.0/modules/mod_core.c
4     --- proftpd-1.3.0~/modules/mod_core.c 2006-05-22 12:27:46.000000000 +0200
5     +++ proftpd-1.3.0/modules/mod_core.c 2006-05-22 12:38:53.000000000 +0200
6     @@ -1025,10 +1025,15 @@
7     if (strcasecmp("all", *(cargv + 1)) == 0 ||
8     strcasecmp("none", *(cargv + 1)) == 0) {
9     pr_netacl_t *acl = pr_netacl_create(cmd->tmp_pool, *(cargv + 1));
10     + if (!acl) {
11     + CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "bad ACL definition '",
12     + *(cargv + 1), "': ", strerror(errno), NULL));
13     + }
14    
15     - if (pr_class_add_acl(acl) < 0)
16     + if (pr_class_add_acl(acl) < 0) {
17     CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error adding rule '",
18     *(cargv + 1), "': ", strerror(errno), NULL));
19     + }
20    
21     cargc = 0;
22     }
23     @@ -1043,18 +1048,24 @@
24    
25     while ((ent = get_token(&str, ",")) != NULL) {
26     if (*ent) {
27     - pr_netacl_t *acl;
28     + pr_netacl_t *acl;
29    
30     - if (strcasecmp(ent, "all") == 0 ||
31     - strcasecmp(ent, "none") == 0) {
32     - cargc = 0;
33     - break;
34     + if (strcasecmp(ent, "all") == 0 ||
35     + strcasecmp(ent, "none") == 0) {
36     + cargc = 0;
37     + break;
38     + }
39     +
40     + acl = pr_netacl_create(cmd->tmp_pool, ent);
41     + if (!acl) {
42     + CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "bad ACL definition '",
43     + *(cargv + 1), "': ", strerror(errno), NULL));
44     }
45    
46     - acl = pr_netacl_create(cmd->tmp_pool, ent);
47     - if (pr_class_add_acl(acl) < 0)
48     - CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error adding rule '", ent,
49     - "': ", strerror(errno), NULL));
50     + if (pr_class_add_acl(acl) < 0) {
51     + CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error adding rule '", ent,
52     + "': ", strerror(errno), NULL));
53     + }
54     }
55     }
56     }
57     @@ -2511,9 +2522,10 @@
58     }
59    
60     acl = pr_netacl_create(c->pool, ent);
61     - if (!acl)
62     - CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "bad ACL definition: '",
63     + if (!acl) {
64     + CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "bad ACL definition '",
65     ent, "': ", strerror(errno), NULL));
66     + }
67    
68     *((pr_netacl_t **) push_array(list)) = acl;
69     }
70     diff -urNad proftpd-1.3.0~/src/netacl.c proftpd-1.3.0/src/netacl.c
71     --- proftpd-1.3.0~/src/netacl.c 2006-05-22 12:27:46.000000000 +0200
72     +++ proftpd-1.3.0/src/netacl.c 2006-05-22 12:38:53.000000000 +0200
73     @@ -1,6 +1,6 @@
74     /*
75     * ProFTPD - FTP server daemon
76     - * Copyright (c) 2003 The ProFTPD Project team
77     + * Copyright (c) 2003-2006 The ProFTPD Project team
78     *
79     * This program is free software; you can redistribute it and/or modify
80     * it under the terms of the GNU General Public License as published by
81     @@ -172,15 +172,20 @@
82    
83     #ifdef PR_USE_IPV6
84     case AF_INET6: {
85     - /* Make sure that the given number of bits is not more than supported
86     - * for IPv6 addresses (128).
87     - */
88     if (acl->masklen > 128) {
89     - errno = EINVAL;
90     - return NULL;
91     - }
92     + errno = EINVAL;
93     + return NULL;
94    
95     - break;
96     + } else if (pr_netaddr_is_v4mappedv6(acl->addr) == TRUE &&
97     + acl->masklen > 32) {
98     +
99     + /* The admin may be trying to use IPv6-style masks on IPv4-mapped
100     + * IPv6 addresses, which of course will not work as expected.
101     + * If the mask is 32 bits or more, warn the admin.
102     + */
103     + pr_log_pri(PR_LOG_WARNING, "warning: possibly using IPv6-style netmask on IPv4-mapped IPv6 address, which will not work as expected");
104     + break;
105     + }
106     }
107     #endif /* PR_USE_IPV6 */
108    
109     diff -urNad proftpd-1.3.0~/src/netaddr.c proftpd-1.3.0/src/netaddr.c
110     --- proftpd-1.3.0~/src/netaddr.c 2005-09-19 23:35:38.000000000 +0200
111     +++ proftpd-1.3.0/src/netaddr.c 2006-05-22 12:38:53.000000000 +0200
112     @@ -1,6 +1,6 @@
113     /*
114     * ProFTPD - FTP server daemon
115     - * Copyright (c) 2003-2005 The ProFTPD Project team
116     + * Copyright (c) 2003-2006 The ProFTPD Project team
117     *
118     * This program is free software; you can redistribute it and/or modify
119     * it under the terms of the GNU General Public License as published by
120     @@ -219,8 +219,7 @@
121     }
122     #endif /* !HAVE_INET_PTON */
123    
124     -#ifdef HAVE_GETHOSTBYNAME2
125     -static void *get_v4inaddr(pr_netaddr_t *na) {
126     +static void *get_v4inaddr(const pr_netaddr_t *na) {
127    
128     /* This function is specifically for IPv4 clients (when gethostbyname2(2) is
129     * present) that have an IPv4-mapped IPv6 address, when performing reverse
130     @@ -234,7 +233,6 @@
131    
132     return (((char *) pr_netaddr_get_inaddr(na)) + 12);
133     }
134     -#endif /* HAVE_GETHOSTBYNAME2 */
135    
136     int pr_netaddr_set_reverse_dns(int enable) {
137     int old_enable = reverse_dns;
138     @@ -652,6 +650,10 @@
139     }
140    
141     int pr_netaddr_cmp(const pr_netaddr_t *na1, const pr_netaddr_t *na2) {
142     + pool *tmp_pool = NULL;
143     + pr_netaddr_t *a, *b;
144     + int res;
145     +
146     if (na1 && !na2)
147     return 1;
148    
149     @@ -662,29 +664,85 @@
150     return 0;
151    
152     if (pr_netaddr_get_family(na1) != pr_netaddr_get_family(na2)) {
153     - /* Cannot compare addresses from different families. */
154     - errno = EINVAL;
155     - return -1;
156     +
157     + /* Cannot compare addresses from different families, unless one
158     + * of the netaddrs has an AF_INET family, and the other has an
159     + * AF_INET6 family AND is an IPv4-mapped IPv6 address.
160     + */
161     +
162     + if (pr_netaddr_is_v4mappedv6(na1) != TRUE &&
163     + pr_netaddr_is_v4mappedv6(na2) != TRUE) {
164     + errno = EINVAL;
165     + return -1;
166     + }
167     +
168     + if (pr_netaddr_is_v4mappedv6(na1) == TRUE) {
169     + tmp_pool = make_sub_pool(permanent_pool);
170     +
171     + /* This case means that na1 is an IPv4-mapped IPv6 address, and
172     + * na2 is an IPv4 address.
173     + */
174     + a = pr_netaddr_alloc(tmp_pool);
175     + pr_netaddr_set_family(a, AF_INET);
176     + pr_netaddr_set_port(a, pr_netaddr_get_port(na1));
177     + memcpy(&a->na_addr.v4.sin_addr, get_v4inaddr(na1),
178     + sizeof(struct in_addr));
179     +
180     + b = (pr_netaddr_t *) na2;
181     +
182     + } else if (pr_netaddr_is_v4mappedv6(na2) == TRUE) {
183     + tmp_pool = make_sub_pool(permanent_pool);
184     +
185     + /* This case means that na is an IPv4 address, and na2 is an
186     + * IPv4-mapped IPv6 address.
187     + */
188     + a = (pr_netaddr_t *) na1;
189     +
190     + b = pr_netaddr_alloc(tmp_pool);
191     + pr_netaddr_set_family(b, AF_INET);
192     + pr_netaddr_set_port(b, pr_netaddr_get_port(na2));
193     + memcpy(&b->na_addr.v4.sin_addr, get_v4inaddr(na2),
194     + sizeof(struct in_addr));
195     +
196     + } else {
197     + a = (pr_netaddr_t *) na1;
198     + b = (pr_netaddr_t *) na2;
199     + }
200     +
201     + } else {
202     + a = (pr_netaddr_t *) na1;
203     + b = (pr_netaddr_t *) na2;
204     }
205    
206     - switch (pr_netaddr_get_family(na1)) {
207     + switch (pr_netaddr_get_family(a)) {
208     case AF_INET:
209     - return memcmp(&na1->na_addr.v4.sin_addr, &na2->na_addr.v4.sin_addr,
210     + res = memcmp(&a->na_addr.v4.sin_addr, &b->na_addr.v4.sin_addr,
211     sizeof(struct in_addr));
212     + if (tmp_pool)
213     + destroy_pool(tmp_pool);
214     + return res;
215    
216     #ifdef PR_USE_IPV6
217     case AF_INET6:
218     - return memcmp(&na1->na_addr.v6.sin6_addr, &na2->na_addr.v6.sin6_addr,
219     + res = memcmp(&a->na_addr.v6.sin6_addr, &b->na_addr.v6.sin6_addr,
220     sizeof(struct in6_addr));
221     + if (tmp_pool);
222     + destroy_pool(tmp_pool);
223     + return res;
224     #endif /* PR_USE_IPV6 */
225     }
226    
227     + if (tmp_pool)
228     + destroy_pool(tmp_pool);
229     +
230     errno = EPERM;
231     return -1;
232     }
233    
234     int pr_netaddr_ncmp(const pr_netaddr_t *na1, const pr_netaddr_t *na2,
235     unsigned int bitlen) {
236     + pool *tmp_pool = NULL;
237     + pr_netaddr_t *a, *b;
238     unsigned int nbytes, nbits;
239     const unsigned char *in1, *in2;
240    
241     @@ -698,12 +756,57 @@
242     return 0;
243    
244     if (pr_netaddr_get_family(na1) != pr_netaddr_get_family(na2)) {
245     - /* Cannot compare addresses from different families. */
246     - errno = EINVAL;
247     - return -1;
248     +
249     + /* Cannot compare addresses from different families, unless one
250     + * of the netaddrs has an AF_INET family, and the other has an
251     + * AF_INET6 family AND is an IPv4-mapped IPv6 address.
252     + */
253     +
254     + if (pr_netaddr_is_v4mappedv6(na1) != TRUE &&
255     + pr_netaddr_is_v4mappedv6(na2) != TRUE) {
256     + errno = EINVAL;
257     + return -1;
258     + }
259     +
260     + if (pr_netaddr_is_v4mappedv6(na1) == TRUE) {
261     + tmp_pool = make_sub_pool(permanent_pool);
262     +
263     + /* This case means that na1 is an IPv4-mapped IPv6 address, and
264     + * na2 is an IPv4 address.
265     + */
266     + a = pr_netaddr_alloc(tmp_pool);
267     + pr_netaddr_set_family(a, AF_INET);
268     + pr_netaddr_set_port(a, pr_netaddr_get_port(na1));
269     + memcpy(&a->na_addr.v4.sin_addr, get_v4inaddr(na1),
270     + sizeof(struct in_addr));
271     +
272     + b = (pr_netaddr_t *) na2;
273     +
274     + } else if (pr_netaddr_is_v4mappedv6(na2) == TRUE) {
275     + tmp_pool = make_sub_pool(permanent_pool);
276     +
277     + /* This case means that na is an IPv4 address, and na2 is an
278     + * IPv4-mapped IPv6 address.
279     + */
280     + a = (pr_netaddr_t *) na1;
281     +
282     + b = pr_netaddr_alloc(tmp_pool);
283     + pr_netaddr_set_family(b, AF_INET);
284     + pr_netaddr_set_port(b, pr_netaddr_get_port(na2));
285     + memcpy(&b->na_addr.v4.sin_addr, get_v4inaddr(na2),
286     + sizeof(struct in_addr));
287     +
288     + } else {
289     + a = (pr_netaddr_t *) na1;
290     + b = (pr_netaddr_t *) na2;
291     + }
292     +
293     + } else {
294     + a = (pr_netaddr_t *) na1;
295     + b = (pr_netaddr_t *) na2;
296     }
297    
298     - switch (pr_netaddr_get_family(na1)) {
299     + switch (pr_netaddr_get_family(a)) {
300     case AF_INET: {
301     /* Make sure that the given number of bits is not more than supported
302     * for IPv4 addresses (32).
303     @@ -736,8 +839,8 @@
304     }
305    
306     /* Retrieve pointers to the contained in_addrs. */
307     - in1 = (const unsigned char *) pr_netaddr_get_inaddr(na1);
308     - in2 = (const unsigned char *) pr_netaddr_get_inaddr(na2);
309     + in1 = (const unsigned char *) pr_netaddr_get_inaddr(a);
310     + in2 = (const unsigned char *) pr_netaddr_get_inaddr(b);
311    
312     /* Determine the number of bytes, and leftover bits, in the given
313     * bit length.
314     @@ -750,8 +853,12 @@
315     int res = memcmp(in1, in2, nbytes);
316    
317     /* No need to continue comparing the addresses if they differ already. */
318     - if (res != 0)
319     + if (res != 0) {
320     + if (tmp_pool)
321     + destroy_pool(tmp_pool);
322     +
323     return res;
324     + }
325     }
326    
327     /* Next, compare the remaining bits in the addresses. */
328     @@ -765,13 +872,22 @@
329     /* Build up a mask covering the bits left to be checked. */
330     mask = (0xff << (8 - nbits)) & 0xff;
331    
332     - if ((in1byte & mask) > (in2byte & mask))
333     + if ((in1byte & mask) > (in2byte & mask)) {
334     + if (tmp_pool)
335     + destroy_pool(tmp_pool);
336     return 1;
337     + }
338    
339     - if ((in1byte & mask) < (in2byte & mask))
340     + if ((in1byte & mask) < (in2byte & mask)) {
341     + if (tmp_pool)
342     + destroy_pool(tmp_pool);
343     return -1;
344     + }
345     }
346    
347     + if (tmp_pool)
348     + destroy_pool(tmp_pool);
349     +
350     /* If we've made it this far, the addresses match, for the given bit
351     * length.
352     */