]> source.dussan.org Git - nextcloud-server.git/commitdiff
encryption proxy wip
authorRobin Appelman <icewind1991@gmail.com>
Fri, 21 Oct 2011 15:02:11 +0000 (17:02 +0200)
committerRobin Appelman <icewind@owncloud.com>
Tue, 21 Feb 2012 19:48:47 +0000 (20:48 +0100)
apps/files_encryption/appinfo/app.php [new file with mode: 0644]
apps/files_encryption/lib/cryptstream.php [new file with mode: 0644]
apps/files_encryption/lib/proxy.php [new file with mode: 0644]
lib/crypt.php
lib/fileproxy.php
lib/filestorage/local.php
lib/filesystemview.php

diff --git a/apps/files_encryption/appinfo/app.php b/apps/files_encryption/appinfo/app.php
new file mode 100644 (file)
index 0000000..82d2544
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+
+OC::$CLASSPATH['OC_Crypt'] = 'apps/files_encryption/lib/crypt.php';
+OC::$CLASSPATH['OC_CryptStream'] = 'apps/files_encryption/lib/cryptstream.php';
+OC::$CLASSPATH['OC_FileProxy_Encryption'] = 'apps/files_encryption/lib/proxy.php';
+
+OC_FileProxy::register(new OC_FileProxy_Encryption());
+
+OC_Hook::connect('OC_User','post_login','OC_Crypt','loginListener');
+
+stream_wrapper_register('crypt','OC_CryptStream');
diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php
new file mode 100644 (file)
index 0000000..e454431
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+/**
+ * ownCloud
+ *
+ * @author Robin Appelman
+ * @copyright 2011 Robin Appelman icewind1991@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * transparently encrypted filestream
+ */
+
+class OC_CryptStream{
+       private $source;
+
+       public function stream_open($path, $mode, $options, &$opened_path){
+               $path=str_replace('crypt://','',$path);
+               $this->source=OC_FileSystem::fopen($path.'.enc',$mode);
+               if(!is_resource($this->source)){
+                       OC_Log::write('files_encryption','failed to open '.$path.'.enc',OC_Log::ERROR);
+               }
+               return is_resource($this->source);
+       }
+       
+       public function stream_seek($offset, $whence=SEEK_SET){
+               fseek($this->source,$offset,$whence);
+       }
+       
+       public function stream_tell(){
+               return ftell($this->source);
+       }
+       
+       public function stream_read($count){
+               $pos=0;
+               $currentPos=ftell($this->source);
+               $offset=$currentPos%8192;
+               fseek($this->source,-$offset,SEEK_CUR);
+               $result='';
+               while($count>$pos){
+                       $data=fread($this->source,8192);
+                       $pos+=8192;
+                       $result.=OC_Crypt::decrypt($data);
+               }
+               return substr($result,$offset,$count);
+       }
+       
+       public function stream_write($data){
+               $length=strlen($data);
+               $written=0;
+               $currentPos=ftell($this->source);
+               if($currentPos%8192!=0){
+                       //make sure we always start on a block start
+                       fseek($this->source,-($currentPos%8192),SEEK_CUR);
+                       $encryptedBlock=fread($this->source,8192);
+                       fseek($this->source,-($currentPos%8192),SEEK_CUR);
+                       $block=OC_Crypt::decrypt($encryptedBlock);
+                       $data=substr($block,0,$currentPos%8192).$data;
+               }
+               while(strlen($data)>0){
+                       if(strlen($data)<8192){
+                               //fetch the current data in that block and append it to the input so we always write entire blocks
+                               $oldPos=ftell($this->source);
+                               $encryptedBlock=fread($this->source,8192);
+                               fseek($this->source,$oldPos);
+                               $block=OC_Crypt::decrypt($encryptedBlock);
+                               $data.=substr($block,strlen($data));
+                       }
+                       $encrypted=OC_Crypt::encrypt(substr($data,0,8192));
+                       fwrite($this->source,$encrypted);
+                       $data=substr($data,8192);
+               }
+               return $length;
+       }
+
+       public function stream_set_option($option,$arg1,$arg2){
+               switch($option){
+                       case STREAM_OPTION_BLOCKING:
+                               stream_set_blocking($this->source,$arg1);
+                               break;
+                       case STREAM_OPTION_READ_TIMEOUT:
+                               stream_set_timeout($this->source,$arg1,$arg2);
+                               break;
+                       case STREAM_OPTION_WRITE_BUFFER:
+                               stream_set_write_buffer($this->source,$arg1,$arg2);
+               }
+       }
+
+       public function stream_stat(){
+               return fstat($this->source);
+       }
+       
+       public function stream_lock($mode){
+               flock($this->source,$mode);
+       }
+       
+       public function stream_flush(){
+               return fflush($this->source);
+       }
+
+       public function stream_eof(){
+               return feof($this->source);
+       }
+
+       public function stream_close(){
+               return fclose($this->source);
+       }
+}
\ No newline at end of file
diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php
new file mode 100644 (file)
index 0000000..f7a991a
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+/**
+* ownCloud
+*
+* @author Robin Appelman
+* @copyright 2011 Robin Appelman icewind1991@gmail.com
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * transparent encryption
+ */
+
+class OC_FileProxy_Encryption extends OC_FileProxy{
+       public function preFile_put_contents($path,&$data){
+               if(substr($path,-4)=='.enc'){
+                       OC_Log::write('files_encryption','file put contents',OC_Log::DEBUG);
+                       if (is_resource($data)) {
+                               $newData='';
+                               while(!feof($data)){
+                                       $block=fread($data,8192);
+                                       $newData.=OC_Crypt::encrypt($block);
+                               }
+                               $data=$newData;
+                       }else{
+                               $data=OC_Crypt::blockEncrypt($data);
+                       }
+               }
+       }
+       
+       public function postFile_get_contents($path,$data){
+               if(substr($path,-4)=='.enc'){
+                       OC_Log::write('files_encryption','file get contents',OC_Log::DEBUG);
+                       return OC_Crypt::blockDecrypt($data);
+               }
+       }
+       
+       public function postFopen($path,&$result){
+               if(substr($path,-4)=='.enc'){
+                       OC_Log::write('files_encryption','fopen',OC_Log::DEBUG);
+                       fclose($result);
+                       $result=fopen('crypt://'.substr($path,0,-4));//remove the .enc extention so we don't catch the fopen request made by cryptstream
+               }
+       }
+       
+       public function preReadFile($path){
+               if(substr($path,-4)=='.enc'){
+                       OC_Log::write('files_encryption','readline',OC_Log::DEBUG);
+                       $stream=fopen('crypt://'.substr($path,0,-4));
+                       while(!feof($stream)){
+                               print(fread($stream,8192));
+                       }
+                       return false;//cancel the original request
+               }
+       }
+}
index 6002067948040a712517881ec1b4396a5bc5a2c2..3e6fa05b85dc5ab485e06ceb776deda6cea93851 100644 (file)
@@ -113,14 +113,13 @@ class OC_Crypt {
                return($bf->encrypt($contents));
         }       
 
-
-        /**
-         * @brief encryption of a file
-         * @param $filename
-         * @param $key the encryption key
-         *
-         * This function encrypts a file
-         */
+       /**
+       * @brief encryption of a file
+       * @param $filename
+       * @param $key the encryption key
+       *
+       * This function encrypts a file
+       */
        public static function encryptfile( $filename, $key) {
                $handleread  = fopen($filename, "rb");
                if($handleread<>FALSE) {
@@ -158,6 +157,30 @@ class OC_Crypt {
                }
                fclose($handleread);
        }
+       
+       /**
+        * encrypt data in 8192b sized blocks
+        */
+       public static function blockEncrypt($data){
+               $result='';
+               while(strlen($data)){
+                       $result=self::encrypt(substr($data,0,8192));
+                       $data=substr($data,8192);
+               }
+               return $result;
+       }
+       
+       /**
+        * decrypt data in 8192b sized blocks
+        */
+       public static function blockDecrypt($data){
+               $result='';
+               while(strlen($data)){
+                       $result=self::decrypt(substr($data,0,8192));
+                       $data=substr($data,8192);
+               }
+               return $result;
+       }
 
 
 
index 1fb22bd11394b39d34f6d10affaf081257c4c7e1..796fd95cb38ad3f6e5c326578902546fdcd58b89 100644 (file)
@@ -83,16 +83,16 @@ class OC_FileProxy{
                return $proxies;
        }
 
-       public static function runPreProxies($operation,$filepath,$filepath2=null){
+       public static function runPreProxies($operation,&$filepath,&$filepath2=null){
                $proxies=self::getProxies($operation,false);
                $operation='pre'.$operation;
                foreach($proxies as $proxy){
-                       if($filepath2){
-                               if(!$proxy->$operation(&$filepath,&$filepath2)){
+                       if(!is_null($filepath2)){
+                               if($proxy->$operation($filepath,$filepath2)===false){
                                        return false;
                                }
                        }else{
-                               if(!$proxy->$operation(&$filepath)){
+                               if($proxy->$operation($filepath)===false){
                                        return false;
                                }
                        }
index dcb516a3afb7ff48f2a2fc64a3c5acc62a49674a..ee4b267bcd496192ac93bd2b7b1d058f156fb5da 100644 (file)
@@ -74,7 +74,7 @@ class OC_Filestorage_Local extends OC_Filestorage{
        public function file_get_contents($path){
                return file_get_contents($this->datadir.$path);
        }
-       public function file_put_contents($path,$data){
+       public function file_put_contents($path,$data=null){
                if($return=file_put_contents($this->datadir.$path,$data)){
                }
        }
index 91c6cd17720babaf01420f8500d96a415c6d2a73..a78f3f652ade49b1375df94d5dec36096c2b1ef8 100644 (file)
@@ -302,7 +302,7 @@ class OC_FilesystemView {
                                }
                        }
                        if($run){
-                               if($extraParam){
+                               if(!is_null($extraParam)){
                                        $result=$storage->$operation($interalPath,$extraParam);
                                }else{
                                        $result=$storage->$operation($interalPath);