diff --git a/appl/ftp/ftpd/ftpcmd.y b/appl/ftp/ftpd/ftpcmd.y index eb672fdbb..07da7a460 100644 --- a/appl/ftp/ftpd/ftpcmd.y +++ b/appl/ftp/ftpd/ftpcmd.y @@ -150,15 +150,26 @@ cmd memset ($3, 0, strlen($3)); free($3); } + | PORT SP host_port CRLF check_secure { if ($5) { - usedefault = 0; - if (pdata >= 0) { + if (paranoid && + (data_dest->sa_family != AF_INET || + (ntohs(data_dest->sin_port) < IPPORT_RESERVED) || + memcmp(data_dest->sin_addr, + &his_addr->sin_addr, + sizeof(data_dest.sin_addr)) != 0)) { + usedefault = 1; + reply(500, "Illegal PORT range rejected."); + } else { + usedefault = 0; + if (pdata >= 0) { close(pdata); pdata = -1; + } + reply(200, "PORT command successful."); } - reply(200, "PORT command successful."); } } | EPRT SP STRING CRLF check_secure diff --git a/appl/ftp/ftpd/ftpd.c b/appl/ftp/ftpd/ftpd.c index 512b98561..c565d3373 100644 --- a/appl/ftp/ftpd/ftpd.c +++ b/appl/ftp/ftpd/ftpd.c @@ -91,6 +91,7 @@ char tmpline[10240]; char hostname[MaxHostNameLen]; char remotehost[MaxHostNameLen]; static char ttyline[20]; +int paranoid = 1; #define AUTH_PLAIN (1 << 0) /* allow sending passwords */ #define AUTH_OTP (1 << 1) /* passwords are one-time */ @@ -2123,7 +2124,18 @@ eprt(char *str) reply(500, "Bad port syntax in EPRT"); return; } + if (port < IPPORT_RESERVED) { + reply(500, "Bad port in invalid range in EPRT"); + return; + } socket_set_port (data_dest, htons(port)); + + if (paranoid && + (data_dest->sa_family != his_addr->sa_family || + memcmp(socket_get_address(data_dest), socket_get_address(his_addr), socket_sockaddr_size(data_dest)) != 0)) + { + reply(500, "Bad address in EPRT"); + } reply(200, "EPRT command successful."); }