generic: port KIO to KPasswdStore and drop kwallet and kwasswdserver

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2022-04-04 23:11:42 +03:00
parent 4634b5c14f
commit 1fe3f61065
26 changed files with 192 additions and 2621 deletions

2
TODO
View file

@ -135,8 +135,6 @@ that we would like to make for the next binary incompatible release.
functions like capitalize and reverse seem to be sparsely used.
(Caleb)
- Prevent re-entering event loop in kded to avoid reentrancy problems like with kwallet in KDE3 (Lubos).
- Customizable KToolTip/KWhatsThis widgets (Jaroslaw Staniek),
now KWhatsThis is a part of KDE GSoC "Implement OpenUsability's Context Sensitive
Help Redesign" project, by Joshua Keel, mentored by Ellen Reitmayr

View file

@ -550,14 +550,6 @@ install(
)
install(
FILES
KWallet/Wallet
DESTINATION ${KDE4_INCLUDE_INSTALL_DIR}/KDE/KWallet
COMPONENT Devel
)
install(
FILES
Solid/AcAdapter

View file

@ -1 +0,0 @@
#include "../../kwallet.h"

View file

@ -28,7 +28,6 @@
265 kdeui (KIconEffect)
281 kdeui (KCModule)
283 kdeui (K*Gesture*)
285 kdeui (Wallet)
291 kdeui (KAboutDialog)
292 kdeui (KComboBox)
293 kdeui (KLineEdit)

View file

@ -12,9 +12,7 @@ information that, for some reason, cannot be kept in any other process.
Here are examples of KDED modules:
kdelibs/kioslave/http/kcookiejar/kcookieserver.cpp Cookie-handling module (including GUI)
kdelibs/kio/misc/kwalletd/kwalletd.cpp KWallet module, handles the wallet file
kdebase/apps/lib/konq/favicons/favicons.cpp Favicons module, for downloading favicon.ico files when browsing
kdebase/runtime/kpasswdserver/kpasswdserver.cpp Password-caching module
A KDED module should install a .desktop file with
ServicesTypes=KDEDModule

View file

@ -57,8 +57,6 @@ public:
//bool isWindowRegistered(qlonglong windowId) const;
/**
* Applications can register/unregister their windows with kded modules.
* This allows kpasswdserver and kcookiejar to delete authentication
* and cookies that are local to a particular window when closing it.
*/
//@{
/**

View file

@ -192,7 +192,6 @@ set(kdeui_LIB_SRCS
util/kpassivepopup.cpp
util/kpassivepopupmessagehandler.cpp
util/kstandardguiitem.cpp
util/kwallet.cpp
util/kwordwrap.cpp
util/kxerrorhandler.cpp
util/kxmessages.cpp
@ -321,13 +320,6 @@ else()
)
endif()
set(kwallet_xml util/org.kde.KWallet.xml)
install(
FILES ${kwallet_xml}
DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR}
)
qt4_add_dbus_interface(kdeui_LIB_SRCS ${kwallet_xml} kwallet_interface )
qt4_add_dbus_interfaces(kdeui_LIB_SRCS jobs/org.kde.JobViewServer.xml )
qt4_add_dbus_interface(kdeui_LIB_SRCS
@ -543,7 +535,6 @@ install(
util/kpassivepopup.h
util/kpassivepopupmessagehandler.h
util/kstandardguiitem.h
util/kwallet.h
util/kwordwrap.h
util/kxerrorhandler.h
util/kxmessages.h

View file

@ -128,7 +128,6 @@ KDEUI_EXECUTABLE_TESTS(
ktitlewidgettest
ktoolbartest
ktoolbarlabelactiontest
kwallettest
kwidgetitemdelegatetest
kwindowtest
kxmlguitest

View file

@ -1,164 +0,0 @@
/*
This file is part of the KDE Libraries
Copyright (C) 2007 Thomas McGuire (thomas.mcguire@gmx.net)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kwallettest.h"
#include <QtTest>
#include <QWidget>
#include <kwallet.h>
#include <kdebug.h>
#include <klauncher_iface.h>
#include <ktoolinvocation.h>
using namespace KWallet;
void KWalletTest::testWallet()
{
QString testWallet = "kwallettestWallet";
QString testFolder = "wallettestfolder";
QString testKeys[] = { "testKey", "account-302948", "\\", "/abc",
"a@b.c" };
QByteArray testValues[] = { "test", "@(!§\"%&", "", ".test", "\\" };
QMap<QString,QString> pwmap;
int numTests = 5;
// Start kdeinit4, so that the wallet damon is started in the background
OrgKdeKLauncherInterface *launcher = KToolInvocation::klauncher();
launcher->autoStart();
// Create a widget to serve as the wallet's parent widget, to get rid of a
// warning
QWidget *w = new QWidget();
// open
Wallet *wallet = Wallet::openWallet( testWallet, w->winId(), Wallet::Synchronous );
if ( wallet == 0 ){
kWarning() << "Couldn't open the wallet. Maybe the wallet daemon is not running?";
}
else{
kWarning() << "Opened wallet" << wallet->walletName();
}
QVERIFY( wallet != 0 );
QVERIFY( Wallet::isOpen( testWallet ) );
kWarning() << "Wallet list:" << Wallet::walletList();
// check on a couple of existing items, preferably at least 1 "internet account" and 1 "application password"
// OSXKeychain::readEntry( "existing name", "existing account", &value, NULL, NULL )
// create folder
wallet->createFolder( testFolder );
QVERIFY( wallet->hasFolder( testFolder ) );
wallet->setFolder( testFolder );
kWarning() << "Wallet's folder list:" << wallet->folderList();
QVERIFY( wallet->currentFolder() == testFolder );
QVERIFY( wallet->folderList().contains( testFolder ) );
// write & read many entries
for ( int i = 0; i < numTests; i++ ) {
wallet->writeEntry( testKeys[i], testValues[i] );
QVERIFY( wallet->hasEntry( testKeys[i] ) );
QByteArray readEntry;
wallet->readEntry( testKeys[i], readEntry );
QVERIFY( readEntry == testValues[i] );
}
pwmap[QString("Bugzilla_login")] = QString("bugs@kde.org");
pwmap[QString("Bugzilla_password")] = QString("buggyPassw0rd");
kWarning() << "pwmap=" << pwmap;
QMap<QString,QString> v;
QVERIFY( !wallet->writeMap( "https://bugs.kde.org/#", pwmap ) );
QVERIFY( wallet->hasEntry("https://bugs.kde.org/#") );
QVERIFY( !wallet->readMap( "https://bugs.kde.org/#", v ) );
QVERIFY( v == pwmap );
// do it again
QVERIFY( !wallet->writeMap( "https://bugs.kde.org/#", pwmap ) );
QVERIFY( wallet->hasEntry("https://bugs.kde.org/#") );
QVERIFY( !wallet->readMap( "https://bugs.kde.org/#", v ) );
QVERIFY( v == pwmap );
QVERIFY( wallet->entryType( testKeys[0] ) == Wallet::Stream );
QVERIFY( wallet->entryType( "https://bugs.kde.org/#" ) == Wallet::Map );
QVERIFY( !wallet->renameEntry( "https://bugs.kde.org/#", "kdeBugs" ) );
QVERIFY( wallet->hasEntry("kdeBugs") );
QVERIFY( !wallet->readMap( "kdeBugs", v ) );
QVERIFY( v == pwmap );
// close
wallet->sync();
QStringList l = wallet->entryList();
kWarning() << "Entry list:" << l;
QVERIFY( l.size() == 6 );
Wallet::closeWallet( testWallet, true );
QVERIFY( !Wallet::isOpen( testWallet ) );
// test for key - closed wallet
for ( int i = 0; i < 5; i++ ) {
QVERIFY( !Wallet::keyDoesNotExist( testWallet, testFolder, testKeys[i] ) );
QVERIFY( Wallet::keyDoesNotExist( testWallet, testFolder, "madeUpKey" ) );
QVERIFY( Wallet::keyDoesNotExist( testWallet, "madeUpFolderName", "madeUpKey" ) );
QVERIFY( Wallet::keyDoesNotExist( testWallet, "madeUpFolderName", testKeys[i] ) );
}
// open
wallet = Wallet::openWallet( testWallet, w->winId(), Wallet::Synchronous );
QVERIFY( wallet != 0 );
QVERIFY( Wallet::isOpen( testWallet ) );
// set folder
QVERIFY( wallet->hasFolder( testFolder ) );
wallet->setFolder( testFolder );
QVERIFY( wallet->currentFolder() == testFolder );
// test for key - opened wallet
for ( int i = 0; i < numTests; i++ ) {
QVERIFY( !Wallet::keyDoesNotExist( testWallet, testFolder, testKeys[i] ) );
QVERIFY( Wallet::keyDoesNotExist( testWallet, testFolder, "madeUpKey" ) );
QVERIFY( Wallet::keyDoesNotExist( testWallet, "madeUpFolderName", "madeUpKey" ) );
QVERIFY( Wallet::keyDoesNotExist( testWallet, "madeUpFolderName", testKeys[i] ) );
}
// read many keys
for ( int i = 0; i < numTests; i++ ) {
QByteArray readEntry;
wallet->readEntry( testKeys[i], readEntry );
QVERIFY( readEntry == testValues[i] );
}
// remove those many test keys
for ( int i = 0; i < numTests; i++ ) {
QVERIFY( !wallet->removeEntry( testKeys[i] ) );
}
// delete folder
wallet->removeFolder( testFolder );
QVERIFY( !wallet->hasFolder( testFolder ) );
// close
Wallet::closeWallet( testWallet, true );
QVERIFY( !Wallet::isOpen( testWallet ) );
QVERIFY( !Wallet::deleteWallet( testWallet ) );
}
QTEST_KDEMAIN(KWalletTest, GUI)
#include "moc_kwallettest.cpp"

View file

@ -1,40 +0,0 @@
/*
This file is part of the KDE Libraries
Copyright (C) 2007 Thomas McGuire (thomas.mcguire@gmx.net)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KWALLETTEST_H
#define KWALLETTEST_H
#include <QtCore/QObject>
#include "qtest_kde.h"
class KWalletTest : public QObject
{
Q_OBJECT
public:
private Q_SLOTS:
void testWallet();
};
#endif

View file

@ -1,901 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2002-2004 George Staikos <staikos@kde.org>
* Copyright (C) 2008 Michael Leupold <lemma@confuego.org>
* Copyright (C) 2011 Valentin Rusu <kde@rusu.info>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "kwallet.h"
#include <QtGui/QApplication>
#include <QtCore/QPointer>
#include <QtGui/QWidget>
#include <QtDBus/QtDBus>
#include <QtCore/qtimer.h>
#include <ktoolinvocation.h>
#include <assert.h>
#include <kcomponentdata.h>
#include <kconfiggroup.h>
#include <kdebug.h>
#include <kdeversion.h>
#include <kglobal.h>
#include <kaboutdata.h>
#include <ksharedconfig.h>
#include <kwindowsystem.h>
#include "kwallet_interface.h"
typedef QMap<QString, QByteArray> StringByteArrayMap;
Q_DECLARE_METATYPE(StringByteArrayMap)
namespace KWallet
{
class KWalletDLauncher
{
public:
KWalletDLauncher();
~KWalletDLauncher();
org::kde::KWallet &getInterface();
org::kde::KWallet *m_wallet;
KConfigGroup m_cgroup;
};
K_GLOBAL_STATIC(KWalletDLauncher, walletLauncher)
static QString appid()
{
if (KGlobal::hasMainComponent()) {
KComponentData cData = KGlobal::mainComponent();
if (cData.isValid()) {
const KAboutData* aboutData = cData.aboutData();
if (aboutData) {
return aboutData->programName();
}
return cData.componentName();
}
}
return qApp->applicationName();
}
static void registerTypes()
{
static bool registered = false;
if (!registered) {
qDBusRegisterMetaType<StringByteArrayMap>();
registered = true;
}
}
const QString Wallet::LocalWallet() {
// NOTE: This method stays unchanged for KSecretsService
KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet"));
if (!cfg.readEntry("Use One Wallet", true)) {
QString tmp = cfg.readEntry("Local Wallet", "localwallet");
if (tmp.isEmpty()) {
return "localwallet";
}
return tmp;
}
QString tmp = cfg.readEntry("Default Wallet", "kdewallet");
if (tmp.isEmpty()) {
return "kdewallet";
}
return tmp;
}
const QString Wallet::NetworkWallet() {
// NOTE: This method stays unchanged for KSecretsService
KConfigGroup cfg(KSharedConfig::openConfig("kwalletrc")->group("Wallet"));
QString tmp = cfg.readEntry("Default Wallet", "kdewallet");
if (tmp.isEmpty()) {
return "kdewallet";
}
return tmp;
}
const QString Wallet::PasswordFolder() {
return "Passwords";
}
const QString Wallet::FormDataFolder() {
return "Form Data";
}
class Wallet::WalletPrivate
{
public:
WalletPrivate(Wallet *wallet, int h, const QString &n)
: q(wallet), name(n), handle(h)
{}
void walletServiceUnregistered();
Wallet *q;
QString name;
QString folder;
int handle;
int transactionId;
};
static const char s_kwalletdServiceName[] = "org.kde.kwalletd";
Wallet::Wallet(int handle, const QString& name)
: QObject(0L), d(new WalletPrivate(this, handle, name))
{
QDBusServiceWatcher *watcher = new QDBusServiceWatcher(QString::fromLatin1(s_kwalletdServiceName), QDBusConnection::sessionBus(),
QDBusServiceWatcher::WatchForUnregistration, this);
connect(watcher, SIGNAL(serviceUnregistered(QString)),
this, SLOT(walletServiceUnregistered()));
connect(&walletLauncher->getInterface(), SIGNAL(walletClosed(int)), SLOT(slotWalletClosed(int)));
connect(&walletLauncher->getInterface(), SIGNAL(folderListUpdated(QString)), SLOT(slotFolderListUpdated(QString)));
connect(&walletLauncher->getInterface(), SIGNAL(folderUpdated(QString,QString)), SLOT(slotFolderUpdated(QString,QString)));
connect(&walletLauncher->getInterface(), SIGNAL(applicationDisconnected(QString,QString)), SLOT(slotApplicationDisconnected(QString,QString)));
// Verify that the wallet is still open
if (d->handle != -1) {
QDBusReply<bool> r = walletLauncher->getInterface().isOpen(d->handle);
if (r.isValid() && !r) {
d->handle = -1;
d->name.clear();
}
}
}
Wallet::~Wallet() {
if (d->handle != -1) {
if (!walletLauncher.isDestroyed()) {
walletLauncher->getInterface().close(d->handle, false, appid());
} else {
kDebug(285) << "Problem with static destruction sequence."
"Destroy any static Wallet before the event-loop exits.";
}
d->handle = -1;
d->folder.clear();
d->name.clear();
}
delete d;
}
QStringList Wallet::walletList() {
QStringList result;
QDBusReply<QStringList> r = walletLauncher->getInterface().wallets();
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
} else {
result = r;
}
return result;
}
void Wallet::changePassword(const QString& name, WId w) {
if( w == 0 ) {
kDebug(285) << "Pass a valid window to KWallet::Wallet::changePassword().";
}
// Make sure the password prompt window will be visible and activated
KWindowSystem::allowExternalProcessWindowActivation();
walletLauncher->getInterface().changePassword(name, (qlonglong)w, appid());
}
bool Wallet::isEnabled() {
QDBusReply<bool> r = walletLauncher->getInterface().isEnabled();
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
} else {
return r;
}
}
bool Wallet::isOpen(const QString& name) {
QDBusReply<bool> r = walletLauncher->getInterface().isOpen(name);
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
} else {
return r;
}
}
int Wallet::closeWallet(const QString& name, bool force) {
QDBusReply<int> r = walletLauncher->getInterface().close(name, force);
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return -1;
} else {
return r;
}
}
int Wallet::deleteWallet(const QString& name) {
QDBusReply<int> r = walletLauncher->getInterface().deleteWallet(name);
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return -1;
} else {
return r;
}
}
Wallet *Wallet::openWallet(const QString& name, WId w, OpenType ot) {
if( w == 0 ) {
kDebug(285) << "Pass a valid window to KWallet::Wallet::openWallet().";
}
Wallet *wallet = new Wallet(-1, name);
// connect the daemon's opened signal to the slot filtering the
// signals we need
connect(&walletLauncher->getInterface(), SIGNAL(walletAsyncOpened(int,int)),
wallet, SLOT(walletAsyncOpened(int,int)));
// Make sure the password prompt window will be visible and activated
KWindowSystem::allowExternalProcessWindowActivation();
// do the call
QDBusReply<int> r;
if (ot == Synchronous) {
r = walletLauncher->getInterface().open(name, (qlonglong)w, appid());
// after this call, r would contain a transaction id >0 if OK or -1 if NOK
// if OK, the slot walletAsyncOpened should have been received, but the transaction id
// will not match. We'll get that handle from the reply - see below
} else if (ot == Asynchronous) {
r = walletLauncher->getInterface().openAsync(name, (qlonglong)w, appid(), true);
} else if (ot == Path) {
r = walletLauncher->getInterface().openPathAsync(name, (qlonglong)w, appid(), true);
} else {
delete wallet;
return 0;
}
// error communicating with the daemon (maybe not running)
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
delete wallet;
return 0;
}
wallet->d->transactionId = r.value();
if (ot == Synchronous || ot == Path) {
// check for an immediate error
if (wallet->d->transactionId < 0) {
delete wallet;
wallet = 0;
} else {
wallet->d->handle = r.value();
}
} else if (ot == Asynchronous) {
if (wallet->d->transactionId < 0) {
QTimer::singleShot(0, wallet, SLOT(emitWalletAsyncOpenError()));
// client code is responsible for deleting the wallet
}
}
return wallet;
}
void Wallet::slotCollectionDeleted()
{
d->folder.clear();
d->name.clear();
emit walletClosed();
}
bool Wallet::disconnectApplication(const QString& wallet, const QString& app) {
QDBusReply<bool> r = walletLauncher->getInterface().disconnectApplication(wallet, app);
if (!r.isValid())
{
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
}
else
return r;
}
QStringList Wallet::users(const QString& name) {
QDBusReply<QStringList> r = walletLauncher->getInterface().users(name);
if (!r.isValid())
{
kDebug(285) << "Invalid DBus reply: " << r.error();
return QStringList();
}
else
return r;
}
int Wallet::sync() {
if (d->handle == -1) {
return -1;
}
walletLauncher->getInterface().sync(d->handle, appid());
return 0;
}
int Wallet::lockWallet() {
if (d->handle == -1) {
return -1;
}
QDBusReply<int> r = walletLauncher->getInterface().close(d->handle, true, appid());
d->handle = -1;
d->folder.clear();
d->name.clear();
if (r.isValid()) {
return r;
}
else {
kDebug(285) << "Invalid DBus reply: " << r.error();
return -1;
}
}
const QString& Wallet::walletName() const {
return d->name;
}
bool Wallet::isOpen() const {
return d->handle != -1;
}
void Wallet::requestChangePassword(WId w) {
if( w == 0 )
kDebug(285) << "Pass a valid window to KWallet::Wallet::requestChangePassword().";
if (d->handle == -1) {
return;
}
// Make sure the password prompt window will be visible and activated
KWindowSystem::allowExternalProcessWindowActivation();
walletLauncher->getInterface().changePassword(d->name, (qlonglong)w, appid());
}
void Wallet::slotWalletClosed(int handle) {
if (d->handle == handle) {
d->handle = -1;
d->folder.clear();
d->name.clear();
emit walletClosed();
}
}
QStringList Wallet::folderList() {
if (d->handle == -1) {
return QStringList();
}
QDBusReply<QStringList> r = walletLauncher->getInterface().folderList(d->handle, appid());
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return QStringList();
} else {
return r;
}
}
QStringList Wallet::entryList() {
if (d->handle == -1) {
return QStringList();
}
QDBusReply<QStringList> r = walletLauncher->getInterface().entryList(d->handle, d->folder, appid());
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return QStringList();
} else {
return r;
}
}
bool Wallet::hasFolder(const QString& f) {
if (d->handle == -1) {
return false;
}
QDBusReply<bool> r = walletLauncher->getInterface().hasFolder(d->handle, f, appid());
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
} else {
return r;
}
}
bool Wallet::createFolder(const QString& f) {
if (d->handle == -1) {
return false;
}
if (!hasFolder(f)) {
QDBusReply<bool> r = walletLauncher->getInterface().createFolder(d->handle, f, appid());
if (!r.isValid())
{
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
}
else
return r;
}
return true; // folder already exists
}
bool Wallet::setFolder(const QString& f) {
bool rc = false;
if (d->handle == -1) {
return rc;
}
// Don't do this - the folder could have disappeared?
#if 0
if (f == d->folder) {
return true;
}
#endif
if (hasFolder(f)) {
d->folder = f;
rc = true;
}
return rc;
}
bool Wallet::removeFolder(const QString& f) {
if (d->handle == -1) {
return false;
}
QDBusReply<bool> r = walletLauncher->getInterface().removeFolder(d->handle, f, appid());
if (d->folder == f) {
setFolder(QString());
}
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
} else {
return r;
}
}
const QString& Wallet::currentFolder() const {
return d->folder;
}
int Wallet::readEntry(const QString& key, QByteArray& value) {
int rc = -1;
if (d->handle == -1) {
return rc;
}
QDBusReply<QByteArray> r = walletLauncher->getInterface().readEntry(d->handle, d->folder, key, appid());
if (r.isValid()) {
value = r;
rc = 0;
}
return rc;
}
int Wallet::readEntryList(const QString& key, QMap<QString, QByteArray>& value) {
int rc = -1;
registerTypes();
if (d->handle == -1) {
return rc;
}
QDBusReply<QVariantMap> r = walletLauncher->getInterface().readEntryList(d->handle, d->folder, key, appid());
if (r.isValid()) {
rc = 0;
// convert <QString, QVariant> to <QString, QByteArray>
const QVariantMap val = r.value();
for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
value.insert(it.key(), it.value().toByteArray());
}
}
return rc;
}
int Wallet::renameEntry(const QString& oldName, const QString& newName) {
int rc = -1;
if (d->handle == -1) {
return rc;
}
QDBusReply<int> r = walletLauncher->getInterface().renameEntry(d->handle, d->folder, oldName, newName, appid());
if (r.isValid()) {
rc = r;
}
return rc;
}
int Wallet::readMap(const QString& key, QMap<QString,QString>& value) {
int rc = -1;
registerTypes();
if (d->handle == -1) {
return rc;
}
QDBusReply<QByteArray> r = walletLauncher->getInterface().readMap(d->handle, d->folder, key, appid());
if (r.isValid()) {
rc = 0;
QByteArray v = r;
if (!v.isEmpty()) {
QDataStream ds(&v, QIODevice::ReadOnly);
ds >> value;
}
}
return rc;
}
int Wallet::readMapList(const QString& key, QMap<QString, QMap<QString, QString> >& value) {
int rc = -1;
registerTypes();
if (d->handle == -1) {
return rc;
}
QDBusReply<QVariantMap> r =
walletLauncher->getInterface().readMapList(d->handle, d->folder, key, appid());
if (r.isValid()) {
rc = 0;
const QVariantMap val = r.value();
for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
QByteArray mapData = it.value().toByteArray();
if (!mapData.isEmpty()) {
QDataStream ds(&mapData, QIODevice::ReadOnly);
QMap<QString,QString> v;
ds >> v;
value.insert(it.key(), v);
}
}
}
return rc;
}
int Wallet::readPassword(const QString& key, QString& value) {
int rc = -1;
if (d->handle == -1) {
return rc;
}
QDBusReply<QString> r = walletLauncher->getInterface().readPassword(d->handle, d->folder, key, appid());
if (r.isValid()) {
value = r;
rc = 0;
}
return rc;
}
int Wallet::readPasswordList(const QString& key, QMap<QString, QString>& value) {
int rc = -1;
registerTypes();
if (d->handle == -1) {
return rc;
}
QDBusReply<QVariantMap> r = walletLauncher->getInterface().readPasswordList(d->handle, d->folder, key, appid());
if (r.isValid()) {
rc = 0;
const QVariantMap val = r.value();
for( QVariantMap::const_iterator it = val.begin(); it != val.end(); ++it ) {
value.insert(it.key(), it.value().toString());
}
}
return rc;
}
int Wallet::writeEntry(const QString& key, const QByteArray& value, EntryType entryType) {
int rc = -1;
if (d->handle == -1) {
return rc;
}
QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, int(entryType), appid());
if (r.isValid()) {
rc = r;
}
return rc;
}
int Wallet::writeEntry(const QString& key, const QByteArray& value) {
int rc = -1;
if (d->handle == -1) {
return rc;
}
QDBusReply<int> r = walletLauncher->getInterface().writeEntry(d->handle, d->folder, key, value, appid());
if (r.isValid()) {
rc = r;
}
return rc;
}
int Wallet::writeMap(const QString& key, const QMap<QString,QString>& value) {
int rc = -1;
registerTypes();
if (d->handle == -1) {
return rc;
}
QByteArray mapData;
QDataStream ds(&mapData, QIODevice::WriteOnly);
ds << value;
QDBusReply<int> r = walletLauncher->getInterface().writeMap(d->handle, d->folder, key, mapData, appid());
if (r.isValid()) {
rc = r;
}
return rc;
}
int Wallet::writePassword(const QString& key, const QString& value) {
int rc = -1;
if (d->handle == -1) {
return rc;
}
QDBusReply<int> r = walletLauncher->getInterface().writePassword(d->handle, d->folder, key, value, appid());
if (r.isValid()) {
rc = r;
}
return rc;
}
bool Wallet::hasEntry(const QString& key) {
if (d->handle == -1) {
return false;
}
QDBusReply<bool> r = walletLauncher->getInterface().hasEntry(d->handle, d->folder, key, appid());
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
} else {
return r;
}
}
int Wallet::removeEntry(const QString& key) {
int rc = -1;
if (d->handle == -1) {
return rc;
}
QDBusReply<int> r = walletLauncher->getInterface().removeEntry(d->handle, d->folder, key, appid());
if (r.isValid()) {
rc = r;
}
return rc;
}
Wallet::EntryType Wallet::entryType(const QString& key) {
int rc = 0;
if (d->handle == -1) {
return Wallet::Unknown;
}
QDBusReply<int> r = walletLauncher->getInterface().entryType(d->handle, d->folder, key, appid());
if (r.isValid()) {
rc = r;
}
return static_cast<EntryType>(rc);
}
void Wallet::WalletPrivate::walletServiceUnregistered()
{
if (handle >= 0) {
q->slotWalletClosed(handle);
}
}
void Wallet::slotFolderUpdated(const QString& wallet, const QString& folder) {
if (d->name == wallet) {
emit folderUpdated(folder);
}
}
void Wallet::slotFolderListUpdated(const QString& wallet) {
if (d->name == wallet) {
emit folderListUpdated();
}
}
void Wallet::slotApplicationDisconnected(const QString& wallet, const QString& application) {
if (d->handle >= 0
&& d->name == wallet
&& application == appid()) {
slotWalletClosed(d->handle);
}
}
void Wallet::walletAsyncOpened(int tId, int handle) {
// ignore responses to calls other than ours
if (d->transactionId != tId || d->handle != -1) {
return;
}
// disconnect the async signal
disconnect(this, SLOT(walletAsyncOpened(int,int)));
d->handle = handle;
emit walletOpened(handle > 0);
}
void Wallet::emitWalletAsyncOpenError() {
emit walletOpened(false);
}
void Wallet::emitWalletOpened() {
emit walletOpened(true);
}
bool Wallet::folderDoesNotExist(const QString& wallet, const QString& folder)
{
QDBusReply<bool> r = walletLauncher->getInterface().folderDoesNotExist(wallet, folder);
if (!r.isValid()) {
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
} else {
return r;
}
}
bool Wallet::keyDoesNotExist(const QString& wallet, const QString& folder, const QString& key)
{
QDBusReply<bool> r = walletLauncher->getInterface().keyDoesNotExist(wallet, folder, key);
if (!r.isValid())
{
kDebug(285) << "Invalid DBus reply: " << r.error();
return false;
} else {
return r;
}
}
KWalletDLauncher::KWalletDLauncher()
: m_wallet(0),
m_cgroup(KSharedConfig::openConfig("kwalletrc", KConfig::NoGlobals)->group("Wallet"))
{
m_wallet = new org::kde::KWallet(QString::fromLatin1(s_kwalletdServiceName), "/modules/kwalletd", QDBusConnection::sessionBus());
}
KWalletDLauncher::~KWalletDLauncher()
{
delete m_wallet;
}
org::kde::KWallet &KWalletDLauncher::getInterface()
{
Q_ASSERT(m_wallet != 0);
// check if kwalletd is already running
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName)))
{
// not running! check if it is enabled.
bool walletEnabled = m_cgroup.readEntry("Enabled", true);
if (walletEnabled) {
// wallet is enabled! try launching it
QString error;
int ret = KToolInvocation::startServiceByDesktopPath("kwalletd.desktop", QStringList(), &error);
if (ret > 0)
{
kError(285) << "Couldn't start kwalletd: " << error << endl;
}
if
(!QDBusConnection::sessionBus().interface()->isServiceRegistered(QString::fromLatin1(s_kwalletdServiceName))) {
kDebug(285) << "The kwalletd service is still not registered";
} else {
kDebug(285) << "The kwalletd service has been registered";
}
} else {
kError(285) << "The kwalletd service has been disabled";
}
}
return *m_wallet;
}
} // namespace KWallet
#include "moc_kwallet.cpp"

View file

@ -1,521 +0,0 @@
/* This file is part of the KDE project
*
* Copyright (C) 2002-2004 George Staikos <staikos@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KWALLET_H
#define KWALLET_H
#include <QtCore/QStringList>
#include <QtCore/QObject>
#include <QtGui/qwindowdefs.h> // krazy:exclude=includes (for WId)
#include <kdeui_export.h>
#include <QDBusError>
namespace KWallet {
/**
* KDE Wallet
*
* This class implements a generic system-wide Wallet for KDE. This is the
* ONLY public interface.
*
* @author George Staikos <staikos@kde.org>
* @short KDE Wallet Class
*/
class KDEUI_EXPORT Wallet : public QObject
{
Q_OBJECT
protected:
/**
* Construct a KWallet object.
* @internal
* @param handle The handle for the wallet.
* @param name The name of the wallet.
*/
Wallet(int handle, const QString& name);
/**
* Copy a KWallet object.
* @internal
*/
Wallet(const Wallet&);
public:
enum EntryType { Unknown=0, Password, Stream, Map, Unused=0xffff };
/**
* Destroy a KWallet object. Closes the wallet.
*/
virtual ~Wallet();
/**
* List all the wallets available.
* @return Returns a list of the names of all wallets that are
* open.
*/
static QStringList walletList();
/**
* Determine if the KDE wallet is enabled. Normally you do
* not need to use this because openWallet() will just fail.
* @return Returns true if the wallet enabled, else false.
*/
static bool isEnabled();
/**
* Determine if the wallet @p name is open by any application.
* @param name The name of the wallet to check.
* @return Returns true if the wallet is open, else false.
*/
static bool isOpen(const QString& name);
/**
* Close the wallet @p name. The wallet will only be closed
* if it is open but not in use (rare), or if it is forced
* closed.
* @param name The name of the wallet to close.
* @param force Set true to force the wallet closed even if it
* is in use by others.
* @return Returns 0 on success, non-zero on error.
*/
static int closeWallet(const QString& name, bool force);
/**
* Delete the wallet @p name. The wallet will be forced closed
* first.
* @param name The name of the wallet to delete.
* @return Returns 0 on success, non-zero on error.
*/
static int deleteWallet(const QString& name);
/**
* Disconnect the application @p app from @p wallet.
* @param wallet The name of the wallet to disconnect.
* @param app The name of the application to disconnect.
* @return Returns true on success, false on error.
*/
static bool disconnectApplication(const QString& wallet, const QString& app);
enum OpenType { Synchronous=0, Asynchronous, Path, OpenTypeUnused=0xff };
/**
* Open the wallet @p name. The user will be prompted to
* allow your application to open the wallet, and may be
* prompted for a password. You are responsible for deleting
* this object when you are done with it.
* @param name The name of the wallet to open.
* @param ot If Asynchronous, the call will return
* immediately with a non-null pointer to an
* invalid wallet. You must immediately connect
* the walletOpened() signal to a slot so that
* you will know when it is opened, or when it
* fails.
* @param w The window id to associate any dialogs with. You can pass
* 0 if you don't have a window the password dialog should
* associate with.
* @return Returns a pointer to the wallet if successful,
* or a null pointer on error or if rejected.
*/
static Wallet* openWallet(const QString& name, WId w, OpenType ot = Synchronous);
/**
* List the applications that are using the wallet @p wallet.
* @param wallet The wallet to query.
* @return Returns a list of all DCOP application IDs using
* the wallet.
*/
static QStringList users(const QString& wallet);
/**
* The name of the wallet used to store local passwords.
*/
static const QString LocalWallet();
/**
* The name of the wallet used to store network passwords.
*/
static const QString NetworkWallet();
/**
* The standardized name of the password folder.
* It is automatically created when a wallet is created, but
* the user may still delete it so you should check for its
* existence and recreate it if necessary and desired.
*/
static const QString PasswordFolder();
/**
* The standardized name of the form data folder.
* It is automatically created when a wallet is created, but
* the user may still delete it so you should check for its
* existence and recreate it if necessary and desired.
*/
static const QString FormDataFolder();
/**
* Request to the wallet service to change the password of
* the wallet @p name.
* @param name The the wallet to change the password of.
* @param w The window id to associate any dialogs with. You can pass
* 0 if you don't have a window the password dialog should
* associate with.
*/
static void changePassword(const QString& name, WId w);
/**
* This syncs the wallet file on disk with what is in memory.
* You don't normally need to use this. It happens
* automatically on close.
* @return Returns 0 on success, non-zero on error.
*/
virtual int sync();
/**
* This closes and locks the current wallet. It will
* disconnect all applications using the wallet.
* @return Returns 0 on success, non-zero on error.
*/
virtual int lockWallet();
/**
* The name of the current wallet.
*/
virtual const QString& walletName() const;
/**
* Determine if the current wallet is open, and is a valid
* wallet handle.
* @return Returns true if the wallet handle is valid and open.
*/
virtual bool isOpen() const;
/**
* Request to the wallet service to change the password of
* the current wallet.
* @param w The window id to associate any dialogs with. You can pass
* 0 if you don't have a window the password dialog should
* associate with.
*/
virtual void requestChangePassword(WId w);
/**
* Obtain the list of all folders contained in the wallet.
* @return Returns an empty list if the wallet is not open.
*/
virtual QStringList folderList();
/**
* Determine if the folder @p f exists in the wallet.
* @param f the name of the folder to check for
* @return Returns true if the folder exists in the wallet.
*/
virtual bool hasFolder(const QString& f);
/**
* Set the current working folder to @p f. The folder must
* exist, or this call will fail. Create a folder with
* createFolder().
* @param f the name of the folder to make the working folder
* @return Returns true if the folder was successfully set.
*/
virtual bool setFolder(const QString& f);
/**
* Remove the folder @p f and all its entries from the wallet.
* @param f the name of the folder to remove
* @return Returns true if the folder was successfully removed.
*/
virtual bool removeFolder(const QString& f);
/**
* Created the folder @p f.
* @param f the name of the folder to create
* @return Returns true if the folder was successfully created.
*/
virtual bool createFolder(const QString& f);
/**
* Determine the current working folder in the wallet.
* If the folder name is empty, it is working in the global
* folder, which is valid but discouraged.
* @return Returns the current working folder.
*/
virtual const QString& currentFolder() const;
/**
* Return the list of keys of all entries in this folder.
* @return Returns an empty list if the wallet is not open, or
* if the folder is empty.
*/
virtual QStringList entryList();
/**
* Rename the entry @p oldName to @p newName.
* @param oldName The original key of the entry.
* @param newName The new key of the entry.
* @return Returns 0 on success, non-zero on error.
*/
virtual int renameEntry(const QString& oldName, const QString& newName);
/**
* Read the entry @p key from the current folder.
* The entry format is unknown except that it is either a
* QByteArray or a QDataStream, which effectively means that
* it is anything.
* @param key The key of the entry to read.
* @param value A buffer to fill with the value.
* @return Returns 0 on success, non-zero on error.
*/
virtual int readEntry(const QString& key, QByteArray& value);
/**
* Read the map entry @p key from the current folder.
* @param key The key of the entry to read.
* @param value A map buffer to fill with the value.
* @return Returns 0 on success, non-zero on error. Will
* return an error if the key was not originally
* written as a map.
*/
virtual int readMap(const QString& key, QMap<QString,QString>& value);
/**
* Read the password entry @p key from the current folder.
* @param key The key of the entry to read.
* @param value A password buffer to fill with the value.
* @return Returns 0 on success, non-zero on error. Will
* return an error if the key was not originally
* written as a password.
*/
virtual int readPassword(const QString& key, QString& value);
/**
* Read the entries matching @p key from the current folder.
* The entry format is unknown except that it is either a
* QByteArray or a QDataStream, which effectively means that
* it is anything.
* @param key The key of the entry to read. Wildcards
* are supported.
* @param value A buffer to fill with the value. The key in
* the map is the entry key.
* @return Returns 0 on success, non-zero on error.
*/
int readEntryList(const QString& key, QMap<QString, QByteArray>& value);
/**
* Read the map entry @p key from the current folder.
* @param key The key of the entry to read. Wildcards
* are supported.
* @param value A buffer to fill with the value. The key in
* the map is the entry key.
* @return Returns 0 on success, non-zero on error. Will
* return an error if the key was not originally
* written as a map.
*/
int readMapList(const QString& key, QMap<QString, QMap<QString, QString> >& value);
/**
* Read the password entry @p key from the current folder.
* @param key The key of the entry to read. Wildcards
* are supported.
* @param value A buffer to fill with the value. The key in
* the map is the entry key.
* @return Returns 0 on success, non-zero on error. Will
* return an error if the key was not originally
* written as a password.
*/
int readPasswordList(const QString& key, QMap<QString, QString>& value);
/**
* Write @p key = @p value as a binary entry to the current
* folder. Be careful with this, it could cause inconsistency
* in the future since you can put an arbitrary entry type in
* place.
* @param key The key of the new entry.
* @param value The value of the entry.
* @param entryType The type of the entry.
* @return Returns 0 on success, non-zero on error.
*/
virtual int writeEntry(const QString& key, const QByteArray& value, EntryType entryType);
/**
* Write @p key = @p value as a binary entry to the current
* folder.
* @param key The key of the new entry.
* @param value The value of the entry.
* @return Returns 0 on success, non-zero on error.
*/
virtual int writeEntry(const QString& key, const QByteArray& value);
/**
* Write @p key = @p value as a map to the current folder.
* @param key The key of the new entry.
* @param value The value of the map.
* @return Returns 0 on success, non-zero on error.
*/
virtual int writeMap(const QString& key, const QMap<QString,QString>& value);
/**
* Write @p key = @p value as a password to the current folder.
* @param key The key of the new entry.
* @param value The value of the password.
* @return Returns 0 on success, non-zero on error.
*/
virtual int writePassword(const QString& key, const QString& value);
/**
* Determine if the current folder has they entry @p key.
* @param key The key to search for.
* @return Returns true if the folder contains @p key.
*/
virtual bool hasEntry(const QString& key);
/**
* Remove the entry @p key from the current folder.
* @param key The key to remove.
* @return Returns 0 on success, non-zero on error.
*/
virtual int removeEntry(const QString& key);
/**
* Determine the type of the entry @p key in this folder.
* @param key The key to look up.
* @return Returns an enumerated type representing the type
* of the entry.
*/
virtual EntryType entryType(const QString& key);
/**
* Determine if a folder does not exist in a wallet. This
* does not require decryption of the wallet.
* This is a handy optimization to avoid prompting the user
* if your data is certainly not in the wallet.
* @param wallet The wallet to look in.
* @param folder The folder to look up.
* @return Returns true if the folder does NOT exist in the
* wallet, or the wallet does not exist.
*/
static bool folderDoesNotExist(const QString& wallet, const QString& folder);
/**
* Determine if an entry in a folder does not exist in a
* wallet. This does not require decryption of the wallet.
* This is a handy optimization to avoid prompting the user
* if your data is certainly not in the wallet.
* @param wallet The wallet to look in.
* @param folder The folder to look in.
* @param key The key to look up.
* @return Returns true if the key does NOT exist in the
* wallet, or the folder or wallet does not exist.
*/
static bool keyDoesNotExist(const QString& wallet, const QString& folder,
const QString& key);
Q_SIGNALS:
/**
* Emitted when this wallet is closed.
*/
void walletClosed();
/**
* Emitted when a folder in this wallet is updated.
* @param folder The folder that was updated.
*/
void folderUpdated(const QString& folder);
/**
* Emitted when the folder list is changed in this wallet.
*/
void folderListUpdated();
/**
* Emitted when a folder in this wallet is removed.
* @param folder The folder that was removed.
*/
void folderRemoved(const QString& folder);
/**
* Emitted when a wallet is opened in asynchronous mode.
* @param success True if the wallet was opened successfully.
*/
void walletOpened(bool success);
private Q_SLOTS:
/**
* @internal
* DBUS slot for signals emitted by the wallet service.
*/
void slotWalletClosed(int handle);
/**
* @internal
* DBUS slot for signals emitted by the wallet service.
*/
void slotFolderUpdated(const QString& wallet, const QString& folder);
/**
* @internal
* DBUS slot for signals emitted by the wallet service.
*/
void slotFolderListUpdated(const QString& wallet);
/**
* @internal
* DBUS slot for signals emitted by the wallet service.
*/
void slotApplicationDisconnected(const QString& wallet, const QString& application);
/**
* @internal
* Callback for kwalletd
* @param tId identifer for the open transaction
* @param handle the wallet's handle
*/
void walletAsyncOpened(int tId, int handle);
/**
* @internal
* DBUS error slot.
*/
void emitWalletAsyncOpenError();
/**
* @internal
* Emits wallet opening success.
*/
void emitWalletOpened();
/**
* @internal
* Received delete notification from KSecretsService infrastructure
*/
void slotCollectionDeleted();
private:
class WalletPrivate;
WalletPrivate* const d;
Q_PRIVATE_SLOT(d, void walletServiceUnregistered())
};
}
#endif //KWALLET_H

View file

@ -1,276 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.KWallet">
<signal name="walletListDirty">
</signal>
<signal name="walletCreated">
<arg name="wallet" type="s" direction="out"/>
</signal>
<signal name="walletOpened">
<arg name="wallet" type="s" direction="out"/>
</signal>
<signal name="walletAsyncOpened">
<arg name="tId" type="i" direction="out"/>
<arg name="handle" type="i" direction="out"/>
</signal>
<signal name="walletDeleted">
<arg name="wallet" type="s" direction="out"/>
</signal>
<signal name="walletClosed">
<arg name="wallet" type="s" direction="out"/>
</signal>
<signal name="walletClosed">
<arg name="handle" type="i" direction="out"/>
</signal>
<signal name="allWalletsClosed">
</signal>
<signal name="folderListUpdated">
<arg name="wallet" type="s" direction="out"/>
</signal>
<signal name="folderUpdated">
<arg type="s" direction="out"/>
<arg type="s" direction="out"/>
</signal>
<signal name="applicationDisconnected">
<arg name="wallet" type="s" direction="out"/>
<arg name="application" type="s" direction="out"/>
</signal>
<method name="isEnabled">
<arg type="b" direction="out"/>
</method>
<method name="open">
<arg type="i" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
<arg name="wId" type="x" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="openPath">
<arg type="i" direction="out"/>
<arg name="path" type="s" direction="in"/>
<arg name="wId" type="x" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="openAsync">
<arg type="i" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
<arg name="wId" type="x" direction="in"/>
<arg name="appid" type="s" direction="in"/>
<arg name="handleSession" type="b" direction="in"/>
</method>
<method name="openPathAsync">
<arg type="i" direction="out"/>
<arg name="path" type="s" direction="in"/>
<arg name="wId" type="x" direction="in"/>
<arg name="appid" type="s" direction="in"/>
<arg name="handleSession" type="b" direction="in"/>
</method>
<method name="close">
<arg type="i" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
<arg name="force" type="b" direction="in"/>
</method>
<method name="close">
<arg type="i" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="force" type="b" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="sync">
<arg name="handle" type="i" direction="in"/>
<arg name="appid" type="s" direction="in"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
<method name="deleteWallet">
<arg type="i" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
</method>
<method name="isOpen">
<arg type="b" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
</method>
<method name="isOpen">
<arg type="b" direction="out"/>
<arg name="handle" type="i" direction="in"/>
</method>
<method name="users">
<arg type="as" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
</method>
<method name="changePassword">
<arg name="wallet" type="s" direction="in"/>
<arg name="wId" type="x" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="wallets">
<arg type="as" direction="out"/>
</method>
<method name="folderList">
<arg type="as" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="hasFolder">
<arg type="b" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="createFolder">
<arg type="b" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="removeFolder">
<arg type="b" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="entryList">
<arg type="as" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="readEntry">
<arg type="ay" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="readMap">
<arg type="ay" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="readPassword">
<arg type="s" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="readEntryList">
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="readMapList">
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="readPasswordList">
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="renameEntry">
<arg type="i" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="oldName" type="s" direction="in"/>
<arg name="newName" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="writeEntry">
<arg type="i" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="value" type="ay" direction="in"/>
<arg name="entryType" type="i" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="writeEntry">
<arg type="i" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="value" type="ay" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="writeMap">
<arg type="i" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="value" type="ay" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="writePassword">
<arg type="i" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="value" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="hasEntry">
<arg type="b" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="entryType">
<arg type="i" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="removeEntry">
<arg type="i" direction="out"/>
<arg name="handle" type="i" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
<arg name="appid" type="s" direction="in"/>
</method>
<method name="disconnectApplication">
<arg type="b" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
<arg name="application" type="s" direction="in"/>
</method>
<method name="reconfigure">
</method>
<method name="folderDoesNotExist">
<arg type="b" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
<arg name="folder" type="s" direction="in"/>
</method>
<method name="keyDoesNotExist">
<arg type="b" direction="out"/>
<arg name="wallet" type="s" direction="in"/>
<arg name="folder" type="s" direction="in"/>
<arg name="key" type="s" direction="in"/>
</method>
<method name="closeAllWallets">
</method>
<method name="networkWallet">
<arg type="s" direction="out"/>
</method>
<method name="localWallet">
<arg type="s" direction="out"/>
</method>
<method name="pamOpen">
<arg name="wallet" type="s" direction="in"/>
<arg name="passwordHash" type="ay" direction="in"/>
<arg name="sessionTimeout" type="i" direction="in"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
</interface>
</node>

View file

@ -89,8 +89,6 @@ set(kiocore_STAT_SRCS
kio/thumbsequencecreator.cpp
kio/udsentry.cpp
kio/hostinfo.cpp
kio/kpasswdserver.cpp
kio/kpasswdserverloop.cpp
kio/usernotificationhandler.cpp
kio/clipboardupdater.cpp
kio/kautomount.cpp
@ -111,14 +109,6 @@ qt4_add_dbus_interface(kiocore_STAT_SRCS
kuiserver_interface
)
set_source_files_properties(kio/org.kde.KPasswdServer.xml
PROPERTIES INCLUDE kio/authinfo.h
)
qt4_add_dbus_interface(kiocore_STAT_SRCS
kio/org.kde.KPasswdServer.xml
kpasswdserver_interface
)
set(kbookmarks_STAT_SRCS
bookmarks/kbookmark.cc
bookmarks/kbookmarkimporter.cc
@ -176,6 +166,7 @@ target_link_libraries(kio PRIVATE
target_link_libraries(kio PUBLIC
${KDE4_KDECORE_LIBS}
${KDE4_KDEUI_LIBS}
${KDE4_KPASSWDSTORE_LIBS}
${QT_QTNETWORK_LIBRARY}
${QT_QTXML_LIBRARY}
${QT_QTGUI_LIBRARY}
@ -311,7 +302,6 @@ install(
FILES
kio/org.kde.KDirNotify.xml
kio/org.kde.kio.FileUndoManager.xml
kio/org.kde.KPasswdServer.xml
DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR}
)

View file

@ -152,8 +152,6 @@ AuthInfo& AuthInfo::operator= ( const AuthInfo& info )
caption = info.caption;
comment = info.comment;
commentLabel = info.commentLabel;
realmValue = info.realmValue;
digestInfo = info.digestInfo;
verifyPath = info.verifyPath;
readOnly = info.readOnly;
keepPassword = info.keepPassword;
@ -210,7 +208,7 @@ QDataStream& KIO::operator<< (QDataStream& s, const AuthInfo& a)
{
s << (quint8)1
<< a.url << a.username << a.password << a.prompt << a.caption
<< a.comment << a.commentLabel << a.realmValue << a.digestInfo
<< a.comment << a.commentLabel
<< a.verifyPath << a.readOnly << a.keepPassword << a.modified
<< a.d->extraFields;
return s;
@ -221,7 +219,7 @@ QDataStream& KIO::operator>> (QDataStream& s, AuthInfo& a)
quint8 version;
s >> version
>> a.url >> a.username >> a.password >> a.prompt >> a.caption
>> a.comment >> a.commentLabel >> a.realmValue >> a.digestInfo
>> a.comment >> a.commentLabel
>> a.verifyPath >> a.readOnly >> a.keepPassword >> a.modified
>> a.d->extraFields;
return s;
@ -232,7 +230,7 @@ QDBusArgument &KIO::operator<<(QDBusArgument &argument, const AuthInfo &a)
argument.beginStructure();
argument << (quint8)1
<< a.url.url() << a.username << a.password << a.prompt << a.caption
<< a.comment << a.commentLabel << a.realmValue << a.digestInfo
<< a.comment << a.commentLabel
<< a.verifyPath << a.readOnly << a.keepPassword << a.modified
<< a.d->extraFields;
argument.endStructure();
@ -247,7 +245,7 @@ const QDBusArgument &KIO::operator>>(const QDBusArgument &argument, AuthInfo &a)
argument.beginStructure();
argument >> version
>> url >> a.username >> a.password >> a.prompt >> a.caption
>> a.comment >> a.commentLabel >> a.realmValue >> a.digestInfo
>> a.comment >> a.commentLabel
>> a.verifyPath >> a.readOnly >> a.keepPassword >> a.modified
>> a.d->extraFields;
argument.endStructure();

View file

@ -171,30 +171,6 @@ public:
*/
QString commentLabel;
/**
* A unique identifier that allows caching of multiple
* passwords for different resources in the same server.
*
* Mostly this setting is applicable to the HTTP protocol
* whose authentication scheme explicitly defines the use
* of such a unique key. However, any protocol that can
* generate or supply a unique id can effectively use it
* to distinguish passwords.
*
* This setting is @em optional and not set by default.
*/
QString realmValue;
/**
* Field to store any extra authentication information for
* protocols that need it.
*
* This setting is @em optional and mostly applicable for HTTP
* protocol. However, any protocol can make use of it to
* store extra info.
*/
QString digestInfo;
/**
* Flag that, if set, indicates whether a path match should be
* performed when requesting for cached authorization.
@ -271,8 +247,7 @@ public:
/**
* Register the meta-types for AuthInfo. This is called from
* AuthInfo's constructor but needed by daemons on the DBus such
* as kpasswdserver.
* AuthInfo's constructor.
* @since 4.3
*/
static void registerMetaTypes();

View file

@ -1,210 +0,0 @@
/*
* This file is part of the KDE libraries
* Copyright (c) 2009 Michael Leupold <lemma@confuego.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "kpasswdserver_p.h"
#include <kio/authinfo.h>
#include <QtCore/QByteArray>
#include <QtCore/QEventLoop>
#include <QtCore/qcoreapplication.h>
#include <kdebug.h>
#include "kpasswdserverloop_p.h"
#include "kpasswdserver_interface.h"
namespace KIO
{
KPasswdServer::KPasswdServer()
: m_interface(new OrgKdeKPasswdServerInterface("org.kde.kded",
"/modules/kpasswdserver",
QDBusConnection::sessionBus()))
{
}
KPasswdServer::~KPasswdServer()
{
delete m_interface;
}
bool KPasswdServer::checkAuthInfo(KIO::AuthInfo &info, qlonglong windowId,
qlonglong usertime)
{
kDebug(7019) << "window-id=" << windowId << "url=" << info.url;
// special handling for kioslaves which aren't QCoreApplications
if (!QCoreApplication::instance()) {
kWarning(7019) << "kioslave is not a QCoreApplication!";
return legacyCheckAuthInfo(info, windowId, usertime);
}
// create the loop for waiting for a result before sending the request
KPasswdServerLoop loop;
QObject::connect(m_interface, SIGNAL(checkAuthInfoAsyncResult(qlonglong,qlonglong,KIO::AuthInfo)),
&loop, SLOT(slotQueryResult(qlonglong,qlonglong,KIO::AuthInfo)));
QDBusReply<qlonglong> reply = m_interface->checkAuthInfoAsync(info, windowId,
usertime);
if (!reply.isValid()) {
if (reply.error().type() == QDBusError::UnknownMethod) {
if (legacyCheckAuthInfo(info, windowId, usertime)) {
return true;
}
}
kWarning(7019) << "Can't communicate with kded_kpasswdserver (for checkAuthInfo)!";
kDebug(7019) << reply.error().name() << reply.error().message();
return false;
}
if (!loop.waitForResult(reply.value())) {
kWarning(7019) << "kded_kpasswdserver died while waiting for reply!";
return false;
}
if (loop.authInfo().isModified()) {
kDebug(7019) << "username=" << info.username << "password=[hidden]";
info = loop.authInfo();
return true;
}
return false;
}
bool KPasswdServer::legacyCheckAuthInfo(KIO::AuthInfo &info, qlonglong windowId,
qlonglong usertime)
{
kWarning(7019) << "Querying old kded_kpasswdserver.";
QByteArray params;
QDataStream stream(&params, QIODevice::WriteOnly);
stream << info;
QDBusReply<QByteArray> reply = m_interface->checkAuthInfo(params, windowId,
usertime);
if (reply.isValid()) {
AuthInfo authResult;
QDataStream stream2(reply.value());
stream2 >> authResult;
if (authResult.isModified()) {
info = authResult;
return true;
}
}
return false;
}
qlonglong KPasswdServer::queryAuthInfo(KIO::AuthInfo &info, const QString &errorMsg,
qlonglong windowId, qlonglong seqNr,
qlonglong usertime)
{
kDebug(7019) << "window-id=" << windowId;
// special handling for kioslaves which aren't QCoreApplications
if (!QCoreApplication::instance()) {
kWarning(7019) << "kioslave is not a QCoreApplication!";
return legacyQueryAuthInfo(info, errorMsg, windowId, seqNr, usertime);
}
// create the loop for waiting for a result before sending the request
KPasswdServerLoop loop;
QObject::connect(m_interface, SIGNAL(queryAuthInfoAsyncResult(qlonglong,qlonglong,KIO::AuthInfo)),
&loop, SLOT(slotQueryResult(qlonglong,qlonglong,KIO::AuthInfo)));
QDBusReply<qlonglong> reply = m_interface->queryAuthInfoAsync(info, errorMsg,
windowId, seqNr,
usertime);
if (!reply.isValid()) {
// backwards compatibility for old kpasswdserver
if (reply.error().type() == QDBusError::UnknownMethod) {
qlonglong res = legacyQueryAuthInfo(info, errorMsg, windowId, seqNr,
usertime);
if (res > 0) {
return res;
}
}
kWarning(7019) << "Can't communicate with kded_kpasswdserver (for queryAuthInfo)!";
kDebug(7019) << reply.error().name() << reply.error().message();
return -1;
}
if (!loop.waitForResult(reply.value())) {
kWarning(7019) << "kded_kpasswdserver died while waiting for reply!";
return -1;
}
info = loop.authInfo();
kDebug(7019) << "username=" << info.username << "password=[hidden]";
return loop.seqNr();
}
qlonglong KPasswdServer::legacyQueryAuthInfo(KIO::AuthInfo &info, const QString &errorMsg,
qlonglong windowId, qlonglong seqNr,
qlonglong usertime)
{
kWarning(7019) << "Querying old kded_kpasswdserver.";
QByteArray params;
QDataStream stream(&params, QIODevice::WriteOnly);
stream << info;
QDBusPendingReply<QByteArray, qlonglong> reply = m_interface->queryAuthInfo(params, errorMsg,
windowId, seqNr,
usertime);
reply.waitForFinished();
if (reply.isValid()) {
AuthInfo authResult;
QDataStream stream2(reply.argumentAt<0>());
stream2 >> authResult;
if (authResult.isModified()) {
info = authResult;
}
return reply.argumentAt<1>();
}
return -1;
}
void KPasswdServer::addAuthInfo(const KIO::AuthInfo &info, qlonglong windowId)
{
QDBusReply<void> reply = m_interface->addAuthInfo(info, windowId);
if (!reply.isValid() && reply.error().type() == QDBusError::UnknownMethod) {
legacyAddAuthInfo(info, windowId);
}
}
void KPasswdServer::legacyAddAuthInfo(const KIO::AuthInfo &info, qlonglong windowId)
{
kWarning(7019) << "Querying old kded_kpasswdserver.";
QByteArray params;
QDataStream stream(&params, QIODevice::WriteOnly);
stream << info;
m_interface->addAuthInfo(params, windowId);
}
void KPasswdServer::removeAuthInfo(const QString &host, const QString &protocol,
const QString &user)
{
m_interface->removeAuthInfo(host, protocol, user);
}
}

View file

@ -1,120 +0,0 @@
/*
* This file is part of the KDE libraries
* Copyright (c) 2009 Michael Leupold <lemma@confuego.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KPASSWDSERVER_P_H
#define KPASSWDSERVER_P_H
#include <qglobal.h>
#include <QString>
class OrgKdeKPasswdServerInterface;
namespace KIO
{
class AuthInfo;
/**
* Interface class for kpasswdserver.
* @internal
* @remarks This is currently only supposed to be used by KIO::SlaveBase
* but might be reused as public API in the future.
*/
class KPasswdServer
{
public:
KPasswdServer();
~KPasswdServer();
/**
* Check if kpasswdserver has cached authentication information regarding
* an AuthInfo object.
* @param info information to check cache for
* @param windowId used as parent for dialogs
* @param usertime FIXME: I'd like to know as well :)
* @return true if kpasswdserver provided cached information, false if not
* @remarks info will contain the results of the check. To see if
* information was retrieved, check info.isModified().
*/
bool checkAuthInfo(KIO::AuthInfo &info, qlonglong windowId,
qlonglong usertime);
/**
* Let kpasswdserver ask the user for authentication information.
* @param info information to query the user for
* @param errorMsg error message that will be displayed to the user
* @param seqNr sequence number to assign to this request
* @param windowId used as parent for dialogs
* @param usertime FIXME: I'd like to know as well :)
* @return kpasswdserver's sequence number or -1 on error
* @remarks info will contain the results of the check. To see if
* information was retrieved, check info.isModified().
*/
qlonglong queryAuthInfo(KIO::AuthInfo &info, const QString &errorMsg,
qlonglong windowId, qlonglong seqNr,
qlonglong usertime);
/**
* Manually add authentication information to kpasswdserver's cache.
* @param info information to add
* @param windowId used as parent window for dialogs
*/
void addAuthInfo(const KIO::AuthInfo &info, qlonglong windowId);
/**
* Manually remove authentication information from kpasswdserver's cache.
* @param host hostname of the information to remove
* @param protocol protocol to remove information for
* @param user username to remove information for
*/
void removeAuthInfo(const QString &host, const QString &protocol,
const QString &user);
private:
/**
* Legacy version of checkAuthInfo provided for compatibility with
* old kpasswdserver.
* @remarks automatically called by checkAuthInfo if needed
*/
bool legacyCheckAuthInfo(KIO::AuthInfo &info, qlonglong windowId,
qlonglong usertime);
/**
* Legacy version of queryAuthInfo provided for compatibility with
* old kpasswdserver.
* @remarks automatically called by queryAuthInfo if needed.
*/
qlonglong legacyQueryAuthInfo(KIO::AuthInfo &info, const QString &errorMsg,
qlonglong windowId, qlonglong seqNr,
qlonglong usertime);
/**
* Legacy version of addAuthInfo provided for compatibility with
* old kpasswdserver.
* @remarks automatically called by removeAuthInfo if needed
*/
void legacyAddAuthInfo(const KIO::AuthInfo &info, qlonglong windowId);
OrgKdeKPasswdServerInterface *m_interface;
};
}
#endif

View file

@ -1,77 +0,0 @@
/*
* This file is part of the KDE libraries
* Copyright (c) 2009 Michael Leupold <lemma@confuego.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "kpasswdserverloop_p.h"
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusServiceWatcher>
namespace KIO
{
KPasswdServerLoop::KPasswdServerLoop() : m_seqNr(-1)
{
QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.kded", QDBusConnection::sessionBus(),
QDBusServiceWatcher::WatchForUnregistration, this);
connect(watcher, SIGNAL(serviceUnregistered(QString)),
this, SLOT(kdedServiceUnregistered()));
}
KPasswdServerLoop::~KPasswdServerLoop()
{
}
bool KPasswdServerLoop::waitForResult(qlonglong requestId)
{
m_requestId = requestId;
m_seqNr = -1;
m_authInfo = AuthInfo();
return (exec() == 0);
}
qlonglong KPasswdServerLoop::seqNr() const
{
return m_seqNr;
}
const AuthInfo &KPasswdServerLoop::authInfo() const
{
return m_authInfo;
}
void KPasswdServerLoop::slotQueryResult(qlonglong requestId, qlonglong seqNr,
const KIO::AuthInfo &authInfo)
{
if (m_requestId == requestId) {
m_seqNr = seqNr;
m_authInfo = authInfo;
exit(0);
}
}
void KPasswdServerLoop::kdedServiceUnregistered()
{
exit(-1);
}
}
#include "moc_kpasswdserverloop_p.cpp"

View file

@ -1,59 +0,0 @@
/*
* This file is part of the KDE libraries
* Copyright (c) 2009 Michael Leupold <lemma@confuego.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) version 3, or any
* later version accepted by the membership of KDE e.V. (or its
* successor approved by the membership of KDE e.V.), which shall
* act as a proxy defined in Section 6 of version 3 of the license.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KPASSWDSERVERLOOP_P_H
#define KPASSWDSERVERLOOP_P_H
#include <kio/authinfo.h>
#include <QtCore/QEventLoop>
namespace KIO {
// Wait for the result of an asynchronous D-Bus request to KPasswdServer.
// Objects of this class are one-way ie. as soon as they have received
// a result you can't call waitForResult() again.
class KPasswdServerLoop : public QEventLoop
{
Q_OBJECT
public:
KPasswdServerLoop();
virtual ~KPasswdServerLoop();
bool waitForResult(qlonglong requestId);
qlonglong seqNr() const;
const AuthInfo &authInfo() const;
public Q_SLOTS:
void slotQueryResult(qlonglong requestId, qlonglong seqNr, const KIO::AuthInfo &authInfo);
private Q_SLOTS:
void kdedServiceUnregistered();
private:
qlonglong m_requestId;
qlonglong m_seqNr;
AuthInfo m_authInfo;
};
}
#endif

View file

@ -1,61 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.kde.KPasswdServer" >
<signal name="checkAuthInfoAsyncResult" >
<arg type="x" name="requestId" />
<arg type="x" name="seqNr" />
<arg type="(ysssssssssbbbba{s(siv)})" name="info" />
<annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="KIO::AuthInfo" />
</signal>
<signal name="queryAuthInfoAsyncResult" >
<arg type="x" name="requestId" />
<arg type="x" name="seqNr" />
<arg type="(ysssssssssbbbba{s(siv)})" name="info" />
<annotation name="org.qtproject.QtDBus.QtTypeName.In2" value="KIO::AuthInfo" />
</signal>
<method name="checkAuthInfo" >
<arg direction="out" type="ay" />
<arg direction="in" type="ay" name="data" />
<arg direction="in" type="x" name="windowId" />
<arg direction="in" type="x" name="usertime" />
</method>
<method name="queryAuthInfo" >
<arg direction="out" type="ay" />
<arg direction="in" type="ay" name="data" />
<arg direction="in" type="s" name="errorMsg" />
<arg direction="in" type="x" name="windowId" />
<arg direction="in" type="x" name="seqNr" />
<arg direction="in" type="x" name="usertime" />
</method>
<method name="checkAuthInfoAsync" >
<arg direction="out" type="x" />
<arg direction="in" type="(ysssssssssbbbba{s(siv)})" name="info" />
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="KIO::AuthInfo" />
<arg direction="in" type="x" name="windowId" />
<arg direction="in" type="x" name="usertime" />
</method>
<method name="queryAuthInfoAsync" >
<arg direction="out" type="x" />
<arg direction="in" type="(ysssssssssbbbba{s(siv)})" name="info" />
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="KIO::AuthInfo" />
<arg direction="in" type="s" name="errorMsg" />
<arg direction="in" type="x" name="windowId" />
<arg direction="in" type="x" name="seqNr" />
<arg direction="in" type="x" name="usertime" />
</method>
<method name="addAuthInfo" >
<arg direction="in" type="ay" name="data" />
<arg direction="in" type="x" name="windowId" />
</method>
<method name="addAuthInfo" >
<arg direction="in" type="(ysssssssssbbbba{s(siv)})" name="info" />
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="KIO::AuthInfo" />
<arg direction="in" type="x" name="windowId" />
</method>
<method name="removeAuthInfo" >
<arg direction="in" type="s" name="host" />
<arg direction="in" type="s" name="protocol" />
<arg direction="in" type="s" name="user" />
</method>
</interface>
</node>

View file

@ -34,6 +34,7 @@
#include <signal.h>
#include <time.h>
#include <QtCore/QBuffer>
#include <QtCore/QFile>
#include <QtCore/QList>
#include <QtCore/QDateTime>
@ -44,13 +45,15 @@
#include <kconfiggroup.h>
#include <kde_file.h>
#include <klocale.h>
#include <kpassworddialog.h>
#include <kwindowsystem.h>
#include "kremoteencoding.h"
#include "connection.h"
#include "ioslave_defaults.h"
#include "slaveinterface.h"
#include "kpasswdserver_p.h"
#include "kpasswdstore.h"
#ifndef NDEBUG
#ifdef HAVE_BACKTRACE
@ -58,6 +61,11 @@
#endif
#endif
#define AUTHINFO_EXTRAFIELD_DOMAIN QLatin1String("domain")
#define AUTHINFO_EXTRAFIELD_ANONYMOUS QLatin1String("anonymous")
#define AUTHINFO_EXTRAFIELD_SKIP_CACHING_ON_QUERY QLatin1String("skip-caching-on-query")
#define AUTHINFO_EXTRAFIELD_HIDE_USERNAME_INPUT QLatin1String("hide-username-line")
extern "C" {
static void sigsegv_handler(int sig);
static void sigpipe_handler(int sig);
@ -72,18 +80,41 @@ typedef QMap<QString,QByteArray> AuthKeysMap;
namespace KIO {
static QByteArray authInfoKey(const AuthInfo &authinfo)
{
return KPasswdStore::makeKey(authinfo.url.prettyUrl());
}
static QString authInfoToData(const AuthInfo &authinfo)
{
QByteArray authdata;
QDataStream authstream(&authdata, QIODevice::WriteOnly);
authstream << authinfo;
return QString::fromAscii(authdata);
}
static AuthInfo authInfoFromData(const QByteArray &authdata)
{
QBuffer authbuffer;
authbuffer.setData(authdata);
authbuffer.open(QBuffer::ReadOnly);
AuthInfo authinfo;
QDataStream authstream(&authbuffer);
authstream >> authinfo;
return authinfo;
}
class SlaveBasePrivate {
public:
SlaveBase* q;
SlaveBasePrivate(SlaveBase* owner): q(owner), m_passwdServer(0) {}
~SlaveBasePrivate() { delete m_passwdServer; }
SlaveBasePrivate(SlaveBase* owner): q(owner), m_passwdStore(nullptr) {}
~SlaveBasePrivate() { delete m_passwdStore; }
UDSEntryList pendingListEntries;
QTime m_timeSinceLastBatch;
Connection appConnection;
QString poolSocket;
bool isConnectedToApp;
static qlonglong s_seqNr;
QString slaveid;
bool resume:1;
@ -105,7 +136,7 @@ public:
enum { Idle, InsideMethod, FinishedCalled, ErrorCalled } m_state;
QByteArray timeoutData;
KPasswdServer* m_passwdServer;
KPasswdStore* m_passwdStore;
// Reconstructs configGroup from configData and mIncomingMetaData
void rebuildConfig()
@ -137,24 +168,23 @@ public:
}
}
KPasswdServer* passwdServer()
KPasswdStore* passwdStore()
{
if (!m_passwdServer) {
m_passwdServer = new KPasswdServer;
if (!m_passwdStore) {
m_passwdStore = new KPasswdStore();
}
return m_passwdServer;
return m_passwdStore;
}
};
}
static SlaveBase *globalSlave;
qlonglong SlaveBasePrivate::s_seqNr;
static SlaveBase *globalSlave = nullptr;
static volatile bool slaveWriteError = false;
static const char *s_protocol;
static const char *s_protocol = nullptr;
#ifdef Q_OS_UNIX
extern "C" {
@ -809,8 +839,8 @@ void SlaveBase::reparseConfiguration()
bool SlaveBase::openPasswordDialog( AuthInfo& info, const QString &errorMsg )
{
const long windowId = metaData(QLatin1String("window-id")).toLong();
const unsigned long userTimestamp = metaData(QLatin1String("user-timestamp")).toULong();
const qlonglong windowId = metaData(QLatin1String("window-id")).toLongLong();
QWidget *windowWidget = QWidget::find(windowId);
QString errorMessage;
if (metaData(QLatin1String("no-auth-prompt")).compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) {
errorMessage = QLatin1String("<NoAuthPrompt>");
@ -818,26 +848,87 @@ bool SlaveBase::openPasswordDialog( AuthInfo& info, const QString &errorMsg )
errorMessage = errorMsg;
}
AuthInfo dlgInfo (info);
AuthInfo dlgInfo(info);
// Make sure the modified flag is not set.
dlgInfo.setModified(false);
// Prevent queryAuthInfo from caching the user supplied password since
// we need the ioslaves to first authenticate against the server with
// it to ensure it is valid.
dlgInfo.setExtraField(QLatin1String("skip-caching-on-query"), true);
dlgInfo.setExtraField(AUTHINFO_EXTRAFIELD_SKIP_CACHING_ON_QUERY, true);
KPasswdServer* passwdServer = d->passwdServer();
KPasswdStore* passwdstore = d->passwdStore();
if (passwdServer) {
qlonglong seqNr = passwdServer->queryAuthInfo(dlgInfo, errorMessage, windowId,
SlaveBasePrivate::s_seqNr, userTimestamp);
if (seqNr > 0) {
SlaveBasePrivate::s_seqNr = seqNr;
if (dlgInfo.isModified()) {
info = dlgInfo;
return true;
if (passwdstore) {
// assemble dialog-flags
KPasswordDialog::KPasswordDialogFlags dialogFlags;
if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) {
dialogFlags |= KPasswordDialog::ShowDomainLine;
if (dlgInfo.getExtraFieldFlags(AUTHINFO_EXTRAFIELD_DOMAIN) & KIO::AuthInfo::ExtraFieldReadOnly) {
dialogFlags |= KPasswordDialog::DomainReadOnly;
}
}
if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid()) {
dialogFlags |= KPasswordDialog::ShowAnonymousLoginCheckBox;
}
if (!dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_HIDE_USERNAME_INPUT).toBool()) {
dialogFlags |= KPasswordDialog::ShowUsernameLine;
}
// If store is not enabled and the caller explicitly requested for it,
// do not show the keep password checkbox.
if (dlgInfo.keepPassword && !passwdstore->cacheOnly())
dialogFlags |= KPasswordDialog::ShowKeepPassword;
KPasswordDialog* dlg = new KPasswordDialog(windowWidget, dialogFlags);
QString username = dlgInfo.username;
QString password = dlgInfo.password;
dlg->setPrompt(dlgInfo.prompt);
dlg->setUsername(username);
if (dlgInfo.caption.isEmpty())
dlg->setWindowTitle(i18n("Authentication Dialog"));
else
dlg->setWindowTitle(dlgInfo.caption);
if (!dlgInfo.comment.isEmpty() )
dlg->addCommentLine(dlgInfo.commentLabel, dlgInfo.comment);
if (!password.isEmpty())
dlg->setPassword(password);
if (dlgInfo.readOnly)
dlg->setUsernameReadOnly(true);
if (!passwdstore->cacheOnly())
dlg->setKeepPassword(true);
if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid ())
dlg->setDomain(dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).toString());
if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid () && password.isEmpty() && username.isEmpty())
dlg->setAnonymousMode(dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).toBool());
KWindowSystem::setMainWindow(dlg, windowId);
if (dlg->exec()) {
dlgInfo.setModified(false);
dlgInfo.username = dlg->username();
dlgInfo.password = dlg->password();
dlgInfo.keepPassword = dlg->keepPassword();
if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid())
dlgInfo.setExtraField(AUTHINFO_EXTRAFIELD_DOMAIN, dlg->domain());
if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS).isValid())
dlgInfo.setExtraField(AUTHINFO_EXTRAFIELD_ANONYMOUS, dlg->anonymousMode());
info = dlgInfo;
return true;
}
}
return false;
@ -947,8 +1038,6 @@ void SlaveBase::dispatch( int command, const QByteArray &data )
switch( command ) {
case CMD_HOST: {
// Reset s_seqNr, see kpasswdserver/DESIGN
SlaveBasePrivate::s_seqNr = 0;
QString passwd;
QString host, user;
quint16 port;
@ -1168,10 +1257,18 @@ void SlaveBase::dispatch( int command, const QByteArray &data )
bool SlaveBase::checkCachedAuthentication( AuthInfo& info )
{
KPasswdServer* passwdServer = d->passwdServer();
return (passwdServer &&
passwdServer->checkAuthInfo(info, metaData(QLatin1String("window-id")).toLong(),
metaData(QLatin1String("user-timestamp")).toULong()));
KPasswdStore* passwdstore = d->passwdStore();
if (!passwdstore) {
return false;
}
const qlonglong windowId = metaData(QLatin1String("window-id")).toLongLong();
const QByteArray authkey = authInfoKey(info);
if (passwdstore->hasPasswd(authkey, windowId)) {
const QString passwd = passwdstore->getPasswd(authkey, windowId);
info = authInfoFromData(passwd.toAscii());
return true;
}
return false;
}
void SlaveBase::dispatchOpenCommand( int command, const QByteArray &data )
@ -1208,13 +1305,13 @@ void SlaveBase::dispatchOpenCommand( int command, const QByteArray &data )
bool SlaveBase::cacheAuthentication( const AuthInfo& info )
{
KPasswdServer* passwdServer = d->passwdServer();
KPasswdStore* passwdstore = d->passwdStore();
if (!passwdServer) {
if (!passwdstore) {
return false;
}
passwdServer->addAuthInfo(info, metaData(QLatin1String("window-id")).toLongLong());
passwdstore->storePasswd(authInfoKey(info), authInfoToData(info), metaData(QLatin1String("window-id")).toLongLong());
return true;
}

View file

@ -709,7 +709,7 @@ public:
* \endcode
*
* \note You should consider using checkCachedAuthentication() to
* see if the password is available in kpasswdserver before calling
* see if the password is available in KPasswdStore before calling
* this function.
*
* \note A call to this function can fail and return @p false,
@ -717,7 +717,7 @@ public:
*
* \note Starting with KDE 4.7, this function will no longer store the password
* information automatically. If you want to store the password information in
* a persistent storage like KWallet, then you MUST call @ref cacheAuthentication.
* a persistent storage like KPasswdStore, then you MUST call @ref cacheAuthentication.
*
* @see checkCachedAuthentication
* @param info See AuthInfo.
@ -731,12 +731,11 @@ public:
* given by @p info.
*
* Use this function to check if any cached password exists
* for the URL given by @p info. If @p AuthInfo::realmValue
* and/or @p AuthInfo::verifyPath flag is specified, then
* they will also be factored in determining the presence
* of a cached password. Note that @p Auth::url is a required
* parameter when attempting to check for cached authorization
* info. Here is a simple example:
* for the URL given by @p info. If @p AuthInfo::verifyPath
* flag is specified, then they will also be factored in
* determining the presence of a cached password. Note that
* @p Auth::url is a required parameter when attempting to
* check for cached authorization info. Here is a simple example:
*
* \code
* AuthInfo info;
@ -756,7 +755,7 @@ public:
bool checkCachedAuthentication( AuthInfo& info );
/**
* Caches @p info in a persistent storage like KWallet.
* Caches @p info in a persistent storage like KPasswdStore.
*
* Starting with KDE 4.7, calling openPasswordDialog will no longer store
* passwords automatically for you. This was done to avoid accidental storage

View file

@ -48,14 +48,20 @@ static const QCryptographicHash::Algorithm kpasswdstore_algorithm = QCryptograph
static const QCryptographicHash::Algorithm kpasswdstore_algorithm = QCryptographicHash::Sha1;
#endif
static QWidget* widgetForWindowID(const qlonglong windowid)
{
return QWidget::find(windowid);
}
class KPasswdStorePrivate
{
public:
KPasswdStorePrivate();
~KPasswdStorePrivate();
bool ensurePasswd(const bool showerror);
bool ensurePasswd(const qlonglong windowid, const bool showerror);
bool hasPasswd() const;
void clearPasswd();
QString decryptPasswd(const QString &passwd, bool *ok);
QString encryptPasswd(const QString &passwd, bool *ok);
@ -91,7 +97,7 @@ KPasswdStorePrivate::~KPasswdStorePrivate()
{
}
bool KPasswdStorePrivate::ensurePasswd(const bool showerror)
bool KPasswdStorePrivate::ensurePasswd(const qlonglong windowid, const bool showerror)
{
Q_ASSERT(!cacheonly);
@ -102,7 +108,7 @@ bool KPasswdStorePrivate::ensurePasswd(const bool showerror)
m_passwdtimer.restart();
if (m_passwd.isEmpty()) {
KPasswordDialog kpasswddialog;
KPasswordDialog kpasswddialog(widgetForWindowID(windowid));
kpasswddialog.setPrompt(i18n("Enter a password for <b>%1</b> password storage", storeid));
if (showerror) {
kpasswddialog.showErrorMessage(i18n("Incorrect password"));
@ -113,20 +119,19 @@ bool KPasswdStorePrivate::ensurePasswd(const bool showerror)
const QByteArray kpasswddialogpass = kpasswddialog.password().toUtf8();
if (kpasswddialogpass.isEmpty()) {
kWarning() << "Password is empty";
clearPasswd();
return false;
}
m_passwd = KPasswdStorePrivate::genBytes(kpasswddialogpass, kpasswdstore_keylen);
if (m_passwd.isEmpty()) {
kWarning() << "Password bytes is empty";
m_passwd.clear();
m_passwdiv.clear();
clearPasswd();
return false;
}
m_passwdiv = KPasswdStorePrivate::genBytes(m_passwd.toHex(), kpasswdstore_ivlen);
if (m_passwdiv.isEmpty()) {
kWarning() << "Password initialization vector is empty";
m_passwd.clear();
m_passwdiv.clear();
clearPasswd();
return false;
}
@ -141,13 +146,12 @@ bool KPasswdStorePrivate::ensurePasswd(const bool showerror)
return true;
}
if (KPasswdStorePrivate::passwdHash(m_passwd) != passwdhash) {
m_passwd.clear();
m_passwdiv.clear();
clearPasswd();
return false;
}
return true;
}
return !m_passwd.isEmpty();
return hasPasswd();
#else
// not used
return true;
@ -159,6 +163,12 @@ bool KPasswdStorePrivate::hasPasswd() const
return !m_passwd.isEmpty();
}
void KPasswdStorePrivate::clearPasswd()
{
m_passwd.clear();
m_passwdiv.clear();
}
QString KPasswdStorePrivate::decryptPasswd(const QString &passwd, bool *ok)
{
#if defined(HAVE_OPENSSL)
@ -310,6 +320,7 @@ KPasswdStore::~KPasswdStore()
void KPasswdStore::setStoreID(const QString &id)
{
d->storeid = id;
d->clearPasswd();
}
void KPasswdStore::setCacheOnly(const bool cacheonly)
@ -318,14 +329,24 @@ void KPasswdStore::setCacheOnly(const bool cacheonly)
d->cache.clear();
}
QString KPasswdStore::getPasswd(const QByteArray &key) const
bool KPasswdStore::cacheOnly() const
{
return d->cacheonly;
}
bool KPasswdStore::hasPasswd(const QByteArray &key, const qlonglong windowid)
{
return !getPasswd(key, windowid).isEmpty();
}
QString KPasswdStore::getPasswd(const QByteArray &key, const qlonglong windowid) const
{
if (d->cacheonly) {
return d->cache.value(key, QString());
}
int retry = kpasswdstore_passretries;
while (retry > 0 && !d->ensurePasswd(retry < kpasswdstore_passretries)) {
while (retry > 0 && !d->ensurePasswd(windowid, retry < kpasswdstore_passretries)) {
retry--;
}
if (!d->hasPasswd()) {
@ -341,7 +362,7 @@ QString KPasswdStore::getPasswd(const QByteArray &key) const
return d->decryptPasswd(passwd, &ok);
}
bool KPasswdStore::storePasswd(const QByteArray &key, const QString &passwd)
bool KPasswdStore::storePasswd(const QByteArray &key, const QString &passwd, const qlonglong windowid)
{
if (d->cacheonly) {
d->cache.insert(key, passwd);
@ -349,11 +370,11 @@ bool KPasswdStore::storePasswd(const QByteArray &key, const QString &passwd)
}
int retry = kpasswdstore_passretries;
while (retry > 0 && !d->ensurePasswd(retry < kpasswdstore_passretries)) {
while (retry > 0 && !d->ensurePasswd(windowid, retry < kpasswdstore_passretries)) {
retry--;
}
if (!d->hasPasswd()) {
KMessageBox::error(nullptr, i18n("The storage could not be open, no passwords will be permanently stored"));
KMessageBox::error(widgetForWindowID(windowid), i18n("The storage could not be open, no passwords will be permanently stored"));
setCacheOnly(true);
return storePasswd(key, passwd);
}

View file

@ -63,15 +63,24 @@ public:
@note Caching only is disabled by default
*/
void setCacheOnly(const bool cacheonly);
/*!
@brief Returns @p true if password are cached only, @p false otherwise
*/
bool cacheOnly() const;
/*!
@brief Returns @p true if there is password for the given @p key in the
password store, @p false otherwise
*/
bool hasPasswd(const QByteArray &key, const qlonglong windowid = 0);
/*!
@brief Retrieves password for the given @p key from the password store
*/
QString getPasswd(const QByteArray &key) const;
QString getPasswd(const QByteArray &key, const qlonglong windowid = 0) const;
/*!
@brief Stores @p passwd with the given @p key in the password store
*/
bool storePasswd(const QByteArray &key, const QString &passwd);
bool storePasswd(const QByteArray &key, const QString &passwd, const qlonglong windowid = 0);
/*!
@brief Makes a unique key from @p string for use with @p getPasswd() and @p storePasswd()

View file

@ -318,69 +318,6 @@ Notes:
<glob pattern="*.kcsrc"/>
</mime-type>
<mime-type type="application/x-kwallet"> <!-- fdo #6326 rejected, will stay KDE-specific -->
<comment>KWallet wallet</comment>
<comment xml:lang="ar">حافظة KWallet</comment>
<comment xml:lang="ast">Cartera de KWallet</comment>
<comment xml:lang="bg">Портфейл KWallet</comment>
<comment xml:lang="bs">Knovčanikov novčanik</comment>
<comment xml:lang="ca">cartera del KWallet</comment>
<comment xml:lang="ca@valencia">cartera del KWallet</comment>
<comment xml:lang="cs">Schránka KWallet</comment>
<comment xml:lang="da">Tegnebog til KWallet</comment>
<comment xml:lang="de">KWallet-Passwortspeicher</comment>
<comment xml:lang="el">Πορτοφόλι KWallet</comment>
<comment xml:lang="en_GB">KWallet wallet</comment>
<comment xml:lang="es">Cartera de KWallet</comment>
<comment xml:lang="et">KWalleti turvalaegas</comment>
<comment xml:lang="eu">KWallet zorroa</comment>
<comment xml:lang="fi">KWallet-lompakko</comment>
<comment xml:lang="fr">Portefeuille KWallet</comment>
<comment xml:lang="ga">Sparán KWallet</comment>
<comment xml:lang="gl">Carteira de KWallet</comment>
<comment xml:lang="hr">KWallet lisnica</comment>
<comment xml:lang="hu">KWallet-jelszófájl</comment>
<comment xml:lang="ia">Kwallet :portafolio</comment>
<comment xml:lang="is">KWallet veski</comment>
<comment xml:lang="it">Portafogli di KDE</comment>
<comment xml:lang="ja">KWallet ウォレット</comment>
<comment xml:lang="kk">KWallet әмияны</comment>
<comment xml:lang="km">កាបូប​របស់ KWallet</comment>
<comment xml:lang="ko">KWallet 지갑</comment>
<comment xml:lang="lt">KWallet piniginė</comment>
<comment xml:lang="lv">KWallet maks</comment>
<comment xml:lang="ml">കെവാലറ്റ് മടിശ്ശീല</comment>
<comment xml:lang="mr">के-वॉलेट पाकीट</comment>
<comment xml:lang="nb">KWallet lommebok</comment>
<comment xml:lang="nds">KWallet-Knipp</comment>
<comment xml:lang="nl">KWallet-portefeuille</comment>
<comment xml:lang="nn">KWallet-lommebok</comment>
<comment xml:lang="pa">KWallet ਵਾਲਿਟ</comment>
<comment xml:lang="pl">Portfel KDE</comment>
<comment xml:lang="pt">Carteira da KWallet</comment>
<comment xml:lang="pt_BR">Carteira do KWallet</comment>
<comment xml:lang="ro">Portofel KWallet</comment>
<comment xml:lang="ru">бумажник KWallet</comment>
<comment xml:lang="se">KWallet bursa</comment>
<comment xml:lang="sk">KWallet wallet</comment>
<comment xml:lang="sl">Listnica za KDE</comment>
<comment xml:lang="sr">К‑новчаников новчаник</comment>
<comment xml:lang="sr@ijekavian">К‑новчаников новчаник</comment>
<comment xml:lang="sr@ijekavianlatin">Knovčanikov novčanik</comment>
<comment xml:lang="sr@latin">Knovčanikov novčanik</comment>
<comment xml:lang="sv">Kwallet-plånbok</comment>
<comment xml:lang="th">กระเป๋าของ 'กระเป๋าคุมข้อมูล-K'</comment>
<comment xml:lang="tr">KWallet cüzdanı</comment>
<comment xml:lang="ug">KWallet ھەميانى</comment>
<comment xml:lang="uk">торбинка KWallet</comment>
<comment xml:lang="zh_CN">KWallet 钱包</comment>
<comment xml:lang="zh_TW">KWallet 錢包</comment>
<magic priority="80">
<match type="string" value="KWALLET" offset="0"/>
</magic>
<glob pattern="*.kwl"/>
</mime-type>
<mime-type type="application/x-plasma">
<sub-class-of type="application/zip"/>
<comment>plasmoid</comment>