KDEUI
kwallet.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 * 00003 * Copyright (C) 2002-2004 George Staikos <staikos@kde.org> 00004 * Copyright (C) 2008 Michael Leupold <lemma@confuego.org> 00005 * Copyright (C) 2011 Valentin Rusu <kde@rusu.info> 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Library General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Library General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Library General Public License 00018 * along with this library; see the file COPYING.LIB. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00020 * Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #include "kwallet.h" 00024 #include "config-kwallet.h" 00025 00026 #include <QtGui/QApplication> 00027 #include <QtCore/QPointer> 00028 #include <QtGui/QWidget> 00029 #include <QtDBus/QtDBus> 00030 #include <ktoolinvocation.h> 00031 00032 #include <assert.h> 00033 #include <kcomponentdata.h> 00034 #include <kconfiggroup.h> 00035 #include <kdebug.h> 00036 #include <kdeversion.h> 00037 #include <kglobal.h> 00038 #include <kaboutdata.h> 00039 #include <ksharedconfig.h> 00040 #include <kwindowsystem.h> 00041 00042 #ifdef HAVE_KSECRETSSERVICE 00043 #include "ksecretsservice/ksecretsservicecollection.h" 00044 #endif 00045 00046 #include "kwallet_interface.h" 00047 00048 #ifdef HAVE_KSECRETSSERVICE 00049 typedef QMap<QString, KSecretsService::StringStringMap> StringToStringStringMapMap; 00050 Q_DECLARE_METATYPE(StringToStringStringMapMap) 00051 #endif 00052 typedef QMap<QString, QByteArray> StringByteArrayMap; 00053 Q_DECLARE_METATYPE(StringByteArrayMap) 00054 00055 namespace KWallet 00056 { 00057 00058 class KWalletDLauncher 00059 { 00060 public: 00061 KWalletDLauncher(); 00062 ~KWalletDLauncher(); 00063 org::kde::KWallet &getInterface(); 00064 00065 // this static variable is used below to switch between old KWallet 00066 // infrastructure and the new one which is built on top of the new 00067 // KSecretsService infrastructure. It's value can be changed via the 00068 // the Wallet configuration module in System Settings 00069 bool m_useKSecretsService; 00070 org::kde::KWallet *m_wallet; 00071 KConfigGroup m_cgroup; 00072 }; 00073 00074 K_GLOBAL_STATIC(KWalletDLauncher, walletLauncher) 00075 00076 static QString appid() 00077 { 00078 if (KGlobal::hasMainComponent()) { 00079 KComponentData cData = KGlobal::mainComponent(); 00080 if (cData.isValid()) { 00081 const KAboutData* aboutData = cData.aboutData(); 00082 if (aboutData) { 00083 return aboutData->programName(); 00084 } 00085 return cData.componentName(); 00086 } 00087 } 00088 return qApp->applicationName(); 00089 } 00090 00091 static void registerTypes() 00092 { 00093 static bool registered = false; 00094 if (!registered) { 00095 #ifdef HAVE_KSECRETSSERVICE 00096 qDBusRegisterMetaType<KSecretsService::StringStringMap>(); 00097 qDBusRegisterMetaType<StringToStringStringMapMap>(); 00098 #endif 00099 qDBusRegisterMetaType<StringByteArrayMap>(); 00100 registered = true; 00101 } 00102 } 00103 00104 bool Wallet::isUsingKSecretsService() 00105 { 00106 return walletLauncher->m_useKSecretsService; 00107 } 00108 00109 const QString Wallet::LocalWallet() { 00110 // NOTE: This method stays unchanged for KSecretsService 00111 KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet")); 00112 if (!cfg.readEntry("Use One Wallet", true)) { 00113 QString tmp = cfg.readEntry("Local Wallet", "localwallet"); 00114 if (tmp.isEmpty()) { 00115 return "localwallet"; 00116 } 00117 return tmp; 00118 } 00119 00120 QString tmp = cfg.readEntry("Default Wallet", "kdewallet"); 00121 if (tmp.isEmpty()) { 00122 return "kdewallet"; 00123 } 00124 return tmp; 00125 } 00126 00127 const QString Wallet::NetworkWallet() { 00128 // NOTE: This method stays unchanged for KSecretsService 00129 KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet")); 00130 00131 QString tmp = cfg.readEntry("Default Wallet", "kdewallet"); 00132 if (tmp.isEmpty()) { 00133 return "kdewallet"; 00134 } 00135 return tmp; 00136 } 00137 00138 const QString Wallet::PasswordFolder() { 00139 return "Passwords"; 00140 } 00141 00142 const QString Wallet::FormDataFolder() { 00143 return "Form Data"; 00144 } 00145 00146 class Wallet::WalletPrivate 00147 { 00148 public: 00149 WalletPrivate(Wallet *wallet, int h, const QString &n) 00150 : q(wallet), name(n), handle(h) 00151 #ifdef HAVE_KSECRETSSERVICE 00152 , secretsCollection(0) 00153 #endif 00154 {} 00155 00156 void walletServiceUnregistered(); 00157 00158 #ifdef HAVE_KSECRETSSERVICE 00159 template <typename T> 00160 int writeEntry( const QString& key, const T &value, Wallet::EntryType entryType ) { 00161 int rc = -1; 00162 KSecretsService::Secret secret; 00163 secret.setValue( QVariant::fromValue<T>(value) ); 00164 00165 KSecretsService::StringStringMap attrs; 00166 attrs[KSS_ATTR_ENTRYFOLDER] = folder; 00167 attrs[KSS_ATTR_WALLETTYPE] = QString("%1").arg((int)entryType); 00168 KSecretsService::CreateCollectionItemJob *createItemJob = secretsCollection->createItem( key, attrs, secret ); 00169 00170 if ( !createItemJob->exec() ) { 00171 kDebug(285) << "Cannot execute CreateCollectionItemJob : " << createItemJob->errorString(); 00172 } 00173 rc = createItemJob->error(); 00174 return rc; 00175 } 00176 00177 QExplicitlySharedDataPointer<KSecretsService::SecretItem> findItem( const QString& key ) const; 00178 template <typename T> int readEntry( const QString& key, T& value ) const; 00179 bool readSecret( const QString& key, KSecretsService::Secret& value ) const; 00180 00181 template <typename V> 00182 int forEachItemThatMatches( const QString &key, V verb ) { 00183 int rc = -1; 00184 KSecretsService::StringStringMap attrs; 00185 attrs[KSS_ATTR_ENTRYFOLDER] = folder; 00186 KSecretsService::SearchCollectionItemsJob *searchItemsJob = secretsCollection->searchItems(attrs); 00187 if ( searchItemsJob->exec() ) { 00188 QRegExp re(key, Qt::CaseSensitive, QRegExp::Wildcard); 00189 foreach( KSecretsService::SearchCollectionItemsJob::Item item , searchItemsJob->items() ) { 00190 KSecretsService::ReadItemPropertyJob *readLabelJob = item->label(); 00191 if ( readLabelJob->exec() ) { 00192 QString label = readLabelJob->propertyValue().toString(); 00193 if ( re.exactMatch( label ) ) { 00194 if ( verb( this, label, item.data() ) ) { 00195 rc = 0; // one successfull iteration already produced results, so success return 00196 } 00197 } 00198 } 00199 else { 00200 kDebug(285) << "Cannot execute ReadItemPropertyJob " << readLabelJob->errorString(); 00201 } 00202 } 00203 } 00204 else { 00205 kDebug(285) << "Cannot execute KSecretsService::SearchCollectionItemsJob " << searchItemsJob->errorString(); 00206 } 00207 return rc; 00208 } 00209 00210 void createDefaultFolders(); 00211 00212 struct InsertIntoEntryList; 00213 struct InsertIntoMapList; 00214 struct InsertIntoPasswordList; 00215 00216 KSecretsService::Collection *secretsCollection; 00217 #endif // HAVE_KSECRETSSERVICE 00218 00219 Wallet *q; 00220 QString name; 00221 QString folder; 00222 int handle; 00223 int transactionId; 00224 QPointer<QEventLoop> loop; 00225 }; 00226 00227 #ifdef HAVE_KSECRETSSERVICE 00228 void Wallet::WalletPrivate::createDefaultFolders() 00229 { 00230 // NOTE: KWalletManager expects newly created wallets to have two default folders 00231 // b->createFolder(KWallet::Wallet::PasswordFolder()); 00232 // b->createFolder(KWallet::Wallet::FormDataFolder()); 00233 QString strDummy(""); 00234 folder = PasswordFolder(); 00235 writeEntry( PasswordFolder(), strDummy, KWallet::Wallet::Unknown ); 00236 00237 folder = FormDataFolder(); 00238 writeEntry( FormDataFolder(), strDummy, KWallet::Wallet::Unknown ); 00239 } 00240 #endif // HAVE_KSECRETSSERVICE 00241 00242 static const char s_kwalletdServiceName[] = "org.kde.kwalletd"; 00243 00244 Wallet::Wallet(int handle, const QString& name) 00245 : QObject(0L), d(new WalletPrivate(this, handle, name)) 00246 { 00247 if (walletLauncher->m_useKSecretsService) { 00248 // see openWallet for initialization code; this constructor does not have any code 00249 } 00250 else { 00251 QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QString::fromLatin1(s_kwalletdServiceName), QDBusConnection::sessionBus(), 00252 QDBusServiceWatcher::WatchForUnregistration, this); 00253 connect(watcher, SIGNAL(serviceUnregistered(QString)), 00254 this, SLOT(walletServiceUnregistered())); 00255 00256 connect(&walletLauncher->getInterface(), SIGNAL(walletClosed(int)), SLOT(slotWalletClosed(int))); 00257 connect(&walletLauncher->getInterface(), SIGNAL(folderListUpdated(QString)), SLOT(slotFolderListUpdated(QString))); 00258 connect(&walletLauncher->getInterface(), SIGNAL(folderUpdated(QString,QString)), SLOT(slotFolderUpdated(QString,QString))); 00259 connect(&walletLauncher->getInterface(), SIGNAL(applicationDisconnected(QString,QString)), SLOT(slotApplicationDisconnected(QString,QString))); 00260 00261 // Verify that the wallet is still open 00262 if (d->handle != -1) { 00263 QDBusReply<bool> r = walletLauncher->getInterface().isOpen(d->handle); 00264 if (r.isValid() && !r) { 00265 d->handle = -1; 00266 d->name.clear(); 00267 } 00268 } 00269 } 00270 } 00271 00272 00273 Wallet::~Wallet() { 00274 #ifdef HAVE_KSECRETSSERVICE 00275 if (walletLauncher->m_useKSecretsService) { 00276 d->folder.clear(); 00277 d->name.clear(); 00278 delete d->secretsCollection; 00279 } 00280 else { 00281 #endif 00282 if (d->handle != -1) { 00283 if (!walletLauncher.isDestroyed()) { 00284 walletLauncher->getInterface().close(d->handle, false, appid()); 00285 } else { 00286 kDebug(285) << "Problem with static destruction sequence." 00287 "Destroy any static Wallet before the event-loop exits."; 00288 } 00289 d->handle = -1; 00290 d->folder.clear(); 00291 d->name.clear(); 00292 } 00293 #ifdef HAVE_KSECRETSSERVICE 00294 } 00295 #endif 00296 delete d; 00297 } 00298 00299 00300 QStringList Wallet::walletList() { 00301 QStringList result; 00302 #ifdef HAVE_KSECRETSSERVICE 00303 if (walletLauncher->m_useKSecretsService) { 00304 KSecretsService::ListCollectionsJob *listJob = KSecretsService::Collection::listCollections(); 00305 if ( listJob->exec() ) { 00306 result = listJob->collections(); 00307 } 00308 else { 00309 kDebug(285) << "Cannot execute ListCollectionsJob: " << listJob->errorString(); 00310 } 00311 } 00312 else { 00313 #endif 00314 QDBusReply<QStringList> r = walletLauncher->getInterface().wallets(); 00315 00316 if (!r.isValid()) 00317 { 00318 kDebug(285) << "Invalid DBus reply: " << r.error(); 00319 } 00320 else 00321 result = r; 00322 #ifdef HAVE_KSECRETSSERVICE 00323 } 00324 #endif 00325 return result; 00326 } 00327 00328 00329 void Wallet::changePassword(const QString& name, WId w) { 00330 if( w == 0 ) 00331 kDebug(285) << "Pass a valid window to KWallet::Wallet::changePassword()."; 00332 00333 // Make sure the password prompt window will be visible and activated 00334 KWindowSystem::allowExternalProcessWindowActivation(); 00335 #ifdef HAVE_KSECRETSSERVICE 00336 if (walletLauncher->m_useKSecretsService) { 00337 KSecretsService::Collection *coll = KSecretsService::Collection::findCollection( name ); 00338 KSecretsService::ChangeCollectionPasswordJob* changePwdJob = coll->changePassword(); 00339 if ( !changePwdJob->exec() ) { 00340 kDebug(285) << "Cannot execute change password job: " << changePwdJob->errorString(); 00341 } 00342 coll->deleteLater(); 00343 } 00344 else { 00345 #endif 00346 walletLauncher->getInterface().changePassword(name, (qlonglong)w, appid()); 00347 #ifdef HAVE_KSECRETSSERVICE 00348 } 00349 #endif 00350 } 00351 00352 00353 bool Wallet::isEnabled() { 00354 #ifdef HAVE_KSECRETSSERVICE 00355 if (walletLauncher->m_useKSecretsService) { 00356 return walletLauncher->m_cgroup.readEntry("Enabled", true); 00357 } 00358 else { 00359 #endif 00360 QDBusReply<bool> r = walletLauncher->getInterface().isEnabled(); 00361 00362 if (!r.isValid()) 00363 { 00364 kDebug(285) << "Invalid DBus reply: " << r.error(); 00365 return false; 00366 } 00367 else 00368 return r; 00369 #ifdef HAVE_KSECRETSSERVICE 00370 } 00371 #endif 00372 } 00373 00374 00375 bool Wallet::isOpen(const QString& name) { 00376 #ifdef HAVE_KSECRETSSERVICE 00377 if (walletLauncher->m_useKSecretsService) { 00378 KSecretsService::Collection *coll = KSecretsService::Collection::findCollection( name, KSecretsService::Collection::OpenOnly ); 00379 KSecretsService::ReadCollectionPropertyJob *readLocked = coll->isLocked(); 00380 if ( readLocked->exec() ) { 00381 return !readLocked->propertyValue().toBool(); 00382 } 00383 else { 00384 kDebug() << "ReadLocked job failed"; 00385 return false; 00386 } 00387 } 00388 else { 00389 #endif 00390 QDBusReply<bool> r = walletLauncher->getInterface().isOpen(name); 00391 00392 if (!r.isValid()) 00393 { 00394 kDebug(285) << "Invalid DBus reply: " << r.error(); 00395 return false; 00396 } 00397 else 00398 return r; 00399 #ifdef HAVE_KSECRETSSERVICE 00400 } 00401 #endif 00402 } 00403 00404 int Wallet::closeWallet(const QString& name, bool force) { 00405 #ifdef HAVE_KSECRETSSERVICE 00406 if (walletLauncher->m_useKSecretsService) { 00407 kDebug(285) << "Wallet::closeWallet NOOP"; 00408 return 0; 00409 } 00410 else { 00411 #endif 00412 QDBusReply<int> r = walletLauncher->getInterface().close(name, force); 00413 00414 if (!r.isValid()) 00415 { 00416 kDebug(285) << "Invalid DBus reply: " << r.error(); 00417 return -1; 00418 } 00419 else 00420 return r; 00421 #ifdef HAVE_KSECRETSSERVICE 00422 } 00423 #endif 00424 } 00425 00426 00427 int Wallet::deleteWallet(const QString& name) { 00428 #ifdef HAVE_KSECRETSSERVICE 00429 if (walletLauncher->m_useKSecretsService) { 00430 KSecretsService::Collection *coll = KSecretsService::Collection::findCollection(name, KSecretsService::Collection::OpenOnly); 00431 KJob *deleteJob = coll->deleteCollection(); 00432 if (!deleteJob->exec()) { 00433 kDebug(285) << "Cannot execute delete job " << deleteJob->errorString(); 00434 } 00435 return deleteJob->error(); 00436 } 00437 else { 00438 #endif 00439 QDBusReply<int> r = walletLauncher->getInterface().deleteWallet(name); 00440 00441 if (!r.isValid()) 00442 { 00443 kDebug(285) << "Invalid DBus reply: " << r.error(); 00444 return -1; 00445 } 00446 else 00447 return r; 00448 #ifdef HAVE_KSECRETSSERVICE 00449 } 00450 #endif 00451 } 00452 00453 Wallet *Wallet::openWallet(const QString& name, WId w, OpenType ot) { 00454 if( w == 0 ) 00455 kDebug(285) << "Pass a valid window to KWallet::Wallet::openWallet()."; 00456 00457 #ifdef HAVE_KSECRETSSERVICE 00458 if (walletLauncher->m_useKSecretsService) { 00459 Wallet *wallet = new Wallet(-1, name); 00460 // FIXME: should we specify CreateCollection or OpenOnly here? 00461 wallet->d->secretsCollection = KSecretsService::Collection::findCollection(name, KSecretsService::Collection::CreateCollection, QVariantMap(), w); 00462 connect( wallet->d->secretsCollection, SIGNAL(statusChanged(int)), wallet, SLOT(slotCollectionStatusChanged(int)) ); 00463 connect( wallet->d->secretsCollection, SIGNAL(deleted()), wallet, SLOT(slotCollectionDeleted()) ); 00464 if ( ot == Synchronous ) { 00465 kDebug() << "WARNING openWallet OpenType=Synchronous requested"; 00466 // TODO: not sure what to do with in this case; however, all other KSecretsService API methods are already 00467 // async and will perform sync inside this API because of it's design 00468 } 00469 return wallet; 00470 } 00471 else { 00472 #endif 00473 Wallet *wallet = new Wallet(-1, name); 00474 00475 // connect the daemon's opened signal to the slot filtering the 00476 // signals we need 00477 connect(&walletLauncher->getInterface(), SIGNAL(walletAsyncOpened(int,int)), 00478 wallet, SLOT(walletAsyncOpened(int,int))); 00479 00480 // Use an eventloop for synchronous calls 00481 QEventLoop loop; 00482 if (ot == Synchronous || ot == Path) { 00483 connect(wallet, SIGNAL(walletOpened(bool)), &loop, SLOT(quit())); 00484 } 00485 00486 // Make sure the password prompt window will be visible and activated 00487 KWindowSystem::allowExternalProcessWindowActivation(); 00488 00489 // do the call 00490 QDBusReply<int> r; 00491 if (ot == Synchronous || ot == Asynchronous) { 00492 r = walletLauncher->getInterface().openAsync(name, (qlonglong)w, appid(), true); 00493 } else if (ot == Path) { 00494 r = walletLauncher->getInterface().openPathAsync(name, (qlonglong)w, appid(), true); 00495 } else { 00496 delete wallet; 00497 return 0; 00498 } 00499 // error communicating with the daemon (maybe not running) 00500 if (!r.isValid()) { 00501 kDebug(285) << "Invalid DBus reply: " << r.error(); 00502 delete wallet; 00503 return 0; 00504 } 00505 wallet->d->transactionId = r.value(); 00506 00507 if (ot == Synchronous || ot == Path) { 00508 // check for an immediate error 00509 if (wallet->d->transactionId < 0) { 00510 delete wallet; 00511 wallet = 0; 00512 } else { 00513 // wait for the daemon's reply 00514 // store a pointer to the event loop so it can be quit in error case 00515 wallet->d->loop = &loop; 00516 loop.exec(); 00517 if (wallet->d->handle < 0) { 00518 delete wallet; 00519 return 0; 00520 } 00521 } 00522 } else if (ot == Asynchronous) { 00523 if (wallet->d->transactionId < 0) { 00524 QTimer::singleShot(0, wallet, SLOT(emitWalletAsyncOpenError())); 00525 // client code is responsible for deleting the wallet 00526 } 00527 } 00528 00529 return wallet; 00530 #ifdef HAVE_KSECRETSSERVICE 00531 } 00532 #endif 00533 } 00534 00535 void Wallet::slotCollectionStatusChanged(int status) 00536 { 00537 #ifdef HAVE_KSECRETSSERVICE 00538 KSecretsService::Collection::Status collStatus = (KSecretsService::Collection::Status)status; 00539 switch ( collStatus ) { 00540 case KSecretsService::Collection::NewlyCreated: 00541 d->createDefaultFolders(); 00542 // fall through 00543 case KSecretsService::Collection::FoundExisting: 00544 emitWalletOpened(); 00545 break; 00546 case KSecretsService::Collection::Deleted: 00547 case KSecretsService::Collection::Invalid: 00548 case KSecretsService::Collection::Pending: 00549 // nothing to do 00550 break; 00551 case KSecretsService::Collection::NotFound: 00552 emitWalletAsyncOpenError(); 00553 break; 00554 } 00555 #endif 00556 } 00557 00558 void Wallet::slotCollectionDeleted() 00559 { 00560 d->folder.clear(); 00561 d->name.clear(); 00562 emit walletClosed(); 00563 } 00564 00565 bool Wallet::disconnectApplication(const QString& wallet, const QString& app) { 00566 #ifdef HAVE_KSECRETSSERVICE 00567 if (walletLauncher->m_useKSecretsService) { 00568 kDebug() << "Wallet::disconnectApplication NOOP"; 00569 return true; 00570 } 00571 else { 00572 #endif 00573 QDBusReply<bool> r = walletLauncher->getInterface().disconnectApplication(wallet, app); 00574 00575 if (!r.isValid()) 00576 { 00577 kDebug(285) << "Invalid DBus reply: " << r.error(); 00578 return false; 00579 } 00580 else 00581 return r; 00582 #ifdef HAVE_KSECRETSSERVICE 00583 } 00584 #endif 00585 } 00586 00587 00588 QStringList Wallet::users(const QString& name) { 00589 #ifdef HAVE_KSECRETSSERVICE 00590 if (walletLauncher->m_useKSecretsService) { 00591 kDebug() << "KSecretsService does not handle users list"; 00592 return QStringList(); 00593 } 00594 else { 00595 #endif 00596 QDBusReply<QStringList> r = walletLauncher->getInterface().users(name); 00597 if (!r.isValid()) 00598 { 00599 kDebug(285) << "Invalid DBus reply: " << r.error(); 00600 return QStringList(); 00601 } 00602 else 00603 return r; 00604 #ifdef HAVE_KSECRETSSERVICE 00605 } 00606 #endif 00607 } 00608 00609 00610 int Wallet::sync() { 00611 #ifdef HAVE_KSECRETSSERVICE 00612 if (walletLauncher->m_useKSecretsService) { 00613 // NOOP with KSecretsService 00614 } 00615 else { 00616 #endif 00617 if (d->handle == -1) { 00618 return -1; 00619 } 00620 00621 walletLauncher->getInterface().sync(d->handle, appid()); 00622 #ifdef HAVE_KSECRETSSERVICE 00623 } 00624 #endif 00625 return 0; 00626 } 00627 00628 00629 int Wallet::lockWallet() { 00630 #ifdef HAVE_KSECRETSSERVICE 00631 if (walletLauncher->m_useKSecretsService) { 00632 KSecretsService::CollectionLockJob *lockJob = d->secretsCollection->lock(); 00633 if (lockJob->exec()) { 00634 d->folder.clear(); 00635 d->name.clear(); 00636 } 00637 else { 00638 kDebug(285) << "Cannot execute KSecretsService::CollectionLockJob : " << lockJob->errorString(); 00639 return -1; 00640 } 00641 return lockJob->error(); 00642 } 00643 else { 00644 #endif 00645 if (d->handle == -1) { 00646 return -1; 00647 } 00648 00649 QDBusReply<int> r = walletLauncher->getInterface().close(d->handle, true, appid()); 00650 d->handle = -1; 00651 d->folder.clear(); 00652 d->name.clear(); 00653 if (r.isValid()) { 00654 return r; 00655 } 00656 else { 00657 kDebug(285) << "Invalid DBus reply: " << r.error(); 00658 return -1; 00659 } 00660 #ifdef HAVE_KSECRETSSERVICE 00661 } 00662 #endif 00663 } 00664 00665 00666 const QString& Wallet::walletName() const { 00667 return d->name; 00668 } 00669 00670 00671 bool Wallet::isOpen() const { 00672 #ifdef HAVE_KSECRETSSERVICE 00673 if (walletLauncher->m_useKSecretsService) { 00674 return !d->secretsCollection->isLocked(); 00675 } 00676 else { 00677 #endif 00678 return d->handle != -1; 00679 #ifdef HAVE_KSECRETSSERVICE 00680 } 00681 #endif 00682 } 00683 00684 00685 void Wallet::requestChangePassword(WId w) { 00686 if( w == 0 ) 00687 kDebug(285) << "Pass a valid window to KWallet::Wallet::requestChangePassword()."; 00688 00689 #ifdef HAVE_KSECRETSSERVICE 00690 if (walletLauncher->m_useKSecretsService) { 00691 KSecretsService::ChangeCollectionPasswordJob *changePwdJob = d->secretsCollection->changePassword(); 00692 if (!changePwdJob->exec()) { 00693 kDebug(285) << "Cannot execute ChangeCollectionPasswordJob : " << changePwdJob->errorString(); 00694 } 00695 } 00696 else { 00697 #endif 00698 if (d->handle == -1) { 00699 return; 00700 } 00701 00702 // Make sure the password prompt window will be visible and activated 00703 KWindowSystem::allowExternalProcessWindowActivation(); 00704 00705 walletLauncher->getInterface().changePassword(d->name, (qlonglong)w, appid()); 00706 #ifdef HAVE_KSECRETSSERVICE 00707 } 00708 #endif 00709 } 00710 00711 00712 void Wallet::slotWalletClosed(int handle) { 00713 #ifdef HAVE_KSECRETSSERVICE 00714 if (walletLauncher->m_useKSecretsService) { 00715 // TODO: implement this 00716 Q_ASSERT(0); 00717 } 00718 else { 00719 #endif 00720 if (d->handle == handle) { 00721 d->handle = -1; 00722 d->folder.clear(); 00723 d->name.clear(); 00724 emit walletClosed(); 00725 } 00726 #ifdef HAVE_KSECRETSSERVICE 00727 } 00728 #endif 00729 } 00730 00731 00732 QStringList Wallet::folderList() { 00733 #ifdef HAVE_KSECRETSSERVICE 00734 if (walletLauncher->m_useKSecretsService) { 00735 QStringList result; 00736 00737 KSecretsService::StringStringMap attrs; 00738 attrs[KSS_ATTR_ENTRYFOLDER] = ""; // search for items having this attribute no matter what value it has 00739 KSecretsService::SearchCollectionItemsJob *searchJob = d->secretsCollection->searchItems(attrs); 00740 00741 if (searchJob->exec()) { 00742 KSecretsService::ReadCollectionItemsJob::ItemList itemList = searchJob->items(); 00743 foreach( const KSecretsService::ReadCollectionItemsJob::Item &item, itemList ) { 00744 KSecretsService::ReadItemPropertyJob *readAttrsJob = item->attributes(); 00745 if (readAttrsJob->exec()) { 00746 KSecretsService::StringStringMap attrs = readAttrsJob->propertyValue().value<KSecretsService::StringStringMap>(); 00747 const QString folder = attrs[KSS_ATTR_ENTRYFOLDER]; 00748 if (!folder.isEmpty() && !result.contains(folder)) { 00749 result.append(folder); 00750 } 00751 } 00752 else { 00753 kDebug(285) << "Cannot read item attributes : " << readAttrsJob->errorString(); 00754 } 00755 } 00756 } 00757 else { 00758 kDebug(285) << "Cannot execute ReadCollectionItemsJob : " << searchJob->errorString(); 00759 } 00760 return result; 00761 } 00762 else { 00763 #endif 00764 if (d->handle == -1) { 00765 return QStringList(); 00766 } 00767 00768 QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle, appid()); 00769 if (!r.isValid()) 00770 { 00771 kDebug(285) << "Invalid DBus reply: " << r.error(); 00772 return QStringList(); 00773 } 00774 else 00775 return r; 00776 #ifdef HAVE_KSECRETSSERVICE 00777 } 00778 #endif 00779 } 00780 00781 00782 QStringList Wallet::entryList() { 00783 #ifdef HAVE_KSECRETSSERVICE 00784 if (walletLauncher->m_useKSecretsService) { 00785 QStringList result; 00786 KSecretsService::StringStringMap attrs; 00787 attrs[KSS_ATTR_ENTRYFOLDER] = d->folder; 00788 KSecretsService::SearchCollectionItemsJob *readItemsJob = d->secretsCollection->searchItems( attrs ); 00789 if ( readItemsJob->exec() ) { 00790 foreach( KSecretsService::SearchCollectionItemsJob::Item item, readItemsJob->items() ) { 00791 KSecretsService::ReadItemPropertyJob *readLabelJob = item->label(); 00792 if ( readLabelJob->exec() ) { 00793 result.append( readLabelJob->propertyValue().toString() ); 00794 } 00795 else { 00796 kDebug(285) << "Cannot execute readLabelJob" << readItemsJob->errorString(); 00797 } 00798 } 00799 } 00800 else { 00801 kDebug(285) << "Cannot execute readItemsJob" << readItemsJob->errorString(); 00802 } 00803 return result; 00804 } 00805 else { 00806 #endif 00807 if (d->handle == -1) { 00808 return QStringList(); 00809 } 00810 00811 QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder, appid()); 00812 if (!r.isValid()) 00813 { 00814 kDebug(285) << "Invalid DBus reply: " << r.error(); 00815 return QStringList(); 00816 } 00817 else 00818 return r; 00819 #ifdef HAVE_KSECRETSSERVICE 00820 } 00821 #endif 00822 } 00823 00824 00825 bool Wallet::hasFolder(const QString& f) { 00826 #ifdef HAVE_KSECRETSSERVICE 00827 if (walletLauncher->m_useKSecretsService) { 00828 // FIXME: well, this is not the best implementation, but it's done quickly :) 00829 // the best way would be to searchItems with the attribute label having the value f 00830 // doing that would reduce DBus traffic. But KWallet API wille not last. 00831 QStringList folders = folderList(); 00832 return folders.contains(f); 00833 } 00834 else { 00835 #endif 00836 if (d->handle == -1) { 00837 return false; 00838 } 00839 00840 QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f, appid()); 00841 if (!r.isValid()) 00842 { 00843 kDebug(285) << "Invalid DBus reply: " << r.error(); 00844 return false; 00845 } 00846 else 00847 return r; 00848 #ifdef HAVE_KSECRETSSERVICE 00849 } 00850 #endif 00851 } 00852 00853 00854 bool Wallet::createFolder(const QString& f) { 00855 #ifdef HAVE_KSECRETSSERVICE 00856 if (walletLauncher->m_useKSecretsService) { 00857 QString strDummy(""); 00858 d->folder = f; 00859 d->writeEntry( f, strDummy, KWallet::Wallet::Unknown ); 00860 return true; 00861 } 00862 else { 00863 #endif 00864 if (d->handle == -1) { 00865 return false; 00866 } 00867 00868 if (!hasFolder(f)) { 00869 QDBusReply<bool> r = walletLauncher->getInterface().createFolder(d->handle, f, appid()); 00870 00871 if (!r.isValid()) 00872 { 00873 kDebug(285) << "Invalid DBus reply: " << r.error(); 00874 return false; 00875 } 00876 else 00877 return r; 00878 } 00879 00880 return true; // folder already exists 00881 #ifdef HAVE_KSECRETSSERVICE 00882 } 00883 #endif 00884 } 00885 00886 00887 bool Wallet::setFolder(const QString& f) { 00888 bool rc = false; 00889 00890 #ifdef HAVE_KSECRETSSERVICE 00891 if (walletLauncher->m_useKSecretsService) { 00892 if (hasFolder(f)) { 00893 d->folder = f; 00894 rc = true; 00895 } 00896 } 00897 else { 00898 #endif 00899 if (d->handle == -1) { 00900 return rc; 00901 } 00902 00903 // Don't do this - the folder could have disappeared? 00904 #if 0 00905 if (f == d->folder) { 00906 return true; 00907 } 00908 #endif 00909 00910 if (hasFolder(f)) { 00911 d->folder = f; 00912 rc = true; 00913 } 00914 #ifdef HAVE_KSECRETSSERVICE 00915 } 00916 #endif 00917 00918 return rc; 00919 } 00920 00921 00922 bool Wallet::removeFolder(const QString& f) { 00923 #ifdef HAVE_KSECRETSSERVICE 00924 if (walletLauncher->m_useKSecretsService) { 00925 bool result = false; 00926 // search for all items having the folder f then delete them 00927 KSecretsService::StringStringMap attrs; 00928 attrs[KSS_ATTR_ENTRYFOLDER] = f; 00929 KSecretsService::SearchCollectionItemsJob *searchJob = d->secretsCollection->searchItems(attrs); 00930 if (searchJob->exec()) { 00931 KSecretsService::SearchCollectionItemsJob::ItemList itemList = searchJob->items(); 00932 if ( !itemList.isEmpty() ) { 00933 result = true; 00934 foreach( const KSecretsService::SearchCollectionItemsJob::Item &item, itemList ) { 00935 KSecretsService::SecretItemDeleteJob *deleteJob = item->deleteItem(); 00936 if (!deleteJob->exec()) { 00937 kDebug(285) << "Cannot delete item : " << deleteJob->errorString(); 00938 result = false; 00939 } 00940 result &= true; 00941 } 00942 } 00943 } 00944 else { 00945 kDebug(285) << "Cannot execute KSecretsService::SearchCollectionItemsJob : " << searchJob->errorString(); 00946 } 00947 return result; 00948 } 00949 else { 00950 #endif 00951 if (d->handle == -1) { 00952 return false; 00953 } 00954 00955 QDBusReply<bool> r = walletLauncher->getInterface().removeFolder(d->handle, f, appid()); 00956 if (d->folder == f) { 00957 setFolder(QString()); 00958 } 00959 00960 if (!r.isValid()) 00961 { 00962 kDebug(285) << "Invalid DBus reply: " << r.error(); 00963 return false; 00964 } 00965 else 00966 return r; 00967 #ifdef HAVE_KSECRETSSERVICE 00968 } 00969 #endif 00970 } 00971 00972 00973 const QString& Wallet::currentFolder() const { 00974 return d->folder; 00975 } 00976 00977 #ifdef HAVE_KSECRETSSERVICE 00978 QExplicitlySharedDataPointer<KSecretsService::SecretItem> Wallet::WalletPrivate::findItem( const QString& key ) const 00979 { 00980 QExplicitlySharedDataPointer<KSecretsService::SecretItem> result; 00981 KSecretsService::StringStringMap attrs; 00982 attrs[KSS_ATTR_ENTRYFOLDER] = folder; 00983 attrs["Label"] = key; 00984 KSecretsService::SearchCollectionItemsJob *searchJob = secretsCollection->searchItems(attrs); 00985 if (searchJob->exec()) { 00986 KSecretsService::SearchCollectionItemsJob::ItemList itemList = searchJob->items(); 00987 if ( !itemList.isEmpty() ) { 00988 result = itemList.first(); 00989 } 00990 else { 00991 kDebug(285) << "entry named " << key << " not found in folder " << folder; 00992 } 00993 } 00994 else { 00995 kDebug(285) << "Cannot exec KSecretsService::SearchCollectionItemsJob : " << searchJob->errorString(); 00996 } 00997 00998 return result; 00999 } 01000 01001 template <typename T> 01002 int Wallet::WalletPrivate::readEntry(const QString& key, T& value) const 01003 { 01004 int rc = -1; 01005 QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = findItem(key); 01006 if ( item ) { 01007 KSecretsService::GetSecretItemSecretJob *readJob = item->getSecret(); 01008 if ( readJob->exec() ) { 01009 KSecretsService::Secret theSecret = readJob->secret(); 01010 kDebug(285) << "Secret contentType is " << theSecret.contentType(); 01011 value = theSecret.value().value<T>(); 01012 rc = 0; 01013 } 01014 else { 01015 kDebug(285) << "Cannot exec GetSecretItemSecretJob : " << readJob->errorString(); 01016 } 01017 } 01018 return rc; 01019 } 01020 01021 bool Wallet::WalletPrivate::readSecret(const QString& key, KSecretsService::Secret& value) const 01022 { 01023 bool result = false; 01024 QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = findItem(key); 01025 if ( item ) { 01026 KSecretsService::GetSecretItemSecretJob *readJob = item->getSecret(); 01027 if ( readJob->exec() ) { 01028 value = readJob->secret(); 01029 result = true; 01030 } 01031 else { 01032 kDebug(285) << "Cannot exec GetSecretItemSecretJob : " << readJob->errorString(); 01033 } 01034 } 01035 return result; 01036 } 01037 #endif 01038 01039 int Wallet::readEntry(const QString& key, QByteArray& value) { 01040 int rc = -1; 01041 01042 #ifdef HAVE_KSECRETSSERVICE 01043 if (walletLauncher->m_useKSecretsService) { 01044 return d->readEntry<QByteArray>(key, value); 01045 } 01046 else { 01047 #endif 01048 if (d->handle == -1) { 01049 return rc; 01050 } 01051 01052 QDBusReply<QByteArray> r = walletLauncher->getInterface().readEntry(d->handle, d->folder, key, appid()); 01053 if (r.isValid()) { 01054 value = r; 01055 rc = 0; 01056 } 01057 #ifdef HAVE_KSECRETSSERVICE 01058 } 01059 #endif 01060 01061 return rc; 01062 } 01063 01064 #ifdef HAVE_KSECRETSSERVICE 01065 struct Wallet::WalletPrivate::InsertIntoEntryList { 01066 InsertIntoEntryList( QMap< QString, QByteArray> &value ) : _value( value ) {} 01067 bool operator() ( Wallet::WalletPrivate*, const QString& label, KSecretsService::SecretItem* item ) { 01068 bool result = false; 01069 KSecretsService::GetSecretItemSecretJob *readSecretJob = item->getSecret(); 01070 if ( readSecretJob->exec() ) { 01071 _value.insert( label, readSecretJob->secret().value().toByteArray() ); 01072 result = true; 01073 } 01074 else { 01075 kDebug(285) << "Cannot execute GetSecretItemSecretJob " << readSecretJob->errorString(); 01076 } 01077 return result; 01078 } 01079 QMap< QString, QByteArray > _value; 01080 }; 01081 #endif 01082 01083 int Wallet::readEntryList(const QString& key, QMap<QString, QByteArray>& value) { 01084 01085 int rc = -1; 01086 01087 #ifdef HAVE_KSECRETSSERVICE 01088 if (walletLauncher->m_useKSecretsService) { 01089 rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoEntryList( value ) ); 01090 } 01091 else { 01092 #endif 01093 registerTypes(); 01094 01095 if (d->handle == -1) { 01096 return rc; 01097 } 01098 01099 QDBusReply<QVariantMap> r = walletLauncher->getInterface().readEntryList(d->handle, d->folder, key, appid()); 01100 if (r.isValid()) { 01101 rc = 0; 01102 // convert <QString, QVariant> to <QString, QByteArray> 01103 const QVariantMap val = r.value(); 01104 for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) { 01105 value.insert(it.key(), it.value().toByteArray()); 01106 } 01107 } 01108 #ifdef HAVE_KSECRETSSERVICE 01109 } 01110 #endif 01111 01112 return rc; 01113 } 01114 01115 01116 int Wallet::renameEntry(const QString& oldName, const QString& newName) { 01117 int rc = -1; 01118 01119 #ifdef HAVE_KSECRETSSERVICE 01120 if (walletLauncher->m_useKSecretsService) { 01121 QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem(oldName); 01122 if (item) { 01123 KSecretsService::WriteItemPropertyJob *writeJob = item->setLabel(newName); 01124 if (!writeJob->exec()) { 01125 kDebug(285) << "Cannot exec WriteItemPropertyJob : " << writeJob->errorString(); 01126 } 01127 rc = writeJob->error(); 01128 } 01129 else { 01130 kDebug(285) << "Cannot locate item " << oldName << " in folder " << d->folder; 01131 } 01132 } 01133 else { 01134 #endif 01135 if (d->handle == -1) { 01136 return rc; 01137 } 01138 01139 QDBusReply<int> r = walletLauncher->getInterface().renameEntry(d->handle, d->folder, oldName, newName, appid()); 01140 if (r.isValid()) { 01141 rc = r; 01142 } 01143 #ifdef HAVE_KSECRETSSERVICE 01144 } 01145 #endif 01146 01147 return rc; 01148 } 01149 01150 01151 int Wallet::readMap(const QString& key, QMap<QString,QString>& value) { 01152 int rc = -1; 01153 01154 #ifdef HAVE_KSECRETSSERVICE 01155 if (walletLauncher->m_useKSecretsService) { 01156 QByteArray ba; 01157 rc = d->readEntry< QByteArray >(key, ba); 01158 if ( rc == 0 && !ba.isEmpty()){ 01159 QDataStream ds( &ba, QIODevice::ReadOnly ); 01160 ds >> value; 01161 } 01162 } 01163 else { 01164 #endif 01165 registerTypes(); 01166 01167 if (d->handle == -1) { 01168 return rc; 01169 } 01170 01171 QDBusReply<QByteArray> r = walletLauncher->getInterface().readMap(d->handle, d->folder, key, appid()); 01172 if (r.isValid()) { 01173 rc = 0; 01174 QByteArray v = r; 01175 if (!v.isEmpty()) { 01176 QDataStream ds(&v, QIODevice::ReadOnly); 01177 ds >> value; 01178 } 01179 } 01180 #ifdef HAVE_KSECRETSSERVICE 01181 } 01182 #endif 01183 01184 return rc; 01185 } 01186 01187 #ifdef HAVE_KSECRETSSERVICE 01188 struct Wallet::WalletPrivate::InsertIntoMapList { 01189 InsertIntoMapList( QMap< QString, QMap< QString, QString > > &value ) : _value( value ) {} 01190 bool operator() ( Wallet::WalletPrivate* d, const QString& label, KSecretsService::SecretItem* ) { 01191 bool result = false; 01192 QMap<QString, QString> map; 01193 if ( d->readEntry< QMap< QString, QString> >(label, map) ) { 01194 _value.insert( label, map ); 01195 result = true; 01196 } 01197 return result; 01198 } 01199 QMap< QString, QMap< QString, QString> > &_value; 01200 }; 01201 #endif 01202 01203 int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString> >& value) { 01204 int rc = -1; 01205 01206 #ifdef HAVE_KSECRETSSERVICE 01207 if (walletLauncher->m_useKSecretsService) { 01208 rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoMapList( value ) ); 01209 } 01210 else { 01211 #endif 01212 registerTypes(); 01213 01214 if (d->handle == -1) { 01215 return rc; 01216 } 01217 01218 QDBusReply<QVariantMap> r = 01219 walletLauncher->getInterface().readMapList(d->handle, d->folder, key, appid()); 01220 if (r.isValid()) { 01221 rc = 0; 01222 const QVariantMap val = r.value(); 01223 for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) { 01224 QByteArray mapData = it.value().toByteArray(); 01225 if (!mapData.isEmpty()) { 01226 QDataStream ds(&mapData, QIODevice::ReadOnly); 01227 QMap<QString,QString> v; 01228 ds >> v; 01229 value.insert(it.key(), v); 01230 } 01231 } 01232 } 01233 #ifdef HAVE_KSECRETSSERVICE 01234 } 01235 #endif 01236 01237 return rc; 01238 } 01239 01240 01241 int Wallet::readPassword(const QString& key, QString& value) { 01242 int rc = -1; 01243 01244 #ifdef HAVE_KSECRETSSERVICE 01245 if (walletLauncher->m_useKSecretsService) { 01246 rc = d->readEntry<QString>(key, value); 01247 } 01248 else { 01249 #endif 01250 if (d->handle == -1) { 01251 return rc; 01252 } 01253 01254 QDBusReply<QString> r = walletLauncher->getInterface().readPassword(d->handle, d->folder, key, appid()); 01255 if (r.isValid()) { 01256 value = r; 01257 rc = 0; 01258 } 01259 #ifdef HAVE_KSECRETSSERVICE 01260 } 01261 #endif 01262 01263 return rc; 01264 } 01265 01266 #ifdef HAVE_KSECRETSSERVICE 01267 struct Wallet::WalletPrivate::InsertIntoPasswordList { 01268 InsertIntoPasswordList( QMap< QString, QString> &value ) : _value( value ) {} 01269 bool operator() ( Wallet::WalletPrivate* d, const QString& label, KSecretsService::SecretItem* ) { 01270 bool result = false; 01271 QString pwd; 01272 if ( d->readEntry<QString>( label, pwd ) == 0 ) { 01273 _value.insert( label, pwd ); 01274 result = true; 01275 } 01276 return result; 01277 } 01278 QMap< QString, QString > &_value; 01279 }; 01280 #endif 01281 01282 int Wallet::readPasswordList(const QString& key, QMap<QString, QString>& value) { 01283 int rc = -1; 01284 01285 #ifdef HAVE_KSECRETSSERVICE 01286 if (walletLauncher->m_useKSecretsService) { 01287 rc = d->forEachItemThatMatches( key, WalletPrivate::InsertIntoPasswordList( value ) ); 01288 } 01289 else { 01290 #endif 01291 registerTypes(); 01292 01293 if (d->handle == -1) { 01294 return rc; 01295 } 01296 01297 QDBusReply<QVariantMap> r = walletLauncher->getInterface().readPasswordList(d->handle, d->folder, key, appid()); 01298 if (r.isValid()) { 01299 rc = 0; 01300 const QVariantMap val = r.value(); 01301 for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) { 01302 value.insert(it.key(), it.value().toString()); 01303 } 01304 } 01305 #ifdef HAVE_KSECRETSSERVICE 01306 } 01307 #endif 01308 01309 return rc; 01310 } 01311 01312 01313 int Wallet::writeEntry(const QString& key, const QByteArray& value, EntryType entryType) { 01314 int rc = -1; 01315 01316 #ifdef HAVE_KSECRETSSERVICE 01317 if (walletLauncher->m_useKSecretsService) { 01318 rc = d->writeEntry( key, value, entryType ); 01319 } 01320 else { 01321 #endif 01322 if (d->handle == -1) { 01323 return rc; 01324 } 01325 01326 QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, int(entryType), appid()); 01327 if (r.isValid()) { 01328 rc = r; 01329 } 01330 #ifdef HAVE_KSECRETSSERVICE 01331 } 01332 #endif 01333 01334 return rc; 01335 } 01336 01337 01338 int Wallet::writeEntry(const QString& key, const QByteArray& value) { 01339 int rc = -1; 01340 01341 #ifdef HAVE_KSECRETSSERVICE 01342 if (walletLauncher->m_useKSecretsService) { 01343 rc = writeEntry( key, value, Stream ); 01344 } 01345 else { 01346 #endif 01347 if (d->handle == -1) { 01348 return rc; 01349 } 01350 01351 QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, appid()); 01352 if (r.isValid()) { 01353 rc = r; 01354 } 01355 #ifdef HAVE_KSECRETSSERVICE 01356 } 01357 #endif 01358 01359 return rc; 01360 } 01361 01362 01363 int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value) { 01364 int rc = -1; 01365 01366 #ifdef HAVE_KSECRETSSERVICE 01367 if (walletLauncher->m_useKSecretsService) { 01368 d->writeEntry( key, value, Map ); 01369 } 01370 else { 01371 #endif 01372 registerTypes(); 01373 01374 if (d->handle == -1) { 01375 return rc; 01376 } 01377 01378 QByteArray mapData; 01379 QDataStream ds(&mapData, QIODevice::WriteOnly); 01380 ds << value; 01381 QDBusReply<int> r = walletLauncher->getInterface().writeMap(d->handle, d->folder, key, mapData, appid()); 01382 if (r.isValid()) { 01383 rc = r; 01384 } 01385 #ifdef HAVE_KSECRETSSERVICE 01386 } 01387 #endif 01388 01389 return rc; 01390 } 01391 01392 01393 int Wallet::writePassword(const QString& key, const QString& value) { 01394 int rc = -1; 01395 01396 #ifdef HAVE_KSECRETSSERVICE 01397 if (walletLauncher->m_useKSecretsService) { 01398 rc = d->writeEntry( key, value, Password ); 01399 } 01400 else { 01401 #endif 01402 if (d->handle == -1) { 01403 return rc; 01404 } 01405 01406 QDBusReply<int> r = walletLauncher->getInterface().writePassword(d->handle, d->folder, key, value, appid()); 01407 if (r.isValid()) { 01408 rc = r; 01409 } 01410 #ifdef HAVE_KSECRETSSERVICE 01411 } 01412 #endif 01413 01414 return rc; 01415 } 01416 01417 01418 bool Wallet::hasEntry(const QString& key) { 01419 #ifdef HAVE_KSECRETSSERVICE 01420 if (walletLauncher->m_useKSecretsService) { 01421 QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key ); 01422 return item; 01423 } 01424 else { 01425 #endif 01426 if (d->handle == -1) { 01427 return false; 01428 } 01429 01430 QDBusReply<bool> r = walletLauncher->getInterface().hasEntry(d->handle, d->folder, key, appid()); 01431 if (!r.isValid()) 01432 { 01433 kDebug(285) << "Invalid DBus reply: " << r.error(); 01434 return false; 01435 } 01436 else 01437 return r; 01438 #ifdef HAVE_KSECRETSSERVICE 01439 } 01440 #endif 01441 } 01442 01443 01444 int Wallet::removeEntry(const QString& key) { 01445 int rc = -1; 01446 01447 #ifdef HAVE_KSECRETSSERVICE 01448 if (walletLauncher->m_useKSecretsService) { 01449 QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key ); 01450 if ( item ) { 01451 KSecretsService::SecretItemDeleteJob *deleteJob = item->deleteItem(); 01452 if ( !deleteJob->exec() ) { 01453 kDebug(285) << "Cannot execute SecretItemDeleteJob " << deleteJob->errorString(); 01454 } 01455 rc = deleteJob->error(); 01456 } 01457 } 01458 else { 01459 #endif 01460 if (d->handle == -1) { 01461 return rc; 01462 } 01463 01464 QDBusReply<int> r = walletLauncher->getInterface().removeEntry(d->handle, d->folder, key, appid()); 01465 if (r.isValid()) { 01466 rc = r; 01467 } 01468 #ifdef HAVE_KSECRETSSERVICE 01469 } 01470 #endif 01471 01472 return rc; 01473 } 01474 01475 01476 Wallet::EntryType Wallet::entryType(const QString& key) { 01477 int rc = 0; 01478 01479 #ifdef HAVE_KSECRETSSERVICE 01480 if (walletLauncher->m_useKSecretsService) { 01481 QExplicitlySharedDataPointer<KSecretsService::SecretItem> item = d->findItem( key ); 01482 if ( item ) { 01483 KSecretsService::ReadItemPropertyJob *readAttrsJob = item->attributes(); 01484 if ( readAttrsJob->exec() ) { 01485 KSecretsService::StringStringMap attrs = readAttrsJob->propertyValue().value<KSecretsService::StringStringMap>(); 01486 if ( attrs.contains( KSS_ATTR_WALLETTYPE ) ) { 01487 QString entryType = attrs[KSS_ATTR_WALLETTYPE]; 01488 bool ok = false; 01489 rc = entryType.toInt( &ok ); 01490 if ( !ok ) { 01491 rc = 0; 01492 kDebug(285) << KSS_ATTR_WALLETTYPE << " attribute holds non int value " << attrs[KSS_ATTR_WALLETTYPE]; 01493 } 01494 } 01495 } 01496 else { 01497 kDebug(285) << "Cannot execute GetSecretItemSecretJob " << readAttrsJob->errorString(); 01498 } 01499 } 01500 } 01501 else { 01502 #endif 01503 if (d->handle == -1) { 01504 return Wallet::Unknown; 01505 } 01506 01507 QDBusReply<int> r = walletLauncher->getInterface().entryType(d->handle, d->folder, key, appid()); 01508 if (r.isValid()) { 01509 rc = r; 01510 } 01511 #ifdef HAVE_KSECRETSSERVICE 01512 } 01513 #endif 01514 return static_cast<EntryType>(rc); 01515 } 01516 01517 01518 void Wallet::WalletPrivate::walletServiceUnregistered() 01519 { 01520 if (loop) { 01521 loop->quit(); 01522 } 01523 01524 if (handle >= 0) { 01525 q->slotWalletClosed(handle); 01526 } 01527 } 01528 01529 void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder) { 01530 #ifdef HAVE_KSECRETSSERVICE 01531 if (walletLauncher->m_useKSecretsService) { 01532 // TODO: implement this 01533 Q_ASSERT(0); 01534 } 01535 else { 01536 #endif 01537 if (d->name == wallet) { 01538 emit folderUpdated(folder); 01539 } 01540 #ifdef HAVE_KSECRETSSERVICE 01541 } 01542 #endif 01543 } 01544 01545 01546 void Wallet::slotFolderListUpdated(const QString& wallet) { 01547 #ifdef HAVE_KSECRETSSERVICE 01548 if (walletLauncher->m_useKSecretsService) { 01549 // TODO: implement this 01550 Q_ASSERT(0); 01551 } 01552 else { 01553 #endif 01554 if (d->name == wallet) { 01555 emit folderListUpdated(); 01556 } 01557 #ifdef HAVE_KSECRETSSERVICE 01558 } 01559 #endif 01560 } 01561 01562 01563 void Wallet::slotApplicationDisconnected(const QString& wallet, const QString& application) { 01564 #ifdef HAVE_KSECRETSSERVICE 01565 if (walletLauncher->m_useKSecretsService) { 01566 // TODO: implement this 01567 Q_ASSERT(0); 01568 } 01569 else { 01570 #endif 01571 if (d->handle >= 0 01572 && d->name == wallet 01573 && application == appid()) { 01574 slotWalletClosed(d->handle); 01575 } 01576 #ifdef HAVE_KSECRETSSERVICE 01577 } 01578 #endif 01579 } 01580 01581 void Wallet::walletAsyncOpened(int tId, int handle) { 01582 #ifdef HAVE_KSECRETSSERVICE 01583 if (walletLauncher->m_useKSecretsService) { 01584 // TODO: implement this 01585 Q_ASSERT(0); 01586 } 01587 else { 01588 #endif 01589 // ignore responses to calls other than ours 01590 if (d->transactionId != tId || d->handle != -1) { 01591 return; 01592 } 01593 01594 // disconnect the async signal 01595 disconnect(this, SLOT(walletAsyncOpened(int,int))); 01596 01597 d->handle = handle; 01598 emit walletOpened(handle > 0); 01599 #ifdef HAVE_KSECRETSSERVICE 01600 } 01601 #endif 01602 } 01603 01604 void Wallet::emitWalletAsyncOpenError() { 01605 emit walletOpened(false); 01606 } 01607 01608 void Wallet::emitWalletOpened() { 01609 emit walletOpened(true); 01610 } 01611 01612 bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder) 01613 { 01614 #ifdef HAVE_KSECRETSSERVICE 01615 if (walletLauncher->m_useKSecretsService) { 01616 kDebug(285) << "WARNING: changing semantics of folderDoesNotExist with KSS: will prompt for the password"; 01617 Wallet *w = openWallet( wallet, 0, Synchronous ); 01618 if ( w ) { 01619 return !w->hasFolder( folder ); 01620 } 01621 else { 01622 return true; 01623 } 01624 } 01625 else { 01626 #endif 01627 QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder); 01628 if (!r.isValid()) 01629 { 01630 kDebug(285) << "Invalid DBus reply: " << r.error(); 01631 return false; 01632 } 01633 else 01634 return r; 01635 #ifdef HAVE_KSECRETSSERVICE 01636 } 01637 #endif 01638 } 01639 01640 01641 bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key) 01642 { 01643 #ifdef HAVE_KSECRETSSERVICE 01644 if (walletLauncher->m_useKSecretsService) { 01645 kDebug(285) << "WARNING: changing semantics of keyDoesNotExist with KSS: will prompt for the password"; 01646 Wallet *w = openWallet( wallet, 0, Synchronous ); 01647 if ( w ) { 01648 return !w->hasEntry(key); 01649 } 01650 return false; 01651 } 01652 else { 01653 #endif 01654 QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key); 01655 if (!r.isValid()) 01656 { 01657 kDebug(285) << "Invalid DBus reply: " << r.error(); 01658 return false; 01659 } 01660 else 01661 return r; 01662 #ifdef HAVE_KSECRETSSERVICE 01663 } 01664 #endif 01665 } 01666 01667 void Wallet::virtual_hook(int, void*) { 01668 //BASE::virtual_hook( id, data ); 01669 } 01670 01671 01672 KWalletDLauncher::KWalletDLauncher() 01673 : m_wallet(0), 01674 m_cgroup(KSharedConfig::openConfig("kwalletrc", KConfig::NoGlobals)->group("Wallet")) 01675 { 01676 m_useKSecretsService = m_cgroup.readEntry("UseKSecretsService", false); 01677 #ifdef HAVE_KSECRETSSERVICE 01678 if (m_useKSecretsService) { 01679 // NOOP 01680 } 01681 else { 01682 #endif 01683 m_wallet = new org::kde::KWallet(QString::fromLatin1(s_kwalletdServiceName), "/modules/kwalletd", QDBusConnection::sessionBus()); 01684 #ifdef HAVE_KSECRETSSERVICE 01685 } 01686 #endif 01687 } 01688 01689 KWalletDLauncher::~KWalletDLauncher() 01690 { 01691 delete m_wallet; 01692 } 01693 01694 org::kde::KWallet &KWalletDLauncher::getInterface() 01695 { 01696 // Q_ASSERT(!m_useKSecretsService); 01697 Q_ASSERT(m_wallet != 0); 01698 01699 // check if kwalletd is already running 01700 if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) 01701 { 01702 // not running! check if it is enabled. 01703 bool walletEnabled = m_cgroup.readEntry("Enabled", true); 01704 if (walletEnabled) { 01705 // wallet is enabled! try launching it 01706 QString error; 01707 int ret = KToolInvocation::startServiceByDesktopPath("kwalletd.desktop", QStringList(), &error); 01708 if (ret > 0) 01709 { 01710 kError(285) << "Couldn't start kwalletd: " << error << endl; 01711 } 01712 01713 if 01714 (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) { 01715 kDebug(285) << "The kwalletd service is still not registered"; 01716 } else { 01717 kDebug(285) << "The kwalletd service has been registered"; 01718 } 01719 } else { 01720 kError(285) << "The kwalletd service has been disabled"; 01721 } 01722 } 01723 01724 return *m_wallet; 01725 } 01726 01727 } // namespace KWallet 01728 01729 #include "kwallet.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:58:00 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:58:00 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.