ID: 42492 User updated by: php at stock-consulting dot com Reported By: php at stock-consulting dot com Status: Open Bug Type: FTP related Operating System: Windows 2000 PHP Version: 5.2.4 New Comment:
Further thoughts. It appears to me that the message "PORT command only accepts..." originates from the FTP server. "PORT command"? What "PORT command"? I thought I was using PASV? Exactly. I can confim that I use ftp_pasv($ftp, true) once, and that I never turn passive mode off. So apparently the FTP functions somehow seem to "forget" (at some random point) that they should use PASV mode. Always suspicious as I am, this smells like something like buffer overflow to me. Let's have a look at ftp.h: typedef struct ftpbuf { php_socket_t fd; /* control connection */ php_sockaddr_storage localaddr; /* local address */ int resp; /* last response code */ char inbuf[FTP_BUFSIZE]; /* last response text */ char *extra; /* extra characters */ int extralen; /* number of extra chars */ char outbuf[FTP_BUFSIZE]; /* command output buffer */ char *pwd; /* cached pwd */ char *syst; /* cached system type */ ftptype_t type; /* current transfer type */ int pasv; /* 0=off; 1=pasv; 2=ready */ <snip> Hm, candiates might be inbuf and outbuf. However, a look at the code pieces which might be primary candidates for a buffer overflow revealed nothing suspicious to me. However, I stumbled across a piece a code which looked kinda fishy to me, beginning at line 1140 in ftp.c: /* shift the extra to the front */ size = FTP_BUFSIZE; rcvd = 0; if (ftp->extra) { memmove(ftp->inbuf, ftp->extra, ftp->extralen); rcvd = ftp->extralen; } ftp->extra, together with ftp->textralen, appear to be essentiall unbounded. Yuk! Now, I don't see any place where ftp->extra or ftp->extralen gets set. I should have a look at the initilization code, to find out if it gets at least initialized correctly. As soon as time permits - currently I have no time and so I've to leave this scene of investivation :-( Best regards, Klaus Previous Comments: ------------------------------------------------------------------------ [2007-08-31 13:07:04] php at stock-consulting dot com Yes, defnitely, I just downloaded it...yesterday? F***! ***! *** ** * ****!!!!! Just checked it (php.exe -v). It's PHP 5.2.3. Okay. Sorry. Upgraded to 5.2.4 now, checked (php.exe -v), yup, now I'm at 5.2.4! Yup. I can confirm the bug in 5.2.4 as well. The warning is now: Warning: ftp_get(): PORT command only accepts client IP address (80.x.x.x!= 10.0.0.1). in my_script.php on line 71 Best regards, Klaus ------------------------------------------------------------------------ [2007-08-31 11:27:49] [EMAIL PROTECTED] And you're really using PHP 5.2.4? ------------------------------------------------------------------------ [2007-08-31 11:15:27] php at stock-consulting dot com Description: ------------ Situation: the local machine, which executes the PHP script via the command line, sits behind a NAT firefall and needs to retrieve directory listings and files from an FTP server sitting somewhere on the Internet. Passive FTP is required to traverse the firewall. The local machine has the IP address 10.0.0.1 (subnet configured as Class C). The external (WAN) IP of the router/firewall is 80.x.x.x (address partially concealed to protect the, erm, innocent). Now the problem: the script correctly connects to the FTP server and begins to retrieve directory listings (recursively) and files. At some RANDOM point, the following warning appears: Warning: ftp_chdir(): PORT command only accepts client IP address (80.x.x.x !=10.0.0.1). in my_script.php on line 40 This warning then appears both at all further attempts to retrieve directory listings and files. The transfers are not successful. Note that directory and file retrieval works perfectly UNTIL the warning occurs for the first time, at some random time. When the script is restarted, it will again work for some listings and files, until, at some different point, the warning will appear again. Reproduce code: --------------- // Short version, stripped from anything which appeared not so useful for this bug report function remote_scan($path) { global $ftp; ftp_chdir($ftp, $path); $raw_entries = ftp_rawlist($ftp, $path); foreach ($raw_entries AS $line) { $entry = preg_split('@\s+@', $line, 9); if ($entry[4] == 0) { remote_scan($path . $entry[8] . '/'); } else { ftp_get($ftp, 'x:/local_path' . $path . $entry[8], $path . $entry[8], FTP_BINARY); } } } $ftp = ftp_connect('ftp.url', 47624); // server uses non-standard port $login_result = ftp_login($ftp, 'user', 'password'); ftp_pasv($ftp, true); remote_scan('/'); ftp_close($ftp); ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=42492&edit=1