Index: squid/src/cf.data.pre diff -c squid/src/cf.data.pre:1.199.2.8 squid/src/cf.data.pre:1.199.2.9 *** squid/src/cf.data.pre:1.199.2.8 Fri Apr 5 01:58:22 2002 --- squid/src/cf.data.pre Sun Jun 23 14:10:16 2002 *************** *** 969,974 **** --- 969,986 ---- connections, then turn off this option. DOC_END + NAME: ftp_sanitycheck + TYPE: onoff + DEFAULT: on + LOC: Config.Ftp.sanitycheck + DOC_START + For security and data integrity reasons Squid by default performs + sanity checks of the addresses of FTP data connections ensure the + data connection is to the requested server. If you need to allow + FTP connections to servers using another IP address for the data + connection then turn this off. + DOC_END + NAME: cache_dns_program TYPE: string IFDEF: USE_DNSSERVERS Index: squid/src/ftp.c diff -c squid/src/ftp.c:1.298.2.6 squid/src/ftp.c:1.298.2.7 *** squid/src/ftp.c:1.298.2.6 Sat Feb 16 17:41:18 2002 --- squid/src/ftp.c Sun Jun 23 14:10:16 2002 *************** *** 1020,1026 **** strCat(ftpState->base_href, rfc1738_escape_part(ftpState->password)); } strCat(ftpState->base_href, "@"); ! } strCat(ftpState->base_href, request->host); if (request->port != urlDefaultPort(PROTO_FTP)) { strCat(ftpState->base_href, ":"); --- 1020,1026 ---- strCat(ftpState->base_href, rfc1738_escape_part(ftpState->password)); } strCat(ftpState->base_href, "@"); ! } strCat(ftpState->base_href, request->host); if (request->port != urlDefaultPort(PROTO_FTP)) { strCat(ftpState->base_href, ":"); *************** *** 1721,1727 **** u_short port; int fd = ftpState->data.fd; char *buf = ftpState->ctrl.last_reply; ! LOCAL_ARRAY(char, junk, 1024); debug(9, 3) ("This is ftpReadPasv\n"); if (code != 227) { debug(9, 3) ("PASV not supported by remote end\n"); --- 1721,1727 ---- u_short port; int fd = ftpState->data.fd; char *buf = ftpState->ctrl.last_reply; ! LOCAL_ARRAY(char, ipaddr, 1024); debug(9, 3) ("This is ftpReadPasv\n"); if (code != 227) { debug(9, 3) ("PASV not supported by remote end\n"); *************** *** 1737,1752 **** /* ANSI sez [^0-9] is undefined, it breaks on Watcom cc */ debug(9, 5) ("scanning: %s\n", buf); n = sscanf(buf, "%[^0123456789]%d,%d,%d,%d,%d,%d", ! junk, &h1, &h2, &h3, &h4, &p1, &p2); if (n != 7 || p1 < 0 || p2 < 0 || p1 > 255 || p2 > 255) { debug(9, 3) ("Bad 227 reply\n"); debug(9, 3) ("n=%d, p1=%d, p2=%d\n", n, p1, p2); ftpSendPort(ftpState); return; } ! snprintf(junk, 1024, "%d.%d.%d.%d", h1, h2, h3, h4); ! if (!safe_inet_addr(junk, NULL)) { ! debug(9, 1) ("unsafe address (%s)\n", junk); ftpSendPort(ftpState); return; } --- 1737,1752 ---- /* ANSI sez [^0-9] is undefined, it breaks on Watcom cc */ debug(9, 5) ("scanning: %s\n", buf); n = sscanf(buf, "%[^0123456789]%d,%d,%d,%d,%d,%d", ! ipaddr, &h1, &h2, &h3, &h4, &p1, &p2); if (n != 7 || p1 < 0 || p2 < 0 || p1 > 255 || p2 > 255) { debug(9, 3) ("Bad 227 reply\n"); debug(9, 3) ("n=%d, p1=%d, p2=%d\n", n, p1, p2); ftpSendPort(ftpState); return; } ! snprintf(ipaddr, 1024, "%d.%d.%d.%d", h1, h2, h3, h4); ! if (!safe_inet_addr(ipaddr, NULL)) { ! debug(9, 1) ("unsafe PASV address (%s) from %s\n", ipaddr, fd_table[ftpState->ctrl.fd].ipaddr); ftpSendPort(ftpState); return; } *************** *** 1756,1768 **** ftpSendPort(ftpState); return; } ! debug(9, 5) ("ftpReadPasv: connecting to %s, port %d\n", junk, port); ftpState->data.port = port; ! ftpState->data.host = xstrdup(junk); safe_free(ftpState->ctrl.last_command); safe_free(ftpState->ctrl.last_reply); ftpState->ctrl.last_command = xstrdup("Connect to server data port"); ! commConnectStart(fd, junk, port, ftpPasvCallback, ftpState); } static void --- 1756,1780 ---- ftpSendPort(ftpState); return; } ! if (Config.Ftp.sanitycheck) { ! if (strcmp(fd_table[ftpState->ctrl.fd].ipaddr, ipaddr) != 0) { ! debug(9, 1) ("unsafe PASV address (%s) from %s\n", ipaddr, fd_table[ftpState->ctrl.fd].ipaddr); ! ftpSendPort(ftpState); ! return; ! } ! if (port < 1024) { ! debug(9, 1) ("unsafe PASV port (%d) from %s\n", port, fd_table[ftpState->ctrl.fd].ipaddr); ! ftpSendPort(ftpState); ! return; ! } ! } ! debug(9, 5) ("ftpReadPasv: connecting to %s, port %d\n", ipaddr, port); ftpState->data.port = port; ! ftpState->data.host = xstrdup(ipaddr); safe_free(ftpState->ctrl.last_command); safe_free(ftpState->ctrl.last_reply); ftpState->ctrl.last_command = xstrdup("Connect to server data port"); ! commConnectStart(fd, ipaddr, port, ftpPasvCallback, ftpState); } static void *************** *** 1889,1894 **** --- 1901,1919 ---- return; } fd = comm_accept(fd, &my_peer, &me); + if (Config.Ftp.sanitycheck) { + char *ipaddr = inet_ntoa(my_peer.sin_addr); + if (strcmp(fd_table[ftpState->ctrl.fd].ipaddr, ipaddr) != 0) { + debug(9, 1) ("FTP data connection from unexpected server (%s:%d), expecting %s\n", ipaddr, (int) ntohs(my_peer.sin_port), fd_table[ftpState->ctrl.fd].ipaddr); + comm_close(fd); + commSetSelect(ftpState->data.fd, + COMM_SELECT_READ, + ftpAcceptDataConnection, + ftpState, + 0); + return; + } + } if (fd < 0) { debug(9, 1) ("ftpHandleDataAccept: comm_accept(%d): %s", fd, xstrerror()); /* XXX Need to set error message */ Index: squid/src/structs.h diff -c squid/src/structs.h:1.361.2.15 squid/src/structs.h:1.361.2.16 *** squid/src/structs.h:1.361.2.15 Mon Oct 8 09:22:03 2001 --- squid/src/structs.h Sun Jun 23 14:10:17 2002 *************** *** 459,464 **** --- 459,465 ---- int list_wrap; char *anon_user; int passive; + int sanitycheck; } Ftp; refresh_t *Refresh; struct _cacheSwap {