From: Kevin Ottens Date: Wed, 17 Jun 2020 17:19:30 +0000 (+0200) Subject: Finally encrypt subdirectories during sync X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~222^2^2~130^2~8 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=f93fdafa80b23b98b47826296bfed3e130181fd5;p=nextcloud-desktop.git Finally encrypt subdirectories during sync We catch when a directory is inside a known encrypted folder and in such a case we now do the following: 1) we encrypt the folder meta data (its name) properly and create it under that mangled name on the server side 2) we mark the new folder itself as encrypted Signed-off-by: Kevin Ottens --- diff --git a/src/libsync/propagateremotemkdir.cpp b/src/libsync/propagateremotemkdir.cpp index 4e5ae7ab4..107cc2831 100644 --- a/src/libsync/propagateremotemkdir.cpp +++ b/src/libsync/propagateremotemkdir.cpp @@ -16,8 +16,10 @@ #include "owncloudpropagator_p.h" #include "account.h" #include "common/syncjournalfilerecord.h" +#include "propagateuploadencrypted.h" #include "propagateremotedelete.h" #include "common/asserts.h" +#include "encryptfolderjob.h" #include #include @@ -36,13 +38,15 @@ void PropagateRemoteMkdir::start() propagator()->_activeJobList.append(this); if (!_deleteExisting) { - return slotStartMkcolJob(); + slotMkdir(); + return; } _job = new DeleteJob(propagator()->account(), propagator()->_remoteFolder + _item->_file, this); - connect(_job, SIGNAL(finishedSignal()), SLOT(slotStartMkcolJob())); + connect(static_cast(_job.data()), &DeleteJob::finishedSignal, + this, &PropagateRemoteMkdir::slotMkdir); _job->start(); } @@ -60,6 +64,28 @@ void PropagateRemoteMkdir::slotStartMkcolJob() _job->start(); } +void PropagateRemoteMkdir::slotStartEncryptedMkcolJob(const QString &path, const QString &filename, quint64 size) +{ + Q_UNUSED(path) + Q_UNUSED(size) + + if (propagator()->_abortRequested.fetchAndAddRelaxed(0)) + return; + + qDebug() << filename; + qCDebug(lcPropagateRemoteMkdir) << filename; + + auto job = new MkColJob(propagator()->account(), + propagator()->_remoteFolder + filename, + this); + connect(job, qOverload(&MkColJob::finished), + _uploadEncryptedHelper, &PropagateUploadEncrypted::unlockFolder); + connect(job, qOverload(&MkColJob::finished), + this, &PropagateRemoteMkdir::slotMkcolJobFinished); + _job = job; + _job->start(); +} + void PropagateRemoteMkdir::abort(PropagatorJob::AbortType abortType) { if (_job && _job->reply()) @@ -75,6 +101,36 @@ void PropagateRemoteMkdir::setDeleteExisting(bool enabled) _deleteExisting = enabled; } +void PropagateRemoteMkdir::slotMkdir() +{ + const auto parentPath = [=]() { + const auto result = propagator()->_remoteFolder; + if (result.startsWith('/')) { + return result.mid(1); + } else { + return result; + } + }(); + const auto path = parentPath + _item->_file; + const auto account = propagator()->account(); + + if (!account->capabilities().clientSideEncryptionAvailable() || + !account->e2e()->isAnyParentFolderEncrypted(path)) { + slotStartMkcolJob(); + return; + } + + // We should be encrypted as well since our parent is + _uploadEncryptedHelper = new PropagateUploadEncrypted(propagator(), _item); + connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::folderNotEncrypted, + this, &PropagateRemoteMkdir::slotStartMkcolJob); + connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::finalized, + this, &PropagateRemoteMkdir::slotStartEncryptedMkcolJob); + connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::error, + []{ qCDebug(lcPropagateRemoteMkdir) << "Error setting up encryption."; }); + _uploadEncryptedHelper->start(); +} + void PropagateRemoteMkdir::slotMkcolJobFinished() { propagator()->_activeJobList.removeOne(this); @@ -121,6 +177,22 @@ void PropagateRemoteMkdir::slotMkcolJobFinished() _job = propfindJob; return; } + + if (!_uploadEncryptedHelper) { + success(); + } else { + // We still need to mark that folder encrypted + propagator()->_activeJobList.append(this); + auto job = new OCC::EncryptFolderJob(propagator()->account(), _job->path(), _item->_fileId, this); + connect(job, &OCC::EncryptFolderJob::finished, this, &PropagateRemoteMkdir::slotEncryptFolderFinished); + job->start(); + } +} + +void PropagateRemoteMkdir::slotEncryptFolderFinished() +{ + qCDebug(lcPropagateRemoteMkdir) << "Success making the new folder encrypted"; + propagator()->_activeJobList.removeOne(this); success(); } diff --git a/src/libsync/propagateremotemkdir.h b/src/libsync/propagateremotemkdir.h index b850e6f2a..469d65bd9 100644 --- a/src/libsync/propagateremotemkdir.h +++ b/src/libsync/propagateremotemkdir.h @@ -18,6 +18,8 @@ namespace OCC { +class PropagateUploadEncrypted; + /** * @brief The PropagateRemoteMkdir class * @ingroup libsync @@ -27,11 +29,13 @@ class PropagateRemoteMkdir : public PropagateItemJob Q_OBJECT QPointer _job; bool _deleteExisting; + PropagateUploadEncrypted *_uploadEncryptedHelper; friend class PropagateDirectory; // So it can access the _item; public: PropagateRemoteMkdir(OwncloudPropagator *propagator, const SyncFileItemPtr &item) : PropagateItemJob(propagator, item) , _deleteExisting(false) + , _uploadEncryptedHelper(nullptr) { } void start() override; @@ -49,8 +53,11 @@ public: void setDeleteExisting(bool enabled); private slots: + void slotMkdir(); void slotStartMkcolJob(); + void slotStartEncryptedMkcolJob(const QString &path, const QString &filename, quint64 size); void slotMkcolJobFinished(); + void slotEncryptFolderFinished(); void propfindResult(const QVariantMap &); void propfindError(); void success();