Exemple #1
0
 public function stream_open($path, $mode, $options, &$opened_path)
 {
     if (!self::$rootView) {
         self::$rootView = new OC_FilesystemView('');
     }
     $path = str_replace('crypt://', '', $path);
     if (dirname($path) == 'streams' and isset(self::$sourceStreams[basename($path)])) {
         $this->source = self::$sourceStreams[basename($path)]['stream'];
         $this->path = self::$sourceStreams[basename($path)]['path'];
         $this->size = self::$sourceStreams[basename($path)]['size'];
     } else {
         $this->path = $path;
         if ($mode == 'w' or $mode == 'w+' or $mode == 'wb' or $mode == 'wb+') {
             $this->size = 0;
         } else {
             $this->size = self::$rootView->filesize($path, $mode);
         }
         OC_FileProxy::$enabled = false;
         //disable fileproxies so we can open the source file
         $this->source = self::$rootView->fopen($path, $mode);
         OC_FileProxy::$enabled = true;
         if (!is_resource($this->source)) {
             OCP\Util::writeLog('files_encryption', 'failed to open ' . $path, OCP\Util::ERROR);
         }
     }
     if (is_resource($this->source)) {
         $this->meta = stream_get_meta_data($this->source);
     }
     return is_resource($this->source);
 }
Exemple #2
0
 /**
  * if session is started, check if ownCloud key pair is set up, if not create it
  * @param \OC\Files\View $view
  *
  * @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled
  */
 public function __construct($view)
 {
     $this->view = $view;
     if (!$this->view->is_dir('files_encryption')) {
         $this->view->mkdir('files_encryption');
     }
     $appConfig = \OC::$server->getAppConfig();
     $publicShareKeyId = Helper::getPublicShareKeyId();
     if ($publicShareKeyId === false) {
         $publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
         $appConfig->setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId);
     }
     if (!Keymanager::publicShareKeyExists($view)) {
         $keypair = Crypt::createKeypair();
         // Save public key
         Keymanager::setPublicKey($keypair['publicKey'], $publicShareKeyId);
         // Encrypt private key empty passphrase
         $cipher = Helper::getCipher();
         $encryptedKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], '', $cipher);
         if ($encryptedKey) {
             Keymanager::setPrivateSystemKey($encryptedKey, $publicShareKeyId);
         } else {
             \OCP\Util::writeLog('files_encryption', 'Could not create public share keys', \OCP\Util::ERROR);
         }
     }
     if (Helper::isPublicAccess() && !self::getPublicSharePrivateKey()) {
         // Disable encryption proxy to prevent recursive calls
         $proxyStatus = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
         $encryptedKey = Keymanager::getPrivateSystemKey($publicShareKeyId);
         $privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
         self::setPublicSharePrivateKey($privateKey);
         \OC_FileProxy::$enabled = $proxyStatus;
     }
 }
Exemple #3
0
 protected function getDocumentHash($view, $path)
 {
     $this->validate($view, $path);
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $hash = sha1($view->file_get_contents($path));
     \OC_FileProxy::$enabled = $proxyStatus;
     return $hash;
 }
 public function testSimple()
 {
     $file = OC::$SERVERROOT . '/3rdparty/MDB2.php';
     $original = file_get_contents($file);
     OC_Filesystem::file_put_contents('/file', $original);
     OC_FileProxy::$enabled = false;
     $stored = OC_Filesystem::file_get_contents('/file');
     OC_FileProxy::$enabled = true;
     $fromFile = OC_Filesystem::file_get_contents('/file');
     $this->assertNotEqual($original, $stored);
     $this->assertEqual($original, $fromFile);
 }
 public static function createkey($username, $passcode)
 {
     // generate a random key
     $key = mt_rand(10000, 99999) . mt_rand(10000, 99999) . mt_rand(10000, 99999) . mt_rand(10000, 99999);
     // encrypt the key with the passcode of the user
     $enckey = OC_Crypt::encrypt($key, $passcode);
     // Write the file
     $proxyEnabled = OC_FileProxy::$enabled;
     OC_FileProxy::$enabled = false;
     $view = new OC_FilesystemView('/' . $username);
     $view->file_put_contents('/encryption.key', $enckey);
     OC_FileProxy::$enabled = $proxyEnabled;
 }
Exemple #6
0
 /**
  * write key to disk
  *
  *
  * @param string $path path to key directory
  * @param string $name key name
  * @param string $key key
  * @param \OC\Files\View $view
  * @return bool
  */
 private static function setKey($path, $name, $key, $view)
 {
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     self::keySetPreparation($view, $path);
     $pathToKey = \OC\Files\Filesystem::normalizePath($path . '/' . $name);
     $result = $view->file_put_contents($pathToKey, $key);
     \OC_FileProxy::$enabled = $proxyStatus;
     if (is_int($result) && $result > 0) {
         self::$key_cache[$pathToKey] = $key;
         return true;
     }
     return false;
 }
Exemple #7
0
 public function set($key, $value, $ttl = 0)
 {
     $storage = $this->getStorage();
     $result = false;
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     if ($storage and $storage->file_put_contents($key, $value)) {
         if ($ttl === 0) {
             $ttl = 86400;
             // 60*60*24
         }
         $result = $storage->touch($key, time() + $ttl);
     }
     \OC_FileProxy::$enabled = $proxyStatus;
     return $result;
 }
Exemple #8
0
 /**
  * if session is started, check if ownCloud key pair is set up, if not create it
  * @param \OC\Files\View $view
  *
  * @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled
  */
 public function __construct($view)
 {
     $this->view = $view;
     if (!$this->view->is_dir('owncloud_private_key')) {
         $this->view->mkdir('owncloud_private_key');
     }
     $appConfig = \OC::$server->getAppConfig();
     $publicShareKeyId = $appConfig->getValue('files_encryption', 'publicShareKeyId');
     if ($publicShareKeyId === null) {
         $publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
         $appConfig->setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId);
     }
     if (!$this->view->file_exists("/public-keys/" . $publicShareKeyId . ".public.key") || !$this->view->file_exists("/owncloud_private_key/" . $publicShareKeyId . ".private.key")) {
         $keypair = Crypt::createKeypair();
         // Disable encryption proxy to prevent recursive calls
         $proxyStatus = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
         // Save public key
         if (!$view->is_dir('/public-keys')) {
             $view->mkdir('/public-keys');
         }
         $this->view->file_put_contents('/public-keys/' . $publicShareKeyId . '.public.key', $keypair['publicKey']);
         // Encrypt private key empty passphrase
         $cipher = \OCA\Encryption\Helper::getCipher();
         $encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], '', $cipher);
         if ($encryptedKey) {
             Keymanager::setPrivateSystemKey($encryptedKey, $publicShareKeyId . '.private.key');
         } else {
             \OCP\Util::writeLog('files_encryption', 'Could not create public share keys', \OCP\Util::ERROR);
         }
         \OC_FileProxy::$enabled = $proxyStatus;
     }
     if (\OCA\Encryption\Helper::isPublicAccess()) {
         // Disable encryption proxy to prevent recursive calls
         $proxyStatus = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
         $encryptedKey = $this->view->file_get_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key');
         $privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
         $this->setPublicSharePrivateKey($privateKey);
         $this->setInitialized(\OCA\Encryption\Session::INIT_SUCCESSFUL);
         \OC_FileProxy::$enabled = $proxyStatus;
     }
 }
 public function stream_open($path, $mode, $options, &$opened_path)
 {
     $path = str_replace('crypt://', '', $path);
     if (dirname($path) == 'streams' and isset(self::$sourceStreams[basename($path)])) {
         $this->source = self::$sourceStreams[basename($path)]['stream'];
         $this->path = self::$sourceStreams[basename($path)]['path'];
     } else {
         $this->path = $path;
         OCP\Util::writeLog('files_encryption', 'open encrypted ' . $path . ' in ' . $mode, OCP\Util::DEBUG);
         OC_FileProxy::$enabled = false;
         //disable fileproxies so we can open the source file
         $this->source = OC_FileSystem::fopen($path, $mode);
         OC_FileProxy::$enabled = true;
         if (!is_resource($this->source)) {
             OCP\Util::writeLog('files_encryption', 'failed to open ' . $path, OCP\Util::ERROR);
         }
     }
     if (is_resource($this->source)) {
         $this->meta = stream_get_meta_data($this->source);
     }
     return is_resource($this->source);
 }
Exemple #10
0
 /**
  * @brief if session is started, check if ownCloud key pair is set up, if not create it
  * @param \OC_FilesystemView $view
  *
  * @note The ownCloud key pair is used to allow public link sharing even if encryption is enabled
  */
 public function __construct($view)
 {
     $this->view = $view;
     if (!$this->view->is_dir('owncloud_private_key')) {
         $this->view->mkdir('owncloud_private_key');
     }
     $publicShareKeyId = \OC_Appconfig::getValue('files_encryption', 'publicShareKeyId');
     if ($publicShareKeyId === null) {
         $publicShareKeyId = 'pubShare_' . substr(md5(time()), 0, 8);
         \OC_Appconfig::setValue('files_encryption', 'publicShareKeyId', $publicShareKeyId);
     }
     if (!$this->view->file_exists("/public-keys/" . $publicShareKeyId . ".public.key") || !$this->view->file_exists("/owncloud_private_key/" . $publicShareKeyId . ".private.key")) {
         $keypair = Crypt::createKeypair();
         // Disable encryption proxy to prevent recursive calls
         $proxyStatus = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
         // Save public key
         if (!$view->is_dir('/public-keys')) {
             $view->mkdir('/public-keys');
         }
         $this->view->file_put_contents('/public-keys/' . $publicShareKeyId . '.public.key', $keypair['publicKey']);
         // Encrypt private key empty passphrase
         $encryptedPrivateKey = Crypt::symmetricEncryptFileContent($keypair['privateKey'], '');
         // Save private key
         $this->view->file_put_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key', $encryptedPrivateKey);
         \OC_FileProxy::$enabled = $proxyStatus;
     }
     if (\OCA\Encryption\Helper::isPublicAccess()) {
         // Disable encryption proxy to prevent recursive calls
         $proxyStatus = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
         $encryptedKey = $this->view->file_get_contents('/owncloud_private_key/' . $publicShareKeyId . '.private.key');
         $privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
         $this->setPublicSharePrivateKey($privateKey);
         \OC_FileProxy::$enabled = $proxyStatus;
     }
 }
Exemple #11
0
 /**
  * @medium
  * Test that data that is written by the crypto stream wrapper with AES 128
  * @note Encrypted data is manually prepared and decrypted here to avoid dependency on success of stream_read
  * @note If this test fails with truncate content, check that enough array slices are being rejoined to form $e, as the crypt.php file may have gotten longer and broken the manual
  * reassembly of its data
  */
 public function testStreamDecryptLongFileContentWithoutHeader()
 {
     // Generate a a random filename
     $filename = 'tmp-' . $this->getUniqueID() . '.test';
     \OCP\Config::setSystemValue('cipher', 'AES-128-CFB');
     // Save long data as encrypted file using stream wrapper
     $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataLong . $this->dataLong);
     \OCP\Config::deleteSystemValue('cipher');
     // Test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // Get file contents without using any wrapper to get it's actual contents on disk
     $retreivedCryptedFile = $this->view->file_get_contents($this->userId . '/files/' . $filename);
     // Check that the file was encrypted before being written to disk
     $this->assertNotEquals($this->dataLong . $this->dataLong, $retreivedCryptedFile);
     // remove the header to check if we can also decrypt old files without a header,
     //  this files should fall back to AES-128
     $cryptedWithoutHeader = substr($retreivedCryptedFile, Encryption\Crypt::BLOCKSIZE);
     $this->view->file_put_contents($this->userId . '/files/' . $filename, $cryptedWithoutHeader);
     // Re-enable proxy - our work is done
     \OC_FileProxy::$enabled = $proxyStatus;
     $decrypted = file_get_contents('crypt:///' . $this->userId . '/files/' . $filename);
     $this->assertEquals($this->dataLong . $this->dataLong, $decrypted);
     // Teardown
     $this->view->unlink($this->userId . '/files/' . $filename);
     Encryption\Keymanager::deleteFileKey($this->view, $filename);
 }
 /**
  * @medium
  */
 function testSetFileKey()
 {
     $key = $this->randomKey;
     $file = 'unittest-' . $this->getUniqueID() . '.txt';
     $util = new Encryption\Util($this->view, $this->userId);
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $this->view->file_put_contents($this->userId . '/files/' . $file, $this->dataShort);
     Encryption\Keymanager::setFileKey($this->view, $util, $file, $key);
     $this->assertTrue($this->view->file_exists('/' . $this->userId . '/files_encryption/keyfiles/' . $file . '.key'));
     // cleanup
     $this->view->unlink('/' . $this->userId . '/files/' . $file);
     // change encryption proxy to previous state
     \OC_FileProxy::$enabled = $proxyStatus;
 }
Exemple #13
0
 /**
  * restore encryption keys from trash bin
  *
  * @param \OC\Files\View $view
  * @param string $file complete path to file
  * @param string $filename name of file
  * @param string $uniqueFilename new file name to restore the file without overwriting existing files
  * @param string $location location of file
  * @param int $timestamp deleteion time
  *
  */
 private static function restoreEncryptionKeys($view, $file, $filename, $uniqueFilename, $location, $timestamp)
 {
     // Take care of encryption keys TODO! Get '.key' in file between file name and delete date (also for permanent delete!)
     if (\OCP\App::isEnabled('files_encryption')) {
         $user = \OCP\User::getUser();
         $rootView = new \OC\Files\View('/');
         $target = \OC\Files\Filesystem::normalizePath('/' . $location . '/' . $uniqueFilename);
         list($owner, $ownerPath) = self::getUidAndFilename($target);
         $util = new \OCA\Encryption\Util(new \OC\Files\View('/'), $user);
         if ($util->isSystemWideMountPoint($ownerPath)) {
             $baseDir = '/files_encryption/';
         } else {
             $baseDir = $owner . '/files_encryption/';
         }
         $path_parts = pathinfo($file);
         $source_location = $path_parts['dirname'];
         if ($view->is_dir('/files_trashbin/keyfiles/' . $file)) {
             if ($source_location != '.') {
                 $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename);
                 $sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename);
             } else {
                 $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $filename);
                 $sharekey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $filename);
             }
         } else {
             $keyfile = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/keyfiles/' . $source_location . '/' . $filename . '.key');
         }
         if ($timestamp) {
             $keyfile .= '.d' . $timestamp;
         }
         // disable proxy to prevent recursive calls
         $proxyStatus = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
         if ($rootView->file_exists($keyfile)) {
             // handle directory
             if ($rootView->is_dir($keyfile)) {
                 // handle keyfiles
                 $rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath);
                 // handle share-keys
                 if ($timestamp) {
                     $sharekey .= '.d' . $timestamp;
                 }
                 $rootView->rename($sharekey, $baseDir . '/share-keys/' . $ownerPath);
             } else {
                 // handle keyfiles
                 $rootView->rename($keyfile, $baseDir . '/keyfiles/' . $ownerPath . '.key');
                 // handle share-keys
                 $ownerShareKey = \OC\Files\Filesystem::normalizePath($user . '/files_trashbin/share-keys/' . $source_location . '/' . $filename . '.' . $user . '.shareKey');
                 if ($timestamp) {
                     $ownerShareKey .= '.d' . $timestamp;
                 }
                 // move only owners key
                 $rootView->rename($ownerShareKey, $baseDir . '/share-keys/' . $ownerPath . '.' . $user . '.shareKey');
                 // try to re-share if file is shared
                 $filesystemView = new \OC\Files\View('/');
                 $session = new \OCA\Encryption\Session($filesystemView);
                 $util = new \OCA\Encryption\Util($filesystemView, $user);
                 // fix the file size
                 $absolutePath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files/' . $ownerPath);
                 $util->fixFileSize($absolutePath);
                 // get current sharing state
                 $sharingEnabled = \OCP\Share::isEnabled();
                 // get users sharing this file
                 $usersSharing = $util->getSharingUsersArray($sharingEnabled, $target);
                 // Attempt to set shareKey
                 $util->setSharedFileKeyfiles($session, $usersSharing, $target);
             }
         }
         // enable proxy
         \OC_FileProxy::$enabled = $proxyStatus;
     }
 }
Exemple #14
0
 /**
  * @param string $path
  * @param int $size
  * @return int|bool
  */
 public function postFileSize($path, $size, $fileInfo = null)
 {
     $view = new \OC\Files\View('/');
     $userId = Helper::getUser($path);
     $util = new Util($view, $userId);
     // if encryption is no longer enabled or if the files aren't migrated yet
     // we return the default file size
     if (!\OCP\App::isEnabled('files_encryption') || $util->getMigrationStatus() !== Util::MIGRATION_COMPLETED) {
         return $size;
     }
     // if path is a folder do nothing
     if ($view->is_dir($path)) {
         $proxyState = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
         $fileInfo = $view->getFileInfo($path);
         \OC_FileProxy::$enabled = $proxyState;
         if (isset($fileInfo['unencrypted_size']) && $fileInfo['unencrypted_size'] > 0) {
             return $fileInfo['unencrypted_size'];
         }
         return $size;
     }
     // get relative path
     $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
     // if path is empty we cannot resolve anything
     if (empty($relativePath)) {
         return $size;
     }
     // get file info from database/cache if not .part file
     if (empty($fileInfo) && !Helper::isPartialFilePath($path)) {
         $proxyState = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
         $fileInfo = $view->getFileInfo($path);
         \OC_FileProxy::$enabled = $proxyState;
     }
     // if file is encrypted return real file size
     if (isset($fileInfo['encrypted']) && $fileInfo['encrypted'] === true) {
         // try to fix unencrypted file size if it doesn't look plausible
         if ((int) $fileInfo['size'] > 0 && (int) $fileInfo['unencrypted_size'] === 0) {
             $fixSize = $util->getFileSize($path);
             $fileInfo['unencrypted_size'] = $fixSize;
             // put file info if not .part file
             if (!Helper::isPartialFilePath($relativePath)) {
                 $view->putFileInfo($path, array('unencrypted_size' => $fixSize));
             }
         }
         $size = $fileInfo['unencrypted_size'];
     } else {
         $fileInfoUpdates = array();
         $fixSize = $util->getFileSize($path);
         if ($fixSize > 0) {
             $size = $fixSize;
             $fileInfoUpdates['encrypted'] = true;
             $fileInfoUpdates['unencrypted_size'] = $size;
             // put file info if not .part file
             if (!Helper::isPartialFilePath($relativePath)) {
                 $view->putFileInfo($path, $fileInfoUpdates);
             }
         }
     }
     return $size;
 }
 /**
  * @NoAdminRequired
  */
 public function start()
 {
     $request = $this->request;
     $response = new JSONResponse();
     $params = $this->request->urlParams;
     $app = new App($this->api->getUserId());
     $addressBook = $app->getAddressBook($params['backend'], $params['addressBookId']);
     if (!$addressBook->hasPermission(\OCP\PERMISSION_CREATE)) {
         $response->setStatus('403');
         $response->bailOut(App::$l10n->t('You do not have permissions to import into this address book.'));
         return $response;
     }
     $filename = isset($request->post['filename']) ? $request->post['filename'] : null;
     $progresskey = isset($request->post['progresskey']) ? $request->post['progresskey'] : null;
     if (is_null($filename)) {
         $response->bailOut(App::$l10n->t('File name missing from request.'));
         return $response;
     }
     if (is_null($progresskey)) {
         $response->bailOut(App::$l10n->t('Progress key missing from request.'));
         return $response;
     }
     $filename = strtr($filename, array('/' => '', "\\" => ''));
     if (\OC\Files\Filesystem::isFileBlacklisted($filename)) {
         $response->bailOut(App::$l10n->t('Attempt to access blacklisted file:') . $filename);
         return $response;
     }
     $view = \OCP\Files::getStorage('contacts');
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $file = $view->file_get_contents('/imports/' . $filename);
     \OC_FileProxy::$enabled = $proxyStatus;
     $writeProgress = function ($pct) use($progresskey) {
         \OC_Cache::set($progresskey, $pct, 300);
     };
     $cleanup = function () use($view, $filename, $progresskey) {
         if (!$view->unlink('/imports/' . $filename)) {
             $response->debug('Unable to unlink /imports/' . $filename);
         }
         \OC_Cache::remove($progresskey);
     };
     $writeProgress('20');
     $nl = "\n";
     $file = str_replace(array("\r", "\n\n"), array("\n", "\n"), $file);
     $lines = explode($nl, $file);
     $inelement = false;
     $parts = array();
     $card = array();
     foreach ($lines as $line) {
         if (strtoupper(trim($line)) == 'BEGIN:VCARD') {
             $inelement = true;
         } elseif (strtoupper(trim($line)) == 'END:VCARD') {
             $card[] = $line;
             $parts[] = implode($nl, $card);
             $card = array();
             $inelement = false;
         }
         if ($inelement === true && trim($line) != '') {
             $card[] = $line;
         }
     }
     if (count($parts) === 0) {
         $response->bailOut(App::$l10n->t('No contacts found in: ') . $filename);
         $cleanup();
         return $response;
     }
     //import the contacts
     $imported = 0;
     $failed = 0;
     $partially = 0;
     $processed = 0;
     // TODO: Add a new group: "Imported at {date}"
     foreach ($parts as $part) {
         try {
             $vcard = VObject\Reader::read($part);
         } catch (VObject\ParseException $e) {
             try {
                 $vcard = VObject\Reader::read($part, VObject\Reader::OPTION_IGNORE_INVALID_LINES);
                 $partially += 1;
                 $response->debug('Import: Retrying reading card. Error parsing VCard: ' . $e->getMessage());
             } catch (\Exception $e) {
                 $failed += 1;
                 $response->debug('Import: skipping card. Error parsing VCard: ' . $e->getMessage());
                 continue;
                 // Ditch cards that can't be parsed by Sabre.
             }
         }
         try {
             $vcard->validate(MyVCard::REPAIR | MyVCard::UPGRADE);
         } catch (\Exception $e) {
             \OCP\Util::writeLog('contacts', __METHOD__ . ' ' . 'Error validating vcard: ' . $e->getMessage(), \OCP\Util::ERROR);
             $failed += 1;
         }
         /**
          * TODO
          * - Check if a contact with identical UID exists.
          * - If so, fetch that contact and call $contact->mergeFromVCard($vcard);
          * - Increment $updated var (not present yet.)
          * - continue
          */
         try {
             if ($addressBook->addChild($vcard)) {
                 $imported += 1;
             } else {
                 $failed += 1;
             }
         } catch (\Exception $e) {
             $response->debug('Error importing vcard: ' . $e->getMessage() . $nl . $vcard->serialize());
             $failed += 1;
         }
         $processed += 1;
         $writeProgress($processed);
     }
     //done the import
     sleep(3);
     // Give client side a chance to read the progress.
     $response->setParams(array('backend' => $params['backend'], 'addressBookId' => $params['addressBookId'], 'imported' => $imported, 'partially' => $partially, 'failed' => $failed));
     return $response;
 }
Exemple #16
0
 /**
  * rollback to an old version of a file.
  */
 public static function rollback($file, $revision)
 {
     if (\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED) == 'true') {
         list($uid, $filename) = self::getUidAndFilename($file);
         $users_view = new \OC\Files\View('/' . $uid);
         $files_view = new \OC\Files\View('/' . \OCP\User::getUser() . '/files');
         $versionCreated = false;
         //first create a new version
         $version = 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename);
         if (!$users_view->file_exists($version)) {
             // disable proxy to prevent multiple fopen calls
             $proxyStatus = \OC_FileProxy::$enabled;
             \OC_FileProxy::$enabled = false;
             $users_view->copy('files' . $filename, 'files_versions' . $filename . '.v' . $users_view->filemtime('files' . $filename));
             // reset proxy state
             \OC_FileProxy::$enabled = $proxyStatus;
             $versionCreated = true;
         }
         // rollback
         if (@$users_view->rename('files_versions' . $filename . '.v' . $revision, 'files' . $filename)) {
             $files_view->touch($file, $revision);
             Storage::expire($file);
             return true;
         } else {
             if ($versionCreated) {
                 $users_view->unlink($version);
             }
         }
     }
     return false;
 }
Exemple #17
0
 /**
  * @brief if the file was really deleted we remove the encryption keys
  * @param array $params
  * @return boolean
  */
 public static function postDelete($params)
 {
     if (!isset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]])) {
         return true;
     }
     $deletedFile = self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]];
     $path = $deletedFile['path'];
     $user = $deletedFile['uid'];
     // we don't need to remember the file any longer
     unset(self::$deleteFiles[$params[\OC\Files\Filesystem::signal_param_path]]);
     $view = new \OC\Files\View('/');
     // return if the file still exists and wasn't deleted correctly
     if ($view->file_exists('/' . $user . '/files/' . $path)) {
         return true;
     }
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // Delete keyfile & shareKey so it isn't orphaned
     if (!Keymanager::deleteFileKey($view, $path, $user)) {
         \OCP\Util::writeLog('Encryption library', 'Keyfile or shareKey could not be deleted for file "' . $user . '/files/' . $path . '"', \OCP\Util::ERROR);
     }
     Keymanager::delAllShareKeys($view, $user, $path);
     \OC_FileProxy::$enabled = $proxyStatus;
 }
Exemple #18
0
 /**
  * recover users files in case of password lost
  * @param string $recoveryPassword
  */
 public function recoverUsersFiles($recoveryPassword)
 {
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $encryptedKey = $this->view->file_get_contents('/owncloud_private_key/' . $this->recoveryKeyId . '.private.key');
     $privateKey = Crypt::decryptPrivateKey($encryptedKey, $recoveryPassword);
     \OC_FileProxy::$enabled = $proxyStatus;
     $this->recoverAllFiles('/', $privateKey);
 }
Exemple #19
0
 /**
  * @brief enable recovery
  *
  * @param $recoveryKeyId
  * @param $recoveryPassword
  * @internal param \OCA\Encryption\Util $util
  * @internal param string $password
  * @return bool
  */
 public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword)
 {
     $view = new \OC\Files\View('/');
     if ($recoveryKeyId === null) {
         $recoveryKeyId = 'recovery_' . substr(md5(time()), 0, 8);
         \OC_Appconfig::setValue('files_encryption', 'recoveryKeyId', $recoveryKeyId);
     }
     if (!$view->is_dir('/owncloud_private_key')) {
         $view->mkdir('/owncloud_private_key');
     }
     if (!$view->file_exists("/public-keys/" . $recoveryKeyId . ".public.key") || !$view->file_exists("/owncloud_private_key/" . $recoveryKeyId . ".private.key")) {
         $keypair = \OCA\Encryption\Crypt::createKeypair();
         \OC_FileProxy::$enabled = false;
         // Save public key
         if (!$view->is_dir('/public-keys')) {
             $view->mkdir('/public-keys');
         }
         $view->file_put_contents('/public-keys/' . $recoveryKeyId . '.public.key', $keypair['publicKey']);
         // Encrypt private key empty passphrase
         $encryptedPrivateKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($keypair['privateKey'], $recoveryPassword);
         // Save private key
         $view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey);
         \OC_FileProxy::$enabled = true;
         // Set recoveryAdmin as enabled
         \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1);
         $return = true;
     } else {
         // get recovery key and check the password
         $util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
         $return = $util->checkRecoveryPassword($recoveryPassword);
         if ($return) {
             \OC_Appconfig::setValue('files_encryption', 'recoveryAdminEnabled', 1);
         }
     }
     return $return;
 }
Exemple #20
0
 /**
  * @medium
  */
 function testGetUidAndFilename()
 {
     \OC_User::setUserId(self::TEST_ENCRYPTION_UTIL_USER1);
     $filename = '/tmp-' . $this->getUniqueID() . '.test';
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $this->view->file_put_contents($this->userId . '/files/' . $filename, $this->dataShort);
     // Re-enable proxy - our work is done
     \OC_FileProxy::$enabled = $proxyStatus;
     $util = new \OCA\Files_Encryption\Util($this->view, $this->userId);
     list($fileOwnerUid, $file) = $util->getUidAndFilename($filename);
     $this->assertEquals(self::TEST_ENCRYPTION_UTIL_USER1, $fileOwnerUid);
     $this->assertEquals($file, $filename);
     $this->view->unlink($this->userId . '/files/' . $filename);
 }
 /**
  * @NoAdminRequired
  */
 public function start()
 {
     $request = $this->request;
     $response = new JSONResponse();
     $params = $this->request->urlParams;
     $app = new App(\OCP\User::getUser());
     $addressBookId = $params['addressBookId'];
     $format = $params['importType'];
     $addressBook = $app->getAddressBook($params['backend'], $addressBookId);
     if (!$addressBook->hasPermission(\OCP\PERMISSION_CREATE)) {
         $response->setStatus('403');
         $response->bailOut(App::$l10n->t('You do not have permissions to import into this address book.'));
         return $response;
     }
     $filename = isset($request->post['filename']) ? $request->post['filename'] : null;
     $progresskey = isset($request->post['progresskey']) ? $request->post['progresskey'] : null;
     if (is_null($filename)) {
         $response->bailOut(App::$l10n->t('File name missing from request.'));
         return $response;
     }
     if (is_null($progresskey)) {
         $response->bailOut(App::$l10n->t('Progress key missing from request.'));
         return $response;
     }
     $filename = strtr($filename, array('/' => '', "\\" => ''));
     if (\OC\Files\Filesystem::isFileBlacklisted($filename)) {
         $response->bailOut(App::$l10n->t('Attempt to access blacklisted file:') . $filename);
         return $response;
     }
     $view = \OCP\Files::getStorage('contacts');
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $file = $view->file_get_contents('/imports/' . $filename);
     \OC_FileProxy::$enabled = $proxyStatus;
     $importManager = new ImportManager();
     $formatList = $importManager->getTypes();
     $found = false;
     $parts = array();
     foreach ($formatList as $formatName => $formatDisplayName) {
         if ($formatName == $format) {
             $parts = $importManager->importFile($view->getLocalFile('/imports/' . $filename), $formatName);
             $found = true;
         }
     }
     if (!$found) {
         // detect file type
         $mostLikelyName = "";
         $mostLikelyValue = 0;
         $probability = $importManager->detectFileType($view->getLocalFile('/imports/' . $filename));
         foreach ($probability as $probName => $probValue) {
             if ($probValue > $mostLikelyValue) {
                 $mostLikelyName = $probName;
                 $mostLikelyValue = $probValue;
             }
         }
         if ($mostLikelyValue > 0) {
             // found one (most likely...)
             $parts = $importManager->importFile($view->getLocalFile('/imports/' . $filename), $mostLikelyName);
         }
     }
     if ($parts) {
         //import the contacts
         $imported = 0;
         $failed = 0;
         $processed = 0;
         $total = count($parts);
         foreach ($parts as $part) {
             /**
              * TODO
              * - Check if a contact with identical UID exists.
              * - If so, fetch that contact and call $contact->mergeFromVCard($part);
              * - Increment $updated var (not present yet.)
              * - continue
              */
             try {
                 $id = $addressBook->addChild($part);
                 if ($id) {
                     $imported++;
                     $favourites = $part->select('X-FAVOURITES');
                     foreach ($favourites as $favourite) {
                         if ($favourite->getValue() == 'yes') {
                             $this->tagMgr->addToFavorites($id);
                         }
                     }
                 } else {
                     $failed++;
                 }
             } catch (\Exception $e) {
                 $response->debug('Error importing vcard: ' . $e->getMessage() . $nl . $part->serialize());
                 $failed++;
             }
             $processed++;
             $this->writeProcess($processed, $total, $progresskey);
         }
     } else {
         $imported = 0;
         $failed = 0;
         $processed = 0;
         $total = 0;
     }
     $this->cleanup($view, $filename, $progresskey, $response);
     //done the import
     sleep(3);
     // Give client side a chance to read the progress.
     $response->setParams(array('backend' => $params['backend'], 'addressBookId' => $params['addressBookId'], 'importType' => $params['importType'], 'imported' => $imported, 'count' => $processed, 'total' => $total, 'failed' => $failed));
     return $response;
 }
Exemple #22
0
 /**
  * Returns a view to ownCloud's files folder
  *
  * @param string $userId user ID
  * @return \OCP\Files\Folder
  */
 function getUserFolder($userId = null)
 {
     if ($userId === null) {
         $user = $this->getUserSession()->getUser();
         if (!$user) {
             return null;
         }
         $userId = $user->getUID();
     } else {
         $user = $this->getUserManager()->get($userId);
     }
     $dir = '/' . $userId;
     $root = $this->getRootFolder();
     $folder = null;
     if (!$root->nodeExists($dir)) {
         $folder = $root->newFolder($dir);
     } else {
         $folder = $root->get($dir);
     }
     $dir = '/files';
     if (!$folder->nodeExists($dir)) {
         $folder = $folder->newFolder($dir);
         if (\OCP\App::isEnabled('files_encryption')) {
             // disable encryption proxy to prevent recursive calls
             $proxyStatus = \OC_FileProxy::$enabled;
             \OC_FileProxy::$enabled = false;
         }
         \OC_Util::copySkeleton($user, $folder);
         if (\OCP\App::isEnabled('files_encryption')) {
             // re-enable proxy - our work is done
             \OC_FileProxy::$enabled = $proxyStatus;
         }
     } else {
         $folder = $folder->get($dir);
     }
     return $folder;
 }
Exemple #23
0
 /**
  * @param $path
  */
 public function handleFile($path)
 {
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $view = new \OC_FilesystemView('/');
     $session = new \OCA\Encryption\Session($view);
     $userId = Helper::getUser($path);
     $util = new Util($view, $userId);
     // split the path parts
     $pathParts = explode('/', $path);
     // get relative path
     $relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
     // only if file is on 'files' folder fix file size and sharing
     if (isset($pathParts[2]) && $pathParts[2] === 'files' && $util->fixFileSize($path)) {
         // get sharing app state
         $sharingEnabled = \OCP\Share::isEnabled();
         // get users
         $usersSharing = $util->getSharingUsersArray($sharingEnabled, $relativePath);
         // update sharing-keys
         $util->setSharedFileKeyfiles($session, $usersSharing, $relativePath);
     }
     \OC_FileProxy::$enabled = $proxyStatus;
 }
Exemple #24
0
 /**
  * Delete a single user's shareKey for a single file
  *
  * @param \OC\Files\View $view relative to data/
  * @param array $userIds list of users we want to remove
  * @param string $filename the owners name of the file for which we want to remove the users relative to data/user/files
  * @param string $owner owner of the file
  */
 public static function delShareKey($view, $userIds, $filename, $owner)
 {
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $util = new Util($view, $owner);
     if ($util->isSystemWideMountPoint($filename)) {
         $shareKeyPath = \OC\Files\Filesystem::normalizePath('/files_encryption/share-keys/' . $filename);
     } else {
         $shareKeyPath = \OC\Files\Filesystem::normalizePath('/' . $owner . '/files_encryption/share-keys/' . $filename);
     }
     if ($view->is_dir($shareKeyPath)) {
         self::recursiveDelShareKeys($shareKeyPath, $userIds, $owner, $view);
     } else {
         foreach ($userIds as $userId) {
             if ($userId === $owner && $view->file_exists('/' . $owner . '/files/' . $filename)) {
                 \OCP\Util::writeLog('files_encryption', 'Tried to delete owner key, but the file still exists!', \OCP\Util::FATAL);
                 continue;
             }
             $result = $view->unlink($shareKeyPath . '.' . $userId . '.shareKey');
             \OCP\Util::writeLog('files_encryption', 'delShareKey: delete share key: ' . $shareKeyPath . '.' . $userId . '.shareKey', \OCP\Util::DEBUG);
             if (!$result) {
                 \OCP\Util::writeLog('Encryption library', 'Could not delete shareKey; does not exist: "' . $shareKeyPath . '.' . $userId . '.shareKey"', \OCP\Util::ERROR);
             }
         }
     }
     \OC_FileProxy::$enabled = $proxyStatus;
 }
    $errorMessage = $l->t('Please repeat the new recovery password');
    \OCP\JSON::error(array('data' => array('message' => $errorMessage)));
    exit;
}
if ($_POST['newPassword'] !== $_POST['confirmPassword']) {
    $errorMessage = $l->t('Repeated recovery key password does not match the provided recovery key password');
    \OCP\JSON::error(array('data' => array('message' => $errorMessage)));
    exit;
}
$view = new \OC\Files\View('/');
$util = new \OCA\Files_Encryption\Util(new \OC\Files\View('/'), \OCP\User::getUser());
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$keyId = $util->getRecoveryKeyId();
$encryptedRecoveryKey = \OCA\Files_Encryption\Keymanager::getPrivateSystemKey($keyId);
$decryptedRecoveryKey = $encryptedRecoveryKey ? \OCA\Files_Encryption\Crypt::decryptPrivateKey($encryptedRecoveryKey, $oldPassword) : false;
if ($decryptedRecoveryKey) {
    $cipher = \OCA\Files_Encryption\Helper::getCipher();
    $encryptedKey = \OCA\Files_Encryption\Crypt::symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword, $cipher);
    if ($encryptedKey) {
        \OCA\Files_Encryption\Keymanager::setPrivateSystemKey($encryptedKey, $keyId);
        $return = true;
    }
}
\OC_FileProxy::$enabled = $proxyStatus;
// success or failure
if ($return) {
    \OCP\JSON::success(array('data' => array('message' => $l->t('Password successfully changed.'))));
} else {
    \OCP\JSON::error(array('data' => array('message' => $l->t('Could not change the password. Maybe the old password was not correct.'))));
}
Exemple #26
0
 /**
  * test webdav put random file
  */
 function testWebdavPUT()
 {
     // generate filename
     $filename = '/tmp-' . uniqid() . '.txt';
     // set server vars
     $_SERVER['REQUEST_METHOD'] = 'OPTIONS';
     $_SERVER['REQUEST_METHOD'] = 'PUT';
     $_SERVER['REQUEST_URI'] = '/remote.php/webdav' . $filename;
     $_SERVER['HTTP_AUTHORIZATION'] = 'Basic dGVzdC13ZWJkYXYtdXNlcjE6dGVzdC13ZWJkYXYtdXNlcjE=';
     $_SERVER['CONTENT_TYPE'] = 'application/octet-stream';
     $_SERVER['PATH_INFO'] = '/webdav' . $filename;
     $_SERVER['CONTENT_LENGTH'] = strlen($this->dataShort);
     // handle webdav request
     $this->handleWebdavRequest($this->dataShort);
     // check if file was created
     $this->assertTrue($this->view->file_exists('/' . $this->userId . '/files' . $filename));
     // check if key-file was created
     $this->assertTrue($this->view->file_exists('/' . $this->userId . '/files_encryption/keyfiles/' . $filename . '.key'));
     // check if shareKey-file was created
     $this->assertTrue($this->view->file_exists('/' . $this->userId . '/files_encryption/share-keys/' . $filename . '.' . $this->userId . '.shareKey'));
     // disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // get encrypted file content
     $encryptedContent = $this->view->file_get_contents('/' . $this->userId . '/files' . $filename);
     // restore proxy state
     \OC_FileProxy::$enabled = $proxyStatus;
     // check if encrypted content is valid
     $this->assertTrue(Encryption\Crypt::isCatfileContent($encryptedContent));
     // get decrypted file contents
     $decrypt = file_get_contents('crypt:///' . $this->userId . '/files' . $filename);
     // check if file content match with the written content
     $this->assertEquals($this->dataShort, $decrypt);
     // return filename for next test
     return $filename;
 }
Exemple #27
0
 /**
  * @medium
  * @brief Test that data that is read by the crypto stream wrapper
  */
 function testSymmetricStreamDecryptShortFileContent()
 {
     $filename = 'tmp-' . uniqid();
     // Save long data as encrypted file using stream wrapper
     $cryptedFile = file_put_contents('crypt:///' . $this->userId . '/files/' . $filename, $this->dataShort);
     // Test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // Disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $this->assertTrue(Encryption\Crypt::isEncryptedMeta($filename));
     \OC_FileProxy::$enabled = $proxyStatus;
     // Get file decrypted contents
     $decrypt = file_get_contents('crypt:///' . $this->userId . '/files/' . $filename);
     $this->assertEquals($this->dataShort, $decrypt);
     // tear down
     $this->view->unlink($this->userId . '/files/' . $filename);
 }
Exemple #28
0
 /**
  * @medium
  */
 function testFailShareFile()
 {
     // login as admin
     \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
     // save file with content
     $cryptedFile = file_put_contents('crypt:///' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename, $this->dataShort);
     // test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // get the file info from previous created file
     $fileInfo = $this->view->getFileInfo('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/' . $this->filename);
     // check if we have a valid file info
     $this->assertTrue(is_array($fileInfo));
     // check if the unencrypted file size is stored
     $this->assertGreaterThan(0, $fileInfo['unencrypted_size']);
     // break users public key
     $this->view->rename('/public-keys/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.public.key', '/public-keys/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.public.key_backup');
     // re-enable the file proxy
     \OC_FileProxy::$enabled = $proxyStatus;
     // share the file
     try {
         \OCP\Share::shareItem('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1, OCP\PERMISSION_ALL);
     } catch (Exception $e) {
         $this->assertEquals(0, strpos($e->getMessage(), "Following users are not set up for encryption"));
     }
     // login as admin
     \Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
     // check if share key for user1 not exists
     $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
     // disable encryption proxy to prevent recursive calls
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // break user1 public key
     $this->view->rename('/public-keys/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.public.key_backup', '/public-keys/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.public.key');
     // remove share file
     $this->view->unlink('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey');
     // re-enable the file proxy
     \OC_FileProxy::$enabled = $proxyStatus;
     // unshare the file with user1
     \OCP\Share::unshare('file', $fileInfo['fileid'], \OCP\Share::SHARE_TYPE_GROUP, \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_GROUP1);
     // check if share key not exists
     $this->assertFalse($this->view->file_exists('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files_encryption/share-keys/' . $this->filename . '.' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER3 . '.shareKey'));
     // cleanup
     $this->view->chroot('/' . \Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1 . '/files/');
     $this->view->unlink($this->filename);
     $this->view->chroot('/');
 }
Exemple #29
0
 /**
  * Encrypt keyfile to multiple users
  * @param Session $session
  * @param array $users list of users which should be able to access the file
  * @param string $filePath path of the file to be shared
  * @return bool
  */
 public function setSharedFileKeyfiles(Session $session, array $users, $filePath)
 {
     // Make sure users are capable of sharing
     $filteredUids = $this->filterShareReadyUsers($users);
     // If we're attempting to share to unready users
     if (!empty($filteredUids['unready'])) {
         \OCP\Util::writeLog('Encryption library', 'Sharing to these user(s) failed as they are unready for encryption:"' . print_r($filteredUids['unready'], 1), \OCP\Util::WARN);
         return false;
     }
     // Get public keys for each user, ready for generating sharekeys
     $userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']);
     // Note proxy status then disable it
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     // Get the current users's private key for decrypting existing keyfile
     $privateKey = $session->getPrivateKey();
     try {
         // Decrypt keyfile
         $plainKeyfile = $this->decryptKeyfile($filePath, $privateKey);
         // Re-enc keyfile to (additional) sharekeys
         $multiEncKey = Crypt::multiKeyEncrypt($plainKeyfile, $userPubKeys);
     } catch (Exception\EncryptionException $e) {
         $msg = 'set shareFileKeyFailed (code: ' . $e->getCode() . '): ' . $e->getMessage();
         \OCP\Util::writeLog('files_encryption', $msg, \OCP\Util::FATAL);
         return false;
     } catch (\Exception $e) {
         $msg = 'set shareFileKeyFailed (unknown error): ' . $e->getMessage();
         \OCP\Util::writeLog('files_encryption', $msg, \OCP\Util::FATAL);
         return false;
     }
     // Save the recrypted key to it's owner's keyfiles directory
     // Save new sharekeys to all necessary user directory
     if (!Keymanager::setFileKey($this->view, $this, $filePath, $multiEncKey['data']) || !Keymanager::setShareKeys($this->view, $this, $filePath, $multiEncKey['keys'])) {
         \OCP\Util::writeLog('Encryption library', 'Keyfiles could not be saved for users sharing ' . $filePath, \OCP\Util::ERROR);
         return false;
     }
     // Return proxy to original status
     \OC_FileProxy::$enabled = $proxyStatus;
     return true;
 }
Exemple #30
0
 /**
  * @medium
  * test if stream wrapper can read files outside from the data folder
  */
 function testStreamFromLocalFile()
 {
     $filename = '/' . $this->userId . '/files/' . 'tmp-' . $this->getUniqueID() . '.txt';
     $tmpFilename = "/tmp/" . $this->getUniqueID() . ".txt";
     // write an encrypted file
     $cryptedFile = $this->view->file_put_contents($filename, $this->dataShort);
     // Test that data was successfully written
     $this->assertTrue(is_int($cryptedFile));
     // create a copy outside of the data folder in /tmp
     $proxyStatus = \OC_FileProxy::$enabled;
     \OC_FileProxy::$enabled = false;
     $encryptedContent = $this->view->file_get_contents($filename);
     \OC_FileProxy::$enabled = $proxyStatus;
     file_put_contents($tmpFilename, $encryptedContent);
     \OCA\Files_Encryption\Helper::addTmpFileToMapper($tmpFilename, $filename);
     // try to read the file from /tmp
     $handle = fopen("crypt://" . $tmpFilename, "r");
     $contentFromTmpFile = stream_get_contents($handle);
     // check if it was successful
     $this->assertEquals($this->dataShort, $contentFromTmpFile);
     fclose($handle);
     // clean up
     unlink($tmpFilename);
     $this->view->unlink($filename);
 }