Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid depth infinity propfind for e2ee #2572

Merged
merged 7 commits into from
Oct 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 48 additions & 12 deletions src/libsync/clientsideencryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1241,29 +1241,65 @@ void ClientSideEncryption::getPublicKeyFromServer()
job->start();
}

void ClientSideEncryption::fetchFolderEncryptedStatus() {
_refreshingEncryptionStatus = true;
auto getEncryptedStatus = new GetFolderEncryptStatusJob(_account, QString());
void ClientSideEncryption::scheduleFolderEncryptedStatusJob(const QString &path)
{
auto getEncryptedStatus = new GetFolderEncryptStatusJob(_account, path, this);
connect(getEncryptedStatus, &GetFolderEncryptStatusJob::encryptStatusReceived,
this, &ClientSideEncryption::folderEncryptedStatusFetched);
this, &ClientSideEncryption::folderEncryptedStatusFetched);
connect(getEncryptedStatus, &GetFolderEncryptStatusJob::encryptStatusError,
this, &ClientSideEncryption::folderEncryptedStatusError);
this, &ClientSideEncryption::folderEncryptedStatusError);
getEncryptedStatus->start();

_folderStatusJobs.append(getEncryptedStatus);
}

void ClientSideEncryption::fetchFolderEncryptedStatus()
{
_refreshingEncryptionStatus = true;
_folder2encryptedStatus.clear();
scheduleFolderEncryptedStatusJob(QString());
}

void ClientSideEncryption::folderEncryptedStatusFetched(const QHash<QString, bool>& result)
{
_refreshingEncryptionStatus = false;
_folder2encryptedStatus = result;
qCDebug(lcCse) << "Retrieved correctly the encrypted status of the folders." << result;
emit folderEncryptedStatusFetchDone(result);
auto job = static_cast<GetFolderEncryptStatusJob *>(sender());
Q_ASSERT(job);

_folderStatusJobs.removeAll(job);

qCDebug(lcCse) << "Retrieved correctly the encrypted status of the folders for" << job->folder() << result;

// FIXME: Can be replaced by _folder2encryptedStatus.insert(result); once we depend on Qt 5.15
for (auto it = result.constKeyValueBegin(); it != result.constKeyValueEnd(); ++it) {
_folder2encryptedStatus.insert((*it).first, (*it).second);
}

for (const auto &folder : result.keys()) {
if (folder == job->folder()) {
continue;
}
scheduleFolderEncryptedStatusJob(folder);
}

if (_folderStatusJobs.isEmpty()) {
_refreshingEncryptionStatus = false;
emit folderEncryptedStatusFetchDone(_folder2encryptedStatus);
}
}

void ClientSideEncryption::folderEncryptedStatusError(int error)
{
_refreshingEncryptionStatus = false;
qCDebug(lcCse) << "Failed to retrieve the status of the folders." << error;
emit folderEncryptedStatusFetchDone({});
auto job = static_cast<GetFolderEncryptStatusJob *>(sender());
Q_ASSERT(job);

qCDebug(lcCse) << "Failed to retrieve the status of the folders for" << job->folder() << error;

_folderStatusJobs.removeAll(job);

if (_folderStatusJobs.isEmpty()) {
_refreshingEncryptionStatus = false;
emit folderEncryptedStatusFetchDone(_folder2encryptedStatus);
}
}

FolderMetadata::FolderMetadata(AccountPtr account, const QByteArray& metadata, int statusCode) : _account(account)
Expand Down
4 changes: 4 additions & 0 deletions src/libsync/clientsideencryption.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class ReadPasswordJob;

namespace OCC {

class GetFolderEncryptStatusJob;

QString baseUrl();

namespace EncryptionHelper {
Expand Down Expand Up @@ -109,6 +111,7 @@ private slots:
void folderEncryptedStatusFetchDone(const QHash<QString, bool> &values);

private:
void scheduleFolderEncryptedStatusJob(const QString &path);
void getPrivateKeyFromServer();
void getPublicKeyFromServer();
void decryptPrivateKey(const QByteArray &key);
Expand All @@ -125,6 +128,7 @@ private slots:
//TODO: Save this on disk.
QHash<QByteArray, QByteArray> _folder2token;
QHash<QString, bool> _folder2encryptedStatus;
QVector<GetFolderEncryptStatusJob*> _folderStatusJobs;

public:
//QSslKey _privateKey;
Expand Down
7 changes: 6 additions & 1 deletion src/libsync/clientsideencryptionjobs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,18 @@ GetFolderEncryptStatusJob::GetFolderEncryptStatusJob(const AccountPtr& account,
{
}

QString GetFolderEncryptStatusJob::folder() const
{
return _folder;
}

void GetFolderEncryptStatusJob::start()
{
QNetworkRequest req;
req.setPriority(QNetworkRequest::HighPriority);
req.setRawHeader("OCS-APIREQUEST", "true");
req.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/xml"));
req.setRawHeader("Depth", "infinity");
req.setRawHeader("Depth", "1");

QByteArray xml = R"(<d:propfind xmlns:d="DAV:"> <d:prop xmlns:nc="http://nextcloud.org/ns"> <nc:is-encrypted/> </d:prop> </d:propfind>)";
auto *buf = new QBuffer(this);
Expand Down
2 changes: 2 additions & 0 deletions src/libsync/clientsideencryptionjobs.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ class OWNCLOUDSYNC_EXPORT GetFolderEncryptStatusJob : public AbstractNetworkJob
public:
explicit GetFolderEncryptStatusJob (const AccountPtr &account, const QString& folder, QObject *parent = nullptr);

QString folder() const;

public slots:
void start() override;

Expand Down