@@ -33,6 +33,11 @@ namespace OCA\Encryption\AppInfo; | |||
'name' => 'Recovery#userRecovery', | |||
'url' => '/ajax/userRecovery', | |||
'verb' => 'POST' | |||
], | |||
[ | |||
'name' => 'Recovery#changeRecoveryPassword', | |||
'url' => '/ajax/changeRecoveryPassword', | |||
'verb' => 'POST' | |||
] | |||
@@ -28,7 +28,7 @@ use OCP\IConfig; | |||
use OCP\IL10N; | |||
use OCP\IRequest; | |||
use OCP\JSON; | |||
use Symfony\Component\HttpFoundation\JsonResponse; | |||
use OCP\AppFramework\Http\DataResponse; | |||
class RecoveryController extends Controller { | |||
/** | |||
@@ -62,32 +62,60 @@ class RecoveryController extends Controller { | |||
// Check if both passwords are the same | |||
if (empty($recoveryPassword)) { | |||
$errorMessage = $this->l->t('Missing recovery key password'); | |||
return new JsonResponse(['data' => ['message' => $errorMessage]], 500); | |||
return new DataResponse(['data' => ['message' => $errorMessage]], 500); | |||
} | |||
if (empty($confirmPassword)) { | |||
$errorMessage = $this->l->t('Please repeat the recovery key password'); | |||
return new JsonResponse(['data' => ['message' => $errorMessage]], 500); | |||
return new DataResponse(['data' => ['message' => $errorMessage]], 500); | |||
} | |||
if ($recoveryPassword !== $confirmPassword) { | |||
$errorMessage = $this->l->t('Repeated recovery key password does not match the provided recovery key password'); | |||
return new JsonResponse(['data' => ['message' => $errorMessage]], 500); | |||
return new DataResponse(['data' => ['message' => $errorMessage]], 500); | |||
} | |||
// Enable recoveryAdmin | |||
$recoveryKeyId = $this->config->getAppValue('encryption', 'recoveryKeyId'); | |||
if (isset($adminEnableRecovery) && $adminEnableRecovery === '1') { | |||
if ($this->recovery->enableAdminRecovery($recoveryKeyId, $recoveryPassword)) { | |||
return new JsonResponse(['data' => array('message' => $this->l->t('Recovery key successfully enabled'))]); | |||
if ($this->recovery->enableAdminRecovery($recoveryPassword)) { | |||
return new DataResponse(['status' =>'success', 'data' => array('message' => $this->l->t('Recovery key successfully enabled'))]); | |||
} | |||
return new JsonResponse(['data' => array('message' => $this->l->t('Could not enable recovery key. Please check your recovery key password!'))]); | |||
return new DataResponse(['data' => array('message' => $this->l->t('Could not enable recovery key. Please check your recovery key password!'))]); | |||
} elseif (isset($adminEnableRecovery) && $adminEnableRecovery === '0') { | |||
if ($this->recovery->disableAdminRecovery($recoveryKeyId, $recoveryPassword)) { | |||
return new JsonResponse(['data' => array('message' => $this->l->t('Recovery key successfully disabled'))]); | |||
if ($this->recovery->disableAdminRecovery($recoveryPassword)) { | |||
return new DataResponse(['data' => array('message' => $this->l->t('Recovery key successfully disabled'))]); | |||
} | |||
return new JsonResponse(['data' => array('message' => $this->l->t('Could not disable recovery key. Please check your recovery key password!'))]); | |||
return new DataResponse(['data' => array('message' => $this->l->t('Could not disable recovery key. Please check your recovery key password!'))]); | |||
} | |||
} | |||
public function changeRecoveryPassword($newPassword, $oldPassword, $confirmPassword) { | |||
//check if both passwords are the same | |||
if (empty($oldPassword)) { | |||
$errorMessage = $this->l->t('Please provide the old recovery password'); | |||
return new DataResponse(array('data' => array('message' => $errorMessage))); | |||
} | |||
if (empty($newPassword)) { | |||
$errorMessage = $this->l->t('Please provide a new recovery password'); | |||
return new DataResponse (array('data' => array('message' => $errorMessage))); | |||
} | |||
if (empty($confirmPassword)) { | |||
$errorMessage = $this->l->t('Please repeat the new recovery password'); | |||
return new DataResponse(array('data' => array('message' => $errorMessage))); | |||
} | |||
if ($newPassword !== $confirmPassword) { | |||
$errorMessage = $this->l->t('Repeated recovery key password does not match the provided recovery key password'); | |||
return new DataResponse(array('data' => array('message' => $errorMessage))); | |||
} | |||
$result = $this->recovery->changeRecoveryKeyPassword($newPassword, $oldPassword); | |||
if ($result) { | |||
return new DataResponse(array('status' => 'success' ,'data' => array('message' => $this->l->t('Password successfully changed.')))); | |||
} else { | |||
return new DataResponse(array('data' => array('message' => $this->l->t('Could not change the password. Maybe the old password was not correct.')))); | |||
} | |||
} | |||
@@ -44,7 +44,7 @@ $(document).ready(function(){ | |||
var confirmNewPassword = $('#repeatedNewEncryptionRecoveryPassword').val(); | |||
OC.msg.startSaving('#encryptionChangeRecoveryKey .msg'); | |||
$.post( | |||
OC.filePath( 'encryption', 'ajax', 'changeRecoveryPassword.php' ) | |||
OC.generateUrl('/apps/encryption/ajax/changeRecoveryPassword') | |||
, { oldPassword: oldRecoveryPassword, newPassword: newRecoveryPassword, confirmPassword: confirmNewPassword } | |||
, function( data ) { | |||
OC.msg.finishedSaving('#encryptionChangeRecoveryKey .msg', data); |
@@ -23,6 +23,6 @@ | |||
namespace OCA\Encryption\Exceptions; | |||
class PrivateKeyMissingException extends GenericEncryptionException{ | |||
class PrivateKeyMissingException extends \Exception{ | |||
} |
@@ -108,6 +108,14 @@ class KeyManager { | |||
$this->config = $config; | |||
$this->recoveryKeyId = $this->config->getAppValue('encryption', | |||
'recoveryKeyId'); | |||
if (empty($this->recoveryKeyId)) { | |||
$this->recoveryKeyId = 'recoveryKey_' . substr(md5(time()), 0, 8); | |||
$this->config->setAppValue('encryption', | |||
'recoveryKeyId', | |||
$this->recoveryKeyId); | |||
} | |||
$this->publicShareKeyId = $this->config->getAppValue('encryption', | |||
'publicShareKeyId'); | |||
$this->log = $log; | |||
@@ -171,7 +179,7 @@ class KeyManager { | |||
* @return bool | |||
*/ | |||
public function checkRecoveryPassword($password) { | |||
$recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId); | |||
$recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.privateKey'); | |||
$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, | |||
$password); | |||
@@ -202,6 +210,26 @@ class KeyManager { | |||
return false; | |||
} | |||
/** | |||
* @param string $uid | |||
* @param string $password | |||
* @param array $keyPair | |||
* @return bool | |||
*/ | |||
public function setRecoveryKey($password, $keyPair) { | |||
// Save Public Key | |||
$this->keyStorage->setSystemUserKey($this->getRecoveryKeyId(). '.publicKey', $keyPair['publicKey']); | |||
$encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'], | |||
$password); | |||
if ($encryptedKey) { | |||
$this->setSystemPrivateKey($this->getRecoveryKeyId(), $encryptedKey); | |||
return true; | |||
} | |||
return false; | |||
} | |||
/** | |||
* @param $userId | |||
* @param $key | |||
@@ -428,9 +456,19 @@ class KeyManager { | |||
} | |||
/** | |||
* @param string $keyId | |||
* @return string returns openssl key | |||
*/ | |||
public function getSystemPrivateKey($keyId) { | |||
return $this->keyStorage->getSystemUserKey($keyId . '.' . $this->privateKeyId); | |||
} | |||
/** | |||
* @param string $keyId | |||
* @param string $key | |||
* @return string returns openssl key | |||
*/ | |||
public function getSystemPrivateKey() { | |||
return $this->keyStorage->getSystemUserKey($this->privateKeyId); | |||
public function setSystemPrivateKey($keyId, $key) { | |||
return $this->keyStorage->setSystemUserKey($keyId . '.' . $this->privateKeyId, $key); | |||
} | |||
} |
@@ -88,24 +88,14 @@ class Recovery { | |||
* @param $password | |||
* @return bool | |||
*/ | |||
public function enableAdminRecovery($recoveryKeyId, $password) { | |||
public function enableAdminRecovery($password) { | |||
$appConfig = $this->config; | |||
if ($recoveryKeyId === null) { | |||
$recoveryKeyId = $this->random->getLowStrengthGenerator(); | |||
$appConfig->setAppValue('encryption', | |||
'recoveryKeyId', | |||
$recoveryKeyId); | |||
} | |||
$keyManager = $this->keyManager; | |||
if (!$keyManager->recoveryKeyExists()) { | |||
$keyPair = $this->crypt->createKeyPair(); | |||
return $this->keyManager->storeKeyPair($this->user->getUID(), | |||
$password, | |||
$keyPair); | |||
$this->keyManager->setRecoveryKey($password, $keyPair); | |||
} | |||
if ($keyManager->checkRecoveryPassword($password)) { | |||
@@ -116,6 +106,23 @@ class Recovery { | |||
return false; | |||
} | |||
/** | |||
* change recovery key id | |||
* | |||
* @param string $newPassword | |||
* @param string $oldPassword | |||
*/ | |||
public function changeRecoveryKeyPassword($newPassword, $oldPassword) { | |||
$recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId()); | |||
$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $oldPassword); | |||
$encryptedRecoveryKey = $this->crypt->symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword); | |||
if ($encryptedRecoveryKey) { | |||
$this->keyManager->setSystemPrivateKey($this->keyManager->getRecoveryKeyId(), $encryptedRecoveryKey); | |||
return true; | |||
} | |||
return false; | |||
} | |||
/** | |||
* @param $recoveryPassword | |||
* @return bool |