Merge pull request #3558 from owncloud/files_encryption_check_private_key
check if the decrypted private key is valid on login and on read/write files
This commit is contained in:
commit
4bafa4e81a
20 changed files with 461 additions and 159 deletions
|
@ -22,28 +22,28 @@ $return = false;
|
|||
$oldPassword = $_POST['oldPassword'];
|
||||
$newPassword = $_POST['newPassword'];
|
||||
|
||||
$view = new \OC\Files\View('/');
|
||||
$util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), \OCP\User::getUser());
|
||||
|
||||
$result = $util->checkRecoveryPassword($oldPassword);
|
||||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
if ($result) {
|
||||
$keyId = $util->getRecoveryKeyId();
|
||||
$keyPath = '/owncloud_private_key/' . $keyId . '.private.key';
|
||||
$view = new \OC\Files\View('/');
|
||||
$keyId = $util->getRecoveryKeyId();
|
||||
$keyPath = '/owncloud_private_key/' . $keyId . '.private.key';
|
||||
|
||||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
$encryptedRecoveryKey = $view->file_get_contents($keyPath);
|
||||
$decryptedRecoveryKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedRecoveryKey, $oldPassword);
|
||||
|
||||
if ($decryptedRecoveryKey) {
|
||||
|
||||
$encryptedRecoveryKey = $view->file_get_contents($keyPath);
|
||||
$decryptedRecoveryKey = \OCA\Encryption\Crypt::symmetricDecryptFileContent($encryptedRecoveryKey, $oldPassword);
|
||||
$encryptedRecoveryKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword);
|
||||
$view->file_put_contents($keyPath, $encryptedRecoveryKey);
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
|
||||
$return = true;
|
||||
}
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
|
||||
// success or failure
|
||||
if ($return) {
|
||||
\OCP\JSON::success(array('data' => array('message' => $l->t('Password successfully changed.'))));
|
||||
|
|
54
apps/files_encryption/ajax/updatePrivateKeyPassword.php
Normal file
54
apps/files_encryption/ajax/updatePrivateKeyPassword.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (c) 2013, Bjoern Schiessle <schiessle@owncloud.com>
|
||||
* This file is licensed under the Affero General Public License version 3 or later.
|
||||
* See the COPYING-README file.
|
||||
*
|
||||
* @brief Script to change recovery key password
|
||||
*
|
||||
*/
|
||||
|
||||
use OCA\Encryption;
|
||||
|
||||
\OCP\JSON::checkLoggedIn();
|
||||
\OCP\JSON::checkAppEnabled('files_encryption');
|
||||
\OCP\JSON::callCheck();
|
||||
|
||||
$l = OC_L10N::get('core');
|
||||
|
||||
$return = false;
|
||||
|
||||
$oldPassword = $_POST['oldPassword'];
|
||||
$newPassword = $_POST['newPassword'];
|
||||
|
||||
$view = new \OC\Files\View('/');
|
||||
$session = new \OCA\Encryption\Session($view);
|
||||
$user = \OCP\User::getUser();
|
||||
|
||||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
$keyPath = '/' . $user . '/files_encryption/' . $user . '.private.key';
|
||||
|
||||
$encryptedKey = $view->file_get_contents($keyPath);
|
||||
$decryptedKey = \OCA\Encryption\Crypt::decryptPrivateKey($encryptedKey, $oldPassword);
|
||||
|
||||
if ($decryptedKey) {
|
||||
|
||||
$encryptedKey = \OCA\Encryption\Crypt::symmetricEncryptFileContent($decryptedKey, $newPassword);
|
||||
$view->file_put_contents($keyPath, $encryptedKey);
|
||||
|
||||
$session->setPrivateKey($decryptedKey);
|
||||
|
||||
$return = true;
|
||||
}
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
|
||||
// success or failure
|
||||
if ($return) {
|
||||
\OCP\JSON::success(array('data' => array('message' => $l->t('Private key password successfully updated.'))));
|
||||
} else {
|
||||
\OCP\JSON::error(array('data' => array('message' => $l->t('Could not update the private key password. Maybe the old password was not correct.'))));
|
||||
}
|
|
@ -35,9 +35,10 @@ if (!OC_Config::getValue('maintenance', false)) {
|
|||
$view = new OC_FilesystemView('/');
|
||||
$session = new \OCA\Encryption\Session($view);
|
||||
|
||||
$user = \OCP\USER::getUser();
|
||||
// check if user has a private key
|
||||
if (
|
||||
!$session->getPrivateKey(\OCP\USER::getUser())
|
||||
!$view->file_exists('/' . $user . '/files_encryption/' . $user . '.private.key')
|
||||
&& OCA\Encryption\Crypt::mode() === 'server'
|
||||
) {
|
||||
|
||||
|
|
24
apps/files_encryption/files/error.php
Normal file
24
apps/files_encryption/files/error.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
if (!isset($_)) { //also provide standalone error page
|
||||
require_once '../../../lib/base.php';
|
||||
|
||||
$l = OC_L10N::get('files_encryption');
|
||||
|
||||
$errorMsg = $l->t('Your private key is not valid! Maybe your password was changed from outside. You can update your private key password in your personal settings to regain access to your files');
|
||||
|
||||
if(isset($_GET['p']) && $_GET['p'] === '1') {
|
||||
header('HTTP/1.0 404 ' . $errorMsg);
|
||||
}
|
||||
|
||||
// check if ajax request
|
||||
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
|
||||
\OCP\JSON::error(array('data' => array('message' => $errorMsg)));
|
||||
} else {
|
||||
header('HTTP/1.0 404 ' . $errorMsg);
|
||||
$tmpl = new OC_Template('files_encryption', 'invalid_private_key', 'guest');
|
||||
$tmpl->printPage();
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
?>
|
|
@ -60,11 +60,16 @@ class Hooks {
|
|||
|
||||
$encryptedKey = Keymanager::getPrivateKey($view, $params['uid']);
|
||||
|
||||
$privateKey = Crypt::symmetricDecryptFileContent($encryptedKey, $params['password']);
|
||||
$privateKey = Crypt::decryptPrivateKey($encryptedKey, $params['password']);
|
||||
|
||||
if ($privateKey === false) {
|
||||
\OCP\Util::writeLog('Encryption library', 'Private key for user "' . $params['uid']
|
||||
. '" is not valid! Maybe the user password was changed from outside if so please change it back to gain access', \OCP\Util::ERROR);
|
||||
}
|
||||
|
||||
$session = new \OCA\Encryption\Session($view);
|
||||
|
||||
$session->setPrivateKey($privateKey, $params['uid']);
|
||||
$session->setPrivateKey($privateKey);
|
||||
|
||||
// Check if first-run file migration has already been performed
|
||||
$ready = false;
|
||||
|
@ -160,7 +165,7 @@ class Hooks {
|
|||
public static function setPassphrase($params) {
|
||||
|
||||
// Only attempt to change passphrase if server-side encryption
|
||||
// is in use (client-side encryption does not have access to
|
||||
// is in use (client-side encryption does not have access to
|
||||
// the necessary keys)
|
||||
if (Crypt::mode() === 'server') {
|
||||
|
||||
|
@ -345,7 +350,7 @@ class Hooks {
|
|||
$sharingEnabled = \OCP\Share::isEnabled();
|
||||
|
||||
// get the path including mount point only if not a shared folder
|
||||
if(strncmp($path, '/Shared' , strlen('/Shared') !== 0)) {
|
||||
if (strncmp($path, '/Shared', strlen('/Shared') !== 0)) {
|
||||
// get path including the the storage mount point
|
||||
$path = $util->getPathWithMountPoint($params['itemSource']);
|
||||
}
|
||||
|
@ -422,14 +427,14 @@ class Hooks {
|
|||
}
|
||||
|
||||
// get the path including mount point only if not a shared folder
|
||||
if(strncmp($path, '/Shared' , strlen('/Shared') !== 0)) {
|
||||
if (strncmp($path, '/Shared', strlen('/Shared') !== 0)) {
|
||||
// get path including the the storage mount point
|
||||
$path = $util->getPathWithMountPoint($params['itemSource']);
|
||||
}
|
||||
|
||||
// if we unshare a folder we need a list of all (sub-)files
|
||||
if ($params['itemType'] === 'folder') {
|
||||
$allFiles = $util->getAllFiles( $path );
|
||||
$allFiles = $util->getAllFiles($path);
|
||||
} else {
|
||||
$allFiles = array($path);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,25 @@
|
|||
* See the COPYING-README file.
|
||||
*/
|
||||
|
||||
function updatePrivateKeyPasswd() {
|
||||
var oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val();
|
||||
var newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val();
|
||||
OC.msg.startSaving('#encryption .msg');
|
||||
$.post(
|
||||
OC.filePath( 'files_encryption', 'ajax', 'updatePrivateKeyPassword.php' )
|
||||
, { oldPassword: oldPrivateKeyPassword, newPassword: newPrivateKeyPassword }
|
||||
, function( data ) {
|
||||
if (data.status === "error") {
|
||||
OC.msg.finishedSaving('#encryption .msg', data);
|
||||
} else {
|
||||
OC.msg.finishedSaving('#encryption .msg', data);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
// Trigger ajax on recoveryAdmin status change
|
||||
$( 'input:radio[name="userEnableRecovery"]' ).change(
|
||||
function() {
|
||||
|
@ -57,4 +75,24 @@ $(document).ready(function(){
|
|||
}
|
||||
|
||||
);
|
||||
|
||||
// update private key password
|
||||
|
||||
$('input:password[name="changePrivateKeyPassword"]').keyup(function(event) {
|
||||
var oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val();
|
||||
var newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val();
|
||||
if (newPrivateKeyPassword !== '' && oldPrivateKeyPassword !== '' ) {
|
||||
$('button:button[name="submitChangePrivateKeyPassword"]').removeAttr("disabled");
|
||||
if(event.which === 13) {
|
||||
updatePrivateKeyPasswd();
|
||||
}
|
||||
} else {
|
||||
$('button:button[name="submitChangePrivateKeyPassword"]').attr("disabled", "true");
|
||||
}
|
||||
});
|
||||
|
||||
$('button:button[name="submitChangePrivateKeyPassword"]').click(function() {
|
||||
updatePrivateKeyPasswd();
|
||||
});
|
||||
|
||||
});
|
|
@ -351,6 +351,34 @@ class Crypt {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Decrypt private key and check if the result is a valid keyfile
|
||||
* @param string $encryptedKey encrypted keyfile
|
||||
* @param string $passphrase to decrypt keyfile
|
||||
* @returns encrypted private key or false
|
||||
*
|
||||
* This function decrypts a file
|
||||
*/
|
||||
public static function decryptPrivateKey($encryptedKey, $passphrase) {
|
||||
|
||||
$plainKey = self::symmetricDecryptFileContent($encryptedKey, $passphrase);
|
||||
|
||||
// check if this a valid private key
|
||||
$res = openssl_pkey_get_private($plainKey);
|
||||
if (is_resource($res)) {
|
||||
$sslInfo = openssl_pkey_get_details($res);
|
||||
if (!isset($sslInfo['key'])) {
|
||||
$plainKey = false;
|
||||
}
|
||||
} else {
|
||||
$plainKey = false;
|
||||
}
|
||||
|
||||
return $plainKey;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates symmetric keyfile content using a generated key
|
||||
* @param string $plainContent content to be encrypted
|
||||
|
|
|
@ -74,7 +74,7 @@ class Helper {
|
|||
if (!$util->ready()) {
|
||||
|
||||
\OCP\Util::writeLog('Encryption library', 'User account "' . $util->getUserId()
|
||||
. '" is not ready for encryption; configuration started', \OCP\Util::DEBUG);
|
||||
. '" is not ready for encryption; configuration started', \OCP\Util::DEBUG);
|
||||
|
||||
if (!$util->setupServerSide($password)) {
|
||||
return false;
|
||||
|
@ -94,6 +94,7 @@ class Helper {
|
|||
* @return bool
|
||||
*/
|
||||
public static function adminEnableRecovery($recoveryKeyId, $recoveryPassword) {
|
||||
|
||||
$view = new \OC\Files\View('/');
|
||||
|
||||
if ($recoveryKeyId === null) {
|
||||
|
@ -128,13 +129,6 @@ class Helper {
|
|||
// Save private key
|
||||
$view->file_put_contents('/owncloud_private_key/' . $recoveryKeyId . '.private.key', $encryptedPrivateKey);
|
||||
|
||||
// create control file which let us check later on if the entered password was correct.
|
||||
$encryptedControlData = \OCA\Encryption\Crypt::keyEncrypt("ownCloud", $keypair['publicKey']);
|
||||
if (!$view->is_dir('/control-file')) {
|
||||
$view->mkdir('/control-file');
|
||||
}
|
||||
$view->file_put_contents('/control-file/controlfile.enc', $encryptedControlData);
|
||||
|
||||
\OC_FileProxy::$enabled = true;
|
||||
|
||||
// Set recoveryAdmin as enabled
|
||||
|
@ -201,4 +195,17 @@ class Helper {
|
|||
|
||||
return $relPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief redirect to a error page
|
||||
*/
|
||||
public static function redirectToErrorPage() {
|
||||
$location = \OC_Helper::linkToAbsolute('apps/files_encryption/files', 'error.php');
|
||||
$post = 0;
|
||||
if(count($_POST) > 0) {
|
||||
$post = 1;
|
||||
}
|
||||
header('Location: ' . $location . '?p=' . $post);
|
||||
exit();
|
||||
}
|
||||
}
|
|
@ -88,9 +88,10 @@ class Session {
|
|||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
$encryptedKey = $this->view->file_get_contents( '/owncloud_private_key/' . $publicShareKeyId . '.private.key' );
|
||||
$privateKey = Crypt::symmetricDecryptFileContent( $encryptedKey, '' );
|
||||
$this->setPublicSharePrivateKey( $privateKey );
|
||||
$encryptedKey = $this->view->file_get_contents(
|
||||
'/owncloud_private_key/' . $publicShareKeyId . '.private.key');
|
||||
$privateKey = Crypt::decryptPrivateKey($encryptedKey, '');
|
||||
$this->setPublicSharePrivateKey($privateKey);
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
}
|
||||
|
@ -121,7 +122,7 @@ class Session {
|
|||
if (\OCA\Encryption\Helper::isPublicAccess()) {
|
||||
return $this->getPublicSharePrivateKey();
|
||||
} else {
|
||||
if (!is_null( \OC::$session->get('privateKey') )) {
|
||||
if (!is_null(\OC::$session->get('privateKey'))) {
|
||||
return \OC::$session->get('privateKey');
|
||||
} else {
|
||||
return false;
|
||||
|
@ -136,7 +137,7 @@ class Session {
|
|||
*/
|
||||
public function setPublicSharePrivateKey($privateKey) {
|
||||
|
||||
\OC::$session->set('publicSharePrivateKey', $privateKey);
|
||||
\OC::$session->set('publicSharePrivateKey', $privateKey);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -149,7 +150,7 @@ class Session {
|
|||
*/
|
||||
public function getPublicSharePrivateKey() {
|
||||
|
||||
if (!is_null( \OC::$session->get('publicSharePrivateKey') )) {
|
||||
if (!is_null(\OC::$session->get('publicSharePrivateKey'))) {
|
||||
return \OC::$session->get('publicSharePrivateKey');
|
||||
} else {
|
||||
return false;
|
||||
|
@ -176,7 +177,7 @@ class Session {
|
|||
*/
|
||||
public function getLegacyKey() {
|
||||
|
||||
if ( !is_null( \OC::$session->get('legacyKey') ) ) {
|
||||
if (!is_null(\OC::$session->get('legacyKey'))) {
|
||||
|
||||
return \OC::$session->get('legacyKey');
|
||||
|
||||
|
|
|
@ -56,18 +56,21 @@ class Stream {
|
|||
private $relPath; // rel path to users file dir
|
||||
private $userId;
|
||||
private $handle; // Resource returned by fopen
|
||||
private $path;
|
||||
private $readBuffer; // For streams that dont support seeking
|
||||
private $meta = array(); // Header / meta for source stream
|
||||
private $count;
|
||||
private $writeCache;
|
||||
private $size;
|
||||
private $unencryptedSize;
|
||||
private $publicKey;
|
||||
private $keyfile;
|
||||
private $encKeyfile;
|
||||
private static $view; // a fsview object set to user dir
|
||||
/**
|
||||
* @var \OC\Files\View
|
||||
*/
|
||||
private $rootView; // a fsview object set to '/'
|
||||
/**
|
||||
* @var \OCA\Encryption\Session
|
||||
*/
|
||||
private $session;
|
||||
private $privateKey;
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
|
@ -82,6 +85,10 @@ class Stream {
|
|||
$this->rootView = new \OC_FilesystemView('/');
|
||||
}
|
||||
|
||||
$this->session = new \OCA\Encryption\Session($this->rootView);
|
||||
|
||||
$this->privateKey = $this->session->getPrivateKey($this->userId);
|
||||
|
||||
$util = new Util($this->rootView, \OCP\USER::getUser());
|
||||
|
||||
$this->userId = $util->getUserId();
|
||||
|
@ -109,6 +116,11 @@ class Stream {
|
|||
|
||||
} else {
|
||||
|
||||
if($this->privateKey === false) {
|
||||
// if private key is not valid redirect user to a error page
|
||||
\OCA\Encryption\Helper::redirectToErrorPage();
|
||||
}
|
||||
|
||||
$this->size = $this->rootView->filesize($this->rawPath, $mode);
|
||||
}
|
||||
|
||||
|
@ -118,7 +130,7 @@ class Stream {
|
|||
|
||||
if (!is_resource($this->handle)) {
|
||||
|
||||
\OCP\Util::writeLog('files_encryption', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
|
||||
\OCP\Util::writeLog('Encryption library', 'failed to open file "' . $this->rawPath . '"', \OCP\Util::ERROR);
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -156,7 +168,7 @@ class Stream {
|
|||
|
||||
// $count will always be 8192 https://bugs.php.net/bug.php?id=21641
|
||||
// This makes this function a lot simpler, but will break this class if the above 'bug' gets 'fixed'
|
||||
\OCP\Util::writeLog('files_encryption', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL);
|
||||
\OCP\Util::writeLog('Encryption library', 'PHP "bug" 21641 no longer holds, decryption system requires refactoring', \OCP\Util::FATAL);
|
||||
|
||||
die();
|
||||
|
||||
|
@ -165,7 +177,7 @@ class Stream {
|
|||
// Get the data from the file handle
|
||||
$data = fread($this->handle, 8192);
|
||||
|
||||
$result = '';
|
||||
$result = null;
|
||||
|
||||
if (strlen($data)) {
|
||||
|
||||
|
@ -175,10 +187,11 @@ class Stream {
|
|||
throw new \Exception(
|
||||
'Encryption key not found for "' . $this->rawPath . '" during attempted read via stream');
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
// Decrypt data
|
||||
$result = Crypt::symmetricDecryptFileContent($data, $this->plainKey);
|
||||
// Decrypt data
|
||||
$result = Crypt::symmetricDecryptFileContent($data, $this->plainKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -228,13 +241,18 @@ class Stream {
|
|||
// If a keyfile already exists
|
||||
if ($this->encKeyfile) {
|
||||
|
||||
$session = new \OCA\Encryption\Session( $this->rootView );
|
||||
// if there is no valid private key return false
|
||||
if ($this->privateKey === false) {
|
||||
|
||||
$privateKey = $session->getPrivateKey($this->userId);
|
||||
// if private key is not valid redirect user to a error page
|
||||
\OCA\Encryption\Helper::redirectToErrorPage();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$shareKey = Keymanager::getShareKey($this->rootView, $this->userId, $this->relPath);
|
||||
|
||||
$this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $privateKey);
|
||||
$this->plainKey = Crypt::multiKeyDecrypt($this->encKeyfile, $shareKey, $this->privateKey);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -257,6 +275,12 @@ class Stream {
|
|||
*/
|
||||
public function stream_write($data) {
|
||||
|
||||
// if there is no valid private key return false
|
||||
if ($this->privateKey === false) {
|
||||
$this->size = 0;
|
||||
return strlen($data);
|
||||
}
|
||||
|
||||
// Disable the file proxies so that encryption is not
|
||||
// automatically attempted when the file is written to disk -
|
||||
// we are handling that separately here and we don't want to
|
||||
|
@ -424,6 +448,28 @@ class Stream {
|
|||
|
||||
$this->flush();
|
||||
|
||||
// if there is no valid private key return false
|
||||
if ($this->privateKey === false) {
|
||||
|
||||
// cleanup
|
||||
if ($this->meta['mode'] !== 'r' && $this->meta['mode'] !== 'rb') {
|
||||
|
||||
// Disable encryption proxy to prevent recursive calls
|
||||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
if ($this->rootView->file_exists($this->rawPath) && $this->size === 0) {
|
||||
$this->rootView->unlink($this->rawPath);
|
||||
}
|
||||
|
||||
// Re-enable proxy - our work is done
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
}
|
||||
|
||||
// if private key is not valid redirect user to a error page
|
||||
\OCA\Encryption\Helper::redirectToErrorPage();
|
||||
}
|
||||
|
||||
if (
|
||||
$this->meta['mode'] !== 'r'
|
||||
and $this->meta['mode'] !== 'rb'
|
||||
|
@ -450,16 +496,14 @@ class Stream {
|
|||
// Encrypt enc key for all sharing users
|
||||
$this->encKeyfiles = Crypt::multiKeyEncrypt($this->plainKey, $publicKeys);
|
||||
|
||||
$view = new \OC_FilesystemView('/');
|
||||
|
||||
// Save the new encrypted file key
|
||||
Keymanager::setFileKey($this->rootView, $this->relPath, $this->userId, $this->encKeyfiles['data']);
|
||||
|
||||
// Save the sharekeys
|
||||
Keymanager::setShareKeys($view, $this->relPath, $this->encKeyfiles['keys']);
|
||||
Keymanager::setShareKeys($this->rootView, $this->relPath, $this->encKeyfiles['keys']);
|
||||
|
||||
// get file info
|
||||
$fileInfo = $view->getFileInfo($this->rawPath);
|
||||
$fileInfo = $this->rootView->getFileInfo($this->rawPath);
|
||||
if (!is_array($fileInfo)) {
|
||||
$fileInfo = array();
|
||||
}
|
||||
|
@ -473,7 +517,7 @@ class Stream {
|
|||
$fileInfo['unencrypted_size'] = $this->unencryptedSize;
|
||||
|
||||
// set fileinfo
|
||||
$view->putFileInfo($this->rawPath, $fileInfo);
|
||||
$this->rootView->putFileInfo($this->rawPath, $fileInfo);
|
||||
}
|
||||
|
||||
return fclose($this->handle);
|
||||
|
|
|
@ -305,7 +305,7 @@ class Util {
|
|||
if (\OCP\DB::isError($result)) {
|
||||
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
|
||||
} else {
|
||||
if($result->numRows() > 0) {
|
||||
if ($result->numRows() > 0) {
|
||||
$row = $result->fetchRow();
|
||||
if (isset($row['recovery_enabled'])) {
|
||||
$recoveryEnabled[] = $row['recovery_enabled'];
|
||||
|
@ -445,7 +445,7 @@ class Util {
|
|||
|
||||
// If the file uses old
|
||||
// encryption system
|
||||
} elseif ( Crypt::isLegacyEncryptedContent( $data, $relPath ) ) {
|
||||
} elseif (Crypt::isLegacyEncryptedContent($data, $relPath)) {
|
||||
|
||||
$found['legacy'][] = array(
|
||||
'name' => $file,
|
||||
|
@ -576,7 +576,9 @@ class Util {
|
|||
// get relative path
|
||||
$relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
|
||||
|
||||
if (isset($pathParts[2]) && $pathParts[2] === 'files' && $this->view->file_exists($path) && $this->isEncryptedPath($path)) {
|
||||
if (isset($pathParts[2]) && $pathParts[2] === 'files' && $this->view->file_exists($path)
|
||||
&& $this->isEncryptedPath($path)
|
||||
) {
|
||||
|
||||
// get the size from filesystem
|
||||
$fullPath = $this->view->getLocalFile($path);
|
||||
|
@ -646,7 +648,7 @@ class Util {
|
|||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @return bool
|
||||
|
@ -690,28 +692,32 @@ class Util {
|
|||
$relPath = $plainFile['path'];
|
||||
|
||||
//relative to /data
|
||||
$rawPath = '/'.$this->userId . '/files/' . $plainFile['path'];
|
||||
$rawPath = '/' . $this->userId . '/files/' . $plainFile['path'];
|
||||
|
||||
// Open plain file handle for binary reading
|
||||
$plainHandle = $this->view->fopen( $rawPath, 'rb' );
|
||||
$plainHandle = $this->view->fopen($rawPath, 'rb');
|
||||
|
||||
// Open enc file handle for binary writing, with same filename as original plain file
|
||||
$encHandle = fopen( 'crypt://' . $relPath.'.tmp', 'wb' );
|
||||
$encHandle = fopen('crypt://' . $relPath . '.tmp', 'wb');
|
||||
|
||||
// Move plain file to a temporary location
|
||||
$size = stream_copy_to_stream( $plainHandle, $encHandle );
|
||||
$size = stream_copy_to_stream($plainHandle, $encHandle);
|
||||
|
||||
fclose($encHandle);
|
||||
|
||||
$fakeRoot = $this->view->getRoot();
|
||||
$this->view->chroot('/'.$this->userId.'/files');
|
||||
$this->view->chroot('/' . $this->userId . '/files');
|
||||
|
||||
$this->view->rename($relPath . '.tmp', $relPath);
|
||||
|
||||
$this->view->chroot($fakeRoot);
|
||||
|
||||
// Add the file to the cache
|
||||
\OC\Files\Filesystem::putFileInfo( $relPath, array( 'encrypted' => true, 'size' => $size, 'unencrypted_size' => $size ) );
|
||||
\OC\Files\Filesystem::putFileInfo($relPath, array(
|
||||
'encrypted' => true,
|
||||
'size' => $size,
|
||||
'unencrypted_size' => $size
|
||||
));
|
||||
}
|
||||
|
||||
// Encrypt legacy encrypted files
|
||||
|
@ -822,7 +828,7 @@ class Util {
|
|||
if (\OCP\DB::isError($result)) {
|
||||
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
|
||||
} else {
|
||||
if($result->numRows() > 0) {
|
||||
if ($result->numRows() > 0) {
|
||||
$row = $result->fetchRow();
|
||||
$path = substr($row['path'], strlen('files'));
|
||||
}
|
||||
|
@ -1113,7 +1119,7 @@ class Util {
|
|||
if (\OCP\DB::isError($result)) {
|
||||
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
|
||||
} else {
|
||||
if($result->numRows() > 0) {
|
||||
if ($result->numRows() > 0) {
|
||||
$row = $result->fetchRow();
|
||||
if (isset($row['migration_status'])) {
|
||||
$migrationStatus[] = $row['migration_status'];
|
||||
|
@ -1199,7 +1205,8 @@ class Util {
|
|||
|
||||
$result = array();
|
||||
|
||||
$content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath($this->userFilesDir . '/' . $dir));
|
||||
$content = $this->view->getDirectoryContent(\OC\Files\Filesystem::normalizePath(
|
||||
$this->userFilesDir . '/' . $dir));
|
||||
|
||||
// handling for re shared folders
|
||||
$pathSplit = explode('/', $dir);
|
||||
|
@ -1260,7 +1267,7 @@ class Util {
|
|||
if (\OCP\DB::isError($result)) {
|
||||
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
|
||||
} else {
|
||||
if($result->numRows() > 0) {
|
||||
if ($result->numRows() > 0) {
|
||||
$row = $result->fetchRow();
|
||||
}
|
||||
}
|
||||
|
@ -1286,7 +1293,7 @@ class Util {
|
|||
if (\OCP\DB::isError($result)) {
|
||||
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
|
||||
} else {
|
||||
if($result->numRows() > 0) {
|
||||
if ($result->numRows() > 0) {
|
||||
$row = $result->fetchRow();
|
||||
}
|
||||
}
|
||||
|
@ -1311,7 +1318,7 @@ class Util {
|
|||
if (\OCP\DB::isError($result)) {
|
||||
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
|
||||
} else {
|
||||
if($result->numRows() > 0) {
|
||||
if ($result->numRows() > 0) {
|
||||
$source = $result->fetchRow();
|
||||
}
|
||||
}
|
||||
|
@ -1332,7 +1339,7 @@ class Util {
|
|||
if (\OCP\DB::isError($result)) {
|
||||
\OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR);
|
||||
} else {
|
||||
if($result->numRows() > 0) {
|
||||
if ($result->numRows() > 0) {
|
||||
$item = $result->fetchRow();
|
||||
}
|
||||
}
|
||||
|
@ -1380,26 +1387,24 @@ class Util {
|
|||
*/
|
||||
public function checkRecoveryPassword($password) {
|
||||
|
||||
$result = false;
|
||||
$pathKey = '/owncloud_private_key/' . $this->recoveryKeyId . ".private.key";
|
||||
$pathControlData = '/control-file/controlfile.enc';
|
||||
|
||||
$proxyStatus = \OC_FileProxy::$enabled;
|
||||
\OC_FileProxy::$enabled = false;
|
||||
|
||||
$recoveryKey = $this->view->file_get_contents($pathKey);
|
||||
|
||||
$decryptedRecoveryKey = Crypt::symmetricDecryptFileContent($recoveryKey, $password);
|
||||
$decryptedRecoveryKey = Crypt::decryptPrivateKey($recoveryKey, $password);
|
||||
|
||||
$controlData = $this->view->file_get_contents($pathControlData);
|
||||
$decryptedControlData = Crypt::keyDecrypt($controlData, $decryptedRecoveryKey);
|
||||
if ($decryptedRecoveryKey) {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
|
||||
if ($decryptedControlData === 'ownCloud') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1528,7 +1533,7 @@ class Util {
|
|||
|
||||
$encryptedKey = $this->view->file_get_contents(
|
||||
'/owncloud_private_key/' . $this->recoveryKeyId . '.private.key');
|
||||
$privateKey = Crypt::symmetricDecryptFileContent($encryptedKey, $recoveryPassword);
|
||||
$privateKey = Crypt::decryptPrivateKey($encryptedKey, $recoveryPassword);
|
||||
|
||||
\OC_FileProxy::$enabled = $proxyStatus;
|
||||
|
||||
|
@ -1544,7 +1549,7 @@ class Util {
|
|||
list($storage, $internalPath) = \OC\Files\Cache\Cache::getById($id);
|
||||
$mount = \OC\Files\Filesystem::getMountByStorageId($storage);
|
||||
$mountPoint = $mount[0]->getMountPoint();
|
||||
$path = \OC\Files\Filesystem::normalizePath($mountPoint.'/'.$internalPath);
|
||||
$path = \OC\Files\Filesystem::normalizePath($mountPoint . '/' . $internalPath);
|
||||
|
||||
// reformat the path to be relative e.g. /user/files/folder becomes /folder/
|
||||
$relativePath = \OCA\Encryption\Helper::stripUserFilesPath($path);
|
||||
|
|
|
@ -14,15 +14,26 @@ $tmpl = new OCP\Template('files_encryption', 'settings-personal');
|
|||
$user = \OCP\USER::getUser();
|
||||
$view = new \OC_FilesystemView('/');
|
||||
$util = new \OCA\Encryption\Util($view, $user);
|
||||
$session = new \OCA\Encryption\Session($view);
|
||||
|
||||
$privateKeySet = ($session->getPrivateKey() !== false) ? true : false;
|
||||
|
||||
$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled');
|
||||
$recoveryEnabledForUser = $util->recoveryEnabledForUser();
|
||||
|
||||
\OCP\Util::addscript('files_encryption', 'settings-personal');
|
||||
\OCP\Util::addScript('settings', 'personal');
|
||||
$result = false;
|
||||
|
||||
$tmpl->assign('recoveryEnabled', $recoveryAdminEnabled);
|
||||
$tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser);
|
||||
if ($recoveryAdminEnabled || !$privateKeySet) {
|
||||
|
||||
return $tmpl->fetchPage();
|
||||
\OCP\Util::addscript('files_encryption', 'settings-personal');
|
||||
\OCP\Util::addScript('settings', 'personal');
|
||||
|
||||
$tmpl->assign('recoveryEnabled', $recoveryAdminEnabled);
|
||||
$tmpl->assign('recoveryEnabledForUser', $recoveryEnabledForUser);
|
||||
$tmpl->assign('privateKeySet', $privateKeySet);
|
||||
|
||||
$result = $tmpl->fetchPage();
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
|
|
10
apps/files_encryption/templates/invalid_private_key.php
Normal file
10
apps/files_encryption/templates/invalid_private_key.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<ul>
|
||||
<li class='error'>
|
||||
<?php $location = \OC_Helper::linkToRoute( "settings_personal" ).'#changePKPasswd' ?>
|
||||
|
||||
<?php p($l->t('Your private key is not valid! Maybe the your password was changed from outside.')); ?>
|
||||
<br/>
|
||||
<?php p($l->t('You can unlock your private key in your ')); ?> <a href="<?php echo $location?>"><?php p($l->t('personal settings')); ?>.</a>
|
||||
<br/>
|
||||
</li>
|
||||
</ul>
|
|
@ -1,54 +1,56 @@
|
|||
<form id="encryption">
|
||||
<fieldset class="personalblock">
|
||||
|
||||
|
||||
<p>
|
||||
<strong><?php p($l->t( 'Encryption' )); ?></strong>
|
||||
<br />
|
||||
<strong><?php p($l->t('Encryption')); ?></strong>
|
||||
<br/>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<?php p($l->t( "Enable encryption passwords recovery key (allow sharing to recovery key):" )); ?>
|
||||
<br />
|
||||
<br />
|
||||
<input type="password" name="recoveryPassword" id="recoveryPassword" />
|
||||
<label for="recoveryPassword"><?php p($l->t( "Recovery account password" )); ?></label>
|
||||
<br />
|
||||
<input
|
||||
type='radio'
|
||||
name='adminEnableRecovery'
|
||||
value='1'
|
||||
<?php echo ( $_["recoveryEnabled"] == 1 ? 'checked="checked"' : 'disabled' ); ?> />
|
||||
<?php p($l->t( "Enabled" )); ?>
|
||||
<br />
|
||||
|
||||
<input
|
||||
type='radio'
|
||||
name='adminEnableRecovery'
|
||||
value='0'
|
||||
<?php echo ( $_["recoveryEnabled"] == 0 ? 'checked="checked"' : 'disabled' ); ?> />
|
||||
<?php p($l->t( "Disabled" )); ?>
|
||||
<?php p($l->t("Enable encryption passwords recovery key (allow sharing to recovery key):")); ?>
|
||||
<br/>
|
||||
<br/>
|
||||
<input type="password" name="recoveryPassword" id="recoveryPassword"/>
|
||||
<label for="recoveryPassword"><?php p($l->t("Recovery account password")); ?></label>
|
||||
<br/>
|
||||
<input
|
||||
type='radio'
|
||||
name='adminEnableRecovery'
|
||||
value='1'
|
||||
<?php echo($_["recoveryEnabled"] == 1 ? 'checked="checked"' : 'disabled'); ?> />
|
||||
<?php p($l->t("Enabled")); ?>
|
||||
<br/>
|
||||
|
||||
<input
|
||||
type='radio'
|
||||
name='adminEnableRecovery'
|
||||
value='0'
|
||||
<?php echo($_["recoveryEnabled"] == 0 ? 'checked="checked"' : 'disabled'); ?> />
|
||||
<?php p($l->t("Disabled")); ?>
|
||||
</p>
|
||||
<br /><br />
|
||||
<br/><br/>
|
||||
|
||||
<p>
|
||||
<strong><?php p($l->t( "Change encryption passwords recovery key:" )); ?></strong>
|
||||
<br /><br />
|
||||
<input
|
||||
<strong><?php p($l->t("Change encryption passwords recovery key:")); ?></strong>
|
||||
<br/><br/>
|
||||
<input
|
||||
type="password"
|
||||
name="changeRecoveryPassword"
|
||||
id="oldRecoveryPassword"
|
||||
<?php echo ( $_["recoveryEnabled"] == 0 ? 'disabled' : '' ); ?> />
|
||||
<label for="oldRecoveryPassword"><?php p($l->t( "Old Recovery account password" )); ?></label>
|
||||
<br />
|
||||
<input
|
||||
<?php echo($_["recoveryEnabled"] == 0 ? 'disabled' : ''); ?> />
|
||||
<label for="oldRecoveryPassword"><?php p($l->t("Old Recovery account password")); ?></label>
|
||||
<br/>
|
||||
<input
|
||||
type="password"
|
||||
name="changeRecoveryPassword"
|
||||
id="newRecoveryPassword"
|
||||
<?php echo ( $_["recoveryEnabled"] == 0 ? 'disabled' : '' ); ?> />
|
||||
<label for="newRecoveryPassword"><?php p($l->t( "New Recovery account password" )); ?></label>
|
||||
<br />
|
||||
<?php echo($_["recoveryEnabled"] == 0 ? 'disabled' : ''); ?> />
|
||||
<label for="newRecoveryPassword"><?php p($l->t("New Recovery account password")); ?></label>
|
||||
<br/>
|
||||
<button
|
||||
type="button"
|
||||
name="submitChangeRecoveryKey"
|
||||
disabled><?php p($l->t( "Change Password" )); ?>
|
||||
disabled><?php p($l->t("Change Password")); ?>
|
||||
</button>
|
||||
<span class="msg"></span>
|
||||
</p>
|
||||
|
|
|
@ -3,12 +3,48 @@
|
|||
<legend>
|
||||
<?php p( $l->t( 'Encryption' ) ); ?>
|
||||
</legend>
|
||||
|
||||
<?php if ( $_["recoveryEnabled"] ): ?>
|
||||
|
||||
<?php if ( ! $_["privateKeySet"] ): ?>
|
||||
<p>
|
||||
<label for="userEnableRecovery"><?php p( $l->t( "Enable password recovery by sharing all files with your administrator:" ) ); ?></label>
|
||||
<a name="changePKPasswd" />
|
||||
<label for="changePrivateKeyPasswd">
|
||||
<?php p( $l->t( "Your private key password no longer match your log-in password:" ) ); ?>
|
||||
</label>
|
||||
<br />
|
||||
<em><?php p( $l->t( "Enabling this option will allow you to reobtain access to your encrypted files if your password is lost" ) ); ?></em>
|
||||
<em><?php p( $l->t( "Set your old private key password to your current log-in password." ) ); ?>
|
||||
<?php if ( $_["recoveryEnabledForUser"] ):
|
||||
p( $l->t( " If you don't remember your old password you can ask your administrator to recover your files." ) );
|
||||
endif; ?>
|
||||
</em>
|
||||
<br />
|
||||
<input
|
||||
type="password"
|
||||
name="changePrivateKeyPassword"
|
||||
id="oldPrivateKeyPassword" />
|
||||
<label for="oldPrivateKeyPassword"><?php p($l->t( "Old log-in password" )); ?></label>
|
||||
<br />
|
||||
<input
|
||||
type="password"
|
||||
name="changePrivateKeyPassword"
|
||||
id="newPrivateKeyPassword" />
|
||||
<label for="newRecoveryPassword"><?php p($l->t( "Current log-in password" )); ?></label>
|
||||
<br />
|
||||
<button
|
||||
type="button"
|
||||
name="submitChangePrivateKeyPassword"
|
||||
disabled><?php p($l->t( "Update Private Key Password" )); ?>
|
||||
</button>
|
||||
<span class="msg"></span>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<br />
|
||||
|
||||
<?php if ( $_["recoveryEnabled"] && $_["privateKeySet"] ): ?>
|
||||
<p>
|
||||
<label for="userEnableRecovery"><?php p( $l->t( "Enable password recovery:" ) ); ?></label>
|
||||
<br />
|
||||
<em><?php p( $l->t( "Enabling this option will allow you to reobtain access to your encrypted files in case of password loss" ) ); ?></em>
|
||||
<br />
|
||||
<input
|
||||
type='radio'
|
||||
|
@ -28,6 +64,7 @@
|
|||
<div id="recoveryEnabledError"><?php p( $l->t( 'Could not update file recovery' ) ); ?></div>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<br />
|
||||
</fieldset>
|
||||
</form>
|
||||
|
|
|
@ -92,8 +92,7 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
|
|||
// reset app files_trashbin
|
||||
if ($this->stateFilesTrashbin) {
|
||||
OC_App::enable('files_trashbin');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
OC_App::disable('files_trashbin');
|
||||
}
|
||||
}
|
||||
|
@ -240,6 +239,23 @@ class Test_Encryption_Crypt extends \PHPUnit_Framework_TestCase {
|
|||
|
||||
}
|
||||
|
||||
function testDecryptPrivateKey() {
|
||||
|
||||
// test successful decrypt
|
||||
$crypted = Encryption\Crypt::symmetricEncryptFileContent($this->genPrivateKey, 'hat');
|
||||
|
||||
$decrypted = Encryption\Crypt::decryptPrivateKey($crypted, 'hat');
|
||||
|
||||
$this->assertEquals($this->genPrivateKey, $decrypted);
|
||||
|
||||
//test private key decrypt with wrong password
|
||||
$wrongPasswd = Encryption\Crypt::decryptPrivateKey($crypted, 'hat2');
|
||||
|
||||
$this->assertEquals(false, $wrongPasswd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @medium
|
||||
*/
|
||||
|
|
|
@ -111,8 +111,7 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
|
|||
// reset app files_trashbin
|
||||
if ($this->stateFilesTrashbin) {
|
||||
OC_App::enable('files_trashbin');
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
OC_App::disable('files_trashbin');
|
||||
}
|
||||
}
|
||||
|
@ -656,9 +655,6 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
|
|||
\OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
|
||||
$recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
|
||||
|
||||
// check if control file created
|
||||
$this->assertTrue($this->view->file_exists('/control-file/controlfile.enc'));
|
||||
|
||||
// login as admin
|
||||
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER1);
|
||||
|
||||
|
@ -761,9 +757,6 @@ class Test_Encryption_Share extends \PHPUnit_Framework_TestCase {
|
|||
\OCA\Encryption\Helper::adminEnableRecovery(null, 'test123');
|
||||
$recoveryKeyId = OC_Appconfig::getValue('files_encryption', 'recoveryKeyId');
|
||||
|
||||
// check if control file created
|
||||
$this->assertTrue($this->view->file_exists('/control-file/controlfile.enc'));
|
||||
|
||||
// login as user1
|
||||
\Test_Encryption_Util::loginHelper(\Test_Encryption_Share::TEST_ENCRYPTION_SHARE_USER2);
|
||||
|
||||
|
|
|
@ -8,8 +8,11 @@
|
|||
|
||||
class OC_Core_LostPassword_Controller {
|
||||
protected static function displayLostPasswordPage($error, $requested) {
|
||||
$encrypted = OC_App::isEnabled('files_encryption');
|
||||
OC_Template::printGuestPage('core/lostpassword', 'lostpassword',
|
||||
array('error' => $error, 'requested' => $requested));
|
||||
array('error' => $error,
|
||||
'requested' => $requested,
|
||||
'encrypted' => $encrypted));
|
||||
}
|
||||
|
||||
protected static function displayResetPasswordPage($success, $args) {
|
||||
|
@ -29,7 +32,14 @@ class OC_Core_LostPassword_Controller {
|
|||
}
|
||||
|
||||
public static function sendEmail($args) {
|
||||
if (OC_User::userExists($_POST['user'])) {
|
||||
|
||||
if(isset($_POST['noEncryption']) || isset($_POST['continue'])) {
|
||||
$continue = true;
|
||||
} else {
|
||||
$continue = false;
|
||||
}
|
||||
|
||||
if (OC_User::userExists($_POST['user']) && $continue) {
|
||||
$token = hash('sha256', OC_Util::generate_random_bytes(30).OC_Config::getValue('passwordsalt', ''));
|
||||
OC_Preferences::setValue($_POST['user'], 'owncloud', 'lostpassword',
|
||||
hash('sha256', $token)); // Hash the token again to prevent timing attacks
|
||||
|
|
|
@ -17,6 +17,14 @@
|
|||
<input type="text" name="user" id="user" placeholder="" value="" autocomplete="off" required autofocus />
|
||||
<label for="user" class="infield"><?php print_unescaped($l->t( 'Username' )); ?></label>
|
||||
<img class="svg" src="<?php print_unescaped(image_path('', 'actions/user.svg')); ?>" alt=""/>
|
||||
<?php if ($_['encrypted']): ?>
|
||||
<br /><br />
|
||||
<?php print_unescaped($l->t('Your files seems to be encrypted. If you didn\'t have enabled the recovery key there will be no way to get your data back once the password was resetted. If you are not sure what to do, please contact your administrator first before continue. Do you really want to continue?')); ?><br />
|
||||
<input type="checkbox" name="continue" value="Yes" />
|
||||
<?php print_unescaped($l->t('Yes, I really want to reset my password now')); ?><br/><br/>
|
||||
<?php else: ?>
|
||||
<input type="checkbox" name="noEncryption" value="Yes" checked />
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<input type="submit" id="submit" value="<?php print_unescaped($l->t('Request reset')); ?>" />
|
||||
</fieldset>
|
||||
|
|
|
@ -7,44 +7,44 @@ OC_JSON::checkLoggedIn();
|
|||
// Manually load apps to ensure hooks work correctly (workaround for issue 1503)
|
||||
OC_APP::loadApps();
|
||||
|
||||
$username = isset($_POST["username"]) ? $_POST["username"] : OC_User::getUser();
|
||||
$password = isset($_POST["password"]) ? $_POST["password"] : null;
|
||||
$oldPassword=isset($_POST["oldpassword"])?$_POST["oldpassword"]:'';
|
||||
$recoveryPassword=isset($_POST["recoveryPassword"])?$_POST["recoveryPassword"]:null;
|
||||
$username = isset($_POST['username']) ? $_POST['username'] : OC_User::getUser();
|
||||
$password = isset($_POST['password']) ? $_POST['password'] : null;
|
||||
$oldPassword = isset($_POST['oldpassword']) ? $_POST['oldpassword'] : '';
|
||||
$recoveryPassword = isset($_POST['recoveryPassword']) ? $_POST['recoveryPassword'] : null;
|
||||
|
||||
$userstatus = null;
|
||||
if(OC_User::isAdminUser(OC_User::getUser())) {
|
||||
if (OC_User::isAdminUser(OC_User::getUser())) {
|
||||
$userstatus = 'admin';
|
||||
}
|
||||
if(OC_SubAdmin::isUserAccessible(OC_User::getUser(), $username)) {
|
||||
if (OC_SubAdmin::isUserAccessible(OC_User::getUser(), $username)) {
|
||||
$userstatus = 'subadmin';
|
||||
}
|
||||
if(OC_User::getUser() === $username && OC_User::checkPassword($username, $oldPassword)) {
|
||||
if (OC_User::getUser() === $username && OC_User::checkPassword($username, $oldPassword)) {
|
||||
$userstatus = 'user';
|
||||
}
|
||||
|
||||
if(is_null($userstatus)) {
|
||||
OC_JSON::error( array( "data" => array( "message" => "Authentication error" )));
|
||||
if (is_null($userstatus)) {
|
||||
OC_JSON::error(array('data' => array('message' => 'Authentication error')));
|
||||
exit();
|
||||
}
|
||||
|
||||
$recoveryAdminEnabled = OC_Appconfig::getValue( 'files_encryption', 'recoveryAdminEnabled' );
|
||||
|
||||
|
||||
$validRecoveryPassword = false;
|
||||
$recoveryPasswordSupported = false;
|
||||
|
||||
if ($recoveryAdminEnabled) {
|
||||
if (\OCP\App::isEnabled('files_encryption') && $userstatus !== 'user') {
|
||||
//handle the recovery case
|
||||
$util = new \OCA\Encryption\Util(new \OC_FilesystemView('/'), $username);
|
||||
$validRecoveryPassword = $util->checkRecoveryPassword($recoveryPassword);
|
||||
$recoveryPasswordSupported = $util->recoveryEnabledForUser();
|
||||
}
|
||||
$recoveryAdminEnabled = OC_Appconfig::getValue('files_encryption', 'recoveryAdminEnabled');
|
||||
|
||||
if ($recoveryPasswordSupported && $recoveryPassword == '') {
|
||||
OC_JSON::error(array("data" => array( "message" => "Please provide a admin recovery password, otherwise all user data will be lost" )));
|
||||
} elseif ( $recoveryPasswordSupported && ! $validRecoveryPassword) {
|
||||
OC_JSON::error(array("data" => array( "message" => "Wrong admin recovery password. Please check the password and try again." )));
|
||||
} else { // now we know that everything is file regarding the recovery password, let's try to change the password
|
||||
$validRecoveryPassword = false;
|
||||
$recoveryPasswordSupported = false;
|
||||
if ($recoveryAdminEnabled) {
|
||||
$validRecoveryPassword = $util->checkRecoveryPassword($recoveryPassword);
|
||||
$recoveryEnabledForUser = $util->recoveryEnabledForUser();
|
||||
}
|
||||
|
||||
if ($recoveryEnabledForUser && $recoveryPassword === '') {
|
||||
OC_JSON::error(array('data' => array('message' => 'Please provide a admin recovery password, otherwise all user data will be lost')));
|
||||
} elseif ($recoveryEnabledForUser && ! $validRecoveryPassword) {
|
||||
OC_JSON::error(array('data' => array('message' => 'Wrong admin recovery password. Please check the password and try again.')));
|
||||
} else { // now we know that everything is fine regarding the recovery password, let's try to change the password
|
||||
$result = OC_User::setPassword($username, $password, $recoveryPassword);
|
||||
if (!$result && $recoveryPasswordSupported) {
|
||||
OC_JSON::error(array("data" => array( "message" => "Back-end doesn't support password change, but the users encryption key was successfully updated." )));
|
||||
|
@ -53,4 +53,12 @@ if ($recoveryPasswordSupported && $recoveryPassword == '') {
|
|||
} else {
|
||||
OC_JSON::success(array("data" => array( "username" => $username )));
|
||||
}
|
||||
|
||||
}
|
||||
} else { // if user changes his own password or if encryption is disabled, proceed
|
||||
if (!is_null($password) && OC_User::setPassword($username, $password)) {
|
||||
OC_JSON::success(array('data' => array('username' => $username)));
|
||||
} else {
|
||||
OC_JSON::error(array('data' => array('message' => 'Unable to change password')));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue