Commit 39fc9b90 authored by Shashwat Jolly's avatar Shashwat Jolly
Browse files

Use encryption key for account caching

- Storing encryption key to KWallet
- Passed winId to client state as KWallet requires it
parent 957bb92a
......@@ -65,6 +65,7 @@ target_link_libraries(akonadi_etesync_resource
KF5::KIOCore
KF5::ConfigWidgets
KF5::WindowSystem
KF5::Wallet
KF5::I18n
)
......
......@@ -19,7 +19,7 @@ QString QStringFromCharPtr(const CharPtr &str)
return ret;
}
void saveEtebaseAccountCache(EtebaseAccount *account, const QString &username, const QString &cacheDir)
void saveEtebaseAccountCache(EtebaseAccount *account, const QString &username, const QByteArray &encryptionKey, const QString &cacheDir)
{
if (!account) {
qCDebug(ETESYNC_LOG) << "Unable to save etebase account cache - account is null";
......@@ -27,7 +27,7 @@ void saveEtebaseAccountCache(EtebaseAccount *account, const QString &username, c
}
qCDebug(ETESYNC_LOG) << "Saving cache for account" << username;
CharPtr cacheData(etebase_account_save(account, nullptr, 0));
CharPtr cacheData(etebase_account_save(account, encryptionKey.constData(), encryptionKey.size()));
QString filePath = cacheDir + QStringLiteral("/") + username;
QFile file(filePath);
......@@ -85,7 +85,7 @@ void saveEtebaseItemCache(const EtebaseItemManager *itemManager, const EtebaseIt
file.write(cacheData);
}
EtebaseAccountPtr getEtebaseAccountFromCache(const EtebaseClient *client, const QString &username, const QString &cacheDir)
EtebaseAccountPtr getEtebaseAccountFromCache(const EtebaseClient *client, const QString &username, const QByteArray &encryptionKey, const QString &cacheDir)
{
if (!client) {
qCDebug(ETESYNC_LOG) << "Unable to get account from cache - client is null";
......@@ -110,7 +110,7 @@ EtebaseAccountPtr getEtebaseAccountFromCache(const EtebaseClient *client, const
QByteArray accountCache = accountCacheFile.readAll();
EtebaseAccountPtr etebaseAccount(etebase_account_restore(client, accountCache.constData(), nullptr, 0));
EtebaseAccountPtr etebaseAccount(etebase_account_restore(client, accountCache.constData(), encryptionKey.constData(), encryptionKey.size()));
return etebaseAccount;
}
......
......@@ -98,10 +98,10 @@ using EtebaseCachePtr = std::unique_ptr<void, EtebaseDeleter>;
using CharPtr = std::unique_ptr<char, EtebaseDeleter>;
QString QStringFromCharPtr(const CharPtr &str);
void saveEtebaseAccountCache(EtebaseAccount *account, const QString &username, const QString &cacheDir);
void saveEtebaseAccountCache(EtebaseAccount *account, const QString &username, const QByteArray &encryptionKey, const QString &cacheDir);
void saveEtebaseCollectionCache(const EtebaseCollectionManager *collectionManager, const EtebaseCollection *etesyncCollection, const QString &cacheDir);
void saveEtebaseItemCache(const EtebaseItemManager *itemManager, const EtebaseItem *etesyncItem, const QString &cacheDir);
EtebaseAccountPtr getEtebaseAccountFromCache(const EtebaseClient *client, const QString &username, const QString &cacheDir);
EtebaseAccountPtr getEtebaseAccountFromCache(const EtebaseClient *client, const QString &username, const QByteArray &encryptionKey, const QString &cacheDir);
EtebaseCollectionPtr getEtebaseCollectionFromCache(const EtebaseCollectionManager *collectionManager, const QString &collectionUid, const QString &cacheDir);
EtebaseItemPtr getEtebaseItemFromCache(const EtebaseItemManager *itemManager, const QString &itemUid, const QString &cacheDir);
void deleteCacheFile(const QString &etebaseUid, const QString &cacheDir);
......
......@@ -6,10 +6,19 @@
#include "etesyncclientstate.h"
#include <KWallet/KWallet>
#include <KLocalizedString>
#include "etesync_debug.h"
using namespace KWallet;
static const QString etebaseWalletFolder = QStringLiteral("Akonadi Etebase");
EteSyncClientState::EteSyncClientState(WId winId) : mWinId(winId)
{
}
void EteSyncClientState::init()
{
// Load settings
......@@ -32,7 +41,7 @@ void EteSyncClientState::init()
}
// Load Etebase account from cache
mAccountXXX = getEtebaseAccountFromCache(mClientXXX.get(), mUsername, Settings::self()->cacheDir());
getAccount();
Q_EMIT clientInitialised(true);
}
......@@ -229,3 +238,70 @@ void EteSyncClientState::saveSettings()
Settings::self()->save();
}
void EteSyncClientState::saveAccount()
{
KWallet::Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), mWinId, Wallet::Synchronous);
if (wallet) {
qCDebug(ETESYNC_LOG) << "Wallet opened";
} else {
qCWarning(ETESYNC_LOG) << "Failed to open wallet!";
return;
}
if (!wallet->hasFolder(etebaseWalletFolder) && !wallet->createFolder(etebaseWalletFolder)) {
qCWarning(ETESYNC_LOG) << "Failed to create wallet folder" << etebaseWalletFolder;
return;
}
if (!wallet->setFolder(etebaseWalletFolder)) {
qWarning() << "Failed to open wallet folder" << etebaseWalletFolder;
return;
}
qCDebug(ETESYNC_LOG) << "Wallet opened, writing to" << etebaseWalletFolder;
QByteArray encryptionKey(32, '\0');
etebase_utils_randombytes(encryptionKey.data(), encryptionKey.size());
if (wallet->writeEntry(mUsername, encryptionKey)) {
qCDebug(ETESYNC_LOG) << "Could not store encryption key for account" << mUsername << "in KWallet";
return;
}
qCDebug(ETESYNC_LOG) << "Wrote encryption key to wallet";
saveEtebaseAccountCache(mAccountXXX.get(), mUsername, encryptionKey, Settings::self()->cacheDir());
}
void EteSyncClientState::getAccount()
{
KWallet::Wallet *wallet = Wallet::openWallet(Wallet::NetworkWallet(), mWinId, Wallet::Synchronous);
if (wallet) {
qCDebug(ETESYNC_LOG) << "Wallet opened";
} else {
qCWarning(ETESYNC_LOG) << "Failed to open wallet!";
return;
}
if (!wallet->hasFolder(etebaseWalletFolder)) {
qCWarning(ETESYNC_LOG) << "Wallet does not have folder" << etebaseWalletFolder;
return;
}
if (!wallet->setFolder(etebaseWalletFolder)) {
qWarning() << "Failed to open wallet folder" << etebaseWalletFolder;
return;
}
qCDebug(ETESYNC_LOG) << "Wallet opened, reading" << etebaseWalletFolder;
if (!wallet->entryList().contains(mUsername)) {
qCDebug(ETESYNC_LOG) << "Encryption key for account" << mUsername << "not found in KWallet";
return;
}
QByteArray encryptionKey;
if (wallet->readEntry(mUsername, encryptionKey)) {
qCDebug(ETESYNC_LOG) << "Could not read encryption key for account" << mUsername << "from KWallet";
return;
}
qCDebug(ETESYNC_LOG) << "Read encryption key from wallet";
mAccountXXX = getEtebaseAccountFromCache(mClientXXX.get(), mUsername, encryptionKey, Settings::self()->cacheDir());
}
......@@ -16,7 +16,7 @@ class EteSyncClientState : public QObject
Q_OBJECT
public:
typedef std::unique_ptr<EteSyncClientState> Ptr;
explicit EteSyncClientState() = default;
explicit EteSyncClientState(WId winId);
void init();
bool initToken(const QString &serverUrl, const QString &username, const QString &password);
......@@ -28,6 +28,8 @@ public:
void refreshUserInfo();
bool login(const QString &serverUrl, const QString &username, const QString &password);
bool accountStatus();
void saveAccount();
void getAccount();
EteSync *client() const
{
......@@ -92,6 +94,7 @@ private:
QString mPassword;
QString mServerUrl;
QString mEncryptionPassword;
WId mWinId;
};
#endif // ETESYNCSETTINGS_H
......@@ -58,7 +58,7 @@ EteSyncResource::EteSyncResource(const QString &id)
// Make resource directory
initialiseDirectory(baseDirectoryPath());
mClientState = EteSyncClientState::Ptr(new EteSyncClientState());
mClientState = EteSyncClientState::Ptr(new EteSyncClientState(winIdForDialogs()));
connect(mClientState.get(), &EteSyncClientState::clientInitialised, this, &EteSyncResource::initialiseDone);
mClientState->init();
......@@ -102,7 +102,7 @@ void EteSyncResource::configure(WId windowId)
initialiseDirectory(itemsCacheDirectoryPath());
// Save account cache
saveEtebaseAccountCache(mClientState->account(), mClientState->username(), cacheDirectoryPath());
mClientState->saveAccount();
mCredentialsRequired = false;
qCDebug(ETESYNC_LOG) << "Setting online";
......@@ -342,6 +342,12 @@ void EteSyncResource::retrieveItems(const Akonadi::Collection &collection)
{
qCDebug(ETESYNC_LOG) << "Retrieving items for collection" << collection.remoteId();
if (!mClientState->account()) {
qCDebug(ETESYNC_LOG) << "Cannot retrieve items - account is null";
cancelTask(i18n("Cannot retrieve items - account is null"));
return;
}
EtebaseCollectionManagerPtr collectionManager(etebase_account_get_collection_manager(mClientState->account()));
EtebaseCollectionPtr etesyncCollection = getEtebaseCollectionFromCache(collectionManager.get(), collection.remoteId(), collectionsCacheDirectoryPath());
if (!etesyncCollection) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment