extend the encryption stream wrapper to handle local files and add a fall back for file size calculation if the storage doesn't support fseek

remotes/origin/ldap_group_count
Bjoern Schiessle 13 years ago
parent d9668977cd
commit 4f8ae789ae
  1. 24
      apps/files_encryption/lib/helper.php
  2. 25
      apps/files_encryption/lib/stream.php
  3. 19
      apps/files_encryption/lib/util.php

@ -29,6 +29,8 @@ namespace OCA\Encryption;
*/
class Helper {
private static $tmpFileMapping; // Map tmp files to files in data/user/files
/**
* @brief register share related hooks
*
@ -423,5 +425,27 @@ class Helper {
public static function escapeGlobPattern($path) {
return preg_replace('/(\*|\?|\[)/', '[$1]', $path);
}
/**
* @brief remember from which file the tmp file (getLocalFile() call) was created
* @param string $tmpFile path of tmp file
* @param string $originalFile path of the original file relative to data/
*/
public static function addTmpFileToMapper($tmpFile, $originalFile) {
self::$tmpFileMapping[$tmpFile] = $originalFile;
}
/**
* @brief get the path of the original file
* @param string $tmpFile path of the tmp file
* @return mixed path of the original file or false
*/
public static function getPathFromTmpFile($tmpFile) {
if (isset(self::$tmpFileMapping[$tmpFile])) {
return self::$tmpFileMapping[$tmpFile];
}
return false;
}
}

@ -64,6 +64,9 @@ class Stream {
private $publicKey;
private $encKeyfile;
private $newFile; // helper var, we only need to write the keyfile for new files
private $isLocalTmpFile = false; // do we operate on a local tmp file
private $localTmpFile; // path of local tmp file
/**
* @var \OC\Files\View
*/
@ -91,13 +94,18 @@ class Stream {
$this->rootView = new \OC_FilesystemView('/');
}
$this->session = new \OCA\Encryption\Session($this->rootView);
$this->privateKey = $this->session->getPrivateKey();
// rawPath is relative to the data directory
$this->rawPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
$normalizedPath = \OC\Files\Filesystem::normalizePath(str_replace('crypt://', '', $path));
if ($originalFile = Helper::getPathFromTmpFile($normalizedPath)) {
$this->rawPath = $originalFile;
$this->isLocalTmpFile = true;
$this->localTmpFile = $normalizedPath;
} else {
$this->rawPath = $normalizedPath;
}
$this->userId = Helper::getUser($this->rawPath);
@ -141,10 +149,14 @@ class Stream {
\OCA\Encryption\Helper::redirectToErrorPage($this->session);
}
$this->size = $this->rootView->filesize($this->rawPath, $mode);
$this->size = $this->rootView->filesize($this->rawPath);
}
$this->handle = $this->rootView->fopen($this->rawPath, $mode);
if ($this->isLocalTmpFile) {
$this->handle = fopen($this->localTmpFile, $mode);
} else {
$this->handle = $this->rootView->fopen($this->rawPath, $mode);
}
\OC_FileProxy::$enabled = $proxyStatus;
@ -488,7 +500,7 @@ class Stream {
if ($this->privateKey === false) {
// cleanup
if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb') {
if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb' && !$this->isLocalTmpFile) {
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy::$enabled;
@ -509,6 +521,7 @@ class Stream {
if (
$this->meta['mode'] !== 'r' &&
$this->meta['mode'] !== 'rb' &&
$this->isLocalTmpFile === false &&
$this->size > 0 &&
$this->unencryptedSize > 0
) {

@ -473,7 +473,9 @@ class Util {
$data = '';
$handle = $this->view->fopen($path, 'r');
if (is_resource($handle)) {
if (fseek($handle, -24, SEEK_END) === 0) {
// suppress fseek warining, we handle the case that fseek doesn't
// work in the else branch
if (@fseek($handle, -24, SEEK_END) === 0) {
$data = fgets($handle);
} else {
// if fseek failed on the storage we create a local copy from the file
@ -537,7 +539,20 @@ class Util {
$lastChunckPos = ($lastChunkNr * 8192);
// seek to end
fseek($stream, $lastChunckPos);
if (@fseek($stream, $lastChunckPos) === -1) {
// storage doesn't support fseek, we need a local copy
fclose($stream);
$localFile = $this->view->getLocalFile($path);
Helper::addTmpFileToMapper($localFile, $path);
$stream = fopen('crypt://' . $localFile, "r");
if (fseek($stream, $lastChunckPos) === -1) {
// if fseek also fails on the local storage, than
// there is nothing we can do
fclose($stream);
\OCP\Util::writeLog('Encryption library', 'couldn\'t determine size of "' . $path, \OCP\Util::ERROR);
return $result;
}
}
// get the content of the last chunk
$lastChunkContent = fread($stream, $lastChunkSize);

Loading…
Cancel
Save