]>
Commit | Line | Data |
---|---|---|
1a8ebc7c TO |
1 | diff -urN proftpd-1.2.5/Make.rules.in proftpd-1.2.5.v6/Make.rules.in |
2 | --- proftpd-1.2.5/Make.rules.in Sat Mar 17 21:34:31 2001 | |
3 | +++ proftpd-1.2.5.v6/Make.rules.in Thu Aug 8 21:35:24 2002 | |
4 | @@ -56,18 +56,18 @@ | |
5 | ||
6 | OBJS=main.o timers.o sets.o pool.o regexp.o dirtree.o support.o inet.o \ | |
7 | log.o bindings.o scoreboard.o feat.o netio.o response.o ident.o \ | |
8 | - data.o modules.o auth.o fsio.o mkhome.o | |
9 | + data.o modules.o auth.o fsio.o mkhome.o intoa.o | |
10 | BUILD_OBJS=src/main.o src/timers.o src/sets.o src/pool.o src/regexp.o \ | |
11 | src/dirtree.o src/support.o src/inet.o src/log.o src/bindings.o \ | |
12 | src/scoreboard.o src/feat.o src/netio.o src/response.o \ | |
13 | src/ident.o src/data.o src/modules.o src/auth.o src/fsio.o \ | |
14 | - src/mkhome.o | |
15 | + src/mkhome.o src/intoa.o | |
16 | ||
17 | MODULE_OBJS=@MODULE_OBJS@ | |
18 | BUILD_MODULE_OBJS=@BUILD_MODULE_OBJS@ modules/module_glue.o | |
19 | ||
20 | -FTPCOUNT_OBJS=ftpcount.o scoreboard.o | |
21 | -BUILD_FTPCOUNT_OBJS=utils/ftpcount.o utils/scoreboard.o | |
22 | +FTPCOUNT_OBJS=ftpcount.o scoreboard.o intoa.o | |
23 | +BUILD_FTPCOUNT_OBJS=utils/ftpcount.o utils/scoreboard.o src/intoa.o | |
24 | ||
25 | FTPSHUT_OBJS=ftpshut.o | |
26 | BUILD_FTPSHUT_OBJS=utils/ftpshut.o | |
27 | @@ -75,5 +75,5 @@ | |
28 | FTPTOP_OBJS=ftptop.o scoreboard.o | |
29 | BUILD_FTPTOP_OBJS=utils/ftptop.o utils/scoreboard.o | |
30 | ||
31 | -FTPWHO_OBJS=ftpwho.o scoreboard.o misc.o | |
32 | -BUILD_FTPWHO_OBJS=utils/ftpwho.o utils/scoreboard.o utils/misc.o | |
33 | +FTPWHO_OBJS=ftpwho.o scoreboard.o misc.o intoa.o | |
34 | +BUILD_FTPWHO_OBJS=utils/ftpwho.o utils/scoreboard.o utils/misc.o src/intoa.o | |
35 | diff -urN proftpd-1.2.5/README.IPv6 proftpd-1.2.5.v6/README.IPv6 | |
36 | --- proftpd-1.2.5/README.IPv6 Thu Jan 1 01:00:00 1970 | |
37 | +++ proftpd-1.2.5.v6/README.IPv6 Thu Aug 8 21:35:24 2002 | |
38 | @@ -0,0 +1,23 @@ | |
39 | +FTP Daemon with IPv6 support for PLD GNU/Linux (http://www.pld.org.pl/) | |
40 | + | |
41 | +IPv6 port by Jan Rekorajski <baggins@pld.org.pl> | |
42 | +Note from me: | |
43 | +Proftpd program is an example of How NOT To write networking code. | |
44 | + | |
45 | +Fixes by Arkadiusz Miskiewicz <misiek@pld.org.pl>: | |
46 | +- removed IPv4-mapped hell | |
47 | +- don't duplicate connection code | |
48 | +- fixed EPRT (parsing, address missmatch) | |
49 | +- inet_validate() recognize colon address notation | |
50 | +- "EPSV ALL" support as specified in RFC | |
51 | +- recognize [v6addr]/mask in Class | |
52 | + | |
53 | +Config: | |
54 | +If you want to specify IPv6 addres, you may use '[' ']' | |
55 | +notation ([::1] for example). | |
56 | + | |
57 | +Known Bugs: | |
58 | +- none known | |
59 | + | |
60 | +Todo: | |
61 | +- test fully VirtualHosts and IPv4 <-> IPv6 interoperability | |
62 | diff -urN proftpd-1.2.5/acconfig.h proftpd-1.2.5.v6/acconfig.h | |
63 | --- proftpd-1.2.5/acconfig.h Sat Mar 17 21:34:31 2001 | |
64 | +++ proftpd-1.2.5.v6/acconfig.h Thu Aug 8 21:35:24 2002 | |
65 | @@ -80,6 +80,13 @@ | |
66 | * configure should, we hope <wink>, detect this for you. | |
67 | */ | |
68 | #undef PF_ARGV_TYPE | |
69 | + | |
70 | +/* Define if you want IPv6 support */ | |
71 | +#undef INET6 | |
72 | + | |
73 | +/* Define if you have ss_family field in struct sockaddr_storage */ | |
74 | +#undef HAVE_SS_FAMILY_IN_SS | |
75 | + | |
76 | @TOP@ | |
77 | ||
78 | /* autoheader generated things inserted here. */ | |
79 | diff -urN proftpd-1.2.5/config.h.in proftpd-1.2.5.v6/config.h.in | |
80 | --- proftpd-1.2.5/config.h.in Sun May 12 22:48:54 2002 | |
81 | +++ proftpd-1.2.5.v6/config.h.in Thu Aug 8 21:35:24 2002 | |
82 | @@ -82,6 +82,13 @@ | |
83 | */ | |
84 | #undef PF_ARGV_TYPE | |
85 | ||
86 | +/* Define if you want IPv6 support */ | |
87 | +#undef INET6 | |
88 | + | |
89 | +/* Define if you have ss_family field in struct sockaddr_storage */ | |
90 | +#undef HAVE_SS_FAMILY_IN_SS | |
91 | + | |
92 | + | |
93 | /* Define if using alloca.c. */ | |
94 | #undef C_ALLOCA | |
95 | ||
96 | diff -urN proftpd-1.2.5/configure.in proftpd-1.2.5.v6/configure.in | |
97 | --- proftpd-1.2.5/configure.in Tue May 21 20:26:30 2002 | |
98 | +++ proftpd-1.2.5.v6/configure.in Thu Aug 8 21:35:24 2002 | |
99 | @@ -520,6 +520,45 @@ | |
100 | esac | |
101 | fi | |
102 | ||
103 | +dnl === part for IPv6 support === | |
104 | +AC_MSG_CHECKING([whether to enable ipv6]) | |
105 | +AC_ARG_ENABLE(ipv6, | |
106 | +[ --enable-ipv6 Enable ipv6 support | |
107 | + --disable-ipv6 Disable ipv6 support], | |
108 | +[case "$enableval" in | |
109 | + no) AC_MSG_RESULT(no) | |
110 | + ;; | |
111 | + *) AC_MSG_RESULT(yes) | |
112 | + AC_DEFINE(INET6) | |
113 | + CFLAGS="$CFLAGS -DINET6" | |
114 | + ;; | |
115 | +esac], | |
116 | +AC_TRY_RUN([ /* PF_INET6 avalable check */ | |
117 | +#include <sys/types.h> | |
118 | +#include <sys/socket.h> | |
119 | +main(){if (socket(PF_INET6, SOCK_STREAM, 0) < 0) exit(1); else exit(0);} | |
120 | +],[ AC_MSG_RESULT(yes) | |
121 | + AC_DEFINE(INET6) | |
122 | +],[ AC_MSG_RESULT(no) | |
123 | +],[ AC_MSG_RESULT(unknown) | |
124 | +])) | |
125 | +AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage], | |
126 | + ac_cv_have_ss_family_in_struct_ss, [ | |
127 | + AC_TRY_COMPILE( | |
128 | + [ | |
129 | +#include <sys/types.h> | |
130 | +#include <sys/socket.h> | |
131 | + ], | |
132 | + [ struct sockaddr_storage s; s.ss_family = 1; ], | |
133 | + [ ac_cv_have_ss_family_in_struct_ss="yes" ], | |
134 | + [ ac_cv_have_ss_family_in_struct_ss="no" ], | |
135 | + ) | |
136 | +]) | |
137 | +if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then | |
138 | + AC_DEFINE(HAVE_SS_FAMILY_IN_SS) | |
139 | +fi | |
140 | +dnl === end of part for IPv6 support === | |
141 | + | |
142 | dnl Check for various argv[] replacing functions on various OSs | |
143 | AC_CHECK_FUNCS(setproctitle) | |
144 | AC_CHECK_HEADERS(libutil.h) | |
145 | diff -urN proftpd-1.2.5/contrib/mod_ratio.c proftpd-1.2.5.v6/contrib/mod_ratio.c | |
146 | --- proftpd-1.2.5/contrib/mod_ratio.c Mon May 27 04:31:50 2002 | |
147 | +++ proftpd-1.2.5.v6/contrib/mod_ratio.c Thu Aug 8 21:35:24 2002 | |
148 | @@ -224,8 +224,6 @@ | |
149 | { | |
150 | modret_t *mr = 0; | |
151 | config_rec *c; | |
152 | - char buf[1024] = {'\0'}; | |
153 | - char *mask; | |
154 | char **data; | |
155 | ||
156 | if (!(g.enable = get_param_int (main_server->conf, "Ratios", FALSE) == TRUE)) | |
157 | @@ -256,23 +254,7 @@ | |
158 | c = find_config (main_server->conf, CONF_PARAM, "HostRatio", TRUE); | |
159 | while (c) | |
160 | { | |
161 | - mask = buf; | |
162 | - if (*(char *) c->argv[0] == '.') | |
163 | - { | |
164 | - *mask++ = '*'; | |
165 | - sstrncpy (mask, c->argv[0], sizeof (buf)); | |
166 | - } | |
167 | - else if (*(char *) ((char *) c->argv[0] + (strlen (c->argv[0]) - 1)) == '.') | |
168 | - { | |
169 | - sstrncpy (mask, c->argv[0], sizeof(buf) - 2); | |
170 | - sstrcat(buf, "*", sizeof(buf)); | |
171 | - } | |
172 | - else | |
173 | - sstrncpy (mask, c->argv[0], sizeof (buf)); | |
174 | - | |
175 | - if (!pr_fnmatch (buf, session.c->remote_name, PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) || | |
176 | - !pr_fnmatch (buf, inet_ntoa (*session.c->remote_ipaddr), | |
177 | - PR_FNM_NOESCAPE | PR_FNM_CASEFOLD)) | |
178 | + if (match_ip(session.c->remote_ipaddr, session.c->remote_name, c->argv[0])) | |
179 | { | |
180 | _set_ratios (c->argv[1], c->argv[2], c->argv[3], c->argv[4]); | |
181 | g.rtype = "h"; | |
182 | @@ -436,7 +418,7 @@ | |
183 | snprintf (buf, sizeof(buf), RATIO_STUFFS); | |
184 | log_pri (LOG_NOTICE, "Ratio: %s/%s %s[%s]: %s.", g.user, | |
185 | session.group, session.c->remote_name, | |
186 | - inet_ntoa (*session.c->remote_ipaddr), buf); | |
187 | + INET_NTOA (session.c->remote_ipaddr), buf); | |
188 | } | |
189 | return DECLINED (cmd); | |
190 | } | |
191 | diff -urN proftpd-1.2.5/contrib/mod_sql.c proftpd-1.2.5.v6/contrib/mod_sql.c | |
192 | --- proftpd-1.2.5/contrib/mod_sql.c Sun Jun 9 04:38:27 2002 | |
193 | +++ proftpd-1.2.5.v6/contrib/mod_sql.c Thu Aug 8 21:35:24 2002 | |
194 | @@ -1314,7 +1314,7 @@ | |
195 | break; | |
196 | case 'a': | |
197 | argp = arg; | |
198 | - sstrncpy(argp, inet_ntoa(*session.c->remote_ipaddr), sizeof(arg)); | |
199 | + sstrncpy(argp, INET_NTOA(session.c->remote_ipaddr), sizeof(arg)); | |
200 | break; | |
201 | case 'l': | |
202 | argp = arg; | |
203 | diff -urN proftpd-1.2.5/include/conf.h proftpd-1.2.5.v6/include/conf.h | |
204 | --- proftpd-1.2.5/include/conf.h Wed Sep 26 17:00:33 2001 | |
205 | +++ proftpd-1.2.5.v6/include/conf.h Thu Aug 8 21:35:24 2002 | |
206 | @@ -322,8 +322,6 @@ | |
207 | ||
208 | /* Generic typedefs */ | |
209 | ||
210 | -typedef struct in_addr p_in_addr_t; | |
211 | - | |
212 | #include "pool.h" | |
213 | #include "regexp.h" | |
214 | #include "proftpd.h" | |
215 | @@ -357,4 +355,8 @@ | |
216 | ||
217 | #endif /* __PROFTPD_SUPPORT_LIBRARY */ | |
218 | ||
219 | +#ifdef HAVE_SS_FAMILY_IN_SS | |
220 | +#define __ss_family ss_family | |
221 | +#endif | |
222 | + | |
223 | #endif /* PR_CONF_H */ | |
224 | diff -urN proftpd-1.2.5/include/dirtree.h proftpd-1.2.5.v6/include/dirtree.h | |
225 | --- proftpd-1.2.5/include/dirtree.h Tue May 21 22:47:15 2002 | |
226 | +++ proftpd-1.2.5.v6/include/dirtree.h Thu Aug 8 21:35:24 2002 | |
227 | @@ -59,7 +59,7 @@ | |
228 | ||
229 | int AnonymousGreeting; /* Do not greet until after user login */ | |
230 | ||
231 | - p_in_addr_t *ipaddr; /* Internal address of this server */ | |
232 | + struct sockaddr_storage *ipaddr; /* Internal address of this server */ | |
233 | struct conn_struc *listen; /* Our listening connection */ | |
234 | xaset_t *conf; /* Configuration details */ | |
235 | ||
236 | @@ -201,7 +201,7 @@ | |
237 | config_rec *find_config(xaset_t *, int, const char *, int); | |
238 | void find_config_set_top(config_rec *); | |
239 | int remove_config(xaset_t *, const char *, int); | |
240 | -class_t *find_class(p_in_addr_t *, char *); | |
241 | +class_t *find_class(struct sockaddr_storage *, char *); | |
242 | ||
243 | array_header *parse_group_expression(pool *, int *, char **); | |
244 | array_header *parse_user_expression(pool *, int *, char **); | |
245 | @@ -236,6 +236,6 @@ | |
246 | char *get_context_name(cmd_rec *); | |
247 | int get_boolean(cmd_rec *, int); | |
248 | char *get_full_cmd(cmd_rec *); | |
249 | -int match_ip(p_in_addr_t *, char *, const char *); | |
250 | +int match_ip(struct sockaddr_storage*, char*, const char *); | |
251 | ||
252 | #endif /* __DIRTREE_H */ | |
253 | diff -urN proftpd-1.2.5/include/ftp.h proftpd-1.2.5.v6/include/ftp.h | |
254 | --- proftpd-1.2.5/include/ftp.h Fri May 10 18:52:39 2002 | |
255 | +++ proftpd-1.2.5.v6/include/ftp.h Thu Aug 8 21:35:24 2002 | |
256 | @@ -85,6 +85,8 @@ | |
257 | #define C_MIC "MIC" /* Integrity protected command */ | |
258 | #define C_PBSZ "PBSZ" /* Protection buffer size */ | |
259 | #define C_PROT "PROT" /* Data channel protection level */ | |
260 | +#define C_EPSV "EPSV" /* Extended PASV */ | |
261 | +#define C_EPRT "EPRT" /* Extended PORT */ | |
262 | ||
263 | #define C_ANY "*" /* Special "wildcard" matching command */ | |
264 | ||
265 | @@ -113,6 +115,7 @@ | |
266 | #define R_225 "225" /* Data connection open; no transfer in progress */ | |
267 | #define R_226 "226" /* Closing data connection. File transfer/abort successful */ | |
268 | #define R_227 "227" /* Entering passive mode (h1,h2,h3,h4,p1,p2) */ | |
269 | +#define R_229 "229" /* Entering extended passive mode (|||p|) */ | |
270 | #define R_230 "230" /* User logged in, proceed */ | |
271 | #define R_232 "232" /* User logged in, authorized by security data */ | |
272 | #define R_234 "234" /* Security data exchange complete */ | |
273 | @@ -138,6 +141,7 @@ | |
274 | #define R_502 "502" /* Command not implemented */ | |
275 | #define R_503 "503" /* Bad sequence of commands */ | |
276 | #define R_504 "504" /* Command not implemented for that parameter */ | |
277 | +#define R_522 "522" /* Extended Port Failure - unknown network protocol */ | |
278 | #define R_530 "530" /* Not logged in */ | |
279 | #define R_532 "532" /* Need account for storing files */ | |
280 | #define R_533 "533" /* Integrity protected command required by policy */ | |
281 | diff -urN proftpd-1.2.5/include/inet.h proftpd-1.2.5.v6/include/inet.h | |
282 | --- proftpd-1.2.5/include/inet.h Tue May 21 22:47:15 2002 | |
283 | +++ proftpd-1.2.5.v6/include/inet.h Thu Aug 8 21:35:24 2002 | |
284 | @@ -69,9 +69,9 @@ | |
285 | int rfd,wfd; /* Read and write fds */ | |
286 | pr_netio_stream_t *instrm, *outstrm; /* Input/Output streams */ | |
287 | ||
288 | - p_in_addr_t *remote_ipaddr; /* Remote address of connection */ | |
289 | + struct sockaddr_storage *remote_ipaddr; /* Remote address of connection */ | |
290 | int remote_port; /* Remote port of connection */ | |
291 | - p_in_addr_t *local_ipaddr; /* Local side of connection */ | |
292 | + struct sockaddr_storage *local_ipaddr; /* Local side of connection */ | |
293 | int local_port; /* Local port */ | |
294 | char *remote_name; /* Remote FQDN */ | |
295 | } conn_t; | |
296 | @@ -85,14 +85,16 @@ | |
297 | char *inet_validate(char *); | |
298 | char *inet_gethostname(pool *); | |
299 | char *inet_fqdn(pool *, const char *); | |
300 | -p_in_addr_t *inet_getaddr(pool *, char *); | |
301 | -char *inet_ascii(pool *, p_in_addr_t *); | |
302 | -char *inet_getname(pool *, p_in_addr_t *); | |
303 | +struct sockaddr_storage *inet_getaddr(pool*,char*); | |
304 | +char *inet_ascii(pool*,struct sockaddr_storage*); | |
305 | +char *inet_getname(pool*,struct sockaddr_storage*); | |
306 | conn_t *inet_copy_connection(pool *, conn_t*); | |
307 | +#if 0 | |
308 | int inet_prebind_socket(pool *, p_in_addr_t *, int); | |
309 | -conn_t *inet_create_dup_connection(pool *, xaset_t *, int, p_in_addr_t *); | |
310 | -conn_t *inet_create_connection(pool *, xaset_t *, int, p_in_addr_t *, int, int); | |
311 | -conn_t *inet_create_connection_portrange(pool *, xaset_t *, p_in_addr_t *, | |
312 | +#endif | |
313 | +conn_t *inet_create_dup_connection(pool*,xaset_t*,int,struct sockaddr_storage*); | |
314 | +conn_t *inet_create_connection(pool *, xaset_t *, int, struct sockaddr_storage *, int, int); | |
315 | +conn_t *inet_create_connection_portrange(pool *, xaset_t *, struct sockaddr_storage *, | |
316 | int, int); | |
317 | void inet_close(pool *, conn_t *); | |
318 | void inet_lingering_close(pool *, conn_t *, long); | |
319 | @@ -104,13 +106,19 @@ | |
320 | int inet_listen(pool *, conn_t *, int); | |
321 | int inet_resetlisten(pool *, conn_t *); | |
322 | int inet_accept_nowait(pool *, conn_t *); | |
323 | -int inet_connect(pool *, conn_t *, p_in_addr_t *, int); | |
324 | -int inet_connect_nowait(pool*,conn_t*,p_in_addr_t*,int); | |
325 | +int inet_connect(pool *, conn_t *, struct sockaddr_storage *, int); | |
326 | +int inet_connect_nowait(pool*,conn_t*,struct sockaddr_storage*, int); | |
327 | int inet_get_conn_info(conn_t *, int); | |
328 | conn_t *inet_accept(pool *, conn_t *, conn_t *, int, int, unsigned char); | |
329 | -conn_t *inet_associate(pool *, conn_t *, p_in_addr_t *, | |
330 | - pr_netio_stream_t *, pr_netio_stream_t *, int); | |
331 | -conn_t *inet_openrw(pool *, conn_t *, p_in_addr_t *, int, int, int, int, int); | |
332 | +conn_t *inet_associate(pool *, conn_t *, struct sockaddr_storage *, IOFILE *, IOFILE *, int); | |
333 | +conn_t *inet_openrw(pool *, conn_t *, struct sockaddr_storage *, int, int, int, int); | |
334 | void inet_resolve_ip(pool *, conn_t *); | |
335 | +int inet_address_match(struct sockaddr_storage *cp,struct sockaddr_storage *rp); | |
336 | +int inet_prefix_match(struct sockaddr_storage *cp,struct sockaddr_storage *rp, int prefix); | |
337 | +#ifdef INET6 | |
338 | +char *INET_NTOA(struct sockaddr_storage *ss); | |
339 | +#else | |
340 | +#define INET_NTOA(a) inet_ntoa(((struct sockaddr_in *)(a))->sin_addr) | |
341 | +#endif | |
342 | ||
343 | #endif /* PR_INET_H */ | |
344 | diff -urN proftpd-1.2.5/include/log.h proftpd-1.2.5.v6/include/log.h | |
345 | --- proftpd-1.2.5/include/log.h Tue May 21 22:47:15 2002 | |
346 | +++ proftpd-1.2.5.v6/include/log.h Thu Aug 8 21:35:24 2002 | |
347 | @@ -66,7 +66,7 @@ | |
348 | #define LOG_XFER_MODE 0644 | |
349 | ||
350 | char *fmt_time(time_t); | |
351 | -int log_wtmp(char *, const char *, const char *, p_in_addr_t *); | |
352 | +int log_wtmp(char *, char *, char *, struct sockaddr_storage *); | |
353 | void log_setfacility(int); | |
354 | int log_openfile(const char *, int *, mode_t); | |
355 | int log_opensyslog(const char *); | |
356 | diff -urN proftpd-1.2.5/include/proftpd.h proftpd-1.2.5.v6/include/proftpd.h | |
357 | --- proftpd-1.2.5/include/proftpd.h Tue May 21 22:47:15 2002 | |
358 | +++ proftpd-1.2.5.v6/include/proftpd.h Thu Aug 8 21:35:24 2002 | |
359 | @@ -71,8 +71,8 @@ | |
360 | typedef struct cdir_struc { | |
361 | struct cdir_struc *next; | |
362 | ||
363 | - u_int_32 address; | |
364 | - u_int_32 netmask; | |
365 | + struct sockaddr_storage address; | |
366 | + u_int_32 prefix; | |
367 | class_t *class; | |
368 | } cdir_t; | |
369 | ||
370 | @@ -94,7 +94,7 @@ | |
371 | volatile int sf_flags; /* Session/State flags */ | |
372 | volatile int sp_flags; /* Session/Protection flags */ | |
373 | ||
374 | - p_in_addr_t data_addr; /* Remote data address */ | |
375 | + struct sockaddr_storage data_addr; /* Remote data address */ | |
376 | unsigned short data_port; /* Remote data port */ | |
377 | ||
378 | unsigned char ident_lookups; /* Is RFC931 (ident) protocol used? */ | |
379 | @@ -210,9 +210,11 @@ | |
380 | #define SF_ANON (1 << 5) /* Anonymous (chroot) login */ | |
381 | #define SF_POST_ABORT (1 << 6) /* After abort has occured */ | |
382 | #define SF_PORT (1 << 7) /* Port command given */ | |
383 | +#define SF_EPSV_ALL (1 << 8) /* EPSV ALL command given */ | |
384 | ||
385 | #define SF_ALL (SF_PASSIVE|SF_ABORT|SF_XFER|SF_ASCII| \ | |
386 | - SF_ASCII_OVERRIDE|SF_ANON|SF_POST_ABORT|SF_PORT) | |
387 | + SF_ASCII_OVERRIDE|SF_ANON|SF_POST_ABORT|SF_PORT| \ | |
388 | + SF_EPSV_ALL) | |
389 | ||
390 | /* Session/Protection flags (RFC 2228) */ | |
391 | ||
392 | diff -urN proftpd-1.2.5/include/support.h proftpd-1.2.5.v6/include/support.h | |
393 | --- proftpd-1.2.5/include/support.h Tue May 21 22:47:15 2002 | |
394 | +++ proftpd-1.2.5.v6/include/support.h Thu Aug 8 21:35:24 2002 | |
395 | @@ -98,4 +98,6 @@ | |
396 | char *sstrncpy(char *, const char *, size_t); | |
397 | char *sreplace(pool *, char *, ...); | |
398 | ||
399 | +void mappedtov4(struct sockaddr_storage *); | |
400 | + | |
401 | #endif /* PR_SUPPORT_H */ | |
402 | diff -urN proftpd-1.2.5/modules/mod_auth.c proftpd-1.2.5.v6/modules/mod_auth.c | |
403 | --- proftpd-1.2.5/modules/mod_auth.c Tue May 21 22:47:16 2002 | |
404 | +++ proftpd-1.2.5.v6/modules/mod_auth.c Thu Aug 8 21:35:24 2002 | |
405 | @@ -1210,7 +1210,7 @@ | |
406 | PRIVS_ROOT | |
407 | while((l = log_read_run(NULL)) != NULL) | |
408 | /* Make sure it matches our current server */ | |
409 | - if(l->server_ip.s_addr == main_server->ipaddr->s_addr && | |
410 | + if(inet_address_match(&l->server_ip, main_server->ipaddr) && | |
411 | l->server_port == main_server->ServerPort) { | |
412 | ||
413 | cur++; | |
414 | @@ -1270,11 +1270,11 @@ | |
415 | ||
416 | /* Make sure it matches our current server. | |
417 | */ | |
418 | - if(l->server_ip.s_addr == main_server->ipaddr->s_addr && | |
419 | + if(inet_address_match(&l->server_ip, main_server->ipaddr) && | |
420 | l->server_port == main_server->ServerPort) { | |
421 | if((c && c->config_type == CONF_ANON && !strcmp(l->user, user)) || | |
422 | !c) { | |
423 | - char *s, *d, ip[32] = {'\0'}; | |
424 | + char *s, *d, ip[64] = {'\0'}; | |
425 | int mpos = sizeof(ip) - 1; | |
426 | ||
427 | cur++; | |
428 | @@ -1292,7 +1292,7 @@ | |
429 | ||
430 | /* Count up sessions on a per-host basis. | |
431 | */ | |
432 | - if(!strcmp(ip, inet_ntoa(*session.c->remote_ipaddr))) { | |
433 | + if(!strcmp(ip, INET_NTOA(session.c->remote_ipaddr))) { | |
434 | samehost++; | |
435 | hcur++; | |
436 | } | |
437 | diff -urN proftpd-1.2.5/modules/mod_core.c proftpd-1.2.5.v6/modules/mod_core.c | |
438 | --- proftpd-1.2.5/modules/mod_core.c Tue May 21 22:47:16 2002 | |
439 | +++ proftpd-1.2.5.v6/modules/mod_core.c Thu Aug 8 21:35:24 2002 | |
440 | @@ -63,6 +63,8 @@ | |
441 | { C_REIN, "is not implemented", FALSE }, | |
442 | { C_PORT, "<sp> h1,h2,h3,h4,p1,p2", TRUE }, | |
443 | { C_PASV, "(returns address/port)", TRUE }, | |
444 | + { C_EPRT, "<sp> |proto|addr|port|", TRUE }, | |
445 | + { C_EPSV, "(returns port |||port|)", TRUE }, | |
446 | { C_TYPE, "<sp> type-code (A, I, L 7, L 8)", TRUE }, | |
447 | { C_STRU, "is not implemented (always F)", TRUE }, | |
448 | { C_MODE, "is not implemented (always S)", TRUE }, | |
449 | @@ -401,7 +403,7 @@ | |
450 | ||
451 | MODRET add_masqueradeaddress(cmd_rec *cmd) { | |
452 | config_rec *c = NULL; | |
453 | - p_in_addr_t *masq_addr = NULL; | |
454 | + struct sockaddr_storage *masq_addr = NULL; | |
455 | char masq_ip[80] = {'\0'}; | |
456 | ||
457 | CHECK_ARGS(cmd, 1); | |
458 | @@ -2029,7 +2031,7 @@ | |
459 | ||
460 | if ((c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress", | |
461 | FALSE)) != NULL) { | |
462 | - p_in_addr_t *masq_addr = (p_in_addr_t *) c->argv[0]; | |
463 | + struct sockaddr_storage *masq_addr = (struct sockaddr_storage *) c->argv[0]; | |
464 | serverfqdn = inet_getname(main_server->pool, masq_addr); | |
465 | } | |
466 | ||
467 | @@ -2191,7 +2193,7 @@ | |
468 | MODRET cmd_pasv(cmd_rec *cmd) | |
469 | { | |
470 | union { | |
471 | - p_in_addr_t addr; | |
472 | + struct in_addr addr; | |
473 | unsigned char u[4]; | |
474 | } addr; | |
475 | ||
476 | @@ -2203,8 +2205,16 @@ | |
477 | config_rec *c = NULL; | |
478 | int pasv_min_port,pasv_max_port; | |
479 | ||
480 | + if (session.flags & SF_EPSV_ALL) | |
481 | + return ERROR_MSG(cmd,R_500,"Illegal PASV command - EPSV ALL requested before."); | |
482 | + | |
483 | CHECK_CMD_ARGS(cmd, 1); | |
484 | ||
485 | +#ifdef INET6 | |
486 | + if (session.c->local_ipaddr->__ss_family == AF_INET6) | |
487 | + return ERROR_MSG(cmd,R_425, "PASV over IPv6? Find a real FTP client."); | |
488 | +#endif | |
489 | + | |
490 | /* If we already have a passive listen data connection open, kill it. | |
491 | */ | |
492 | if(session.d) { | |
493 | @@ -2250,14 +2260,16 @@ | |
494 | session.data_port = session.d->local_port; | |
495 | session.flags |= SF_PASSIVE; | |
496 | ||
497 | - addr.addr = *session.d->local_ipaddr; | |
498 | + addr.addr.s_addr = ((struct sockaddr_in *)session.d->local_ipaddr)->sin_addr.s_addr; | |
499 | ||
500 | /* check for a MasqueradeAddress configuration record, and return that | |
501 | * addr if appropriate. | |
502 | */ | |
503 | if ((c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress", | |
504 | - FALSE)) != NULL) | |
505 | - addr.addr = *((p_in_addr_t *) c->argv[0]); | |
506 | + FALSE)) != NULL) { | |
507 | + struct sockaddr_storage *masq_addr = (struct sockaddr_storage *)c->argv[0]; | |
508 | + addr.addr.s_addr = ((struct sockaddr_in *)masq_addr)->sin_addr.s_addr; | |
509 | + } | |
510 | ||
511 | port.port = htons(session.data_port); | |
512 | ||
513 | @@ -2275,7 +2287,7 @@ | |
514 | MODRET cmd_port(cmd_rec *cmd) | |
515 | { | |
516 | union { | |
517 | - p_in_addr_t addr; | |
518 | + struct in_addr addr; | |
519 | unsigned char u[4]; | |
520 | } addr; | |
521 | ||
522 | @@ -2285,11 +2297,19 @@ | |
523 | } port; | |
524 | ||
525 | char *a,*endp,*arg; | |
526 | - int i,cnt = 0; | |
527 | + int p,i,cnt = 0; | |
528 | int allow_foreign_addr = 0; | |
529 | ||
530 | + if (session.flags & SF_EPSV_ALL) | |
531 | + return ERROR_MSG(cmd,R_500,"Illegal PORT command - EPSV ALL requested before."); | |
532 | + | |
533 | CHECK_CMD_ARGS(cmd, 2); | |
534 | ||
535 | +#ifdef INET6 | |
536 | + if (session.c->local_ipaddr->__ss_family == AF_INET6) | |
537 | + return ERROR_MSG(cmd,R_500, "PORT over IPv6? Find a real FTP client."); | |
538 | +#endif | |
539 | + | |
540 | /* Format is h1,h2,h3,h4,p1,p2 (ASCII in network order) */ | |
541 | a = pstrdup(cmd->tmp_pool,cmd->argv[1]); | |
542 | ||
543 | @@ -2322,8 +2342,10 @@ | |
544 | allow_foreign_addr = get_param_int(TOPLEVEL_CONF,"AllowForeignAddress",FALSE); | |
545 | ||
546 | if(allow_foreign_addr != 1) { | |
547 | - if(addr.addr.s_addr != session.c->remote_ipaddr->s_addr || | |
548 | - !port.port) { | |
549 | + | |
550 | + p = ((struct sockaddr_in *)session.c->remote_ipaddr)->sin_addr.s_addr; | |
551 | + | |
552 | + if(addr.addr.s_addr != p || !port.port) { | |
553 | log_pri(LOG_WARNING, "Refused PORT %s (address mismatch).", cmd->arg); | |
554 | return ERROR_MSG(cmd, R_500, "Illegal PORT command."); | |
555 | } | |
556 | @@ -2338,7 +2360,9 @@ | |
557 | return ERROR_MSG(cmd,R_500,"Illegal PORT command."); | |
558 | } | |
559 | ||
560 | - memcpy(&session.data_addr, &addr.addr, sizeof(session.data_addr)); | |
561 | + session.data_addr.__ss_family = AF_INET; | |
562 | + ((struct sockaddr_in *)&session.data_addr)->sin_port = port.port; | |
563 | + ((struct sockaddr_in *)&session.data_addr)->sin_addr.s_addr = addr.addr.s_addr; | |
564 | session.data_port = ntohs(port.port); | |
565 | session.flags &= (SF_ALL^SF_PASSIVE); | |
566 | ||
567 | @@ -2355,6 +2379,207 @@ | |
568 | return HANDLED(cmd); | |
569 | } | |
570 | ||
571 | +MODRET cmd_epsv(cmd_rec *cmd) | |
572 | +{ | |
573 | + char *endp,*arg; | |
574 | + int family; | |
575 | + config_rec *c = NULL; | |
576 | + int pasv_min_port,pasv_max_port; | |
577 | + | |
578 | + CHECK_CMD_MIN_ARGS(cmd, 1); | |
579 | + | |
580 | + arg = pstrdup(cmd->tmp_pool,cmd->argv[1]); | |
581 | + | |
582 | + if (arg) { | |
583 | + if (!strncasecmp(arg, "all", 3)) { | |
584 | + session.flags |= SF_EPSV_ALL; | |
585 | + add_response(R_200, "EPSV ALL command successful."); | |
586 | + return HANDLED(cmd); | |
587 | + } else { | |
588 | + family = strtol(arg, &endp, 10); | |
589 | + if (family == 1) { | |
590 | +#ifdef INET6 | |
591 | + if (!(session.c->local_ipaddr->__ss_family == AF_INET)) | |
592 | + return ERROR_MSG(cmd,R_522,"Illegal EPSV command - IPv4 not supported over this link."); | |
593 | +#endif | |
594 | + } else if (family == 2) { | |
595 | +#ifdef INET6 | |
596 | + if (!(session.c->local_ipaddr->__ss_family == AF_INET6)) | |
597 | +#endif | |
598 | + return ERROR_MSG(cmd,R_522,"Illegal EPSV command - IPv6 not supported over this link."); | |
599 | + } else { | |
600 | + return ERROR_MSG(cmd,R_522,"Illegal EPSV command - unknown network protocol."); | |
601 | + } | |
602 | + } | |
603 | + } | |
604 | + | |
605 | + /* If we already have a passive listen data connection open, | |
606 | + * kill it. | |
607 | + */ | |
608 | + | |
609 | + if(session.d) { | |
610 | + inet_close(session.d->pool,session.d); | |
611 | + session.d = NULL; | |
612 | + } | |
613 | + | |
614 | + if ((c = find_config(main_server->conf, CONF_PARAM, "PassivePorts", FALSE)) != | |
615 | + NULL) { | |
616 | + pasv_min_port = (int)c->argv[0]; | |
617 | + pasv_max_port = (int)c->argv[1]; | |
618 | + | |
619 | + if(!(session.d = inet_create_connection_portrange(session.pool, NULL, | |
620 | + session.c->local_ipaddr, | |
621 | + pasv_min_port,pasv_max_port))) { | |
622 | + /* If not able to open a passive port in the given range, default to | |
623 | + * normal behavior (using INPORT_ANY), and log the failure. This | |
624 | + * indicates a too-small range configuration. | |
625 | + */ | |
626 | + log_pri(LOG_WARNING, "unable to find open port in PassivePorts range " | |
627 | + "%d-%d: defaulting to INPORT_ANY", pasv_min_port, pasv_max_port); | |
628 | + } | |
629 | + } | |
630 | + | |
631 | + | |
632 | + /* Open up the connection and pass it back. | |
633 | + */ | |
634 | + if (!session.d) | |
635 | + session.d = inet_create_connection(session.pool, NULL, -1, | |
636 | + session.c->local_ipaddr, | |
637 | + INPORT_ANY, FALSE); | |
638 | + | |
639 | + if(!session.d) | |
640 | + return ERROR_MSG(cmd,R_425, | |
641 | + "Unable to build data connection: Internal error."); | |
642 | + | |
643 | + inet_setblock(session.pool,session.d); | |
644 | + inet_listen(session.pool,session.d,1); | |
645 | + | |
646 | + session.d->inf = io_open(session.pool,session.d->listen_fd,IO_READ); | |
647 | + | |
648 | + /* Now tell the client our address/port */ | |
649 | + session.data_port = session.d->local_port; | |
650 | + session.flags |= SF_PASSIVE; | |
651 | + | |
652 | + log_debug(DEBUG1,"Entering Extended Passive Mode (|||%u|).", (int)session.data_port); | |
653 | + add_response(R_229, "Entering Extended Passive Mode (|||%u|).", (int)session.data_port); | |
654 | + | |
655 | + return HANDLED(cmd); | |
656 | +} | |
657 | + | |
658 | +MODRET cmd_eprt(cmd_rec *cmd) | |
659 | +{ | |
660 | + struct sockaddr_storage addr; | |
661 | + unsigned short port = 0; | |
662 | + char *a,*endp,*arg; | |
663 | + char delim[2]; | |
664 | + int family,i,cnt = 0; | |
665 | + int allow_foreign_addr = 0; | |
666 | + | |
667 | + if (session.flags & SF_EPSV_ALL) | |
668 | + return ERROR_MSG(cmd,R_500,"Illegal EPRT command - EPSV ALL requested before."); | |
669 | + | |
670 | + CHECK_CMD_ARGS(cmd, 2); | |
671 | + | |
672 | + bzero(&addr, sizeof(struct sockaddr_storage)); | |
673 | + | |
674 | + /* Format is <d>proto<d>ip address<d>port<d> (ASCII in network order) */ | |
675 | + a = pstrdup(cmd->tmp_pool,cmd->argv[1]); | |
676 | + | |
677 | + delim[0] = *a++; | |
678 | + delim[1] = '\0'; | |
679 | + | |
680 | + family = strtol(a, &endp, 10); | |
681 | + if (family == 1) | |
682 | + addr.__ss_family = AF_INET; | |
683 | +#ifdef INET6 | |
684 | + else if (family == 2) | |
685 | + addr.__ss_family = AF_INET6; | |
686 | +#endif | |
687 | + else | |
688 | + return ERROR_MSG(cmd,R_522,"Illegal EPRT command - unknown network protocol."); | |
689 | + | |
690 | + if (!*endp) | |
691 | + return ERROR_MSG(cmd,R_501,"Illegal EPRT command."); | |
692 | + | |
693 | + a = ++endp; | |
694 | + | |
695 | + while(a && *a && cnt < 2) { | |
696 | + arg = strsep(&a,delim); | |
697 | + | |
698 | + if(!arg && a && *a) { | |
699 | + arg = a; | |
700 | + a = NULL; | |
701 | + } else if(!arg) | |
702 | + break; | |
703 | + | |
704 | + if (cnt == 0) { | |
705 | + i = 0; | |
706 | + if (family == 1) | |
707 | + i = inet_pton(AF_INET, arg, &((struct sockaddr_in *)&addr)->sin_addr); | |
708 | +#ifdef INET6 | |
709 | + else | |
710 | + i = inet_pton(AF_INET6, arg, &((struct sockaddr_in6 *)&addr)->sin6_addr); | |
711 | +#endif | |
712 | + if (i == 0) | |
713 | + break; | |
714 | + } else if (cnt == 1) { | |
715 | + i = strtol(arg,&endp,10); | |
716 | + if(*endp || i < 1) | |
717 | + break; | |
718 | + port = (unsigned short)i; | |
719 | + if (family == 1) | |
720 | + ((struct sockaddr_in *)&addr)->sin_port = htons(port); | |
721 | +#ifdef INET6 | |
722 | + else | |
723 | + ((struct sockaddr_in6 *)&addr)->sin6_port = htons(port); | |
724 | +#endif | |
725 | + } else | |
726 | + break; | |
727 | + cnt++; | |
728 | + } | |
729 | + | |
730 | + if(cnt != 2 || (a && *a)) | |
731 | + return ERROR_MSG(cmd,R_501,"Illegal EPRT command."); | |
732 | + | |
733 | + /* Make sure that the address specified matches the address | |
734 | + * that the control connection is coming from. | |
735 | + */ | |
736 | + | |
737 | + allow_foreign_addr = get_param_int(TOPLEVEL_CONF,"AllowForeignAddress",FALSE); | |
738 | + | |
739 | + if(allow_foreign_addr != 1) { | |
740 | + if(!inet_address_match(&addr, session.c->remote_ipaddr) || !port) { | |
741 | + log_pri(LOG_WARNING, "Refused EPRT %s (address mismatch).", cmd->arg); | |
742 | + return ERROR_MSG(cmd, R_500, "Illegal EPRT command."); | |
743 | + } | |
744 | + } | |
745 | + | |
746 | + /* Additionally, make sure that the port number used is a "high | |
747 | + * numbered" port, to avoid bounce attacks | |
748 | + */ | |
749 | + | |
750 | + if(port < 1024) { | |
751 | + log_pri(LOG_WARNING, "Refused EPRT %s (bounce attack).", cmd->arg); | |
752 | + return ERROR_MSG(cmd,R_500,"Illegal EPRT command."); | |
753 | + } | |
754 | + | |
755 | + memcpy(&session.data_addr, &addr, sizeof(struct sockaddr_storage)); | |
756 | + session.data_port = port; | |
757 | + session.flags &= (SF_ALL^SF_PASSIVE); | |
758 | + | |
759 | + /* If we already have a data connection open, kill it. | |
760 | + */ | |
761 | + | |
762 | + if(session.d) { | |
763 | + inet_close(session.d->pool,session.d); | |
764 | + session.d = NULL; | |
765 | + } | |
766 | + | |
767 | + session.flags |= SF_PORT; | |
768 | + add_response(R_200,"EPRT command successful."); | |
769 | + return HANDLED(cmd); | |
770 | +} | |
771 | + | |
772 | MODRET cmd_help(cmd_rec *cmd) | |
773 | { | |
774 | int i,c = 0; | |
775 | @@ -3044,18 +3269,15 @@ | |
776 | return NULL; | |
777 | } | |
778 | ||
779 | -static cdir_t *add_cdir(class_t *class, u_int_32 address, u_int_8 netmask) | |
780 | +static cdir_t *add_cdir(class_t *class, struct sockaddr_storage *address, u_int_32 prefix) | |
781 | { | |
782 | cdir_t *n; | |
783 | ||
784 | n = calloc(1, sizeof(cdir_t)); | |
785 | ||
786 | n->class = class; | |
787 | - while (netmask--) { | |
788 | - n->netmask >>= 1; | |
789 | - n->netmask |= 0x80000000; | |
790 | - } | |
791 | - n->address = address & n->netmask; | |
792 | + n->prefix = prefix; | |
793 | + memcpy(&n->address, address, sizeof(struct sockaddr_storage)); | |
794 | ||
795 | n->next = cdir_list; | |
796 | cdir_list = n; | |
797 | @@ -3063,7 +3285,7 @@ | |
798 | return n; | |
799 | } | |
800 | ||
801 | -static cdir_t *find_cdir(u_int_32 address) | |
802 | +static cdir_t *find_cdir(struct sockaddr_storage *address) | |
803 | { | |
804 | cdir_t *c, *f; | |
805 | ||
806 | @@ -3071,7 +3293,8 @@ | |
807 | f = NULL; | |
808 | while (c) { | |
809 | /* within cdir range ? && more specific netmask ? */ | |
810 | - if (((address & c->netmask) == c->address) && (f == NULL || (f && (f->netmask < c->netmask)))) | |
811 | + if (inet_prefix_match(&c->address, address, c->prefix) && | |
812 | + (f == NULL || (f && (f->prefix < c->prefix)))) | |
813 | f = c; | |
814 | ||
815 | c = c->next; | |
816 | @@ -3108,18 +3331,18 @@ | |
817 | return NULL; | |
818 | } | |
819 | ||
820 | -class_t *find_class(p_in_addr_t *addr, char *remote_name) | |
821 | +class_t *find_class(struct sockaddr_storage *addr, char *remote_name) | |
822 | { | |
823 | cdir_t *ip; | |
824 | hostname_t *host; | |
825 | class_t *c, *f; | |
826 | ||
827 | - if ((ip = find_cdir(ntohl(addr->s_addr))) != NULL) | |
828 | + if ((ip = find_cdir(addr)) != NULL) | |
829 | return ip->class; | |
830 | ||
831 | if ((host = find_hostname(remote_name)) != NULL) | |
832 | return host->class; | |
833 | - if ((host = find_hostname(inet_ntoa(*addr))) != NULL) | |
834 | + if ((host = find_hostname(INET_NTOA(addr))) != NULL) | |
835 | return host->class; | |
836 | ||
837 | c = class_list; | |
838 | @@ -3140,8 +3363,8 @@ | |
839 | { | |
840 | int bits, ret; | |
841 | class_t *n; | |
842 | - p_in_addr_t *res; | |
843 | - char *ptr, ipaddress[20] = {'\0'}, errmsg[80] = {'\0'}; | |
844 | + struct sockaddr_storage *res; | |
845 | + char *ptr, *ptrr, ipaddress[50] = {'\0'}, errmsg[80] = {'\0'}; | |
846 | #if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP) | |
847 | regex_t *preg; | |
848 | #endif | |
849 | @@ -3197,19 +3420,28 @@ | |
850 | CONF_ERROR(cmd, "wrong syntax error."); | |
851 | } else { | |
852 | bits = atol(ptr + 1); | |
853 | - | |
854 | +#ifdef INET6 | |
855 | + if (bits < 0 || bits > 128) { | |
856 | +#else | |
857 | if (bits < 0 || bits > 32) { | |
858 | +#endif | |
859 | log_pri(LOG_ERR, "Class '%s' ipmask %s skipped: wrong netmask.", | |
860 | cmd->argv[1], cmd->argv[3]); | |
861 | } | |
862 | ||
863 | *ptr = 0; | |
864 | } | |
865 | + | |
866 | + if ((ptr = strchr(ipaddress, '[')) && (ptrr = strrchr(ipaddress, ']'))) { | |
867 | + ptr++; | |
868 | + *ptrr = 0; | |
869 | + } else | |
870 | + ptr = ipaddress; | |
871 | ||
872 | - if((res = inet_getaddr(cmd->pool, ipaddress)) != NULL) { | |
873 | - add_cdir(n, ntohl(res->s_addr), bits); | |
874 | - log_debug(DEBUG4, "Class '%s' ipmask %p/%d added.", | |
875 | - cmd->argv[1], res, bits); | |
876 | + if((res = inet_getaddr(cmd->pool, ptr)) != NULL) { | |
877 | + add_cdir(n, res, bits); | |
878 | + log_debug(DEBUG4, "Class '%s' ipmask %s/%d added.", | |
879 | + cmd->argv[1], INET_NTOA(res), bits); | |
880 | } else { | |
881 | log_pri(LOG_ERR, "Class '%s' ip could not parse '%s'.", | |
882 | cmd->argv[1], cmd->argv[3]); | |
883 | @@ -3335,6 +3567,8 @@ | |
884 | { PRE_CMD, "*",G_NONE, regex_filters,FALSE, FALSE, CL_NONE }, | |
885 | #endif | |
886 | { CMD, C_HELP, G_NONE, cmd_help, FALSE, FALSE, CL_INFO }, | |
887 | + { CMD, C_EPRT, G_NONE, cmd_eprt, TRUE, FALSE, CL_MISC }, | |
888 | + { CMD, C_EPSV, G_NONE, cmd_epsv, TRUE, FALSE, CL_MISC }, | |
889 | { CMD, C_PORT, G_NONE, cmd_port, TRUE, FALSE, CL_MISC }, | |
890 | { CMD, C_PASV, G_NONE, cmd_pasv, TRUE, FALSE, CL_MISC }, | |
891 | { CMD, C_SYST, G_NONE, cmd_syst, TRUE, FALSE, CL_INFO }, | |
892 | diff -urN proftpd-1.2.5/modules/mod_log.c proftpd-1.2.5.v6/modules/mod_log.c | |
893 | --- proftpd-1.2.5/modules/mod_log.c Tue May 21 22:47:17 2002 | |
894 | +++ proftpd-1.2.5.v6/modules/mod_log.c Thu Aug 8 21:35:24 2002 | |
895 | @@ -537,7 +537,7 @@ | |
896 | ||
897 | case META_REMOTE_IP: | |
898 | argp = arg; | |
899 | - sstrncpy(argp, inet_ntoa(*session.c->remote_ipaddr), sizeof(arg)); | |
900 | + sstrncpy(argp, INET_NTOA(session.c->remote_ipaddr), sizeof(arg)); | |
901 | m++; | |
902 | break; | |
903 | ||
904 | diff -urN proftpd-1.2.5/src/data.c proftpd-1.2.5.v6/src/data.c | |
905 | --- proftpd-1.2.5/src/data.c Tue May 21 22:47:22 2002 | |
906 | +++ proftpd-1.2.5.v6/src/data.c Thu Aug 8 21:35:24 2002 | |
907 | @@ -230,10 +230,9 @@ | |
908 | ||
909 | if(c) { | |
910 | log_debug(DEBUG4,"active data connection opened - local : %s:%d", | |
911 | - inet_ntoa(*session.d->local_ipaddr), session.d->local_port); | |
912 | + INET_NTOA(session.d->local_ipaddr), session.d->local_port); | |
913 | log_debug(DEBUG4,"active data connection opened - remote : %s:%d", | |
914 | - inet_ntoa(*session.d->remote_ipaddr), | |
915 | - session.d->remote_port); | |
916 | + INET_NTOA(session.d->remote_ipaddr), session.d->remote_port); | |
917 | ||
918 | if(size) { | |
919 | send_response(R_150, | |
920 | diff -urN proftpd-1.2.5/src/dirtree.c proftpd-1.2.5.v6/src/dirtree.c | |
921 | --- proftpd-1.2.5/src/dirtree.c Tue May 21 22:47:22 2002 | |
922 | +++ proftpd-1.2.5.v6/src/dirtree.c Thu Aug 8 21:35:24 2002 | |
923 | @@ -917,13 +917,14 @@ | |
924 | * returns 0 if no match | |
925 | */ | |
926 | ||
927 | -int match_ip(p_in_addr_t *addr, char *name, const char *match) | |
928 | +int match_ip(struct sockaddr_storage *addr, char *name, const char *match) | |
929 | { | |
930 | char buf[1024]; | |
931 | - char *mask,*cp; | |
932 | - int cidr_mode = 0, cidr_bits; | |
933 | - p_in_addr_t cidr_addr; | |
934 | - u_int_32 cidr_mask = 0; | |
935 | + char *bufptr,*cp; | |
936 | + int netmatch = 0; | |
937 | +#ifdef INET6 | |
938 | + struct in6_addr ia6, net6; | |
939 | +#endif /* INET6 */ | |
940 | ||
941 | if(!strcasecmp(match,"ALL")) | |
942 | return 1; | |
943 | @@ -932,55 +933,108 @@ | |
944 | return -1; | |
945 | ||
946 | memset(buf,0,sizeof(buf)); | |
947 | - mask = buf; | |
948 | + bufptr = buf; | |
949 | ||
950 | if(*match == '.') { | |
951 | - *mask++ = '*'; | |
952 | - *mask = '\0'; | |
953 | + *bufptr++ = '*'; | |
954 | + *bufptr = '\0'; | |
955 | sstrcat(buf, match, sizeof(buf)); | |
956 | } else if(*(match + strlen(match) - 1) == '.') { | |
957 | sstrcat(buf, match, sizeof(buf)); | |
958 | sstrcat(buf, "*", sizeof(buf)); | |
959 | - } else if((cp = strchr(match,'/')) != NULL) { /* check for CIDR notation */ | |
960 | - /* first portion of CIDR should be dotted quad, second portion | |
961 | - * is netmask | |
962 | - */ | |
963 | - sstrncpy(buf, match, (cp-match)+1 <= sizeof(buf) ? | |
964 | - (cp-match)+1 : sizeof(buf)); | |
965 | - cidr_bits = atoi(cp+1); | |
966 | - | |
967 | - if(cidr_bits > 0 && cidr_bits < 33) { | |
968 | - int shift = 32 - cidr_bits; | |
969 | - | |
970 | - cidr_mode = 1; | |
971 | - while(cidr_bits--) | |
972 | - cidr_mask = (cidr_mask << 1) | 1; | |
973 | - cidr_mask = cidr_mask << shift; | |
974 | -#ifdef HAVE_INET_ATON | |
975 | - if(inet_aton(mask,&cidr_addr) == 0) | |
976 | - return 0; | |
977 | -#else | |
978 | - cidr_addr.s_addr = inet_addr(mask); | |
979 | -#endif | |
980 | - cidr_addr.s_addr &= htonl(cidr_mask); | |
981 | - } else { | |
982 | - return 0; | |
983 | - } | |
984 | + } else if(*match == '[' && *(match + strlen(match) - 1) == ']') { | |
985 | + sstrcat(buf, match+1, sizeof(buf)); | |
986 | + *(bufptr + strlen(bufptr) - 1) = '\0'; | |
987 | } else { | |
988 | sstrcat(buf, match, sizeof(buf)); | |
989 | } | |
990 | - | |
991 | - if(cidr_mode) { | |
992 | - if((addr->s_addr & htonl(cidr_mask)) == cidr_addr.s_addr) | |
993 | + /* Now match can be one of the following: | |
994 | + * (1) *.domain | |
995 | + * (2) 123.456.* | |
996 | + * (3) 123.456.0.0/16 | |
997 | + * (4) abcd:1234:: | |
998 | + * (5) abcd:1234::dead:beef | |
999 | + * (6) abcd:1234::/32 | |
1000 | + */ | |
1001 | +#ifdef INET6 | |
1002 | + if (addr->__ss_family == AF_INET6) { | |
1003 | + cp = (char *)&((struct sockaddr_in6 *)addr)->sin6_addr; | |
1004 | + } else | |
1005 | +#endif | |
1006 | + cp = (char *)&((struct sockaddr_in *)addr)->sin_addr; | |
1007 | + /* This will catch (1) and (2) */ | |
1008 | + if(pr_fnmatch(buf, name, PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) == 0 || | |
1009 | + pr_fnmatch(buf, INET_NTOA(addr), PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) == 0) | |
1010 | + return 1; | |
1011 | + | |
1012 | + /* This will catch (4) and (5) */ | |
1013 | +#ifdef INET6 | |
1014 | + /* For IPv6, pr_fnmatch() for comparing addresses is | |
1015 | + not working enough. */ | |
1016 | + if (inet_pton(AF_INET6, buf, &net6) == 1) { | |
1017 | + if (name && inet_pton(AF_INET6, name, &ia6) == 1 && | |
1018 | + IN6_ARE_ADDR_EQUAL(&ia6, &net6)) { | |
1019 | return 1; | |
1020 | - } else { | |
1021 | - if(pr_fnmatch(buf, name, PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) == 0 || | |
1022 | - pr_fnmatch(buf, inet_ntoa(*addr), | |
1023 | - PR_FNM_NOESCAPE | PR_FNM_CASEFOLD) == 0) | |
1024 | + } else if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)addr)->sin6_addr, &net6)) { | |
1025 | return 1; | |
1026 | + } | |
1027 | } | |
1028 | - | |
1029 | - return 0; | |
1030 | +#endif | |
1031 | + | |
1032 | + /* And now (3) and (6) */ | |
1033 | + if((cp = strchr(match,'/')) != NULL) { /* check for CIDR notation */ | |
1034 | + /* first portion of CIDR should be dotted quad, second portion | |
1035 | + * is netmask | |
1036 | + */ | |
1037 | + int bits, c, n; | |
1038 | + struct in_addr ia, net; | |
1039 | + unsigned int mask; | |
1040 | + | |
1041 | + *cp = '\0'; | |
1042 | +#ifdef INET6 | |
1043 | + if (addr->__ss_family == AF_INET6) { | |
1044 | + ia.s_addr = INADDR_NONE; | |
1045 | + } else | |
1046 | +#endif | |
1047 | + ia.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; | |
1048 | + net.s_addr = inet_addr(match); | |
1049 | + if (ia.s_addr != (unsigned int)INADDR_NONE && | |
1050 | + net.s_addr != (unsigned int)INADDR_NONE) { | |
1051 | + if (strchr(cp+1, '.') == (char *)NULL) { | |
1052 | + mask = atoi(cp+1); | |
1053 | + for (bits = c = 0; c < mask && c < 32; c++) | |
1054 | + bits |= (1 << (31 - c)); | |
1055 | + mask = htonl(bits); | |
1056 | + } else { | |
1057 | + mask = inet_addr(cp+1); | |
1058 | + } | |
1059 | + if ((ia.s_addr & mask) == (net.s_addr & mask)) | |
1060 | + return 1; | |
1061 | +#ifdef INET6 | |
1062 | + } else if (inet_pton(AF_INET6, buf, &net6) == 1) { | |
1063 | + struct sockaddr_in6 *pia6; | |
1064 | + | |
1065 | + pia6 = (struct sockaddr_in6 *)addr; | |
1066 | + if (strchr(cp+1, ':') == (char *)NULL) { | |
1067 | + mask = atoi(cp+1); | |
1068 | + n = mask / 8; | |
1069 | + bits = mask % 8; | |
1070 | + netmatch = 1; | |
1071 | + for (c = 0; c < n; c++) | |
1072 | + if (pia6->sin6_addr.s6_addr[c] != net6.s6_addr[c]) { | |
1073 | + netmatch = 0; | |
1074 | + break; | |
1075 | + } | |
1076 | + if (netmatch && bits > 0) { | |
1077 | + if ((pia6->sin6_addr.s6_addr[c] & (0xff << (8 - bits))) != | |
1078 | + (net6.s6_addr[c] & (0xff << (8 - bits)))) | |
1079 | + netmatch = 0; | |
1080 | + } | |
1081 | + } | |
1082 | +#endif /* INET6 */ | |
1083 | + } | |
1084 | + } | |
1085 | + return netmatch; | |
1086 | } | |
1087 | ||
1088 | /* As of 1.2.0rc3, a '!' character in front of the IP address | |
1089 | @@ -2513,7 +2567,7 @@ | |
1090 | FALSE)) != NULL) { | |
1091 | log_pri(LOG_INFO, "%s:%d masquerading as %s", | |
1092 | inet_ascii(s->pool, s->ipaddr), s->ServerPort, | |
1093 | - inet_ascii(s->pool, (p_in_addr_t *) c->argv[0])); | |
1094 | + inet_ascii(s->pool, c->argv[0])); | |
1095 | } | |
1096 | ||
1097 | /* honor the DefaultServer directive only if SocketBindTight is not | |
1098 | @@ -2521,7 +2575,11 @@ | |
1099 | */ | |
1100 | if (get_param_int(s->conf, "DefaultServer", FALSE) == 1) { | |
1101 | if (!SocketBindTight) | |
1102 | - s->ipaddr->s_addr = 0; | |
1103 | +#ifdef INET6 | |
1104 | + memcpy(&((struct sockaddr_in6 *)s->ipaddr)->sin6_addr, &in6addr_any, sizeof(struct in6_addr)); | |
1105 | +#else | |
1106 | + ((struct sockaddr_in *)s->ipaddr)->sin_addr = INADDR_ANY; | |
1107 | +#endif | |
1108 | else | |
1109 | log_pri(LOG_NOTICE, | |
1110 | "SocketBindTight in effect, ignoring DefaultServer"); | |
1111 | diff -urN proftpd-1.2.5/src/inet.c proftpd-1.2.5.v6/src/inet.c | |
1112 | --- proftpd-1.2.5/src/inet.c Tue May 21 22:47:22 2002 | |
1113 | +++ proftpd-1.2.5.v6/src/inet.c Thu Aug 8 21:35:31 2002 | |
1114 | @@ -130,7 +130,11 @@ | |
1115 | for(p = buf; p && *p; p++) { | |
1116 | /* Per RFC requirements, these are all that are valid from a DNS. | |
1117 | */ | |
1118 | - if(!isalnum(*p) && *p != '.' && *p != '-') { | |
1119 | + if(!isalnum(*p) && *p != '.' && *p != '-' | |
1120 | +#ifdef INET6 | |
1121 | + && *p != ':' | |
1122 | +#endif | |
1123 | + ) { | |
1124 | /* We set it to _ because we know that's an invalid, yet safe, option | |
1125 | * for a DNS entry. | |
1126 | */ | |
1127 | @@ -175,35 +179,31 @@ | |
1128 | ||
1129 | /* DNS/hosts lookup for a particular name | |
1130 | */ | |
1131 | -p_in_addr_t *inet_getaddr(pool *pool, char *name) | |
1132 | +struct sockaddr_storage *inet_getaddr(pool *pool, char *name) | |
1133 | { | |
1134 | - struct hostent *host; | |
1135 | - p_in_addr_t *res; | |
1136 | + struct addrinfo hints, *res, *res0; | |
1137 | + struct sockaddr_storage *ss; | |
1138 | ||
1139 | - res = (p_in_addr_t*)pcalloc(pool,sizeof(p_in_addr_t)); | |
1140 | + ss = (struct sockaddr_storage*)pcalloc(pool,sizeof(struct sockaddr_storage)); | |
1141 | ||
1142 | - /* Try dotted quad notation first */ | |
1143 | -#ifdef HAVE_INET_ATON | |
1144 | - if(inet_aton(name,res)) | |
1145 | - return res; | |
1146 | -#else | |
1147 | - /* This is a bit unclean, because inet_addr() is obsolete, and | |
1148 | - * returns -1 (255.255.255.255) if the input is invalid. The caller | |
1149 | - * _might_ just be trying to resolve "255.255.255.255", in which case | |
1150 | - * this entire function will fail. Hopefully, you have inet_aton(). | |
1151 | - * <grin> | |
1152 | - */ | |
1153 | - if((res->s_addr = inet_addr(name)) != -1) | |
1154 | - return res; | |
1155 | -#endif | |
1156 | + bzero(&hints, sizeof(hints)); | |
1157 | + hints.ai_family = AF_UNSPEC; | |
1158 | + hints.ai_socktype = SOCK_STREAM; | |
1159 | ||
1160 | - host = gethostbyname(name); | |
1161 | - if(host) { | |
1162 | - memcpy(res, host->h_addr_list[0], sizeof(p_in_addr_t)); | |
1163 | - return res; | |
1164 | + if (getaddrinfo(name, "0", &hints, &res0)) | |
1165 | + return NULL; | |
1166 | + for (res = res0; res; res = res->ai_next) { | |
1167 | + if (res->ai_family == AF_INET | |
1168 | +#ifdef INET6 | |
1169 | + || res->ai_family == AF_INET6 | |
1170 | +#endif | |
1171 | + ) { | |
1172 | + memcpy(ss, res->ai_addr, res->ai_addrlen); | |
1173 | + freeaddrinfo(res0); | |
1174 | + return ss; | |
1175 | + } | |
1176 | } | |
1177 | - | |
1178 | - | |
1179 | + freeaddrinfo(res0); | |
1180 | return NULL; | |
1181 | } | |
1182 | ||
1183 | @@ -211,54 +211,51 @@ | |
1184 | * memory. | |
1185 | */ | |
1186 | ||
1187 | -char *inet_ascii(pool *pool, p_in_addr_t *addr) | |
1188 | +char *inet_ascii(pool *pool, struct sockaddr_storage *ss) | |
1189 | { | |
1190 | + static char buf[1024]; | |
1191 | char *res = NULL; | |
1192 | ||
1193 | - if((res = inet_ntoa(*addr)) != NULL) | |
1194 | - res = pstrdup(pool,res); | |
1195 | + if (getnameinfo((struct sockaddr *)ss, sizeof(struct sockaddr_storage), | |
1196 | + buf, sizeof(buf), NULL, 0, NI_NUMERICHOST)) | |
1197 | + return NULL; | |
1198 | + | |
1199 | + res = pstrdup(pool,buf); | |
1200 | ||
1201 | return res; | |
1202 | } | |
1203 | ||
1204 | /* Given an ip addresses, return the FQDN */ | |
1205 | -char *inet_getname(pool *pool, p_in_addr_t *addr) | |
1206 | +char *inet_getname(pool *pool, struct sockaddr_storage *addr) | |
1207 | { | |
1208 | + static char peername[1024]; | |
1209 | char *res = NULL; | |
1210 | char **checkaddr; | |
1211 | - struct hostent *hptr_rev = NULL, *hptr_forw = NULL; | |
1212 | static char *res_cache = NULL; | |
1213 | - static p_in_addr_t *addr_cache = NULL; | |
1214 | + static struct sockaddr_storage *addr_cache = NULL; | |
1215 | ||
1216 | if(reverse_dns) { | |
1217 | - if(res_cache && addr_cache && addr_cache->s_addr == addr->s_addr) { | |
1218 | + if(res_cache && addr_cache && inet_address_match(addr_cache, addr)) { | |
1219 | res = pstrdup(pool, res_cache); | |
1220 | return inet_validate(res); | |
1221 | } | |
1222 | - | |
1223 | - if((hptr_rev = gethostbyaddr((const char *)addr, | |
1224 | - sizeof(p_in_addr_t), AF_INET)) != NULL) { | |
1225 | - if((hptr_forw = gethostbyname(hptr_rev->h_name)) != NULL) { | |
1226 | - for(checkaddr = hptr_forw->h_addr_list; *checkaddr; ++checkaddr) { | |
1227 | - if(((p_in_addr_t*)(*checkaddr))->s_addr == addr->s_addr) { | |
1228 | - res = pstrdup(pool, hptr_rev->h_name); | |
1229 | - break; | |
1230 | - } | |
1231 | - } | |
1232 | - } | |
1233 | + | |
1234 | + if (getnameinfo((struct sockaddr *)&addr, sizeof(struct sockaddr_storage), | |
1235 | + peername, sizeof(peername), NULL, 0, 0) == 0) { | |
1236 | + res = pstrdup(pool, peername); | |
1237 | } | |
1238 | } | |
1239 | ||
1240 | if(!res) | |
1241 | - res = pstrdup(pool, inet_ntoa(*addr)); | |
1242 | + res = pstrdup(pool, INET_NTOA(addr)); | |
1243 | ||
1244 | if(reverse_dns) { | |
1245 | /* cache the result */ | |
1246 | if(!addr_cache) | |
1247 | - addr_cache = malloc(sizeof(p_in_addr_t)); | |
1248 | + addr_cache = malloc(sizeof(struct sockaddr_storage)); | |
1249 | ||
1250 | if(addr_cache) | |
1251 | - memcpy(addr_cache, addr, sizeof(p_in_addr_t)); | |
1252 | + memcpy(addr_cache, addr, sizeof(struct sockaddr_storage)); | |
1253 | ||
1254 | if(res_cache) | |
1255 | free(res_cache); | |
1256 | @@ -305,12 +302,12 @@ | |
1257 | res->inf = res->outf = NULL; | |
1258 | ||
1259 | if(c->local_ipaddr) { | |
1260 | - res->local_ipaddr = (p_in_addr_t*)palloc(res->pool,sizeof(p_in_addr_t)); | |
1261 | + res->local_ipaddr = (struct sockaddr_storage*)palloc(res->pool,sizeof(struct sockaddr_storage)); | |
1262 | *res->local_ipaddr = *c->local_ipaddr; | |
1263 | } | |
1264 | ||
1265 | if(c->remote_ipaddr) { | |
1266 | - res->remote_ipaddr = (p_in_addr_t*)palloc(res->pool,sizeof(p_in_addr_t)); | |
1267 | + res->remote_ipaddr = (struct sockaddr_storage*)palloc(res->pool,sizeof(struct sockaddr_storage)); | |
1268 | *res->remote_ipaddr = *c->remote_ipaddr; | |
1269 | } | |
1270 | ||
1271 | @@ -396,14 +393,15 @@ | |
1272 | * just for the new connection. | |
1273 | */ | |
1274 | static conn_t *inet_initialize_connection(pool *p, xaset_t *servers, int fd, | |
1275 | - p_in_addr_t *bind_addr, int port, | |
1276 | - int retry_bind, int reporting) | |
1277 | + struct sockaddr_storage *bind_addr, | |
1278 | + int port, int retry_bind, int reporting) | |
1279 | { | |
1280 | pool *subpool; | |
1281 | conn_t *c; | |
1282 | array_header *tmp; | |
1283 | server_rec *s; | |
1284 | - struct sockaddr_in servaddr; | |
1285 | + struct sockaddr_storage servaddr; | |
1286 | + int family; | |
1287 | int i,res = 0, len, one = 1, hold_errno; | |
1288 | ||
1289 | CHECK_INET_POOL; | |
1290 | @@ -414,7 +412,7 @@ | |
1291 | /* Build the accept IPs dynamically using the inet work pool, | |
1292 | * once built, move into the conn struc. | |
1293 | */ | |
1294 | - tmp = make_array(inet_pool, 5, sizeof(p_in_addr_t)); | |
1295 | + tmp = make_array(inet_pool, 5, sizeof(struct sockaddr_storage)); | |
1296 | subpool = make_sub_pool(p); | |
1297 | c = (conn_t *) pcalloc(subpool, sizeof(conn_t)); | |
1298 | c->pool = subpool; | |
1299 | @@ -422,9 +420,9 @@ | |
1300 | if(servers && servers->xas_list) { | |
1301 | for(s = (server_rec *) servers->xas_list; s; s = s->next) | |
1302 | if(s->ipaddr) | |
1303 | - *((p_in_addr_t *) push_array(tmp)) = *s->ipaddr; | |
1304 | + memcpy(((struct sockaddr_storage*)push_array(tmp)), s->ipaddr, sizeof(struct sockaddr_storage)); | |
1305 | } else { | |
1306 | - *((p_in_addr_t *) push_array(tmp)) = *main_server->ipaddr; | |
1307 | + memcpy(((struct sockaddr_storage*)push_array(tmp)), main_server->ipaddr, sizeof(struct sockaddr_storage)); | |
1308 | } | |
1309 | ||
1310 | c->local_port = port; | |
1311 | @@ -436,6 +434,18 @@ | |
1312 | */ | |
1313 | if(fd == -1) { | |
1314 | ||
1315 | + if (bind_addr) | |
1316 | + family = bind_addr->__ss_family; | |
1317 | + else { | |
1318 | +#ifdef INET6 | |
1319 | + if ((fd = socket(AF_INET6, SOCK_STREAM, 0)) != -1) { | |
1320 | + close(fd); | |
1321 | + family = AF_INET6; | |
1322 | + } else | |
1323 | +#endif | |
1324 | + family = AF_INET; | |
1325 | + } | |
1326 | + | |
1327 | /* Certain versions of Solaris apparently require us to be root | |
1328 | * in order to create a socket inside a chroot ?? | |
1329 | */ | |
1330 | @@ -461,7 +471,7 @@ | |
1331 | # endif | |
1332 | #endif | |
1333 | ||
1334 | - fd = socket(AF_INET, SOCK_STREAM, tcp_proto); | |
1335 | + fd = socket(family, SOCK_STREAM, tcp_proto); | |
1336 | ||
1337 | #if defined(SOLARIS2) || defined(FREEBSD2) || defined(FREEBSD3) || \ | |
1338 | defined(FREEBSD4) || defined(__OpenBSD__) || defined(__NetBSD__) || \ | |
1339 | @@ -494,15 +504,28 @@ | |
1340 | ||
1341 | memset(&servaddr, 0, sizeof(servaddr)); | |
1342 | ||
1343 | - servaddr.sin_family = AF_INET; | |
1344 | - | |
1345 | if(bind_addr) | |
1346 | - memcpy(&servaddr.sin_addr, bind_addr, sizeof(servaddr.sin_addr)); | |
1347 | - else | |
1348 | - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); | |
1349 | - | |
1350 | - servaddr.sin_port = htons(port); | |
1351 | + memcpy(&servaddr, bind_addr, sizeof(struct sockaddr_storage)); | |
1352 | + else { | |
1353 | +#ifdef INET6 | |
1354 | + if (family == AF_INET6) | |
1355 | + ((struct sockaddr_in6 *)&servaddr)->sin6_addr = in6addr_any; | |
1356 | + else | |
1357 | +#endif | |
1358 | + ((struct sockaddr_in *)&servaddr)->sin_addr.s_addr = htonl(INADDR_ANY); | |
1359 | + } | |
1360 | ||
1361 | +#ifdef INET6 | |
1362 | + if (family == AF_INET6) { | |
1363 | + ((struct sockaddr_in6 *)&servaddr)->sin6_family = AF_INET6; | |
1364 | + ((struct sockaddr_in6 *)&servaddr)->sin6_port = htons(port); | |
1365 | + } else | |
1366 | +#endif | |
1367 | + { | |
1368 | + ((struct sockaddr_in *)&servaddr)->sin_family = AF_INET; | |
1369 | + ((struct sockaddr_in *)&servaddr)->sin_port = htons(port); | |
1370 | + } | |
1371 | + | |
1372 | if(port != INPORT_ANY && port < 1024) { | |
1373 | block_signals(); | |
1374 | PRIVS_ROOT | |
1375 | @@ -549,7 +572,8 @@ | |
1376 | ||
1377 | if(reporting) { | |
1378 | log_pri(LOG_ERR, "Failed binding to %s, port %d: %s", | |
1379 | - inet_ntoa(servaddr.sin_addr), port, strerror(hold_errno)); | |
1380 | + INET_NTOA((struct sockaddr_storage *)&servaddr), | |
1381 | + port, strerror(hold_errno)); | |
1382 | log_pri(LOG_ERR, "Check the ServerType directive " | |
1383 | "to ensure you are configured correctly."); | |
1384 | } | |
1385 | @@ -571,11 +595,16 @@ | |
1386 | */ | |
1387 | len = sizeof(servaddr); | |
1388 | if(fd >= 0 && getsockname(fd, (struct sockaddr *) &servaddr, &len) != -1) { | |
1389 | + mappedtov4(&servaddr); | |
1390 | if(!c->local_ipaddr) | |
1391 | - c->local_ipaddr = (p_in_addr_t *) pcalloc(c->pool, | |
1392 | - sizeof(p_in_addr_t)); | |
1393 | - *c->local_ipaddr = servaddr.sin_addr; | |
1394 | - c->local_port = ntohs(servaddr.sin_port); | |
1395 | + c->local_ipaddr = (struct sockaddr_storage*)pcalloc(c->pool,sizeof(struct sockaddr_storage)); | |
1396 | + memcpy(c->local_ipaddr, &servaddr, sizeof(struct sockaddr_storage)); | |
1397 | +#ifdef INET6 | |
1398 | + if (servaddr.__ss_family == AF_INET6) | |
1399 | + c->local_port = ntohs(((struct sockaddr_in6 *)&servaddr)->sin6_port); | |
1400 | + else | |
1401 | +#endif | |
1402 | + c->local_port = ntohs(((struct sockaddr_in *)&servaddr)->sin_port); | |
1403 | } | |
1404 | } | |
1405 | ||
1406 | @@ -586,8 +615,8 @@ | |
1407 | } | |
1408 | ||
1409 | conn_t *inet_create_connection(pool *p, xaset_t *servers, int fd, | |
1410 | - p_in_addr_t *bind_addr, int port, | |
1411 | - int retry_bind) | |
1412 | + struct sockaddr_storage *bind_addr, | |
1413 | + int port, int retry_bind) | |
1414 | { | |
1415 | conn_t *c = inet_initialize_connection(p, servers, fd, bind_addr, | |
1416 | port, retry_bind, TRUE); | |
1417 | @@ -607,7 +636,8 @@ | |
1418 | */ | |
1419 | ||
1420 | conn_t *inet_create_connection_portrange(pool *p, xaset_t *servers, | |
1421 | - p_in_addr_t *bind_addr, int low_port, int high_port) | |
1422 | + struct sockaddr_storage *bind_addr, | |
1423 | + int low_port, int high_port) | |
1424 | { | |
1425 | int range_len, index; | |
1426 | int *range, *ports; | |
1427 | @@ -902,20 +932,30 @@ | |
1428 | return 0; | |
1429 | } | |
1430 | ||
1431 | -int inet_connect(pool *pool, conn_t *c, p_in_addr_t *addr, int port) | |
1432 | +int inet_connect(pool *pool, conn_t *c, struct sockaddr_storage *addr, int port) | |
1433 | { | |
1434 | - struct sockaddr_in remaddr; | |
1435 | int ret; | |
1436 | + struct sockaddr_storage remaddr; | |
1437 | ||
1438 | inet_setblock(pool,c); | |
1439 | - remaddr.sin_family = AF_INET; | |
1440 | - remaddr.sin_addr = *addr; | |
1441 | - remaddr.sin_port = htons(port); | |
1442 | - | |
1443 | + memcpy(&remaddr, addr, sizeof(struct sockaddr_storage)); | |
1444 | +#ifdef INET6 | |
1445 | + if (addr->__ss_family == AF_INET6) | |
1446 | + ((struct sockaddr_in6 *)&remaddr)->sin6_port = htons(port); | |
1447 | + else | |
1448 | +#endif | |
1449 | + ((struct sockaddr_in *)&remaddr)->sin_port = htons(port); | |
1450 | + | |
1451 | c->mode = CM_CONNECT; | |
1452 | ||
1453 | - while( (ret = connect(c->listen_fd,(struct sockaddr*)&remaddr,sizeof(remaddr))) == -1 && | |
1454 | - errno == EINTR ) ; | |
1455 | + while( (ret = connect(c->listen_fd,(struct sockaddr*)&remaddr, | |
1456 | +#ifdef INET6 | |
1457 | + (addr->__ss_family == AF_INET) ? | |
1458 | + sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6) | |
1459 | +#else | |
1460 | + sizeof(struct sockaddr_in) | |
1461 | +#endif | |
1462 | + ) == -1) && errno == EINTR ) ; | |
1463 | ||
1464 | if(ret == -1) { | |
1465 | c->mode = CM_ERROR; | |
1466 | @@ -937,18 +977,28 @@ | |
1467 | * called once, and can then be selected for writing. | |
1468 | */ | |
1469 | ||
1470 | -int inet_connect_nowait(pool *pool, conn_t *c, p_in_addr_t *addr, int port) | |
1471 | +int inet_connect_nowait(pool *pool, conn_t *c, struct sockaddr_storage *addr, int port) | |
1472 | { | |
1473 | - struct sockaddr_in remaddr; | |
1474 | + struct sockaddr_storage remaddr; | |
1475 | ||
1476 | inet_setnonblock(pool,c); | |
1477 | - | |
1478 | - remaddr.sin_family = AF_INET; | |
1479 | - remaddr.sin_addr = *addr; | |
1480 | - remaddr.sin_port = htons(port); | |
1481 | + memcpy(&remaddr, addr, sizeof(struct sockaddr_storage)); | |
1482 | +#ifdef INET6 | |
1483 | + if (addr->__ss_family == AF_INET6) | |
1484 | + ((struct sockaddr_in6 *)&remaddr)->sin6_port = htons(port); | |
1485 | + else | |
1486 | +#endif | |
1487 | + ((struct sockaddr_in *)&remaddr)->sin_port = htons(port); | |
1488 | ||
1489 | c->mode = CM_CONNECT; | |
1490 | - if(connect(c->listen_fd,(struct sockaddr*)&remaddr,sizeof(remaddr)) == -1) { | |
1491 | + if(connect(c->listen_fd,(struct sockaddr*)&remaddr, | |
1492 | +#ifdef INET6 | |
1493 | + (addr->__ss_family == AF_INET) ? | |
1494 | + sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6) | |
1495 | +#else | |
1496 | + sizeof(struct sockaddr_in) | |
1497 | +#endif | |
1498 | + ) == -1) { | |
1499 | if(errno != EINPROGRESS && errno != EALREADY) { | |
1500 | c->mode = CM_ERROR; | |
1501 | c->xerrno = errno; | |
1502 | @@ -978,7 +1028,7 @@ | |
1503 | int inet_accept_nowait(pool *pool, conn_t *c) | |
1504 | { | |
1505 | int fd; | |
1506 | - struct sockaddr_in servaddr; | |
1507 | + struct sockaddr_storage servaddr; | |
1508 | int len = sizeof(servaddr); | |
1509 | ||
1510 | if(c->mode == CM_LISTEN) | |
1511 | @@ -1013,7 +1063,7 @@ | |
1512 | int resolve) { | |
1513 | conn_t *res = NULL; | |
1514 | int newfd = -1, allow_foreign_addr = -1; | |
1515 | - struct sockaddr_in addr; | |
1516 | + struct sockaddr_storage addr; | |
1517 | int addrlen = sizeof(addr); | |
1518 | ||
1519 | d->mode = CM_ACCEPT; | |
1520 | @@ -1025,10 +1075,32 @@ | |
1521 | &addrlen)) != -1) { | |
1522 | if((allow_foreign_addr != 1) && | |
1523 | (getpeername(newfd, (struct sockaddr *) &addr, &addrlen) != -1)) { | |
1524 | - if(addr.sin_addr.s_addr != c->remote_ipaddr->s_addr) { | |
1525 | + mappedtov4(&addr); | |
1526 | +#ifdef INET6 | |
1527 | + if (addr.__ss_family == AF_INET6) { | |
1528 | + if (!IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)&addr)->sin6_addr, | |
1529 | + &((struct sockaddr_in6 *)c->remote_ipaddr)->sin6_addr)) { | |
1530 | + log_pri(LOG_NOTICE, | |
1531 | + "SECURITY VIOLATION: Passive connection from %s rejected.", | |
1532 | + INET_NTOA(&addr)); | |
1533 | + close(newfd); | |
1534 | + continue; | |
1535 | + } | |
1536 | + } else | |
1537 | +#endif | |
1538 | + if (addr.__ss_family == AF_INET) { | |
1539 | + if(((struct sockaddr_in *)&addr)->sin_addr.s_addr != | |
1540 | + ((struct sockaddr_in *)c->remote_ipaddr)->sin_addr.s_addr) { | |
1541 | + log_pri(LOG_NOTICE, | |
1542 | + "SECURITY VIOLATION: Passive connection from %s rejected.", | |
1543 | + INET_NTOA(&addr)); | |
1544 | + close(newfd); | |
1545 | + continue; | |
1546 | + } | |
1547 | + } else { | |
1548 | log_pri(LOG_NOTICE, | |
1549 | "SECURITY VIOLATION: Passive connection from %s rejected.", | |
1550 | - inet_ntoa(addr.sin_addr)); | |
1551 | + INET_NTOA(&addr)); | |
1552 | close(newfd); | |
1553 | continue; | |
1554 | } | |
1555 | @@ -1047,7 +1119,7 @@ | |
1556 | } | |
1557 | ||
1558 | int inet_get_conn_info(conn_t *c, int fd) { | |
1559 | - static struct sockaddr_in servaddr; | |
1560 | + static struct sockaddr_storage servaddr; | |
1561 | int len = sizeof(servaddr); | |
1562 | ||
1563 | /* Sanity check. | |
1564 | @@ -1058,21 +1130,33 @@ | |
1565 | } | |
1566 | ||
1567 | if (getsockname(fd, (struct sockaddr *) &servaddr, &len) != -1) { | |
1568 | + mappedtov4(&servaddr); | |
1569 | if (!c->local_ipaddr) | |
1570 | - c->local_ipaddr = (p_in_addr_t *) pcalloc(c->pool, sizeof(p_in_addr_t)); | |
1571 | - *c->local_ipaddr = servaddr.sin_addr; | |
1572 | - c->local_port = ntohs(servaddr.sin_port); | |
1573 | - | |
1574 | + c->local_ipaddr = (struct sockaddr_storage*)pcalloc(c->pool,sizeof(struct sockaddr_storage)); | |
1575 | + memcpy(c->local_ipaddr, &servaddr, sizeof(struct sockaddr_storage)); | |
1576 | +#ifdef INET6 | |
1577 | + if (servaddr.__ss_family == AF_INET6) | |
1578 | + c->local_port = ntohs(((struct sockaddr_in6 *)&servaddr)->sin6_port); | |
1579 | + else | |
1580 | +#endif | |
1581 | + if (servaddr.__ss_family == AF_INET) | |
1582 | + c->local_port = ntohs(((struct sockaddr_in *)&servaddr)->sin_port); | |
1583 | } else | |
1584 | return -1; | |
1585 | ||
1586 | len = sizeof(servaddr); | |
1587 | ||
1588 | if (getpeername(fd, (struct sockaddr *) &servaddr, &len) != -1) { | |
1589 | - c->remote_ipaddr = (p_in_addr_t *) pcalloc(c->pool, sizeof(p_in_addr_t)); | |
1590 | - *c->remote_ipaddr = servaddr.sin_addr; | |
1591 | - c->remote_port = ntohs(servaddr.sin_port); | |
1592 | - | |
1593 | + mappedtov4(&servaddr); | |
1594 | + c->remote_ipaddr = (struct sockaddr_storage*)pcalloc(c->pool,sizeof(struct sockaddr_storage)); | |
1595 | + memcpy(c->remote_ipaddr, &servaddr, sizeof(struct sockaddr_storage)); | |
1596 | +#ifdef INET6 | |
1597 | + if (servaddr.__ss_family == AF_INET6) | |
1598 | + c->remote_port = ntohs(((struct sockaddr_in6 *)&servaddr)->sin6_port); | |
1599 | + else | |
1600 | +#endif | |
1601 | + if (servaddr.__ss_family == AF_INET) | |
1602 | + c->remote_port = ntohs(((struct sockaddr_in *)&servaddr)->sin_port); | |
1603 | } else | |
1604 | return -1; | |
1605 | ||
1606 | @@ -1086,7 +1170,7 @@ | |
1607 | * If resolve is non-zero, the remote address is reverse resolved. | |
1608 | */ | |
1609 | ||
1610 | -conn_t *inet_associate(pool *pool, conn_t *c, p_in_addr_t *addr, | |
1611 | +conn_t *inet_associate(pool *pool, conn_t *c, struct sockaddr_storage *addr, | |
1612 | IOFILE *inf, IOFILE *outf, int resolve) | |
1613 | { | |
1614 | int rfd,wfd; | |
1615 | @@ -1120,15 +1204,15 @@ | |
1616 | ||
1617 | if(addr) { | |
1618 | if(!res->remote_ipaddr) | |
1619 | - res->remote_ipaddr = (p_in_addr_t*)palloc(res->pool,sizeof(p_in_addr_t)); | |
1620 | - *res->remote_ipaddr = *addr; | |
1621 | + res->remote_ipaddr = (struct sockaddr_storage*)palloc(res->pool,sizeof(struct sockaddr_storage)); | |
1622 | + memcpy(res->remote_ipaddr, addr, sizeof(struct sockaddr_storage)); | |
1623 | } | |
1624 | ||
1625 | if(resolve && res->remote_ipaddr) | |
1626 | res->remote_name = inet_getname(res->pool,res->remote_ipaddr); | |
1627 | ||
1628 | if(!res->remote_name) | |
1629 | - res->remote_name = pstrdup(res->pool,inet_ntoa(*res->remote_ipaddr)); | |
1630 | + res->remote_name = pstrdup(res->pool,INET_NTOA(res->remote_ipaddr)); | |
1631 | ||
1632 | inet_setoptions(res->pool,res,0,0); | |
1633 | /* inet_setnonblock(res->pool,res); */ | |
1634 | @@ -1152,7 +1236,7 @@ | |
1635 | * Important, do not call any log_* functions from inside of inet_openrw() | |
1636 | * or any functions it calls, as the possibility for fd overwriting occurs. | |
1637 | */ | |
1638 | -conn_t *inet_openrw(pool *pool, conn_t *c, p_in_addr_t *addr, int fd, | |
1639 | +conn_t *inet_openrw(pool *pool, conn_t *c, struct sockaddr_storage *addr, int fd, | |
1640 | int rfd,int wfd, int resolve) | |
1641 | { | |
1642 | conn_t *res = NULL; | |
1643 | @@ -1172,15 +1256,15 @@ | |
1644 | ||
1645 | if (addr) { | |
1646 | if (!res->remote_ipaddr) | |
1647 | - res->remote_ipaddr = (p_in_addr_t*)palloc(res->pool,sizeof(p_in_addr_t)); | |
1648 | - *res->remote_ipaddr = *addr; | |
1649 | + res->remote_ipaddr = (struct sockaddr_storage*)palloc(res->pool,sizeof(struct sockaddr_storage)); | |
1650 | + memcpy(res->remote_ipaddr, addr, sizeof(struct sockaddr_storage)); | |
1651 | } | |
1652 | ||
1653 | if (resolve && res->remote_ipaddr) | |
1654 | res->remote_name = inet_getname(res->pool,res->remote_ipaddr); | |
1655 | ||
1656 | if (!res->remote_name) | |
1657 | - res->remote_name = pstrdup(res->pool,inet_ntoa(*res->remote_ipaddr)); | |
1658 | + res->remote_name = pstrdup(res->pool,INET_NTOA(res->remote_ipaddr)); | |
1659 | ||
1660 | if (fd == -1 && c->listen_fd != -1) | |
1661 | fd = c->listen_fd; | |
1662 | @@ -1224,6 +1308,127 @@ | |
1663 | return res; | |
1664 | } | |
1665 | ||
1666 | +int inet_address_match(struct sockaddr_storage *cp, | |
1667 | + struct sockaddr_storage *rp) | |
1668 | +{ | |
1669 | + struct sockaddr_in *sin_cp, *sin_rp; | |
1670 | +#ifdef INET6 | |
1671 | + struct sockaddr_in6 *sin6_cp, *sin6_rp; | |
1672 | + | |
1673 | + if (cp->__ss_family == AF_INET6 && rp->__ss_family == AF_INET) { | |
1674 | + sin6_cp = (struct sockaddr_in6 *)cp; | |
1675 | + sin_rp = (struct sockaddr_in *)rp; | |
1676 | + if (IN6_IS_ADDR_V4MAPPED(&sin6_cp->sin6_addr) && | |
1677 | + memcmp(&sin6_cp->sin6_addr.s6_addr[12], &sin_rp->sin_addr.s_addr, | |
1678 | + sizeof(struct in_addr)) == 0) | |
1679 | + return 1; | |
1680 | + else | |
1681 | + return 0; | |
1682 | + } else if (cp->__ss_family == AF_INET && rp->__ss_family == AF_INET6) { | |
1683 | + sin_cp = (struct sockaddr_in *)cp; | |
1684 | + sin6_rp = (struct sockaddr_in6 *)rp; | |
1685 | + if (IN6_IS_ADDR_V4MAPPED(&sin6_rp->sin6_addr) && | |
1686 | + memcmp(&sin6_rp->sin6_addr.s6_addr[12], &sin_cp->sin_addr.s_addr, | |
1687 | + sizeof(struct in_addr)) == 0) | |
1688 | + return 1; | |
1689 | + else | |
1690 | + return 0; | |
1691 | + } | |
1692 | +#endif /* INET6 */ | |
1693 | + if (cp->__ss_family != rp->__ss_family) | |
1694 | + return 0; | |
1695 | + if (cp->__ss_family == AF_INET) { | |
1696 | + sin_cp = (struct sockaddr_in *)cp; | |
1697 | + sin_rp = (struct sockaddr_in *)rp; | |
1698 | + if (sin_cp->sin_addr.s_addr == sin_rp->sin_addr.s_addr) | |
1699 | + return 1; | |
1700 | + else | |
1701 | + return 0; | |
1702 | +#ifdef INET6 | |
1703 | + } else if (cp->__ss_family == AF_INET6) { | |
1704 | + sin6_cp = (struct sockaddr_in6 *)cp; | |
1705 | + sin6_rp = (struct sockaddr_in6 *)rp; | |
1706 | + if (IN6_ARE_ADDR_EQUAL(&sin6_cp->sin6_addr, &sin6_rp->sin6_addr)) | |
1707 | + return 1; | |
1708 | + else | |
1709 | + return 0; | |
1710 | +#endif /* INET6 */ | |
1711 | + } | |
1712 | + return 0; | |
1713 | +} | |
1714 | + | |
1715 | +int inet_prefix_match(struct sockaddr_storage *cp, | |
1716 | + struct sockaddr_storage *rp, int prefix) | |
1717 | +{ | |
1718 | + u_int_32 netmask = 0; | |
1719 | + struct sockaddr_in *sin_cp, *sin_rp; | |
1720 | + struct in_addr cp4, rp4; | |
1721 | +#ifdef INET6 | |
1722 | + struct sockaddr_in6 *sin6_cp, *sin6_rp; | |
1723 | + struct in6_addr cp6, rp6; | |
1724 | + | |
1725 | + if (cp->__ss_family == AF_INET6 && rp->__ss_family == AF_INET) { | |
1726 | + sin6_cp = (struct sockaddr_in6 *)cp; | |
1727 | + sin_rp = (struct sockaddr_in *)rp; | |
1728 | + if (IN6_IS_ADDR_V4MAPPED(&sin6_cp->sin6_addr)) { | |
1729 | + if (prefix > 32) prefix = 32; | |
1730 | + while (prefix--) { netmask >>= 1; netmask |= 0x80000000; } | |
1731 | + cp4.s_addr = ntohl(sin6_cp->sin6_addr.s6_addr32[3]) & netmask; | |
1732 | + rp4.s_addr = ntohl(sin_rp->sin_addr.s_addr) & netmask; | |
1733 | + if (cp4.s_addr == rp4.s_addr) | |
1734 | + return 1; | |
1735 | + else | |
1736 | + return 0; | |
1737 | + } else | |
1738 | + return 0; | |
1739 | + } else if (cp->__ss_family == AF_INET && rp->__ss_family == AF_INET6) { | |
1740 | + sin_cp = (struct sockaddr_in *)cp; | |
1741 | + sin6_rp = (struct sockaddr_in6 *)rp; | |
1742 | + if (IN6_IS_ADDR_V4MAPPED(&sin6_rp->sin6_addr)) { | |
1743 | + if (prefix > 32) prefix = 32; | |
1744 | + while (prefix--) { netmask >>= 1; netmask |= 0x80000000; } | |
1745 | + cp4.s_addr = ntohl(sin_cp->sin_addr.s_addr) & netmask; | |
1746 | + rp4.s_addr = ntohl(sin6_rp->sin6_addr.s6_addr32[3]) & netmask; | |
1747 | + if (cp4.s_addr == rp4.s_addr) | |
1748 | + return 1; | |
1749 | + else | |
1750 | + return 0; | |
1751 | + } else | |
1752 | + return 0; | |
1753 | + } | |
1754 | +#endif /* INET6 */ | |
1755 | + if (cp->__ss_family != rp->__ss_family) | |
1756 | + return 0; | |
1757 | + if (cp->__ss_family == AF_INET) { | |
1758 | + if (prefix > 32) prefix = 32; | |
1759 | + while (prefix--) { netmask >>= 1; netmask |= 0x80000000; } | |
1760 | + cp4.s_addr = ntohl(((struct sockaddr_in *)cp)->sin_addr.s_addr) & netmask; | |
1761 | + rp4.s_addr = ntohl(((struct sockaddr_in *)rp)->sin_addr.s_addr) & netmask; | |
1762 | + if (cp4.s_addr == rp4.s_addr) | |
1763 | + return 1; | |
1764 | + else | |
1765 | + return 0; | |
1766 | +#ifdef INET6 | |
1767 | + } else if (cp->__ss_family == AF_INET6) { | |
1768 | + int i,j; | |
1769 | + | |
1770 | + memcpy(&cp6, &((struct sockaddr_in6 *)cp)->sin6_addr, sizeof(struct in6_addr)); | |
1771 | + memcpy(&rp6, &((struct sockaddr_in6 *)rp)->sin6_addr, sizeof(struct in6_addr)); | |
1772 | + for (i=0; i<4; i++) { | |
1773 | + j=0; netmask=0; | |
1774 | + while (prefix && j++<32) { prefix--; netmask >>= 1; netmask |= 0x80000000; } | |
1775 | + cp6.s6_addr32[i] &= htonl(netmask); | |
1776 | + rp6.s6_addr32[i] &= htonl(netmask); | |
1777 | + } | |
1778 | + if (IN6_ARE_ADDR_EQUAL(&cp6, &rp6)) | |
1779 | + return 1; | |
1780 | + else | |
1781 | + return 0; | |
1782 | +#endif /* INET6 */ | |
1783 | + } | |
1784 | + return 0; | |
1785 | +} | |
1786 | + | |
1787 | /* Perform reverse ip dns resolution on an existing | |
1788 | * connection. | |
1789 | */ | |
1790 | @@ -1234,7 +1439,7 @@ | |
1791 | c->remote_name = inet_getname(c->pool,c->remote_ipaddr); | |
1792 | ||
1793 | if(!c->remote_name) | |
1794 | - c->remote_name = pstrdup(c->pool,inet_ntoa(*c->remote_ipaddr)); | |
1795 | + c->remote_name = pstrdup(c->pool,INET_NTOA(c->remote_ipaddr)); | |
1796 | ||
1797 | } | |
1798 | } | |
1799 | diff -urN proftpd-1.2.5/src/intoa.c proftpd-1.2.5.v6/src/intoa.c | |
1800 | --- proftpd-1.2.5/src/intoa.c Thu Jan 1 01:00:00 1970 | |
1801 | +++ proftpd-1.2.5.v6/src/intoa.c Thu Aug 8 21:35:24 2002 | |
1802 | @@ -0,0 +1,40 @@ | |
1803 | +/* | |
1804 | + * ProFTPD - FTP server daemon | |
1805 | + * Copyright (c) 1997, 1998 Public Flood Software | |
1806 | + * Copyright (C) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net> | |
1807 | + * | |
1808 | + * This program is free software; you can redistribute it and/or modify | |
1809 | + * it under the terms of the GNU General Public License as published by | |
1810 | + * the Free Software Foundation; either version 2 of the License, or | |
1811 | + * (at your option) any later version. | |
1812 | + * | |
1813 | + * This program is distributed in the hope that it will be useful, | |
1814 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
1815 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
1816 | + * GNU General Public License for more details. | |
1817 | + * | |
1818 | + * You should have received a copy of the GNU General Public License | |
1819 | + * along with this program; if not, write to the Free Software | |
1820 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | |
1821 | + */ | |
1822 | + | |
1823 | +/* | |
1824 | + * Inet support functions, many wrappers for netdb functions | |
1825 | + */ | |
1826 | + | |
1827 | + | |
1828 | +#include "conf.h" | |
1829 | +#include "privs.h" | |
1830 | + | |
1831 | +#ifdef INET6 | |
1832 | +char *INET_NTOA(struct sockaddr_storage *ss) | |
1833 | +{ | |
1834 | + static char buf[1024]; | |
1835 | + | |
1836 | + if (getnameinfo((struct sockaddr *)ss, sizeof(struct sockaddr_storage), | |
1837 | + buf, sizeof(buf), NULL, 0, NI_NUMERICHOST)) | |
1838 | + strcpy(buf, "0.0.0.0"); | |
1839 | + | |
1840 | + return buf; | |
1841 | +} | |
1842 | +#endif | |
1843 | diff -urN proftpd-1.2.5/src/log.c proftpd-1.2.5.v6/src/log.c | |
1844 | --- proftpd-1.2.5/src/log.c Tue May 21 22:47:22 2002 | |
1845 | +++ proftpd-1.2.5.v6/src/log.c Thu Aug 8 21:35:24 2002 | |
1846 | @@ -434,12 +434,12 @@ | |
1847 | return NULL; | |
1848 | } | |
1849 | ||
1850 | -void log_run_address(const char *remote_name, const p_in_addr_t *remote_ipaddr) | |
1851 | +void log_run_address(const char *remote_name, const struct sockaddr_storage *remote_ipaddr) | |
1852 | { | |
1853 | char buf[LOGBUFFER_SIZE] = {'\0'}; | |
1854 | ||
1855 | snprintf(buf, sizeof(buf), "%s [%s]", | |
1856 | - remote_name, inet_ntoa(*remote_ipaddr)); | |
1857 | + remote_name, INET_NTOA((struct sockaddr_storage *)remote_ipaddr)); | |
1858 | buf[sizeof(buf) - 1] = '\0'; | |
1859 | address = pstrdup(permanent_pool,buf); | |
1860 | } | |
1861 | @@ -459,7 +459,7 @@ | |
1862 | */ | |
1863 | ||
1864 | int log_add_run(pid_t mpid, time_t *idle_since, char *user,char *class, | |
1865 | - p_in_addr_t *server_ip, unsigned short server_port, | |
1866 | + struct sockaddr_storage *server_ip, unsigned short server_port, | |
1867 | unsigned long tx_size, unsigned long tx_done, char *op, ...) | |
1868 | { | |
1869 | logrun_t ent,fent; | |
1870 | @@ -590,7 +590,7 @@ | |
1871 | * but I haven't been able to test them. | |
1872 | */ | |
1873 | ||
1874 | -int log_wtmp(char *line, char *name, char *host, p_in_addr_t *ip) | |
1875 | +int log_wtmp(char *line, char *name, char *host, struct sockaddr_storage *ip) | |
1876 | { | |
1877 | struct stat buf; | |
1878 | struct utmp ut; | |
1879 | @@ -657,8 +657,14 @@ | |
1880 | memset(&ut,0,sizeof(ut)); | |
1881 | #ifdef HAVE_UTMAXTYPE | |
1882 | #ifdef LINUX | |
1883 | - if(ip) | |
1884 | - memcpy(&ut.ut_addr,ip,sizeof(ut.ut_addr)); | |
1885 | + if(ip) { | |
1886 | +#ifdef INET6 | |
1887 | + if (ip->__ss_family == AF_INET6) | |
1888 | + memcpy(&ut.ut_addr_v6,&((struct sockaddr_in6 *)ip)->sin6_addr,sizeof(ut.ut_addr_v6)); | |
1889 | + else | |
1890 | +#endif | |
1891 | + memcpy(&ut.ut_addr,&((struct sockaddr_in *)ip)->sin_addr,sizeof(ut.ut_addr)); | |
1892 | + } | |
1893 | #else | |
1894 | sstrncpy(ut.ut_id,"ftp",sizeof(ut.ut_id)); | |
1895 | ut.ut_exit.e_termination = 0; | |
1896 | @@ -835,7 +841,7 @@ | |
1897 | if(session.c && session.c->remote_name) { | |
1898 | snprintf(serverinfo + strlen(serverinfo), | |
1899 | sizeof(serverinfo) - strlen(serverinfo), " (%s[%s])", | |
1900 | - session.c->remote_name, inet_ntoa(*session.c->remote_ipaddr)); | |
1901 | + session.c->remote_name, INET_NTOA(session.c->remote_ipaddr)); | |
1902 | serverinfo[sizeof(serverinfo) - 1] = '\0'; | |
1903 | } | |
1904 | } | |
1905 | diff -urN proftpd-1.2.5/src/main.c proftpd-1.2.5.v6/src/main.c | |
1906 | --- proftpd-1.2.5/src/main.c Tue May 21 22:47:23 2002 | |
1907 | +++ proftpd-1.2.5.v6/src/main.c Thu Aug 8 21:35:24 2002 | |
1908 | @@ -108,7 +108,7 @@ | |
1909 | struct _binding *next; | |
1910 | ||
1911 | server_rec *server; /* server to handle request */ | |
1912 | - p_in_addr_t ipaddr; /* ip address "bound" to */ | |
1913 | + struct sockaddr_storage ipaddr; /* ip address "bound" to */ | |
1914 | int port; | |
1915 | conn_t *listen; /* listen connection (if separate) */ | |
1916 | char isdefault; /* if default connection */ | |
1917 | @@ -158,17 +158,17 @@ | |
1918 | ||
1919 | char *config_filename = CONFIG_FILE_PATH; | |
1920 | ||
1921 | -int add_binding(server_rec *server, p_in_addr_t *ipaddr, conn_t *listen, | |
1922 | +int add_binding(server_rec *server, struct sockaddr_storage *ipaddr, conn_t *listen, | |
1923 | char isdefault, char islocalhost) | |
1924 | { | |
1925 | binding_t *b; | |
1926 | ||
1927 | for(b = bind_list; b; b=b->next) | |
1928 | - if(b->ipaddr.s_addr == ipaddr->s_addr && | |
1929 | + if(inet_address_match(&b->ipaddr, ipaddr) && | |
1930 | b->port == server->ServerPort) { | |
1931 | /* binding already exists for this IP */ | |
1932 | log_pri(LOG_NOTICE,"cannot bind %s:%d to server '%s', already bound to '%s'.", | |
1933 | - inet_ntoa(*ipaddr),server->ServerPort, | |
1934 | + INET_NTOA(ipaddr),server->ServerPort, | |
1935 | server->ServerName,b->server->ServerName); | |
1936 | return -1; | |
1937 | } | |
1938 | @@ -179,7 +179,7 @@ | |
1939 | b = palloc(bind_pool,sizeof(binding_t)); | |
1940 | b->server = server; | |
1941 | b->port = server->ServerPort; | |
1942 | - b->ipaddr = *ipaddr; | |
1943 | + memcpy(&b->ipaddr, ipaddr, sizeof(struct sockaddr_storage)); | |
1944 | b->listen = listen; | |
1945 | b->isdefault = isdefault; | |
1946 | b->islocalhost = islocalhost; | |
1947 | @@ -190,12 +190,12 @@ | |
1948 | return 0; | |
1949 | } | |
1950 | ||
1951 | -server_rec *find_binding(p_in_addr_t *ipaddr, int port) | |
1952 | +server_rec *find_binding(struct sockaddr_storage *ipaddr, int port) | |
1953 | { | |
1954 | binding_t *b,*local_b = NULL,*default_b = NULL; | |
1955 | ||
1956 | for(b = bind_list; b; b=b->next) { | |
1957 | - if(b->ipaddr.s_addr == ipaddr->s_addr && (!b->port || b->port == port)) | |
1958 | + if(inet_address_match(&b->ipaddr, ipaddr) && (!b->port || b->port == port)) | |
1959 | return b->server; | |
1960 | ||
1961 | if(b->islocalhost) | |
1962 | @@ -206,20 +206,20 @@ | |
1963 | ||
1964 | /* Not found in binding list, so see if it's the loopback address */ | |
1965 | if(local_b) { | |
1966 | - p_in_addr_t loopback,loopmask,tmp; | |
1967 | - | |
1968 | -#ifdef HAVE_INET_ATON | |
1969 | - inet_aton(LOOPBACK_NET,&loopback); | |
1970 | - inet_aton(LOOPBACK_MASK,&loopmask); | |
1971 | -#else | |
1972 | - loopback.s_addr = inet_addr(LOOPBACK_NET); | |
1973 | - loopmask.s_addr = inet_addr(LOOPBACK_MASK); | |
1974 | + struct sockaddr_storage loopback; | |
1975 | + struct sockaddr_in *loopback4 = (struct sockaddr_in *)&loopback; | |
1976 | +#ifdef INET6 | |
1977 | + struct sockaddr_in6 *loopback6 = (struct sockaddr_in6 *)&loopback; | |
1978 | + | |
1979 | + loopback.__ss_family = AF_INET6; | |
1980 | + memcpy(&loopback6->sin6_addr, &in6addr_loopback, sizeof(struct in6_addr)); | |
1981 | + if(inet_address_match(ipaddr, (struct sockaddr_storage *)&loopback) && | |
1982 | + (!local_b->port || port == local_b->port)) | |
1983 | + return local_b->server; | |
1984 | #endif | |
1985 | - loopback.s_addr = ntohl(loopback.s_addr); | |
1986 | - loopmask.s_addr = ntohl(loopmask.s_addr); | |
1987 | - tmp.s_addr = ntohl(ipaddr->s_addr); | |
1988 | - | |
1989 | - if((tmp.s_addr & loopmask.s_addr) == loopback.s_addr && | |
1990 | + loopback.__ss_family = AF_INET; | |
1991 | + loopback4->sin_addr.s_addr = INADDR_LOOPBACK; | |
1992 | + if(inet_address_match(ipaddr, (struct sockaddr_storage *)&loopback) && | |
1993 | (!local_b->port || port == local_b->port)) | |
1994 | return local_b->server; | |
1995 | } | |
1996 | @@ -664,8 +664,8 @@ | |
1997 | if ((c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress", | |
1998 | FALSE)) != NULL) { | |
1999 | ||
2000 | - p_in_addr_t *masq_addr = (p_in_addr_t *) c->argv[0]; | |
2001 | - serveraddress = pstrdup(main_server->pool, inet_ntoa(*masq_addr)); | |
2002 | + struct sockaddr_storage *masq_addr = (struct sockaddr_storage *) c->argv[0]; | |
2003 | + serveraddress = pstrdup(main_server->pool, INET_NTOA(masq_addr)); | |
2004 | } | |
2005 | ||
2006 | time(&now); | |
2007 | @@ -962,7 +962,7 @@ | |
2008 | ||
2009 | set_proc_title("proftpd: connected: %s (%s:%d)", | |
2010 | c->remote_name ? c->remote_name : "?", | |
2011 | - c->remote_ipaddr ? inet_ntoa(*c->remote_ipaddr) : "?", | |
2012 | + c->remote_ipaddr ? INET_NTOA(c->remote_ipaddr) : "?", | |
2013 | c->remote_port ? c->remote_port : 0 | |
2014 | ); | |
2015 | ||
2016 | @@ -972,8 +972,8 @@ | |
2017 | ||
2018 | if ((masq_c = find_config(server->conf, CONF_PARAM, "MasqueradeAddress", | |
2019 | FALSE)) != NULL) { | |
2020 | - p_in_addr_t *masq_addr = (p_in_addr_t *) masq_c->argv[0]; | |
2021 | - serveraddress = pstrdup(server->pool, inet_ntoa(*masq_addr)); | |
2022 | + struct sockaddr_storage *masq_addr = (struct sockaddr_storage *) masq_c->argv[0]; | |
2023 | + serveraddress = pstrdup(server->pool, INET_NTOA(masq_addr)); | |
2024 | } | |
2025 | ||
2026 | display = (char*)get_param_ptr(server->conf,"DisplayConnect",FALSE); | |
2027 | @@ -1482,8 +1482,8 @@ | |
2028 | if ((c = find_config(main_server->conf, CONF_PARAM, "MasqueradeAddress", | |
2029 | FALSE)) != NULL) { | |
2030 | ||
2031 | - p_in_addr_t *masq_addr = (p_in_addr_t *) c->argv[0]; | |
2032 | - serveraddress = pstrdup(main_server->pool, inet_ntoa(*masq_addr)); | |
2033 | + struct sockaddr_storage *masq_addr = (struct sockaddr_storage *) c->argv[0]; | |
2034 | + serveraddress = pstrdup(main_server->pool, INET_NTOA(masq_addr)); | |
2035 | } | |
2036 | ||
2037 | reason = sreplace(permanent_pool,shutmsg, | |
2038 | @@ -1501,7 +1501,7 @@ | |
2039 | ||
2040 | log_auth(LOG_NOTICE, "connection refused (%s) from %s [%s]", | |
2041 | reason, session.c->remote_name, | |
2042 | - inet_ntoa(*session.c->remote_ipaddr)); | |
2043 | + INET_NTOA(session.c->remote_ipaddr)); | |
2044 | ||
2045 | send_response(R_500, | |
2046 | "FTP server shut down (%s) -- please try again later.", | |
2047 | @@ -1532,7 +1532,7 @@ | |
2048 | /* Check config tree for <Limit LOGIN> directives */ | |
2049 | if(!login_check_limits(serv->conf,TRUE,FALSE,&i)) { | |
2050 | log_pri(LOG_NOTICE,"Connection from %s [%s] denied.", | |
2051 | - session.c->remote_name,inet_ntoa(*session.c->remote_ipaddr)); | |
2052 | + session.c->remote_name,INET_NTOA(session.c->remote_ipaddr)); | |
2053 | exit(0); | |
2054 | } | |
2055 | ||
2056 | @@ -1563,10 +1563,10 @@ | |
2057 | init_child_modules(); | |
2058 | ||
2059 | log_debug(DEBUG4,"connected - local : %s:%d", | |
2060 | - inet_ntoa(*session.c->local_ipaddr), | |
2061 | + INET_NTOA(session.c->local_ipaddr), | |
2062 | session.c->local_port); | |
2063 | log_debug(DEBUG4,"connected - remote : %s:%d", | |
2064 | - inet_ntoa(*session.c->remote_ipaddr), | |
2065 | + INET_NTOA(session.c->remote_ipaddr), | |
2066 | session.c->remote_port); | |
2067 | ||
2068 | /* xfer_set_data_port(conn->local_ipaddr,conn->local_port-1); */ | |
2069 | @@ -2172,7 +2172,7 @@ | |
2070 | { | |
2071 | config_rec *c; | |
2072 | conn_t *listen; | |
2073 | - p_in_addr_t *ipaddr; | |
2074 | + struct sockaddr_storage *ipaddr; | |
2075 | ||
2076 | c = find_config(s->conf,CONF_PARAM,"Bind",FALSE); | |
2077 | while(c) { | |
2078 | diff -urN proftpd-1.2.5/src/support.c proftpd-1.2.5.v6/src/support.c | |
2079 | --- proftpd-1.2.5/src/support.c Tue May 21 22:47:23 2002 | |
2080 | +++ proftpd-1.2.5.v6/src/support.c Thu Aug 8 21:35:24 2002 | |
2081 | @@ -902,3 +902,22 @@ | |
2082 | ||
2083 | return dest; | |
2084 | } | |
2085 | + | |
2086 | +/* convert IPv4-mapped to real IPv4 struct */ | |
2087 | +void mappedtov4( struct sockaddr_storage *ss ) | |
2088 | +{ | |
2089 | + struct sockaddr_in sin; | |
2090 | + struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss; | |
2091 | + if (ss->__ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) { | |
2092 | + memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12, | |
2093 | + sizeof(sin.sin_addr)); | |
2094 | + sin.sin_port = ((struct sockaddr_in6 *)ss)->sin6_port; | |
2095 | + sin.sin_family = AF_INET; | |
2096 | +#ifdef SIN6_LEN | |
2097 | + sin.sin_len = sizeof(struct sockaddr_in); | |
2098 | +#endif | |
2099 | + memset(ss, 0, sizeof(struct sockaddr_storage)); | |
2100 | + memcpy(ss, &sin, sizeof(sin)); | |
2101 | + } | |
2102 | +} | |
2103 | + |