1 /* $KAME: ftp.c,v 1.24 2005/03/16 05:05:48 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>
51 #include <netinet/in.h>
52 #include <arpa/inet.h>
57 static char rbuf[MSS];
58 static char sbuf[MSS];
59 static int passivemode = 0;
60 static int wport4 = -1; /* listen() to active */
61 static int wport6 = -1; /* listen() to passive */
62 static int port4 = -1; /* active: inbound passive: outbound */
63 static int port6 = -1; /* active: outbound passive: inbound */
64 static struct sockaddr_storage data4; /* server data address */
65 static struct sockaddr_storage data6; /* client data address */
66 static int epsvall = 0;
68 enum state { NONE, LPRT, EPRT, LPSV, EPSV };
70 static int ftp_activeconn __P((void));
71 static int ftp_passiveconn __P((void));
72 static int ftp_copy __P((int, int));
73 static int ftp_copyresult __P((int, int, enum state));
74 static int ftp_copycommand __P((int, int, enum state *));
77 ftp_relay(int ctl6, int ctl4)
85 enum state state = NONE;
88 syslog(LOG_INFO, "starting ftp control connection");
93 pfd[0].events = POLLIN;
95 pfd[1].events = POLLIN;
98 pfd[2].events = POLLIN;
103 pfd[3].events = POLLIN;
109 pfd[4].events = POLLIN;
114 pfd[5].events = POLLIN;
118 pfd[4].fd = pfd[5].fd = -1;
119 pfd[4].events = pfd[5].events = 0;
125 if (ctl4 >= FD_SETSIZE)
126 exit_failure("descriptor too big");
127 FD_SET(ctl4, &readfds);
129 if (ctl6 >= FD_SETSIZE)
130 exit_failure("descriptor too big");
131 FD_SET(ctl6, &readfds);
132 maxfd = (ctl6 > maxfd) ? ctl6 : maxfd;
134 if (port4 >= FD_SETSIZE)
135 exit_failure("descriptor too big");
136 FD_SET(port4, &readfds);
137 maxfd = (port4 > maxfd) ? port4 : maxfd;
140 if (port6 >= FD_SETSIZE)
141 exit_failure("descriptor too big");
142 FD_SET(port6, &readfds);
143 maxfd = (port6 > maxfd) ? port6 : maxfd;
147 if (wport4 >= FD_SETSIZE)
148 exit_failure("descriptor too big");
149 FD_SET(wport4, &readfds);
150 maxfd = (wport4 > maxfd) ? wport4 : maxfd;
153 if (wport6 >= FD_SETSIZE)
154 exit_failure("descriptor too big");
155 FD_SET(wport6, &readfds);
156 maxfd = (wport6 > maxfd) ? wport6 : maxfd;
160 tv.tv_sec = FAITH_TIMEOUT;
164 error = poll(pfd, sizeof(pfd)/sizeof(pfd[0]), tv.tv_sec * 1000);
166 error = select(maxfd + 1, &readfds, NULL, NULL, &tv);
170 exit_failure("poll: %s", strerror(errno));
172 exit_failure("select: %s", strerror(errno));
176 exit_failure("connection timeout");
179 * The order of the following checks does (slightly) matter.
180 * It is important to visit all checks (do not use "continue"),
181 * otherwise some of the pipe may become full and we cannot
185 if (pfd[1].revents & POLLIN)
187 if (FD_ISSET(ctl6, &readfds))
191 * copy control connection from the client.
192 * command translation is necessary.
194 error = ftp_copycommand(ctl6, ctl4, &state);
198 else if (error == 0) {
201 exit_success("terminating ftp control connection");
206 if (pfd[0].revents & POLLIN)
208 if (FD_ISSET(ctl4, &readfds))
212 * copy control connection from the server
213 * translation of result code is necessary.
215 error = ftp_copyresult(ctl4, ctl6, state);
219 else if (error == 0) {
222 exit_success("terminating ftp control connection");
227 if (0 <= port4 && 0 <= port6 && (pfd[2].revents & POLLIN))
229 if (0 <= port4 && 0 <= port6 && FD_ISSET(port4, &readfds))
233 * copy data connection.
234 * no special treatment necessary.
237 if (pfd[2].revents & POLLIN)
239 if (FD_ISSET(port4, &readfds))
241 error = ftp_copy(port4, port6);
249 syslog(LOG_INFO, "terminating data connection");
256 if (0 <= port4 && 0 <= port6 && (pfd[3].revents & POLLIN))
258 if (0 <= port4 && 0 <= port6 && FD_ISSET(port6, &readfds))
262 * copy data connection.
263 * no special treatment necessary.
266 if (pfd[3].revents & POLLIN)
268 if (FD_ISSET(port6, &readfds))
270 error = ftp_copy(port6, port4);
278 syslog(LOG_INFO, "terminating data connection");
286 if (wport4 && (pfd[4].revents & POLLIN))
288 if (wport4 && FD_ISSET(wport4, &readfds))
292 * establish active data connection from the server.
297 if (wport4 && (pfd[5].revents & POLLIN))
299 if (wport6 && FD_ISSET(wport6, &readfds))
303 * establish passive data connection from the client.
311 exit_failure("%s", strerror(errno));
320 struct pollfd pfd[1];
324 struct timeval timeout;
327 /* get active connection from server */
330 pfd[0].events = POLLIN;
333 if (wport4 >= FD_SETSIZE)
334 exit_failure("descriptor too big");
335 FD_SET(wport4, &set);
337 timeout.tv_sec = 120;
341 if (poll(pfd, sizeof(pfd)/sizeof(pfd[0]), timeout.tv_sec * 1000) == 0 ||
342 (port4 = accept(wport4, (struct sockaddr *)&data4, &n)) < 0)
344 if (select(wport4 + 1, &set, NULL, NULL, &timeout) == 0 ||
345 (port4 = accept(wport4, (struct sockaddr *)&data4, &n)) < 0)
350 syslog(LOG_INFO, "active mode data connection failed");
354 /* ask active connection to client */
355 sa = (struct sockaddr *)&data6;
356 port6 = socket(sa->sa_family, SOCK_STREAM, 0);
361 syslog(LOG_INFO, "active mode data connection failed");
364 error = connect(port6, sa, sa->sa_len);
369 port6 = port4 = wport4 = -1;
370 syslog(LOG_INFO, "active mode data connection failed");
374 syslog(LOG_INFO, "active mode data connection established");
384 struct pollfd pfd[1];
388 struct timeval timeout;
391 /* get passive connection from client */
394 pfd[0].events = POLLIN;
397 if (wport6 >= FD_SETSIZE)
398 exit_failure("descriptor too big");
399 FD_SET(wport6, &set);
401 timeout.tv_sec = 120;
405 if (poll(pfd, sizeof(pfd)/sizeof(pfd[0]), timeout.tv_sec * 1000) == 0 ||
406 (port6 = accept(wport6, (struct sockaddr *)&data6, &len)) < 0)
408 if (select(wport6 + 1, &set, NULL, NULL, &timeout) == 0 ||
409 (port6 = accept(wport6, (struct sockaddr *)&data6, &len)) < 0)
414 syslog(LOG_INFO, "passive mode data connection failed");
418 /* ask passive connection to server */
419 sa = (struct sockaddr *)&data4;
420 port4 = socket(sa->sa_family, SOCK_STREAM, 0);
425 syslog(LOG_INFO, "passive mode data connection failed");
428 error = connect(port4, sa, sa->sa_len);
433 wport6 = port4 = port6 = -1;
434 syslog(LOG_INFO, "passive mode data connection failed");
438 syslog(LOG_INFO, "passive mode data connection established");
443 ftp_copy(int src, int dst)
445 int error, atmark, n;
447 /* OOB data handling */
448 error = ioctl(src, SIOCATMARK, &atmark);
449 if (error != -1 && atmark == 1) {
450 n = read(src, rbuf, 1);
453 send(dst, rbuf, n, MSG_OOB);
455 n = read(src, rbuf, sizeof(rbuf));
463 n = read(src, rbuf, sizeof(rbuf));
474 exit_failure("%s", strerror(errno));
476 return 0; /* to make gcc happy */
480 ftp_copyresult(int src, int dst, enum state state)
482 int error, atmark, n;
489 /* OOB data handling */
490 error = ioctl(src, SIOCATMARK, &atmark);
491 if (error != -1 && atmark == 1) {
492 n = read(src, rbuf, 1);
495 send(dst, rbuf, n, MSG_OOB);
497 n = read(src, rbuf, sizeof(rbuf));
505 n = read(src, rbuf, sizeof(rbuf));
514 for (i = 0; i < 3; i++) {
529 /* param points to first non-command token, if any */
530 while (*param && isspace(*param))
537 if (!passivemode && rbuf[0] == '1') {
538 if (ftp_activeconn() < 0) {
539 n = snprintf(rbuf, sizeof(rbuf),
540 "425 Cannot open data connetion\r\n");
541 if (n < 0 || n >= sizeof(rbuf))
550 /* expecting "200 PORT command successful." */
552 p = strstr(rbuf, "PORT");
554 p[0] = (state == LPRT) ? 'L' : 'E';
566 * expecting "227 Entering Passive Mode (x,x,x,x,x,x,x)"
567 * (in some cases result comes without paren)
578 unsigned int ho[4], po[2];
579 struct sockaddr_in *sin;
580 struct sockaddr_in6 *sin6;
584 * PASV result -> LPSV/EPSV result
587 while (*p && *p != '(' && !isdigit(*p)) /*)*/
590 goto passivefail0; /*XXX*/
593 n = sscanf(p, "%u,%u,%u,%u,%u,%u",
594 &ho[0], &ho[1], &ho[2], &ho[3], &po[0], &po[1]);
596 goto passivefail0; /*XXX*/
598 /* keep PORT parameter */
599 memset(&data4, 0, sizeof(data4));
600 sin = (struct sockaddr_in *)&data4;
601 sin->sin_len = sizeof(*sin);
602 sin->sin_family = AF_INET;
603 sin->sin_addr.s_addr = 0;
604 for (n = 0; n < 4; n++) {
605 sin->sin_addr.s_addr |=
606 htonl((ho[n] & 0xff) << ((3 - n) * 8));
608 sin->sin_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
610 /* get ready for passive data connection */
611 memset(&data6, 0, sizeof(data6));
612 sin6 = (struct sockaddr_in6 *)&data6;
613 sin6->sin6_len = sizeof(*sin6);
614 sin6->sin6_family = AF_INET6;
615 wport6 = socket(sin6->sin6_family, SOCK_STREAM, 0);
618 n = snprintf(sbuf, sizeof(sbuf),
619 "500 could not translate from PASV\r\n");
620 if (n < 0 || n >= sizeof(sbuf))
629 error = setsockopt(wport6, IPPROTO_IPV6, IPV6_FAITH,
632 exit_failure("setsockopt(IPV6_FAITH): %s", strerror(errno));
635 error = bind(wport6, (struct sockaddr *)sin6, sin6->sin6_len);
641 error = listen(wport6, 1);
648 /* transmit LPSV or EPSV */
650 * addr from dst, port from wport6
653 error = getsockname(wport6, (struct sockaddr *)&data6, &len);
659 sin6 = (struct sockaddr_in6 *)&data6;
660 port = sin6->sin6_port;
663 error = getsockname(dst, (struct sockaddr *)&data6, &len);
669 sin6 = (struct sockaddr_in6 *)&data6;
670 sin6->sin6_port = port;
673 a = (char *)&sin6->sin6_addr;
674 p = (char *)&sin6->sin6_port;
675 n = snprintf(sbuf, sizeof(sbuf),
676 "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",
677 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
678 UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]),
679 UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]),
680 UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]),
681 2, UC(p[0]), UC(p[1]));
682 if (n < 0 || n >= sizeof(sbuf))
689 n = snprintf(sbuf, sizeof(sbuf),
690 "229 Entering Extended Passive Mode (|||%d|)\r\n",
691 ntohs(sin6->sin6_port));
692 if (n < 0 || n >= sizeof(sbuf))
703 exit_failure("%s", strerror(errno));
705 return 0; /* to make gcc happy */
709 ftp_copycommand(int src, int dst, enum state *state)
711 int error, atmark, n;
713 unsigned int af, hal, ho[16], pal, po[2];
716 struct sockaddr_in *sin;
717 struct sockaddr_in6 *sin6;
722 /* OOB data handling */
723 error = ioctl(src, SIOCATMARK, &atmark);
724 if (error != -1 && atmark == 1) {
725 n = read(src, rbuf, 1);
728 send(dst, rbuf, n, MSG_OOB);
730 n = read(src, rbuf, sizeof(rbuf));
738 n = read(src, rbuf, sizeof(rbuf));
753 for (i = 0; i < 4; i++) {
755 /* invalid command */
759 *q++ = islower(*p) ? toupper(*p) : *p;
763 /* invalid command */
769 /* param points to first non-command token, if any */
770 while (*param && isspace(*param))
777 if (strcmp(cmd, "LPRT") == 0 && param) {
787 wport4 = wport6 = port4 = port6 = -1;
790 n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n",
792 if (n < 0 || n >= sizeof(sbuf))
800 "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
801 &af, &hal, &ho[0], &ho[1], &ho[2], &ho[3],
802 &ho[4], &ho[5], &ho[6], &ho[7],
803 &ho[8], &ho[9], &ho[10], &ho[11],
804 &ho[12], &ho[13], &ho[14], &ho[15],
805 &pal, &po[0], &po[1]);
806 if (n != 21 || af != 6 || hal != 16|| pal != 2) {
807 n = snprintf(sbuf, sizeof(sbuf),
808 "501 illegal parameter to LPRT\r\n");
809 if (n < 0 || n >= sizeof(sbuf))
816 /* keep LPRT parameter */
817 memset(&data6, 0, sizeof(data6));
818 sin6 = (struct sockaddr_in6 *)&data6;
819 sin6->sin6_len = sizeof(*sin6);
820 sin6->sin6_family = AF_INET6;
821 for (n = 0; n < 16; n++)
822 sin6->sin6_addr.s6_addr[n] = ho[n];
823 sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
826 /* get ready for active data connection */
828 error = getsockname(dst, (struct sockaddr *)&data4, &len);
831 n = snprintf(sbuf, sizeof(sbuf),
832 "500 could not translate to PORT\r\n");
833 if (n < 0 || n >= sizeof(sbuf))
839 if (((struct sockaddr *)&data4)->sa_family != AF_INET)
841 sin = (struct sockaddr_in *)&data4;
843 wport4 = socket(sin->sin_family, SOCK_STREAM, 0);
846 error = bind(wport4, (struct sockaddr *)sin, sin->sin_len);
852 error = listen(wport4, 1);
861 error = getsockname(wport4, (struct sockaddr *)&data4, &len);
867 if (((struct sockaddr *)&data4)->sa_family != AF_INET) {
872 sin = (struct sockaddr_in *)&data4;
873 a = (char *)&sin->sin_addr;
874 p = (char *)&sin->sin_port;
875 n = snprintf(sbuf, sizeof(sbuf), "PORT %d,%d,%d,%d,%d,%d\r\n",
876 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
878 if (n < 0 || n >= sizeof(sbuf))
885 } else if (strcmp(cmd, "EPRT") == 0 && param) {
889 char *afp, *hostp, *portp;
890 struct addrinfo hints, *res;
898 wport4 = wport6 = port4 = port6 = -1;
901 n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n",
903 if (n < 0 || n >= sizeof(sbuf))
911 ch = *p++; /* boundary character */
913 while (*p && *p != ch)
917 n = snprintf(sbuf, sizeof(sbuf),
918 "501 illegal parameter to EPRT\r\n");
919 if (n < 0 || n >= sizeof(sbuf))
927 while (*p && *p != ch)
933 while (*p && *p != ch)
939 n = sscanf(afp, "%d", &af);
940 if (n != 1 || af != 2) {
941 n = snprintf(sbuf, sizeof(sbuf),
942 "501 unsupported address family to EPRT\r\n");
943 if (n < 0 || n >= sizeof(sbuf))
949 memset(&hints, 0, sizeof(hints));
950 hints.ai_family = AF_UNSPEC;
951 hints.ai_socktype = SOCK_STREAM;
952 hints.ai_protocol = IPPROTO_TCP;
953 error = getaddrinfo(hostp, portp, &hints, &res);
955 n = snprintf(sbuf, sizeof(sbuf),
956 "501 EPRT: %s\r\n", gai_strerror(error));
957 if (n < 0 || n >= sizeof(sbuf))
964 n = snprintf(sbuf, sizeof(sbuf),
965 "501 EPRT: %s resolved to multiple addresses\r\n", hostp);
966 if (n < 0 || n >= sizeof(sbuf))
975 memcpy(&data6, res->ai_addr, res->ai_addrlen);
978 } else if (strcmp(cmd, "LPSV") == 0 && !param) {
988 wport4 = wport6 = port4 = port6 = -1;
991 n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n",
993 if (n < 0 || n >= sizeof(sbuf))
1001 n = snprintf(sbuf, sizeof(sbuf), "PASV\r\n");
1002 if (n < 0 || n >= sizeof(sbuf))
1005 write(dst, sbuf, n);
1007 passivemode = 0; /* to be set to 1 later */
1009 } else if (strcmp(cmd, "EPSV") == 0 && !param) {
1017 wport4 = wport6 = port4 = port6 = -1;
1019 n = snprintf(sbuf, sizeof(sbuf), "PASV\r\n");
1020 if (n < 0 || n >= sizeof(sbuf))
1023 write(dst, sbuf, n);
1025 passivemode = 0; /* to be set to 1 later */
1027 } else if (strcmp(cmd, "EPSV") == 0 && param
1028 && strncasecmp(param, "ALL", 3) == 0 && isspace(param[3])) {
1033 n = snprintf(sbuf, sizeof(sbuf), "200 EPSV ALL command successful.\r\n");
1034 if (n < 0 || n >= sizeof(sbuf))
1037 write(src, sbuf, n);
1039 } else if (strcmp(cmd, "PORT") == 0 || strcmp(cmd, "PASV") == 0) {
1043 n = snprintf(sbuf, sizeof(sbuf), "502 %s not implemented.\r\n", cmd);
1044 if (n < 0 || n >= sizeof(sbuf))
1047 write(src, sbuf, n);
1049 } else if (passivemode
1050 && (strcmp(cmd, "STOR") == 0
1051 || strcmp(cmd, "STOU") == 0
1052 || strcmp(cmd, "RETR") == 0
1053 || strcmp(cmd, "LIST") == 0
1054 || strcmp(cmd, "NLST") == 0
1055 || strcmp(cmd, "APPE") == 0)) {
1057 * commands with data transfer. need to care about passive
1058 * mode data connection.
1061 if (ftp_passiveconn() < 0) {
1062 n = snprintf(sbuf, sizeof(sbuf), "425 Cannot open data connetion\r\n");
1063 if (n < 0 || n >= sizeof(sbuf))
1066 write(src, sbuf, n);
1068 /* simply relay the command */
1069 write(dst, rbuf, n);
1075 /* simply relay it */
1077 write(dst, rbuf, n);
1082 exit_failure("%s", strerror(errno));
1084 return 0; /* to make gcc happy */