Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Encapsulate 'safe credentials' and 'secure_tokens' in SessionService …
Browse files Browse the repository at this point in the history
…calls with dedicated keys.
  • Loading branch information
cdujeu committed Sep 22, 2016
1 parent 0cafd46 commit 9db8219
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 47 deletions.
17 changes: 7 additions & 10 deletions core/src/core/src/pydio/Core/Controller/CliRunner.php
Expand Up @@ -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;
}
Expand Down
12 changes: 4 additions & 8 deletions core/src/core/src/pydio/Core/Http/Cli/AuthCliMiddleware.php
Expand Up @@ -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;
}

}


Expand Down
Expand Up @@ -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');
Expand All @@ -38,6 +39,8 @@
class SecureTokenMiddleware
{

const SECURE_TOKENS_KEY = "PYDIO_SECURE_TOKENS";

/**
*
* @param ServerRequestInterface $requestInterface
Expand All @@ -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"];
Expand All @@ -78,28 +81,21 @@ 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;
}
/**
* Get the secure token from the session
* @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
Expand All @@ -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));
}

}
56 changes: 47 additions & 9 deletions core/src/plugins/core.auth/MemorySafe.php
Expand Up @@ -21,6 +21,7 @@
namespace Pydio\Auth\Core;

use Pydio\Core\Model\ContextInterface;
use Pydio\Core\Services\SessionService;
use Pydio\Core\Utils\Vars\OptionsHelper;


Expand All @@ -34,6 +35,9 @@
*/
class MemorySafe
{

const SAFE_CREDENTIALS_KEY = "PYDIO_SAFE_CREDENTIALS";

private static $instance;

private $user;
Expand Down Expand Up @@ -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;
}

/**
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion core/src/plugins/editor.audio/AudioPreviewer.php
Expand Up @@ -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.="<track><location>".AJXP_SERVER_ACCESS."?secure_token=".SecureTokenMiddleware::getSecureToken()."&get_action=audio_proxy&file=".base64_encode($child->getAttribute("filename"))."</location><title>".$label."</title></track>";
$xmlBuff.="<track><location>".AJXP_SERVER_ACCESS."?&get_action=audio_proxy&file=".base64_encode($child->getAttribute("filename"))."</location><title>".$label."</title></track>";
}
$xmlBuff.="</trackList>";
$xmlBuff.= "</playlist>";
Expand Down
2 changes: 1 addition & 1 deletion core/src/plugins/editor.audio/manifest.xml
Expand Up @@ -9,7 +9,7 @@
</client_settings>
<registry_contributions>
<actions>
<action name="audio_proxy" contentTypedProvider="true">
<action name="audio_proxy" contentTypedProvider="true" skipSecureToken="true">
<processing>
<serverCallback methodName="switchAction" restParams="/file+" developerComment="Server an audio file as a stream">
<input_param name="file" type="AJXP_NODE" description="Path to the file"/>
Expand Down

0 comments on commit 9db8219

Please sign in to comment.