]> git.pld-linux.org Git - packages/ftp.git/blame - netkit-ftp-usagi-ipv6.patch
- release 31 (by relup.sh)
[packages/ftp.git] / netkit-ftp-usagi-ipv6.patch
CommitLineData
37a2e2e3 1diff -uNr netkit-ftp-0.17/CVS/Entries netkit-ftp/CVS/Entries
2diff -uNr netkit-ftp-0.17/ChangeLog netkit-ftp/ChangeLog
3--- netkit-ftp-0.17/ChangeLog Sun Jul 23 04:38:08 2000
4+++ netkit-ftp/ChangeLog Tue Nov 28 03:50:10 2000
5@@ -1,3 +1,6 @@
6+28-Nov-2000:
7+ IPv6 support. (Hiroyuki YAMAMORI <h-yamamo@db3.so-net.ne.jp>)
8+
9 8-Jul-2000:
10 Fix misused printf-function call (not %n-exploitable though).
11
12diff -uNr netkit-ftp-0.17/configure netkit-ftp/configure
13--- netkit-ftp-0.17/configure Sat Jul 29 21:00:28 2000
14+++ netkit-ftp/configure Sat Jan 27 06:14:54 2001
15@@ -24,6 +24,7 @@
16 --binmode=mode Mode for binaries [755]
17 --manmode=mode Mode for manual pages [644]
18 --with-c-compiler=cc Program for compiling C source [guessed]
19+ --enable-ipv6 Enable IPv6 support
20 EOF
21 exit 0;;
22 --verbose) ;;
23@@ -39,6 +40,11 @@
24 --manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
25 --with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;;
26 --without-readline|--disable-readline) WITHOUT_READLINE=1;;
27+
28+ --disable-ipv6) ENABLE_IPV6=no;;
29+ --enable-ipv6=*) ENABLE_IPV6=`echo $1 | sed 's/^[^=]*=//'`;;
30+ --enable-ipv6) ENABLE_IPV6=yes;;
31+
32 *) echo "Unrecognized option: $1"; exit 1;;
33 esac
34 shift
35@@ -142,6 +148,42 @@
36
37 LDFLAGS=
38 LIBS=
39+
40+rm -f __conftest*
41+
42+##################################################
43+## Enable IPv6
44+echo -n "Whether to enable IPv6 support... "
45+if [ x"$ENABLE_IPV6" = x"yes" ]; then
46+ echo yes
47+ CFLAGS="$CFLAGS -DINET6"
48+else
49+ echo no
50+fi
51+
52+rm -f __conftest*
53+
54+## Search IPv6 Library / Headers
55+if [ x"$ENABLE_IPV6" = x"yes" ]; then
56+ echo -n "Search for IPv6 library... "
57+ inet6libdirs="/usr/local/v6/lib /usr/local/lib /usr /usr/inet6/lib"
58+ inet6libs="inet6"
59+ inet6found=no
60+ for inet6libdir in $inet6libdirs; do
61+ for inet6lib in $inet6libs; do
62+ if [ -d $inet6libdir ] && [ -f $inet6libdir/lib$inet6lib.a ]; then
63+ inet6found=yes
64+ break 2
65+ fi
66+ done
67+ done
68+ if [ x"$inet6found" = x"yes" ]; then
69+ echo "$inet6libdir/lib$inet6lib.a"
70+ LIBS="$LIBS -L$inet6libdir -l$inet6lib"
71+ else
72+ echo "not found"
73+ fi
74+fi
75
76 rm -f __conftest*
77
78diff -uNr netkit-ftp-0.17/ftp/CVS/Entries netkit-ftp/ftp/CVS/Entries
79--- netkit-ftp-0.17/ftp/CVS/Entries Thu Jan 1 02:00:00 1970
80+++ netkit-ftp/ftp/CVS/Entries Mon Feb 19 06:50:49 2001
81@@ -0,0 +1,16 @@
82+/.cvsignore/1.1.1.1/Fri Nov 3 19:18:15 2000//
83+/Makefile/1.4/Sat Jan 27 05:57:08 2001//
84+/cmds.c/1.3/Fri Jan 12 21:36:27 2001//
85+/cmds.h/1.1.1.1/Fri Nov 3 19:18:15 2000//
86+/cmdtab.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
87+/domacro.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
88+/ftp.1/1.1.1.1/Fri Nov 3 19:18:15 2000//
89+/ftp.c/1.11/Sun Feb 11 12:26:59 2001//
90+/ftp_var.h/1.3/Fri Jan 12 21:36:27 2001//
91+/glob.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
92+/glob.h/1.1.1.1/Fri Nov 3 19:18:15 2000//
93+/main.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
94+/netrc.5/1.1.1.1/Fri Nov 3 19:18:15 2000//
95+/pathnames.h/1.1.1.1/Fri Nov 3 19:18:15 2000//
96+/ruserpass.c/1.1.1.1/Fri Nov 3 19:18:15 2000//
97+D
98diff -uNr netkit-ftp-0.17/ftp/CVS/Repository netkit-ftp/ftp/CVS/Repository
99--- netkit-ftp-0.17/ftp/CVS/Repository Thu Jan 1 02:00:00 1970
100+++ netkit-ftp/ftp/CVS/Repository Mon Feb 19 06:50:49 2001
101@@ -0,0 +1 @@
102+usagi/src/netkit-ftp/ftp
103diff -uNr netkit-ftp-0.17/ftp/CVS/Root netkit-ftp/ftp/CVS/Root
104--- netkit-ftp-0.17/ftp/CVS/Root Thu Jan 1 02:00:00 1970
105+++ netkit-ftp/ftp/CVS/Root Mon Feb 19 06:50:49 2001
106@@ -0,0 +1 @@
107+:pserver:anoncvs@anoncvs.linux-ipv6.org:/cvsroot/usagi
108diff -uNr netkit-ftp-0.17/ftp/Makefile netkit-ftp/ftp/Makefile
109--- netkit-ftp-0.17/ftp/Makefile Sun Aug 1 09:00:12 1999
110+++ netkit-ftp/ftp/Makefile Sat Jan 27 07:57:08 2001
111@@ -16,10 +16,13 @@
112 cmds.o glob.o: glob.h
113
114 install: ftp
115+ install -d $(INSTALLROOT)$(BINDIR)
116 install -s -m$(BINMODE) ftp $(INSTALLROOT)$(BINDIR)
117 ln -sf ftp $(INSTALLROOT)$(BINDIR)/pftp
118+ install -d $(INSTALLROOT)$(MANDIR)/man1
119 install -m$(MANMODE) ftp.1 $(INSTALLROOT)$(MANDIR)/man1
120 ln -sf ftp.1 $(INSTALLROOT)$(MANDIR)/man1/pftp.1
121+ install -d $(INSTALLROOT)$(MANDIR)/man5
122 install -m$(MANMODE) netrc.5 $(INSTALLROOT)$(MANDIR)/man5
123
124 clean:
125diff -uNr netkit-ftp-0.17/ftp/cmds.c netkit-ftp/ftp/cmds.c
126--- netkit-ftp-0.17/ftp/cmds.c Sun Jul 23 04:36:59 2000
127+++ netkit-ftp/ftp/cmds.c Fri Jan 12 23:36:27 2001
128@@ -1,3 +1,5 @@
129+/* $USAGI$ */
130+
131 /*
132 * Copyright (c) 1985, 1989 Regents of the University of California.
133 * All rights reserved.
37a2e2e3 134@@ -190,7 +192,7 @@
135 setpeer(int argc, char *argv[])
136 {
137 char *host;
138- unsigned short port;
139+ char *port;
140
141 if (connected) {
142 printf("Already connected to %s, use close first.\n",
143@@ -205,22 +207,17 @@
144 code = -1;
145 return;
146 }
147- port = ftp_port;
148+ port = NULL;
149 if (argc > 2) {
150- port = atoi(argv[2]);
151- if (port < 1) {
152- printf("%s: bad port number-- %s\n", argv[1], argv[2]);
153- printf ("usage: %s host-name [port]\n", argv[0]);
154- code = -1;
155- return;
156- }
157- port = htons(port);
158+ port = argv[2];
159 }
160 host = hookup(argv[1], port);
161 if (host) {
162 int overbose;
163
164 connected = 1;
165+ try_epsv = 1;
166+ try_eprt = 1;
167 /*
168 * Set up defaults for FTP.
169 */
37a2e2e3 170diff -uNr netkit-ftp-0.17/ftp/ftp.c netkit-ftp/ftp/ftp.c
171--- netkit-ftp-0.17/ftp/ftp.c Mon Dec 13 22:33:20 1999
172+++ netkit-ftp/ftp/ftp.c Sun Feb 11 14:26:59 2001
173@@ -1,3 +1,34 @@
174+/* $USAGI$ */
175+
176+/*
177+ * Copyright (C) 1997 and 1998 WIDE Project.
178+ * All rights reserved.
179+ *
180+ * Redistribution and use in source and binary forms, with or without
181+ * modification, are permitted provided that the following conditions
182+ * are met:
183+ * 1. Redistributions of source code must retain the above copyright
184+ * notice, this list of conditions and the following disclaimer.
185+ * 2. Redistributions in binary form must reproduce the above copyright
186+ * notice, this list of conditions and the following disclaimer in the
187+ * documentation and/or other materials provided with the distribution.
188+ * 3. Neither the name of the project nor the names of its contributors
189+ * may be used to endorse or promote products derived from this software
190+ * without specific prior written permission.
191+ *
192+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
193+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
194+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
195+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
196+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
197+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
198+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
199+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
200+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
201+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
202+ * SUCH DAMAGE.
203+ */
204+
205 /*
206 * Copyright (c) 1985, 1989 Regents of the University of California.
207 * All rights reserved.
37a2e2e3 208@@ -63,14 +94,38 @@
209 #include "ftp_var.h"
210 #include "cmds.h"
211
212+#ifdef _USAGI
213+#include "version.h"
214+#else
215 #include "../version.h"
216+#endif
217+
218+union sockunion {
219+ struct sockinet {
220+ u_short si_family;
221+ u_short si_port;
222+ } su_si;
223+ struct sockaddr su_sa;
224+ struct sockaddr_in su_sin;
225+#ifdef INET6
226+ struct sockaddr_in6 su_sin6;
227+#endif
228+};
229+#define su_family su_sa.sa_family
230+#define su_port su_si.si_port
231+
232+#ifdef INET6
233+#define ex_af2prot(a) (a == AF_INET ? 1 : (a == AF_INET6 ? 2 : 0))
234+#else
235+#define ex_af2prot(a) (a == AF_INET ? 1 : 0)
236+#endif
237
238 int data = -1;
239 off_t restart_point = 0;
240
241-static struct sockaddr_in hisctladdr;
242-static struct sockaddr_in data_addr;
243-static struct sockaddr_in myctladdr;
244+static union sockunion hisctladdr;
245+static union sockunion data_addr;
246+static union sockunion myctladdr;
247 static int ptflag = 0;
248 static sigjmp_buf recvabort;
249 static sigjmp_buf sendabort;
250@@ -96,79 +151,119 @@
251 static FILE *dataconn(const char *);
252
253 char *
254-hookup(char *host, int port)
255+hookup(const char *host, const char *port)
256 {
257- register struct hostent *hp = 0;
258- int s, tos;
259+ int s, tos, error;
260 socklen_t len;
261 static char hostnamebuf[256];
262-
263+ struct addrinfo hints, *res, *res0;
264+ char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
265+ char *cause = "ftp: unknown";
266+
267+ if (port) {
268+ strncpy(pbuf, port, sizeof(pbuf) - 1);
269+ pbuf[sizeof(pbuf) - 1] = '\0';
270+ } else {
271+ sprintf(pbuf, "%d", ntohs(ftp_port));
272+ }
273 memset(&hisctladdr, 0, sizeof(hisctladdr));
274- if (inet_aton(host, &hisctladdr.sin_addr)) {
275- hisctladdr.sin_family = AF_INET;
276- strncpy(hostnamebuf, host, sizeof(hostnamebuf));
277- hostnamebuf[sizeof(hostnamebuf)-1]=0;
278- }
279- else {
280- hp = gethostbyname(host);
281- if (hp == NULL) {
282- fprintf(stderr, "ftp: %s: ", host);
283- herror((char *)NULL);
284- code = -1;
285- return((char *) 0);
286+ memset(&hints, 0, sizeof(hints));
287+ hints.ai_flags = AI_CANONNAME;
288+ hints.ai_socktype = SOCK_STREAM;
289+ error = getaddrinfo(host, pbuf, &hints, &res0);
290+ if (error) {
291+ if (port) {
292+ strcpy(hbuf, " ");
293+ } else {
294+ hbuf[0] = '\0';
295+ pbuf[0] = '\0';
296 }
297- hisctladdr.sin_family = hp->h_addrtype;
298- if (hp->h_length > (int)sizeof(hisctladdr.sin_addr)) {
299- hp->h_length = sizeof(hisctladdr.sin_addr);
300- }
301- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0], hp->h_length);
302- (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
303- hostnamebuf[sizeof(hostnamebuf)-1] = 0;
304- }
305- hostname = hostnamebuf;
306- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
307- if (s < 0) {
308- perror("ftp: socket");
309+ fprintf(stderr, "ftp: %s%s%s: %s\n", host, hbuf, pbuf,
310+ gai_strerror(error));
311 code = -1;
312 return (0);
313 }
314- hisctladdr.sin_port = port;
315- while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
316- if (hp && hp->h_addr_list[1]) {
317- int oerrno = errno;
318-
319- fprintf(stderr, "ftp: connect to address %s: ",
320- inet_ntoa(hisctladdr.sin_addr));
321- errno = oerrno;
322- perror((char *) 0);
323- hp->h_addr_list++;
324- memcpy(&hisctladdr.sin_addr, hp->h_addr_list[0],
325- hp->h_length);
326- fprintf(stdout, "Trying %s...\n",
327- inet_ntoa(hisctladdr.sin_addr));
328- (void) close(s);
329- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
330- if (s < 0) {
331- perror("ftp: socket");
332- code = -1;
333- return (0);
334+
335+ if (res0->ai_canonname) {
336+ struct addrinfo h, *a;
337+ memset(&h, 0, sizeof(h));
338+ h.ai_family = PF_UNSPEC;
339+ h.ai_socktype = SOCK_STREAM;
340+ h.ai_flags = AI_NUMERICHOST;
341+ if (!getaddrinfo(res0->ai_canonname, NULL, &h, &a)) {
342+ strncpy(hostnamebuf, res0->ai_canonname, sizeof(hostnamebuf));
343+ freeaddrinfo(a);
344+ } else
345+ strncpy(hostnamebuf, host, sizeof(hostnamebuf));
346+ }
347+ else
348+ strncpy(hostnamebuf, host, sizeof(hostnamebuf));
349+ hostnamebuf[sizeof(hostnamebuf) - 1] = '\0';
350+ hostname = hostnamebuf;
351+
352+ s = -1;
353+ for (res = res0; res; res = res->ai_next) {
354+ if (!ex_af2prot(res->ai_family)) {
355+ cause = "ftp: mismatch address family";
356+ errno = EPROTONOSUPPORT;
357+ continue;
358+ }
359+ if ((size_t)res->ai_addrlen > sizeof(hisctladdr)) {
360+ cause = "ftp: mismatch struct sockaddr size";
361+ errno = EPROTO;
362+ continue;
363+ }
364+ if (getnameinfo(res->ai_addr, res->ai_addrlen,
365+ hbuf, sizeof(hbuf), NULL, 0,
366+ NI_NUMERICHOST))
367+ strcpy(hbuf, "???");
368+ if (res0->ai_next) /* if we have multiple possibilities */
369+ fprintf(stdout, "Trying %s...\n", hbuf);
370+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
371+ if (s < 0) {
372+ cause = "ftp: socket";
373+ continue;
374+ }
375+ while ((error = connect(s, res->ai_addr, res->ai_addrlen)) < 0
376+ && errno == EINTR) {
377+ ;
378+ }
379+ if (error) {
380+ /* this "if" clause is to prevent print warning twice */
381+ if (res->ai_next) {
382+ fprintf(stderr,
383+ "ftp: connect to address %s", hbuf);
384+ perror("");
385 }
386+ cause = "ftp: connect";
387+ close(s);
388+ s = -1;
389 continue;
390 }
391- perror("ftp: connect");
392+ /* finally we got one */
393+ break;
394+ }
395+ if (s < 0) {
396+ perror(cause);
397 code = -1;
398- goto bad;
399+ freeaddrinfo(res0);
400+ return NULL;
401 }
402- len = sizeof (myctladdr);
403+ len = res->ai_addrlen;
404+ memcpy(&hisctladdr, res->ai_addr, len);
405+ freeaddrinfo(res0);
406 if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
407 perror("ftp: getsockname");
408 code = -1;
409 goto bad;
410 }
411 #ifdef IP_TOS
412+ if (hisctladdr.su_family == AF_INET)
413+ {
414 tos = IPTOS_LOWDELAY;
415 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
416 perror("ftp: setsockopt TOS (ignored)");
417+ }
418 #endif
419 cin = fdopen(s, "r");
420 cout = fdopen(s, "w");
421@@ -182,7 +277,7 @@
422 goto bad;
423 }
424 if (verbose)
425- printf("Connected to %s.\n", hostname);
426+ printf("Connected to %s (%s).\n", hostname, hbuf);
427 if (getreply(0) > 2) { /* read startup message from server */
428 if (cin)
429 (void) fclose(cin);
430@@ -392,8 +487,10 @@
431 }
432 if (dig < 4 && isdigit(c))
433 code = code * 10 + (c - '0');
434- if (!pflag && code == 227)
435+ if (!pflag && (code == 227 || code == 228))
436 pflag = 1;
437+ else if (!pflag && code == 229)
438+ pflag = 100;
439 if (dig > 4 && pflag == 1 && isdigit(c))
440 pflag = 2;
441 if (pflag == 2) {
442@@ -405,6 +502,8 @@
443 pflag = 3;
444 }
445 }
446+ if (pflag == 100 && c == '(')
447+ pflag = 2;
448 if (dig == 4 && c == '-') {
449 if (continuation)
450 code = 0;
451@@ -1083,15 +1182,25 @@
452 static int
453 initconn(void)
454 {
455- register char *p, *a;
456+ u_char *p, *a;
457 int result, tmpno = 0;
458 socklen_t len;
459 int on = 1;
460- int tos;
461- u_long a1,a2,a3,a4,p1,p2;
462-
463+ int tos, error = 0;
464+ u_int ad[16], po[2], af, alen, plen;
465+ char *pasvcmd = NULL;
466+ char hbuf[MAXHOSTNAMELEN], pbuf[NI_MAXSERV];
467+
468+#ifdef INET6
469+ if (myctladdr.su_family == AF_INET6
470+ && (IN6_IS_ADDR_LINKLOCAL(&myctladdr.su_sin6.sin6_addr)
471+ || IN6_IS_ADDR_SITELOCAL(&myctladdr.su_sin6.sin6_addr))) {
472+ fprintf(stderr, "use of scoped address can be troublesome\n");
473+ }
474+#endif
475 if (passivemode) {
476- data = socket(AF_INET, SOCK_STREAM, 0);
477+ data_addr = hisctladdr;
478+ data = socket(data_addr.su_family, SOCK_STREAM, 0);
479 if (data < 0) {
480 perror("ftp: socket");
481 return(1);
482@@ -1100,52 +1209,201 @@
483 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
484 sizeof (on)) < 0)
485 perror("ftp: setsockopt (ignored)");
486- if (command("PASV") != COMPLETE) {
487+ switch (data_addr.su_family) {
488+ case AF_INET:
489+#if 0
490+ if (try_epsv) {
491+ result = command(pasvcmd = "EPSV 1");
492+ if (code / 10 == 22 && code != 229) {
493+ fprintf(stderr,
494+ "wrong server: return code must be 229\n");
495+ result = COMPLETE + 1;
496+ }
497+ } else {
498+#endif
499+ result = COMPLETE + 1;
500+
501+ if (result != COMPLETE) {
502+ try_epsv = 0;
503+ result = command(pasvcmd = "PASV");
504+ }
505+ break;
506+#ifdef INET6
507+ case AF_INET6:
508+ if (try_epsv) {
509+ result = command(pasvcmd = "EPSV 2");
510+ if (code / 10 == 22 && code != 229) {
511+ fprintf(stderr,
512+ "wrong server: return code must be 229\n");
513+ result = COMPLETE + 1;
514+ }
515+ } else {
516+ result = COMPLETE + 1;
517+ }
518+ if (result != COMPLETE) {
519+ try_epsv = 0;
520+ result = command(pasvcmd = "LPSV");
521+ }
522+ break;
523+#endif
524+ default:
525+ result = COMPLETE + 1;
526+ break;
527+ }
528+ if (result != COMPLETE) {
529 printf("Passive mode refused.\n");
530- return(1);
531+ goto bad;
532 }
533
534+#define pack2(var) \
535+ (((var[0] & 0xff) << 8) | ((var[1] & 0xff) << 0))
536+#define pack4(var) \
537+ ((((var)[0] & 0xff) << 24) | (((var)[1] & 0xff) << 16) | \
538+ (((var)[2] & 0xff) << 8) | (((var)[3] & 0xff) << 0))
539+
540 /*
541 * What we've got at this point is a string of comma separated
542 * one-byte unsigned integer values, separated by commas.
543- * The first four are the an IP address. The fifth is the MSB
544- * of the port number, the sixth is the LSB. From that we'll
545- * prepare a sockaddr_in.
546 */
547-
548- if (sscanf(pasv,"%ld,%ld,%ld,%ld,%ld,%ld",
549- &a1,&a2,&a3,&a4,&p1,&p2)
550- != 6)
551- {
552- printf("Passive mode address scan failure. Shouldn't happen!\n");
553- return(1);
554+ error = 0;
555+ if (strcmp(pasvcmd, "PASV") == 0) {
556+ if (data_addr.su_family != AF_INET) {
557+ error = 2;
558+ goto psv_done;
559+ }
560+ if (code / 10 == 22 && code != 227) {
561+ error = 227;
562+ goto psv_done;
563+ }
564+ if (sscanf(pasv, "%u,%u,%u,%u,%u,%u",
565+ &ad[0], &ad[1], &ad[2], &ad[3],
566+ &po[0], &po[1]) != 6) {
567+ error = 1;
568+ goto psv_done;
569+ }
570+ data_addr.su_sin.sin_addr.s_addr = htonl(pack4(ad));
571+ data_addr.su_port = htons(pack2(po));
572+ } else
573+ if (strcmp(pasvcmd, "LPSV") == 0) {
574+ if (code / 10 == 22 && code != 228) {
575+ error = 228;
576+ goto psv_done;
577+ }
578+ switch (data_addr.su_family) {
579+ case AF_INET:
580+ if (sscanf(pasv, "%u,%u,%u,%u,%u,%u,%u,%u,%u",
581+ &af, &alen,
582+ &ad[0], &ad[1], &ad[2], &ad[3],
583+ &plen, &po[0], &po[1]) != 9) {
584+ error = 1;
585+ goto psv_done;
586+ }
587+ if (af != 4 || alen != 4 || plen != 2) {
588+ error = 2;
589+ goto psv_done;
590+ }
591+ data_addr.su_sin.sin_addr.s_addr =
592+ htonl(pack4(ad));
593+ data_addr.su_port = htons(pack2(po));
594+ break;
595+#ifdef INET6
596+ case AF_INET6:
597+ if (sscanf(pasv,
598+ "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
599+ &af, &alen,
600+ &ad[0], &ad[1], &ad[2], &ad[3],
601+ &ad[4], &ad[5], &ad[6], &ad[7],
602+ &ad[8], &ad[9], &ad[10], &ad[11],
603+ &ad[12], &ad[13], &ad[14], &ad[15],
604+ &plen, &po[0], &po[1]) != 21) {
605+ error = 1;
606+ goto psv_done;
607+ }
608+ if (af != 6 || alen != 16 || plen != 2) {
609+ error = 2;
610+ goto psv_done;
611+ }
612+ data_addr.su_sin6.sin6_addr.s6_addr32[0] =
613+ htonl(pack4(ad));
614+ data_addr.su_sin6.sin6_addr.s6_addr32[1] =
615+ htonl(pack4(ad+4));
616+ data_addr.su_sin6.sin6_addr.s6_addr32[2] =
617+ htonl(pack4(ad+8));
618+ data_addr.su_sin6.sin6_addr.s6_addr32[3] =
619+ htonl(pack4(ad+12));
620+ data_addr.su_port = htons(pack2(po));
621+ break;
622+#endif
623+ default:
624+ error = 1;
625+ }
626+ } else if (strncmp(pasvcmd, "EPSV", 4) == 0) {
627+ char delim[4];
628+ u_int epsvpo;
629+
630+ if (code / 10 == 22 && code != 229) {
631+ error = 229;
632+ goto psv_done;
633+ }
634+ if (sscanf(pasv, "%c%c%c%u%c", &delim[0], &delim[1],
635+ &delim[2], &epsvpo, &delim[3]) != 5) {
636+ error = 1;
637+ goto psv_done;
638+ }
639+ if (delim[0] != delim[1] || delim[0] != delim[2]
640+ || delim[0] != delim[3]) {
641+ error = 1;
642+ goto psv_done;
643+ }
644+ data_addr.su_port = htons(epsvpo);
645+ } else {
646+ error = 1;
647+ }
648+psv_done:
649+ switch (error) {
650+ case 0:
651+ break;
652+ case 1:
653+ fprintf(stderr,
654+ "Passive mode address scan failure. Shouldn't happen!\n");
655+ goto bad;
656+ case 2:
657+ fprintf(stderr,
658+ "Passive mode AF mismatch. Shouldn't happen!\n");
659+ goto bad;
660+ case 227:
661+ case 228:
662+ case 229:
663+ fprintf(stderr,
664+ "wrong server: return code must be %d\n", error);
665+ goto bad;
666+ default:
667+ fprintf(stderr, "Bug\n");
668 }
669
670- data_addr.sin_family = AF_INET;
671- data_addr.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) |
672- (a3 << 8) | a4);
673- data_addr.sin_port = htons((p1 << 8) | p2);
674-
675 if (connect(data, (struct sockaddr *) &data_addr,
676 sizeof(data_addr))<0) {
677 perror("ftp: connect");
678 return(1);
679 }
680 #ifdef IP_TOS
681+ if (data_addr.su_family == AF_INET)
682+ {
683 tos = IPTOS_THROUGHPUT;
684 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos,
685 sizeof(tos)) < 0)
686 perror("ftp: setsockopt TOS (ignored)");
687+ }
688 #endif
689 return(0);
690 }
691 noport:
692 data_addr = myctladdr;
693 if (sendport)
694- data_addr.sin_port = 0; /* let system pick one */
695+ data_addr.su_port = 0; /* let system pick one */
696 if (data != -1)
697 (void) close(data);
698- data = socket(AF_INET, SOCK_STREAM, 0);
699+ data = socket(data_addr.su_family, SOCK_STREAM, 0);
700 if (data < 0) {
701 perror("ftp: socket");
702 if (tmpno)
703@@ -1172,13 +1430,47 @@
704 if (listen(data, 1) < 0)
705 perror("ftp: listen");
706 if (sendport) {
707- a = (char *)&data_addr.sin_addr;
708- p = (char *)&data_addr.sin_port;
709-#define UC(b) (((int)b)&0xff)
710- result =
711- command("PORT %d,%d,%d,%d,%d,%d",
712- UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
713- UC(p[0]), UC(p[1]));
714+ af = ex_af2prot(data_addr.su_family);
715+ if (try_eprt && af > 1) { /* only IPv6 */
716+ if (getnameinfo((struct sockaddr *)&data_addr, len,
717+ hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
718+ NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
719+ result = command("EPRT |%d|%s|%s|",
720+ af, hbuf, pbuf);
721+ if (result != COMPLETE) {
722+ try_eprt = 0;
723+ }
724+ } else {
725+ result = ERROR;
726+ }
727+ } else {
728+ result = COMPLETE + 1;
729+ }
730+ if (result == COMPLETE)
731+ goto prt_done;
732+
733+ p = (u_char *)&data_addr.su_port;
734+ switch (data_addr.su_family) {
735+ case AF_INET:
736+ a = (u_char *)&data_addr.su_sin.sin_addr;
737+ result = command("PORT %u,%u,%u,%u,%u,%u",
738+ a[0], a[1], a[2], a[3], p[0], p[1]);
739+ break;
740+#ifdef INET6
741+ case AF_INET6:
742+ a = (u_char *)&data_addr.su_sin6.sin6_addr;
743+ result = command(
744+ "LPRT 6,16,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,2,%d,%d",
745+ a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
746+ a[8], a[9],a[10],a[11],a[12],a[13],a[14],a[15],
747+ p[0], p[1]);
748+ break;
749+#endif
750+ default:
751+ result = COMPLETE + 1; /* xxx */
752+ }
753+
754+ prt_done:
755 if (result == ERROR && sendport == -1) {
756 sendport = 0;
757 tmpno = 1;
758@@ -1189,9 +1481,12 @@
759 if (tmpno)
760 sendport = 1;
761 #ifdef IP_TOS
762+ if (data_addr.su_family == AF_INET)
763+ {
764 on = IPTOS_THROUGHPUT;
765 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
766 perror("ftp: setsockopt TOS (ignored)");
767+ }
768 #endif
769 return (0);
770 bad:
771@@ -1204,7 +1499,7 @@
772 static FILE *
773 dataconn(const char *lmode)
774 {
775- struct sockaddr_in from;
776+ union sockunion from;
777 int s, tos;
778 socklen_t fromlen = sizeof(from);
779
780@@ -1220,9 +1515,12 @@
781 (void) close(data);
782 data = s;
783 #ifdef IP_TOS
784+ if (from.su_family == AF_INET)
785+ {
786 tos = IPTOS_THROUGHPUT;
787 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
788 perror("ftp: setsockopt TOS (ignored)");
789+ }
790 #endif
791 return (fdopen(data, lmode));
792 }
793@@ -1284,8 +1582,8 @@
794 static struct comvars {
795 int connect;
796 char name[MAXHOSTNAMELEN];
797- struct sockaddr_in mctl;
798- struct sockaddr_in hctl;
799+ union sockunion mctl;
800+ union sockunion hctl;
801 FILE *in;
802 FILE *out;
803 int tpe;
804@@ -1323,7 +1621,7 @@
805 connected = op->connect;
806 if (hostname) {
807 (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
808- ip->name[strlen(ip->name)] = '\0';
809+ ip->name[sizeof(ip->name) - 1] = '\0';
810 }
811 else {
812 ip->name[0] = 0;
813@@ -1352,18 +1650,18 @@
814 ip->ntflg = ntflag;
815 ntflag = op->ntflg;
816 (void) strncpy(ip->nti, ntin, 16);
817- (ip->nti)[strlen(ip->nti)] = '\0';
818+ (ip->nti)[16] = '\0'; /* shouldn't use strlen */
819 (void) strcpy(ntin, op->nti);
820 (void) strncpy(ip->nto, ntout, 16);
821- (ip->nto)[strlen(ip->nto)] = '\0';
822+ (ip->nto)[16] = '\0';
823 (void) strcpy(ntout, op->nto);
824 ip->mapflg = mapflag;
825 mapflag = op->mapflg;
826 (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
827- (ip->mi)[strlen(ip->mi)] = '\0';
828+ (ip->mi)[MAXPATHLEN - 1] = '\0';
829 (void) strcpy(mapin, op->mi);
830 (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
831- (ip->mo)[strlen(ip->mo)] = '\0';
832+ (ip->mo)[MAXPATHLEN - 1] = '\0';
833 (void) strcpy(mapout, op->mo);
834 (void) signal(SIGINT, oldintr);
835 if (abrtflag) {
836diff -uNr netkit-ftp-0.17/ftp/ftp_var.h netkit-ftp/ftp/ftp_var.h
837--- netkit-ftp-0.17/ftp/ftp_var.h Sat Oct 2 21:39:17 1999
838+++ netkit-ftp/ftp/ftp_var.h Fri Jan 12 23:36:27 2001
839@@ -1,3 +1,5 @@
840+/* $USAGI$ */
841+
842 /*
843 * Copyright (c) 1985, 1989 Regents of the University of California.
844 * All rights reserved.
37a2e2e3 845@@ -112,6 +114,8 @@
846 Extern int mflag; /* flag: if != 0, then active multi command */
847
848 Extern int options; /* used during socket creation */
849+Extern int try_epsv; /* try EPSV for this session */
850+Extern int try_eprt; /* try EPRT for this session */
851
852 /*
853 * Format of command table.
854@@ -140,7 +144,7 @@
855 Extern char macbuf[4096];
856 #define MACBUF_SIZE 4096
857
858-char *hookup(char *host, int port);
859+char *hookup(const char *host, const char *port);
860 struct cmd *getcmd(const char *);
861 char **makeargv(int *pargc, char **parg);
862 int dologin(const char *host);
This page took 0.21148 seconds and 4 git commands to generate.