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();
90 const QByteArray serviceName( walletName.toUtf8() );
91 const QByteArray accountName( key.toUtf8() );
92 SecKeychainItemRef itemRef;
94 OSStatus result = SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), NULL, NULL, &itemRef );
95 if (
isError( result, &errMsg ) ) {
96 qWarning() <<
"Could not retrieve password:" << qPrintable(errMsg);
99 const CFReleaser<SecKeychainItemRef> itemReleaser( itemRef );
100 result = SecKeychainItemDelete( itemRef );
101 if (
isError( result, &errMsg ) ) {
102 qWarning() <<
"Could not delete password:" << qPrintable(errMsg);
111 if (!cfg.readEntry(
"Use One Wallet",
true)) {
112 QString tmp = cfg.readEntry(
"Local Wallet",
"localwallet");
114 return "localwallet";
119 QString tmp = cfg.readEntry(
"Default Wallet",
"kdewallet");
129 QString tmp = cfg.readEntry(
"Default Wallet",
"kdewallet");
144 class Wallet::WalletPrivate
147 explicit WalletPrivate(
const QString &n)
152 void walletServiceUnregistered() {
160 :
QObject(0L), d(new WalletPrivate(name)) {
170 #ifdef OSX_KEYCHAIN_PORT_DISABLED
171 return walletLauncher->getInterface().wallets();
179 #ifdef OSX_KEYCHAIN_PORT_DISABLED
181 kDebug(285) <<
"Pass a valid window to KWallet::Wallet::changePassword().";
182 walletLauncher->getInterface().changePassword(name, (qlonglong)w,
appid());
194 #ifdef OSX_KEYCHAIN_PORT_DISABLED
195 return walletLauncher->getInterface().isOpen(name);
203 #ifdef OSX_KEYCHAIN_PORT_DISABLED
204 QDBusReply<int> r = walletLauncher->getInterface().close(name, force);
205 return r.isValid() ? r : -1;
213 #ifdef OSX_KEYCHAIN_PORT_DISABLED
214 QDBusReply<int> r = walletLauncher->getInterface().deleteWallet(name);
215 return r.isValid() ? r : -1;
226 QMetaObject::invokeMethod( wallet,
"emitWalletOpened", Qt::QueuedConnection );
232 #ifdef OSX_KEYCHAIN_PORT_DISABLED
233 return walletLauncher->getInterface().disconnectApplication(wallet, app);
241 #ifdef OSX_KEYCHAIN_PORT_DISABLED
242 return walletLauncher->getInterface().users(name);
250 #ifdef OSX_KEYCHAIN_PORT_DISABLED
251 if (d->handle == -1) {
255 walletLauncher->getInterface().sync(d->handle,
appid());
262 #ifdef OSX_KEYCHAIN_PORT_DISABLED
263 if (d->handle == -1) {
267 QDBusReply<int> r = walletLauncher->getInterface().close(d->handle,
true,
appid());
285 #ifdef OSX_KEYCHAIN_PORT_DISABLED
286 return d->handle != -1;
294 #ifdef OSX_KEYCHAIN_PORT_DISABLED
296 kDebug(285) <<
"Pass a valid window to KWallet::Wallet::requestChangePassword().";
297 if (d->handle == -1) {
301 walletLauncher->getInterface().changePassword(d->name, (qlonglong)w,
appid());
306 void Wallet::slotWalletClosed(
int handle) {
307 #ifdef OSX_KEYCHAIN_PORT_DISABLED
308 if (d->handle == handle) {
319 #ifdef OSX_KEYCHAIN_PORT_DISABLED
320 if (d->handle == -1) {
324 QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle,
appid());
333 #ifdef OSX_KEYCHAIN_PORT_DISABLED
334 if (d->handle == -1) {
338 QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder,
appid());
347 #ifdef OSX_KEYCHAIN_PORT_DISABLED
348 if (d->handle == -1) {
352 QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f,
appid());
361 #ifdef OSX_KEYCHAIN_PORT_DISABLED
362 if (d->handle == -1) {
367 QDBusReply<bool> r = walletLauncher->getInterface().createFolder(d->handle, f,
appid());
379 #ifdef OSX_KEYCHAIN_PORT_DISABLED
382 if (d->handle == -1) {
388 if (f == d->folder) {
406 #ifdef OSX_KEYCHAIN_PORT_DISABLED
407 if (d->handle == -1) {
411 QDBusReply<bool> r = walletLauncher->getInterface().removeFolder(d->handle, f,
appid());
412 if (d->folder == f) {
429 const QByteArray serviceName(
walletName().toUtf8() );
430 const QByteArray accountName( key.toUtf8() );
431 UInt32 passwordSize = 0;
432 void* passwordData = 0;
434 if (
isError( SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), &passwordSize, &passwordData, NULL ), &errMsg ) ) {
435 qWarning() <<
"Could not retrieve password:" << qPrintable(errMsg);
439 value = QByteArray( reinterpret_cast<const char*>( passwordData ), passwordSize );
440 SecKeychainItemFreeContent( NULL, passwordData );
446 #ifdef OSX_KEYCHAIN_PORT_DISABLED
451 if (d->handle == -1) {
455 QDBusReply<QVariantMap> r = walletLauncher->getInterface().readEntryList(d->handle, d->folder, key,
appid());
459 const QVariantMap val = r.value();
460 for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
461 value.insert(it.key(), it.value().toByteArray());
473 #ifdef OSX_KEYCHAIN_PORT_DISABLED
476 if (d->handle == -1) {
480 QDBusReply<int> r = walletLauncher->getInterface().renameEntry(d->handle, d->folder, oldName, newName,
appid());
497 if ( !v.isEmpty() ) {
498 QDataStream ds( &v, QIODevice::ReadOnly );
506 #ifdef OSX_KEYCHAIN_PORT_DISABLED
511 if (d->handle == -1) {
515 QDBusReply<QVariantMap> r =
516 walletLauncher->getInterface().readMapList(d->handle, d->folder, key,
appid());
519 const QVariantMap val = r.value();
520 for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
521 QByteArray mapData = it.value().toByteArray();
522 if (!mapData.isEmpty()) {
523 QDataStream ds(&mapData, QIODevice::ReadOnly);
526 value.insert(it.key(), v);
542 value = QString::fromUtf8( ba.constData() );
552 const QByteArray serviceName( walletName.toUtf8() );
553 const QByteArray accountName( key.toUtf8() );
555 OSStatus err = SecKeychainAddGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), value.size(), value.constData(), NULL );
556 if (err == errSecDuplicateItem) {
558 if (
isError( err, &errMsg ) ) {
559 kWarning() <<
"Could not delete old key in keychain for replacing: " << qPrintable(errMsg);
563 if (
isError( err, &errMsg ) ) {
564 kWarning() <<
"Could not store password in keychain: " << qPrintable(errMsg);
567 kDebug() <<
"Succesfully written out key:" << key;
573 Q_UNUSED( entryType )
585 QDataStream ds(&mapData, QIODevice::WriteOnly);
597 const QByteArray serviceName(
walletName().toUtf8() );
598 const QByteArray accountName( key.toUtf8() );
599 return !
isError( SecKeychainFindGenericPassword( NULL, serviceName.size(), serviceName.constData(), accountName.size(), accountName.constData(), NULL, NULL, NULL ), 0 );
608 #ifdef OSX_KEYCHAIN_PORT_DISABLED
611 if (d->handle == -1) {
615 QDBusReply<int> r = walletLauncher->getInterface().entryType(d->handle, d->folder, key,
appid());
627 void Wallet::slotFolderUpdated(
const QString& wallet,
const QString& folder) {
628 if (d->name == wallet) {
634 void Wallet::slotFolderListUpdated(
const QString& wallet) {
635 if (d->name == wallet) {
641 void Wallet::slotApplicationDisconnected(
const QString& wallet,
const QString& application) {
642 #ifdef OSX_KEYCHAIN_PORT_DISABLED
645 && application ==
appid()) {
646 slotWalletClosed(d->handle);
651 void Wallet::walletAsyncOpened(
int tId,
int handle) {
652 #ifdef OSX_KEYCHAIN_PORT_DISABLED
654 if (d->transactionId != tId || d->handle != -1) {
659 disconnect(
this, SLOT(walletAsyncOpened(
int,
int)));
666 void Wallet::emitWalletAsyncOpenError() {
670 void Wallet::emitWalletOpened() {
677 #ifdef OSX_KEYCHAIN_PORT_DISABLED
678 QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder);
688 #ifdef OSX_KEYCHAIN_PORT_DISABLED
689 QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key);
696 void Wallet::slotCollectionStatusChanged(
int status)
700 void Wallet::slotCollectionDeleted()
712 #include "kwallet.moc"