fixed finding encrypted files in subfolders and removed unused code

remotes/origin/stable6
Florin Peter 2013-05-22 00:53:07 +07:00
parent 095fc790ac
commit 9ca9a22c6a
4 changed files with 61 additions and 200 deletions

@ -326,44 +326,6 @@ class Keymanager
}
/**
* @brief store private keys from the user
*
* @param string $privatekey
* @param string $publickey
* @return bool true/false
*/
public static function setUserKeys($privatekey, $publickey)
{
return (self::setPrivateKey($privatekey) && self::setPublicKey($publickey));
}
/**
* @brief store public key of the user
*
* @param string $key
* @return bool true/false
*/
public static function setPublicKey($key)
{
$view = new \OC_FilesystemView('/public-keys');
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
if (!$view->file_exists('')) $view->mkdir('');
$result = $view->file_put_contents(\OCP\User::getUser() . '.public.key', $key);
\OC_FileProxy::$enabled = $proxyStatus;
return $result;
}
/**
* @brief store share key
*
@ -538,7 +500,7 @@ class Keymanager
list($owner, $filename) = $util->getUidAndFilename($filePath);
$shareKeyPath = '/' . $owner . '/files_encryption/share-keys/' . $filename;
$shareKeyPath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files_encryption/share-keys/' . $filename);
if ($view->is_dir($shareKeyPath)) {
@ -611,22 +573,4 @@ class Keymanager
return $targetPath;
}
/**
* @brief Fetch the legacy encryption key from user files
* @internal param string $login used to locate the legacy key
* @internal param string $passphrase used to decrypt the legacy key
* @return boolean
*
* if the key is left out, the default handeler will be used
*/
public function getLegacyKey()
{
$user = \OCP\User::getUser();
$view = new \OC_FilesystemView('/' . $user);
return $view->file_get_contents('encryption.key');
}
}

@ -170,7 +170,7 @@ class Proxy extends \OC_FileProxy
$data = $encData;
// Update the file cache with file info
\OC\Files\Filesystem::putFileInfo($filePath, array('encrypted' => true, 'size' => strlen($size), 'unencrypted_size' => $size), '');
\OC\Files\Filesystem::putFileInfo($filePath, array('encrypted' => true, 'size' => strlen($data), 'unencrypted_size' => $size), '');
// Re-enable proxy - our work is done
\OC_FileProxy::$enabled = $proxyStatus;
@ -189,28 +189,25 @@ class Proxy extends \OC_FileProxy
public function postFile_get_contents($path, $data)
{
// FIXME: $path for shared files is just /uid/files/Shared/filepath
$userId = \OCP\USER::getUser();
$view = new \OC_FilesystemView('/');
$util = new Util($view, $userId);
$relPath = $util->stripUserFilesPath($path);
// TODO check for existing key file and reuse it if possible to avoid problems with versioning etc.
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
// init session
$session = new Session($view);
// If data is a catfile
if (
Crypt::mode() == 'server'
&& Crypt::isCatfileContent($data) // TODO: Do we really need this check? Can't we assume it is properly encrypted?
&& Crypt::isCatfileContent($data)
) {
// TODO: use get owner to find correct location of key files for shared files
$session = new Session($view);
$privateKey = $session->getPrivateKey($userId);
// Get the encrypted keyfile
@ -229,9 +226,7 @@ class Proxy extends \OC_FileProxy
&& isset($_SESSION['legacyenckey'])
&& Crypt::isEncryptedMeta($path)
) {
$plainData = Crypt::legacyDecrypt($data, $session->getLegacyKey());
}
\OC_FileProxy::$enabled = $proxyStatus;
@ -292,19 +287,6 @@ class Proxy extends \OC_FileProxy
}
/**
* @brief When a file is renamed, rename its keyfile also
* @param $path
* @return bool Result of rename()
* @note This is pre rather than post because using post didn't work
*/
public function postWrite($path)
{
$this->handleFile($path);
return true;
}
/**
* @param $path
* @return bool
@ -362,7 +344,6 @@ class Proxy extends \OC_FileProxy
// protocol and let it do the decryption work instead
$result = fopen('crypt://' . $path_f, $meta['mode']);
} elseif (
self::shouldEncrypt($path)
and $meta ['mode'] != 'r'
@ -428,11 +409,28 @@ class Proxy extends \OC_FileProxy
*/
public function postStat($path, $data)
{
$content = '';
$view = new \OC_FilesystemView('/');
if($view->file_exists($path)) {
// disable encryption proxy
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
// we only need 24 byte from the last chunk
$handle = $view->fopen($path, 'r');
if (!fseek($handle, -24, SEEK_END)) {
$content = fgets($handle);
}
// re-enable proxy
\OC_FileProxy::$enabled = $proxyStatus;
}
// check if file is encrypted
if (Crypt::isCatfileContent($path)) {
if (Crypt::isCatfileContent($content)) {
// get file info from cache
$cached = \OC\Files\Filesystem::getFileInfo($path, '');
$cached = $view->getFileInfo($path);
// set the real file size
$data['size'] = $cached['unencrypted_size'];

@ -50,8 +50,6 @@ namespace OCA\Encryption;
*/
class Stream
{
public static $sourceStreams = array();
private $plainKey;
private $encKeyfiles;
@ -96,57 +94,41 @@ class Stream
// rawPath is relative to the data directory
$this->rawPath = $util->getUserFilesDir() . $this->relPath;
// Disable fileproxies so we can get the file size and open the source file without recursive encryption
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
if (
dirname($this->rawPath) == 'streams'
and isset(self::$sourceStreams[basename($this->rawPath)])
$mode == 'w'
or $mode == 'w+'
or $mode == 'wb'
or $mode == 'wb+'
) {
// Is this just for unit testing purposes?
$this->handle = self::$sourceStreams[basename($this->rawPath)]['stream'];
$this->path = self::$sourceStreams[basename($this->rawPath)]['path'];
$this->size = self::$sourceStreams[basename($this->rawPath)]['size'];
// We're writing a new file so start write counter with 0 bytes
$this->size = 0;
$this->unencryptedSize = 0;
} else {
// Disable fileproxies so we can get the file size and open the source file without recursive encryption
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
if (
$mode == 'w'
or $mode == 'w+'
or $mode == 'wb'
or $mode == 'wb+'
) {
// We're writing a new file so start write counter with 0 bytes
$this->size = 0;
$this->unencryptedSize = 0;
} else {
$this->size = $this->rootView->filesize($this->rawPath, $mode);
}
$this->size = $this->rootView->filesize($this->rawPath, $mode);
$this->handle = $this->rootView->fopen($this->rawPath, $mode);
}
\OC_FileProxy::$enabled = $proxyStatus;
$this->handle = $this->rootView->fopen($this->rawPath, $mode);
if (!is_resource($this->handle)) {
\OC_FileProxy::$enabled = $proxyStatus;
\OCP\Util::writeLog('files_encryption', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
if (!is_resource($this->handle)) {
} else {
\OCP\Util::writeLog('files_encryption', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
$this->meta = stream_get_meta_data($this->handle);
} else {
}
$this->meta = stream_get_meta_data($this->handle);
}
}
return is_resource($this->handle);
@ -165,14 +147,6 @@ class Stream
}
/**
* @return int
*/
public function stream_tell()
{
return ftell($this->handle);
}
/**
* @param $count
* @return bool|string
@ -259,7 +233,6 @@ class Stream
// If a keyfile already exists
if ($this->encKeyfile) {
$this->setUserProperty();
$session = new Session($this->rootView);
@ -279,23 +252,6 @@ class Stream
}
public function setUserProperty()
{
// Only get the user again if it isn't already set
if (empty($this->userId)) {
// TODO: Move this user call out of here - it belongs
// elsewhere
$this->userId = \OCP\User::getUser();
}
// TODO: Add a method for getting the user in case OCP\User::
// getUser() doesn't work (can that scenario ever occur?)
}
/**
* @brief Handle plain data from the stream, and write it in 8192 byte blocks
* @param string $data data to be written to disk
@ -318,16 +274,10 @@ class Stream
// Get the length of the unencrypted data that we are handling
$length = strlen($data);
// So far this round, no data has been written
$written = 0;
// Find out where we are up to in the writing of data to the
// Find out where we are up to in the writing of data to the
// file
$pointer = ftell($this->handle);
// Make sure the userId is set
$this->setUserProperty();
// Get / generate the keyfile for the file we're handling
// If we're writing a new file (not overwriting an existing
// one), save the newly generated keyfile
@ -337,7 +287,6 @@ class Stream
}
// If extra data is left over from the last round, make sure it
// is integrated into the next 6126 / 8192 block
if ($this->writeCache) {
@ -351,17 +300,16 @@ class Stream
}
// While there still remains somed data to be processed & written
while (strlen($data) > 0) {
// Remaining length for this iteration, not of the
// entire file (may be greater than 8192 bytes)
$remainingLength = strlen( $data );
$remainingLength = strlen($data);
// If data remaining to be written is less than the
// size of 1 6126 byte block
if (strlen($data) < 6126) {
if ($remainingLength < 6126) {
// Set writeCache to contents of $data
// The writeCache will be carried over to the
@ -388,9 +336,7 @@ class Stream
// being handled totals more than 6126 bytes
fwrite($this->handle, $encrypted);
$writtenLen = strlen($encrypted);
// Remove the chunk we just processed from
// Remove the chunk we just processed from
// $data, leaving only unprocessed data in $data
// var, for handling on the next round
$data = substr($data, 6126);
@ -416,16 +362,19 @@ class Stream
*/
public function stream_set_option($option, $arg1, $arg2)
{
$return = false;
switch ($option) {
case STREAM_OPTION_BLOCKING:
stream_set_blocking($this->handle, $arg1);
$return = stream_set_blocking($this->handle, $arg1);
break;
case STREAM_OPTION_READ_TIMEOUT:
stream_set_timeout($this->handle, $arg1, $arg2);
$return = stream_set_timeout($this->handle, $arg1, $arg2);
break;
case STREAM_OPTION_WRITE_BUFFER:
stream_set_write_buffer($this->handle, $arg1, $arg2);
$return = stream_set_write_buffer($this->handle, $arg1);
}
return $return;
}
/**
@ -441,7 +390,7 @@ class Stream
*/
public function stream_lock($mode)
{
flock($this->handle, $mode);
return flock($this->handle, $mode);
}
/**

@ -367,14 +367,16 @@ class Util
* @note $directory needs to be a path relative to OC data dir. e.g.
* /admin/files NOT /backup OR /home/www/oc/data/admin/files
*/
public function findEncFiles($directory)
public function findEncFiles($directory, &$found = false)
{
// Disable proxy - we don't want files to be decrypted before
// we handle them
\OC_FileProxy::$enabled = false;
$found = array('plain' => array(), 'encrypted' => array(), 'legacy' => array());
if($found == false) {
$found = array('plain' => array(), 'encrypted' => array(), 'legacy' => array());
}
if (
$this->view->is_dir($directory)
@ -395,7 +397,7 @@ class Util
// its contents
if ($this->view->is_dir($filePath)) {
$this->findEncFiles($filePath);
$this->findEncFiles($filePath, $found);
// If the path is a file, determine
// its encryption status
@ -636,38 +638,6 @@ class Util
}
/**
* @brief Format a path to be relative to the /user directory
* @note e.g. turns '/admin/files/test.txt' into 'files/test.txt'
*/
public function stripFilesPath($path)
{
$trimmed = ltrim($path, '/');
$split = explode('/', $trimmed);
$sliced = array_slice($split, 1);
$relPath = implode('/', $sliced);
return $relPath;
}
/**
* @brief Format a shared path to be relative to the /user/files/ directory
* @note Expects a path like /uid/files/Shared/filepath
*/
public function stripSharedFilePath($path)
{
$trimmed = ltrim($path, '/');
$split = explode('/', $trimmed);
$sliced = array_slice($split, 3);
$relPath = implode('/', $sliced);
return $relPath;
}
/**
* @param $path
* @return bool