php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #55651
Patch ftp_usepasvaddress_php70.patch.patch revision 2016-01-23 04:52 UTC by edistro01 at gmail dot com
Patch ftp_usepasvaddress_php70.patch revision 2015-12-10 12:00 UTC by kaplan@php.net
Patch ftp_usepasvaddress.patch revision 2011-09-09 08:10 UTC by abrender at elitehosts dot com

Patch ftp_usepasvaddress_php70.patch for FTP related Bug #55651

Patch version 2015-12-10 12:00 UTC

Return to Bug #55651 | Download this patch
Patch Revisions:

Developer: kaplan@php.net

commit dd27f6a3cdaff3d8a5f3bbcad61953db7b45facf
Author: Avi Brender <abrender@elitehosts.com>
Date:   Thu Dec 10 13:36:09 2015 +0200

    Implement FR #55651: (Option to ignore the returned FTP PASV address)

diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
index bb41b1a..41aa378 100644
--- a/ext/ftp/ftp.c
+++ b/ext/ftp/ftp.c
@@ -754,10 +754,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;
@@ -810,8 +811,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;
+	if (ftp->usepasvaddress) {
 	sin->sin_addr = ipbox.ia[0];
+	}
 	sin->sin_port = ipbox.s[2];
 
 	ftp->pasv = 2;
diff --git a/ext/ftp/ftp.h b/ext/ftp/ftp.h
index 546c69c..1b699b2 100644
--- a/ext/ftp/ftp.h
+++ b/ext/ftp/ftp.h
@@ -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 */
 	zend_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 */
diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c
index eaed5c6..7c958fb 100644
--- a/ext/ftp/php_ftp.c
+++ b/ext/ftp/php_ftp.c
@@ -326,6 +326,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);
@@ -379,6 +380,7 @@ PHP_FUNCTION(ftp_connect)
 
 	/* autoseek for resuming */
 	ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
+	ftp->usepasvaddress = FTP_DEFAULT_USEPASVADDRESS;
 #ifdef HAVE_FTP_SSL
 	/* disable ssl */
 	ftp->use_ssl = 0;
@@ -415,6 +417,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;
 
@@ -1478,6 +1481,15 @@ PHP_FUNCTION(ftp_set_option)
 			ftp->autoseek = Z_TYPE_P(z_value) == IS_TRUE ? 1 : 0;
 			RETURN_TRUE;
 			break;
+		case PHP_FTP_OPT_USEPASVADDRESS:
+			if (Z_TYPE_P(z_value) != IS_TRUE && Z_TYPE_P(z_value) != IS_FALSE) {
+				php_error_docref(NULL, 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, E_WARNING, "Unknown option '%pd'", option);
 			RETURN_FALSE;
@@ -1509,6 +1521,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, E_WARNING, "Unknown option '%pd'", option);
 			RETURN_FALSE;
diff --git a/ext/ftp/php_ftp.h b/ext/ftp/php_ftp.h
index 3ddc76f..8000a3e 100644
--- a/ext/ftp/php_ftp.h
+++ b/ext/ftp/php_ftp.h
@@ -32,6 +32,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);
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 20:01:29 2024 UTC