aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xapps/files_encryption/lib/crypt.php4
-rw-r--r--apps/files_encryption/lib/proxy.php10
-rw-r--r--apps/files_encryption/lib/stream.php60
-rw-r--r--apps/files_encryption/lib/util.php78
-rwxr-xr-xapps/files_encryption/test/crypt.php6
5 files changed, 99 insertions, 59 deletions
diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php
index 2be6e3ae5d9..f92930c2cbd 100755
--- a/apps/files_encryption/lib/crypt.php
+++ b/apps/files_encryption/lib/crypt.php
@@ -114,7 +114,7 @@ class Crypt {
* @return true / false
* @note see also OCA\Encryption\Util->isEncryptedPath()
*/
- public static function isCatfile( $content ) {
+ public static function isCatfileContent( $content ) {
if ( !$content ) {
@@ -179,7 +179,7 @@ class Crypt {
if (
isset( $metadata['encrypted'] )
and $metadata['encrypted'] === true
- and ! self::isCatfile( $data )
+ and ! self::isCatfileContent( $data )
) {
return true;
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
index c5b1c8154c4..2a738c80e38 100644
--- a/apps/files_encryption/lib/proxy.php
+++ b/apps/files_encryption/lib/proxy.php
@@ -74,7 +74,7 @@ class Proxy extends \OC_FileProxy {
}
- if ( Crypt::isCatfile( $path ) ) {
+ if ( Crypt::isCatfileContent( $path ) ) {
return true;
@@ -209,7 +209,7 @@ class Proxy extends \OC_FileProxy {
// If data is a catfile
if (
Crypt::mode() == 'server'
- && Crypt::isCatfile( $data )
+ && Crypt::isCatfileContent( $data )
) {
// TODO use get owner to find correct location of key files for shared files
@@ -439,7 +439,7 @@ class Proxy extends \OC_FileProxy {
public function postGetMimeType( $path, $mime ) {
- if ( Crypt::isCatfile( $path ) ) {
+ if ( Crypt::isCatfileContent( $path ) ) {
$mime = \OCP\Files::getMimeType( 'crypt://' . $path, 'w' );
@@ -451,7 +451,7 @@ class Proxy extends \OC_FileProxy {
public function postStat( $path, $data ) {
- if ( Crypt::isCatfile( $path ) ) {
+ if ( Crypt::isCatfileContent( $path ) ) {
$cached = \OC\Files\Filesystem::getFileInfo( $path, '' );
@@ -464,7 +464,7 @@ class Proxy extends \OC_FileProxy {
public function postFileSize( $path, $size ) {
- if ( Crypt::isCatfile( $path ) ) {
+ if ( Crypt::isCatfileContent( $path ) ) {
$cached = \OC\Files\Filesystem::getFileInfo( $path, '' );
diff --git a/apps/files_encryption/lib/stream.php b/apps/files_encryption/lib/stream.php
index 6074638ab39..0b2e6ab3e64 100644
--- a/apps/files_encryption/lib/stream.php
+++ b/apps/files_encryption/lib/stream.php
@@ -68,42 +68,33 @@ class Stream {
private $rootView; // a fsview object set to '/'
public function stream_open( $path, $mode, $options, &$opened_path ) {
-
- $this->userId = \OCP\User::getUser();
- // Get access to filesystem via filesystemview object
- if ( !self::$view ) {
-
- self::$view = new \OC_FilesystemView( $this->userId . '/' );
-
- }
+ $this->userId = \OCP\User::getUser();
- // Set rootview object if necessary
- if ( ! $this->rootView ) {
+ if ( ! isset( $this->rootView ) ) {
- $this->rootView = new \OC_FilesystemView( $this->userId . '/' );
+ $this->rootView = new \OC_FilesystemView( '/' );
}
- // Get the bare file path
- $path = str_replace( 'crypt://', '', $path );
+ // Strip identifier text from path
+ $this->rawPath = str_replace( 'crypt://', '', $path );
- $this->rawPath = $path;
-
- $this->path_f = $this->userId . '/files/' . $path;
+ // Set file path relative to user files dir
+ $this->relPath = $this->userId . '/files/' . $this->rawPath;
if (
- dirname( $path ) == 'streams'
- and isset( self::$sourceStreams[basename( $path )] )
+ dirname( $this->rawPath ) == 'streams'
+ and isset( self::$sourceStreams[basename( $this->rawPath )] )
) {
// Is this just for unit testing purposes?
- $this->handle = self::$sourceStreams[basename( $path )]['stream'];
+ $this->handle = self::$sourceStreams[basename( $this->rawPath )]['stream'];
- $this->path = self::$sourceStreams[basename( $path )]['path'];
+ $this->path = self::$sourceStreams[basename( $this->rawPath )]['path'];
- $this->size = self::$sourceStreams[basename( $path )]['size'];
+ $this->size = self::$sourceStreams[basename( $this->rawPath )]['size'];
} else {
@@ -114,41 +105,38 @@ class Stream {
or $mode == 'wb+'
) {
+ // We're writing a new file so start write counter with 0 bytes
$this->size = 0;
} else {
+ $this->size = $this->rootView->filesize( $this->relPath, $mode );
-
- $this->size = self::$view->filesize( $this->path_f, $mode );
-
- //$this->size = filesize( $path );
+ //$this->size = filesize( $this->rawPath );
}
// Disable fileproxies so we can open the source file without recursive encryption
\OC_FileProxy::$enabled = false;
- //$this->handle = fopen( $path, $mode );
+ //$this->handle = fopen( $this->rawPath, $mode );
- $this->handle = self::$view->fopen( $this->path_f, $mode );
+ $this->handle = $this->rootView->fopen( $this->relPath, $mode );
\OC_FileProxy::$enabled = true;
- if ( !is_resource( $this->handle ) ) {
+ if ( ! is_resource( $this->handle ) ) {
- \OCP\Util::writeLog( 'files_encryption', 'failed to open '.$path, \OCP\Util::ERROR );
+ \OCP\Util::writeLog( 'files_encryption', 'failed to open file "'.$this->rootView . '"', \OCP\Util::ERROR );
+ } else {
+
+ $this->meta = stream_get_meta_data( $this->handle );
+
}
}
- if ( is_resource( $this->handle ) ) {
-
- $this->meta = stream_get_meta_data( $this->handle );
-
- }
-
return is_resource( $this->handle );
}
@@ -238,7 +226,7 @@ class Stream {
// If a keyfile already exists for a file named identically to
// file to be written
- if ( self::$view->file_exists( $this->userId . '/'. 'files_encryption' . '/' . 'keyfiles' . '/' . $this->rawPath . '.key' ) ) {
+ if ( $this->rootView->file_exists( $this->userId . '/'. 'files_encryption' . '/' . 'keyfiles' . '/' . $this->rawPath . '.key' ) ) {
// TODO: add error handling for when file exists but no
// keyfile
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index 6a18feea7df..e8b5be2de15 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -24,13 +24,12 @@
# Bugs
# ----
# Sharing a file to a user without encryption set up will not provide them with access but won't notify the sharer
-# When encryption app is disabled files become unreadable
# Timeouts on first login due to encryption of very large files
# Missing features
# ----------------
-# Re-use existing keyfiles so they don't need version control
+# Re-use existing keyfiles so they don't need version control (part implemented, stream{} and util{} remain)
# Make sure user knows if large files weren't encrypted
# Trashbin support
@@ -280,14 +279,14 @@ class Util {
// will eat server resources :(
if (
Keymanager::getFileKey( $this->view, $this->userId, $file )
- && Crypt::isCatfile( $data )
+ && Crypt::isCatfileContent( $data )
) {
$found['encrypted'][] = array( 'name' => $file, 'path' => $filePath );
// If the file uses old
// encryption system
- } elseif ( Crypt::isLegacyEncryptedContent( $this->view->file_get_contents( $filePath ), $relPath ) ) {
+ } elseif ( Crypt::isLegacyEncryptedContent( $this->tail( $filePath, 3 ), $relPath ) ) {
$found['legacy'][] = array( 'name' => $file, 'path' => $filePath );
@@ -325,6 +324,49 @@ class Util {
}
/**
+ * @brief Fetch the last lines of a file efficiently
+ * @note Safe to use on large files; does not read entire file to memory
+ * @note Derivative of http://tekkie.flashbit.net/php/tail-functionality-in-php
+ */
+ public function tail( $filename, $numLines ) {
+
+ \OC_FileProxy::$enabled = false;
+
+ $text = '';
+ $pos = -1;
+ $handle = $this->view->fopen( $filename, 'r' );
+
+ while ( $numLines > 0 ) {
+
+ --$pos;
+
+ if( fseek( $handle, $pos, SEEK_END ) !== 0 ) {
+
+ rewind( $handle );
+ $numLines = 0;
+
+ } elseif ( fgetc( $handle ) === "\n" ) {
+
+ --$numLines;
+
+ }
+
+ $block_size = ( -$pos ) % 8192;
+ if ( $block_size === 0 || $numLines === 0 ) {
+
+ $text = fread( $handle, ( $block_size === 0 ? 8192 : $block_size ) ) . $text;
+
+ }
+ }
+
+ fclose( $handle );
+
+ \OC_FileProxy::$enabled = true;
+
+ return $text;
+ }
+
+ /**
* @brief Check if a given path identifies an encrypted file
* @return true / false
*/
@@ -338,7 +380,7 @@ class Util {
\OC_FileProxy::$enabled = true;
- return Crypt::isCatfile( $data );
+ return Crypt::isCatfileContent( $data );
}
@@ -403,22 +445,32 @@ class Util {
// Encrypt unencrypted files
foreach ( $found['plain'] as $plainFile ) {
+
+ // Open plain file handle
+
+
+ // Open enc file handle
+
- // Fetch data from file
- $plainData = $this->view->file_get_contents( $plainFile['path'] );
+ // Read plain file in chunks
- // Encrypt data, generate catfile
- $encrypted = Crypt::keyEncryptKeyfile( $plainData, $publicKey );
$relPath = $this->stripUserFilesPath( $plainFile['path'] );
- // Save keyfile
- Keymanager::setFileKey( $this->view, $relPath, $this->userId, $encrypted['key'] );
+ // Open handle with for binary reading
+ $plainHandle = $this->view->fopen( $plainFile['path'], 'rb' );
+ // Open handle with for binary writing
+ $encHandle = fopen( 'crypt://' . 'var/www/oc6/data/' . $plainFile['path'] . '.tmp', 'ab' );
// Overwrite the existing file with the encrypted one
- $this->view->file_put_contents( $plainFile['path'], $encrypted['data'] );
+ //$this->view->file_put_contents( $plainFile['path'], $encrypted['data'] );
+ $size = stream_copy_to_stream( $plainHandle, $encHandle );
+
+ // Fetch the key that has just been set/updated by the stream
+ $encKey = Keymanager::getFileKey( $relPath );
- $size = strlen( $encrypted['data'] );
+ // Save keyfile
+ Keymanager::setFileKey( $this->view, $relPath, $this->userId, $encKey );
// Add the file to the cache
\OC\Files\Filesystem::putFileInfo( $plainFile['path'], array( 'encrypted'=>true, 'size' => $size ), '' );
diff --git a/apps/files_encryption/test/crypt.php b/apps/files_encryption/test/crypt.php
index 48ad2ee0075..b02e63b2ffc 100755
--- a/apps/files_encryption/test/crypt.php
+++ b/apps/files_encryption/test/crypt.php
@@ -416,13 +416,13 @@ class Test_Crypt extends \PHPUnit_Framework_TestCase {
function testIsEncryptedContent() {
- $this->assertFalse( Encryption\Crypt::isCatfile( $this->dataUrl ) );
+ $this->assertFalse( Encryption\Crypt::isCatfileContent( $this->dataUrl ) );
- $this->assertFalse( Encryption\Crypt::isCatfile( $this->legacyEncryptedData ) );
+ $this->assertFalse( Encryption\Crypt::isCatfileContent( $this->legacyEncryptedData ) );
$keyfileContent = Encryption\Crypt::symmetricEncryptFileContent( $this->dataUrl, 'hat' );
- $this->assertTrue( Encryption\Crypt::isCatfile( $keyfileContent ) );
+ $this->assertTrue( Encryption\Crypt::isCatfileContent( $keyfileContent ) );
}