Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 265 - (show annotations) (download)
Wed Jul 11 23:16:10 2007 UTC (16 years, 10 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 */