Contents of /trunk/proftpd/patches/proftpd-1.3.0a-ipv6_cidr_warn.patch
Parent Directory | Revision Log
Revision 265 -
(show annotations)
(download)
Wed Jul 11 23:16:10 2007 UTC (17 years, 3 months ago) by niro
File size: 11008 byte(s)
Wed Jul 11 23:16:10 2007 UTC (17 years, 3 months ago) by niro
File size: 11008 byte(s)
- proftpd-1.3.0a-r1
1 | # 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 | */ |