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