. * */ /** * transparent encryption */ class OC_FileProxy_Encryption extends OC_FileProxy{ private static $blackList=null; //mimetypes blacklisted from encryption private static $enableEncryption=null; /** * Check if a file requires encryption * @param string $path * @return bool * * Tests if encryption is enabled, and file is allowed by blacklists */ private static function shouldEncrypt( $path ) { if ( is_null( self::$enableEncryption ) ) { self::$enableEncryption = ( OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' ); } if( !self::$enableEncryption ) { return false; } if( is_null(self::$blackList ) ) { self::$blackList = explode(',',OCP\Config::getAppValue( 'files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg' ) ); } if( self::isEncrypted( $path ) ) { return true; } $extension = substr( $path, strrpos( $path,'.' ) +1 ); if ( array_search( $extension, self::$blackList ) === false ){ return true; } return false; } /** * Check if a file is encrypted according to database file cache * @param string $path * @return bool */ private static function isEncrypted( $path ){ // Fetch all file metadata from DB $metadata = OC_FileCache_Cached::get( $path, '' ); // Return encryption status return isset( $metadata['encrypted'] ) and ( 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 $size = strlen( $data ); $data = Crypt::blockEncrypt( $data ); OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' ); } } } public function postFile_get_contents($path,$data){ if(self::isEncrypted($path)){ $cached=OC_FileCache_Cached::get($path,''); $data=OC_Crypt::blockDecrypt($data,'',$cached['size']); } 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' and $meta['mode']!='rb'){ 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 OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing',OCP\Util::DEBUG); $tmp=fopen('php://temp'); OCP\Files::streamCopy($result,$tmp); fclose($result); OC_Filesystem::file_put_contents($path,$tmp); fclose($tmp); } $result=fopen('crypt://'.$path,$meta['mode']); } return $result; } public function postGetMimeType($path,$mime){ if(self::isEncrypted($path)){ $mime=OCP\Files::getMimeType('crypt://'.$path,'w'); } return $mime; } public function postStat($path,$data){ if(self::isEncrypted($path)){ $cached=OC_FileCache_Cached::get($path,''); $data['size']=$cached['size']; } return $data; } public function postFileSize($path,$size){ if(self::isEncrypted($path)){ $cached=OC_FileCache_Cached::get($path,''); return $cached['size']; }else{ return $size; } } }