1 /* $KAME: ftp.c,v 1.11 2001/07/02 14:36:49 itojun Exp $ */
4 * Copyright (C) 1997 and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/ioctl.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
54 static char rbuf[MSS];
55 static char sbuf[MSS];
56 static int passivemode = 0;
57 static int wport4 = -1; /* listen() to active */
58 static int wport6 = -1; /* listen() to passive */
59 static int port4 = -1; /* active: inbound passive: outbound */
60 static int port6 = -1; /* active: outbound passive: inbound */
61 static struct sockaddr_storage data4; /* server data address */
62 static struct sockaddr_storage data6; /* client data address */
63 static int epsvall = 0;
66 enum state { NONE, LPRT, EPRT, PORT, LPSV, EPSV, PASV };
68 enum state { NONE, LPRT, EPRT, LPSV, EPSV };
71 static int ftp_activeconn __P((void));
72 static int ftp_passiveconn __P((void));
73 static int ftp_copy __P((int, int));
74 static int ftp_copyresult __P((int, int, enum state));
75 static int ftp_copycommand __P((int, int, enum state *));
78 ftp_relay(int ctl6, int ctl4)
82 enum state state = NONE;
85 syslog(LOG_INFO, "starting ftp control connection");
89 FD_SET(ctl4, &readfds);
90 FD_SET(ctl6, &readfds);
92 FD_SET(port4, &readfds);
94 FD_SET(port6, &readfds);
97 FD_SET(wport4, &readfds);
99 FD_SET(wport6, &readfds);
101 tv.tv_sec = FAITH_TIMEOUT;
104 error = select(256, &readfds, NULL, NULL, &tv);
106 exit_failure("select: %s", strerror(errno));
108 exit_failure("connection timeout");
111 * The order of the following checks does (slightly) matter.
112 * It is important to visit all checks (do not use "continue"),
113 * otherwise some of the pipe may become full and we cannot
116 if (FD_ISSET(ctl6, &readfds)) {
118 * copy control connection from the client.
119 * command translation is necessary.
121 error = ftp_copycommand(ctl6, ctl4, &state);
125 else if (error == 0) {
128 exit_success("terminating ftp control connection");
131 if (FD_ISSET(ctl4, &readfds)) {
133 * copy control connection from the server
134 * translation of result code is necessary.
136 error = ftp_copyresult(ctl4, ctl6, state);
140 else if (error == 0) {
143 exit_success("terminating ftp control connection");
146 if (0 <= port4 && 0 <= port6 && FD_ISSET(port4, &readfds)) {
148 * copy data connection.
149 * no special treatment necessary.
151 if (FD_ISSET(port4, &readfds))
152 error = ftp_copy(port4, port6);
160 syslog(LOG_INFO, "terminating data connection");
166 if (0 <= port4 && 0 <= port6 && FD_ISSET(port6, &readfds)) {
168 * copy data connection.
169 * no special treatment necessary.
171 if (FD_ISSET(port6, &readfds))
172 error = ftp_copy(port6, port4);
180 syslog(LOG_INFO, "terminating data connection");
187 if (wport4 && FD_ISSET(wport4, &readfds)) {
189 * establish active data connection from the server.
193 if (wport6 && FD_ISSET(wport6, &readfds)) {
195 * establish passive data connection from the client.
203 exit_failure("%s", strerror(errno));
212 struct timeval timeout;
215 /* get active connection from server */
217 FD_SET(wport4, &set);
218 timeout.tv_sec = 120;
219 timeout.tv_usec = -1;
221 if (select(wport4 + 1, &set, NULL, NULL, &timeout) == 0
222 || (port4 = accept(wport4, (struct sockaddr *)&data4, &n)) < 0) {
225 syslog(LOG_INFO, "active mode data connection failed");
229 /* ask active connection to client */
230 sa = (struct sockaddr *)&data6;
231 port6 = socket(sa->sa_family, SOCK_STREAM, 0);
236 syslog(LOG_INFO, "active mode data connection failed");
239 error = connect(port6, sa, sa->sa_len);
244 port6 = port4 = wport4 = -1;
245 syslog(LOG_INFO, "active mode data connection failed");
249 syslog(LOG_INFO, "active mode data connection established");
259 struct timeval timeout;
262 /* get passive connection from client */
264 FD_SET(wport6, &set);
265 timeout.tv_sec = 120;
268 if (select(wport6 + 1, &set, NULL, NULL, &timeout) == 0
269 || (port6 = accept(wport6, (struct sockaddr *)&data6, &n)) < 0) {
272 syslog(LOG_INFO, "passive mode data connection failed");
276 /* ask passive connection to server */
277 sa = (struct sockaddr *)&data4;
278 port4 = socket(sa->sa_family, SOCK_STREAM, 0);
283 syslog(LOG_INFO, "passive mode data connection failed");
286 error = connect(port4, sa, sa->sa_len);
291 wport6 = port4 = port6 = -1;
292 syslog(LOG_INFO, "passive mode data connection failed");
296 syslog(LOG_INFO, "passive mode data connection established");
301 ftp_copy(int src, int dst)
306 /* OOB data handling */
307 error = ioctl(src, SIOCATMARK, &atmark);
308 if (error != -1 && atmark == 1) {
309 n = read(src, rbuf, 1);
312 send(dst, rbuf, n, MSG_OOB);
314 n = read(src, rbuf, sizeof(rbuf));
322 n = read(src, rbuf, sizeof(rbuf));
333 exit_failure("%s", strerror(errno));
335 return 0; /* to make gcc happy */
339 ftp_copyresult(int src, int dst, enum state state)
346 /* OOB data handling */
347 error = ioctl(src, SIOCATMARK, &atmark);
348 if (error != -1 && atmark == 1) {
349 n = read(src, rbuf, 1);
352 send(dst, rbuf, n, MSG_OOB);
354 n = read(src, rbuf, sizeof(rbuf));
362 n = read(src, rbuf, sizeof(rbuf));
375 for (i = 0; i < 3; i++) {
390 /* param points to first non-command token, if any */
391 while (*param && isspace(*param))
399 if (!passivemode && rbuf[0] == '1') {
400 if (ftp_activeconn() < 0) {
401 n = snprintf(rbuf, sizeof(rbuf),
402 "425 Cannot open data connetion\r\n");
405 return n > 0 ? write(dst, rbuf, n) : n;
408 /* expecting "200 PORT command successful." */
412 p = strstr(rbuf, "PORT");
414 p[0] = (state == LPRT) ? 'L' : 'E';
425 /* expecting "200 EPRT command successful." */
429 p = strstr(rbuf, "EPRT");
444 * expecting "227 Entering Passive Mode (x,x,x,x,x,x,x)"
445 * (in some cases result comes without paren)
456 unsigned int ho[4], po[2];
457 struct sockaddr_in *sin;
458 struct sockaddr_in6 *sin6;
463 * PASV result -> LPSV/EPSV result
466 while (*p && *p != '(' && !isdigit(*p)) /*)*/
469 goto passivefail0; /*XXX*/
472 n = sscanf(p, "%u,%u,%u,%u,%u,%u",
473 &ho[0], &ho[1], &ho[2], &ho[3], &po[0], &po[1]);
475 goto passivefail0; /*XXX*/
477 /* keep PORT parameter */
478 memset(&data4, 0, sizeof(data4));
479 sin = (struct sockaddr_in *)&data4;
480 sin->sin_len = sizeof(*sin);
481 sin->sin_family = AF_INET;
482 sin->sin_addr.s_addr = 0;
483 for (n = 0; n < 4; n++) {
484 sin->sin_addr.s_addr |=
485 htonl((ho[n] & 0xff) << ((3 - n) * 8));
487 sin->sin_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
489 /* get ready for passive data connection */
490 memset(&data6, 0, sizeof(data6));
491 sin6 = (struct sockaddr_in6 *)&data6;
492 sin6->sin6_len = sizeof(*sin6);
493 sin6->sin6_family = AF_INET6;
494 wport6 = socket(sin6->sin6_family, SOCK_STREAM, 0);
497 n = snprintf(sbuf, sizeof(sbuf),
498 "500 could not translate from PASV\r\n");
499 return n > 0 ? write(src, sbuf, n) : n;
504 error = setsockopt(wport6, IPPROTO_IPV6, IPV6_FAITH,
507 exit_failure("setsockopt(IPV6_FAITH): %s", strerror(errno));
510 error = bind(wport6, (struct sockaddr *)sin6, sin6->sin6_len);
516 error = listen(wport6, 1);
523 /* transmit LPSV or EPSV */
525 * addr from dst, port from wport6
528 error = getsockname(wport6, (struct sockaddr *)&data6, &n);
534 sin6 = (struct sockaddr_in6 *)&data6;
535 port = sin6->sin6_port;
538 error = getsockname(dst, (struct sockaddr *)&data6, &n);
544 sin6 = (struct sockaddr_in6 *)&data6;
545 sin6->sin6_port = port;
550 a = (char *)&sin6->sin6_addr;
551 p = (char *)&sin6->sin6_port;
552 n = snprintf(sbuf, sizeof(sbuf),
553 "228 Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\r\n",
554 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
555 UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]),
556 UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]),
557 UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]),
558 2, UC(p[0]), UC(p[1]));
560 n = write(dst, sbuf, n);
564 n = snprintf(sbuf, sizeof(sbuf),
565 "229 Entering Extended Passive Mode (|||%d|)\r\n",
566 ntohs(sin6->sin6_port));
568 n = write(dst, sbuf, n);
575 /* expecting "229 Entering Extended Passive Mode (|||x|)" */
587 struct sockaddr_in *sin;
588 struct sockaddr_in6 *sin6;
591 * EPSV result -> PORT result
594 while (*p && *p != '(') /*)*/
597 goto passivefail1; /*XXX*/
599 n = sscanf(p, "|||%hu|", &port);
601 goto passivefail1; /*XXX*/
603 /* keep EPRT parameter */
605 error = getpeername(src, (struct sockaddr *)&data4, &n);
607 goto passivefail1; /*XXX*/
608 sin6 = (struct sockaddr_in6 *)&data4;
609 sin6->sin6_port = htons(port);
611 /* get ready for passive data connection */
612 memset(&data6, 0, sizeof(data6));
613 sin = (struct sockaddr_in *)&data6;
614 sin->sin_len = sizeof(*sin);
615 sin->sin_family = AF_INET;
616 wport6 = socket(sin->sin_family, SOCK_STREAM, 0);
619 n = snprintf(sbuf, sizeof(sbuf),
620 "500 could not translate from EPSV\r\n");
621 return n > 0 ? write(src, sbuf, n) : n;
626 error = setsockopt(wport6, IPPROTO_IP, IP_FAITH,
629 exit_error("setsockopt(IP_FAITH): %s", strerror(errno));
632 error = bind(wport6, (struct sockaddr *)sin, sin->sin_len);
638 error = listen(wport6, 1);
647 * addr from dst, port from wport6
650 error = getsockname(wport6, (struct sockaddr *)&data6, &n);
656 sin = (struct sockaddr_in *)&data6;
657 port = sin->sin_port;
660 error = getsockname(dst, (struct sockaddr *)&data6, &n);
666 sin = (struct sockaddr_in *)&data6;
667 sin->sin_port = port;
672 a = (char *)&sin->sin_addr;
673 p = (char *)&sin->sin_port;
674 n = snprintf(sbuf, sizeof(sbuf),
675 "227 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n",
676 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
679 n = write(dst, sbuf, n);
688 exit_failure("%s", strerror(errno));
690 return 0; /* to make gcc happy */
694 ftp_copycommand(int src, int dst, enum state *state)
698 unsigned int af, hal, ho[16], pal, po[2];
701 struct sockaddr_in *sin;
702 struct sockaddr_in6 *sin6;
706 /* OOB data handling */
707 error = ioctl(src, SIOCATMARK, &atmark);
708 if (error != -1 && atmark == 1) {
709 n = read(src, rbuf, 1);
712 send(dst, rbuf, n, MSG_OOB);
714 n = read(src, rbuf, sizeof(rbuf));
722 n = read(src, rbuf, sizeof(rbuf));
741 for (i = 0; i < 4; i++) {
743 /* invalid command */
747 *q++ = islower(*p) ? toupper(*p) : *p;
751 /* invalid command */
757 /* param points to first non-command token, if any */
758 while (*param && isspace(*param))
766 if (strcmp(cmd, "LPRT") == 0 && param) {
776 wport4 = wport6 = port4 = port6 = -1;
779 n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n",
781 return n > 0 ? write(src, sbuf, n) : n;
785 "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
786 &af, &hal, &ho[0], &ho[1], &ho[2], &ho[3],
787 &ho[4], &ho[5], &ho[6], &ho[7],
788 &ho[8], &ho[9], &ho[10], &ho[11],
789 &ho[12], &ho[13], &ho[14], &ho[15],
790 &pal, &po[0], &po[1]);
791 if (n != 21 || af != 6 || hal != 16|| pal != 2) {
792 n = snprintf(sbuf, sizeof(sbuf),
793 "501 illegal parameter to LPRT\r\n");
794 return n > 0 ? write(src, sbuf, n) : n;
797 /* keep LPRT parameter */
798 memset(&data6, 0, sizeof(data6));
799 sin6 = (struct sockaddr_in6 *)&data6;
800 sin6->sin6_len = sizeof(*sin6);
801 sin6->sin6_family = AF_INET6;
802 for (n = 0; n < 16; n++)
803 sin6->sin6_addr.s6_addr[n] = ho[n];
804 sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
807 /* get ready for active data connection */
809 error = getsockname(dst, (struct sockaddr *)&data4, &n);
812 n = snprintf(sbuf, sizeof(sbuf),
813 "500 could not translate to PORT\r\n");
814 return n > 0 ? write(src, sbuf, n) : n;
816 if (((struct sockaddr *)&data4)->sa_family != AF_INET)
818 sin = (struct sockaddr_in *)&data4;
820 wport4 = socket(sin->sin_family, SOCK_STREAM, 0);
823 error = bind(wport4, (struct sockaddr *)sin, sin->sin_len);
829 error = listen(wport4, 1);
838 error = getsockname(wport4, (struct sockaddr *)&data4, &n);
844 if (((struct sockaddr *)&data4)->sa_family != AF_INET) {
849 sin = (struct sockaddr_in *)&data4;
850 a = (char *)&sin->sin_addr;
851 p = (char *)&sin->sin_port;
852 n = snprintf(sbuf, sizeof(sbuf), "PORT %d,%d,%d,%d,%d,%d\r\n",
853 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
856 n = write(dst, sbuf, n);
860 } else if (strcmp(cmd, "EPRT") == 0 && param) {
864 char *afp, *hostp, *portp;
865 struct addrinfo hints, *res;
873 wport4 = wport6 = port4 = port6 = -1;
876 n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n",
878 return n > 0 ? write(src, sbuf, n) : n;
882 ch = *p++; /* boundary character */
884 while (*p && *p != ch)
888 n = snprintf(sbuf, sizeof(sbuf),
889 "501 illegal parameter to EPRT\r\n");
890 return n > 0 ? write(src, sbuf, n) : n;
894 while (*p && *p != ch)
900 while (*p && *p != ch)
906 n = sscanf(afp, "%d", &af);
907 if (n != 1 || af != 2) {
908 n = snprintf(sbuf, sizeof(sbuf),
909 "501 unsupported address family to EPRT\r\n");
910 return n > 0 ? write(src, sbuf, n) : n;
912 memset(&hints, 0, sizeof(hints));
913 hints.ai_family = AF_UNSPEC;
914 hints.ai_socktype = SOCK_STREAM;
915 error = getaddrinfo(hostp, portp, &hints, &res);
917 n = snprintf(sbuf, sizeof(sbuf),
918 "501 EPRT: %s\r\n", gai_strerror(error));
919 return n > 0 ? write(src, sbuf, n) : n;
922 n = snprintf(sbuf, sizeof(sbuf),
923 "501 EPRT: %s resolved to multiple addresses\r\n", hostp);
924 return n > 0 ? write(src, sbuf, n) : n;
927 memcpy(&data6, res->ai_addr, res->ai_addrlen);
930 } else if (strcmp(cmd, "LPSV") == 0 && !param) {
940 wport4 = wport6 = port4 = port6 = -1;
943 n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n",
945 return n > 0 ? write(src, sbuf, n) : n;
949 n = snprintf(sbuf, sizeof(sbuf), "PASV\r\n");
951 n = write(dst, sbuf, n);
953 passivemode = 0; /* to be set to 1 later */
955 } else if (strcmp(cmd, "EPSV") == 0 && !param) {
963 wport4 = wport6 = port4 = port6 = -1;
965 n = snprintf(sbuf, sizeof(sbuf), "PASV\r\n");
967 n = write(dst, sbuf, n);
969 passivemode = 0; /* to be set to 1 later */
971 } else if (strcmp(cmd, "EPSV") == 0 && param
972 && strncasecmp(param, "ALL", 3) == 0 && isspace(param[3])) {
977 n = snprintf(sbuf, sizeof(sbuf), "200 EPSV ALL command successful.\r\n");
978 return n > 0 ? write(src, sbuf, n) : n;
980 } else if (strcmp(cmd, "PORT") == 0 && param) {
984 char host[NI_MAXHOST], serv[NI_MAXSERV];
992 wport4 = wport6 = port4 = port6 = -1;
995 n = sscanf(p, "%u,%u,%u,%u,%u,%u",
996 &ho[0], &ho[1], &ho[2], &ho[3], &po[0], &po[1]);
998 n = snprintf(sbuf, sizeof(sbuf),
999 "501 illegal parameter to PORT\r\n");
1000 return n > 0 ? write(src, sbuf, n) : n;
1003 memset(&data6, 0, sizeof(data6));
1004 sin = (struct sockaddr_in *)&data6;
1005 sin->sin_len = sizeof(*sin);
1006 sin->sin_family = AF_INET;
1007 sin->sin_addr.s_addr = htonl(
1008 ((ho[0] & 0xff) << 24) | ((ho[1] & 0xff) << 16) |
1009 ((ho[2] & 0xff) << 8) | (ho[3] & 0xff));
1010 sin->sin_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
1012 /* get ready for active data connection */
1014 error = getsockname(dst, (struct sockaddr *)&data4, &n);
1017 n = snprintf(sbuf, sizeof(sbuf),
1018 "500 could not translate to EPRT\r\n");
1019 return n > 0 ? write(src, sbuf, n) : n;
1021 if (((struct sockaddr *)&data4)->sa_family != AF_INET6)
1024 ((struct sockaddr_in6 *)&data4)->sin6_port = 0;
1025 sa = (struct sockaddr *)&data4;
1026 wport4 = socket(sa->sa_family, SOCK_STREAM, 0);
1029 error = bind(wport4, sa, sa->sa_len);
1035 error = listen(wport4, 1);
1044 error = getsockname(wport4, (struct sockaddr *)&data4, &n);
1051 sa = (struct sockaddr *)&data4;
1052 if (getnameinfo(sa, sa->sa_len, host, sizeof(host),
1053 serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV)) {
1058 n = snprintf(sbuf, sizeof(sbuf), "EPRT |%d|%s|%s|\r\n", af, host, serv);
1060 n = write(dst, sbuf, n);
1064 } else if (strcmp(cmd, "PASV") == 0 && !param) {
1075 wport4 = wport6 = port4 = port6 = -1;
1078 n = snprintf(sbuf, sizeof(sbuf), "EPSV\r\n");
1080 n = write(dst, sbuf, n);
1082 passivemode = 0; /* to be set to 1 later */
1085 } else if (strcmp(cmd, "PORT") == 0 || strcmp(cmd, "PASV") == 0) {
1089 n = snprintf(sbuf, sizeof(sbuf), "502 %s not implemented.\r\n", cmd);
1090 return n > 0 ? write(src, sbuf, n) : n;
1092 } else if (passivemode
1093 && (strcmp(cmd, "STOR") == 0
1094 || strcmp(cmd, "STOU") == 0
1095 || strcmp(cmd, "RETR") == 0
1096 || strcmp(cmd, "LIST") == 0
1097 || strcmp(cmd, "NLST") == 0
1098 || strcmp(cmd, "APPE") == 0)) {
1100 * commands with data transfer. need to care about passive
1101 * mode data connection.
1104 if (ftp_passiveconn() < 0) {
1105 n = snprintf(sbuf, sizeof(sbuf), "425 Cannot open data connetion\r\n");
1107 n = write(src, sbuf, n);
1109 /* simply relay the command */
1110 write(dst, rbuf, n);
1116 /* simply relay it */
1118 return write(dst, rbuf, n);
1122 exit_failure("%s", strerror(errno));
1124 return 0; /* to make gcc happy */