From 9db82193a9cd80c27c20b839a6fd3a561bc16d82 Mon Sep 17 00:00:00 2001 From: cdujeu Date: Thu, 22 Sep 2016 18:32:00 +0200 Subject: [PATCH] Encapsulate 'safe credentials' and 'secure_tokens' in SessionService calls with dedicated keys. --- .../src/pydio/Core/Controller/CliRunner.php | 17 +++--- .../pydio/Core/Http/Cli/AuthCliMiddleware.php | 12 ++-- .../Http/Middleware/SecureTokenMiddleware.php | 30 ++++------ core/src/plugins/core.auth/MemorySafe.php | 56 ++++++++++++++++--- .../plugins/editor.audio/AudioPreviewer.php | 2 +- core/src/plugins/editor.audio/manifest.xml | 2 +- 6 files changed, 72 insertions(+), 47 deletions(-) diff --git a/core/src/core/src/pydio/Core/Controller/CliRunner.php b/core/src/core/src/pydio/Core/Controller/CliRunner.php index 1436dc3b02..0c617a1cf4 100644 --- a/core/src/core/src/pydio/Core/Controller/CliRunner.php +++ b/core/src/core/src/pydio/Core/Controller/CliRunner.php @@ -109,19 +109,16 @@ public static function applyActionInBackground(ContextInterface $ctx, $actionNam } } - $repoObject = $ctx->getRepository(); - $clearEnv = false; - if ($repoObject->getContextOption($ctx, "USE_SESSION_CREDENTIALS")) { - $encodedCreds = MemorySafe::getEncodedCredentialString(); - if (!empty($encodedCreds)) { - putenv("AJXP_SAFE_CREDENTIALS=" . $encodedCreds); - $clearEnv = "AJXP_SAFE_CREDENTIALS"; - } + $envSet = false; + if ($ctx->getRepository()->getContextOption($ctx, "USE_SESSION_CREDENTIALS")) { + $envSet = MemorySafe::setEnv(); } + // NOW RUN COMMAND $res = self::runCommandInBackground($cmd, $logFile); - if (!empty($clearEnv)) { - putenv($clearEnv); + + if($envSet){ + MemorySafe::clearEnv(); } return $res; } diff --git a/core/src/core/src/pydio/Core/Http/Cli/AuthCliMiddleware.php b/core/src/core/src/pydio/Core/Http/Cli/AuthCliMiddleware.php index ee5ef58e1f..944c4321ba 100644 --- a/core/src/core/src/pydio/Core/Http/Cli/AuthCliMiddleware.php +++ b/core/src/core/src/pydio/Core/Http/Cli/AuthCliMiddleware.php @@ -72,15 +72,11 @@ protected static function authenticateFromCliParameters($options){ $cKey = ConfService::getGlobalConf("AJXP_CLI_SECRET_KEY", "conf"); if(empty($cKey)) $cKey = "\1CDAFx¨op#"; $optUser = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($optToken.$cKey), base64_decode($optUser), MCRYPT_MODE_ECB), "\0"); - $env = getenv("AJXP_SAFE_CREDENTIALS"); - if(!empty($env)){ - $array = MemorySafe::getCredentialsFromEncodedString($env); - if(isSet($array["user"]) && $array["user"] == $optUser){ - unset($optToken); - $optPass = $array["password"]; - } + $envPass = MemorySafe::loadPasswordStringFromEnvironment($optUser); + if($envPass !== false){ + unset($optToken); + $optPass = $envPass; } - } diff --git a/core/src/core/src/pydio/Core/Http/Middleware/SecureTokenMiddleware.php b/core/src/core/src/pydio/Core/Http/Middleware/SecureTokenMiddleware.php index bddc02132b..1a9be956a5 100644 --- a/core/src/core/src/pydio/Core/Http/Middleware/SecureTokenMiddleware.php +++ b/core/src/core/src/pydio/Core/Http/Middleware/SecureTokenMiddleware.php @@ -25,6 +25,7 @@ use Pydio\Core\Exception\PydioException; use Pydio\Core\Http\Server; use Pydio\Core\PluginFramework\PluginsService; +use Pydio\Core\Services\SessionService; use Pydio\Core\Utils\Vars\StringHelper; defined('AJXP_EXEC') or die('Access not allowed'); @@ -38,6 +39,8 @@ class SecureTokenMiddleware { + const SECURE_TOKENS_KEY = "PYDIO_SECURE_TOKENS"; + /** * * @param ServerRequestInterface $requestInterface @@ -58,7 +61,7 @@ public static function handleRequest(\Psr\Http\Message\ServerRequestInterface $r }); $pluginsUnSecureActions[] = "get_secure_token"; - if (!in_array($requestInterface->getAttribute("action"), $pluginsUnSecureActions) && self::getSecureToken()) { + if (!in_array($requestInterface->getAttribute("action"), $pluginsUnSecureActions) && self::hasSecureToken()) { $params = $requestInterface->getParsedBody(); if(array_key_exists("secure_token", $params)){ $token = $params["secure_token"]; @@ -78,15 +81,10 @@ public static function handleRequest(\Psr\Http\Message\ServerRequestInterface $r */ public static function generateSecureToken() { - if(!isSet($_SESSION["SECURE_TOKENS"])){ - $_SESSION["SECURE_TOKENS"] = array(); - } - if(isSet($_SESSION["FORCE_SECURE_TOKEN"])){ - $_SESSION["SECURE_TOKENS"][] = $_SESSION["FORCE_SECURE_TOKEN"]; - return $_SESSION["FORCE_SECURE_TOKEN"]; - } + $arr = SessionService::fetch(self::SECURE_TOKENS_KEY) OR []; $newToken = StringHelper::generateRandomString(32); - $_SESSION["SECURE_TOKENS"][] = $newToken; + $arr[] = $newToken; + SessionService::save(self::SECURE_TOKENS_KEY, $arr); return $newToken; } /** @@ -94,12 +92,10 @@ public static function generateSecureToken() * @static * @return string|bool */ - public static function getSecureToken() + protected static function hasSecureToken() { - if(isSet($_SESSION["SECURE_TOKENS"]) && count($_SESSION["SECURE_TOKENS"])){ - return true; - } - return false; + $arr = SessionService::fetch(self::SECURE_TOKENS_KEY); + return ($arr !== null && is_array($arr) && count($arr)); } /** * Verify a secure token value from the session @@ -109,10 +105,8 @@ public static function getSecureToken() */ public static function checkSecureToken($token) { - if (isSet($_SESSION["SECURE_TOKENS"]) && in_array($token, $_SESSION["SECURE_TOKENS"])) { - return true; - } - return false; + $arr = SessionService::fetch(self::SECURE_TOKENS_KEY); + return ($arr !== null && is_array($arr) && in_array($token, $arr)); } } \ No newline at end of file diff --git a/core/src/plugins/core.auth/MemorySafe.php b/core/src/plugins/core.auth/MemorySafe.php index b24a12b95d..f6ea6319b1 100644 --- a/core/src/plugins/core.auth/MemorySafe.php +++ b/core/src/plugins/core.auth/MemorySafe.php @@ -21,6 +21,7 @@ namespace Pydio\Auth\Core; use Pydio\Core\Model\ContextInterface; +use Pydio\Core\Services\SessionService; use Pydio\Core\Utils\Vars\OptionsHelper; @@ -34,6 +35,9 @@ */ class MemorySafe { + + const SAFE_CREDENTIALS_KEY = "PYDIO_SAFE_CREDENTIALS"; + private static $instance; private $user; @@ -113,9 +117,44 @@ private function _decodePassword($encoded, $user) * Store the password credentials in the session * @return void */ - public function store() - { - $_SESSION["AJXP_SAFE_CREDENTIALS"] = base64_encode($this->user.$this->separator.$this->encodedPassword); + public function store() { + SessionService::save(self::SAFE_CREDENTIALS_KEY, base64_encode($this->user.$this->separator.$this->encodedPassword)); + } + + /** + * Set the encrypted string in the environment for running a CLI. + * @return bool + */ + public static function setEnv(){ + $encodedCreds = self::getEncodedCredentialString(); + if (!empty($encodedCreds)) { + putenv(self::SAFE_CREDENTIALS_KEY. "=" . $encodedCreds); + return true; + } + return false; + } + + /** + * Clear the environment variable + */ + public static function clearEnv(){ + putenv(self::SAFE_CREDENTIALS_KEY); + } + + /** + * Try to load encrypted string, decode, and get password if the user is corresponding. + * @param string $userId + * @return bool|mixed + */ + public static function loadPasswordStringFromEnvironment($userId){ + $env = getenv(self::SAFE_CREDENTIALS_KEY); + if(!empty($env)){ + $array = self::getCredentialsFromEncodedString($env); + if(isSet($array["user"]) && $array["user"] == $userId){ + return $array["password"]; + } + } + return false; } /** @@ -125,8 +164,8 @@ public function store() */ public function load($encodedString = "") { - if ($encodedString == "" && !empty($_SESSION["AJXP_SAFE_CREDENTIALS"])) { - $encodedString = $_SESSION["AJXP_SAFE_CREDENTIALS"]; + if ($encodedString == "" && SessionService::has(self::SAFE_CREDENTIALS_KEY)) { + $encodedString = SessionService::fetch(self::SAFE_CREDENTIALS_KEY); } if(empty($encodedString)) return; $sessData = base64_decode($encodedString); @@ -140,7 +179,7 @@ public function load($encodedString = "") */ public function clear() { - unset($_SESSION["AJXP_SAFE_CREDENTIALS"]); + SessionService::delete(self::SAFE_CREDENTIALS_KEY); $this->user = null; $this->encodedPassword = null; } @@ -204,9 +243,8 @@ public static function loadCredentials() /** * @return mixed */ - public static function getEncodedCredentialString() - { - return $_SESSION["AJXP_SAFE_CREDENTIALS"]; + public static function getEncodedCredentialString() { + return SessionService::fetch(self::SAFE_CREDENTIALS_KEY); } /** diff --git a/core/src/plugins/editor.audio/AudioPreviewer.php b/core/src/plugins/editor.audio/AudioPreviewer.php index 99c526da29..d9f2ba395c 100644 --- a/core/src/plugins/editor.audio/AudioPreviewer.php +++ b/core/src/plugins/editor.audio/AudioPreviewer.php @@ -131,7 +131,7 @@ public function switchAction(\Psr\Http\Message\ServerRequestInterface $requestIn $ar = explode(".", $label); $ext = strtolower(end($ar)); if(!$isFile || $ext != "mp3") continue; - $xmlBuff.="".AJXP_SERVER_ACCESS."?secure_token=".SecureTokenMiddleware::getSecureToken()."&get_action=audio_proxy&file=".base64_encode($child->getAttribute("filename"))."".$label.""; + $xmlBuff.="".AJXP_SERVER_ACCESS."?&get_action=audio_proxy&file=".base64_encode($child->getAttribute("filename"))."".$label.""; } $xmlBuff.=""; $xmlBuff.= ""; diff --git a/core/src/plugins/editor.audio/manifest.xml b/core/src/plugins/editor.audio/manifest.xml index 973b8dd8ec..3310f87fab 100644 --- a/core/src/plugins/editor.audio/manifest.xml +++ b/core/src/plugins/editor.audio/manifest.xml @@ -9,7 +9,7 @@ - +