Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions lib/private/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ public function __construct($webRoot) {
$manager = $c->getUserManager();

$session = new \OC\Session\Memory('');
$cryptoWrapper = $c->getSessionCryptoWrapper();
$session = $cryptoWrapper->wrapSession($session);

$userSession = new \OC\User\Session($manager, $session);
$userSession->listen('\OC\User', 'preCreateUser', function ($uid, $password) {
Expand Down Expand Up @@ -252,7 +250,7 @@ public function __construct($webRoot) {

if($config->getSystemValue('installed', false) && !(defined('PHPUNIT_RUN') && PHPUNIT_RUN)) {
$v = \OC_App::getAppVersions();
$v['core'] = implode('.', \OC_Util::getVersion());
$v['core'] = md5(file_get_contents(\OC::$SERVERROOT . '/version.php'));
$version = implode(',', $v);
$instanceId = \OC_Util::getInstanceId();
$path = \OC::$SERVERROOT;
Expand Down
62 changes: 45 additions & 17 deletions lib/private/session/cryptosessiondata.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,47 @@
class CryptoSessionData implements \ArrayAccess, ISession {
/** @var ISession */
protected $session;

/** @var \OCP\Security\ICrypto */
protected $crypto;

/** @var string */
protected $passphrase;
/** @var array */
protected $sessionValues;
/** @var bool */
protected $isModified = false;
CONST encryptedSessionName = 'encrypted_session_data';

/**
* @param ISession $session
* @param ICrypto $crypto
* @param string $passphrase
*/
public function __construct(ISession $session, ICrypto $crypto, $passphrase) {
public function __construct(ISession $session,
ICrypto $crypto,
$passphrase) {
$this->crypto = $crypto;
$this->session = $session;
$this->passphrase = $passphrase;
$this->initializeSession();
}

/**
* Close session if class gets destructed
*/
public function __destruct() {
$this->close();
}

protected function initializeSession() {
$encryptedSessionData = $this->session->get(self::encryptedSessionName);
try {
$this->sessionValues = json_decode(
$this->crypto->decrypt($encryptedSessionData, $this->passphrase),
true
);
} catch (\Exception $e) {
$this->sessionValues = [];
}
}

/**
Expand All @@ -57,8 +82,8 @@ public function __construct(ISession $session, ICrypto $crypto, $passphrase) {
* @param mixed $value
*/
public function set($key, $value) {
$encryptedValue = $this->crypto->encrypt(json_encode($value), $this->passphrase);
$this->session->set($key, $encryptedValue);
$this->sessionValues[$key] = $value;
$this->isModified = true;
}

/**
Expand All @@ -68,17 +93,11 @@ public function set($key, $value) {
* @return string|null Either the value or null
*/
public function get($key) {
$encryptedValue = $this->session->get($key);
if ($encryptedValue === null) {
return null;
if(isset($this->sessionValues[$key])) {
return $this->sessionValues[$key];
}

try {
$value = $this->crypto->decrypt($encryptedValue, $this->passphrase);
return json_decode($value);
} catch (\Exception $e) {
return null;
}
return null;
}

/**
Expand All @@ -88,7 +107,7 @@ public function get($key) {
* @return bool
*/
public function exists($key) {
return $this->session->exists($key);
return isset($this->sessionValues[$key]);
}

/**
Expand All @@ -97,20 +116,29 @@ public function exists($key) {
* @param string $key
*/
public function remove($key) {
$this->session->remove($key);
$this->isModified = true;
unset($this->sessionValues[$key]);
$this->session->remove(self::encryptedSessionName);
}

/**
* Reset and recreate the session
*/
public function clear() {
$this->sessionValues = [];
$this->isModified = true;
$this->session->clear();
}

/**
* Close the session and release the lock
* Close the session and release the lock, also writes all changed data in batch
*/
public function close() {
if($this->isModified) {
$encryptedValue = $this->crypto->encrypt(json_encode($this->sessionValues), $this->passphrase);
$this->session->set(self::encryptedSessionName, $encryptedValue);
$this->isModified = false;
}
$this->session->close();
}

Expand Down
8 changes: 4 additions & 4 deletions lib/private/session/internal.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
* @package OC\Session
*/
class Internal extends Session {
/**
* @param string $name
* @throws \Exception
*/
public function __construct($name) {
session_name($name);
set_error_handler(array($this, 'trapError'));
Expand All @@ -42,10 +46,6 @@ public function __construct($name) {
}
}

public function __destruct() {
$this->close();
}

/**
* @param string $key
* @param integer $value
Expand Down
13 changes: 2 additions & 11 deletions tests/lib/session/cryptowrappingtest.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,17 @@ protected function setUp() {
$this->instance = new CryptoSessionData($this->wrappedSession, $this->crypto, 'PASS');
}

public function testWrappingSet() {
$unencryptedValue = 'foobar';

$this->wrappedSession->expects($this->once())
->method('set')
->with('key', $this->crypto->encrypt(json_encode($unencryptedValue)));
$this->instance->set('key', $unencryptedValue);
}

public function testUnwrappingGet() {
$unencryptedValue = 'foobar';
$encryptedValue = $this->crypto->encrypt($unencryptedValue);

$this->wrappedSession->expects($this->once())
->method('get')
->with('key')
->with('encrypted_session_data')
->willReturnCallback(function () use ($encryptedValue) {
return $encryptedValue;
});

$this->assertSame($unencryptedValue, $this->wrappedSession->get('key'));
$this->assertSame($unencryptedValue, $this->wrappedSession->get('encrypted_session_data'));
}
}