kio Library API Documentation

kwalletd.cpp

00001 /*
00002    This file is part of the KDE libraries
00003 
00004    Copyright (c) 2002-2004 George Staikos <staikos@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, USA.
00020 
00021 */
00022 
00023 #include "kbetterthankdialogbase.h"
00024 #include "kwalletwizard.h"
00025 #include "kwalletd.h"
00026 #include "ktimeout.h"
00027 
00028 #include <dcopclient.h>
00029 #include <dcopref.h>
00030 #include <kactivelabel.h>
00031 #include <kapplication.h>
00032 #include <kconfig.h>
00033 #include <kdebug.h>
00034 #include <kdirwatch.h>
00035 #include <kglobal.h>
00036 #include <klocale.h>
00037 #include <kmessagebox.h>
00038 #include <kpassdlg.h>
00039 #include <kstandarddirs.h>
00040 #include <kwalletentry.h>
00041 #include <kwin.h>
00042 
00043 #include <qdir.h>
00044 #include <qlabel.h>
00045 #include <qlayout.h>
00046 #include <qpushbutton.h>
00047 #include <qregexp.h>
00048 #include <qstylesheet.h>
00049 #include <qvbox.h>
00050 
00051 #include <assert.h>
00052 
00053 #ifdef Q_WS_X11
00054 #include <X11/Xlib.h>
00055 #endif
00056 
00057 extern "C" {
00058    KDE_EXPORT KDEDModule *create_kwalletd(const QCString &name) {
00059        return new KWalletD(name);
00060    }
00061 }
00062 
00063 
00064 class KWalletTransaction {
00065     public:
00066         KWalletTransaction() {
00067             tType = Unknown;
00068             transaction = 0L;
00069             client = 0L;
00070         }
00071 
00072         ~KWalletTransaction() {
00073             // Don't delete these!
00074             transaction = 0L;
00075             client = 0L;
00076         }
00077 
00078         enum Type { Unknown, Open, ChangePassword, OpenFail };
00079         DCOPClient *client;
00080         DCOPClientTransaction *transaction;
00081         Type tType;
00082         QCString rawappid, returnObject;
00083         QCString appid;
00084         uint wId;
00085         QString wallet;
00086 };
00087 
00088 
00089 KWalletD::KWalletD(const QCString &name)
00090 : KDEDModule(name), _failed(0) {
00091     srand(time(0));
00092     _showingFailureNotify = false;
00093     _transactions.setAutoDelete(true);
00094     _timeouts = new KTimeout(17);
00095     _closeIdle = false;
00096     _idleTime = 0;
00097     connect(_timeouts, SIGNAL(timedOut(int)), this, SLOT(timedOut(int)));
00098     reconfigure();
00099     KGlobal::dirs()->addResourceType("kwallet", "share/apps/kwallet");
00100     connect(KApplication::dcopClient(),
00101         SIGNAL(applicationRemoved(const QCString&)),
00102         this,
00103         SLOT(slotAppUnregistered(const QCString&)));
00104     _dw = new KDirWatch(this, "KWallet Directory Watcher");
00105     _dw->addDir(KGlobal::dirs()->saveLocation("kwallet"));
00106     _dw->startScan(true);
00107     connect(_dw, SIGNAL(dirty(const QString&)), this, SLOT(emitWalletListDirty()));
00108 }
00109 
00110 
00111 KWalletD::~KWalletD() {
00112     delete _timeouts;
00113     _timeouts = 0;
00114 
00115     closeAllWallets();
00116     _transactions.clear();
00117 }
00118 
00119 
00120 int KWalletD::generateHandle() {
00121     int rc;
00122 
00123     // ASSUMPTION: RAND_MAX is fairly large.
00124     do {
00125         rc = rand();
00126     } while (_wallets.find(rc) || rc == 0);
00127 
00128     return rc;
00129 }
00130 
00131 
00132 void KWalletD::processTransactions() {
00133     static bool processing = false;
00134 
00135     if (processing) {
00136         return;
00137     }
00138 
00139     processing = true;
00140 
00141     // Process remaining transactions
00142     KWalletTransaction *xact;
00143     while (!_transactions.isEmpty()) {
00144         xact = _transactions.first();
00145         QCString replyType;
00146         int res;
00147 
00148         assert(xact->tType != KWalletTransaction::Unknown);
00149 
00150         switch (xact->tType) {
00151             case KWalletTransaction::Open:
00152                 res = doTransactionOpen(xact->appid, xact->wallet, xact->wId);
00153                 replyType = "int";
00154                 if (!xact->returnObject.isEmpty()) {
00155                     DCOPRef(xact->rawappid, xact->returnObject).send("walletOpenResult", res);
00156                 }
00157 
00158                 // multiple requests from the same client
00159                 // should not produce multiple password
00160                 // dialogs on a failure
00161                 if (res < 0) {
00162                     QPtrListIterator<KWalletTransaction> it(_transactions);
00163                     KWalletTransaction *x;
00164                     while ((x = it.current()) && x != xact) {
00165                         ++it;
00166                     }
00167                     if (x) {
00168                         ++it;
00169                     }
00170                     while ((x = it.current())) {
00171                         if (xact->appid == x->appid && x->tType == KWalletTransaction::Open && x->wallet == xact->wallet && x->wId == xact->wId) {
00172                             x->tType = KWalletTransaction::OpenFail;
00173                         }
00174                         ++it;
00175                     }
00176                 }
00177                 break;
00178             case KWalletTransaction::OpenFail:
00179                 res = -1;
00180                 replyType = "int";
00181                 if (!xact->returnObject.isEmpty()) {
00182                     DCOPRef(xact->rawappid, xact->returnObject).send("walletOpenResult", res);
00183                 }
00184                 break;
00185             case KWalletTransaction::ChangePassword:
00186                 doTransactionChangePassword(xact->appid, xact->wallet, xact->wId);
00187                 // fall through - no return
00188             default:
00189                 _transactions.removeRef(xact);
00190                 continue;
00191         }
00192 
00193         if (xact->returnObject.isEmpty() && xact->tType != KWalletTransaction::ChangePassword) {
00194             QByteArray replyData;
00195             QDataStream stream(replyData, IO_WriteOnly);
00196             stream << res;
00197             xact->client->endTransaction(xact->transaction, replyType, replyData);
00198         }
00199         _transactions.removeRef(xact);
00200     }
00201 
00202     processing = false;
00203 }
00204 
00205 
00206 void KWalletD::openAsynchronous(const QString& wallet, const QCString& returnObject, uint wId) {
00207     DCOPClient *dc = callingDcopClient();
00208     if (!dc) {
00209         return;
00210     }
00211 
00212     QCString appid = dc->senderId();
00213     if (!_enabled ||
00214         !QRegExp("^[A-Za-z0-9]+[A-Za-z0-9\\s\\-_]*$").exactMatch(wallet)) {
00215         DCOPRef(appid, returnObject).send("walletOpenResult", -1);
00216         return;
00217     }
00218 
00219     QCString peerName = friendlyDCOPPeerName();
00220 
00221     KWalletTransaction *xact = new KWalletTransaction;
00222 
00223     xact->appid = peerName;
00224     xact->rawappid = appid;
00225     xact->client = callingDcopClient();
00226     xact->wallet = wallet;
00227     xact->wId = wId;
00228     xact->tType = KWalletTransaction::Open;
00229     xact->returnObject = returnObject;
00230     _transactions.append(xact);
00231 
00232     DCOPRef(appid, returnObject).send("walletOpenResult", 0);
00233 
00234     QTimer::singleShot(0, this, SLOT(processTransactions()));
00235 }
00236 
00237 
00238 int KWalletD::openPath(const QString& path, uint wId) {
00239     if (!_enabled) { // guard
00240         return -1;
00241     }
00242 
00243     // FIXME: setup transaction
00244     int rc = internalOpen(friendlyDCOPPeerName(), path, true, wId);
00245     return rc;
00246 }
00247 
00248 
00249 int KWalletD::open(const QString& wallet, uint wId) {
00250     if (!_enabled) { // guard
00251         return -1;
00252     }
00253 
00254     if (!QRegExp("^[A-Za-z0-9]+[A-Za-z0-9\\s\\-_]*$").exactMatch(wallet)) {
00255         return -1;
00256     }
00257 
00258     QCString appid = friendlyDCOPPeerName();
00259 
00260     KWalletTransaction *xact = new KWalletTransaction;
00261     _transactions.append(xact);
00262 
00263     if (_transactions.count() > 1) {
00264         xact->appid = appid;
00265         xact->client = callingDcopClient();
00266         xact->transaction = xact->client->beginTransaction();
00267         xact->wallet = wallet;
00268         xact->wId = wId;
00269         xact->tType = KWalletTransaction::Open;
00270         return 0; // process later
00271     }
00272 
00273     int rc = doTransactionOpen(appid, wallet, wId);
00274 
00275     _transactions.remove(xact);
00276 
00277     if (rc < 0) {
00278         // multiple requests from the same client should not produce multiple password dialogs on a failure
00279         for (KWalletTransaction *x = _transactions.first(); x; x = _transactions.next()) {
00280             if (appid == x->appid && x->tType == KWalletTransaction::Open && x->wallet == wallet && x->wId == wId)
00281                 x->tType = KWalletTransaction::OpenFail;
00282         }
00283     }
00284 
00285     processTransactions();
00286 
00287     return rc;
00288 }
00289 
00290 
00291 int KWalletD::doTransactionOpen(const QCString& appid, const QString& wallet, uint wId) {
00292     if (_firstUse && !wallets().contains(KWallet::Wallet::LocalWallet())) {
00293         // First use wizard
00294         KWalletWizard *wiz = new KWalletWizard(0);
00295 #ifdef Q_WS_X11
00296         XSetTransientForHint(qt_xdisplay(), wiz->winId(), wId);
00297 #endif
00298         int rc = wiz->exec();
00299         if (rc == QDialog::Accepted) {
00300             KConfig cfg("kwalletrc");
00301             cfg.setGroup("Wallet");
00302             cfg.writeEntry("First Use", false);
00303             cfg.writeEntry("Enabled", wiz->_useWallet->isChecked());
00304             cfg.writeEntry("Close When Idle", wiz->_closeIdle->isChecked());
00305             cfg.writeEntry("Use One Wallet", !wiz->_networkWallet->isChecked());
00306             cfg.sync();
00307             reconfigure();
00308 
00309             if (!wiz->_useWallet->isChecked()) {
00310                 delete wiz;
00311                 return -1;
00312             }
00313 
00314             // Create the wallet
00315             KWallet::Backend *b = new KWallet::Backend(KWallet::Wallet::LocalWallet());
00316             QByteArray p;
00317             p.duplicate(wiz->_pass1->text().utf8(), wiz->_pass1->text().length());
00318             b->open(p);
00319             b->createFolder(KWallet::Wallet::PasswordFolder());
00320             b->createFolder(KWallet::Wallet::FormDataFolder());
00321             b->close(p);
00322             p.fill(0);
00323             delete b;
00324             delete wiz;
00325         } else {
00326             delete wiz;
00327             return -1;
00328         }
00329     } else if (_firstUse) {
00330         KConfig cfg("kwalletrc");
00331         _firstUse = false;
00332         cfg.setGroup("Wallet");
00333         cfg.writeEntry("First Use", false);
00334         cfg.sync();
00335     }
00336 
00337     int rc = internalOpen(appid, wallet, false, wId);
00338     return rc;
00339 }
00340 
00341 
00342 int KWalletD::internalOpen(const QCString& appid, const QString& wallet, bool isPath, WId w) {
00343     int rc = -1;
00344     bool brandNew = false;
00345 
00346     QCString thisApp;
00347     if (appid.isEmpty()) {
00348         thisApp = "KDE System";
00349     } else {
00350         thisApp = appid;
00351     }
00352 
00353     if (implicitDeny(wallet, thisApp)) {
00354         return -1;
00355     }
00356 
00357     for (QIntDictIterator<KWallet::Backend> i(_wallets); i.current(); ++i) {
00358         if (i.current()->walletName() == wallet) {
00359             rc = i.currentKey();
00360             break;
00361         }
00362     }
00363 
00364     if (rc == -1) {
00365         if (_wallets.count() > 20) {
00366             kdDebug() << "Too many wallets open." << endl;
00367             return -1;
00368         }
00369 
00370         KWallet::Backend *b = new KWallet::Backend(wallet, isPath);
00371         KPasswordDialog *kpd = 0L;
00372         bool emptyPass = false;
00373         if ((isPath && QFile::exists(wallet)) || (!isPath && KWallet::Backend::exists(wallet))) {
00374             int pwless = b->open(QByteArray());
00375             if (0 != pwless || !b->isOpen()) {
00376                 if (pwless == 0) {
00377                     // release, start anew
00378                     delete b;
00379                     b = new KWallet::Backend(wallet, isPath);
00380                 }
00381                 kpd = new KPasswordDialog(KPasswordDialog::Password, false, 0);
00382                 if (appid.isEmpty()) {
00383                     kpd->setPrompt(i18n("<qt>KDE has requested to open the wallet '<b>%1</b>'. Please enter the password for this wallet below.").arg(QStyleSheet::escape(wallet)));
00384                 } else {
00385                     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(QStyleSheet::escape(appid)).arg(QStyleSheet::escape(wallet)));
00386                 }
00387                 brandNew = false;
00388                 kpd->setButtonOK(KGuiItem(i18n("&Open"),"fileopen"));
00389             } else {
00390                 emptyPass = true;
00391             }
00392         } else if (wallet == KWallet::Wallet::LocalWallet() ||
00393                 wallet == KWallet::Wallet::NetworkWallet()) {
00394             // Auto create these wallets.
00395             kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0);
00396             if (appid.isEmpty()) {
00397                 kpd->setPrompt(i18n("KDE 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."));
00398             } else {
00399                 kpd->setPrompt(i18n("<qt>The application '<b>%1</b>' has requested to open the KDE 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(QStyleSheet::escape(appid)));
00400             }
00401             brandNew = true;
00402             kpd->setButtonOK(KGuiItem(i18n("&Open"),"fileopen"));
00403         } else {
00404             kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0);
00405             if (appid.length() == 0) {
00406                 kpd->setPrompt(i18n("<qt>KDE 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(QStyleSheet::escape(wallet)));
00407             } else {
00408                 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(QStyleSheet::escape(appid)).arg(QStyleSheet::escape(wallet)));
00409             }
00410             brandNew = true;
00411             kpd->setButtonOK(KGuiItem(i18n("C&reate"),"filenew"));
00412         }
00413 
00414         if (kpd) {
00415             kpd->setCaption(i18n("KDE Wallet Service"));
00416             kpd->setAllowEmptyPasswords(true);
00417         }
00418 
00419         const char *p = 0L;
00420         while (!b->isOpen()) {
00421 #ifdef Q_WS_X11
00422             XSetTransientForHint(qt_xdisplay(), kpd->winId(), w);
00423 #endif
00424             KWin::setState( kpd->winId(), NET::KeepAbove );
00425             KWin::setOnAllDesktops(kpd->winId(), true);
00426             if (kpd->exec() == KDialog::Accepted) {
00427                 p = kpd->password();
00428                 int rc = b->open(QByteArray().duplicate(p, strlen(p)));
00429                 if (!b->isOpen()) {
00430                     kpd->setPrompt(i18n("<qt>Error opening the wallet '<b>%1</b>'. Please try again.<br>(Error code %2: %3)").arg(QStyleSheet::escape(wallet)).arg(rc).arg(KWallet::Backend::openRCToString(rc)));
00431                     kpd->clearPassword();
00432                 }
00433             } else {
00434                 break;
00435             }
00436         }
00437 
00438         if (!emptyPass && (!p || !b->isOpen())) {
00439             delete b;
00440             delete kpd;
00441             return -1;
00442         }
00443 
00444         if (emptyPass && _openPrompt && !isAuthorizedApp(appid, wallet, w)) {
00445             delete b;
00446             delete kpd;
00447             return -1;
00448         }
00449 
00450         _wallets.insert(rc = generateHandle(), b);
00451         if (emptyPass) {
00452             _passwords[wallet] = "";
00453         } else {
00454             _passwords[wallet] = p;
00455         }
00456         _handles[appid].append(rc);
00457 
00458         delete kpd; // don't refactor this!!  Argh I hate KPassDlg
00459 
00460         if (brandNew) {
00461             createFolder(rc, KWallet::Wallet::PasswordFolder());
00462             createFolder(rc, KWallet::Wallet::FormDataFolder());
00463         }
00464 
00465         b->ref();
00466         if (_closeIdle && _timeouts) {
00467             _timeouts->addTimer(rc, _idleTime);
00468         }
00469         QByteArray data;
00470         QDataStream ds(data, IO_WriteOnly);
00471         ds << wallet;
00472         if (brandNew) {
00473             emitDCOPSignal("walletCreated(QString)", data);
00474         }
00475         emitDCOPSignal("walletOpened(QString)", data);
00476         if (_wallets.count() == 1 && _launchManager) {
00477             KApplication::startServiceByDesktopName("kwalletmanager-kwalletd");
00478         }
00479     } else {
00480         if (!_handles[appid].contains(rc) && _openPrompt && !isAuthorizedApp(appid, wallet, w)) {
00481             return -1;
00482         }
00483         _handles[appid].append(rc);
00484         _wallets.find(rc)->ref();
00485     }
00486 
00487     return rc;
00488 }
00489 
00490 
00491 bool KWalletD::isAuthorizedApp(const QCString& appid, const QString& wallet, WId w) {
00492     int response = 0;
00493 
00494     QCString thisApp;
00495     if (appid.isEmpty()) {
00496         thisApp = "KDE System";
00497     } else {
00498         thisApp = appid;
00499     }
00500 
00501     if (!implicitAllow(wallet, thisApp)) {
00502         KBetterThanKDialogBase *dialog = new KBetterThanKDialogBase;
00503         if (appid.isEmpty()) {
00504             dialog->setLabel(i18n("<qt>KDE has requested access to the open wallet '<b>%1</b>'.").arg(QStyleSheet::escape(wallet)));
00505         } else {
00506             dialog->setLabel(i18n("<qt>The application '<b>%1</b>' has requested access to the open wallet '<b>%2</b>'.").arg(QStyleSheet::escape(QString(appid))).arg(QStyleSheet::escape(wallet)));
00507         }
00508 #ifdef Q_WS_X11
00509         XSetTransientForHint(qt_xdisplay(), dialog->winId(), w);
00510 #endif
00511         KWin::setState(dialog->winId(), NET::KeepAbove);
00512         KWin::setOnAllDesktops(dialog->winId(), true);
00513 
00514         response = dialog->exec();
00515         delete dialog;
00516     }
00517 
00518     if (response == 0 || response == 1) {
00519         if (response == 1) {
00520             KConfig cfg("kwalletrc");
00521             cfg.setGroup("Auto Allow");
00522             QStringList apps = cfg.readListEntry(wallet);
00523             if (!apps.contains(thisApp)) {
00524                 apps += thisApp;
00525                 _implicitAllowMap[wallet] += thisApp;
00526                 cfg.writeEntry(wallet, apps);
00527                 cfg.sync();
00528             }
00529         }
00530     } else if (response == 3) {
00531         KConfig cfg("kwalletrc");
00532         cfg.setGroup("Auto Deny");
00533         QStringList apps = cfg.readListEntry(wallet);
00534         if (!apps.contains(thisApp)) {
00535             apps += thisApp;
00536             _implicitDenyMap[wallet] += thisApp;
00537             cfg.writeEntry(wallet, apps);
00538             cfg.sync();
00539         }
00540         return false;
00541     } else {
00542         return false;
00543     }
00544     return true;
00545 }
00546 
00547 
00548 int KWalletD::deleteWallet(const QString& wallet) {
00549     QString path = KGlobal::dirs()->saveLocation("kwallet") + QDir::separator() + wallet + ".kwl";
00550 
00551     if (QFile::exists(path)) {
00552         close(wallet, true);
00553         QFile::remove(path);
00554         QByteArray data;
00555         QDataStream ds(data, IO_WriteOnly);
00556         ds << wallet;
00557         emitDCOPSignal("walletDeleted(QString)", data);
00558         return 0;
00559     }
00560 
00561     return -1;
00562 }
00563 
00564 
00565 void KWalletD::changePassword(const QString& wallet, uint wId) {
00566     QCString appid = friendlyDCOPPeerName();
00567 
00568     KWalletTransaction *xact = new KWalletTransaction;
00569 
00570     xact->appid = appid;
00571     xact->client = callingDcopClient();
00572     xact->wallet = wallet;
00573     xact->wId = wId;
00574     xact->tType = KWalletTransaction::ChangePassword;
00575 
00576     _transactions.append(xact);
00577 
00578     QTimer::singleShot(0, this, SLOT(processTransactions()));
00579 }
00580 
00581 
00582 void KWalletD::doTransactionChangePassword(const QCString& appid, const QString& wallet, uint wId) {
00583     QIntDictIterator<KWallet::Backend> it(_wallets);
00584     KWallet::Backend *w = 0L;
00585     int handle = -1;
00586     bool reclose = false;
00587 
00588     for (; it.current(); ++it) {
00589         if (it.current()->walletName() == wallet) {
00590             break;
00591         }
00592     }
00593 
00594     if (!it.current()) {
00595         handle = doTransactionOpen(appid, wallet, wId);
00596         if (-1 == handle) {
00597             KMessageBox::sorryWId(wId, i18n("Unable to open wallet. The wallet must be opened in order to change the password."), i18n("KDE Wallet Service"));
00598             return;
00599         }
00600 
00601         w = _wallets.find(handle);
00602         reclose = true;
00603     } else {
00604         handle = it.currentKey();
00605         w = it.current();
00606     }
00607 
00608     assert(w);
00609 
00610     KPasswordDialog *kpd;
00611     kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0);
00612     kpd->setPrompt(i18n("<qt>Please choose a new password for the wallet '<b>%1</b>'.").arg(QStyleSheet::escape(wallet)));
00613     kpd->setCaption(i18n("KDE Wallet Service"));
00614     kpd->setAllowEmptyPasswords(true);
00615 #ifdef Q_WS_X11
00616     XSetTransientForHint(qt_xdisplay(), kpd->winId(), wId);
00617 #endif
00618     if (kpd->exec() == KDialog::Accepted) {
00619         const char *p = kpd->password();
00620         if (p) {
00621             _passwords[wallet] = p;
00622             QByteArray pa;
00623             pa.duplicate(p, strlen(p));
00624             int rc = w->close(pa);
00625             if (rc < 0) {
00626                 KMessageBox::sorryWId(wId, i18n("Error re-encrypting the wallet. Password was not changed."), i18n("KDE Wallet Service"));
00627                 reclose = true;
00628             } else {
00629                 rc = w->open(pa);
00630                 if (rc < 0) {
00631                     KMessageBox::sorryWId(wId, i18n("Error reopening the wallet. Data may be lost."), i18n("KDE Wallet Service"));
00632                     reclose = true;
00633                 }
00634             }
00635         }
00636     }
00637 
00638     delete kpd;
00639 
00640     if (reclose) {
00641         close(handle, true);
00642     }
00643 }
00644 
00645 
00646 int KWalletD::close(const QString& wallet, bool force) {
00647     int handle = -1;
00648     KWallet::Backend *w = 0L;
00649 
00650     for (QIntDictIterator<KWallet::Backend> it(_wallets);
00651                         it.current();
00652                             ++it) {
00653         if (it.current()->walletName() == wallet) {
00654             handle = it.currentKey();
00655             w = it.current();
00656             break;
00657         }
00658     }
00659 
00660     return closeWallet(w, handle, force);
00661 }
00662 
00663 
00664 int KWalletD::closeWallet(KWallet::Backend *w, int handle, bool force) {
00665     if (w) {
00666         const QString& wallet = w->walletName();
00667         assert(_passwords.contains(wallet));
00668         if (w->refCount() == 0 || force) {
00669             invalidateHandle(handle);
00670             if (_closeIdle && _timeouts) {
00671                 _timeouts->removeTimer(handle);
00672             }
00673             _wallets.remove(handle);
00674             if (_passwords.contains(wallet)) {
00675                 w->close(QByteArray().duplicate(_passwords[wallet].data(), _passwords[wallet].length()));
00676                 _passwords[wallet].fill(0);
00677                 _passwords.remove(wallet);
00678             }
00679             doCloseSignals(handle, wallet);
00680             delete w;
00681             return 0;
00682         }
00683         return 1;
00684     }
00685 
00686     return -1;
00687 }
00688 
00689 
00690 int KWalletD::close(int handle, bool force) {
00691     QCString appid = friendlyDCOPPeerName();
00692     KWallet::Backend *w = _wallets.find(handle);
00693     bool contains = false;
00694 
00695     if (w) { // the handle is valid
00696         if (_handles.contains(appid)) { // we know this app
00697             if (_handles[appid].contains(handle)) {
00698                 // the app owns this handle
00699                 _handles[appid].remove(_handles[appid].find(handle));
00700                 contains = true;
00701                 if (_handles[appid].isEmpty()) {
00702                     _handles.remove(appid);
00703                 }
00704             }
00705         }
00706 
00707         // watch the side effect of the deref()
00708         if ((contains && w->deref() == 0 && !_leaveOpen) || force) {
00709             if (_closeIdle && _timeouts) {
00710                 _timeouts->removeTimer(handle);
00711             }
00712             _wallets.remove(handle);
00713             if (force) {
00714                 invalidateHandle(handle);
00715             }
00716             if (_passwords.contains(w->walletName())) {
00717                 w->close(QByteArray().duplicate(_passwords[w->walletName()].data(), _passwords[w->walletName()].length()));
00718                 _passwords[w->walletName()].fill(0);
00719                 _passwords.remove(w->walletName());
00720             }
00721             doCloseSignals(handle, w->walletName());
00722             delete w;
00723             return 0;
00724         }
00725         return 1; // not closed
00726     }
00727 
00728     return -1; // not open to begin with, or other error
00729 }
00730 
00731 
00732 bool KWalletD::isOpen(const QString& wallet) const {
00733     for (QIntDictIterator<KWallet::Backend> it(_wallets);
00734                         it.current();
00735                             ++it) {
00736         if (it.current()->walletName() == wallet) {
00737             return true;
00738         }
00739     }
00740     return false;
00741 }
00742 
00743 
00744 bool KWalletD::isOpen(int handle) {
00745     if (handle == 0) {
00746         return false;
00747     }
00748 
00749     KWallet::Backend *rc = _wallets.find(handle);
00750 
00751     if (rc == 0 && ++_failed > 5) {
00752         _failed = 0;
00753         QTimer::singleShot(0, this, SLOT(notifyFailures()));
00754     } else if (rc != 0) {
00755         _failed = 0;
00756     }
00757 
00758     return rc != 0;
00759 }
00760 
00761 
00762 QStringList KWalletD::wallets() const {
00763     QString path = KGlobal::dirs()->saveLocation("kwallet");
00764     QDir dir(path, "*.kwl");
00765     QStringList rc;
00766 
00767     dir.setFilter(QDir::Files | QDir::NoSymLinks);
00768 
00769     const QFileInfoList *list = dir.entryInfoList();
00770     QFileInfoListIterator it(*list);
00771     QFileInfo *fi;
00772     while ((fi = it.current()) != 0L) {
00773         QString fn = fi->fileName();
00774         if (fn.endsWith(".kwl")) {
00775             fn.truncate(fn.length()-4);
00776         }
00777         rc += fn;
00778         ++it;
00779     }
00780     return rc;
00781 }
00782 
00783 
00784 void KWalletD::sync(int handle) {
00785     KWallet::Backend *b;
00786 
00787     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00788         QByteArray p;
00789         QString wallet = b->walletName();
00790         p.duplicate(_passwords[wallet].data(), _passwords[wallet].length());
00791         b->sync(p);
00792         p.fill(0);
00793     }
00794 }
00795 
00796 
00797 QStringList KWalletD::folderList(int handle) {
00798     KWallet::Backend *b;
00799 
00800     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00801         return b->folderList();
00802     }
00803 
00804     return QStringList();
00805 }
00806 
00807 
00808 bool KWalletD::hasFolder(int handle, const QString& f) {
00809     KWallet::Backend *b;
00810 
00811     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00812         return b->hasFolder(f);
00813     }
00814 
00815     return false;
00816 }
00817 
00818 
00819 bool KWalletD::removeFolder(int handle, const QString& f) {
00820     KWallet::Backend *b;
00821 
00822     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00823         bool rc = b->removeFolder(f);
00824         QByteArray data;
00825         QDataStream ds(data, IO_WriteOnly);
00826         ds << b->walletName();
00827         emitDCOPSignal("folderListUpdated(QString)", data);
00828         return rc;
00829     }
00830 
00831     return false;
00832 }
00833 
00834 
00835 bool KWalletD::createFolder(int handle, const QString& f) {
00836     KWallet::Backend *b;
00837 
00838     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00839         bool rc = b->createFolder(f);
00840         QByteArray data;
00841         QDataStream ds(data, IO_WriteOnly);
00842         ds << b->walletName();
00843         emitDCOPSignal("folderListUpdated(QString)", data);
00844         return rc;
00845     }
00846 
00847     return false;
00848 }
00849 
00850 
00851 QByteArray KWalletD::readMap(int handle, const QString& folder, const QString& key) {
00852     KWallet::Backend *b;
00853 
00854     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00855         b->setFolder(folder);
00856         KWallet::Entry *e = b->readEntry(key);
00857         if (e && e->type() == KWallet::Wallet::Map) {
00858             return e->map();
00859         }
00860     }
00861 
00862     return QByteArray();
00863 }
00864 
00865 
00866 QMap<QString,QByteArray> KWalletD::readMapList(int handle, const QString& folder, const QString& key) {
00867     KWallet::Backend *b;
00868 
00869     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00870         b->setFolder(folder);
00871         QPtrList<KWallet::Entry> e = b->readEntryList(key);
00872         QMap<QString, QByteArray> rc;
00873         QPtrListIterator<KWallet::Entry> it(e);
00874         KWallet::Entry *entry;
00875         while ((entry = it.current())) {
00876             if (entry->type() == KWallet::Wallet::Map) {
00877                 rc.insert(entry->key(), entry->map());
00878             }
00879             ++it;
00880         }
00881         return rc;
00882     }
00883 
00884     return QMap<QString, QByteArray>();
00885 }
00886 
00887 
00888 QByteArray KWalletD::readEntry(int handle, const QString& folder, const QString& key) {
00889     KWallet::Backend *b;
00890 
00891     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00892         b->setFolder(folder);
00893         KWallet::Entry *e = b->readEntry(key);
00894         if (e) {
00895             return e->value();
00896         }
00897     }
00898 
00899     return QByteArray();
00900 }
00901 
00902 
00903 QMap<QString, QByteArray> KWalletD::readEntryList(int handle, const QString& folder, const QString& key) {
00904     KWallet::Backend *b;
00905 
00906     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00907         b->setFolder(folder);
00908         QPtrList<KWallet::Entry> e = b->readEntryList(key);
00909         QMap<QString, QByteArray> rc;
00910         QPtrListIterator<KWallet::Entry> it(e);
00911         KWallet::Entry *entry;
00912         while ((entry = it.current())) {
00913             rc.insert(entry->key(), entry->value());
00914             ++it;
00915         }
00916         return rc;
00917     }
00918 
00919     return QMap<QString, QByteArray>();
00920 }
00921 
00922 
00923 QStringList KWalletD::entryList(int handle, const QString& folder) {
00924     KWallet::Backend *b;
00925 
00926     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00927         b->setFolder(folder);
00928         return b->entryList();
00929     }
00930 
00931     return QStringList();
00932 }
00933 
00934 
00935 QString KWalletD::readPassword(int handle, const QString& folder, const QString& key) {
00936     KWallet::Backend *b;
00937 
00938     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00939         b->setFolder(folder);
00940         KWallet::Entry *e = b->readEntry(key);
00941         if (e && e->type() == KWallet::Wallet::Password) {
00942             return e->password();
00943         }
00944     }
00945 
00946     return QString::null;
00947 }
00948 
00949 
00950 QMap<QString, QString> KWalletD::readPasswordList(int handle, const QString& folder, const QString& key) {
00951     KWallet::Backend *b;
00952 
00953     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00954         b->setFolder(folder);
00955         QPtrList<KWallet::Entry> e = b->readEntryList(key);
00956         QMap<QString, QString> rc;
00957         QPtrListIterator<KWallet::Entry> it(e);
00958         KWallet::Entry *entry;
00959         while ((entry = it.current())) {
00960             if (entry->type() == KWallet::Wallet::Password) {
00961                 rc.insert(entry->key(), entry->password());
00962             }
00963             ++it;
00964         }
00965         return rc;
00966     }
00967 
00968     return QMap<QString, QString>();
00969 }
00970 
00971 
00972 int KWalletD::writeMap(int handle, const QString& folder, const QString& key, const QByteArray& value) {
00973     KWallet::Backend *b;
00974 
00975     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00976         b->setFolder(folder);
00977         KWallet::Entry e;
00978         e.setKey(key);
00979         e.setValue(value);
00980         e.setType(KWallet::Wallet::Map);
00981         b->writeEntry(&e);
00982         emitFolderUpdated(b->walletName(), folder);
00983         return 0;
00984     }
00985 
00986     return -1;
00987 }
00988 
00989 
00990 int KWalletD::writeEntry(int handle, const QString& folder, const QString& key, const QByteArray& value, int entryType) {
00991     KWallet::Backend *b;
00992 
00993     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
00994         b->setFolder(folder);
00995         KWallet::Entry e;
00996         e.setKey(key);
00997         e.setValue(value);
00998         e.setType(KWallet::Wallet::EntryType(entryType));
00999         b->writeEntry(&e);
01000         emitFolderUpdated(b->walletName(), folder);
01001         return 0;
01002     }
01003 
01004     return -1;
01005 }
01006 
01007 
01008 int KWalletD::writeEntry(int handle, const QString& folder, const QString& key, const QByteArray& value) {
01009     KWallet::Backend *b;
01010 
01011     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
01012         b->setFolder(folder);
01013         KWallet::Entry e;
01014         e.setKey(key);
01015         e.setValue(value);
01016         e.setType(KWallet::Wallet::Stream);
01017         b->writeEntry(&e);
01018         emitFolderUpdated(b->walletName(), folder);
01019         return 0;
01020     }
01021 
01022     return -1;
01023 }
01024 
01025 
01026 int KWalletD::writePassword(int handle, const QString& folder, const QString& key, const QString& value) {
01027     KWallet::Backend *b;
01028 
01029     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
01030         b->setFolder(folder);
01031         KWallet::Entry e;
01032         e.setKey(key);
01033         e.setValue(value);
01034         e.setType(KWallet::Wallet::Password);
01035         b->writeEntry(&e);
01036         emitFolderUpdated(b->walletName(), folder);
01037         return 0;
01038     }
01039 
01040     return -1;
01041 }
01042 
01043 
01044 int KWalletD::entryType(int handle, const QString& folder, const QString& key) {
01045     KWallet::Backend *b;
01046 
01047     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
01048         if (!b->hasFolder(folder)) {
01049             return KWallet::Wallet::Unknown;
01050         }
01051         b->setFolder(folder);
01052         if (b->hasEntry(key)) {
01053             return b->readEntry(key)->type();
01054         }
01055     }
01056 
01057     return KWallet::Wallet::Unknown;
01058 }
01059 
01060 
01061 bool KWalletD::hasEntry(int handle, const QString& folder, const QString& key) {
01062     KWallet::Backend *b;
01063 
01064     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
01065         if (!b->hasFolder(folder)) {
01066             return false;
01067         }
01068         b->setFolder(folder);
01069         return b->hasEntry(key);
01070     }
01071 
01072     return false;
01073 }
01074 
01075 
01076 int KWalletD::removeEntry(int handle, const QString& folder, const QString& key) {
01077     KWallet::Backend *b;
01078 
01079     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
01080         if (!b->hasFolder(folder)) {
01081             return 0;
01082         }
01083         b->setFolder(folder);
01084         bool rc = b->removeEntry(key);
01085         emitFolderUpdated(b->walletName(), folder);
01086         return rc ? 0 : -3;
01087     }
01088 
01089     return -1;
01090 }
01091 
01092 
01093 void KWalletD::slotAppUnregistered(const QCString& app) {
01094     if (_handles.contains(app)) {
01095         QValueList<int> l = _handles[app];
01096         for (QValueList<int>::Iterator i = l.begin(); i != l.end(); i++) {
01097             _handles[app].remove(*i);
01098             KWallet::Backend *w = _wallets.find(*i);
01099             if (w && !_leaveOpen && 0 == w->deref()) {
01100                 close(w->walletName(), true);
01101             }
01102         }
01103         _handles.remove(app);
01104     }
01105 }
01106 
01107 
01108 void KWalletD::invalidateHandle(int handle) {
01109     for (QMap<QCString,QValueList<int> >::Iterator i = _handles.begin();
01110                             i != _handles.end();
01111                                     ++i) {
01112         i.data().remove(handle);
01113     }
01114 }
01115 
01116 
01117 KWallet::Backend *KWalletD::getWallet(const QCString& appid, int handle) {
01118     if (handle == 0) {
01119         return 0L;
01120     }
01121 
01122     KWallet::Backend *w = _wallets.find(handle);
01123 
01124     if (w) { // the handle is valid
01125         if (_handles.contains(appid)) { // we know this app
01126             if (_handles[appid].contains(handle)) {
01127                 // the app owns this handle
01128                 _failed = 0;
01129                 if (_closeIdle && _timeouts) {
01130                     _timeouts->resetTimer(handle, _idleTime);
01131                 }
01132                 return w;
01133             }
01134         }
01135     }
01136 
01137     if (++_failed > 5) {
01138         _failed = 0;
01139         QTimer::singleShot(0, this, SLOT(notifyFailures()));
01140     }
01141 
01142     return 0L;
01143 }
01144 
01145 
01146 void KWalletD::notifyFailures() {
01147     if (!_showingFailureNotify) {
01148         _showingFailureNotify = true;
01149         KMessageBox::information(0, i18n("There have been repeated failed attempts to gain access to a wallet. An application may be misbehaving."), i18n("KDE Wallet Service"));
01150         _showingFailureNotify = false;
01151     }
01152 }
01153 
01154 
01155 void KWalletD::doCloseSignals(int handle, const QString& wallet) {
01156     QByteArray data;
01157     QDataStream ds(data, IO_WriteOnly);
01158     ds << handle;
01159     emitDCOPSignal("walletClosed(int)", data);
01160 
01161     QByteArray data2;
01162     QDataStream ds2(data2, IO_WriteOnly);
01163     ds2 << wallet;
01164     emitDCOPSignal("walletClosed(QString)", data2);
01165 
01166     if (_wallets.isEmpty()) {
01167         emitDCOPSignal("allWalletsClosed()", QByteArray());
01168     }
01169 }
01170 
01171 
01172 int KWalletD::renameEntry(int handle, const QString& folder, const QString& oldName, const QString& newName) {
01173     KWallet::Backend *b;
01174 
01175     if ((b = getWallet(friendlyDCOPPeerName(), handle))) {
01176         b->setFolder(folder);
01177         int rc = b->renameEntry(oldName, newName);
01178         emitFolderUpdated(b->walletName(), folder);
01179         return rc;
01180     }
01181 
01182     return -1;
01183 }
01184 
01185 
01186 QStringList KWalletD::users(const QString& wallet) const {
01187     QStringList rc;
01188 
01189     for (QIntDictIterator<KWallet::Backend> it(_wallets);
01190                         it.current();
01191                             ++it) {
01192         if (it.current()->walletName() == wallet) {
01193             for (QMap<QCString,QValueList<int> >::ConstIterator hit = _handles.begin(); hit != _handles.end(); ++hit) {
01194                 if (hit.data().contains(it.currentKey())) {
01195                     rc += hit.key();
01196                 }
01197             }
01198             break;
01199         }
01200     }
01201 
01202     return rc;
01203 }
01204 
01205 
01206 bool KWalletD::disconnectApplication(const QString& wallet, const QCString& application) {
01207     for (QIntDictIterator<KWallet::Backend> it(_wallets);
01208                         it.current();
01209                             ++it) {
01210         if (it.current()->walletName() == wallet) {
01211             if (_handles[application].contains(it.currentKey())) {
01212                 _handles[application].remove(it.currentKey());
01213 
01214                 if (_handles[application].isEmpty()) {
01215                     _handles.remove(application);
01216                 }
01217 
01218                 if (it.current()->deref() == 0) {
01219                     close(it.current()->walletName(), true);
01220                 }
01221 
01222                 QByteArray data;
01223                 QDataStream ds(data, IO_WriteOnly);
01224                 ds << wallet;
01225                 ds << application;
01226                 emitDCOPSignal("applicationDisconnected(QString,QCString)", data);
01227 
01228                 return true;
01229             }
01230         }
01231     }
01232 
01233     return false;
01234 }
01235 
01236 
01237 void KWalletD::emitFolderUpdated(const QString& wallet, const QString& folder) {
01238     QByteArray data;
01239     QDataStream ds(data, IO_WriteOnly);
01240     ds << wallet;
01241     ds << folder;
01242     emitDCOPSignal("folderUpdated(QString,QString)", data);
01243 }
01244 
01245 
01246 void KWalletD::emitWalletListDirty() {
01247     emitDCOPSignal("walletListDirty()", QByteArray());
01248 }
01249 
01250 
01251 void KWalletD::reconfigure() {
01252     KConfig cfg("kwalletrc");
01253     cfg.setGroup("Wallet");
01254     _firstUse = cfg.readBoolEntry("First Use", true);
01255     _enabled = cfg.readBoolEntry("Enabled", true);
01256     _launchManager = cfg.readBoolEntry("Launch Manager", true);
01257     _leaveOpen = cfg.readBoolEntry("Leave Open", false);
01258     bool idleSave = _closeIdle;
01259     _closeIdle = cfg.readBoolEntry("Close When Idle", false);
01260     _openPrompt = cfg.readBoolEntry("Prompt on Open", true);
01261     int timeSave = _idleTime;
01262     // in minutes!
01263     _idleTime = cfg.readNumEntry("Idle Timeout", 10) * 60 * 1000;
01264 
01265     if (cfg.readBoolEntry("Close on Screensaver", false)) {
01266         connectDCOPSignal("kdesktop", "KScreensaverIface", "KDE_start_screensaver()", "closeAllWallets()", false);
01267     } else {
01268         disconnectDCOPSignal("kdesktop", "KScreensaverIface", "KDE_start_screensaver()", "closeAllWallets()");
01269     }
01270 
01271     // Handle idle changes
01272     if (_closeIdle) {
01273         if (_idleTime != timeSave) { // Timer length changed
01274             QIntDictIterator<KWallet::Backend> it(_wallets);
01275             for (; it.current(); ++it) {
01276                 _timeouts->resetTimer(it.currentKey(), _idleTime);
01277             }
01278         }
01279 
01280         if (!idleSave) { // add timers for all the wallets
01281             QIntDictIterator<KWallet::Backend> it(_wallets);
01282             for (; it.current(); ++it) {
01283                 _timeouts->addTimer(it.currentKey(), _idleTime);
01284             }
01285         }
01286     } else {
01287         _timeouts->clear();
01288     }
01289 
01290     // Update the implicit allow stuff
01291     _implicitAllowMap.clear();
01292     cfg.setGroup("Auto Allow");
01293     QStringList entries = cfg.entryMap("Auto Allow").keys();
01294     for (QStringList::Iterator i = entries.begin(); i != entries.end(); ++i) {
01295         _implicitAllowMap[*i] = cfg.readListEntry(*i);
01296     }
01297 
01298     // Update the implicit allow stuff
01299     _implicitDenyMap.clear();
01300     cfg.setGroup("Auto Deny");
01301     entries = cfg.entryMap("Auto Deny").keys();
01302     for (QStringList::Iterator i = entries.begin(); i != entries.end(); ++i) {
01303         _implicitDenyMap[*i] = cfg.readListEntry(*i);
01304     }
01305 
01306     // Update if wallet was enabled/disabled
01307     if (!_enabled) { // close all wallets
01308         while (!_wallets.isEmpty()) {
01309             QIntDictIterator<KWallet::Backend> it(_wallets);
01310             if (!it.current()) { // necessary?
01311                 break;
01312             }
01313             closeWallet(it.current(), it.currentKey(), true);
01314         }
01315     }
01316 }
01317 
01318 
01319 bool KWalletD::isEnabled() const {
01320     return _enabled;
01321 }
01322 
01323 
01324 bool KWalletD::folderDoesNotExist(const QString& wallet, const QString& folder) {
01325     if (!wallets().contains(wallet)) {
01326         return true;
01327     }
01328 
01329     for (QIntDictIterator<KWallet::Backend> it(_wallets); it.current(); ++it) {
01330         if (it.current()->walletName() == wallet) {
01331             return it.current()->folderDoesNotExist(folder);
01332         }
01333     }
01334 
01335     KWallet::Backend *b = new KWallet::Backend(wallet);
01336     b->open(QByteArray());
01337     bool rc = b->folderDoesNotExist(folder);
01338     delete b;
01339     return rc;
01340 }
01341 
01342 
01343 bool KWalletD::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key) {
01344     if (!wallets().contains(wallet)) {
01345         return true;
01346     }
01347 
01348     for (QIntDictIterator<KWallet::Backend> it(_wallets); it.current(); ++it) {
01349         if (it.current()->walletName() == wallet) {
01350             return it.current()->entryDoesNotExist(folder, key);
01351         }
01352     }
01353 
01354     KWallet::Backend *b = new KWallet::Backend(wallet);
01355     b->open(QByteArray());
01356     bool rc = b->entryDoesNotExist(folder, key);
01357     delete b;
01358     return rc;
01359 }
01360 
01361 
01362 bool KWalletD::implicitAllow(const QString& wallet, const QCString& app) {
01363     return _implicitAllowMap[wallet].contains(QString::fromLocal8Bit(app));
01364 }
01365 
01366 
01367 bool KWalletD::implicitDeny(const QString& wallet, const QCString& app) {
01368     return _implicitDenyMap[wallet].contains(QString::fromLocal8Bit(app));
01369 }
01370 
01371 
01372 QCString KWalletD::friendlyDCOPPeerName() {
01373     DCOPClient *dc = callingDcopClient();
01374     if (!dc) {
01375         return "";
01376     }
01377     return dc->senderId().replace(QRegExp("-[0-9]+$"), "");
01378 }
01379 
01380 
01381 void KWalletD::timedOut(int id) {
01382     KWallet::Backend *w = _wallets.find(id);
01383     if (w) {
01384         closeWallet(w, id, true);
01385     }
01386 }
01387 
01388 
01389 void KWalletD::closeAllWallets() {
01390     QIntDict<KWallet::Backend> tw = _wallets;
01391 
01392     for (QIntDictIterator<KWallet::Backend> it(tw); it.current(); ++it) {
01393         closeWallet(it.current(), it.currentKey(), true);
01394     }
01395 
01396     tw.clear();
01397 
01398     // All of this should be basically noop.  Let's just be safe.
01399     _wallets.clear();
01400 
01401     for (QMap<QString,QCString>::Iterator it = _passwords.begin();
01402                         it != _passwords.end();
01403                         ++it) {
01404         it.data().fill(0);
01405     }
01406     _passwords.clear();
01407 }
01408 
01409 
01410 QString KWalletD::networkWallet() {
01411     return KWallet::Wallet::NetworkWallet();
01412 }
01413 
01414 
01415 QString KWalletD::localWallet() {
01416     return KWallet::Wallet::LocalWallet();
01417 }
01418 
01419 
01420 #include "kwalletd.moc"
KDE Logo
This file is part of the documentation for kio Library Version 3.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Aug 2 12:24:28 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003