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. functions like capitalize and reverse seem to be sparsely used.
(Caleb) (Caleb)
- Prevent re-entering event loop in kded to avoid reentrancy problems like with kwallet in KDE3 (Lubos).
- Customizable KToolTip/KWhatsThis widgets (Jaroslaw Staniek), - Customizable KToolTip/KWhatsThis widgets (Jaroslaw Staniek),
now KWhatsThis is a part of KDE GSoC "Implement OpenUsability's Context Sensitive now KWhatsThis is a part of KDE GSoC "Implement OpenUsability's Context Sensitive
Help Redesign" project, by Joshua Keel, mentored by Ellen Reitmayr 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( install(
FILES FILES
Solid/AcAdapter Solid/AcAdapter

View file

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

View file

@ -28,7 +28,6 @@
265 kdeui (KIconEffect) 265 kdeui (KIconEffect)
281 kdeui (KCModule) 281 kdeui (KCModule)
283 kdeui (K*Gesture*) 283 kdeui (K*Gesture*)
285 kdeui (Wallet)
291 kdeui (KAboutDialog) 291 kdeui (KAboutDialog)
292 kdeui (KComboBox) 292 kdeui (KComboBox)
293 kdeui (KLineEdit) 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: Here are examples of KDED modules:
kdelibs/kioslave/http/kcookiejar/kcookieserver.cpp Cookie-handling module (including GUI) 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/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 A KDED module should install a .desktop file with
ServicesTypes=KDEDModule ServicesTypes=KDEDModule

View file

@ -57,8 +57,6 @@ public:
//bool isWindowRegistered(qlonglong windowId) const; //bool isWindowRegistered(qlonglong windowId) const;
/** /**
* Applications can register/unregister their windows with kded modules. * 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/kpassivepopup.cpp
util/kpassivepopupmessagehandler.cpp util/kpassivepopupmessagehandler.cpp
util/kstandardguiitem.cpp util/kstandardguiitem.cpp
util/kwallet.cpp
util/kwordwrap.cpp util/kwordwrap.cpp
util/kxerrorhandler.cpp util/kxerrorhandler.cpp
util/kxmessages.cpp util/kxmessages.cpp
@ -321,13 +320,6 @@ else()
) )
endif() 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_interfaces(kdeui_LIB_SRCS jobs/org.kde.JobViewServer.xml )
qt4_add_dbus_interface(kdeui_LIB_SRCS qt4_add_dbus_interface(kdeui_LIB_SRCS
@ -543,7 +535,6 @@ install(
util/kpassivepopup.h util/kpassivepopup.h
util/kpassivepopupmessagehandler.h util/kpassivepopupmessagehandler.h
util/kstandardguiitem.h util/kstandardguiitem.h
util/kwallet.h
util/kwordwrap.h util/kwordwrap.h
util/kxerrorhandler.h util/kxerrorhandler.h
util/kxmessages.h util/kxmessages.h

View file

@ -128,7 +128,6 @@ KDEUI_EXECUTABLE_TESTS(
ktitlewidgettest ktitlewidgettest
ktoolbartest ktoolbartest
ktoolbarlabelactiontest ktoolbarlabelactiontest
kwallettest
kwidgetitemdelegatetest kwidgetitemdelegatetest
kwindowtest kwindowtest
kxmlguitest 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/thumbsequencecreator.cpp
kio/udsentry.cpp kio/udsentry.cpp
kio/hostinfo.cpp kio/hostinfo.cpp
kio/kpasswdserver.cpp
kio/kpasswdserverloop.cpp
kio/usernotificationhandler.cpp kio/usernotificationhandler.cpp
kio/clipboardupdater.cpp kio/clipboardupdater.cpp
kio/kautomount.cpp kio/kautomount.cpp
@ -111,14 +109,6 @@ qt4_add_dbus_interface(kiocore_STAT_SRCS
kuiserver_interface 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 set(kbookmarks_STAT_SRCS
bookmarks/kbookmark.cc bookmarks/kbookmark.cc
bookmarks/kbookmarkimporter.cc bookmarks/kbookmarkimporter.cc
@ -176,6 +166,7 @@ target_link_libraries(kio PRIVATE
target_link_libraries(kio PUBLIC target_link_libraries(kio PUBLIC
${KDE4_KDECORE_LIBS} ${KDE4_KDECORE_LIBS}
${KDE4_KDEUI_LIBS} ${KDE4_KDEUI_LIBS}
${KDE4_KPASSWDSTORE_LIBS}
${QT_QTNETWORK_LIBRARY} ${QT_QTNETWORK_LIBRARY}
${QT_QTXML_LIBRARY} ${QT_QTXML_LIBRARY}
${QT_QTGUI_LIBRARY} ${QT_QTGUI_LIBRARY}
@ -311,7 +302,6 @@ install(
FILES FILES
kio/org.kde.KDirNotify.xml kio/org.kde.KDirNotify.xml
kio/org.kde.kio.FileUndoManager.xml kio/org.kde.kio.FileUndoManager.xml
kio/org.kde.KPasswdServer.xml
DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR} DESTINATION ${KDE4_DBUS_INTERFACES_INSTALL_DIR}
) )

View file

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

View file

@ -171,30 +171,6 @@ public:
*/ */
QString commentLabel; 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 * Flag that, if set, indicates whether a path match should be
* performed when requesting for cached authorization. * performed when requesting for cached authorization.
@ -271,8 +247,7 @@ public:
/** /**
* Register the meta-types for AuthInfo. This is called from * Register the meta-types for AuthInfo. This is called from
* AuthInfo's constructor but needed by daemons on the DBus such * AuthInfo's constructor.
* as kpasswdserver.
* @since 4.3 * @since 4.3
*/ */
static void registerMetaTypes(); 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 <signal.h>
#include <time.h> #include <time.h>
#include <QtCore/QBuffer>
#include <QtCore/QFile> #include <QtCore/QFile>
#include <QtCore/QList> #include <QtCore/QList>
#include <QtCore/QDateTime> #include <QtCore/QDateTime>
@ -44,13 +45,15 @@
#include <kconfiggroup.h> #include <kconfiggroup.h>
#include <kde_file.h> #include <kde_file.h>
#include <klocale.h> #include <klocale.h>
#include <kpassworddialog.h>
#include <kwindowsystem.h>
#include "kremoteencoding.h" #include "kremoteencoding.h"
#include "connection.h" #include "connection.h"
#include "ioslave_defaults.h" #include "ioslave_defaults.h"
#include "slaveinterface.h" #include "slaveinterface.h"
#include "kpasswdserver_p.h" #include "kpasswdstore.h"
#ifndef NDEBUG #ifndef NDEBUG
#ifdef HAVE_BACKTRACE #ifdef HAVE_BACKTRACE
@ -58,6 +61,11 @@
#endif #endif
#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" { extern "C" {
static void sigsegv_handler(int sig); static void sigsegv_handler(int sig);
static void sigpipe_handler(int sig); static void sigpipe_handler(int sig);
@ -72,18 +80,41 @@ typedef QMap<QString,QByteArray> AuthKeysMap;
namespace KIO { 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 { class SlaveBasePrivate {
public: public:
SlaveBase* q; SlaveBase* q;
SlaveBasePrivate(SlaveBase* owner): q(owner), m_passwdServer(0) {} SlaveBasePrivate(SlaveBase* owner): q(owner), m_passwdStore(nullptr) {}
~SlaveBasePrivate() { delete m_passwdServer; } ~SlaveBasePrivate() { delete m_passwdStore; }
UDSEntryList pendingListEntries; UDSEntryList pendingListEntries;
QTime m_timeSinceLastBatch; QTime m_timeSinceLastBatch;
Connection appConnection; Connection appConnection;
QString poolSocket; QString poolSocket;
bool isConnectedToApp; bool isConnectedToApp;
static qlonglong s_seqNr;
QString slaveid; QString slaveid;
bool resume:1; bool resume:1;
@ -105,7 +136,7 @@ public:
enum { Idle, InsideMethod, FinishedCalled, ErrorCalled } m_state; enum { Idle, InsideMethod, FinishedCalled, ErrorCalled } m_state;
QByteArray timeoutData; QByteArray timeoutData;
KPasswdServer* m_passwdServer; KPasswdStore* m_passwdStore;
// Reconstructs configGroup from configData and mIncomingMetaData // Reconstructs configGroup from configData and mIncomingMetaData
void rebuildConfig() void rebuildConfig()
@ -137,24 +168,23 @@ public:
} }
} }
KPasswdServer* passwdServer() KPasswdStore* passwdStore()
{ {
if (!m_passwdServer) { if (!m_passwdStore) {
m_passwdServer = new KPasswdServer; m_passwdStore = new KPasswdStore();
} }
return m_passwdServer; return m_passwdStore;
} }
}; };
} }
static SlaveBase *globalSlave; static SlaveBase *globalSlave = nullptr;
qlonglong SlaveBasePrivate::s_seqNr;
static volatile bool slaveWriteError = false; static volatile bool slaveWriteError = false;
static const char *s_protocol; static const char *s_protocol = nullptr;
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
extern "C" { extern "C" {
@ -809,8 +839,8 @@ void SlaveBase::reparseConfiguration()
bool SlaveBase::openPasswordDialog( AuthInfo& info, const QString &errorMsg ) bool SlaveBase::openPasswordDialog( AuthInfo& info, const QString &errorMsg )
{ {
const long windowId = metaData(QLatin1String("window-id")).toLong(); const qlonglong windowId = metaData(QLatin1String("window-id")).toLongLong();
const unsigned long userTimestamp = metaData(QLatin1String("user-timestamp")).toULong(); QWidget *windowWidget = QWidget::find(windowId);
QString errorMessage; QString errorMessage;
if (metaData(QLatin1String("no-auth-prompt")).compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) { if (metaData(QLatin1String("no-auth-prompt")).compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) {
errorMessage = QLatin1String("<NoAuthPrompt>"); errorMessage = QLatin1String("<NoAuthPrompt>");
@ -818,26 +848,87 @@ bool SlaveBase::openPasswordDialog( AuthInfo& info, const QString &errorMsg )
errorMessage = errorMsg; errorMessage = errorMsg;
} }
AuthInfo dlgInfo (info); AuthInfo dlgInfo(info);
// Make sure the modified flag is not set. // Make sure the modified flag is not set.
dlgInfo.setModified(false); dlgInfo.setModified(false);
// Prevent queryAuthInfo from caching the user supplied password since // Prevent queryAuthInfo from caching the user supplied password since
// we need the ioslaves to first authenticate against the server with // we need the ioslaves to first authenticate against the server with
// it to ensure it is valid. // 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) { if (passwdstore) {
qlonglong seqNr = passwdServer->queryAuthInfo(dlgInfo, errorMessage, windowId, // assemble dialog-flags
SlaveBasePrivate::s_seqNr, userTimestamp); KPasswordDialog::KPasswordDialogFlags dialogFlags;
if (seqNr > 0) {
SlaveBasePrivate::s_seqNr = seqNr; if (dlgInfo.getExtraField(AUTHINFO_EXTRAFIELD_DOMAIN).isValid()) {
if (dlgInfo.isModified()) { dialogFlags |= KPasswordDialog::ShowDomainLine;
info = dlgInfo; if (dlgInfo.getExtraFieldFlags(AUTHINFO_EXTRAFIELD_DOMAIN) & KIO::AuthInfo::ExtraFieldReadOnly) {
return true; 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; return false;
@ -947,8 +1038,6 @@ void SlaveBase::dispatch( int command, const QByteArray &data )
switch( command ) { switch( command ) {
case CMD_HOST: { case CMD_HOST: {
// Reset s_seqNr, see kpasswdserver/DESIGN
SlaveBasePrivate::s_seqNr = 0;
QString passwd; QString passwd;
QString host, user; QString host, user;
quint16 port; quint16 port;
@ -1168,10 +1257,18 @@ void SlaveBase::dispatch( int command, const QByteArray &data )
bool SlaveBase::checkCachedAuthentication( AuthInfo& info ) bool SlaveBase::checkCachedAuthentication( AuthInfo& info )
{ {
KPasswdServer* passwdServer = d->passwdServer(); KPasswdStore* passwdstore = d->passwdStore();
return (passwdServer && if (!passwdstore) {
passwdServer->checkAuthInfo(info, metaData(QLatin1String("window-id")).toLong(), return false;
metaData(QLatin1String("user-timestamp")).toULong())); }
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 ) 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 ) bool SlaveBase::cacheAuthentication( const AuthInfo& info )
{ {
KPasswdServer* passwdServer = d->passwdServer(); KPasswdStore* passwdstore = d->passwdStore();
if (!passwdServer) { if (!passwdstore) {
return false; return false;
} }
passwdServer->addAuthInfo(info, metaData(QLatin1String("window-id")).toLongLong()); passwdstore->storePasswd(authInfoKey(info), authInfoToData(info), metaData(QLatin1String("window-id")).toLongLong());
return true; return true;
} }

View file

@ -709,7 +709,7 @@ public:
* \endcode * \endcode
* *
* \note You should consider using checkCachedAuthentication() to * \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. * this function.
* *
* \note A call to this function can fail and return @p false, * \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 * \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 * 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 * @see checkCachedAuthentication
* @param info See AuthInfo. * @param info See AuthInfo.
@ -731,12 +731,11 @@ public:
* given by @p info. * given by @p info.
* *
* Use this function to check if any cached password exists * Use this function to check if any cached password exists
* for the URL given by @p info. If @p AuthInfo::realmValue * for the URL given by @p info. If @p AuthInfo::verifyPath
* and/or @p AuthInfo::verifyPath flag is specified, then * flag is specified, then they will also be factored in
* they will also be factored in determining the presence * determining the presence of a cached password. Note that
* of a cached password. Note that @p Auth::url is a required * @p Auth::url is a required parameter when attempting to
* parameter when attempting to check for cached authorization * check for cached authorization info. Here is a simple example:
* info. Here is a simple example:
* *
* \code * \code
* AuthInfo info; * AuthInfo info;
@ -756,7 +755,7 @@ public:
bool checkCachedAuthentication( AuthInfo& info ); 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 * Starting with KDE 4.7, calling openPasswordDialog will no longer store
* passwords automatically for you. This was done to avoid accidental storage * 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; static const QCryptographicHash::Algorithm kpasswdstore_algorithm = QCryptographicHash::Sha1;
#endif #endif
static QWidget* widgetForWindowID(const qlonglong windowid)
{
return QWidget::find(windowid);
}
class KPasswdStorePrivate class KPasswdStorePrivate
{ {
public: public:
KPasswdStorePrivate(); KPasswdStorePrivate();
~KPasswdStorePrivate(); ~KPasswdStorePrivate();
bool ensurePasswd(const bool showerror); bool ensurePasswd(const qlonglong windowid, const bool showerror);
bool hasPasswd() const; bool hasPasswd() const;
void clearPasswd();
QString decryptPasswd(const QString &passwd, bool *ok); QString decryptPasswd(const QString &passwd, bool *ok);
QString encryptPasswd(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); Q_ASSERT(!cacheonly);
@ -102,7 +108,7 @@ bool KPasswdStorePrivate::ensurePasswd(const bool showerror)
m_passwdtimer.restart(); m_passwdtimer.restart();
if (m_passwd.isEmpty()) { if (m_passwd.isEmpty()) {
KPasswordDialog kpasswddialog; KPasswordDialog kpasswddialog(widgetForWindowID(windowid));
kpasswddialog.setPrompt(i18n("Enter a password for <b>%1</b> password storage", storeid)); kpasswddialog.setPrompt(i18n("Enter a password for <b>%1</b> password storage", storeid));
if (showerror) { if (showerror) {
kpasswddialog.showErrorMessage(i18n("Incorrect password")); kpasswddialog.showErrorMessage(i18n("Incorrect password"));
@ -113,20 +119,19 @@ bool KPasswdStorePrivate::ensurePasswd(const bool showerror)
const QByteArray kpasswddialogpass = kpasswddialog.password().toUtf8(); const QByteArray kpasswddialogpass = kpasswddialog.password().toUtf8();
if (kpasswddialogpass.isEmpty()) { if (kpasswddialogpass.isEmpty()) {
kWarning() << "Password is empty"; kWarning() << "Password is empty";
clearPasswd();
return false; return false;
} }
m_passwd = KPasswdStorePrivate::genBytes(kpasswddialogpass, kpasswdstore_keylen); m_passwd = KPasswdStorePrivate::genBytes(kpasswddialogpass, kpasswdstore_keylen);
if (m_passwd.isEmpty()) { if (m_passwd.isEmpty()) {
kWarning() << "Password bytes is empty"; kWarning() << "Password bytes is empty";
m_passwd.clear(); clearPasswd();
m_passwdiv.clear();
return false; return false;
} }
m_passwdiv = KPasswdStorePrivate::genBytes(m_passwd.toHex(), kpasswdstore_ivlen); m_passwdiv = KPasswdStorePrivate::genBytes(m_passwd.toHex(), kpasswdstore_ivlen);
if (m_passwdiv.isEmpty()) { if (m_passwdiv.isEmpty()) {
kWarning() << "Password initialization vector is empty"; kWarning() << "Password initialization vector is empty";
m_passwd.clear(); clearPasswd();
m_passwdiv.clear();
return false; return false;
} }
@ -141,13 +146,12 @@ bool KPasswdStorePrivate::ensurePasswd(const bool showerror)
return true; return true;
} }
if (KPasswdStorePrivate::passwdHash(m_passwd) != passwdhash) { if (KPasswdStorePrivate::passwdHash(m_passwd) != passwdhash) {
m_passwd.clear(); clearPasswd();
m_passwdiv.clear();
return false; return false;
} }
return true; return true;
} }
return !m_passwd.isEmpty(); return hasPasswd();
#else #else
// not used // not used
return true; return true;
@ -159,6 +163,12 @@ bool KPasswdStorePrivate::hasPasswd() const
return !m_passwd.isEmpty(); return !m_passwd.isEmpty();
} }
void KPasswdStorePrivate::clearPasswd()
{
m_passwd.clear();
m_passwdiv.clear();
}
QString KPasswdStorePrivate::decryptPasswd(const QString &passwd, bool *ok) QString KPasswdStorePrivate::decryptPasswd(const QString &passwd, bool *ok)
{ {
#if defined(HAVE_OPENSSL) #if defined(HAVE_OPENSSL)
@ -310,6 +320,7 @@ KPasswdStore::~KPasswdStore()
void KPasswdStore::setStoreID(const QString &id) void KPasswdStore::setStoreID(const QString &id)
{ {
d->storeid = id; d->storeid = id;
d->clearPasswd();
} }
void KPasswdStore::setCacheOnly(const bool cacheonly) void KPasswdStore::setCacheOnly(const bool cacheonly)
@ -318,14 +329,24 @@ void KPasswdStore::setCacheOnly(const bool cacheonly)
d->cache.clear(); 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) { if (d->cacheonly) {
return d->cache.value(key, QString()); return d->cache.value(key, QString());
} }
int retry = kpasswdstore_passretries; int retry = kpasswdstore_passretries;
while (retry > 0 && !d->ensurePasswd(retry < kpasswdstore_passretries)) { while (retry > 0 && !d->ensurePasswd(windowid, retry < kpasswdstore_passretries)) {
retry--; retry--;
} }
if (!d->hasPasswd()) { if (!d->hasPasswd()) {
@ -341,7 +362,7 @@ QString KPasswdStore::getPasswd(const QByteArray &key) const
return d->decryptPasswd(passwd, &ok); 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) { if (d->cacheonly) {
d->cache.insert(key, passwd); d->cache.insert(key, passwd);
@ -349,11 +370,11 @@ bool KPasswdStore::storePasswd(const QByteArray &key, const QString &passwd)
} }
int retry = kpasswdstore_passretries; int retry = kpasswdstore_passretries;
while (retry > 0 && !d->ensurePasswd(retry < kpasswdstore_passretries)) { while (retry > 0 && !d->ensurePasswd(windowid, retry < kpasswdstore_passretries)) {
retry--; retry--;
} }
if (!d->hasPasswd()) { 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); setCacheOnly(true);
return storePasswd(key, passwd); return storePasswd(key, passwd);
} }

View file

@ -63,15 +63,24 @@ public:
@note Caching only is disabled by default @note Caching only is disabled by default
*/ */
void setCacheOnly(const bool cacheonly); 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 @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 @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() @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"/> <glob pattern="*.kcsrc"/>
</mime-type> </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"> <mime-type type="application/x-plasma">
<sub-class-of type="application/zip"/> <sub-class-of type="application/zip"/>
<comment>plasmoid</comment> <comment>plasmoid</comment>