summaryrefslogtreecommitdiffstats
path: root/kio/misc/kwalletd/kwalletd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kio/misc/kwalletd/kwalletd.cpp')
-rw-r--r--kio/misc/kwalletd/kwalletd.cpp1514
1 files changed, 0 insertions, 1514 deletions
diff --git a/kio/misc/kwalletd/kwalletd.cpp b/kio/misc/kwalletd/kwalletd.cpp
deleted file mode 100644
index eca13c463..000000000
--- a/kio/misc/kwalletd/kwalletd.cpp
+++ /dev/null
@@ -1,1514 +0,0 @@
-/*
- This file is part of the KDE libraries
-
- Copyright (c) 2002-2004 George Staikos <staikos@kde.org>
-
- 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 "kbetterthankdialogbase.h"
-#include "kwalletwizard.h"
-#include "kwalletd.h"
-#include "ktimeout.h"
-
-#include <dcopclient.h>
-#include <dcopref.h>
-#include <kactivelabel.h>
-#include <kapplication.h>
-#include <kconfig.h>
-#include <kdebug.h>
-#include <kdirwatch.h>
-#include <kglobal.h>
-#include <klocale.h>
-#include <kmessagebox.h>
-#include <kpassdlg.h>
-#include <kstandarddirs.h>
-#include <kwalletentry.h>
-#include <twin.h>
-
-#include <tqdir.h>
-#include <tqlabel.h>
-#include <tqlayout.h>
-#include <tqpushbutton.h>
-#include <tqregexp.h>
-#include <tqstylesheet.h>
-#include <tqvbox.h>
-
-#include <assert.h>
-
-extern "C" {
- KDE_EXPORT KDEDModule *create_kwalletd(const TQCString &name) {
- return new KWalletD(name);
- }
-}
-
-
-class KWalletTransaction {
- public:
- KWalletTransaction() {
- tType = Unknown;
- transaction = 0L;
- client = 0L;
- modal = false;
- }
-
- ~KWalletTransaction() {
- // Don't delete these!
- transaction = 0L;
- client = 0L;
- }
-
- enum Type { Unknown, Open, ChangePassword, OpenFail };
- DCOPClient *client;
- DCOPClientTransaction *transaction;
- Type tType;
- TQCString rawappid, returnObject;
- TQCString appid;
- uint wId;
- TQString wallet;
- bool modal;
-};
-
-
-KWalletD::KWalletD(const TQCString &name)
-: KDEDModule(name), _failed(0) {
- srand(time(0));
- _showingFailureNotify = false;
- _transactions.setAutoDelete(true);
- _timeouts = new KTimeout(17);
- _closeIdle = false;
- _idleTime = 0;
- connect(_timeouts, TQT_SIGNAL(timedOut(int)), this, TQT_SLOT(timedOut(int)));
- reconfigure();
- KGlobal::dirs()->addResourceType("kwallet", "share/apps/kwallet");
- connect(KApplication::dcopClient(),
- TQT_SIGNAL(applicationRemoved(const TQCString&)),
- this,
- TQT_SLOT(slotAppUnregistered(const TQCString&)));
- _dw = new KDirWatch(this, "KWallet Directory Watcher");
- _dw->addDir(KGlobal::dirs()->saveLocation("kwallet"));
- _dw->startScan(true);
- connect(_dw, TQT_SIGNAL(dirty(const TQString&)), this, TQT_SLOT(emitWalletListDirty()));
-}
-
-
-KWalletD::~KWalletD() {
- delete _timeouts;
- _timeouts = 0;
-
- closeAllWallets();
- _transactions.clear();
-}
-
-
-int KWalletD::generateHandle() {
- int rc;
-
- // ASSUMPTION: RAND_MAX is fairly large.
- do {
- rc = rand();
- } while (_wallets.find(rc) || rc == 0);
-
- return rc;
-}
-
-
-void KWalletD::processTransactions() {
- static bool processing = false;
-
- if (processing) {
- return;
- }
-
- processing = true;
-
- // Process remaining transactions
- KWalletTransaction *xact;
- while (!_transactions.isEmpty()) {
- xact = _transactions.first();
- TQCString replyType;
- int res;
-
- assert(xact->tType != KWalletTransaction::Unknown);
-
- switch (xact->tType) {
- case KWalletTransaction::Open:
- res = doTransactionOpen(xact->appid, xact->wallet, xact->wId, xact->modal);
- replyType = "int";
- if (!xact->returnObject.isEmpty()) {
- DCOPRef(xact->rawappid, xact->returnObject).send("walletOpenResult", res);
- }
-
- // multiple requests from the same client
- // should not produce multiple password
- // dialogs on a failure
- if (res < 0) {
- TQPtrListIterator<KWalletTransaction> it(_transactions);
- KWalletTransaction *x;
- while ((x = it.current()) && x != xact) {
- ++it;
- }
- if (x) {
- ++it;
- }
- while ((x = it.current())) {
- if (xact->appid == x->appid && x->tType == KWalletTransaction::Open && x->wallet == xact->wallet && x->wId == xact->wId) {
- x->tType = KWalletTransaction::OpenFail;
- }
- ++it;
- }
- }
- break;
- case KWalletTransaction::OpenFail:
- res = -1;
- replyType = "int";
- if (!xact->returnObject.isEmpty()) {
- DCOPRef(xact->rawappid, xact->returnObject).send("walletOpenResult", res);
- }
- break;
- case KWalletTransaction::ChangePassword:
- doTransactionChangePassword(xact->appid, xact->wallet, xact->wId);
- // fall through - no return
- default:
- _transactions.removeRef(xact);
- continue;
- }
-
- if (xact->returnObject.isEmpty() && xact->tType != KWalletTransaction::ChangePassword) {
- TQByteArray replyData;
- TQDataStream stream(replyData, IO_WriteOnly);
- stream << res;
- xact->client->endTransaction(xact->transaction, replyType, replyData);
- }
- _transactions.removeRef(xact);
- }
-
- processing = false;
-}
-
-
-void KWalletD::openAsynchronous(const TQString& wallet, const TQCString& returnObject, uint wId) {
- DCOPClient *dc = callingDcopClient();
- if (!dc) {
- return;
- }
-
- TQCString appid = dc->senderId();
- if (!_enabled ||
- !TQRegExp("^[A-Za-z0-9]+[A-Za-z0-9\\s\\-_]*$").exactMatch(wallet)) {
- DCOPRef(appid, returnObject).send("walletOpenResult", -1);
- return;
- }
-
- TQCString peerName = friendlyDCOPPeerName();
-
- KWalletTransaction *xact = new KWalletTransaction;
-
- xact->appid = peerName;
- xact->rawappid = appid;
- xact->client = callingDcopClient();
- xact->wallet = wallet;
- xact->wId = wId;
- xact->tType = KWalletTransaction::Open;
- xact->returnObject = returnObject;
- _transactions.append(xact);
-
- DCOPRef(appid, returnObject).send("walletOpenResult", 0);
-
- TQTimer::singleShot(0, this, TQT_SLOT(processTransactions()));
- checkActiveDialog();
-}
-
-
-int KWalletD::openPath(const TQString& path, uint wId) {
- if (!_enabled) { // guard
- return -1;
- }
-
- // FIXME: setup transaction
- int rc = internalOpen(friendlyDCOPPeerName(), path, true, wId);
- return rc;
-}
-
-
-int KWalletD::open(const TQString& wallet, uint wId) {
- if (!_enabled) { // guard
- return -1;
- }
-
- if (!TQRegExp("^[A-Za-z0-9]+[A-Za-z0-9\\s\\-_]*$").exactMatch(wallet)) {
- return -1;
- }
-
- TQCString appid = friendlyDCOPPeerName();
-
- KWalletTransaction *xact = new KWalletTransaction;
- _transactions.append(xact);
-
- xact->appid = appid;
- xact->client = callingDcopClient();
- xact->transaction = xact->client->beginTransaction();
- xact->wallet = wallet;
- xact->wId = wId;
- xact->tType = KWalletTransaction::Open;
- xact->modal = true; // mark dialogs as modal, the app has blocking wait
- TQTimer::singleShot(0, this, TQT_SLOT(processTransactions()));
- checkActiveDialog();
- return 0; // process later
-}
-
-
-// Sets up a dialog that will be shown by kwallet.
-void KWalletD::setupDialog( TQWidget* dialog, WId wId, const TQCString& appid, bool modal ) {
- if( wId != 0 )
- KWin::setMainWindow( dialog, wId ); // correct, set dialog parent
- else {
- if( appid.isEmpty())
- kdWarning() << "Using kwallet without parent window!" << endl;
- else
- kdWarning() << "Application '" << appid << "' using kwallet without parent window!" << endl;
- // allow dialog activation even if it interrupts, better than trying hacks
- // with keeping the dialog on top or on all desktops
- kapp->updateUserTimestamp();
- }
- if( modal )
- KWin::setState( dialog->winId(), NET::Modal );
- else
- KWin::clearState( dialog->winId(), NET::Modal );
- activeDialog = dialog;
-}
-
-// If there's a dialog already open and another application tries some operation that'd lead to
-// opening a dialog, that application will be blocked by this dialog. A proper solution would
-// be to set the second application's window also as a parent for the active dialog, so that
-// KWin properly handles focus changes and so on, but there's currently no support for multiple
-// dialog parents. Hopefully to be done in KDE4, for now just use all kinds of bad hacks to make
-// sure the user doesn't overlook the active dialog.
-void KWalletD::checkActiveDialog() {
- if( !activeDialog || !activeDialog->isShown())
- return;
- kapp->updateUserTimestamp();
- KWin::setState( activeDialog->winId(), NET::KeepAbove );
- KWin::setOnAllDesktops( activeDialog->winId(), true );
- KWin::forceActiveWindow( activeDialog->winId());
-}
-
-int KWalletD::doTransactionOpen(const TQCString& appid, const TQString& wallet, uint wId, bool modal) {
- if (_firstUse && !wallets().contains(KWallet::Wallet::LocalWallet())) {
- // First use wizard
- KWalletWizard *wiz = new KWalletWizard(0);
- setupDialog( wiz, wId, appid, modal );
- int rc = wiz->exec();
- if (rc == TQDialog::Accepted) {
- KConfig cfg("kwalletrc");
- cfg.setGroup("Wallet");
- cfg.writeEntry("First Use", false);
- cfg.writeEntry("Enabled", wiz->_useWallet->isChecked());
- cfg.writeEntry("Close When Idle", wiz->_closeIdle->isChecked());
- cfg.writeEntry("Use One Wallet", !wiz->_networkWallet->isChecked());
- cfg.sync();
- reconfigure();
-
- if (!wiz->_useWallet->isChecked()) {
- delete wiz;
- return -1;
- }
-
- // Create the wallet
- KWallet::Backend *b = new KWallet::Backend(KWallet::Wallet::LocalWallet());
- TQByteArray p;
- p.duplicate(wiz->_pass1->text().utf8(), wiz->_pass1->text().length());
- b->open(p);
- b->createFolder(KWallet::Wallet::PasswordFolder());
- b->createFolder(KWallet::Wallet::FormDataFolder());
- b->close(p);
- p.fill(0);
- delete b;
- delete wiz;
- } else {
- delete wiz;
- return -1;
- }
- } else if (_firstUse) {
- KConfig cfg("kwalletrc");
- _firstUse = false;
- cfg.setGroup("Wallet");
- cfg.writeEntry("First Use", false);
- cfg.sync();
- }
-
- int rc = internalOpen(appid, wallet, false, wId, modal);
- return rc;
-}
-
-int KWalletD::tryOpen(const TQString& wallet, const TQCString& password)
-{
- if (isOpen(wallet))
- return 0;
-
- if (_tryOpenBlocked.isActive()) {
- kdDebug() << "tryOpen is active.." << endl;
- return -1;
- }
-
- if (!KWallet::Backend::exists(wallet))
- return -2;
-
- KWallet::Backend *b = new KWallet::Backend(wallet, false /*isPath*/);
- int rc = b->open(TQByteArray().duplicate(password, strlen(password)));
- if (rc == 0) {
- _wallets.insert(rc = generateHandle(), b);
- _passwords[wallet] = password;
- b->ref();
- _tryOpenBlocked.stop();
- TQByteArray data;
- TQDataStream ds(data, IO_WriteOnly);
- ds << wallet;
- emitDCOPSignal("walletOpened(TQString)", data);
- }
- else {
- delete b;
- // make sure that we're not bombed with a dictionary attack
- _tryOpenBlocked.start (30 * 1000, true /*single shot*/);
- if (++_failed > 5) {
- _failed = 0;
- TQTimer::singleShot(0, this, TQT_SLOT(notifyFailures()));
- }
-
- rc = -1;
- }
- return rc;
-}
-
-int KWalletD::internalOpen(const TQCString& appid, const TQString& wallet, bool isPath, WId w, bool modal) {
- int rc = -1;
- bool brandNew = false;
-
- TQCString thisApp;
- if (appid.isEmpty()) {
- thisApp = "TDE System";
- } else {
- thisApp = appid;
- }
-
- if (implicitDeny(wallet, thisApp)) {
- return -1;
- }
-
- for (TQIntDictIterator<KWallet::Backend> i(_wallets); i.current(); ++i) {
- if (i.current()->walletName() == wallet) {
- rc = i.currentKey();
- break;
- }
- }
-
- if (rc == -1) {
- if (_wallets.count() > 20) {
- kdDebug() << "Too many wallets open." << endl;
- return -1;
- }
-
- KWallet::Backend *b = new KWallet::Backend(wallet, isPath);
- KPasswordDialog *kpd = 0L;
- bool emptyPass = false;
- if ((isPath && TQFile::exists(wallet)) || (!isPath && KWallet::Backend::exists(wallet))) {
- int pwless = b->open(TQByteArray());
- if (0 != pwless || !b->isOpen()) {
- if (pwless == 0) {
- // release, start anew
- delete b;
- b = new KWallet::Backend(wallet, isPath);
- }
- kpd = new KPasswordDialog(KPasswordDialog::Password, false, 0);
- if (appid.isEmpty()) {
- kpd->setPrompt(i18n("<qt>TDE has requested to open the wallet '<b>%1</b>'. Please enter the password for this wallet below.").arg(TQStyleSheet::escape(wallet)));
- } else {
- kpd->setPrompt(i18n("<qt>The application '<b>%1</b>' has requested to open the wallet '<b>%2</b>'. Please enter the password for this wallet below.").arg(TQStyleSheet::escape(appid)).arg(TQStyleSheet::escape(wallet)));
- }
- brandNew = false;
- kpd->setButtonOK(KGuiItem(i18n("&Open"),"fileopen"));
- } else {
- emptyPass = true;
- }
- } else if (wallet == KWallet::Wallet::LocalWallet() ||
- wallet == KWallet::Wallet::NetworkWallet()) {
- // Auto create these wallets.
- kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0);
- if (appid.isEmpty()) {
- kpd->setPrompt(i18n("TDE has requested to open the wallet. This is used to store sensitive data in a secure fashion. Please enter a password to use with this wallet or click cancel to deny the application's request."));
- } else {
- kpd->setPrompt(i18n("<qt>The application '<b>%1</b>' has requested to open the TDE wallet. This is used to store sensitive data in a secure fashion. Please enter a password to use with this wallet or click cancel to deny the application's request.").arg(TQStyleSheet::escape(appid)));
- }
- brandNew = true;
- kpd->setButtonOK(KGuiItem(i18n("&Open"),"fileopen"));
- } else {
- kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0);
- if (appid.length() == 0) {
- kpd->setPrompt(i18n("<qt>TDE has requested to create a new wallet named '<b>%1</b>'. Please choose a password for this wallet, or cancel to deny the application's request.").arg(TQStyleSheet::escape(wallet)));
- } else {
- kpd->setPrompt(i18n("<qt>The application '<b>%1</b>' has requested to create a new wallet named '<b>%2</b>'. Please choose a password for this wallet, or cancel to deny the application's request.").arg(TQStyleSheet::escape(appid)).arg(TQStyleSheet::escape(wallet)));
- }
- brandNew = true;
- kpd->setButtonOK(KGuiItem(i18n("C&reate"),"filenew"));
- }
-
- if (kpd) {
- kpd->setCaption(i18n("TDE Wallet Service"));
- kpd->setAllowEmptyPasswords(true);
- }
-
- const char *p = 0L;
- while (!b->isOpen()) {
- assert(kpd); // kpd can't be null if isOpen() is false
- setupDialog( kpd, w, appid, modal );
- if (kpd->exec() == KDialog::Accepted) {
- p = kpd->password();
- int rc = b->open(TQByteArray().duplicate(p, strlen(p)));
- if (!b->isOpen()) {
- kpd->setPrompt(i18n("<qt>Error opening the wallet '<b>%1</b>'. Please try again.<br>(Error code %2: %3)").arg(TQStyleSheet::escape(wallet)).arg(rc).arg(KWallet::Backend::openRCToString(rc)));
- kpd->clearPassword();
- }
- } else {
- break;
- }
- }
-
- if (!emptyPass && (!p || !b->isOpen())) {
- delete b;
- delete kpd;
- return -1;
- }
-
- if (emptyPass && _openPrompt && !isAuthorizedApp(appid, wallet, w)) {
- delete b;
- delete kpd;
- return -1;
- }
-
- _wallets.insert(rc = generateHandle(), b);
- if (emptyPass) {
- _passwords[wallet] = "";
- } else {
- _passwords[wallet] = p;
- }
- _handles[appid].append(rc);
-
- delete kpd; // don't refactor this!! Argh I hate KPassDlg
-
- if (brandNew) {
- createFolder(rc, KWallet::Wallet::PasswordFolder());
- createFolder(rc, KWallet::Wallet::FormDataFolder());
- }
-
- b->ref();
- if (_closeIdle && _timeouts) {
- _timeouts->addTimer(rc, _idleTime);
- }
- TQByteArray data;
- TQDataStream ds(data, IO_WriteOnly);
- ds << wallet;
- if (brandNew) {
- emitDCOPSignal("walletCreated(TQString)", data);
- }
- emitDCOPSignal("walletOpened(TQString)", data);
- if (_wallets.count() == 1 && _launchManager) {
- KApplication::startServiceByDesktopName("kwalletmanager-kwalletd");
- }
- } else {
- if (!_handles[appid].contains(rc) && _openPrompt && !isAuthorizedApp(appid, wallet, w)) {
- return -1;
- }
- _handles[appid].append(rc);
- _wallets.find(rc)->ref();
- }
-
- return rc;
-}
-
-
-bool KWalletD::isAuthorizedApp(const TQCString& appid, const TQString& wallet, WId w) {
- int response = 0;
-
- TQCString thisApp;
- if (appid.isEmpty()) {
- thisApp = "TDE System";
- } else {
- thisApp = appid;
- }
-
- if (!implicitAllow(wallet, thisApp)) {
- KBetterThanKDialogBase *dialog = new KBetterThanKDialogBase;
- if (appid.isEmpty()) {
- dialog->setLabel(i18n("<qt>TDE has requested access to the open wallet '<b>%1</b>'.").arg(TQStyleSheet::escape(wallet)));
- } else {
- dialog->setLabel(i18n("<qt>The application '<b>%1</b>' has requested access to the open wallet '<b>%2</b>'.").arg(TQStyleSheet::escape(TQString(appid))).arg(TQStyleSheet::escape(wallet)));
- }
- setupDialog( dialog, w, appid, false );
- response = dialog->exec();
- delete dialog;
- }
-
- if (response == 0 || response == 1) {
- if (response == 1) {
- KConfig cfg("kwalletrc");
- cfg.setGroup("Auto Allow");
- TQStringList apps = cfg.readListEntry(wallet);
- if (!apps.contains(thisApp)) {
- apps += thisApp;
- _implicitAllowMap[wallet] += thisApp;
- cfg.writeEntry(wallet, apps);
- cfg.sync();
- }
- }
- } else if (response == 3) {
- KConfig cfg("kwalletrc");
- cfg.setGroup("Auto Deny");
- TQStringList apps = cfg.readListEntry(wallet);
- if (!apps.contains(thisApp)) {
- apps += thisApp;
- _implicitDenyMap[wallet] += thisApp;
- cfg.writeEntry(wallet, apps);
- cfg.sync();
- }
- return false;
- } else {
- return false;
- }
- return true;
-}
-
-
-int KWalletD::deleteWallet(const TQString& wallet) {
- TQString path = KGlobal::dirs()->saveLocation("kwallet") + TQDir::separator() + wallet + ".kwl";
-
- if (TQFile::exists(path)) {
- close(wallet, true);
- TQFile::remove(path);
- TQByteArray data;
- TQDataStream ds(data, IO_WriteOnly);
- ds << wallet;
- emitDCOPSignal("walletDeleted(TQString)", data);
- return 0;
- }
-
- return -1;
-}
-
-
-void KWalletD::changePassword(const TQString& wallet, uint wId) {
- TQCString appid = friendlyDCOPPeerName();
-
- KWalletTransaction *xact = new KWalletTransaction;
-
- xact->appid = appid;
- xact->client = callingDcopClient();
- xact->wallet = wallet;
- xact->wId = wId;
- xact->tType = KWalletTransaction::ChangePassword;
-
- _transactions.append(xact);
-
- TQTimer::singleShot(0, this, TQT_SLOT(processTransactions()));
- checkActiveDialog();
-}
-
-
-void KWalletD::doTransactionChangePassword(const TQCString& appid, const TQString& wallet, uint wId) {
- TQIntDictIterator<KWallet::Backend> it(_wallets);
- KWallet::Backend *w = 0L;
- int handle = -1;
- bool reclose = false;
-
- for (; it.current(); ++it) {
- if (it.current()->walletName() == wallet) {
- break;
- }
- }
-
- if (!it.current()) {
- handle = doTransactionOpen(appid, wallet, wId,false);
- if (-1 == handle) {
- KMessageBox::sorryWId(wId, i18n("Unable to open wallet. The wallet must be opened in order to change the password."), i18n("TDE Wallet Service"));
- return;
- }
-
- w = _wallets.find(handle);
- reclose = true;
- } else {
- handle = it.currentKey();
- w = it.current();
- }
-
- assert(w);
-
- KPasswordDialog *kpd;
- kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0);
- kpd->setPrompt(i18n("<qt>Please choose a new password for the wallet '<b>%1</b>'.").arg(TQStyleSheet::escape(wallet)));
- kpd->setCaption(i18n("TDE Wallet Service"));
- kpd->setAllowEmptyPasswords(true);
- setupDialog( kpd, wId, appid, false );
- if (kpd->exec() == KDialog::Accepted) {
- const char *p = kpd->password();
- if (p) {
- _passwords[wallet] = p;
- TQByteArray pa;
- pa.duplicate(p, strlen(p));
- int rc = w->close(pa);
- if (rc < 0) {
- KMessageBox::sorryWId(wId, i18n("Error re-encrypting the wallet. Password was not changed."), i18n("TDE Wallet Service"));
- reclose = true;
- } else {
- rc = w->open(pa);
- if (rc < 0) {
- KMessageBox::sorryWId(wId, i18n("Error reopening the wallet. Data may be lost."), i18n("TDE Wallet Service"));
- reclose = true;
- }
- }
- }
- }
-
- delete kpd;
-
- if (reclose) {
- close(handle, true);
- }
-}
-
-
-int KWalletD::close(const TQString& wallet, bool force) {
- int handle = -1;
- KWallet::Backend *w = 0L;
-
- for (TQIntDictIterator<KWallet::Backend> it(_wallets);
- it.current();
- ++it) {
- if (it.current()->walletName() == wallet) {
- handle = it.currentKey();
- w = it.current();
- break;
- }
- }
-
- return closeWallet(w, handle, force);
-}
-
-
-int KWalletD::closeWallet(KWallet::Backend *w, int handle, bool force) {
- if (w) {
- const TQString& wallet = w->walletName();
- assert(_passwords.contains(wallet));
- if (w->refCount() == 0 || force) {
- invalidateHandle(handle);
- if (_closeIdle && _timeouts) {
- _timeouts->removeTimer(handle);
- }
- _wallets.remove(handle);
- if (_passwords.contains(wallet)) {
- w->close(TQByteArray().duplicate(_passwords[wallet].data(), _passwords[wallet].length()));
- _passwords[wallet].fill(0);
- _passwords.remove(wallet);
- }
- doCloseSignals(handle, wallet);
- delete w;
- return 0;
- }
- return 1;
- }
-
- return -1;
-}
-
-
-int KWalletD::close(int handle, bool force) {
- TQCString appid = friendlyDCOPPeerName();
- KWallet::Backend *w = _wallets.find(handle);
- bool contains = false;
-
- if (w) { // the handle is valid
- if (_handles.contains(appid)) { // we know this app
- if (_handles[appid].contains(handle)) {
- // the app owns this handle
- _handles[appid].remove(_handles[appid].find(handle));
- contains = true;
- if (_handles[appid].isEmpty()) {
- _handles.remove(appid);
- }
- }
- }
-
- // watch the side effect of the deref()
- if ((contains && w->deref() == 0 && !_leaveOpen) || force) {
- if (_closeIdle && _timeouts) {
- _timeouts->removeTimer(handle);
- }
- _wallets.remove(handle);
- if (force) {
- invalidateHandle(handle);
- }
- if (_passwords.contains(w->walletName())) {
- w->close(TQByteArray().duplicate(_passwords[w->walletName()].data(), _passwords[w->walletName()].length()));
- _passwords[w->walletName()].fill(0);
- _passwords.remove(w->walletName());
- }
- doCloseSignals(handle, w->walletName());
- delete w;
- return 0;
- }
- return 1; // not closed
- }
-
- return -1; // not open to begin with, or other error
-}
-
-
-bool KWalletD::isOpen(const TQString& wallet) const {
- for (TQIntDictIterator<KWallet::Backend> it(_wallets);
- it.current();
- ++it) {
- if (it.current()->walletName() == wallet) {
- return true;
- }
- }
- return false;
-}
-
-
-bool KWalletD::isOpen(int handle) {
- if (handle == 0) {
- return false;
- }
-
- KWallet::Backend *rc = _wallets.find(handle);
-
- if (rc == 0 && ++_failed > 5) {
- _failed = 0;
- TQTimer::singleShot(0, this, TQT_SLOT(notifyFailures()));
- } else if (rc != 0) {
- _failed = 0;
- }
-
- return rc != 0;
-}
-
-
-TQStringList KWalletD::wallets() const {
- TQString path = KGlobal::dirs()->saveLocation("kwallet");
- TQDir dir(path, "*.kwl");
- TQStringList rc;
-
- dir.setFilter(TQDir::Files | TQDir::NoSymLinks);
-
- const TQFileInfoList *list = dir.entryInfoList();
- TQFileInfoListIterator it(*list);
- TQFileInfo *fi;
- while ((fi = it.current()) != 0L) {
- TQString fn = fi->fileName();
- if (fn.endsWith(".kwl")) {
- fn.truncate(fn.length()-4);
- }
- rc += fn;
- ++it;
- }
- return rc;
-}
-
-
-void KWalletD::sync(int handle) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- }
-}
-
-
-TQStringList KWalletD::folderList(int handle) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- return b->folderList();
- }
-
- return TQStringList();
-}
-
-
-bool KWalletD::hasFolder(int handle, const TQString& f) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- return b->hasFolder(f);
- }
-
- return false;
-}
-
-
-bool KWalletD::removeFolder(int handle, const TQString& f) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- bool rc = b->removeFolder(f);
- // write changes to disk immediately
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- TQByteArray data;
- TQDataStream ds(data, IO_WriteOnly);
- ds << b->walletName();
- emitDCOPSignal("folderListUpdated(TQString)", data);
- return rc;
- }
-
- return false;
-}
-
-
-bool KWalletD::createFolder(int handle, const TQString& f) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- bool rc = b->createFolder(f);
- // write changes to disk immediately
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- TQByteArray data;
- TQDataStream ds(data, IO_WriteOnly);
- ds << b->walletName();
- emitDCOPSignal("folderListUpdated(TQString)", data);
- return rc;
- }
-
- return false;
-}
-
-
-TQByteArray KWalletD::readMap(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- KWallet::Entry *e = b->readEntry(key);
- if (e && e->type() == KWallet::Wallet::Map) {
- return e->map();
- }
- }
-
- return TQByteArray();
-}
-
-
-TQMap<TQString,TQByteArray> KWalletD::readMapList(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- TQPtrList<KWallet::Entry> e = b->readEntryList(key);
- TQMap<TQString, TQByteArray> rc;
- TQPtrListIterator<KWallet::Entry> it(e);
- KWallet::Entry *entry;
- while ((entry = it.current())) {
- if (entry->type() == KWallet::Wallet::Map) {
- rc.insert(entry->key(), entry->map());
- }
- ++it;
- }
- return rc;
- }
-
- return TQMap<TQString, TQByteArray>();
-}
-
-
-TQByteArray KWalletD::readEntry(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- KWallet::Entry *e = b->readEntry(key);
- if (e) {
- return e->value();
- }
- }
-
- return TQByteArray();
-}
-
-
-TQMap<TQString, TQByteArray> KWalletD::readEntryList(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- TQPtrList<KWallet::Entry> e = b->readEntryList(key);
- TQMap<TQString, TQByteArray> rc;
- TQPtrListIterator<KWallet::Entry> it(e);
- KWallet::Entry *entry;
- while ((entry = it.current())) {
- rc.insert(entry->key(), entry->value());
- ++it;
- }
- return rc;
- }
-
- return TQMap<TQString, TQByteArray>();
-}
-
-
-TQStringList KWalletD::entryList(int handle, const TQString& folder) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- return b->entryList();
- }
-
- return TQStringList();
-}
-
-
-TQString KWalletD::readPassword(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- KWallet::Entry *e = b->readEntry(key);
- if (e && e->type() == KWallet::Wallet::Password) {
- return e->password();
- }
- }
-
- return TQString::null;
-}
-
-
-TQMap<TQString, TQString> KWalletD::readPasswordList(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- TQPtrList<KWallet::Entry> e = b->readEntryList(key);
- TQMap<TQString, TQString> rc;
- TQPtrListIterator<KWallet::Entry> it(e);
- KWallet::Entry *entry;
- while ((entry = it.current())) {
- if (entry->type() == KWallet::Wallet::Password) {
- rc.insert(entry->key(), entry->password());
- }
- ++it;
- }
- return rc;
- }
-
- return TQMap<TQString, TQString>();
-}
-
-
-int KWalletD::writeMap(int handle, const TQString& folder, const TQString& key, const TQByteArray& value) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- KWallet::Entry e;
- e.setKey(key);
- e.setValue(value);
- e.setType(KWallet::Wallet::Map);
- b->writeEntry(&e);
- // write changes to disk immediately
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- emitFolderUpdated(b->walletName(), folder);
- return 0;
- }
-
- return -1;
-}
-
-
-int KWalletD::writeEntry(int handle, const TQString& folder, const TQString& key, const TQByteArray& value, int entryType) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- KWallet::Entry e;
- e.setKey(key);
- e.setValue(value);
- e.setType(KWallet::Wallet::EntryType(entryType));
- b->writeEntry(&e);
- // write changes to disk immediately
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- emitFolderUpdated(b->walletName(), folder);
- return 0;
- }
-
- return -1;
-}
-
-
-int KWalletD::writeEntry(int handle, const TQString& folder, const TQString& key, const TQByteArray& value) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- KWallet::Entry e;
- e.setKey(key);
- e.setValue(value);
- e.setType(KWallet::Wallet::Stream);
- b->writeEntry(&e);
- // write changes to disk immediately
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- emitFolderUpdated(b->walletName(), folder);
- return 0;
- }
-
- return -1;
-}
-
-
-int KWalletD::writePassword(int handle, const TQString& folder, const TQString& key, const TQString& value) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- KWallet::Entry e;
- e.setKey(key);
- e.setValue(value);
- e.setType(KWallet::Wallet::Password);
- b->writeEntry(&e);
- // write changes to disk immediately
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- emitFolderUpdated(b->walletName(), folder);
- return 0;
- }
-
- return -1;
-}
-
-
-int KWalletD::entryType(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- if (!b->hasFolder(folder)) {
- return KWallet::Wallet::Unknown;
- }
- b->setFolder(folder);
- if (b->hasEntry(key)) {
- return b->readEntry(key)->type();
- }
- }
-
- return KWallet::Wallet::Unknown;
-}
-
-
-bool KWalletD::hasEntry(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- if (!b->hasFolder(folder)) {
- return false;
- }
- b->setFolder(folder);
- return b->hasEntry(key);
- }
-
- return false;
-}
-
-
-int KWalletD::removeEntry(int handle, const TQString& folder, const TQString& key) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- if (!b->hasFolder(folder)) {
- return 0;
- }
- b->setFolder(folder);
- bool rc = b->removeEntry(key);
- // write changes to disk immediately
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- emitFolderUpdated(b->walletName(), folder);
- return rc ? 0 : -3;
- }
-
- return -1;
-}
-
-
-void KWalletD::slotAppUnregistered(const TQCString& app) {
- if (_handles.contains(app)) {
- TQValueList<int> l = _handles[app];
- for (TQValueList<int>::Iterator i = l.begin(); i != l.end(); ++i) {
- _handles[app].remove(*i);
- KWallet::Backend *w = _wallets.find(*i);
- if (w && !_leaveOpen && 0 == w->deref()) {
- close(w->walletName(), true);
- }
- }
- _handles.remove(app);
- }
-}
-
-
-void KWalletD::invalidateHandle(int handle) {
- for (TQMap<TQCString,TQValueList<int> >::Iterator i = _handles.begin();
- i != _handles.end();
- ++i) {
- i.data().remove(handle);
- }
-}
-
-
-KWallet::Backend *KWalletD::getWallet(const TQCString& appid, int handle) {
- if (handle == 0) {
- return 0L;
- }
-
- KWallet::Backend *w = _wallets.find(handle);
-
- if (w) { // the handle is valid
- if (_handles.contains(appid)) { // we know this app
- if (_handles[appid].contains(handle)) {
- // the app owns this handle
- _failed = 0;
- if (_closeIdle && _timeouts) {
- _timeouts->resetTimer(handle, _idleTime);
- }
- return w;
- }
- }
- }
-
- if (++_failed > 5) {
- _failed = 0;
- TQTimer::singleShot(0, this, TQT_SLOT(notifyFailures()));
- }
-
- return 0L;
-}
-
-
-void KWalletD::notifyFailures() {
- if (!_showingFailureNotify) {
- _showingFailureNotify = true;
- KMessageBox::information(0, i18n("There have been repeated failed attempts to gain access to a wallet. An application may be misbehaving."), i18n("TDE Wallet Service"));
- _showingFailureNotify = false;
- }
-}
-
-
-void KWalletD::doCloseSignals(int handle, const TQString& wallet) {
- TQByteArray data;
- TQDataStream ds(data, IO_WriteOnly);
- ds << handle;
- emitDCOPSignal("walletClosed(int)", data);
-
- TQByteArray data2;
- TQDataStream ds2(data2, IO_WriteOnly);
- ds2 << wallet;
- emitDCOPSignal("walletClosed(TQString)", data2);
-
- if (_wallets.isEmpty()) {
- emitDCOPSignal("allWalletsClosed()", TQByteArray());
- }
-}
-
-
-int KWalletD::renameEntry(int handle, const TQString& folder, const TQString& oldName, const TQString& newName) {
- KWallet::Backend *b;
-
- if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
- b->setFolder(folder);
- int rc = b->renameEntry(oldName, newName);
- // write changes to disk immediately
- TQByteArray p;
- TQString wallet = b->walletName();
- p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
- b->sync(p);
- p.fill(0);
- emitFolderUpdated(b->walletName(), folder);
- return rc;
- }
-
- return -1;
-}
-
-
-TQStringList KWalletD::users(const TQString& wallet) const {
- TQStringList rc;
-
- for (TQIntDictIterator<KWallet::Backend> it(_wallets);
- it.current();
- ++it) {
- if (it.current()->walletName() == wallet) {
- for (TQMap<TQCString,TQValueList<int> >::ConstIterator hit = _handles.begin(); hit != _handles.end(); ++hit) {
- if (hit.data().contains(it.currentKey())) {
- rc += hit.key();
- }
- }
- break;
- }
- }
-
- return rc;
-}
-
-
-bool KWalletD::disconnectApplication(const TQString& wallet, const TQCString& application) {
- for (TQIntDictIterator<KWallet::Backend> it(_wallets);
- it.current();
- ++it) {
- if (it.current()->walletName() == wallet) {
- if (_handles[application].contains(it.currentKey())) {
- _handles[application].remove(it.currentKey());
-
- if (_handles[application].isEmpty()) {
- _handles.remove(application);
- }
-
- if (it.current()->deref() == 0) {
- close(it.current()->walletName(), true);
- }
-
- TQByteArray data;
- TQDataStream ds(data, IO_WriteOnly);
- ds << wallet;
- ds << application;
- emitDCOPSignal("applicationDisconnected(TQString,TQCString)", data);
-
- return true;
- }
- }
- }
-
- return false;
-}
-
-
-void KWalletD::emitFolderUpdated(const TQString& wallet, const TQString& folder) {
- TQByteArray data;
- TQDataStream ds(data, IO_WriteOnly);
- ds << wallet;
- ds << folder;
- emitDCOPSignal("folderUpdated(TQString,TQString)", data);
-}
-
-
-void KWalletD::emitWalletListDirty() {
- emitDCOPSignal("walletListDirty()", TQByteArray());
-}
-
-
-void KWalletD::reconfigure() {
- KConfig cfg("kwalletrc");
- cfg.setGroup("Wallet");
- _firstUse = cfg.readBoolEntry("First Use", true);
- _enabled = cfg.readBoolEntry("Enabled", true);
- _launchManager = cfg.readBoolEntry("Launch Manager", true);
- _leaveOpen = cfg.readBoolEntry("Leave Open", false);
- bool idleSave = _closeIdle;
- _closeIdle = cfg.readBoolEntry("Close When Idle", false);
- _openPrompt = cfg.readBoolEntry("Prompt on Open", true);
- int timeSave = _idleTime;
- // in minutes!
- _idleTime = cfg.readNumEntry("Idle Timeout", 10) * 60 * 1000;
-
- if (cfg.readBoolEntry("Close on Screensaver", false)) {
- connectDCOPSignal("kdesktop", "KScreensaverIface", "KDE_start_screensaver()", "closeAllWallets()", false);
- } else {
- disconnectDCOPSignal("kdesktop", "KScreensaverIface", "KDE_start_screensaver()", "closeAllWallets()");
- }
-
- // Handle idle changes
- if (_closeIdle) {
- if (_idleTime != timeSave) { // Timer length changed
- TQIntDictIterator<KWallet::Backend> it(_wallets);
- for (; it.current(); ++it) {
- _timeouts->resetTimer(it.currentKey(), _idleTime);
- }
- }
-
- if (!idleSave) { // add timers for all the wallets
- TQIntDictIterator<KWallet::Backend> it(_wallets);
- for (; it.current(); ++it) {
- _timeouts->addTimer(it.currentKey(), _idleTime);
- }
- }
- } else {
- _timeouts->clear();
- }
-
- // Update the implicit allow stuff
- _implicitAllowMap.clear();
- cfg.setGroup("Auto Allow");
- TQStringList entries = cfg.entryMap("Auto Allow").keys();
- for (TQStringList::Iterator i = entries.begin(); i != entries.end(); ++i) {
- _implicitAllowMap[*i] = cfg.readListEntry(*i);
- }
-
- // Update the implicit allow stuff
- _implicitDenyMap.clear();
- cfg.setGroup("Auto Deny");
- entries = cfg.entryMap("Auto Deny").keys();
- for (TQStringList::Iterator i = entries.begin(); i != entries.end(); ++i) {
- _implicitDenyMap[*i] = cfg.readListEntry(*i);
- }
-
- // Update if wallet was enabled/disabled
- if (!_enabled) { // close all wallets
- while (!_wallets.isEmpty()) {
- TQIntDictIterator<KWallet::Backend> it(_wallets);
- if (!it.current()) { // necessary?
- break;
- }
- closeWallet(it.current(), it.currentKey(), true);
- }
- }
-}
-
-
-bool KWalletD::isEnabled() const {
- return _enabled;
-}
-
-
-bool KWalletD::folderDoesNotExist(const TQString& wallet, const TQString& folder) {
- if (!wallets().contains(wallet)) {
- return true;
- }
-
- for (TQIntDictIterator<KWallet::Backend> it(_wallets); it.current(); ++it) {
- if (it.current()->walletName() == wallet) {
- return it.current()->folderDoesNotExist(folder);
- }
- }
-
- KWallet::Backend *b = new KWallet::Backend(wallet);
- b->open(TQByteArray());
- bool rc = b->folderDoesNotExist(folder);
- delete b;
- return rc;
-}
-
-
-bool KWalletD::keyDoesNotExist(const TQString& wallet, const TQString& folder, const TQString& key) {
- if (!wallets().contains(wallet)) {
- return true;
- }
-
- for (TQIntDictIterator<KWallet::Backend> it(_wallets); it.current(); ++it) {
- if (it.current()->walletName() == wallet) {
- return it.current()->entryDoesNotExist(folder, key);
- }
- }
-
- KWallet::Backend *b = new KWallet::Backend(wallet);
- b->open(TQByteArray());
- bool rc = b->entryDoesNotExist(folder, key);
- delete b;
- return rc;
-}
-
-
-bool KWalletD::implicitAllow(const TQString& wallet, const TQCString& app) {
- return _implicitAllowMap[wallet].contains(TQString::fromLocal8Bit(app));
-}
-
-
-bool KWalletD::implicitDeny(const TQString& wallet, const TQCString& app) {
- return _implicitDenyMap[wallet].contains(TQString::fromLocal8Bit(app));
-}
-
-
-TQCString KWalletD::friendlyDCOPPeerName() {
- DCOPClient *dc = callingDcopClient();
- if (!dc) {
- return "";
- }
- return dc->senderId().replace(TQRegExp("-[0-9]+$"), "");
-}
-
-
-void KWalletD::timedOut(int id) {
- KWallet::Backend *w = _wallets.find(id);
- if (w) {
- closeWallet(w, id, true);
- }
-}
-
-
-void KWalletD::closeAllWallets() {
- TQIntDict<KWallet::Backend> tw = _wallets;
-
- for (TQIntDictIterator<KWallet::Backend> it(tw); it.current(); ++it) {
- closeWallet(it.current(), it.currentKey(), true);
- }
-
- tw.clear();
-
- // All of this should be basically noop. Let's just be safe.
- _wallets.clear();
-
- for (TQMap<TQString,TQCString>::Iterator it = _passwords.begin();
- it != _passwords.end();
- ++it) {
- it.data().fill(0);
- }
- _passwords.clear();
-}
-
-
-TQString KWalletD::networkWallet() {
- return KWallet::Wallet::NetworkWallet();
-}
-
-
-TQString KWalletD::localWallet() {
- return KWallet::Wallet::LocalWallet();
-}
-
-
-#include "kwalletd.moc"