2012-08-14 22:06:56 +04:00
< ? php
2013-01-24 22:37:34 +04:00
2012-08-14 22:06:56 +04:00
/**
* ownCloud
*
2014-11-14 14:20:59 +03:00
* @ copyright ( C ) 2014 ownCloud , Inc .
*
* @ author Sam Tuke < samtuke @ owncloud . org >
* @ author Bjoern Schiessle < schiessle @ owncloud . com >
2012-08-14 22:06:56 +04:00
*
* 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 />.
*
*/
2014-12-03 12:57:16 +03:00
namespace OCA\Files_Encryption ;
2012-08-14 22:06:56 +04:00
/**
* Class for hook specific logic
*/
class Hooks {
2013-12-19 20:29:38 +04:00
// file for which we want to rename the keys after the rename operation was successful
private static $renamedFiles = array ();
2014-01-31 23:38:35 +04:00
// file for which we want to delete the keys after the delete operation was successful
private static $deleteFiles = array ();
2014-05-27 17:09:43 +04:00
// file for which we want to delete the keys after the delete operation was successful
2014-11-10 14:40:24 +03:00
private static $unmountedFiles = array ();
2013-12-19 20:29:38 +04:00
2012-08-14 22:06:56 +04:00
/**
2014-05-19 19:50:53 +04:00
* Startup encryption backend upon user login
2012-08-14 22:06:56 +04:00
* @ note This method should never be called for users using client side encryption
*/
2013-05-27 19:26:58 +04:00
public static function login ( $params ) {
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' ) === false ) {
return true ;
}
2013-06-21 12:37:51 +04:00
$l = new \OC_L10N ( 'files_encryption' );
2012-08-14 22:06:56 +04:00
2014-05-12 18:30:39 +04:00
$view = new \OC\Files\View ( '/' );
2013-05-27 19:26:58 +04:00
2013-05-31 13:55:40 +04:00
// ensure filesystem is loaded
2014-05-22 17:43:42 +04:00
if ( ! \OC\Files\Filesystem :: $loaded ) {
2013-05-31 13:55:40 +04:00
\OC_Util :: setupFS ( $params [ 'uid' ]);
}
2014-12-03 18:52:44 +03:00
$privateKey = Keymanager :: getPrivateKey ( $view , $params [ 'uid' ]);
2013-09-17 18:53:52 +04:00
// if no private key exists, check server configuration
2014-05-22 17:43:42 +04:00
if ( ! $privateKey ) {
2013-09-17 18:53:52 +04:00
//check if all requirements are met
2014-05-22 17:43:42 +04:00
if ( ! Helper :: checkRequirements () || ! Helper :: checkConfiguration ()) {
2013-09-17 18:53:52 +04:00
$error_msg = $l -> t ( " Missing requirements. " );
2014-12-04 14:01:11 +03:00
$hint = $l -> t ( 'Please make sure that OpenSSL together with the PHP extension is enabled and configured properly. For now, the encryption app has been disabled.' );
2013-09-17 18:53:52 +04:00
\OC_App :: disable ( 'files_encryption' );
\OCP\Util :: writeLog ( 'Encryption library' , $error_msg . ' ' . $hint , \OCP\Util :: ERROR );
\OCP\Template :: printErrorPage ( $error_msg , $hint );
}
2013-08-26 20:08:23 +04:00
}
2013-09-03 15:24:30 +04:00
$util = new Util ( $view , $params [ 'uid' ]);
2013-05-27 19:26:58 +04:00
// setup user, if user not ready force relogin
if ( Helper :: setupUser ( $util , $params [ 'password' ]) === false ) {
return false ;
}
2013-07-29 19:06:05 +04:00
$session = $util -> initEncryption ( $params );
2013-05-15 16:33:08 +04:00
2013-05-04 18:14:38 +04:00
// Check if first-run file migration has already been performed
2013-06-12 14:21:11 +04:00
$ready = false ;
2014-02-10 13:56:11 +04:00
$migrationStatus = $util -> getMigrationStatus ();
2014-05-19 17:08:02 +04:00
if ( $migrationStatus === Util :: MIGRATION_OPEN && $session !== false ) {
2013-06-12 14:21:11 +04:00
$ready = $util -> beginMigration ();
2014-02-10 13:56:11 +04:00
} elseif ( $migrationStatus === Util :: MIGRATION_IN_PROGRESS ) {
// refuse login as long as the initial encryption is running
2014-02-11 15:44:06 +04:00
sleep ( 5 );
\OCP\User :: logout ();
return false ;
2013-06-12 14:21:11 +04:00
}
2013-05-27 19:26:58 +04:00
2014-05-22 17:43:42 +04:00
$result = true ;
2013-05-04 18:14:38 +04:00
// If migration not yet done
2013-06-11 14:03:50 +04:00
if ( $ready ) {
2013-05-27 19:26:58 +04:00
2014-02-10 19:43:04 +04:00
// Encrypt existing user files
try {
2014-07-08 15:07:05 +04:00
$result = $util -> encryptAll ( '/' . $params [ 'uid' ] . '/' . 'files' );
2014-02-10 19:43:04 +04:00
} catch ( \Exception $ex ) {
\OCP\Util :: writeLog ( 'Encryption library' , 'Initial encryption failed! Error: ' . $ex -> getMessage (), \OCP\Util :: FATAL );
$result = false ;
}
if ( $result ) {
2013-05-27 19:26:58 +04:00
\OC_Log :: write (
2014-05-22 17:43:42 +04:00
'Encryption library' , 'Encryption of existing files belonging to "' . $params [ 'uid' ] . '" completed'
, \OC_Log :: INFO
);
2014-02-10 19:43:04 +04:00
// Register successful migration in DB
$util -> finishMigration ();
2014-05-22 17:43:42 +04:00
} else {
\OCP\Util :: writeLog ( 'Encryption library' , 'Initial encryption failed!' , \OCP\Util :: FATAL );
$util -> resetMigrationStatus ();
\OCP\User :: logout ();
2014-02-10 19:43:04 +04:00
}
2013-05-04 18:14:38 +04:00
}
2012-08-14 22:06:56 +04:00
2014-05-22 17:43:42 +04:00
return $result ;
2012-08-14 22:06:56 +04:00
}
2013-05-14 00:34:11 +04:00
2014-08-07 17:26:09 +04:00
/**
* remove keys from session during logout
*/
public static function logout () {
2014-12-03 18:52:44 +03:00
$session = new Session ( new \OC\Files\View ());
2014-08-07 17:26:09 +04:00
$session -> removeKeys ();
}
2013-05-27 19:26:58 +04:00
/**
2014-05-19 19:50:53 +04:00
* setup encryption backend upon user created
2013-05-27 19:26:58 +04:00
* @ note This method should never be called for users using client side encryption
*/
public static function postCreateUser ( $params ) {
2013-05-14 00:34:11 +04:00
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' )) {
2014-05-12 18:30:39 +04:00
$view = new \OC\Files\View ( '/' );
2013-10-29 18:08:12 +04:00
$util = new Util ( $view , $params [ 'uid' ]);
Helper :: setupUser ( $util , $params [ 'password' ]);
}
2013-05-27 19:26:58 +04:00
}
2013-05-14 00:34:11 +04:00
2013-05-27 19:26:58 +04:00
/**
2014-05-19 19:50:53 +04:00
* cleanup encryption backend upon user deleted
2013-05-27 19:26:58 +04:00
* @ note This method should never be called for users using client side encryption
*/
public static function postDeleteUser ( $params ) {
2013-05-14 00:49:27 +04:00
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' )) {
2014-11-14 19:30:38 +03:00
Keymanager :: deletePublicKey ( new \OC\Files\View (), $params [ 'uid' ]);
2013-10-29 18:08:12 +04:00
}
2013-05-27 19:26:58 +04:00
}
2013-05-14 00:49:27 +04:00
2013-06-06 15:32:02 +04:00
/**
2014-05-19 19:50:53 +04:00
* If the password can ' t be changed within ownCloud , than update the key password in advance .
2013-06-06 15:32:02 +04:00
*/
public static function preSetPassphrase ( $params ) {
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' )) {
if ( ! \OC_User :: canUserChangePassword ( $params [ 'uid' ]) ) {
self :: setPassphrase ( $params );
}
2013-06-06 15:32:02 +04:00
}
}
2013-05-27 19:26:58 +04:00
/**
2014-05-19 19:50:53 +04:00
* Change a user ' s encryption passphrase
2012-12-11 17:22:46 +04:00
* @ param array $params keys : uid , password
*/
2013-05-16 16:53:04 +04:00
public static function setPassphrase ( $params ) {
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' ) === false ) {
return true ;
}
2012-12-11 17:22:46 +04:00
// Only attempt to change passphrase if server-side encryption
2013-05-31 15:58:58 +04:00
// is in use (client-side encryption does not have access to
2012-12-11 17:22:46 +04:00
// the necessary keys)
2013-05-27 22:44:38 +04:00
if ( Crypt :: mode () === 'server' ) {
2013-04-30 01:37:08 +04:00
2014-05-12 18:30:39 +04:00
$view = new \OC\Files\View ( '/' );
2014-12-03 18:52:44 +03:00
$session = new Session ( $view );
2013-04-30 01:37:08 +04:00
2014-09-22 17:04:55 +04:00
// Get existing decrypted private key
$privateKey = $session -> getPrivateKey ();
2013-05-16 16:53:04 +04:00
2014-09-22 17:04:55 +04:00
if ( $params [ 'uid' ] === \OCP\User :: getUser () && $privateKey ) {
2013-05-16 16:53:04 +04:00
// Encrypt private key with new user pwd as passphrase
2014-07-21 15:02:28 +04:00
$encryptedPrivateKey = Crypt :: symmetricEncryptFileContent ( $privateKey , $params [ 'password' ], Helper :: getCipher ());
2013-05-16 16:53:04 +04:00
// Save private key
2014-07-21 15:02:28 +04:00
if ( $encryptedPrivateKey ) {
Keymanager :: setPrivateKey ( $encryptedPrivateKey , \OCP\User :: getUser ());
} else {
\OCP\Util :: writeLog ( 'files_encryption' , 'Could not update users encryption password' , \OCP\Util :: ERROR );
}
2013-05-16 16:53:04 +04:00
// NOTE: Session does not need to be updated as the
// private key has not changed, only the passphrase
// used to decrypt it has changed
2013-05-27 19:26:58 +04:00
2013-05-16 16:53:04 +04:00
} else { // admin changed the password for a different user, create new keys and reencrypt file keys
2013-05-27 19:26:58 +04:00
2013-05-16 16:53:04 +04:00
$user = $params [ 'uid' ];
2013-12-05 21:51:30 +04:00
$util = new Util ( $view , $user );
$recoveryPassword = isset ( $params [ 'recoveryPassword' ]) ? $params [ 'recoveryPassword' ] : null ;
2013-05-16 16:53:04 +04:00
2014-05-19 17:08:02 +04:00
// we generate new keys if...
// ...we have a recovery password and the user enabled the recovery key
// ...encryption was activated for the first time (no keys exists)
// ...the user doesn't have any files
2013-12-05 21:51:30 +04:00
if (( $util -> recoveryEnabledForUser () && $recoveryPassword )
2014-05-19 17:08:02 +04:00
|| ! $util -> userKeysExists ()
|| ! $view -> file_exists ( $user . '/files' )) {
2013-05-16 16:53:04 +04:00
2014-09-16 17:16:27 +04:00
// backup old keys
$util -> backupAllKeys ( 'recovery' );
2013-12-05 21:51:30 +04:00
$newUserPassword = $params [ 'password' ];
2013-05-16 16:53:04 +04:00
2013-12-05 21:51:30 +04:00
// make sure that the users home is mounted
\OC\Files\Filesystem :: initMountPoints ( $user );
2013-05-27 19:26:58 +04:00
2013-12-05 21:51:30 +04:00
$keypair = Crypt :: createKeypair ();
2013-05-16 16:53:04 +04:00
2013-12-05 21:51:30 +04:00
// Disable encryption proxy to prevent recursive calls
$proxyStatus = \OC_FileProxy :: $enabled ;
\OC_FileProxy :: $enabled = false ;
2013-05-16 16:53:04 +04:00
2013-12-05 21:51:30 +04:00
// Save public key
2014-11-14 19:30:38 +03:00
Keymanager :: setPublicKey ( $keypair [ 'publicKey' ], $user );
2013-05-16 16:53:04 +04:00
2014-07-21 15:02:28 +04:00
// Encrypt private key with new password
2014-12-03 18:52:44 +03:00
$encryptedKey = Crypt :: symmetricEncryptFileContent ( $keypair [ 'privateKey' ], $newUserPassword , Helper :: getCipher ());
2014-07-21 15:02:28 +04:00
if ( $encryptedKey ) {
Keymanager :: setPrivateKey ( $encryptedKey , $user );
if ( $recoveryPassword ) { // if recovery key is set we can re-encrypt the key files
$util = new Util ( $view , $user );
$util -> recoverUsersFiles ( $recoveryPassword );
}
} else {
\OCP\Util :: writeLog ( 'files_encryption' , 'Could not update users encryption password' , \OCP\Util :: ERROR );
2013-12-05 21:51:30 +04:00
}
2013-05-16 16:53:04 +04:00
2013-12-05 21:51:30 +04:00
\OC_FileProxy :: $enabled = $proxyStatus ;
}
2013-05-16 16:53:04 +04:00
}
2012-12-11 17:22:46 +04:00
}
}
2013-05-13 16:28:45 +04:00
2014-10-29 14:45:13 +03:00
/**
* after password reset we create a new key pair for the user
*
* @ param array $params
*/
public static function postPasswordReset ( $params ) {
$uid = $params [ 'uid' ];
$password = $params [ 'password' ];
$util = new Util ( new \OC\Files\View (), $uid );
$util -> replaceUserKeys ( $password );
}
2013-05-13 16:28:45 +04:00
/*
2014-05-19 19:50:53 +04:00
* check if files can be encrypted to every user .
2013-05-13 16:28:45 +04:00
*/
2013-05-20 23:46:28 +04:00
/**
2014-05-13 15:29:25 +04:00
* @ param array $params
2013-05-20 23:46:28 +04:00
*/
2013-05-13 16:28:45 +04:00
public static function preShared ( $params ) {
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' ) === false ) {
return true ;
}
2013-08-01 16:19:33 +04:00
$l = new \OC_L10N ( 'files_encryption' );
2013-05-13 16:28:45 +04:00
$users = array ();
2014-11-14 19:30:38 +03:00
$view = new \OC\Files\View ( '/' );
2013-05-13 16:28:45 +04:00
switch ( $params [ 'shareType' ]) {
case \OCP\Share :: SHARE_TYPE_USER :
$users [] = $params [ 'shareWith' ];
break ;
case \OCP\Share :: SHARE_TYPE_GROUP :
$users = \OC_Group :: usersInGroup ( $params [ 'shareWith' ]);
break ;
}
2013-08-01 15:04:55 +04:00
$notConfigured = array ();
2013-05-13 16:28:45 +04:00
foreach ( $users as $user ) {
2014-11-14 19:30:38 +03:00
if ( ! Keymanager :: publicKeyExists ( $view , $user )) {
2013-08-01 15:04:55 +04:00
$notConfigured [] = $user ;
2013-05-13 16:28:45 +04:00
}
}
2013-05-21 01:44:10 +04:00
2013-08-01 15:04:55 +04:00
if ( count ( $notConfigured ) > 0 ) {
$params [ 'run' ] = false ;
2013-08-01 16:19:33 +04:00
$params [ 'error' ] = $l -> t ( 'Following users are not set up for encryption:' ) . ' ' . join ( ', ' , $notConfigured );
2013-05-27 19:26:58 +04:00
}
2013-08-30 12:17:50 +04:00
2013-05-13 16:28:45 +04:00
}
2013-02-12 15:45:54 +04:00
/**
2014-07-16 15:30:58 +04:00
* update share keys if a file was shared
2013-01-14 23:07:28 +04:00
*/
2013-05-13 16:28:45 +04:00
public static function postShared ( $params ) {
2013-04-22 13:58:39 +04:00
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' ) === false ) {
return true ;
}
2013-05-13 16:28:45 +04:00
if ( $params [ 'itemType' ] === 'file' || $params [ 'itemType' ] === 'folder' ) {
2014-04-15 22:18:04 +04:00
$path = \OC\Files\Filesystem :: getPath ( $params [ 'fileSource' ]);
2013-05-07 19:16:16 +04:00
2014-11-10 14:40:24 +03:00
self :: updateKeyfiles ( $path );
2014-07-16 15:30:58 +04:00
}
}
2013-04-22 13:58:39 +04:00
2014-07-16 15:30:58 +04:00
/**
* update keyfiles and share keys recursively
*
* @ param string $path to the file / folder
*/
2014-11-10 14:40:24 +03:00
private static function updateKeyfiles ( $path ) {
2014-07-16 15:30:58 +04:00
$view = new \OC\Files\View ( '/' );
$userId = \OCP\User :: getUser ();
2014-12-03 18:52:44 +03:00
$session = new Session ( $view );
2014-07-16 15:30:58 +04:00
$util = new Util ( $view , $userId );
$sharingEnabled = \OCP\Share :: isEnabled ();
2013-05-30 03:38:11 +04:00
2014-07-16 15:30:58 +04:00
$mountManager = \OC\Files\Filesystem :: getMountManager ();
$mount = $mountManager -> find ( '/' . $userId . '/files' . $path );
$mountPoint = $mount -> getMountPoint ();
2013-04-22 13:58:39 +04:00
2014-07-16 15:30:58 +04:00
// if a folder was shared, get a list of all (sub-)folders
2014-11-10 14:40:24 +03:00
if ( $view -> is_dir ( '/' . $userId . '/files' . $path )) {
2014-07-16 15:30:58 +04:00
$allFiles = $util -> getAllFiles ( $path , $mountPoint );
} else {
$allFiles = array ( $path );
}
foreach ( $allFiles as $path ) {
$usersSharing = $util -> getSharingUsersArray ( $sharingEnabled , $path );
$util -> setSharedFileKeyfiles ( $session , $usersSharing , $path );
2013-02-20 23:18:00 +04:00
}
2013-01-14 23:07:28 +04:00
}
2013-05-27 19:26:58 +04:00
2013-01-14 23:07:28 +04:00
/**
2014-07-04 14:06:23 +04:00
* unshare file / folder from a user with whom you shared the file before
2013-01-14 23:07:28 +04:00
*/
2013-05-27 19:26:58 +04:00
public static function postUnshare ( $params ) {
2013-05-06 01:41:42 +04:00
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' ) === false ) {
return true ;
}
2013-05-27 19:26:58 +04:00
if ( $params [ 'itemType' ] === 'file' || $params [ 'itemType' ] === 'folder' ) {
2013-05-06 01:41:42 +04:00
2014-05-12 18:30:39 +04:00
$view = new \OC\Files\View ( '/' );
2014-12-04 21:51:04 +03:00
$userId = $params [ 'uidOwner' ];
$userView = new \OC\Files\View ( '/' . $userId . '/files' );
2013-05-27 19:26:58 +04:00
$util = new Util ( $view , $userId );
2014-12-04 21:51:04 +03:00
$path = $userView -> getPath ( $params [ 'fileSource' ]);
2013-05-07 19:16:16 +04:00
// for group shares get a list of the group members
2013-05-27 22:44:38 +04:00
if ( $params [ 'shareType' ] === \OCP\Share :: SHARE_TYPE_GROUP ) {
2013-05-07 19:16:16 +04:00
$userIds = \OC_Group :: usersInGroup ( $params [ 'shareWith' ]);
2013-05-13 17:45:30 +04:00
} else {
2014-12-04 21:51:04 +03:00
if ( $params [ 'shareType' ] === \OCP\Share :: SHARE_TYPE_LINK || $params [ 'shareType' ] === \OCP\Share :: SHARE_TYPE_REMOTE ) {
2013-05-27 19:26:58 +04:00
$userIds = array ( $util -> getPublicShareKeyId ());
} else {
$userIds = array ( $params [ 'shareWith' ]);
}
2013-05-07 19:16:16 +04:00
}
2014-05-28 19:18:41 +04:00
$mountManager = \OC\Files\Filesystem :: getMountManager ();
$mount = $mountManager -> find ( '/' . $userId . '/files' . $path );
$mountPoint = $mount -> getMountPoint ();
2013-05-29 21:11:39 +04:00
2013-05-30 03:38:11 +04:00
// if we unshare a folder we need a list of all (sub-)files
if ( $params [ 'itemType' ] === 'folder' ) {
2014-04-15 22:18:04 +04:00
$allFiles = $util -> getAllFiles ( $path , $mountPoint );
2013-05-07 19:16:16 +04:00
} else {
2013-05-27 19:26:58 +04:00
$allFiles = array ( $path );
2013-05-07 19:16:16 +04:00
}
2013-05-27 19:26:58 +04:00
foreach ( $allFiles as $path ) {
2013-05-07 19:16:16 +04:00
// check if the user still has access to the file, otherwise delete share key
2013-05-27 19:26:58 +04:00
$sharingUsers = $util -> getSharingUsersArray ( true , $path );
2013-05-07 19:16:16 +04:00
// Unshare every user who no longer has access to the file
2013-05-27 19:26:58 +04:00
$delUsers = array_diff ( $userIds , $sharingUsers );
2014-11-10 14:40:24 +03:00
$keyPath = Keymanager :: getKeyPath ( $view , $util , $path );
2014-07-04 14:06:23 +04:00
2013-05-20 23:24:39 +04:00
// delete share key
2014-11-10 14:40:24 +03:00
Keymanager :: delShareKey ( $view , $delUsers , $keyPath , $userId , $path );
2013-05-07 19:16:16 +04:00
}
}
}
2013-05-27 19:26:58 +04:00
2013-12-19 20:29:38 +04:00
/**
2014-05-19 19:50:53 +04:00
* mark file as renamed so that we know the original source after the file was renamed
2013-12-19 21:40:40 +04:00
* @ param array $params with the old path and the new path
2013-12-19 20:29:38 +04:00
*/
public static function preRename ( $params ) {
2014-10-29 14:22:50 +03:00
self :: preRenameOrCopy ( $params , 'rename' );
2013-12-19 20:29:38 +04:00
}
2013-01-14 23:07:28 +04:00
/**
2014-10-29 14:22:50 +03:00
* mark file as copied so that we know the original source after the file was copied
2014-07-24 17:30:00 +04:00
* @ param array $params with the old path and the new path
*/
public static function preCopy ( $params ) {
2014-10-29 14:22:50 +03:00
self :: preRenameOrCopy ( $params , 'copy' );
}
private static function preRenameOrCopy ( $params , $operation ) {
2014-07-24 17:30:00 +04:00
$user = \OCP\User :: getUser ();
$view = new \OC\Files\View ( '/' );
$util = new Util ( $view , $user );
// we only need to rename the keys if the rename happens on the same mountpoint
// otherwise we perform a stream copy, so we get a new set of keys
$mp1 = $view -> getMountPoint ( '/' . $user . '/files/' . $params [ 'oldpath' ]);
$mp2 = $view -> getMountPoint ( '/' . $user . '/files/' . $params [ 'newpath' ]);
2014-11-28 19:53:21 +03:00
$oldKeysPath = Keymanager :: getKeyPath ( $view , $util , $params [ 'oldpath' ]);
2014-11-10 14:40:24 +03:00
2014-11-28 19:53:21 +03:00
if ( $mp1 === $mp2 ) {
2014-07-24 17:30:00 +04:00
self :: $renamedFiles [ $params [ 'oldpath' ]] = array (
2014-10-29 14:22:50 +03:00
'operation' => $operation ,
2014-11-10 14:40:24 +03:00
'oldKeysPath' => $oldKeysPath ,
2014-10-29 14:22:50 +03:00
);
2014-11-28 19:53:21 +03:00
} else {
self :: $renamedFiles [ $params [ 'oldpath' ]] = array (
'operation' => 'cleanup' ,
'oldKeysPath' => $oldKeysPath ,
);
2014-07-24 17:30:00 +04:00
}
}
/**
* after a file is renamed / copied , rename / copy its keyfile and share - keys also fix the file size and fix also the sharing
2013-05-27 19:26:58 +04:00
*
2014-07-24 17:30:00 +04:00
* @ param array $params array with oldpath and newpath
2013-05-27 19:26:58 +04:00
*/
2014-07-24 17:30:00 +04:00
public static function postRenameOrCopy ( $params ) {
2013-10-29 18:08:12 +04:00
if ( \OCP\App :: isEnabled ( 'files_encryption' ) === false ) {
return true ;
}
2014-05-12 18:30:39 +04:00
$view = new \OC\Files\View ( '/' );
2013-05-27 19:26:58 +04:00
$userId = \OCP\User :: getUser ();
$util = new Util ( $view , $userId );
2014-11-10 14:40:24 +03:00
if ( isset ( self :: $renamedFiles [ $params [ 'oldpath' ]][ 'operation' ]) &&
isset ( self :: $renamedFiles [ $params [ 'oldpath' ]][ 'oldKeysPath' ])) {
2014-07-24 17:30:00 +04:00
$operation = self :: $renamedFiles [ $params [ 'oldpath' ]][ 'operation' ];
2014-11-10 14:40:24 +03:00
$oldKeysPath = self :: $renamedFiles [ $params [ 'oldpath' ]][ 'oldKeysPath' ];
2014-07-16 15:30:58 +04:00
unset ( self :: $renamedFiles [ $params [ 'oldpath' ]]);
2014-11-28 19:53:21 +03:00
if ( $operation === 'cleanup' ) {
return $view -> unlink ( $oldKeysPath );
}
2013-12-19 21:40:40 +04:00
} else {
2014-07-02 19:53:54 +04:00
\OCP\Util :: writeLog ( 'Encryption library' , " can't get path and owner from the file before it was renamed " , \OCP\Util :: DEBUG );
2013-12-19 21:40:40 +04:00
return false ;
}
2013-12-19 20:29:38 +04:00
list ( $ownerNew , $pathNew ) = $util -> getUidAndFilename ( $params [ 'newpath' ]);
if ( $util -> isSystemWideMountPoint ( $pathNew )) {
2014-11-10 14:40:24 +03:00
$newKeysPath = 'files_encryption/keys/' . $pathNew ;
2013-05-27 19:26:58 +04:00
} else {
2014-11-10 14:40:24 +03:00
$newKeysPath = $ownerNew . '/files_encryption/keys/' . $pathNew ;
2013-05-27 19:26:58 +04:00
}
2014-11-10 14:40:24 +03:00
// create key folders if it doesn't exists
if ( ! $view -> file_exists ( dirname ( $newKeysPath ))) {
2014-12-02 18:08:06 +03:00
$view -> mkdir ( dirname ( $newKeysPath ));
2013-05-27 19:26:58 +04:00
}
2014-11-10 14:40:24 +03:00
$view -> $operation ( $oldKeysPath , $newKeysPath );
2013-05-27 19:26:58 +04:00
2014-06-23 18:14:52 +04:00
// update sharing-keys
2014-11-10 14:40:24 +03:00
self :: updateKeyfiles ( $params [ 'newpath' ]);
2013-05-27 19:26:58 +04:00
}
2013-06-27 16:09:22 +04:00
/**
2013-08-30 12:17:50 +04:00
* set migration status and the init status back to '0' so that all new files get encrypted
2013-06-27 16:09:22 +04:00
* if the app gets enabled again
* @ param array $params contains the app ID
*/
public static function preDisable ( $params ) {
if ( $params [ 'app' ] === 'files_encryption' ) {
2013-08-30 12:17:50 +04:00
2014-12-04 18:48:07 +03:00
\OC :: $server -> getConfig () -> deleteAppFromAllUsers ( 'files_encryption' );
2013-08-30 12:17:50 +04:00
2014-12-03 18:52:44 +03:00
$session = new Session ( new \OC\Files\View ( '/' ));
$session -> setInitialized ( Session :: NOT_INITIALIZED );
2013-06-27 16:09:22 +04:00
}
}
2013-10-22 18:15:24 +04:00
/**
* set the init status to 'NOT_INITIALIZED' ( 0 ) if the app gets enabled
* @ param array $params contains the app ID
*/
public static function postEnable ( $params ) {
if ( $params [ 'app' ] === 'files_encryption' ) {
2014-12-03 18:52:44 +03:00
$session = new Session ( new \OC\Files\View ( '/' ));
$session -> setInitialized ( Session :: NOT_INITIALIZED );
2013-10-22 18:15:24 +04:00
}
}
2014-01-31 23:38:35 +04:00
/**
2014-05-19 19:50:53 +04:00
* if the file was really deleted we remove the encryption keys
2014-01-31 23:38:35 +04:00
* @ param array $params
2014-02-06 19:30:58 +04:00
* @ return boolean | null
2014-01-31 23:38:35 +04:00
*/
public static function postDelete ( $params ) {
2014-11-10 14:40:24 +03:00
$path = $params [ \OC\Files\Filesystem :: signal_param_path ];
if ( ! isset ( self :: $deleteFiles [ $path ])) {
2014-01-31 23:38:35 +04:00
return true ;
}
2014-11-10 14:40:24 +03:00
$deletedFile = self :: $deleteFiles [ $path ];
$keyPath = $deletedFile [ 'keyPath' ];
2014-01-31 23:38:35 +04:00
// we don't need to remember the file any longer
2014-11-10 14:40:24 +03:00
unset ( self :: $deleteFiles [ $path ]);
2014-01-31 23:38:35 +04:00
$view = new \OC\Files\View ( '/' );
// return if the file still exists and wasn't deleted correctly
2014-11-10 14:40:24 +03:00
if ( $view -> file_exists ( '/' . \OCP\User :: getUser () . '/files/' . $path )) {
2014-01-31 23:38:35 +04:00
return true ;
}
// Delete keyfile & shareKey so it isn't orphaned
2014-11-10 14:40:24 +03:00
$view -> unlink ( $keyPath );
2014-01-31 23:38:35 +04:00
}
/**
2014-05-19 19:50:53 +04:00
* remember the file which should be deleted and it ' s owner
2014-01-31 23:38:35 +04:00
* @ param array $params
2014-02-06 19:30:58 +04:00
* @ return boolean | null
2014-01-31 23:38:35 +04:00
*/
public static function preDelete ( $params ) {
2014-11-10 14:40:24 +03:00
$view = new \OC\Files\View ( '/' );
2014-01-31 23:38:35 +04:00
$path = $params [ \OC\Files\Filesystem :: signal_param_path ];
// skip this method if the trash bin is enabled or if we delete a file
// outside of /data/user/files
if ( \OCP\App :: isEnabled ( 'files_trashbin' )) {
return true ;
}
2014-12-02 18:08:06 +03:00
$util = new Util ( $view , \OCP\USER :: getUser ());
2014-01-31 23:38:35 +04:00
2014-11-10 14:40:24 +03:00
$keysPath = Keymanager :: getKeyPath ( $view , $util , $path );
self :: $deleteFiles [ $path ] = array (
'keyPath' => $keysPath );
2014-01-31 23:38:35 +04:00
}
2014-05-27 17:09:43 +04:00
/**
2014-07-04 14:06:23 +04:00
* unmount file from yourself
2014-05-27 17:09:43 +04:00
* remember files / folders which get unmounted
*/
2014-11-10 14:40:24 +03:00
public static function preUnmount ( $params ) {
$view = new \OC\Files\View ( '/' );
$user = \OCP\User :: getUser ();
2014-05-27 17:09:43 +04:00
$path = $params [ \OC\Files\Filesystem :: signal_param_path ];
$util = new Util ( $view , $user );
list ( $owner , $ownerPath ) = $util -> getUidAndFilename ( $path );
2014-11-10 14:40:24 +03:00
$keysPath = Keymanager :: getKeyPath ( $view , $util , $path );
self :: $unmountedFiles [ $path ] = array (
'keyPath' => $keysPath ,
'owner' => $owner ,
'ownerPath' => $ownerPath
);
2014-05-27 17:09:43 +04:00
}
2014-07-04 14:06:23 +04:00
/**
* unmount file from yourself
*/
2014-11-10 14:40:24 +03:00
public static function postUnmount ( $params ) {
$path = $params [ \OC\Files\Filesystem :: signal_param_path ];
$user = \OCP\User :: getUser ();
2014-05-27 17:09:43 +04:00
2014-11-10 14:40:24 +03:00
if ( ! isset ( self :: $unmountedFiles [ $path ])) {
2014-05-27 17:09:43 +04:00
return true ;
}
2014-11-10 14:40:24 +03:00
$umountedFile = self :: $unmountedFiles [ $path ];
$keyPath = $umountedFile [ 'keyPath' ];
$owner = $umountedFile [ 'owner' ];
$ownerPath = $umountedFile [ 'ownerPath' ];
2014-05-27 17:09:43 +04:00
$view = new \OC\Files\View ();
// we don't need to remember the file any longer
2014-11-10 14:40:24 +03:00
unset ( self :: $unmountedFiles [ $path ]);
2014-05-27 17:09:43 +04:00
2014-11-10 14:40:24 +03:00
// check if the user still has access to the file, otherwise delete share key
$sharingUsers = \OCP\Share :: getUsersSharingFile ( $path , $user );
2014-12-04 21:51:04 +03:00
if ( ! in_array ( $user , $sharingUsers [ 'users' ])) {
Keymanager :: delShareKey ( $view , array ( $user ), $keyPath , $owner , $ownerPath );
2014-05-27 17:09:43 +04:00
}
}
2012-08-14 22:06:56 +04:00
}