Mainly work on implementing new encryption system (+ keyfile handling) into proxy classs

This commit is contained in:
Sam Tuke 2012-07-25 18:28:56 +01:00
parent adf5c953dd
commit 9f51841c57
5 changed files with 73 additions and 42 deletions

View File

@ -5,18 +5,26 @@ OC::$CLASSPATH['OCA_Encryption\Hooks'] = 'apps/files_encryption/hooks/hooks.php'
OC::$CLASSPATH['OCA_Encryption\Util'] = 'apps/files_encryption/lib/util.php';
OC::$CLASSPATH['OCA_Encryption\Keymanager'] = 'apps/files_encryption/lib/keymanager.php';
OC::$CLASSPATH['OC_CryptStream'] = 'apps/files_encryption/lib/cryptstream.php';
OC::$CLASSPATH['OC_FileProxy_Encryption'] = 'apps/files_encryption/lib/proxy.php';
OC::$CLASSPATH['OCA_Encryption\Proxy'] = 'apps/files_encryption/lib/proxy.php';
//OC_FileProxy::register(new OC_FileProxy_Encryption());
OC_FileProxy::register(new OCA_Encryption\Proxy());
OCP\Util::connectHook('OC_User','post_login','OCA_Encryption\Hooks','login');
stream_wrapper_register('crypt','OC_CryptStream');
if( !isset($_SESSION['enckey']) and OCP\User::isLoggedIn() ){//force the user to re-loggin if the encryption key isn't unlocked (happens when a user is logged in before the encryption app is enabled)
if(
!isset( $_SESSION['enckey'] )
and OCP\User::isLoggedIn()
) {
// Force the user to re-log in if the encryption key isn't unlocked (happens when a user is logged in before the encryption app is enabled)
OCP\User::logout();
header("Location: ".OC::$WEBROOT.'/');
exit();
}
OCP\App::registerAdmin('files_encryption', 'settings');
OCP\App::registerAdmin('files_encryption', 'settings');

View File

@ -52,7 +52,6 @@ class Hooks {
return true;
}
}

View File

@ -27,6 +27,7 @@ namespace OCA_Encryption;
*/
class Keymanager {
# TODO: Try and get rid of username dependencies as these methods need to be used in a proxy class that doesn't have username access
/**
* @brief retrieve private key from a user
@ -36,9 +37,9 @@ class Keymanager {
*/
public static function getPrivateKey( $user ) {
$view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' . '/' );
$view = new \OC_FilesystemView( '/' . $user . '/' . 'files_encryption' );
return $view->file_get_contents( $user.'.private.key' );
return $view->file_get_contents( '/' . $user.'.private.key' );
}
/**
@ -96,15 +97,20 @@ class Keymanager {
/**
* @brief store file encryption key
*
* @param string user name of the file owner
* @param string file name
* @param string key
* @param string $userId name of the file owner
* @param string $path relative path of the file, including filename
* @param string $key
* @return bool true/false
*/
public static function setFileKey($user, $file, $key) {
$fileKeyStorage = \OCP\Config::getSystemValue('datadirectory').'/'.$user.'/files_encryption/keyfiles/';
$view = new \OC_FilesystemView($fileKeyStorage);
return $view->file_put_contents($file.'.key', $key);
public static function setFileKey( $userId, $path, $key ) {
\OC_FileProxy::$enabled = false;
$view = new \OC_FilesystemView( '/' . $userId . '/' . 'files_encryption' );
return $view->file_put_contents( '/' . $path . '.key', $key );
\OC_FileProxy::$enabled = true;
}

View File

@ -3,8 +3,9 @@
/**
* ownCloud
*
* @author Robin Appelman
* @copyright 2011 Robin Appelman icewind1991@gmail.com
* @author Sam Tuke, Robin Appelman
* @copyright 2012 Sam Tuke samtuke@owncloud.com, 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
@ -26,7 +27,9 @@
* transparent encryption
*/
class OC_FileProxy_Encryption extends OC_FileProxy {
namespace OCA_Encryption;
class Proxy extends \OC_FileProxy {
private static $blackList = null; //mimetypes blacklisted from encryption
@ -43,7 +46,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy {
if ( is_null( self::$enableEncryption ) ) {
self::$enableEncryption = ( OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' );
self::$enableEncryption = ( \OCP\Config::getAppValue( 'files_encryption', 'enable_encryption', 'true' ) == 'true' );
}
@ -55,11 +58,11 @@ class OC_FileProxy_Encryption extends OC_FileProxy {
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' ) );
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 ) ) {
if( Crypt::isEncryptedContent( $path ) ) {
return true;
@ -84,7 +87,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy {
private static function isEncrypted( $path ){
// Fetch all file metadata from DB
$metadata = OC_FileCache_Cached::get( $path, '' );
$metadata = \OC_FileCache_Cached::get( $path, '' );
// Return encryption status
return isset( $metadata['encrypted'] ) and ( bool )$metadata['encrypted'];
@ -95,13 +98,24 @@ class OC_FileProxy_Encryption extends OC_FileProxy {
if ( self::shouldEncrypt( $path ) ) {
if ( !is_resource( $data ) ) {//stream put contents should have been converter to fopen
if ( !is_resource( $data ) ) { //stream put contents should have been converter to fopen
// Set the filesize for userland, before encrypting
$size = strlen( $data );
$data = OCA_Encryption\Crypt::symmetricEncryptFileContent( $data, '', $cached['size'] );
// Encrypt plain data and fetch key
$encrypted = Crypt::symmetricEncryptFileContentKeyfile( $data, $_SESSION['enckey'] );
OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' );
// Replace plain content with encrypted content by reference
$data = $encrypted['encrypted'];
# TODO: check if file is in subdirectories, and if so, create those parent directories. Or else monitor creation of directories using hooks to ensure path will always exist (what about existing directories when encryption is enabled?)
// Save keyfile for newly encrypted file in parallel directory
Keymanager::setFileKey( \OCP\USER::getUser(), $path, $encrypted['key'] );
// Update the file cache with file info
\OC_FileCache::put( $path, array( 'encrypted'=>true, 'size' => $size ), '' );
}
}
@ -109,11 +123,11 @@ class OC_FileProxy_Encryption extends OC_FileProxy {
public function postFile_get_contents( $path, $data ) {
if ( self::isEncrypted( $path ) ) {
$cached = OC_FileCache_Cached::get( $path, '' );
if ( Crypt::isEncryptedContent( $data ) ) {
trigger_error('best');
$cached = \OC_FileCache_Cached::get( $path, '' );
$data = OCA_Encryption\Crypt::symmetricDecryptFileContent( $data, '' );
$data = Crypt::symmetricDecryptFileContent( $data, $_SESSION['enckey'] );
}
@ -121,21 +135,22 @@ class OC_FileProxy_Encryption extends OC_FileProxy {
}
public function postFopen($path,&$result){
if(!$result){
return $result;
}
$meta=stream_get_meta_data($result);
if(self::isEncrypted($path)){
if(Crypt::isEncryptedContent($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){
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);
\OCP\Util::writeLog('files_encryption','Decrypting '.$path.' before writing', \OCP\Util::DEBUG);
$tmp=fopen('php://temp');
OCP\Files::streamCopy($result,$tmp);
\OCP\Files::streamCopy($result,$tmp);
fclose($result);
OC_Filesystem::file_put_contents($path,$tmp);
\OC_Filesystem::file_put_contents($path,$tmp);
fclose($tmp);
}
$result=fopen('crypt://'.$path,$meta['mode']);
@ -144,23 +159,23 @@ class OC_FileProxy_Encryption extends OC_FileProxy {
}
public function postGetMimeType($path,$mime){
if(self::isEncrypted($path)){
$mime=OCP\Files::getMimeType('crypt://'.$path,'w');
if(Crypt::isEncryptedContent($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,'');
if(Crypt::isEncryptedContent($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,'');
if(Crypt::isEncryptedContent($path)){
$cached = \OC_FileCache_Cached::get($path,'');
return $cached['size'];
}else{
return $size;

View File

@ -184,15 +184,16 @@ class Util {
* if the key is left out, the default handeler will be used
*/
public function getLegacyKey( $passphrase ) {
//OC_FileProxy::$enabled = false;
// Disable proxies to prevent attempt to automatically decrypt key
OC_FileProxy::$enabled = false;
if (
$passphrase
and $key = $this->view->file_get_contents( '/encryption.key' )
) {
//OC_FileProxy::$enabled = true;
OC_FileProxy::$enabled = true;
if ( $this->legacyKey = $this->legacyDecrypt( $key, $passphrase ) ) {
@ -206,6 +207,8 @@ class Util {
} else {
OC_FileProxy::$enabled = true;
return false;
}