diff --git a/src/runtime/kwalletd/CMakeLists.txt b/src/runtime/kwalletd/CMakeLists.txt index 918ba5d..fb0b95d 100644 --- a/src/runtime/kwalletd/CMakeLists.txt +++ b/src/runtime/kwalletd/CMakeLists.txt @@ -1,128 +1,118 @@ project(kwalletd5) find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Gui) find_package(KF5Config ${KF5_DEP_VERSION} REQUIRED) find_package(KF5ConfigWidgets ${KF5_DEP_VERSION} REQUIRED) find_package(KF5CoreAddons ${KF5_DEP_VERSION} REQUIRED) find_package(KF5DBusAddons ${KF5_DEP_VERSION} REQUIRED) find_package(KF5IconThemes ${KF5_DEP_VERSION} REQUIRED) find_package(KF5Notifications ${KF5_DEP_VERSION} REQUIRED) find_package(KF5Service ${KF5_DEP_VERSION} REQUIRED) find_package(KF5WidgetsAddons ${KF5_DEP_VERSION} REQUIRED) find_package(KF5WindowSystem ${KF5_DEP_VERSION} REQUIRED) ########### find needed packages ###### find_package(Gpgmepp 1.7.0) # provided by GpgME if (Gpgmepp_FOUND) message("GPG support enabled") add_definitions(-DHAVE_GPGMEPP) add_definitions(-DBOOST_NO_EXCEPTIONS) include_directories(${GPGME_INCLUDES}) endif(Gpgmepp_FOUND) include_directories(${CMAKE_CURRENT_BINARY_DIR}) ########### build backends ######### add_subdirectory(backend) ########### kwalletd ############### include_directories(${CMAKE_CURRENT_SOURCE_DIR}/backend) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../api/KWallet) include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../api/KWallet) remove_definitions(-DQT_NO_CAST_FROM_ASCII) -# migration agent need exceptions enabled -kde_enable_exceptions() - ecm_setup_version(${KF5_VERSION} VARIABLE_PREFIX KWALLETD VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kwalletd_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5WalletConfigVersion.cmake" SOVERSION 5) set(kwalletd_SRCS main.cpp kbetterthankdialog.cpp kwalletd.cpp kwalletwizard.cpp ktimeout.cpp kwalletsessionstore.cpp - migrationagent.cpp - migrationwizard.cpp ) ecm_qt_declare_logging_category(kwalletd_SRCS HEADER kwalletd_debug.h IDENTIFIER KWALLETD_LOG CATEGORY_NAME kf5.kwallet.kwalletd) ki18n_wrap_ui(kwalletd_SRCS kbetterthankdialogbase.ui kwalletwizardpageexplanation.ui kwalletwizardpageintro.ui kwalletwizardpageoptions.ui kwalletwizardpagepassword.ui - migrationwizard1.ui - migrationwizard2.ui ) if (Gpgmepp_FOUND) set(kwalletd_SRCS ${kwalletd_SRCS} knewwalletdialog.cpp ) ki18n_wrap_ui(kwalletd_SRCS kwalletwizardpagepasswordgpg.ui kwalletwizardpagegpgkey.ui knewwalletdialogintro.ui knewwalletdialoggpg.ui ) endif(Gpgmepp_FOUND) set(kwallet_xml ${CMAKE_SOURCE_DIR}/src/api/KWallet/org.kde.KWallet.xml) qt5_add_dbus_adaptor( kwalletd_SRCS ${kwallet_xml} kwalletd.h KWalletD ) -# this is needed for the migration agent -qt5_add_dbus_interface(kwalletd_SRCS ${kwallet_xml} kwallet4_interface) - if(WIN32) configure_file(org.kde.kwalletd5.service.win.in ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kwalletd5.service) else() configure_file(org.kde.kwalletd5.service.in ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kwalletd5.service) endif() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.kwalletd5.service DESTINATION ${DBUS_SERVICES_INSTALL_DIR}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.kwalletd.service DESTINATION ${DBUS_SERVICES_INSTALL_DIR}) add_executable( kwalletd5 ${kwalletd_SRCS} ) target_link_libraries(kwalletd5 kwalletbackend5 KF5Wallet Qt5::Widgets KF5::I18n KF5::CoreAddons KF5::ConfigCore KF5::ConfigWidgets KF5::IconThemes KF5::Service KF5::DBusAddons KF5::WidgetsAddons KF5::WindowSystem KF5::Notifications) if (Gpgmepp_FOUND) target_link_libraries(kwalletd5 Gpgmepp) kde_target_enable_exceptions(kwalletd5 PRIVATE) endif(Gpgmepp_FOUND) install(TARGETS kwalletd5 ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) ########### install files ############### install( FILES kwalletd5.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) install( FILES kwalletd.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR} ) diff --git a/src/runtime/kwalletd/kwalletd.h b/src/runtime/kwalletd/kwalletd.h index 16486dd..0aee7ea 100644 --- a/src/runtime/kwalletd/kwalletd.h +++ b/src/runtime/kwalletd/kwalletd.h @@ -1,252 +1,251 @@ /* This file is part of the KDE libraries Copyright (c) 2002-2004 George Staikos Copyright (c) 2008 Michael Leupold This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _KWALLETD_H_ #define _KWALLETD_H_ #include #include #include #include "kwalletbackend.h" #include #include #include #include #include #include "ktimeout.h" #include "kwalletsessionstore.h" class KDirWatch; class KTimeout; // @Private class KWalletTransaction; class KWalletSessionStore; class KWalletD : public QObject, protected QDBusContext { Q_OBJECT public: KWalletD(); ~KWalletD() override; public Q_SLOTS: // Is the wallet enabled? If not, all open() calls fail. bool isEnabled() const; // Open and unlock the wallet int open(const QString &wallet, qlonglong wId, const QString &appid); // Open and unlock the wallet with this path int openPath(const QString &path, qlonglong wId, const QString &appid); // Open the wallet asynchronously int openAsync(const QString &wallet, qlonglong wId, const QString &appid, bool handleSession); // Open and unlock the wallet with this path asynchronously int openPathAsync(const QString &path, qlonglong wId, const QString &appid, bool handleSession); // Close and lock the wallet // If force = true, will close it for all users. Behave. This // can break applications, and is generally intended for use by // the wallet manager app only. int close(const QString &wallet, bool force); int close(int handle, bool force, const QString &appid); // Save to disk but leave open Q_NOREPLY void sync(int handle, const QString &appid); // Physically deletes the wallet from disk. int deleteWallet(const QString &wallet); // Returns true if the wallet is open bool isOpen(const QString &wallet); bool isOpen(int handle); // List the users of this wallet QStringList users(const QString &wallet) const; // Change the password of this wallet void changePassword(const QString &wallet, qlonglong wId, const QString &appid); // A list of all wallets QStringList wallets() const; // A list of all folders in this wallet QStringList folderList(int handle, const QString &appid); // Does this wallet have this folder? bool hasFolder(int handle, const QString &folder, const QString &appid); // Create this folder bool createFolder(int handle, const QString &folder, const QString &appid); // Remove this folder bool removeFolder(int handle, const QString &folder, const QString &appid); // List of entries in this folder QStringList entryList(int handle, const QString &folder, const QString &appid); // Read an entry. If the entry does not exist, it just // returns an empty result. It is your responsibility to check // hasEntry() first. QByteArray readEntry(int handle, const QString &folder, const QString &key, const QString &appid); QByteArray readMap(int handle, const QString &folder, const QString &key, const QString &appid); QString readPassword(int handle, const QString &folder, const QString &key, const QString &appid); QVariantMap readEntryList(int handle, const QString &folder, const QString &key, const QString &appid); QVariantMap readMapList(int handle, const QString &folder, const QString &key, const QString &appid); QVariantMap readPasswordList(int handle, const QString &folder, const QString &key, const QString &appid); // Rename an entry. rc=0 on success. int renameEntry(int handle, const QString &folder, const QString &oldName, const QString &newName, const QString &appid); // Write an entry. rc=0 on success. int writeEntry(int handle, const QString &folder, const QString &key, const QByteArray &value, int entryType, const QString &appid); int writeEntry(int handle, const QString &folder, const QString &key, const QByteArray &value, const QString &appid); int writeMap(int handle, const QString &folder, const QString &key, const QByteArray &value, const QString &appid); int writePassword(int handle, const QString &folder, const QString &key, const QString &value, const QString &appid); // Does the entry exist? bool hasEntry(int handle, const QString &folder, const QString &key, const QString &appid); // What type is the entry? int entryType(int handle, const QString &folder, const QString &key, const QString &appid); // Remove an entry. rc=0 on success. int removeEntry(int handle, const QString &folder, const QString &key, const QString &appid); // Disconnect an app from a wallet bool disconnectApplication(const QString &wallet, const QString &application); void reconfigure(); // Determine bool folderDoesNotExist(const QString &wallet, const QString &folder); bool keyDoesNotExist(const QString &wallet, const QString &folder, const QString &key); void closeAllWallets(); QString networkWallet(); QString localWallet(); void screenSaverChanged(bool); // Open a wallet using a pre-hashed password. This is only useful in cooperation // with the kwallet PAM module. It's also less secure than manually entering the // password as the password hash is transmitted using D-Bus. int pamOpen(const QString &wallet, const QByteArray &passwordHash, int sessionTimeout); Q_SIGNALS: void walletAsyncOpened(int id, int handle); // used to notify KWallet::Wallet void walletListDirty(); void walletCreated(const QString &wallet); void walletOpened(const QString &wallet); void walletDeleted(const QString &wallet); void walletClosed(const QString &wallet); void walletClosed(int handle); void allWalletsClosed(); void folderListUpdated(const QString &wallet); void folderUpdated(const QString &, const QString &); void applicationDisconnected(const QString &wallet, const QString &application); private Q_SLOTS: void slotServiceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner); void emitWalletListDirty(); void timedOutClose(int handle); void timedOutSync(int handle); void notifyFailures(); void processTransactions(); void activatePasswordDialog(); void registerKWalletd4Service(); #ifdef Q_WS_X11 void connectToScreenSaver(); #endif private: - friend class MigrationAgent; // Internal - open a wallet int internalOpen(const QString &appid, const QString &wallet, bool isPath, WId w, bool modal, const QString &service); // Internal - close this wallet. int internalClose(KWallet::Backend * const w, const int handle, const bool force, const bool saveBeforeClose = true); bool isAuthorizedApp(const QString &appid, const QString &wallet, WId w); // This also validates the handle. May return NULL. KWallet::Backend *getWallet(const QString &appid, int handle); // Generate a new unique handle. int generateHandle(); // Emit signals about closing wallets void doCloseSignals(int, const QString &); void emitFolderUpdated(const QString &, const QString &); // Implicitly allow access for this application bool implicitAllow(const QString &wallet, const QString &app); bool implicitDeny(const QString &wallet, const QString &app); void doTransactionChangePassword(const QString &appid, const QString &wallet, qlonglong wId); void doTransactionOpenCancelled(const QString &appid, const QString &wallet, const QString &service); int doTransactionOpen(const QString &appid, const QString &wallet, bool isPath, qlonglong wId, bool modal, const QString &service); void initiateSync(int handle); void setupDialog(QWidget *dialog, WId wId, const QString &appid, bool modal); void checkActiveDialog(); QPair findWallet(const QString &walletName) const; typedef QHash Wallets; Wallets _wallets; KDirWatch *_dw; int _failed; // configuration values bool _leaveOpen, _closeIdle, _launchManager, _enabled; bool _openPrompt, _firstUse, _showingFailureNotify; int _idleTime; QMap _implicitAllowMap, _implicitDenyMap; KTimeout _closeTimers; KTimeout _syncTimers; const int _syncTime; static bool _processing; KWalletTransaction *_curtrans; // current transaction QList _transactions; QPointer< QWidget > activeDialog; #ifdef Q_WS_X11 QDBusInterface *screensaver; #endif // sessions KWalletSessionStore _sessions; QDBusServiceWatcher _serviceWatcher; bool _useGpg; }; #endif diff --git a/src/runtime/kwalletd/main.cpp b/src/runtime/kwalletd/main.cpp index c91cf67..5edf89e 100644 --- a/src/runtime/kwalletd/main.cpp +++ b/src/runtime/kwalletd/main.cpp @@ -1,233 +1,230 @@ /** * This file is part of the KDE project * Copyright (C) 2008 Michael Leupold * Copyright (C) 2014 Alex Fiestas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kwalletd_debug.h" #include #include #include #include #include #include #include #include #include #include "backend/kwalletbackend.h" //For the hash size #include "kwalletd.h" #include "kwalletd_version.h" -#include "migrationagent.h" #ifndef Q_OS_WIN #include #include #include #include #define BSIZE 1000 static int pipefd = 0; static int socketfd = 0; #endif static bool isWalletEnabled() { KConfig cfg(QStringLiteral("kwalletrc")); KConfigGroup walletGroup(&cfg, "Wallet"); return walletGroup.readEntry("Enabled", true); } #ifndef Q_OS_WIN //Waits until the PAM_MODULE sends the hash static char *waitForHash() { printf("kwalletd5: Waiting for hash on %d-\n", pipefd); int totalRead = 0; int readBytes = 0; int attempts = 0; char *buf = (char*)malloc(sizeof(char) * PBKDF2_SHA512_KEYSIZE); memset(buf, '\0', PBKDF2_SHA512_KEYSIZE); while(totalRead != PBKDF2_SHA512_KEYSIZE) { readBytes = read(pipefd, buf + totalRead, PBKDF2_SHA512_KEYSIZE - totalRead); if (readBytes == -1 || attempts > 5) { free(buf); return nullptr; } totalRead += readBytes; ++attempts; } close(pipefd); return buf; } //Waits until startkde sends the environment variables static int waitForEnvironment() { printf("kwalletd5: waitingForEnvironment on: %d\n", socketfd); int s2; struct sockaddr_un remote; socklen_t t = sizeof(remote); if ((s2 = accept(socketfd, (struct sockaddr *)&remote, &t)) == -1) { fprintf(stdout, "kwalletd5: Couldn't accept incoming connection\n"); return -1; } printf("kwalletd5: client connected\n"); char str[BSIZE] = {'\0'}; int chop = 0; FILE *s3 = fdopen(dup(s2), "r"); while(!feof(s3)) { if (fgets(str, BSIZE, s3)) { chop = strlen(str) - 1; if (str[chop] == '\n') { str[chop] = '\0'; } putenv(strdup(str)); } } fclose(s3); printf("kwalletd5: client disconnected\n"); close(socketfd); return 1; } char* checkPamModule(int argc, char **argv) { printf("kwalletd5: Checking for pam module\n"); char *hash = nullptr; int x = 1; for (; x < argc; ++x) { if (strcmp(argv[x], "--pam-login") != 0) { continue; } printf("kwalletd5: Got pam-login param\n"); argv[x] = nullptr; x++; //We need at least 2 extra arguments after --pam-login if (x + 1 > argc) { printf("kwalletd5: Invalid arguments (less than needed)\n"); return nullptr; } //first socket for the hash, comes from a pipe pipefd = atoi(argv[x]); argv[x] = nullptr; x++; //second socket for environment, comes from a localsocket socketfd = atoi(argv[x]); argv[x] = nullptr; break; } if (!pipefd || !socketfd) { printf("Lacking a socket, pipe: %d, env:%d\n", pipefd, socketfd); return nullptr; } hash = waitForHash(); if (hash == nullptr || waitForEnvironment() == -1) { printf("kwalletd5: Hash or environment not received\n"); free(hash); return nullptr; } return hash; } #endif #ifdef HAVE_KF5INIT extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv) #else int main(int argc, char **argv) #endif { char *hash = nullptr; #ifndef Q_OS_WIN if (getenv("PAM_KWALLET5_LOGIN")) { hash = checkPamModule(argc, argv); } #endif QApplication app(argc, argv); // this kwalletd5 program should be able to start with KDE4's kwalletd // using kwalletd name would prevent KDBusService unique instance to initialize // so we setApplicationName("kwalletd5") app.setApplicationName(QStringLiteral("kwalletd5")); app.setApplicationDisplayName(i18n("KDE Wallet Service")); app.setOrganizationDomain(QStringLiteral("kde.org")); app.setApplicationVersion(KWALLETD_VERSION_STRING); KAboutData aboutdata(I18N_NOOP("kwalletd"), i18n("KDE Wallet Service"), KWALLETD_VERSION_STRING, i18n("KDE Wallet Service"), KAboutLicense::LGPL, i18n("(C) 2002-2013, The KDE Developers")); aboutdata.addAuthor(i18n("Valentin Rusu"), i18n("Maintainer, GPG backend support"), QStringLiteral("kde@rusu.info")); aboutdata.addAuthor(i18n("Michael Leupold"), i18n("Former Maintainer"), QStringLiteral("lemma@confuego.org")); aboutdata.addAuthor(i18n("George Staikos"), i18n("Former maintainer"), QStringLiteral("staikos@kde.org")); aboutdata.addAuthor(i18n("Thiago Maceira"), i18n("D-Bus Interface"), QStringLiteral("thiago@kde.org")); KDBusService dbusUniqueInstance(KDBusService::Unique); - KWalletD walletd; - MigrationAgent migrationAgent(&walletd, hash); - // NOTE: the command should be parsed only after KDBusService instantiation QCommandLineParser cmdParser; aboutdata.setupCommandLine(&cmdParser); cmdParser.process(app); aboutdata.setProgramIconName(QStringLiteral("kwalletmanager")); app.setQuitOnLastWindowClosed(false); auto disableSessionManagement = [](QSessionManager &sm) { sm.setRestartHint(QSessionManager::RestartNever); }; QObject::connect(&app, &QGuiApplication::commitDataRequest, disableSessionManagement); QObject::connect(&app, &QGuiApplication::saveStateRequest, disableSessionManagement); // check if kwallet is disabled if (!isWalletEnabled()) { qCDebug(KWALLETD_LOG) << "kwalletd is disabled!"; return (0); } qCDebug(KWALLETD_LOG) << "kwalletd5 started"; #ifndef Q_OS_WIN if (hash) { + KWalletD walletd; QByteArray passHash(hash, PBKDF2_SHA512_KEYSIZE); int wallet = walletd.pamOpen(KWallet::Wallet::LocalWallet(), passHash, 0); if (wallet < 0) { qWarning() << "Wallet failed to get opened by PAM, error code is" << wallet; } else { qCDebug(KWALLETD_LOG) << "Wallet opened by PAM"; } free(hash); } #endif return app.exec(); } diff --git a/src/runtime/kwalletd/migrationagent.cpp b/src/runtime/kwalletd/migrationagent.cpp deleted file mode 100644 index 8ad3cf8..0000000 --- a/src/runtime/kwalletd/migrationagent.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - This file is part of the KDE Frameworks - - Copyright (c) 2014 Valentin Rusu - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ - -#include "migrationagent.h" -#include "kwalletd_debug.h" -#include "migrationwizard.h" -#include "kwalletd.h" - -#include -#include -#include -#include - -#include -#include - -#define SERVICE_KWALLETD4 "org.kde.kwalletd" -#define ENTRY_ALREADY_MIGRATED "alreadyMigrated" -#define ENTRY_SHOW_MIGRATION_WIZARD "showMigrationWizard" - -MigrationAgent::MigrationAgent(KWalletD* kd, const char *hash) : - _kf5_daemon(kd) - , _kde4_daemon(nullptr) - , _pam_hash(hash) -{ - connect(this, &MigrationAgent::migrationFinished, _kf5_daemon, &KWalletD::registerKWalletd4Service); - if (isAlreadyMigrated()) { - qCDebug(KWALLETD_LOG) << "old wallets were already migrated"; - emit migrationFinished(); - } else { - QTimer::singleShot(100, this, SLOT(migrateWallets())); - } -} - -void MigrationAgent::migrateWallets() -{ - // the migration is done in several steps : - // is the setting "alreadyMigrated" present and true ? - // if yes, then stop here - // if not, then is kwalletd present (the daemon from KDE4) ? - // if not, then stop here - // if yes, then start the migration wizard - // if the migration wizard returns without error - // create "alreadyMigrated=true" setting - qCDebug(KWALLETD_LOG) << "Migration agent starting..."; - if (connectOldDaemon()) { - if (!isEmptyOldWallet()) { - if (isMigrationWizardOk()) { - setAlreadyMigrated(); - emit migrationFinished(); - } else { - qCDebug(KWALLETD_LOG) << "Migration wizard returned an error or has been canceled. The migration agent will resume upon next daemon start"; - } - } else { - qCDebug(KWALLETD_LOG) << "Old wallet is empty. No need to migrate."; - setAlreadyMigrated(); - emit migrationFinished(); - } - } else { - qCDebug(KWALLETD_LOG) << "KDE4 kwalletd not present, stopping migration agent"; - emit migrationFinished(); - } - qCDebug(KWALLETD_LOG) << "Migration agent stop."; -} - -bool MigrationAgent::isAlreadyMigrated() -{ - KConfig kwalletrc(QStringLiteral("kwalletrc")); - KConfigGroup cfg(&kwalletrc, "Migration"); - return cfg.readEntry(ENTRY_ALREADY_MIGRATED, false); -} - -void MigrationAgent::setAlreadyMigrated() -{ - KConfig kwalletrc(QStringLiteral("kwalletrc")); - KConfigGroup cfg(&kwalletrc, "Migration"); - cfg.writeEntry(ENTRY_ALREADY_MIGRATED, true); -} - -bool MigrationAgent::connectOldDaemon() -{ - // the old daemon may not have been started, so attempt start it - // NOTE we provide a "fake" org.kde.kwalletd.service file - see the project structure - // however, this thing is a HACK as we cannot tell here, in KF5, user's KDE4 install prefix - // the provided .service file assumes /usr/bin - QDBusConnectionInterface *bus = QDBusConnection::sessionBus().interface(); - if (!bus->isServiceRegistered(QStringLiteral(SERVICE_KWALLETD4))) { - qCDebug(KWALLETD_LOG) << "kwalletd not started. Attempting start..."; - QDBusReply reply = bus->startService(SERVICE_KWALLETD4); - if (!reply.isValid()) { - qCDebug(KWALLETD_LOG) << "Couldn't start kwalletd: " << reply.error(); - return false; - } - if (!bus->isServiceRegistered(QStringLiteral(SERVICE_KWALLETD4))) { - qCDebug(KWALLETD_LOG) << "The kwalletd service is still not registered after start attemtp. Aborting migration"; - return false; - } else { - qCDebug(KWALLETD_LOG) << "The kwalletd service has been registered"; - } - } - - _kde4_daemon = new org::kde::KWallet(QStringLiteral(SERVICE_KWALLETD4), QStringLiteral("/modules/kwalletd"), QDBusConnection::sessionBus()); - return _kde4_daemon->isValid(); -} - -bool MigrationAgent::isMigrationWizardOk() -{ - bool ok = false; - - // The migration wizard would no longer been shown by default. - // see BUG 351056 - // NOTE if user wants to show the migration wizard, then he should add the - // following setting to the kwalletrc: - // [Migration] - // showMigrationWizard=true - KConfig kwalletrc(QStringLiteral("kwalletrc")); - KConfigGroup cfg(&kwalletrc, "Migration"); - bool showMigrationWizard = cfg.readEntry(ENTRY_SHOW_MIGRATION_WIZARD, false); - - if (showMigrationWizard) { - MigrationWizard *wizard = new MigrationWizard(this); - int result = wizard->exec(); - if (QDialog::Accepted == result) { - // the user either migrated the wallets, or choose not to be prompted again - ok = true; - } - } else { - if (performMigration(0, true)) { - ok = true; - } else { - qCDebug(KWALLETD_LOG) << "Migration failed."; - } - } - - return ok; -} - -void MigrationAgent::emitProgressMessage(const QString &msg) -{ - emit progressMessage(msg); -} - -class MigrationException { - public: MigrationException(const QString &msg): _msg(msg) {} - QString _msg; -}; - -template R invokeAndCheck(MigrationAgent *migrationAgent, F f, QString errorMsg) { - QDBusPendingReply reply = f(); - reply.waitForFinished(); - QApplication::processEvents(); // keep UI responsive to show progress messages - if (!reply.isValid()) { - migrationAgent->emitProgressMessage(errorMsg); - throw MigrationException(errorMsg); - } - return reply.value(); -} - -bool MigrationAgent::isEmptyOldWallet() const { - QStringList wallets; - try { - wallets = invokeAndCheck( - const_cast(this), [this] { return _kde4_daemon->wallets(); }, - i18n("Cannot read old wallet list. Aborting.")); - } catch (MigrationException ex) { - return true; - } - - return wallets.length() == 0; -} - -bool MigrationAgent::performMigration(WId wid, bool withoutWizard) -{ - auto appId = i18n("KDE Wallet Migration Agent"); - try { - QStringList wallets = invokeAndCheck( - this, [this] { return _kde4_daemon->wallets(); }, - i18n("Cannot read old wallet list. Aborting.")); - - for (const QString &wallet : qAsConst(wallets)) { - emit progressMessage(i18n("Migrating wallet: %1", wallet)); - emit progressMessage(i18n("* Creating KF5 wallet: %1", wallet)); - - int handle5 = -1; - if (withoutWizard && (_pam_hash != nullptr)) { - // see BUG 351056 for why this hacky code - // If the user has several wallets, all the values will be - // merged into the single LocalWallet - handle5 = _kf5_daemon->pamOpen(KWallet::Wallet::LocalWallet(), _pam_hash, 0); - } else { - handle5 = _kf5_daemon->internalOpen(appId, wallet, false, 0, true, QString()); - } - if (handle5 <0) { - emit progressMessage(i18n("ERROR when attempting new wallet creation. Aborting.")); - return false; - } - - int handle4 = invokeAndCheck( - this, [this, wallet, wid, appId] { return _kde4_daemon->open(wallet, wid, appId); }, - i18n("Cannot open KDE4 wallet named: %1", wallet)); - emit progressMessage(i18n("* Opened KDE4 wallet: %1", wallet)); - - const QStringList folders = invokeAndCheck( - this, [this, handle4, appId] { return _kde4_daemon->folderList(handle4, appId); }, - i18n("Cannot retrieve folder list. Aborting.")); - - for (const QString &folder : folders) { - emit progressMessage(i18n("* Migrating folder %1", folder)); - - const QStringList entries = invokeAndCheck( - this, [this, handle4, folder, appId] { return _kde4_daemon->entryList(handle4, folder, appId); }, - i18n("Cannot retrieve folder %1 entries. Aborting.", folder)); - - for (const QString &key : entries) { - - int entryType = invokeAndCheck( - this, [this, handle4, folder, key, appId] { return _kde4_daemon->entryType(handle4, folder, key, appId); }, - i18n("Cannot retrieve key %1 info. Aborting.", key)); - - // handle the case where the entries are already there - if (_kf5_daemon->hasEntry(handle5, folder, key, appId)) { - emit progressMessage(i18n("* SKIPPING entry %1 in folder %2 as it seems already migrated", key, folder)); - } else { - QByteArray entry = invokeAndCheck( - this, [this, handle4, folder, key, appId] { return _kde4_daemon->readEntry(handle4, folder, key, appId); }, - i18n("Cannot retrieve key %1 data. Aborting.", key)); - if ( _kf5_daemon->writeEntry(handle5, folder, key, entry, entryType, appId) != 0 ) { - auto msg = i18n("Cannot write entry %1 in the new wallet. Aborting.", key); - emit progressMessage(msg); - throw MigrationException(msg); - } - } - } - } - - //_kde4_daemon->close(handle4, false, appId); - //_kf5_daemon->close(handle5, true, appId); - _kf5_daemon->sync(handle5, appId); - emit progressMessage(i18n("DONE migrating wallet\n")); - } - } catch (MigrationException ex) { - return false; - } - return true; -} - diff --git a/src/runtime/kwalletd/migrationagent.h b/src/runtime/kwalletd/migrationagent.h deleted file mode 100644 index 9c974a0..0000000 --- a/src/runtime/kwalletd/migrationagent.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - This file is part of the KDE Frameworks - - Copyright (c) 2014 Valentin Rusu - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - -*/ -#ifndef _MIGRATIONAGENT_H_ -#define _MIGRATIONAGENT_H_ - -#include - -#include - -class KWalletD; - - -class MigrationAgent : public QObject { - Q_OBJECT -public: - MigrationAgent(KWalletD* kd, const char* hash); - - bool isEmptyOldWallet() const; - bool performMigration(WId wid, bool withoutWizard); - -private Q_SLOTS: - void migrateWallets(); - bool isAlreadyMigrated(); - bool connectOldDaemon(); - bool isMigrationWizardOk(); - void setAlreadyMigrated(); -public Q_SLOTS: - void emitProgressMessage(const QString &); - -Q_SIGNALS: - void progressMessage(const QString &); - void migrationFinished(); - -private: - KWalletD *_kf5_daemon; - org::kde::KWallet *_kde4_daemon; - const char *_pam_hash; -}; - -#endif // _MIGRATIONAGENT_H_ diff --git a/src/runtime/kwalletd/migrationwizard.cpp b/src/runtime/kwalletd/migrationwizard.cpp deleted file mode 100644 index 972dcf0..0000000 --- a/src/runtime/kwalletd/migrationwizard.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of the KDE Frameworks - * - * Copyright (c) 2014 Valentin Rusu - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "migrationwizard.h" -#include "ui_migrationwizard1.h" -#include "ui_migrationwizard2.h" -#include "migrationagent.h" - -class MigrationPage1 : public QWizardPage { -public: - MigrationPage1(QWidget *wizard) - : QWizardPage(wizard) - { - _ui.setupUi(this); - connect(_ui._optionNo, SIGNAL(toggled(bool)), wizard, SLOT(page1Updated())); - connect(_ui._optionNotInterested, SIGNAL(toggled(bool)), wizard, SLOT(page1Updated())); - connect(_ui._optionYes, SIGNAL(toggled(bool)), wizard, SLOT(page1Updated())); - connect(_ui._optionNo, &QRadioButton::toggled, this, &QWizardPage::completeChanged); - } - - bool isComplete() const override { - return !_ui._optionNo->isChecked(); - } - - Ui::MigrationPage1 _ui; -}; - -class MigrationPage2 : public QWizardPage { -public: - MigrationPage2(MigrationWizard* wizard) - : QWizardPage(wizard) - , _agent(wizard->agent()) - , _migrationCompleted(false) - { - _ui.setupUi(this); - } - - void initializePage() override { - connect(_agent, SIGNAL(progressMessage(QString)), _ui._report, SLOT(append(QString))); - _migrationCompleted = _agent->performMigration(winId(), false); - emit completeChanged(); - } - - bool isComplete() const override { - return _migrationCompleted; - } - - Ui::MigrationPage2 _ui; - MigrationAgent *_agent; - bool _migrationCompleted; -}; - -MigrationPage1 *page1 = nullptr; -MigrationPage2 *page2 = nullptr; - -MigrationWizard::MigrationWizard(MigrationAgent *agent) - : _agent(agent) -{ - setOption(HaveFinishButtonOnEarlyPages); - page1 = new MigrationPage1(this); - addPage(page1); - - page2 = new MigrationPage2(this); - addPage(page2); -} - -MigrationWizard::~MigrationWizard() -{ - delete page1; - delete page2; -} - -void MigrationWizard::page1Updated() -{ - if (page1->_ui._optionYes->isChecked()) { - page1->setFinalPage(false); - button(NextButton)->setEnabled(true); - } - if (page1->_ui._optionNo->isChecked()) { - page1->setFinalPage(true); - button(NextButton)->setEnabled(false); - } - if (page1->_ui._optionNotInterested->isChecked()) { - page1->setFinalPage(true); - button(NextButton)->setEnabled(false); - } -} - - diff --git a/src/runtime/kwalletd/migrationwizard.h b/src/runtime/kwalletd/migrationwizard.h deleted file mode 100644 index 8796997..0000000 --- a/src/runtime/kwalletd/migrationwizard.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the KDE Frameworks - * - * Copyright (c) 2014 Valentin Rusu - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef _MIGRATIONWIZARD_H_ -#define _MIGRATIONWIZARD_H_ - -#include - -class MigrationAgent; - -class MigrationWizard : public QWizard { - Q_OBJECT -public: - explicit MigrationWizard(MigrationAgent *agent); - ~MigrationWizard() override; - - MigrationAgent *agent() const { return _agent; } - -public Q_SLOTS: - void page1Updated(); - -private: - MigrationAgent *_agent; -}; - -#endif // _MIGRATIONWIZARD_H_ diff --git a/src/runtime/kwalletd/migrationwizard1.ui b/src/runtime/kwalletd/migrationwizard1.ui deleted file mode 100644 index 0c2c33a..0000000 --- a/src/runtime/kwalletd/migrationwizard1.ui +++ /dev/null @@ -1,122 +0,0 @@ - - - MigrationPage1 - - - - 0 - 0 - 523 - 377 - - - - - - - The KDE Wallet System - - - - - - - Congratulations! The system detected that you're running the latest version of the KWallet, using KDE Frameworks 5. - -It seems that you also have KDE4 wallet(s) on your system. - -Would you like them to be migrated to this new KWallet version? The operation will only take one minute to be performed. - - - - true - - - true - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - &Yes, migrate my wallets now. - - - true - - - - - - - No, I'd rather do this upon ne&xt session start, -and I'll cancel this wizard for now. - - - - - - - No, and p&lease do not prompt me again. - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - Qt::Vertical - - - - 20 - 102 - - - - - - - - - KTitleWidget - QWidget -
ktitlewidget.h
-
-
- - -
diff --git a/src/runtime/kwalletd/migrationwizard2.ui b/src/runtime/kwalletd/migrationwizard2.ui deleted file mode 100644 index f9a7650..0000000 --- a/src/runtime/kwalletd/migrationwizard2.ui +++ /dev/null @@ -1,51 +0,0 @@ - - - MigrationPage2 - - - - 0 - 0 - 521 - 377 - - - - - - - The KDE Wallet System - - - - - - - QTextEdit::AutoBulletList - - - true - - - false - - - true - - - Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - - KTitleWidget - QWidget -
ktitlewidget.h
-
-
- - -
diff --git a/src/runtime/kwalletd/org.kde.kwalletd.service b/src/runtime/kwalletd/org.kde.kwalletd.service deleted file mode 100644 index f3c0a38..0000000 --- a/src/runtime/kwalletd/org.kde.kwalletd.service +++ /dev/null @@ -1,6 +0,0 @@ -# this installs an activatable service for the legacy, KDE4, kwalletd -# NOTE this file assumes the kwalletd daemon is installed in the usual /usr/bin directory -# that is because we have no means here, in KF5, to know about the KDE4 prefix -[D-BUS Service] -Name=org.kde.kwalletd -Exec=/usr/bin/kwalletd