This commit is contained in:
brantje 2017-01-02 22:06:55 +01:00
Родитель b05137b93f
Коммит 3f4afba34f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5FF1D117F918687F
9 изменённых файлов: 146 добавлений и 94 удалений

Просмотреть файл

@ -33,8 +33,7 @@ class VaultController extends ApiController {
$UserId,
VaultService $vaultService,
CredentialService $credentialService,
SettingsService $settings,
EncryptService $encryptService) {
SettingsService $settings) {
parent::__construct(
$AppName,
$request,

Просмотреть файл

@ -29,6 +29,7 @@ use OCP\AppFramework\Db\Mapper;
class CredentialMapper extends Mapper {
private $utils;
public function __construct(IDBConnection $db, Utils $utils) {
parent::__construct($db, 'passman_credentials');
$this->utils = $utils;
@ -37,6 +38,7 @@ class CredentialMapper extends Mapper {
/**
* Obtains the credentials by vault id (not guid)
*
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
* @return Credential[]
@ -49,6 +51,7 @@ class CredentialMapper extends Mapper {
/**
* Get a random credentail from a vault
*
* @param $vault_id
* @param $user_id
* @return Credential
@ -57,58 +60,62 @@ class CredentialMapper extends Mapper {
$sql = 'SELECT * FROM `*PREFIX*passman_credentials` ' .
'WHERE `user_id` = ? and vault_id = ? AND shared_key is NULL LIMIT 20';
$entities = $this->findEntities($sql, [$user_id, $vault_id]);
$count = count($entities)-1;
$count = count($entities) - 1;
$entities = array_splice($entities, rand(0, $count), 1);
return $entities;
}
/**
* Get expired credentials
*
* @param $timestamp
* @return Credential[]
*/
public function getExpiredCredentials($timestamp){
public function getExpiredCredentials($timestamp) {
$sql = 'SELECT * FROM `*PREFIX*passman_credentials` ' .
'WHERE `expire_time` > 0 AND `expire_time` < ?';
return $this->findEntities($sql, [$timestamp]);
}
/**
/**
* Get an credential by id.
* Optional user id
* @param $credential_id
* @param null $user_id
* @return Credential
*/
public function getCredentialById($credential_id, $user_id = null){
*
* @param $credential_id
* @param null $user_id
* @return Credential
*/
public function getCredentialById($credential_id, $user_id = null) {
$sql = 'SELECT * FROM `*PREFIX*passman_credentials` ' .
'WHERE `id` = ?';
// If we want to check the owner, add it to the query
// If we want to check the owner, add it to the query
$params = [$credential_id];
if ($user_id !== null){
$sql .= ' and `user_id` = ? ';
if ($user_id !== null) {
$sql .= ' and `user_id` = ? ';
array_push($params, $user_id);
}
return $this->findEntity($sql,$params);
return $this->findEntity($sql, $params);
}
/**
* Get credential label by id
*
* @param $credential_id
* @return Credential
*/
public function getCredentialLabelById($credential_id){
public function getCredentialLabelById($credential_id) {
$sql = 'SELECT id, label FROM `*PREFIX*passman_credentials` ' .
'WHERE `id` = ? ';
return $this->findEntity($sql,[$credential_id]);
return $this->findEntity($sql, [$credential_id]);
}
/**
* Save credential to the database.
*
* @param $raw_credential
* @return Credential
*/
public function create($raw_credential){
public function create($raw_credential) {
$credential = new Credential();
$credential->setGuid($this->utils->GUID());
@ -131,7 +138,7 @@ class CredentialMapper extends Mapper {
$credential->setCustomFields($raw_credential['custom_fields']);
$credential->setOtp($raw_credential['otp']);
$credential->setHidden($raw_credential['hidden']);
if(isset($raw_credential['shared_key'])) {
if (isset($raw_credential['shared_key'])) {
$credential->setSharedKey($raw_credential['shared_key']);
}
return parent::insert($credential);
@ -139,10 +146,11 @@ class CredentialMapper extends Mapper {
/**
* Update a credential
*
* @param $raw_credential array An array containing all the credential fields
* @return Credential The updated credential
*/
public function updateCredential($raw_credential){
public function updateCredential($raw_credential) {
$original = $this->getCredentialByGUID($raw_credential['guid']);
$credential = new Credential();
$credential->setId($original->getId());
@ -166,32 +174,33 @@ class CredentialMapper extends Mapper {
$credential->setOtp($raw_credential['otp']);
$credential->setHidden($raw_credential['hidden']);
$credential->setDeleteTime($raw_credential['delete_time']);
if(isset($raw_credential['shared_key'])) {
if (isset($raw_credential['shared_key'])) {
$credential->setSharedKey($raw_credential['shared_key']);
}
return parent::update($credential);
}
public function deleteCredential(Credential $credential){
public function deleteCredential(Credential $credential) {
return $this->delete($credential);
}
public function upd(Credential $credential){
public function upd(Credential $credential) {
$this->update($credential);
}
/**
* Finds a credential by the given guid
* @param $credential_guid
* @return Credential
*/
public function getCredentialByGUID($credential_guid, $user_id = null){
$q = 'SELECT * FROM `*PREFIX*passman_credentials` WHERE guid = ? ';
/**
* Finds a credential by the given guid
*
* @param $credential_guid
* @return Credential
*/
public function getCredentialByGUID($credential_guid, $user_id = null) {
$q = 'SELECT * FROM `*PREFIX*passman_credentials` WHERE guid = ? ';
$params = [$credential_guid];
if ($user_id !== null){
if ($user_id !== null) {
$q .= ' and `user_id` = ? ';
array_push($params, $user_id);
}
return $this->findEntity($q, $params);
}
return $this->findEntity($q, $params);
}
}

Просмотреть файл

@ -44,6 +44,7 @@ class CredentialRevisionService {
/**
* Create a new revision for a credential
*
* @param $credential
* @param $userId
* @param $credential_id
@ -57,13 +58,14 @@ class CredentialRevisionService {
/**
* Get revisions of a credential
*
* @param $credential_id
* @param null $user_id
* @return CredentialRevision[]
*/
public function getRevisions($credential_id, $user_id = null){
public function getRevisions($credential_id, $user_id = null) {
$result = $this->credentialRevisionMapper->getRevisions($credential_id, $user_id);
foreach ($result as $index => $revision){
foreach ($result as $index => $revision) {
$c = json_decode(base64_decode($revision->getCredentialData()), true);
$result[$index] = $revision->jsonSerialize();
$result[$index]['credential_data'] = $this->encryptService->decryptCredential($c);
@ -77,7 +79,7 @@ class CredentialRevisionService {
* @param null $user_id
* @return CredentialRevision
*/
public function getRevision($credential_id, $user_id = null){
public function getRevision($credential_id, $user_id = null) {
$revision = $this->credentialRevisionMapper->getRevision($credential_id, $user_id);
$c = json_decode(base64_decode($revision->getCredentialData()), true);
$revision->setCredentialData($this->encryptService->decryptCredential($c));
@ -86,20 +88,22 @@ class CredentialRevisionService {
/**
* Delete a revision
*
* @param $revision_id
* @param $user_id
* @return CredentialRevision
*/
public function deleteRevision($revision_id, $user_id){
public function deleteRevision($revision_id, $user_id) {
return $this->credentialRevisionMapper->deleteRevision($revision_id, $user_id);
}
/**
* Update revision
*
* @param CredentialRevision $credentialRevision
* @return CredentialRevision
*/
public function updateRevision(CredentialRevision $credentialRevision){
public function updateRevision(CredentialRevision $credentialRevision) {
$credential_data = $credentialRevision->getCredentialData();
$credential_data = json_decode(base64_decode($credential_data), true);
$credential_data = base64_encode(json_encode($this->encryptService->encryptCredential($credential_data)));

Просмотреть файл

@ -50,8 +50,7 @@ class CredentialService {
/**
* Create a new credential
*
* @param $user_id
* @param $item_guid
* @param array $credential
* @return Credential
*/
public function createCredential($credential) {
@ -152,8 +151,6 @@ class CredentialService {
if ($acl->hasPermission(SharingACL::READ)) {
return $this->encryptService->decryptCredential($credential);
}
throw new DoesNotExistException("Did expect one result but found none when executing");
}
}

Просмотреть файл

@ -293,6 +293,23 @@ class EncryptService {
return $this->handleCredential($credential, 'encrypt');
}
private function extractKeysFromCredential($credential){
$userKey = '';
$userSuppliedKey = '';
if ($credential instanceof Credential) {
$userSuppliedKey = $credential->getLabel();
$sk = $credential->getSharedKey();
$userKey = (isset($sk)) ? $sk : $credential->getUserId();
}
if (is_array($credential)) {
$userSuppliedKey = $credential['label'];
$userKey = (isset($credential['shared_key'])) ? $credential['shared_key'] : $credential['user_id'];
}
return array($userKey, $userSuppliedKey);
}
/**
* Handles the encryption / decryption of a credential
*
@ -302,27 +319,22 @@ class EncryptService {
*/
private function handleCredential($credential, $op) {
$service_function = ($op === 'encrypt') ? 'encrypt' : 'decrypt';
if ($credential instanceof Credential) {
$userSuppliedKey = $credential->getLabel();
$sk = $credential->getSharedKey();
$userKey = (isset($sk)) ? $sk : $credential->getUserId();
} else {
$userSuppliedKey = $credential['label'];
$userKey = (isset($credential['shared_key'])) ? $credential['shared_key'] : $credential['user_id'];
}
$key = EncryptService::makeKey($userKey, $this->server_key, $userSuppliedKey);
list($userKey, $userSuppliedKey) = $this->extractKeysFromCredential($credential);
$key = EncryptService::makeKey($userKey, $this->server_key, $userSuppliedKey);
foreach ($this->encrypted_credential_fields as $field) {
if ($credential instanceof Credential) {
$field = str_replace(' ', '', str_replace('_', ' ', ucwords($field, '_')));
$set = 'set' . $field;
$get = 'get' . $field;
$credential->{$set}($this->{$service_function}($credential->{$get}(), $key));
} else {
}
if (is_array($credential)) {
$credential[$field] = $this->{$service_function}($credential[$field], $key);
}
}
return $credential;
}
@ -355,12 +367,16 @@ class EncryptService {
* @return File|array
* @throws \Exception
*/
private function handleFile($file, $op){
private function handleFile($file, $op) {
$service_function = ($op === 'encrypt') ? 'encrypt' : 'decrypt';
$userKey = '';
$userSuppliedKey = '';
if ($file instanceof File) {
$userSuppliedKey = $file->getSize();
$userKey = md5($file->getMimetype());
} else {
}
if (is_array($file)) {
$userSuppliedKey = $file['size'];
$userKey = md5($file['mimetype']);
}
@ -371,10 +387,13 @@ class EncryptService {
if ($file instanceof File) {
$file->setFilename($this->{$service_function}($file->getFilename(), $key));
$file->setFileData($this->{$service_function}($file->getFileData(), $key));
} else {
}
if (is_array($file)) {
$file['filename'] = $this->{$service_function}($file['filename'], $key);
$file['file_data'] = $this->{$service_function}($file['file_data'], $key);
}
return $file;
}
}

Просмотреть файл

@ -42,12 +42,13 @@ class ShareService {
private $encryptService;
private $server_key;
public function __construct(
SharingACLMapper $sharingACL,
ShareRequestMapper $shareRequest,
CredentialMapper $credentials,
CredentialRevisionService $revisions,
EncryptService $encryptService
EncryptService $encryptService
) {
$this->sharingACL = $sharingACL;
$this->shareRequest = $shareRequest;
@ -159,6 +160,7 @@ class ShareService {
/**
* Gets the acl for a given item guid
*
* @param $user_id
* @param $item_guid
* @return SharingACL
@ -200,31 +202,33 @@ class ShareService {
}
/**
* Deletes a share request by the item ID
* @param ShareRequest $request
* @return \PDOStatement
*/
/**
* Deletes a share request by the item ID
*
* @param ShareRequest $request
* @return \PDOStatement
*/
public function cleanItemRequestsForUser(ShareRequest $request) {
return $this->shareRequest->cleanItemRequestsForUser($request->getItemId(), $request->getTargetUserId());
}
/**
* Get an share request by id
* @param $id
* @return ShareRequest
*/
/**
* Get an share request by id
*
* @param $id
* @return ShareRequest
*/
public function getShareRequestById($id) {
return $this->shareRequest->getShareRequestById($id);
}
/**
* Get an share request by $item_guid and $target_vault_guid
*
* @param $item_guid
* @param $target_vault_guid
* @return ShareRequest
*/
/**
* Get an share request by $item_guid and $target_vault_guid
*
* @param $item_guid
* @param $target_vault_guid
* @return ShareRequest
*/
public function getRequestByGuid($item_guid, $target_vault_guid) {
return $this->shareRequest->getRequestByItemAndVaultGuid($item_guid, $target_vault_guid);
}
@ -284,11 +288,12 @@ class ShareService {
return $this->sharingACL->deleteShareACL($ACL);
}
/**
* Updates the given ACL entry
* @param SharingACL $sharingACL
* @return SharingACL
*/
/**
* Updates the given ACL entry
*
* @param SharingACL $sharingACL
* @return SharingACL
*/
public function updateCredentialACL(SharingACL $sharingACL) {
return $this->sharingACL->updateCredentialACL($sharingACL);
}
@ -309,7 +314,7 @@ class ShareService {
}
public function updatePendingShareRequestsForCredential($item_guid, $user_id, $permissions){
return $this->shareRequest->updatePendingRequestPermissions($item_guid, $user_id, $permissions);
}
public function updatePendingShareRequestsForCredential($item_guid, $user_id, $permissions) {
return $this->shareRequest->updatePendingRequestPermissions($item_guid, $user_id, $permissions);
}
}

Просмотреть файл

@ -24,6 +24,7 @@
namespace OCA\Passman\Migration;
use OCA\Passman\Db\CredentialRevision;
use OCA\Passman\Db\File;
use OCA\Passman\Service\CredentialRevisionService;
use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\EncryptService;
@ -36,7 +37,7 @@ use OCP\Migration\IRepairStep;
class ServerSideEncryption implements IRepairStep {
/** @var encryptService */
/** @var EncryptService */
private $encryptService;
/** @var IDBConnection */
@ -73,6 +74,8 @@ class ServerSideEncryption implements IRepairStep {
}
public function run(IOutput $output) {
$output->info('Enabling Service Side Encryption for passman');
if (version_compare($this->installedVersion, '2.0.0RC4', '<')) {
$this->encryptCredentials();
$this->encryptRevisions();
@ -80,15 +83,19 @@ class ServerSideEncryption implements IRepairStep {
}
}
private function fetchAll($sql){
return $this->db->executeQuery($sql)->fetchAll();
}
private function encryptCredentials() {
$credentials = $this->db->executeQuery('SELECT * FROM `*PREFIX*passman_credentials`')->fetchAll();
$credentials = $this->fetchAll('SELECT * FROM `*PREFIX*passman_credentials`');
foreach ($credentials as $credential) {
$this->credentialService->updateCredential($credential);
}
}
private function encryptRevisions() {
$revisions = $this->db->executeQuery('SELECT * FROM `*PREFIX*passman_revisions`')->fetchAll();
$revisions = $this->fetchAll('SELECT * FROM `*PREFIX*passman_revisions`');
foreach ($revisions as $_revision) {
$revision = new CredentialRevision();
$revision->setId($_revision['id']);
@ -97,14 +104,23 @@ class ServerSideEncryption implements IRepairStep {
$revision->setUserId($_revision['user_id']);
$revision->setCreated($_revision['created']);
$revision->setEditedBy($_revision['edited_by']);
$revision->setCredentialData( $_revision['credential_data']);
$revision->setCredentialData($_revision['credential_data']);
$this->revisionService->updateRevision($revision);
}
}
private function encryptFiles() {
$files = $this->db->executeQuery('SELECT * FROM `*PREFIX*passman_files`')->fetchAll();
foreach ($files as $file) {
$files = $this->fetchAll('SELECT * FROM `*PREFIX*passman_files`');
foreach ($files as $_file) {
$file = new File();
$file->setId($_file['id']);
$file->setGuid($_file['guid']);
$file->setUserId($_file['user_id']);
$file->setMimetype($_file['minetype']);
$file->setFilename($_file['filename']);
$file->setSize($_file['size']);
$file->setCreated($_file['created']);
$file->setFileData($_file['file_data']);
$this->fileService->updateFile($file);
}
}

Просмотреть файл

@ -31,7 +31,7 @@ $ciphers = openssl_get_cipher_methods();
<h2><?php p($l->t('Passman Settings')); ?></h2>
<?php
if ($checkVersion) {
p($l->t('Github version:'). ' '. $githubVersion);
p($l->t('Github version:') . ' ' . $githubVersion);
print '<br />';
} ?>
Local version: <?php p($localVersion); ?><br/>
@ -53,7 +53,7 @@ $ciphers = openssl_get_cipher_methods();
<p>
<input type="checkbox" name="passman_sharing_enabled"
id="passman_sharing_enabled" class="checkbox"
value="1" />
value="1"/>
<label for="passman_sharing_enabled">
<?php p($l->t('Allow users on this server to share passwords with other users')); ?>
</label>
@ -102,12 +102,13 @@ $ciphers = openssl_get_cipher_methods();
</p>
<p>
<label for="server_side_encryption">Server side encryption method:</label>
<label for="server_side_encryption">Server side encryption
method:</label>
<select name="server_side_encryption2" id="server_side_encryption2">
<?php
foreach ($ciphers as $cipher){
print '<option value="'. $cipher .'">'. $cipher .'</option>';
}
foreach ($ciphers as $cipher) {
print '<option value="' . $cipher . '">' . $cipher . '</option>';
}
?>
</select> (Not working atm. OpenSSL has no equivalent of <code>mcrypt_get_key_size()</code>)
</p>

Просмотреть файл

@ -24,6 +24,7 @@
namespace OCA\Passman\Controller;
use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\SettingsService;
use OCA\Passman\Service\VaultService;
use PHPUnit_Framework_TestCase;
@ -46,9 +47,10 @@ class VaultControllerTest extends PHPUnit_Framework_TestCase {
$request = $this->getMockBuilder('OCP\IRequest')->getMock();
$this->vaultService = $this->createMock(VaultService::class);
$this->credentialService = $this->createMock(CredentialService::class);
$this->settingsService = $this->createMock(SettingsService::class);
$this->controller = new VaultController(
'passman', $request, $this->userId, $this->vaultService, $this->credentialService
'passman', $request, $this->userId, $this->vaultService, $this->credentialService, $this->settingsService
);
}