. * */ /** * transparent encryption */ class OC_FileProxy_Encryption extends OC_FileProxy{ private static $blackList=null; //mimetypes blacklisted from encryption private static $metaData=array(); //metadata cache /** * check if a file should be encrypted during write * @param string $path * @return bool */ private static function shouldEncrypt($path){ if(is_null(self::$blackList)){ self::$blackList=explode(',',OC_Appconfig::getValue('files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg')); } if(self::isEncrypted($path)){ return true; } $extention=substr($path,strrpos($path,'.')+1); if(array_search($extention,self::$blackList)===false){ return true; } } /** * check if a file is encrypted * @param string $path * @return bool */ private static function isEncrypted($path){ if(isset(self::$metaData[$path])){ $metadata=self::$metaData[$path]; }else{ $metadata=OC_FileCache::getCached($path); self::$metaData[$path]=$metadata; } return (bool)$metadata['encrypted']; } public function preFile_put_contents($path,&$data){ if(self::shouldEncrypt($path)){ if (!is_resource($data)) {//stream put contents should have been converter to fopen $data=OC_Crypt::blockEncrypt($data); } } } public function postFile_get_contents($path,$data){ if(self::isEncrypted($path)){ $data=OC_Crypt::blockDecrypt($data); } return $data; } public function postFopen($path,&$result){ if(!$result){ return $result; } $meta=stream_get_meta_data($result); if(self::isEncrypted($path)){ fclose($result); $result=fopen('crypt://'.$path,$meta['mode']); }elseif(self::shouldEncrypt($path) and $meta['mode']!='r'){ if(OC_Filesystem::file_exists($path) and OC_Filesystem::filesize($path)>0){ //first encrypt the target file so we don't end up with a half encrypted file OC_Log::write('files_encryption','Decrypting '.$path.' before writing',OC_Log::DEBUG); $tmp=fopen('php://temp'); while(!feof($result)){ $chunk=fread($result,8192); if($chunk){ fwrite($tmp,$chunk); } } fclose($result); OC_Filesystem::file_put_contents($path,$tmp); fclose($tmp); } $result=fopen('crypt://'.$path,$meta['mode']); } return $result; } public function preReadFile($path){ if(self::isEncrypted($path)){ $stream=fopen('crypt://'.$path,'r'); while(!feof($stream)){ print(fread($stream,8192)); } return false;//cancel the original request } } public function postGetMimeType($path,$mime){ if((!OC_FileCache::inCache($path) and self::shouldEncrypt($path)) or self::isEncrypted($path)){ return OC_Helper::getMimeType('crypt://'.$path,'w'); }else{ return $mime; } } }