diff --git a/core/src/core/src/pydio/Core/Http/Dav/AuthBackendBasic.php b/core/src/core/src/pydio/Core/Http/Dav/AuthBackendBasic.php index 8d6fd9df40..ba3c01fcc1 100644 --- a/core/src/core/src/pydio/Core/Http/Dav/AuthBackendBasic.php +++ b/core/src/core/src/pydio/Core/Http/Dav/AuthBackendBasic.php @@ -41,6 +41,10 @@ defined('AJXP_EXEC') or die( 'Access not allowed'); +/** + * Class AuthBackendBasic + * @package Pydio\Core\Http\Dav + */ class AuthBackendBasic extends Sabre\DAV\Auth\Backend\AbstractBasic { /** @@ -61,18 +65,33 @@ public static function detectBasicHeader() return (strpos(strtolower($value),'basic') ===0) ; } + /** + * AuthBackendBasic constructor. + * @param ContextInterface $ctx + */ public function __construct(ContextInterface $ctx) { $this->context = $ctx; } + /** + * @param string $username + * @param string $password + * @return bool|void + */ protected function validateUserPass($username, $password) { // Warning, this can only work if TRANSMIT_CLEAR_PASS is true; return UsersService::checkPassword($username, $password, false, -1); } + /** + * @param Sabre\DAV\Server $server + * @param string $realm + * @return bool + * @throws Sabre\DAV\Exception\NotAuthenticated + */ public function authenticate(Sabre\DAV\Server $server, $realm) { $auth = new Sabre\HTTP\BasicAuth(); diff --git a/core/src/core/src/pydio/Core/Http/Dav/DAVServer.php b/core/src/core/src/pydio/Core/Http/Dav/DAVServer.php index f3c2474531..e543eba003 100644 --- a/core/src/core/src/pydio/Core/Http/Dav/DAVServer.php +++ b/core/src/core/src/pydio/Core/Http/Dav/DAVServer.php @@ -27,6 +27,7 @@ use Pydio\Core\Services\RepositoryService; use Pydio\Log\Core\Logger; use Sabre\DAV as DAV; +use Sabre\DAV\Exception\Forbidden; defined('AJXP_EXEC') or die('Access not allowed'); @@ -45,6 +46,7 @@ class DAVServer /** * @param $baseURI * @param $davRoute + * @throws Forbidden */ public static function handleRoute($baseURI, $davRoute){ @@ -53,7 +55,7 @@ public static function handleRoute($baseURI, $davRoute){ self::$context = Context::emptyContext(); if (!ConfService::getGlobalConf("WEBDAV_ENABLE")) { - die('You are not allowed to access this service'); + throw new Forbidden('You are not allowed to access this service'); } PluginsService::getInstance(self::$context)->initActivePlugins(); @@ -80,8 +82,7 @@ public static function handleRoute($baseURI, $davRoute){ } } if ($repository == null) { - Logger::debug("not found, dying $repositoryId"); - die('You are not allowed to access this service'); + throw new Forbidden('You are not allowed to access this service'); } self::$context->setRepositoryId($repositoryId); diff --git a/core/src/core/src/pydio/Core/Utils/Utils.php b/core/src/core/src/pydio/Core/Utils/Utils.php index 5de70bc00a..bfe8789f6b 100644 --- a/core/src/core/src/pydio/Core/Utils/Utils.php +++ b/core/src/core/src/pydio/Core/Utils/Utils.php @@ -22,6 +22,7 @@ use Psr\Http\Message\UploadedFileInterface; +use Pydio\Core\Exception\PydioException; use Pydio\Core\Model\Context; use Pydio\Core\Model\ContextInterface; use Pydio\Core\Model\RepositoryInterface; @@ -945,7 +946,7 @@ public static function updateI18nFromRef($filename, $reference) * @param $outputArray * @param $testedParams * @param bool $showSkipLink - * @return void + * @return string */ public static function testResultsToTable($outputArray, $testedParams, $showSkipLink = true) { @@ -975,8 +976,9 @@ public static function testResultsToTable($outputArray, $testedParams, $showSkip if($result == "dump") $result = "passed"; $ALL_ROWS[$result][$item["name"]] = $item["info"]; } - + ob_start(); include(AJXP_TESTS_FOLDER . "/startup.phtml"); + return ob_get_flush(); } /** @@ -1650,7 +1652,7 @@ public static function runCreateTablesQuery($p, $file) } - /* + /** * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt * $algorithm - The hash algorithm to use. Recommended: SHA256 * $password - The password. @@ -1664,15 +1666,23 @@ public static function runCreateTablesQuery($p, $file) * * This implementation of PBKDF2 was originally created by https://defuse.ca * With improvements by http://www.variations-of-shadow.com + * @param $algorithm + * @param $password + * @param $salt + * @param $count + * @param $key_length + * @param bool $raw_output + * @return string + * @throws PydioException */ public static function pbkdf2_apply($algorithm, $password, $salt, $count, $key_length, $raw_output = false) { $algorithm = strtolower($algorithm); if(!in_array($algorithm, hash_algos(), true)) - die('PBKDF2 ERROR: Invalid hash algorithm.'); + throw new PydioException('PBKDF2 ERROR: Invalid hash algorithm.'); if($count <= 0 || $key_length <= 0) - die('PBKDF2 ERROR: Invalid parameters.'); + throw new PydioException('PBKDF2 ERROR: Invalid parameters.'); $hash_length = strlen(hash($algorithm, "", true)); $block_count = ceil($key_length / $hash_length); @@ -1700,7 +1710,12 @@ public static function pbkdf2_apply($algorithm, $password, $salt, $count, $key_l } - // Compares two strings $a and $b in length-constant time. + /** + * Compares two strings $a and $b in length-constant time. + * @param $a + * @param $b + * @return bool + */ public static function pbkdf2_slow_equals($a, $b) { $diff = strlen($a) ^ strlen($b); @@ -1711,6 +1726,12 @@ public static function pbkdf2_slow_equals($a, $b) return $diff === 0; } + /** + * @param $password + * @param $correct_hash + * @return bool + * @throws PydioException + */ public static function pbkdf2_validate_password($password, $correct_hash) { $params = explode(":", $correct_hash); @@ -1737,6 +1758,11 @@ public static function pbkdf2_validate_password($password, $correct_hash) } + /** + * @param $password + * @return string + * @throws PydioException + */ public static function pbkdf2_create_hash($password) { // format: algorithm:iterations:salt:hash diff --git a/core/src/plugins/access.mysql/MysqlAccessDriver.php b/core/src/plugins/access.mysql/MysqlAccessDriver.php index ee46f1bc5c..678c804d7c 100644 --- a/core/src/plugins/access.mysql/MysqlAccessDriver.php +++ b/core/src/plugins/access.mysql/MysqlAccessDriver.php @@ -439,7 +439,7 @@ public function switchAction($action, $httpVars, $fileVars, ContextInterface $ct XMLWriter::close(); } $this->closeDbLink($link); - exit(1); + return null; break; } diff --git a/core/src/plugins/editor.imagick/IMagickPreviewer.php b/core/src/plugins/editor.imagick/IMagickPreviewer.php index 7e41d5be48..e7eb01245e 100644 --- a/core/src/plugins/editor.imagick/IMagickPreviewer.php +++ b/core/src/plugins/editor.imagick/IMagickPreviewer.php @@ -160,7 +160,6 @@ public function switchAction($action, $httpVars, $filesVars, \Pydio\Core\Model\C header("Content-Length: ".filesize($file)); header('Cache-Control: public'); readfile($file); - exit(1); } else if ($action == "delete_imagick_data" && !$selection->isEmpty()) { /* diff --git a/core/src/plugins/gui.ajax/RichClient.php b/core/src/plugins/gui.ajax/RichClient.php index 86197514cd..ccf9154d55 100644 --- a/core/src/plugins/gui.ajax/RichClient.php +++ b/core/src/plugins/gui.ajax/RichClient.php @@ -36,6 +36,7 @@ use Pydio\Core\Controller\HTMLWriter; use Pydio\Core\PluginFramework\Plugin; use Pydio\Core\PluginFramework\PluginsService; +use Zend\Diactoros\Response\HtmlResponse; use Zend\Diactoros\Response\JsonResponse; defined('AJXP_EXEC') or die( 'Access not allowed'); @@ -116,8 +117,9 @@ public function getBootGui(ServerRequestInterface &$request, ResponseInterface & $testedParams = array(); $passed = Utils::runTests($outputArray, $testedParams); if (!$passed && !isset($httpVars["ignore_tests"])) { - Utils::testResultsToTable($outputArray, $testedParams); - die(); + $html = Utils::testResultsToTable($outputArray, $testedParams); + $response = new HtmlResponse($html); + return; } else { Utils::testResultsToFile($outputArray, $testedParams); } diff --git a/core/src/plugins/log.sql/SqlLogDriver.php b/core/src/plugins/log.sql/SqlLogDriver.php index a9e76c258b..a1651602d7 100644 --- a/core/src/plugins/log.sql/SqlLogDriver.php +++ b/core/src/plugins/log.sql/SqlLogDriver.php @@ -539,8 +539,7 @@ public function xmlListLogFiles($nodeName = "file", $year = null, $month = null, } } } catch (DibiException $e) { - echo get_class($e), ': ', $e->getMessage(), "\n"; - exit(1); + throw $e; } if ($print) { diff --git a/core/src/plugins/meta.svn/SvnManager.php b/core/src/plugins/meta.svn/SvnManager.php index 44a8c70193..891b19304e 100644 --- a/core/src/plugins/meta.svn/SvnManager.php +++ b/core/src/plugins/meta.svn/SvnManager.php @@ -231,7 +231,7 @@ public function switchAction($actionName, $httpVars, $filesVars, ContextInterfac $realFile = escapeshellarg($realFile); $revision = escapeshellarg($revision); system( (SVNLIB_PATH!=""?SVNLIB_PATH."/":"") ."svn cat -r$revision $realFile"); - exit(0); + return; } else if ($actionName == "revert_file") { $revision = escapeshellarg($httpVars["revision"]); diff --git a/core/src/plugins/uploader.flex/FlexUpload.php b/core/src/plugins/uploader.flex/FlexUpload.php index 3163deddf7..8f2b998aa5 100644 --- a/core/src/plugins/uploader.flex/FlexUpload.php +++ b/core/src/plugins/uploader.flex/FlexUpload.php @@ -77,8 +77,8 @@ public function preProcess(\Psr\Http\Message\ServerRequestInterface &$request, \ if ($request->getAttribute("action") == "upload" && ($loggedUser == null || !$loggedUser->canWrite($ctx->getRepositoryId()."")) && isSet($request->getUploadedFiles()['Filedata'])) { - header('HTTP/1.0 ' . '410 Not authorized'); - die('Error 410 Not authorized!'); + $response = $response->withStatus(410, "Not authorized"); + return; } } diff --git a/core/src/plugins/uploader.html/SimpleUpload.php b/core/src/plugins/uploader.html/SimpleUpload.php index 6114e7772f..9ba81dd350 100644 --- a/core/src/plugins/uploader.html/SimpleUpload.php +++ b/core/src/plugins/uploader.html/SimpleUpload.php @@ -28,6 +28,7 @@ use Pydio\Core\Controller\XMLWriter; use Pydio\Core\PluginFramework\Plugin; use Pydio\Core\Utils\TextEncoder; +use Zend\Diactoros\Response\TextResponse; defined('AJXP_EXEC') or die( 'Access not allowed'); @@ -92,7 +93,7 @@ public function preProcess(\Psr\Http\Message\ServerRequestInterface &$request, \ // Checking headers if (isSet($serverData['HTTP_X_FILE_SIZE'])) { if ($serverData['CONTENT_LENGTH'] != $serverData['HTTP_X_FILE_SIZE']) { - exit('Warning, wrong headers'); + $response = new TextResponse("Warning, wrong headers"); } } diff --git a/core/src/plugins/uploader.plupload/Pluploader.php b/core/src/plugins/uploader.plupload/Pluploader.php index de88e5d789..b567a902c1 100644 --- a/core/src/plugins/uploader.plupload/Pluploader.php +++ b/core/src/plugins/uploader.plupload/Pluploader.php @@ -101,123 +101,134 @@ public function getTemplate(\Psr\Http\Message\ServerRequestInterface $requestInt public function unifyChunks($action, &$httpVars, &$fileVars, \Pydio\Core\Model\ContextInterface $ctx) { - $filename = Utils::decodeSecureMagic($httpVars["name"]); - - $tmpName = $fileVars["file"]["tmp_name"]; - $chunk = $httpVars["chunk"]; - $chunks = $httpVars["chunks"]; - - //error_log("currentChunk:".$chunk." chunks: ".$chunks); - - $repository = $ctx->getRepository(); - $userSelection = UserSelection::fromContext($ctx, []); - $dir = Utils::securePath($httpVars["dir"]); - $destStreamURL = $userSelection->currentBaseUrl().$dir."/"; - - $parentNode = new AJXP_Node($userSelection->currentBaseUrl()); - $driver = $parentNode->getDriver(); - $remote = false; - if (method_exists($driver, "storeFileToCopy")) { - $remote = true; - $destCopy = XMLWriter::replaceAjxpXmlKeywords($repository->getContextOption($ctx, "TMP_UPLOAD")); - // Make tmp folder a bit more unique using secure_token - $tmpFolder = $destCopy."/".$httpVars["secure_token"]; - if(!is_dir($tmpFolder)){ - @mkdir($tmpFolder, 0700, true); - } - $target = $tmpFolder.'/'.$filename; - $fileVars["file"]["destination"] = base64_encode($dir); - }else if(MetaStreamWrapper::wrapperIsRemote($destStreamURL)){ - $remote = true; - $tmpFolder = Utils::getAjxpTmpDir()."/".$httpVars["secure_token"]; - if(!is_dir($tmpFolder)){ - @mkdir($tmpFolder, 0700, true); - } - $target = $tmpFolder.'/'.$filename; - }else{ + $filename = Utils::decodeSecureMagic($httpVars["name"]); - $target = $destStreamURL.$filename; + $tmpName = $fileVars["file"]["tmp_name"]; + $chunk = $httpVars["chunk"]; + $chunks = $httpVars["chunks"]; + + //error_log("currentChunk:".$chunk." chunks: ".$chunks); + + $repository = $ctx->getRepository(); + $userSelection = UserSelection::fromContext($ctx, []); + $dir = Utils::securePath($httpVars["dir"]); + $destStreamURL = $userSelection->currentBaseUrl().$dir."/"; + + $parentNode = new AJXP_Node($userSelection->currentBaseUrl()); + $driver = $parentNode->getDriver(); + $remote = false; + if (method_exists($driver, "storeFileToCopy")) { + $remote = true; + $destCopy = XMLWriter::replaceAjxpXmlKeywords($repository->getContextOption($ctx, "TMP_UPLOAD")); + // Make tmp folder a bit more unique using secure_token + $tmpFolder = $destCopy."/".$httpVars["secure_token"]; + if(!is_dir($tmpFolder)){ + @mkdir($tmpFolder, 0700, true); } + $target = $tmpFolder.'/'.$filename; + $fileVars["file"]["destination"] = base64_encode($dir); + }else if(MetaStreamWrapper::wrapperIsRemote($destStreamURL)){ + $remote = true; + $tmpFolder = Utils::getAjxpTmpDir()."/".$httpVars["secure_token"]; + if(!is_dir($tmpFolder)){ + @mkdir($tmpFolder, 0700, true); + } + $target = $tmpFolder.'/'.$filename; + }else{ + + $target = $destStreamURL.$filename; + } + + + //error_log("Directory: ".$dir); + + // Clean the fileName for security reasons + //$filename = preg_replace('/[^\w\._]+/', '', $filename); + $contentType = ""; + // Look for the content type header + if (isset($_SERVER["HTTP_CONTENT_TYPE"])) + $contentType = $_SERVER["HTTP_CONTENT_TYPE"]; + if (isset($_SERVER["CONTENT_TYPE"])) + $contentType = $_SERVER["CONTENT_TYPE"]; + + // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5 + if (strpos($contentType, "multipart") !== false) { + if (isset($tmpName) && is_uploaded_file($tmpName)) { + //error_log("tmpName: ".$tmpName); - //error_log("Directory: ".$dir); - - // Clean the fileName for security reasons - //$filename = preg_replace('/[^\w\._]+/', '', $filename); - $contentType = ""; - // Look for the content type header - if (isset($_SERVER["HTTP_CONTENT_TYPE"])) - $contentType = $_SERVER["HTTP_CONTENT_TYPE"]; - - if (isset($_SERVER["CONTENT_TYPE"])) - $contentType = $_SERVER["CONTENT_TYPE"]; - - // Handle non multipart uploads older WebKit versions didn't support multipart in HTML5 - if (strpos($contentType, "multipart") !== false) { - if (isset($tmpName) && is_uploaded_file($tmpName)) { - //error_log("tmpName: ".$tmpName); - - // Open temp file - $out = fopen($target, $chunk == 0 ? "wb" : "ab"); - if ($out) { - // Read binary input stream and append it to temp file - $in = fopen($tmpName, "rb"); - - if ($in) { - while ($buff = fread($in, 4096)) - fwrite($out, $buff); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); - fclose($in); - fclose($out); - @unlink($tmpName); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}'); - } else { // Open temp file $out = fopen($target, $chunk == 0 ? "wb" : "ab"); if ($out) { // Read binary input stream and append it to temp file - $in = fopen("php://input", "rb"); + $in = fopen($tmpName, "rb"); if ($in) { while ($buff = fread($in, 4096)) fwrite($out, $buff); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); - + } else{ + echo('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); + return; + } fclose($in); fclose($out); - } else - die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); + @unlink($tmpName); + } else{ + echo('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); + return; + } + } else{ + echo('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}'); + return; + } + } else { + // Open temp file + $out = fopen($target, $chunk == 0 ? "wb" : "ab"); + if ($out) { + // Read binary input stream and append it to temp file + $in = fopen("php://input", "rb"); + + if ($in) { + while ($buff = fread($in, 4096)) + fwrite($out, $buff); + } else{ + echo('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}'); + return; + } + + fclose($in); + fclose($out); + } else{ + echo('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}'); + return; } - /* we apply the hook if we are uploading the last chunk */ - if($chunk == $chunks-1){ - if(!$remote){ - Controller::applyHook("node.change", array(null, new AJXP_Node($destStreamURL.$filename), false)); + } + /* we apply the hook if we are uploading the last chunk */ + if($chunk == $chunks-1){ + if(!$remote){ + Controller::applyHook("node.change", array(null, new AJXP_Node($destStreamURL.$filename), false)); + }else{ + if(method_exists($driver, "storeFileToCopy")){ + $fileVars["file"]["tmp_name"] = $target; + $fileVars["file"]["name"] = $filename; + $driver->storeFileToCopy($fileVars["file"]); + $request = \Zend\Diactoros\ServerRequestFactory::fromGlobals(); + $request = $request->withAttribute("action", "next_to_remote")->withParsedBody([]); + Controller::run($request); + }else{ - if(method_exists($driver, "storeFileToCopy")){ - $fileVars["file"]["tmp_name"] = $target; - $fileVars["file"]["name"] = $filename; - $driver->storeFileToCopy($fileVars["file"]); - $request = \Zend\Diactoros\ServerRequestFactory::fromGlobals(); - $request = $request->withAttribute("action", "next_to_remote")->withParsedBody([]); - Controller::run($request); - - }else{ - // Remote Driver case: copy temp file to destination - $node = new AJXP_Node($destStreamURL.$filename); - Controller::applyHook("node.before_create", array($node, filesize($target))); - Controller::applyHook("node.before_change", array(new AJXP_Node($destStreamURL))); - $res = copy($target, $destStreamURL.$filename); - if($res) @unlink($target); - Controller::applyHook("node.change", array(null, $node, false)); - } + // Remote Driver case: copy temp file to destination + $node = new AJXP_Node($destStreamURL.$filename); + Controller::applyHook("node.before_create", array($node, filesize($target))); + Controller::applyHook("node.before_change", array(new AJXP_Node($destStreamURL))); + $res = copy($target, $destStreamURL.$filename); + if($res) @unlink($target); + Controller::applyHook("node.change", array(null, $node, false)); } } - // Return JSON-RPC response - die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); + } + // Return JSON-RPC response + echo('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}'); + return; } } diff --git a/core/src/runTests.php b/core/src/runTests.php index 794b3b569b..8cac3a1ad2 100644 --- a/core/src/runTests.php +++ b/core/src/runTests.php @@ -247,7 +247,7 @@ function apiPost($baseData, $url, $parameters, $private){ $testedParams = array(); $passed = true; $passed = Utils::runTests($outputArray, $testedParams); - Utils::testResultsToTable($outputArray, $testedParams, true); Utils::testResultsToFile($outputArray, $testedParams); + echo Utils::testResultsToTable($outputArray, $testedParams, true); } \ No newline at end of file