Development Snapshot

Opening short files via webdav, that were saved via webdav, now works
This commit is contained in:
Sam Tuke 2012-12-04 19:53:13 +00:00
parent bfd47cd2df
commit bc3550b37b
5 changed files with 172 additions and 41 deletions

View File

@ -67,7 +67,9 @@ class Hooks {
$_SESSION['enckey'] = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] ); $_SESSION['enckey'] = Crypt::symmetricDecryptFileContent( $encryptedKey, $params['password'] );
// trigger_error( "\$_SESSION['enckey'] = {$_SESSION['enckey']}" ); \OC_FileProxy::$enabled = false;
file_put_contents( '/home/samtuke/enckey', $_SESSION['enckey'] );
\OC_FileProxy::$enabled = true;
$view1 = new \OC_FilesystemView( '/' . $params['uid'] ); $view1 = new \OC_FilesystemView( '/' . $params['uid'] );

View File

@ -142,14 +142,15 @@ class Proxy extends \OC_FileProxy {
Crypt::mode() == 'server' Crypt::mode() == 'server'
&& Crypt::isEncryptedContent( $data ) && Crypt::isEncryptedContent( $data )
) { ) {
//trigger_error("bong");
$filePath = explode( '/', $path ); $filePath = explode( '/', $path );
$filePath = array_slice( $filePath, 3 ); $filePath = array_slice( $filePath, 3 );
$filePath = '/' . implode( '/', $filePath ); $filePath = '/' . implode( '/', $filePath );
$cached = \OC_FileCache_Cached::get( $path, '' ); //$cached = \OC_FileCache_Cached::get( $path, '' );
$keyFile = Keymanager::getFileKey( $filePath ); $keyFile = Keymanager::getFileKey( $filePath );
@ -158,8 +159,9 @@ class Proxy extends \OC_FileProxy {
} elseif ( } elseif (
Crypt::mode() == 'server' Crypt::mode() == 'server'
&& isset( $_SESSION['legacyenckey'] ) && isset( $_SESSION['legacyenckey'] )
//&& Crypt::isEncryptedMeta( $path ) && Crypt::isEncryptedMeta( $path )
) { ) {
trigger_error("mong");
$data = Crypt::legacyDecrypt( $data, $_SESSION['legacyenckey'] ); $data = Crypt::legacyDecrypt( $data, $_SESSION['legacyenckey'] );
//trigger_error($data); //trigger_error($data);
@ -180,6 +182,10 @@ class Proxy extends \OC_FileProxy {
} }
// Reformat path for use with OC_FSV
$path_split = explode( '/', $path );
$path_f = implode( array_slice( $path_split, 3 ) );
// Disable encryption proxy to prevent recursive calls // Disable encryption proxy to prevent recursive calls
\OC_FileProxy::$enabled = false; \OC_FileProxy::$enabled = false;
@ -192,14 +198,17 @@ class Proxy extends \OC_FileProxy {
$util = new Util( $view, \OCP\USER::getUser()); $util = new Util( $view, \OCP\USER::getUser());
// If file is already encrypted, decrypt using crypto protocol // If file is already encrypted, decrypt using crypto protocol
if ( Crypt::mode() == 'server' && $util->isEncryptedPath( $path ) ) { if (
Crypt::mode() == 'server'
&& $util->isEncryptedPath( $path )
) {
// Close the original encrypted file // Close the original encrypted file
fclose( $result ); fclose( $result );
// Open the file using the crypto protocol and let // Open the file using the crypto stream wrapper
// it do the decryption work instead // protocol and let it do the decryption work instead
$result = fopen( 'crypt://' . $path, $meta['mode'] ); $result = fopen( 'crypt://' . $path_f, $meta['mode'] );
} elseif ( } elseif (
@ -207,14 +216,10 @@ class Proxy extends \OC_FileProxy {
and $meta ['mode'] != 'r' and $meta ['mode'] != 'r'
and $meta['mode'] != 'rb' and $meta['mode'] != 'rb'
) { ) {
// If the file should be encrypted and has been opened for // If the file is not yet encrypted, but should be
// reading only // encrypted when it's saved (it's not read only)
// Reformat path for use with OC_FSV // NOTE: this is the case for new files saved via WebDAV
$path_split = explode( '/', $path );
$path_f = implode( array_slice( $path_split, 3 ) );
// trigger_error("$path_f = ".var_export($path_f, 1));
if ( if (
$view->file_exists( $path ) $view->file_exists( $path )
@ -222,7 +227,7 @@ class Proxy extends \OC_FileProxy {
) { ) {
$x = $view->file_get_contents( $path ); $x = $view->file_get_contents( $path );
trigger_error( "size = ".var_export( $x, 1 ) ); //trigger_error( "size = ".var_export( $x, 1 ) );
$tmp = tmpfile(); $tmp = tmpfile();

View File

@ -39,33 +39,51 @@ namespace OCA\Encryption;
*/ */
class Util { class Util {
# DONE: add method to check if file is encrypted using new system
# DONE: add method to check if file is encrypted using old system
# DONE: add method to fetch legacy key
# DONE: add method to decrypt legacy encrypted data
# DONE: fix / test the crypt stream proxy class
# DONE: replace cryptstream wrapper new AES based system
# DONE: Encryption works for writing new text files in web ui
# DONE: reading unencrypted files when encryption is enabled works via webdav
# TODO: file uploaded via web ui get encrypted
# TODO: new files created and uploaded via webdav get encrypted
# TODO: add support for optional recovery user in case of lost passphrase / keys # Web UI:
# TODO: add admin optional required long passphrase for users
# TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc.
# TODO: add UI buttons for encrypt / decrypt everything?
# TODO: add method to encrypt all user files using new system ## DONE: files created via web ui are encrypted
# TODO: add method to decrypt all user files using new system ## DONE: file created & encrypted via web ui are readable in web ui
# TODO: add method to encrypt all user files using old system
# TODO: add method to decrypt all user files using old system
# WebDAV:
## DONE: new data filled files added via webdav get encrypted
## DONE: new data filled files added via webdav are readable via webdav
## DONE: reading unencrypted files when encryption is enabled works via webdav
# TODO: files created & encrypted via web ui are readable via webdav
# Legacy support:
## DONE: add method to check if file is encrypted using new system
## DONE: add method to check if file is encrypted using old system
## DONE: add method to fetch legacy key
## DONE: add method to decrypt legacy encrypted data
## TODO: add method to encrypt all user files using new system
## TODO: add method to decrypt all user files using new system
## TODO: add method to encrypt all user files using old system
## TODO: add method to decrypt all user files using old system
# Admin UI:
## TODO: add support for optional recovery in case of lost passphrase / keys
## TODO: add admin optional required long passphrase for users
## TODO: add UI buttons for encrypt / decrypt everything
## TODO: implement flag system to allow user to specify encryption by folder, subfolder, etc.
# Integration testing:
## TODO: test new encryption with webdav
## TODO: test new encryption with versioning
## TODO: test new encryption with sharing
## TODO: test new encryption with proxies
# TODO: test new encryption with webdav
# TODO: test new encryption with versioning
# TODO: test new encryption with sharing
# TODO: test new encryption with proxies
# NOTE: Curretly code on line 206 onwards in lib/proxy.php needs work. This code is executed when webdav writes take place, and appears to need to convert streams into fopen resources. Currently code within the if statement on 215 is not executing. Investigate the paths (handled there (which appear to be blank), and whether oc_fsv is borking them during processing. # NOTE: Curretly code on line 206 onwards in lib/proxy.php needs work. This code is executed when webdav writes take place, and appears to need to convert streams into fopen resources. Currently code within the if statement on 215 is not executing. Investigate the paths (handled there (which appear to be blank), and whether oc_fsv is borking them during processing.
@ -73,6 +91,7 @@ class Util {
# NOTE: for some reason file_get_contents is not working in proxy class postfopen. The same line works in sscce, but always returns an empty string in proxy.php. this is the same regardless of whether oc_fs, oc_fsv, or direct use of phps file_get_contents is used # NOTE: for some reason file_get_contents is not working in proxy class postfopen. The same line works in sscce, but always returns an empty string in proxy.php. this is the same regardless of whether oc_fs, oc_fsv, or direct use of phps file_get_contents is used
private $view; // OC_FilesystemView object for filesystem operations private $view; // OC_FilesystemView object for filesystem operations
private $pwd; // User Password private $pwd; // User Password
private $client; // Client side encryption mode flag private $client; // Client side encryption mode flag
@ -241,8 +260,14 @@ class Util {
*/ */
public function isEncryptedPath( $path ) { public function isEncryptedPath( $path ) {
// Disable encryption proxy so data retreived is in its
// original form
\OC_FileProxy::$enabled = false;
$data = $this->view->file_get_contents( $path ); $data = $this->view->file_get_contents( $path );
\OC_FileProxy::$enabled = true;
return Crypt::isEncryptedContent( $data ); return Crypt::isEncryptedContent( $data );
} }

View File

@ -1,11 +1,109 @@
<?php <?php
/** /**
* Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> * Copyright (c) 2012 Sam Tuke <samtuke@owncloud.com>,
* and Robin Appelman <icewind@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or * This file is licensed under the Affero General Public License version 3 or
* later. * later.
* See the COPYING-README file. * See the COPYING-README file.
*/ */
require_once "PHPUnit/Framework/TestCase.php";
require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Generator.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/MockInterface.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Mock.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Container.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Configuration.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CompositeExpectation.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/ExpectationDirector.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Expectation.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Exception.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/CountValidatorAbstract.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/Exception.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CountValidator/Exact.php' );
use \Mockery as m;
use OCA\Encryption;
class Test_Util extends \PHPUnit_Framework_TestCase {
public function setUp() {
$this->proxy = new Encryption\Proxy();
$this->tmpFileName = "tmpFile-".time();
$this->privateKey = file_get_contents( realpath( dirname(__FILE__).'/data/admin.public.key' ) );
$this->publicKey = file_get_contents( realpath( dirname(__FILE__).'/data/admin.private.key' ) );
$this->encDataShort = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester-enc' ) );
$this->encDataShortKey = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester.key' ) );
$this->dataShort = file_get_contents( realpath( dirname(__FILE__).'/data/yoga-manchester' ) );
$this->dataLong = file_get_contents( realpath( dirname(__FILE__).'/../lib/crypt.php' ) );
$this->longDataPath = realpath( dirname(__FILE__).'/../lib/crypt.php' );
$this->data1 = file_get_contents( realpath( dirname(__FILE__).'/../../../data/admin/files/enc-test.txt' ) );
$this->userId = 'admin';
$this->pass = 'admin';
$_SESSION['enckey'] = '-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDiH3EA4EpFA7Fx
s2dyyfL5jwXeYXrTqQJ6DqKgGn8VsbT3eu8R9KzM2XitVwZe8c8L52DvJ06o5vg0
GqPYxilFdOFJe/ggac5Tq8UmJiZS4EqYEMwxBIfIyWTxeGV06/0HOwnVAkqHMcBz
64qldtgi5O8kZMEM2/gKBgU0kMLJzM+8oEWhL1+gsUWQhxd8cKLXypS6iWgqFJrz
f/X0hJsJR+gyYxNpahtnjzd/LxLAETrOMsl2tue+BAxmjbAM0aG0NEM0div+b59s
2uz/iWbxImp5pOdYVKcVW89D4XBMyGegR40trV2VwiuX1blKCfdjMsJhiaL9pymp
ug1wzyQFAgMBAAECggEAK6c+PZkPPXuVCgpEcliiW6NM0r2m5K3AGKgypQ34csu3
z/8foCvIIFPrhCtEw5eTDQ1CHWlNOjY8vHJYJ0U6Onpx86nHIRrMBkMm8FJ1G5LJ
U8oKYXwqaozWu/cuPwA//OFc6I5krOzh5n8WaRMkbrgbor8AtebRX74By0AXGrXe
cswJI7zR96oFn4Dm7Pgvpg5Zhk1vFJ+w6QtH+4DDJ6PBvlZsRkGxYBLGVd/3qhAI
sBAyjFlSzuP4eCRhHOhHC/e4gmAH9evFVXB88jFyRZm3K+jQ5W5CwrVRBCV2lph6
2B6P7CBJN+IjGKMhy+75y13UvvKPv9IwH8Fzl2x1gQKBgQD8qQOr7a6KhSj16wQE
jim2xqt9gQ2jH5No405NrKs/PFQQZnzD4YseQsiK//NUjOJiUhaT+L5jhIpzINHt
RJpt3bGkEZmLyjdjgTpB3GwZdXa28DNK9VdXZ19qIl/ZH0qAjKmJCRahUDASMnVi
M4Pkk9yx9ZIKkri4TcuMWqc0DQKBgQDlHKBTITZq/arYPD6Nl3NsoOdqVRqJrGay
0TjXAVbBXe46+z5lnMsqwXb79nx14hdmSEsZULrw/3f+MnQbdjMTYLFP24visZg9
MN8vAiALiiiR1a+Crz+DTA1Q8sGOMVCMqMDmD7QBys3ZuWxuapm0txAiIYUtsjJZ
XN76T4nZ2QKBgQCHaT3igzwsWTmesxowJtEMeGWomeXpKx8h89EfqA8PkRGsyIDN
qq+YxEoe1RZgljEuaLhZDdNcGsjo8woPk9kAUPTH7fbRCMuutK+4ZJ469s1tNkcH
QX5SBcEJbOrZvv967ehe3VQXmJZq6kgnHVzuwKBjcC2ZJRGDFY6l5l/+cQKBgCqh
+Adf/8NK7paMJ0urqfPFwSodKfICXZ3apswDWMRkmSbqh4La+Uc8dsqN5Dz/VEFZ
JHhSeGbN8uMfOlG93eU2MehdPxtw1pZUWMNjjtj23XO9ooob2CKzbSrp8TBnZsi1
widNNr66oTFpeo7VUUK6acsgF6sYJJxSVr+XO1yJAoGAEhvitq8shNKcEY0xCipS
k1kbgyS7KKB7opVxI5+ChEqyUDijS3Y9FZixrRIWE6i2uGu86UG+v2lbKvSbM4Qm
xvbOcX9OVMnlRb7n8woOP10UMY+ZE2x+YEUXQTLtPYq7F66e1OfxltstMxLQA+3d
Y1d5piFV8PXK3Fg2F+Cj5qg=
-----END PRIVATE KEY-----
';
\OC_User::setUserId( $this->userId );
}
public function testpreFile_get_contents() {
// This won't work for now because mocking of the static keymanager class isn't working :(
// $mock = m::mock( 'alias:OCA\Encryption\Keymanager' );
//
// $mock->shouldReceive( 'getFileKey' )->times(2)->andReturn( $this->encDataShort );
//
// $encrypted = $this->proxy->postFile_get_contents( 'data/'.$this->tmpFileName, $this->encDataShortKey );
//
// $this->assertNotEquals( $this->dataShort, $encrypted );
//
// var_dump($encrypted);
$decrypted = $this->proxy->postFile_get_contents( 'data/admin/files/enc-test.txt', $this->data1 );
var_dump($decrypted);
}
}
// class Test_CryptProxy extends UnitTestCase { // class Test_CryptProxy extends UnitTestCase {
// private $oldConfig; // private $oldConfig;
// private $oldKey; // private $oldKey;

View File

@ -9,9 +9,10 @@
require_once "PHPUnit/Framework/TestCase.php"; require_once "PHPUnit/Framework/TestCase.php";
require_once realpath( dirname(__FILE__).'/../../../lib/base.php' ); require_once realpath( dirname(__FILE__).'/../../../lib/base.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery.php' ); require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Container.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Generator.php' ); require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Generator.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/MockInterface.php' ); require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/MockInterface.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Mock.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Container.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Configuration.php' ); require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/Configuration.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CompositeExpectation.php' ); require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/CompositeExpectation.php' );
require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/ExpectationDirector.php' ); require_once realpath( dirname(__FILE__).'/../../../3rdparty/mockery/Mockery/ExpectationDirector.php' );