diff options
author | Tristan Darricau <tristan.darricau@sensiolabs.com> | 2016-02-11 22:16:10 +0100 |
---|---|---|
committer | Tristan Darricau <tristan.darricau@sensiolabs.com> | 2016-02-11 22:16:10 +0100 |
commit | c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b (patch) | |
tree | d1a901b18261466f47a5db5cc1cf9362a9974a1f | |
parent | aa6dd6d4ff28f38f9596b7bb3adf19a8a7988b67 (diff) | |
parent | 8cf086ef9b200f0b59348c0f0d4946f9ebc4adae (diff) | |
download | forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.tar forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.tar.gz forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.tar.bz2 forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.tar.xz forums-c9e5d308f2ebaae5ddaa70faf25af93fe2eb368b.zip |
Merge pull request #4159 from marc1706/ticket/14448
[ticket/14448] Use guzzle for remote files uploading
* marc1706/ticket/14448:
[ticket/14448] Correctly pass verify setting if available
[ticket/14448] Let user decide if remote upload certs should be checked
[ticket/14448] Add new vendor files and dirs to clean task
[ticket/14448] Do not try to test remote upload timeout
[ticket/14448] Remove no longer needed guzzle 3.9.3
[ticket/14448] Use GuzzleHttp and try to verify certs
[ticket/14448] Update composer.json and lock file for guzzlehttp
[ticket/14431] Remote avatar uploading
[ticket/14431] Remote avatar uploading
-rw-r--r-- | build/build.xml | 36 | ||||
-rw-r--r-- | phpBB/composer.json | 1 | ||||
-rw-r--r-- | phpBB/composer.lock | 505 | ||||
-rw-r--r-- | phpBB/config/default/container/services_files.yml | 1 | ||||
-rw-r--r-- | phpBB/includes/acp/acp_board.php | 1 | ||||
-rw-r--r-- | phpBB/install/schemas/schema_data.sql | 1 | ||||
-rw-r--r-- | phpBB/language/en/acp/board.php | 2 | ||||
-rw-r--r-- | phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php | 31 | ||||
-rw-r--r-- | phpBB/phpbb/files/types/remote.php | 128 | ||||
-rw-r--r-- | tests/files/types_remote_test.php | 24 | ||||
-rw-r--r-- | tests/functional/fileupload_remote_test.php | 5 |
11 files changed, 323 insertions, 412 deletions
diff --git a/build/build.xml b/build/build.xml index e6862c0886..6d5b652b0a 100644 --- a/build/build.xml +++ b/build/build.xml @@ -318,6 +318,35 @@ <delete file="${dir}/vendor/google/recaptcha/phpunit.xml.dist" /> <delete file="${dir}/vendor/google/recaptcha/README.md" /> + <delete dir="${dir}/vendor/guzzlehttp/guzzle/build" /> + <delete dir="${dir}/vendor/guzzlehttp/guzzle/docs" /> + <delete dir="${dir}/vendor/guzzlehttp/guzzle/tests" /> + <delete file="${dir}/vendor/guzzlehttp/guzzle/CHANGELOG.md" /> + <delete file="${dir}/vendor/guzzlehttp/guzzle/.editorconfig" /> + <delete file="${dir}/vendor/guzzlehttp/guzzle/.gitignore" /> + <delete file="${dir}/vendor/guzzlehttp/guzzle/Makefile" /> + <delete file="${dir}/vendor/guzzlehttp/guzzle/phpunit.xml.dist" /> + <delete file="${dir}/vendor/guzzlehttp/guzzle/README.md" /> + <delete file="${dir}/vendor/guzzlehttp/guzzle/.travis.yml" /> + <delete file="${dir}/vendor/guzzlehttp/guzzle/UPGRADING.md" /> + + <delete dir="${dir}/vendor/guzzlehttp/ringphp/docs" /> + <delete dir="${dir}/vendor/guzzlehttp/ringphp/tests" /> + <delete file="${dir}/vendor/guzzlehttp/ringphp/CHANGELOG.md" /> + <delete file="${dir}/vendor/guzzlehttp/ringphp/.gitignore" /> + <delete file="${dir}/vendor/guzzlehttp/ringphp/Makefile" /> + <delete file="${dir}/vendor/guzzlehttp/ringphp/phpunit.xml.dist" /> + <delete file="${dir}/vendor/guzzlehttp/ringphp/README.rst" /> + <delete file="${dir}/vendor/guzzlehttp/ringphp/.travis.yml" /> + + <delete dir="${dir}/vendor/guzzlehttp/streams/tests" /> + <delete file="${dir}/vendor/guzzlehttp/streams/CHANGELOG.rst" /> + <delete file="${dir}/vendor/guzzlehttp/streams/.gitignore" /> + <delete file="${dir}/vendor/guzzlehttp/streams/Makefile" /> + <delete file="${dir}/vendor/guzzlehttp/streams/phpunit.xml.dist" /> + <delete file="${dir}/vendor/guzzlehttp/streams/README.rst" /> + <delete file="${dir}/vendor/guzzlehttp/streams/.travis.yml" /> + <delete dir="${dir}/vendor/lusitanian/oauth/examples" /> <delete dir="${dir}/vendor/lusitanian/oauth/tests" /> <delete file="${dir}/vendor/lusitanian/oauth/.gitignore" /> @@ -335,6 +364,13 @@ <delete file="${dir}/vendor/psr/log/.gitignore" /> <delete file="${dir}/vendor/psr/log/README.md" /> + <delete dir="${dir}/vendor/react/promise/tests" /> + <delete file="${dir}/vendor/react/promise/CHANGELOG.md" /> + <delete file="${dir}/vendor/react/promise/.gitignore" /> + <delete file="${dir}/vendor/react/promise/phpunit.xml.dist" /> + <delete file="${dir}/vendor/react/promise/README.md" /> + <delete file="${dir}/vendor/react/promise/.travis.yml" /> + <delete dir="${dir}/vendor/s9e/text-formatter/.git" /> <delete dir="${dir}/vendor/symfony/config/.git" /> diff --git a/phpBB/composer.json b/phpBB/composer.json index 89bbce4588..a6c3a2aa93 100644 --- a/phpBB/composer.json +++ b/phpBB/composer.json @@ -28,6 +28,7 @@ "php": ">=5.4,<7.1", "bantu/ini-get-wrapper": "1.0.*", "google/recaptcha": "~1.1", + "guzzlehttp/guzzle": "~5.3", "lusitanian/oauth": "^0.8.1", "marc1706/fast-image-size": "1.1.*", "patchwork/utf8": "1.1.*", diff --git a/phpBB/composer.lock b/phpBB/composer.lock index 6412029b0b..cad14d8913 100644 --- a/phpBB/composer.lock +++ b/phpBB/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "f76b5185058599cad6a87ef7c8c35fbf", - "content-hash": "b89d3c18f8d9b3c4dc476f92030a83a1", + "hash": "d4e2fb7ee961c4734df4e385db2e6995", + "content-hash": "b15dfee84d1e9f3e2f5a3cc290b0be58", "packages": [ { "name": "bantu/ini-get-wrapper", @@ -83,6 +83,165 @@ "time": "2015-09-02 17:23:59" }, { + "name": "guzzlehttp/guzzle", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "f3c8c22471cb55475105c14769644a49c3262b93" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f3c8c22471cb55475105c14769644a49c3262b93", + "reference": "f3c8c22471cb55475105c14769644a49c3262b93", + "shasum": "" + }, + "require": { + "guzzlehttp/ringphp": "^1.1", + "php": ">=5.4.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0", + "psr/log": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2015-05-20 03:47:55" + }, + { + "name": "guzzlehttp/ringphp", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/RingPHP.git", + "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "shasum": "" + }, + "require": { + "guzzlehttp/streams": "~3.0", + "php": ">=5.4.0", + "react/promise": "~2.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Ring\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", + "time": "2015-05-20 03:37:09" + }, + { + "name": "guzzlehttp/streams", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/streams.git", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple abstraction over streams of data", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ], + "time": "2014-10-12 19:18:40" + }, + { "name": "ircmaxell/password-compat", "version": "v1.0.4", "source": { @@ -332,6 +491,50 @@ "time": "2012-12-21 11:40:51" }, { + "name": "react/promise", + "version": "v2.2.1", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627", + "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "time": "2015-07-03 13:48:55" + }, + { "name": "s9e/text-formatter", "version": "0.4.8", "source": { @@ -1404,260 +1607,6 @@ "time": "2015-05-05 21:14:57" }, { - "name": "guzzle/guzzle", - "version": "v3.9.3", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle3.git", - "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9", - "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "php": ">=5.3.3", - "symfony/event-dispatcher": "~2.1" - }, - "replace": { - "guzzle/batch": "self.version", - "guzzle/cache": "self.version", - "guzzle/common": "self.version", - "guzzle/http": "self.version", - "guzzle/inflection": "self.version", - "guzzle/iterator": "self.version", - "guzzle/log": "self.version", - "guzzle/parser": "self.version", - "guzzle/plugin": "self.version", - "guzzle/plugin-async": "self.version", - "guzzle/plugin-backoff": "self.version", - "guzzle/plugin-cache": "self.version", - "guzzle/plugin-cookie": "self.version", - "guzzle/plugin-curlauth": "self.version", - "guzzle/plugin-error-response": "self.version", - "guzzle/plugin-history": "self.version", - "guzzle/plugin-log": "self.version", - "guzzle/plugin-md5": "self.version", - "guzzle/plugin-mock": "self.version", - "guzzle/plugin-oauth": "self.version", - "guzzle/service": "self.version", - "guzzle/stream": "self.version" - }, - "require-dev": { - "doctrine/cache": "~1.3", - "monolog/monolog": "~1.0", - "phpunit/phpunit": "3.7.*", - "psr/log": "~1.0", - "symfony/class-loader": "~2.1", - "zendframework/zend-cache": "2.*,<2.3", - "zendframework/zend-log": "2.*,<2.3" - }, - "suggest": { - "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.9-dev" - } - }, - "autoload": { - "psr-0": { - "Guzzle": "src/", - "Guzzle\\Tests": "tests/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Guzzle Community", - "homepage": "https://github.com/guzzle/guzzle/contributors" - } - ], - "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2015-03-18 18:23:50" - }, - { - "name": "guzzlehttp/guzzle", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "f3c8c22471cb55475105c14769644a49c3262b93" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f3c8c22471cb55475105c14769644a49c3262b93", - "reference": "f3c8c22471cb55475105c14769644a49c3262b93", - "shasum": "" - }, - "require": { - "guzzlehttp/ringphp": "^1.1", - "php": ">=5.4.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "^4.0", - "psr/log": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "rest", - "web service" - ], - "time": "2015-05-20 03:47:55" - }, - { - "name": "guzzlehttp/ringphp", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/RingPHP.git", - "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", - "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", - "shasum": "" - }, - "require": { - "guzzlehttp/streams": "~3.0", - "php": ">=5.4.0", - "react/promise": "~2.0" - }, - "require-dev": { - "ext-curl": "*", - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "ext-curl": "Guzzle will use specific adapters if cURL is present" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Ring\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", - "time": "2015-05-20 03:37:09" - }, - { - "name": "guzzlehttp/streams", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/streams.git", - "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", - "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "GuzzleHttp\\Stream\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - } - ], - "description": "Provides a simple abstraction over streams of data", - "homepage": "http://guzzlephp.org/", - "keywords": [ - "Guzzle", - "stream" - ], - "time": "2014-10-12 19:18:40" - }, - { "name": "michelf/php-markdown", "version": "1.6.0", "source": { @@ -2282,50 +2231,6 @@ "time": "2013-03-08 08:21:40" }, { - "name": "react/promise", - "version": "v2.2.1", - "source": { - "type": "git", - "url": "https://github.com/reactphp/promise.git", - "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/3b6fca09c7d56321057fa8867c8dbe1abf648627", - "reference": "3b6fca09c7d56321057fa8867c8dbe1abf648627", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "React\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jan Sorgalla", - "email": "jsorgalla@gmail.com" - } - ], - "description": "A lightweight implementation of CommonJS Promises/A for PHP", - "time": "2015-07-03 13:48:55" - }, - { "name": "sami/sami", "version": "v1.4.1", "source": { diff --git a/phpBB/config/default/container/services_files.yml b/phpBB/config/default/container/services_files.yml index 39277bcd9d..88414d89a9 100644 --- a/phpBB/config/default/container/services_files.yml +++ b/phpBB/config/default/container/services_files.yml @@ -49,6 +49,7 @@ services: class: phpbb\files\types\remote scope: prototype arguments: + - '@config' - '@files.factory' - '@language' - '@php_ini' diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php index 26663d2a62..9d65c48bed 100644 --- a/phpBB/includes/acp/acp_board.php +++ b/phpBB/includes/acp/acp_board.php @@ -415,6 +415,7 @@ class acp_board 'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'referer_validation' => array('lang' => 'REFERRER_VALID', 'validate' => 'int:0:3','type' => 'custom', 'method' => 'select_ref_check', 'explain' => true), + 'remote_upload_verify' => array('lang' => 'UPLOAD_CERT_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'check_dnsbl' => array('lang' => 'CHECK_DNSBL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'email_check_mx' => array('lang' => 'EMAIL_CHECK_MX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'max_pass_chars' => array('lang' => 'PASSWORD_LENGTH', 'validate' => 'int:8:255', 'type' => false, 'method' => false, 'explain' => false,), diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index 6d3a199a5a..ede31e53e6 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -239,6 +239,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('queue_interval', ' INSERT INTO phpbb_config (config_name, config_value) VALUES ('ranks_path', 'images/ranks'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('read_notification_expire_days', '30'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('read_notification_gc', '86400'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('remote_upload_verify', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('require_activation', '0'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('referer_validation', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('script_path', ''); diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php index ba51595dc3..462d66a04a 100644 --- a/phpBB/language/en/acp/board.php +++ b/phpBB/language/en/acp/board.php @@ -535,6 +535,8 @@ $lang = array_merge($lang, array( 'REFERRER_VALID_EXPLAIN' => 'If enabled, the referrer of POST requests will be checked against the host/script path settings. This may cause issues with boards using several domains and or external logins.', 'TPL_ALLOW_PHP' => 'Allow php in templates', 'TPL_ALLOW_PHP_EXPLAIN' => 'If this option is enabled, <code>PHP</code> and <code>INCLUDEPHP</code> statements will be recognised and parsed in templates.', + 'UPLOAD_CERT_VALID' => 'Validate upload certificate', + 'UPLOAD_CERT_VALID_EXPLAIN' => 'If enabled, certificates of remote uploads will be validated. This requires the CA bundle to be defined by the <samp>openssl.cafile</samp> or <samp>curl.cainfo</samp> setting in your php.ini.', )); // Email Settings diff --git a/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php b/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php new file mode 100644 index 0000000000..d61f6b96fd --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php @@ -0,0 +1,31 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v320; + +class remote_upload_validation extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320a2', + ); + } + + public function update_data() + { + return array( + array('config.add', array('remote_upload_verify', '0')), + ); + } +} diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index d311face98..1fdba0ca32 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -14,6 +14,7 @@ namespace phpbb\files\types; use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\config\config; use phpbb\files\factory; use phpbb\files\filespec; use phpbb\language\language; @@ -21,6 +22,9 @@ use phpbb\request\request_interface; class remote extends base { + /** @var config phpBB config */ + protected $config; + /** @var factory Files factory */ protected $factory; @@ -42,14 +46,16 @@ class remote extends base /** * Construct a form upload type * + * @param config $config phpBB config * @param factory $factory Files factory * @param language $language Language class * @param IniGetWrapper $php_ini ini_get() wrapper * @param request_interface $request Request object * @param string $phpbb_root_path phpBB root path */ - public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) + public function __construct(config $config, factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) { + $this->config = $config; $this->factory = $factory; $this->language = $language; $this->php_ini = $php_ini; @@ -86,19 +92,6 @@ class remote extends base $url = parse_url($upload_url); - $default_port = 80; - $hostname = $url['host']; - - if ($url['scheme'] == 'https') - { - $default_port = 443; - $hostname = 'tls://' . $url['host']; - } - - $host = $url['host']; - $path = $url['path']; - $port = (!empty($url['port'])) ? (int) $url['port'] : $default_port; - $upload_ary['type'] = 'application/octet-stream'; $url['path'] = explode('.', $url['path']); @@ -106,108 +99,55 @@ class remote extends base $url['path'] = implode('', $url['path']); $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); - $filesize = 0; $remote_max_filesize = $this->get_max_file_size(); - $errno = 0; - $errstr = ''; + $guzzle_options = [ + 'timeout' => $this->upload->upload_timeout, + 'connect_timeout' => $this->upload->upload_timeout, + 'verify' => !empty($this->config['remote_upload_verify']) ? (bool) $this->config['remote_upload_verify'] : false, + ]; + $client = new \GuzzleHttp\Client($guzzle_options); - if (!($fsock = @fsockopen($hostname, $port, $errno, $errstr))) + try { - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + $response = $client->get($upload_url, $guzzle_options); } - - // Make sure $path not beginning with / - if (strpos($path, '/') === 0) + catch (\GuzzleHttp\Exception\ClientException $clientException) { - $path = substr($path, 1); + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); } - - fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n"); - fputs($fsock, "HOST: " . $host . "\r\n"); - fputs($fsock, "Connection: close\r\n\r\n"); - - // Set a proper timeout for the socket - socket_set_timeout($fsock, $this->upload->upload_timeout); - - $get_info = false; - $data = ''; - $length = false; - $timer_stop = time() + $this->upload->upload_timeout; - - while ((!$length || $filesize < $length) && !@feof($fsock)) + catch (\GuzzleHttp\Exception\RequestException $requestException) { - if ($get_info) + if (strpos($requestException->getMessage(), 'cURL error 28') !== false || preg_match('/408|504/', $requestException->getCode())) { - if ($length) - { - // Don't attempt to read past end of file if server indicated length - $block = @fread($fsock, min($length - $filesize, 1024)); - } - else - { - $block = @fread($fsock, 1024); - } - - $filesize += strlen($block); - - if ($remote_max_filesize && $filesize > $remote_max_filesize) - { - $max_filesize = get_formatted_filesize($remote_max_filesize, false); - - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); - } - - $data .= $block; + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); } else { - $line = @fgets($fsock, 1024); - - if ($line == "\r\n") - { - $get_info = true; - } - else - { - if (stripos($line, 'content-type: ') !== false) - { - $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line))); - } - else if ($this->upload->max_filesize && stripos($line, 'content-length: ') !== false) - { - $length = (int) str_replace('content-length: ', '', strtolower($line)); - - if ($remote_max_filesize && $length && $length > $remote_max_filesize) - { - $max_filesize = get_formatted_filesize($remote_max_filesize, false); - - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); - } - } - else if (stripos($line, '404 not found') !== false) - { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); - } - } + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } + } + catch (\Exception $e) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } - $stream_meta_data = stream_get_meta_data($fsock); + $content_length = $response->getBody()->getSize(); + if ($remote_max_filesize && $content_length > $remote_max_filesize) + { + $max_filesize = get_formatted_filesize($remote_max_filesize, false); - // Cancel upload if we exceed timeout - if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) - { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); - } + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } - @fclose($fsock); - if (empty($data)) + if ($content_length == 0) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); } + $data = $response->getBody(); + $filename = tempnam(sys_get_temp_dir(), unique_id() . '-'); if (!($fp = @fopen($filename, 'wb'))) diff --git a/tests/files/types_remote_test.php b/tests/files/types_remote_test.php index caed5c9e05..476d8ed3ba 100644 --- a/tests/files/types_remote_test.php +++ b/tests/files/types_remote_test.php @@ -20,6 +20,9 @@ class phpbb_files_types_remote_test extends phpbb_test_case private $filesystem; + /** @var \phpbb\config\config */ + protected $config; + /** @var \Symfony\Component\DependencyInjection\ContainerInterface */ protected $container; @@ -43,6 +46,8 @@ class phpbb_files_types_remote_test extends phpbb_test_case global $config, $phpbb_root_path, $phpEx; $config = new \phpbb\config\config(array()); + $this->config = $config; + $this->config->set('remote_upload_verify', 0); $this->request = $this->getMock('\phpbb\request\request'); $this->filesystem = new \phpbb\filesystem\filesystem(); @@ -67,7 +72,7 @@ class phpbb_files_types_remote_test extends phpbb_test_case public function test_upload_fsock_fail() { - $type_remote = new \phpbb\files\types\remote($this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); + $type_remote = new \phpbb\files\types\remote($this->config, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); $upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); $upload->set_allowed_extensions(array('png')); $type_remote->set_upload($upload); @@ -102,7 +107,7 @@ class phpbb_files_types_remote_test extends phpbb_test_case $php_ini->expects($this->any()) ->method('getString') ->willReturn($max_file_size); - $type_remote = new \phpbb\files\types\remote($this->factory, $this->language, $php_ini, $this->request, $this->phpbb_root_path); + $type_remote = new \phpbb\files\types\remote($this->config, $this->factory, $this->language, $php_ini, $this->request, $this->phpbb_root_path); $upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); $upload->set_allowed_extensions(array('png')); $type_remote->set_upload($upload); @@ -112,22 +117,9 @@ class phpbb_files_types_remote_test extends phpbb_test_case $this->assertSame($expected, $file->error); } - public function test_upload_timeout() - { - $type_remote = new \phpbb\files\types\remote($this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); - $upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); - $upload->set_allowed_extensions(array('png')); - $type_remote->set_upload($upload); - $upload->upload_timeout = -5; - - $file = $type_remote->upload('http://google.com/?.png'); - - $this->assertSame(array('REMOTE_UPLOAD_TIMEOUT'), $file->error); - } - public function test_upload_wrong_path() { - $type_remote = new \phpbb\files\types\foo($this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); + $type_remote = new \phpbb\files\types\foo($this->config, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); $upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path); $upload->set_allowed_extensions(array('png')); $type_remote->set_upload($upload); diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php index 7e0f192b40..b70d49cddd 100644 --- a/tests/functional/fileupload_remote_test.php +++ b/tests/functional/fileupload_remote_test.php @@ -45,11 +45,12 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case if (!is_array($config)) { - $config = array(); + $config = new \phpbb\config\config(array()); } $config['rand_seed'] = ''; $config['rand_seed_last_update'] = time() + 600; + $config['remote_upload_verify'] = 0; $this->filesystem = new \phpbb\filesystem\filesystem(); $this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); @@ -60,7 +61,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case $container->set('files.filespec', new \phpbb\files\filespec($this->filesystem, $this->language, $this->php_ini, new \FastImageSize\FastImageSize(), $this->phpbb_root_path)); $this->factory = new \phpbb\files\factory($container); $container->set('files.factory', $this->factory); - $container->set('files.types.remote', new \phpbb\files\types\remote($this->factory, $this->language, $this->php_ini, $this->request, $phpbb_root_path)); + $container->set('files.types.remote', new \phpbb\files\types\remote($config, $this->factory, $this->language, $this->php_ini, $this->request, $phpbb_root_path)); $this->phpbb_root_path = $phpbb_root_path; } |