]> granicus.if.org Git - php/commitdiff
Implement FR #55651 (Option to ignore the returned FTP PASV address)
authorAvi Brender <abrender@elitehosts.com>
Thu, 10 Dec 2015 09:37:03 +0000 (11:37 +0200)
committerLior Kaplan <kaplanlior@gmail.com>
Tue, 15 Dec 2015 09:07:40 +0000 (11:07 +0200)
ext/ftp/ftp.c
ext/ftp/ftp.h
ext/ftp/php_ftp.c
ext/ftp/php_ftp.h

index d40e964b7fc73c150c9313d9229a9a427ee013b4..01ec36b0969e1e2f9cec226ac1dc6bc43a4c0c9e 100644 (file)
@@ -722,10 +722,11 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
        memset(&ftp->pasvaddr, 0, n);
        sa = (struct sockaddr *) &ftp->pasvaddr;
 
-#if HAVE_IPV6
        if (getpeername(ftp->fd, sa, &n) < 0) {
                return 0;
        }
+
+#if HAVE_IPV6
        if (sa->sa_family == AF_INET6) {
                struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
                char *endptr, delimiter;
@@ -778,8 +779,9 @@ ftp_pasv(ftpbuf_t *ftp, int pasv)
                ipbox.c[n] = (unsigned char) b[n];
        }
        sin = (struct sockaddr_in *) sa;
-       sin->sin_family = AF_INET;
-       sin->sin_addr = ipbox.ia[0];
+       if (ftp->usepasvaddress) {
+               sin->sin_addr = ipbox.ia[0];
+       }
        sin->sin_port = ipbox.s[2];
 
        ftp->pasv = 2;
index 41781ddb173124b2a6bc3accf04daf051e86e44d..201ec5d5711a72c2a68d38d0aab4e64ff81bbbe0 100644 (file)
@@ -31,6 +31,7 @@
 
 #define        FTP_DEFAULT_TIMEOUT     90
 #define FTP_DEFAULT_AUTOSEEK 1
+#define FTP_DEFAULT_USEPASVADDRESS     1
 #define PHP_FTP_FAILED                 0
 #define PHP_FTP_FINISHED               1
 #define PHP_FTP_MOREDATA               2
@@ -71,6 +72,7 @@ typedef struct ftpbuf
        php_sockaddr_storage    pasvaddr;       /* passive mode address */
        long    timeout_sec;    /* User configurable timeout (seconds) */
        int                     autoseek;       /* User configurable autoseek flag */
+       int                     usepasvaddress; /* Use the address returned by the pasv command */
 
        int                             nb;             /* "nonblocking" transfer in progress */
        databuf_t               *data;  /* Data connection for "nonblocking" transfers */
index 9a8680ccf6879a17a0a2c13af32dea49a3712468..dc474dfefd5cd1ea439a0851fa9614cbde46aec8 100644 (file)
@@ -315,6 +315,7 @@ PHP_MINIT_FUNCTION(ftp)
        REGISTER_LONG_CONSTANT("FTP_AUTORESUME", PHP_FTP_AUTORESUME, CONST_PERSISTENT | CONST_CS);
        REGISTER_LONG_CONSTANT("FTP_TIMEOUT_SEC", PHP_FTP_OPT_TIMEOUT_SEC, CONST_PERSISTENT | CONST_CS);
        REGISTER_LONG_CONSTANT("FTP_AUTOSEEK", PHP_FTP_OPT_AUTOSEEK, CONST_PERSISTENT | CONST_CS);
+       REGISTER_LONG_CONSTANT("FTP_USEPASVADDRESS", PHP_FTP_OPT_USEPASVADDRESS, CONST_PERSISTENT | CONST_CS);
        REGISTER_LONG_CONSTANT("FTP_FAILED", PHP_FTP_FAILED, CONST_PERSISTENT | CONST_CS);
        REGISTER_LONG_CONSTANT("FTP_FINISHED", PHP_FTP_FINISHED, CONST_PERSISTENT | CONST_CS);
        REGISTER_LONG_CONSTANT("FTP_MOREDATA", PHP_FTP_MOREDATA, CONST_PERSISTENT | CONST_CS);
@@ -363,6 +364,7 @@ PHP_FUNCTION(ftp_connect)
 
        /* autoseek for resuming */
        ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
+       ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
 #if HAVE_OPENSSL_EXT
        /* disable ssl */
        ftp->use_ssl = 0;
@@ -399,6 +401,7 @@ PHP_FUNCTION(ftp_ssl_connect)
 
        /* autoseek for resuming */
        ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
+       ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
        /* enable ssl */
        ftp->use_ssl = 1;
 
@@ -1399,6 +1402,15 @@ PHP_FUNCTION(ftp_set_option)
                        ftp->autoseek = Z_LVAL_P(z_value);
                        RETURN_TRUE;
                        break;
+               case PHP_FTP_OPT_USEPASVADDRESS:
+                       if (Z_TYPE_P(z_value) != IS_BOOL) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Option USEPASVADDRESS expects value of type boolean, %s given",
+                                       zend_zval_type_name(z_value));
+                               RETURN_FALSE;
+                       }
+                       ftp->usepasvaddress = Z_LVAL_P(z_value);
+                       RETURN_TRUE;
+                       break;
                default:
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option '%ld'", option);
                        RETURN_FALSE;
@@ -1428,6 +1440,9 @@ PHP_FUNCTION(ftp_get_option)
                case PHP_FTP_OPT_AUTOSEEK:
                        RETURN_BOOL(ftp->autoseek);
                        break;
+               case PHP_FTP_OPT_USEPASVADDRESS:
+                       RETURN_BOOL(ftp->usepasvaddress);
+                       break;
                default:
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown option '%ld'", option);
                        RETURN_FALSE;
index 40e03ffa024606bcda51e95bad7306449c7d4531..6b52fa658cd48066e670e5f5fcb75b85dd0f0081 100644 (file)
@@ -29,6 +29,7 @@ extern zend_module_entry php_ftp_module_entry;
 
 #define PHP_FTP_OPT_TIMEOUT_SEC        0
 #define PHP_FTP_OPT_AUTOSEEK   1
+#define PHP_FTP_OPT_USEPASVADDRESS     2
 #define PHP_FTP_AUTORESUME             -1
 
 PHP_MINIT_FUNCTION(ftp);