26 #include <kdeversion.h>
27 #include <QtGui/QApplication>
28 #include <QtCore/QPointer>
29 #include <QtGui/QWidget>
39 #include <Carbon/Carbon.h>
40 #include <Security/Security.h>
41 #include <Security/SecKeychain.h>
43 using namespace KWallet;
55 explicit CFReleaser(
const T& r ) :
ref( r ) {}
56 ~CFReleaser() { CFRelease(
ref ); }
62 return QString::fromLatin1( CFStringGetCStringPtr( sr, NULL ) );
66 const CFReleaser<CFStringRef>
ref( SecCopyErrorMessageString( s, NULL ) );
86 return qApp->applicationName();
92 if (!cfg.readEntry(
"Use One Wallet",
true)) {
93 QString tmp = cfg.readEntry(
"Local Wallet",
"localwallet");
100 QString tmp = cfg.readEntry(
"Default Wallet",
"kdewallet");
110 QString tmp = cfg.readEntry(
"Default Wallet",
"kdewallet");
125 class Wallet::WalletPrivate
128 explicit WalletPrivate(
const QString &n)
133 void walletServiceUnregistered() {
141 :
QObject(0L), d(new WalletPrivate(name)) {
151 #ifdef OSX_KEYCHAIN_PORT_DISABLED
152 return walletLauncher->getInterface().wallets();
160 #ifdef OSX_KEYCHAIN_PORT_DISABLED
162 kDebug(285) <<
"Pass a valid window to KWallet::Wallet::changePassword().";
163 walletLauncher->getInterface().changePassword(name, (qlonglong)w,
appid());
175 #ifdef OSX_KEYCHAIN_PORT_DISABLED
176 return walletLauncher->getInterface().isOpen(name);
184 #ifdef OSX_KEYCHAIN_PORT_DISABLED
185 QDBusReply<int> r = walletLauncher->getInterface().close(name, force);
186 return r.isValid() ? r : -1;
194 #ifdef OSX_KEYCHAIN_PORT_DISABLED
195 QDBusReply<int> r = walletLauncher->getInterface().deleteWallet(name);
196 return r.isValid() ? r : -1;
207 QMetaObject::invokeMethod( wallet,
"emitWalletOpened", Qt::QueuedConnection );
213 #ifdef OSX_KEYCHAIN_PORT_DISABLED
214 return walletLauncher->getInterface().disconnectApplication(wallet, app);
222 #ifdef OSX_KEYCHAIN_PORT_DISABLED
223 return walletLauncher->getInterface().users(name);
231 #ifdef OSX_KEYCHAIN_PORT_DISABLED
232 if (d->handle == -1) {
236 walletLauncher->getInterface().sync(d->handle,
appid());
243 #ifdef OSX_KEYCHAIN_PORT_DISABLED
244 if (d->handle == -1) {
248 QDBusReply<int> r = walletLauncher->getInterface().close(d->handle,
true,
appid());
266 #ifdef OSX_KEYCHAIN_PORT_DISABLED
267 return d->handle != -1;
275 #ifdef OSX_KEYCHAIN_PORT_DISABLED
277 kDebug(285) <<
"Pass a valid window to KWallet::Wallet::requestChangePassword().";
278 if (d->handle == -1) {
282 walletLauncher->getInterface().changePassword(d->name, (qlonglong)w,
appid());
287 void Wallet::slotWalletClosed(
int handle) {
288 #ifdef OSX_KEYCHAIN_PORT_DISABLED
289 if (d->handle == handle) {
300 #ifdef OSX_KEYCHAIN_PORT_DISABLED
301 if (d->handle == -1) {
305 QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle,
appid());
314 #ifdef OSX_KEYCHAIN_PORT_DISABLED
315 if (d->handle == -1) {
319 QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder,
appid());
328 #ifdef OSX_KEYCHAIN_PORT_DISABLED
329 if (d->handle == -1) {
333 QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f,
appid());
342 #ifdef OSX_KEYCHAIN_PORT_DISABLED
343 if (d->handle == -1) {
348 QDBusReply<bool> r = walletLauncher->getInterface().createFolder(d->handle, f,
appid());
360 #ifdef OSX_KEYCHAIN_PORT_DISABLED
363 if (d->handle == -1) {
369 if (f == d->folder) {
387 #ifdef OSX_KEYCHAIN_PORT_DISABLED
388 if (d->handle == -1) {
392 QDBusReply<bool> r = walletLauncher->getInterface().removeFolder(d->handle, f,
appid());
393 if (d->folder == f) {
410 const QByteArray serviceName(
walletName().toUtf8() );
411 const QByteArray accountName( key.toUtf8() );
412 UInt32 passwordSize = 0;
413 void* passwordData = 0;
415 if (
isError( SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), &passwordSize, &passwordData, NULL ), &errMsg ) ) {
416 qWarning() <<
"Could not retrieve password:" << qPrintable(errMsg);
420 value = QByteArray( reinterpret_cast<const char*>( passwordData ), passwordSize );
421 SecKeychainItemFreeContent( NULL, passwordData );
427 #ifdef OSX_KEYCHAIN_PORT_DISABLED
432 if (d->handle == -1) {
436 QDBusReply<QVariantMap> r = walletLauncher->getInterface().readEntryList(d->handle, d->folder, key,
appid());
440 const QVariantMap val = r.value();
441 for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
442 value.insert(it.key(), it.value().toByteArray());
454 #ifdef OSX_KEYCHAIN_PORT_DISABLED
457 if (d->handle == -1) {
461 QDBusReply<int> r = walletLauncher->getInterface().renameEntry(d->handle, d->folder, oldName, newName,
appid());
478 if ( !v.isEmpty() ) {
479 QDataStream ds( &v, QIODevice::ReadOnly );
487 #ifdef OSX_KEYCHAIN_PORT_DISABLED
492 if (d->handle == -1) {
496 QDBusReply<QVariantMap> r =
497 walletLauncher->getInterface().readMapList(d->handle, d->folder, key,
appid());
500 const QVariantMap val = r.value();
501 for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
502 QByteArray mapData = it.value().toByteArray();
503 if (!mapData.isEmpty()) {
504 QDataStream ds(&mapData, QIODevice::ReadOnly);
507 value.insert(it.key(), v);
523 value = QString::fromUtf8( ba.constData() );
534 const QByteArray serviceName(
walletName().toUtf8() );
535 const QByteArray accountName( key.toUtf8() );
537 if (
isError( SecKeychainAddGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), password.size(), password.constData(), NULL ), &errMsg ) ) {
538 kWarning() <<
"Could not store password in keychain: " << qPrintable(errMsg);
546 const QByteArray serviceName(
walletName().toUtf8() );
547 const QByteArray accountName( key.toUtf8() );
549 if (
isError( SecKeychainAddGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), value.size(), value.constData(), NULL ), &errMsg ) ) {
550 kWarning() <<
"Could not store password in keychain: " << qPrintable(errMsg);
559 QDataStream ds(&mapData, QIODevice::WriteOnly);
571 const QByteArray serviceName(
walletName().toUtf8() );
572 const QByteArray accountName( key.toUtf8() );
573 return !
isError( SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), NULL, NULL, NULL ), 0 );
578 const QByteArray serviceName(
walletName().toUtf8() );
579 const QByteArray accountName( key.toUtf8() );
580 SecKeychainItemRef itemRef;
582 if (
isError( SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), NULL, NULL, &itemRef ), &errMsg ) ) {
583 qWarning() <<
"Could not retrieve password:" << qPrintable(errMsg);
586 const CFReleaser<SecKeychainItemRef> itemReleaser( itemRef );
587 if (
isError( SecKeychainItemDelete( itemRef ), &errMsg ) ) {
588 qWarning() <<
"Could not delete password:" << qPrintable(errMsg);
596 #ifdef OSX_KEYCHAIN_PORT_DISABLED
599 if (d->handle == -1) {
603 QDBusReply<int> r = walletLauncher->getInterface().entryType(d->handle, d->folder, key,
appid());
615 void Wallet::slotFolderUpdated(
const QString& wallet,
const QString& folder) {
616 if (d->name == wallet) {
622 void Wallet::slotFolderListUpdated(
const QString& wallet) {
623 if (d->name == wallet) {
629 void Wallet::slotApplicationDisconnected(
const QString& wallet,
const QString& application) {
630 #ifdef OSX_KEYCHAIN_PORT_DISABLED
633 && application ==
appid()) {
634 slotWalletClosed(d->handle);
639 void Wallet::walletAsyncOpened(
int tId,
int handle) {
640 #ifdef OSX_KEYCHAIN_PORT_DISABLED
642 if (d->transactionId != tId || d->handle != -1) {
647 disconnect(
this, SLOT(walletAsyncOpened(
int,
int)));
654 void Wallet::emitWalletAsyncOpenError() {
658 void Wallet::emitWalletOpened() {
665 #ifdef OSX_KEYCHAIN_PORT_DISABLED
666 QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder);
676 #ifdef OSX_KEYCHAIN_PORT_DISABLED
677 QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key);
684 void Wallet::slotCollectionStatusChanged(
int status)
688 void Wallet::slotCollectionDeleted()
700 #include "kwallet.moc"