added check by numRows()

changed to public api where it was possible
reformat code to comply with the coding guidelines
This commit is contained in:
Florin Peter 2013-05-27 12:41:55 +02:00
parent 788c5940f0
commit 89f0c8f39d
1 changed files with 387 additions and 335 deletions

View File

@ -49,14 +49,13 @@ namespace OCA\Encryption;
/**
* @brief Class for utilities relating to encrypted file storage system
* @param OC_FilesystemView $view expected to have OC '/' as root path
* @param \OC_FilesystemView $view expected to have OC '/' as root path
* @param string $userId ID of the logged in user
* @param int $client indicating status of client side encryption. Currently
* unused, likely to become obsolete shortly
*/
class Util
{
class Util {
// Web UI:
@ -128,9 +127,8 @@ class Util
$this->recoveryKeyId = \OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
// if we are anonymous/public
if ( $this->userId === false ||
( isset( $_GET['service'] ) && $_GET['service'] == 'files' &&
isset( $_GET['t'] ) )
if ($this->userId === false
|| (isset($_GET['service']) && $_GET['service'] == 'files' && isset($_GET['t']))
) {
$this->userId = $this->publicShareKeyId;
@ -138,26 +136,32 @@ class Util
if ($GLOBALS['app'] === 'files_sharing') {
$this->userDir = '/' . $GLOBALS['fileOwner'];
$this->fileFolderName = 'files';
$this->userFilesDir = '/' . $GLOBALS['fileOwner'] . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
$this->userFilesDir = '/' . $GLOBALS['fileOwner'] . '/'
. $this->fileFolderName; // TODO: Does this need to be user configurable?
$this->publicKeyDir = '/' . 'public-keys';
$this->encryptionDir = '/' . $GLOBALS['fileOwner'] . '/' . 'files_encryption';
$this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
$this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
$this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
$this->privateKeyPath = '/owncloud_private_key/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
$this->publicKeyPath =
$this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
$this->privateKeyPath =
'/owncloud_private_key/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
$this->isPublic = true;
}
} else {
$this->userDir = '/' . $this->userId;
$this->fileFolderName = 'files';
$this->userFilesDir = '/' . $this->userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
$this->userFilesDir =
'/' . $this->userId . '/' . $this->fileFolderName; // TODO: Does this need to be user configurable?
$this->publicKeyDir = '/' . 'public-keys';
$this->encryptionDir = '/' . $this->userId . '/' . 'files_encryption';
$this->keyfilesPath = $this->encryptionDir . '/' . 'keyfiles';
$this->shareKeysPath = $this->encryptionDir . '/' . 'share-keys';
$this->publicKeyPath = $this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
$this->privateKeyPath = $this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
$this->publicKeyPath =
$this->publicKeyDir . '/' . $this->userId . '.public.key'; // e.g. data/public-keys/admin.public.key
$this->privateKeyPath =
$this->encryptionDir . '/' . $this->userId . '.private.key'; // e.g. data/admin/admin.private.key
}
}
@ -192,12 +196,12 @@ class Util
// Set directories to check / create
$setUpDirs = array(
$this->userDir
, $this->userFilesDir
, $this->publicKeyDir
, $this->encryptionDir
, $this->keyfilesPath
, $this->shareKeysPath
$this->userDir,
$this->userFilesDir,
$this->publicKeyDir,
$this->encryptionDir,
$this->keyfilesPath,
$this->shareKeysPath
);
// Check / create all necessary dirs
@ -237,20 +241,29 @@ class Util
} else {
// check if public-key exists but private-key is missing
if ($this->view->file_exists($this->publicKeyPath) && !$this->view->file_exists($this->privateKeyPath)) {
\OC_Log::write( 'Encryption library', 'public key exists but private key is missing for "' . $this->userId . '"', \OC_Log::FATAL );
\OCP\Util::writeLog('Encryption library',
'public key exists but private key is missing for "' . $this->userId . '"', \OCP\Util::FATAL);
return false;
} else if ( !$this->view->file_exists( $this->publicKeyPath ) && $this->view->file_exists( $this->privateKeyPath ) ) {
\OC_Log::write( 'Encryption library', 'private key exists but public key is missing for "' . $this->userId . '"', \OC_Log::FATAL );
} else {
if (!$this->view->file_exists($this->publicKeyPath) && $this->view->file_exists($this->privateKeyPath)
) {
\OCP\Util::writeLog('Encryption library',
'private key exists but public key is missing for "' . $this->userId . '"', \OCP\Util::FATAL);
return false;
}
}
}
// If there's no record for this user's encryption preferences
if (false === $this->recoveryEnabledForUser()) {
// create database configuration
$sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery_enabled`) VALUES (?,?,?)';
$args = array( $this->userId, 'server-side', 0 );
$args = array(
$this->userId,
'server-side',
0
);
$query = \OCP\DB::prepare($sql);
$query->execute($args);
@ -276,12 +289,7 @@ class Util
*/
public function recoveryEnabledForUser() {
$sql = 'SELECT
recovery_enabled
FROM
`*PREFIX*encryption`
WHERE
uid = ?';
$sql = 'SELECT `recovery_enabled` FROM `*PREFIX*encryption` WHERE uid = ?';
$args = array($this->userId);
@ -291,14 +299,16 @@ class Util
$recoveryEnabled = array();
if (\OC_DB::isError($result)) {
\OC_Log::write('Encryption library', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if($result->numRows() > 0) {
$row = $result->fetchRow();
if (isset($row['recovery_enabled'])) {
$recoveryEnabled[] = $row['recovery_enabled'];
}
}
}
// If no record is found
if (empty($recoveryEnabled)) {
@ -326,23 +336,23 @@ class Util
// If a record for this user already exists, update it
if (false === $recoveryStatus) {
$sql = 'INSERT INTO `*PREFIX*encryption`
(`uid`,`mode`,`recovery_enabled`)
VALUES (?,?,?)';
$sql = 'INSERT INTO `*PREFIX*encryption` (`uid`,`mode`,`recovery_enabled`) VALUES (?,?,?)';
$args = array( $this->userId, 'server-side', $enabled );
$args = array(
$this->userId,
'server-side',
$enabled
);
// Create a new record instead
} else {
$sql = 'UPDATE
*PREFIX*encryption
SET
recovery_enabled = ?
WHERE
uid = ?';
$sql = 'UPDATE `*PREFIX*encryption` SET recovery_enabled = ? WHERE uid = ?';
$args = array( $enabled, $this->userId );
$args = array(
$enabled,
$this->userId
);
}
@ -363,6 +373,7 @@ class Util
/**
* @brief Find all files and their encryption status within a directory
* @param string $directory The path of the parent directory to search
* @param bool $found the founded files if called again
* @return mixed false if 0 found, array on success. Keys: name, path
* @note $directory needs to be a path relative to OC data dir. e.g.
* /admin/files NOT /backup OR /home/www/oc/data/admin/files
@ -374,7 +385,11 @@ class Util
\OC_FileProxy::$enabled = false;
if ($found == false) {
$found = array( 'plain' => array(), 'encrypted' => array(), 'legacy' => array() );
$found = array(
'plain' => array(),
'encrypted' => array(),
'legacy' => array()
);
}
if (
@ -420,18 +435,27 @@ class Util
&& Crypt::isCatfileContent($data)
) {
$found['encrypted'][] = array( 'name' => $file, 'path' => $filePath );
$found['encrypted'][] = array(
'name' => $file,
'path' => $filePath
);
// If the file uses old
// encryption system
} elseif (Crypt::isLegacyEncryptedContent($this->tail($filePath, 3), $relPath)) {
$found['legacy'][] = array( 'name' => $file, 'path' => $filePath );
$found['legacy'][] = array(
'name' => $file,
'path' => $filePath
);
// If the file is not encrypted
} else {
$found['plain'][] = array( 'name' => $file, 'path' => $relPath );
$found['plain'][] = array(
'name' => $file,
'path' => $relPath
);
}
@ -584,8 +608,8 @@ class Util
/**
* @brief fix the file size of the encrypted file
* @param $path absolute path
* @return true / false if file is encrypted
* @param string $path absolute path
* @return boolean true / false if file is encrypted
*/
public function fixFileSize($path) {
@ -707,7 +731,11 @@ class Util
$this->view->unlink($rawPath . '.plaintmp');
// Add the file to the cache
\OC\Files\Filesystem::putFileInfo( $plainFile['path'], array( 'encrypted' => true, 'size' => $size, 'unencrypted_size' => $size ) );
\OC\Files\Filesystem::putFileInfo($plainFile['path'], array(
'encrypted' => true,
'size' => $size,
'unencrypted_size' => $size
));
}
// Encrypt legacy encrypted files
@ -751,7 +779,10 @@ class Util
$size = strlen($recrypted['data']);
// Add the file to the cache
\OC\Files\Filesystem::putFileInfo( $rawPath, array( 'encrypted' => true, 'size' => $size ), '' );
\OC\Files\Filesystem::putFileInfo($rawPath, array(
'encrypted' => true,
'size' => $size
), '');
}
}
@ -817,19 +848,21 @@ class Util
*/
public static function fileIdToPath($fileId) {
$query = \OC_DB::prepare( 'SELECT `path`'
. ' FROM `*PREFIX*filecache`'
. ' WHERE `fileid` = ?' );
$sql = 'SELECT `path` FROM `*PREFIX*filecache` WHERE `fileid` = ?';
$query = \OCP\DB::prepare($sql);
$result = $query->execute(array($fileId));
$path = false;
if (\OC_DB::isError($result)) {
\OC_Log::write('Encryption library', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if($result->numRows() > 0) {
$row = $result->fetchRow();
$path = substr($row['path'], strlen('files'));
}
}
return $path;
@ -838,7 +871,7 @@ class Util
/**
* @brief Filter an array of UIDs to return only ones ready for sharing
* @param array $unfilteredUsers users to be checked for sharing readiness
* @return multi-dimensional array. keys: ready, unready
* @return array as multi-dimensional array. keys: ready, unready
*/
public function filterShareReadyUsers($unfilteredUsers) {
@ -868,7 +901,8 @@ class Util
// Log warning; we can't do necessary setup here
// because we don't have the user passphrase
\OC_Log::write( 'Encryption library', '"' . $user . '" is not setup for encryption', \OC_Log::WARN );
\OCP\Util::writeLog('Encryption library',
'"' . $user . '" is not setup for encryption', \OCP\Util::WARN);
}
@ -938,7 +972,9 @@ class Util
// If we're attempting to share to unready users
if (!empty($filteredUids['unready'])) {
\OC_Log::write( 'Encryption library', 'Sharing to these user(s) failed as they are unready for encryption:"' . print_r( $filteredUids['unready'], 1 ), \OC_Log::WARN );
\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;
@ -969,7 +1005,8 @@ class Util
|| !Keymanager::setShareKeys($this->view, $filePath, $multiEncKey['keys'])
) {
\OC_Log::write( 'Encryption library', 'Keyfiles could not be saved for users sharing ' . $filePath, \OC_Log::ERROR );
\OCP\Util::writeLog('Encryption library',
'Keyfiles could not be saved for users sharing ' . $filePath, \OCP\Util::ERROR);
return false;
@ -1049,14 +1086,12 @@ class Util
*/
public function setMigrationStatus($status) {
$sql = 'UPDATE
*PREFIX*encryption
SET
migration_status = ?
WHERE
uid = ?';
$sql = 'UPDATE `*PREFIX*encryption` SET migration_status = ? WHERE uid = ?';
$args = array( $status, $this->userId );
$args = array(
$status,
$this->userId
);
$query = \OCP\DB::prepare($sql);
@ -1080,12 +1115,7 @@ class Util
*/
public function getMigrationStatus() {
$sql = 'SELECT
migration_status
FROM
`*PREFIX*encryption`
WHERE
uid = ?';
$sql = 'SELECT `migration_status` FROM `*PREFIX*encryption` WHERE uid = ?';
$args = array($this->userId);
@ -1095,14 +1125,16 @@ class Util
$migrationStatus = array();
if (\OC_DB::isError($result)) {
\OC_Log::write('Encryption library', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if($result->numRows() > 0) {
$row = $result->fetchRow();
if (isset($row['migration_status'])) {
$migrationStatus[] = $row['migration_status'];
}
}
}
// If no record is found
if (empty($migrationStatus)) {
@ -1135,12 +1167,16 @@ class Util
$filename = $path;
$fileOwnerUid = $GLOBALS['fileOwner'];
return array( $fileOwnerUid, $filename );
return array(
$fileOwnerUid,
$filename
);
} else {
// Check that UID is valid
if (!\OCP\User::userExists($fileOwnerUid)) {
throw new \Exception( 'Could not find owner (UID = "' . var_export( $fileOwnerUid, 1 ) . '") of file "' . $path . '"' );
throw new \Exception(
'Could not find owner (UID = "' . var_export($fileOwnerUid, 1) . '") of file "' . $path . '"');
}
// NOTE: Bah, this dependency should be elsewhere
@ -1162,7 +1198,10 @@ class Util
}
return array( $fileOwnerUid, $filename );
return array(
$fileOwnerUid,
$filename
);
}
@ -1228,18 +1267,20 @@ class Util
*/
public static function getShareParent($id) {
$query = \OC_DB::prepare( 'SELECT `file_target`, `item_type`'
. ' FROM `*PREFIX*share`'
. ' WHERE `id` = ?' );
$sql = 'SELECT `file_target`, `item_type` FROM `*PREFIX*share` WHERE `id` = ?';
$query = \OCP\DB::prepare($sql);
$result = $query->execute(array($id));
$row = array();
if (\OC_DB::isError($result)) {
\OC_Log::write('Encryption library', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if($result->numRows() > 0) {
$row = $result->fetchRow();
}
}
return $row;
@ -1252,18 +1293,20 @@ class Util
*/
public static function getParentFromShare($id) {
$query = \OC_DB::prepare( 'SELECT `parent`'
. ' FROM `*PREFIX*share`'
. ' WHERE `id` = ?' );
$sql = 'SELECT `parent` FROM `*PREFIX*share` WHERE `id` = ?';
$query = \OCP\DB::prepare($sql);
$result = $query->execute(array($id));
$row = array();
if (\OC_DB::isError($result)) {
\OC_Log::write('Encryption library', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if($result->numRows() > 0) {
$row = $result->fetchRow();
}
}
return $row;
@ -1277,16 +1320,18 @@ class Util
*/
public function getOwnerFromSharedFile($id) {
$query = \OC_DB::prepare( 'SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1 );
$query = \OCP\DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1);
$result = $query->execute(array($id));
$source = array();
if (\OC_DB::isError($result)) {
\OC_Log::write('Encryption library', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if($result->numRows() > 0) {
$source = $result->fetchRow();
}
}
$fileOwner = false;
@ -1296,16 +1341,18 @@ class Util
while (isset($parent)) {
$query = \OC_DB::prepare( 'SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1 );
$query = \OCP\DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1);
$result = $query->execute(array($parent));
$item = array();
if (\OC_DB::isError($result)) {
\OC_Log::write('Encryption library', \OC_DB::getErrorMessage($result), \OC_Log::ERROR);
if (\OCP\DB::isError($result)) {
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
} else {
if($result->numRows() > 0) {
$item = $result->fetchRow();
}
}
if (isset($item['parent'])) {
@ -1434,7 +1481,10 @@ class Util
$userIds[] = $this->publicShareKeyId;
}
} else {
$userIds = array( $this->userId, $this->recoveryKeyId );
$userIds = array(
$this->userId,
$this->recoveryKeyId
);
}
$filteredUids = $this->filterShareReadyUsers($userIds);
@ -1443,7 +1493,8 @@ class Util
//decrypt file key
$encKeyfile = $this->view->file_get_contents($this->keyfilesPath . $file . ".key");
$shareKey = $this->view->file_get_contents( $this->shareKeysPath . $file . "." . $this->recoveryKeyId . ".shareKey" );
$shareKey = $this->view->file_get_contents(
$this->shareKeysPath . $file . "." . $this->recoveryKeyId . ".shareKey");
$plainKeyfile = Crypt::multiKeyDecrypt($encKeyfile, $shareKey, $privateKey);
// encrypt file key again to all users, this time with the new public key for the recovered use
$userPubKeys = Keymanager::getPublicKeys($this->view, $filteredUids['ready']);
@ -1488,7 +1539,8 @@ class Util
$proxyStatus = \OC_FileProxy::$enabled;
\OC_FileProxy::$enabled = false;
$encryptedKey = $this->view->file_get_contents( '/owncloud_private_key/' . $this->recoveryKeyId . '.private.key' );
$encryptedKey = $this->view->file_get_contents(
'/owncloud_private_key/' . $this->recoveryKeyId . '.private.key');
$privateKey = Crypt::symmetricDecryptFileContent($encryptedKey, $recoveryPassword);
\OC_FileProxy::$enabled = $proxyStatus;