2005-03-28 07:11:58 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com>
|
|
|
|
* Copyright (C) 2004,2005 Brad Hards <bradh@frogmouth.net>
|
|
|
|
*
|
|
|
|
* 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) 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
|
|
|
|
* 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, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "qca_keystore.h"
|
|
|
|
|
2005-04-09 07:43:15 +00:00
|
|
|
#include "qcaprovider.h"
|
|
|
|
|
2005-03-28 07:11:58 +00:00
|
|
|
namespace QCA {
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
Provider::Context *getContext(const QString &type, Provider *p);
|
|
|
|
|
|
|
|
static QMutex *keyStoreMutex = 0;
|
|
|
|
static int tracker_register(KeyStore *ks, const QString &str); // returns trackerId
|
|
|
|
static void tracker_unregister(KeyStore *ks, int trackerId);
|
|
|
|
static KeyStoreListContext *tracker_get_owner(int trackerId);
|
|
|
|
static int tracker_get_storeContextId(int trackerId);
|
|
|
|
static QString tracker_get_storeId(int trackerId);
|
|
|
|
|
2005-03-28 07:11:58 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// KeyStoreEntry
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
KeyStoreEntry::KeyStoreEntry()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyStoreEntry::KeyStoreEntry(const KeyStoreEntry &from)
|
|
|
|
:Algorithm(from)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyStoreEntry::~KeyStoreEntry()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyStoreEntry & KeyStoreEntry::operator=(const KeyStoreEntry &from)
|
|
|
|
{
|
|
|
|
Algorithm::operator=(from);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KeyStoreEntry::isNull() const
|
|
|
|
{
|
2005-04-09 07:43:15 +00:00
|
|
|
return (!context() ? true : false);
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
KeyStoreEntry::Type KeyStoreEntry::type() const
|
|
|
|
{
|
2005-04-09 07:43:15 +00:00
|
|
|
return static_cast<const KeyStoreEntryContext *>(context())->type();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString KeyStoreEntry::name() const
|
|
|
|
{
|
2005-04-09 07:43:15 +00:00
|
|
|
return static_cast<const KeyStoreEntryContext *>(context())->name();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString KeyStoreEntry::id() const
|
|
|
|
{
|
2005-04-09 07:43:15 +00:00
|
|
|
return static_cast<const KeyStoreEntryContext *>(context())->id();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
KeyBundle KeyStoreEntry::keyBundle() const
|
|
|
|
{
|
2005-07-06 22:27:02 +00:00
|
|
|
return static_cast<const KeyStoreEntryContext *>(context())->keyBundle();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Certificate KeyStoreEntry::certificate() const
|
|
|
|
{
|
2005-04-09 07:43:15 +00:00
|
|
|
return static_cast<const KeyStoreEntryContext *>(context())->certificate();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CRL KeyStoreEntry::crl() const
|
|
|
|
{
|
2005-04-09 07:43:15 +00:00
|
|
|
return static_cast<const KeyStoreEntryContext *>(context())->crl();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PGPKey KeyStoreEntry::pgpSecretKey() const
|
|
|
|
{
|
2005-07-06 22:27:02 +00:00
|
|
|
return static_cast<const KeyStoreEntryContext *>(context())->pgpSecretKey();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PGPKey KeyStoreEntry::pgpPublicKey() const
|
|
|
|
{
|
2005-07-06 22:27:02 +00:00
|
|
|
return static_cast<const KeyStoreEntryContext *>(context())->pgpPublicKey();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// KeyStore
|
|
|
|
//----------------------------------------------------------------------------
|
2005-07-28 12:17:09 +00:00
|
|
|
class KeyStore::Private
|
2005-03-28 07:11:58 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
public:
|
|
|
|
Private() : trackerId(-1), ksl(0), contextId(-1)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void invalidate()
|
|
|
|
{
|
|
|
|
trackerId = -1;
|
|
|
|
ksl = 0;
|
|
|
|
contextId = -1;
|
|
|
|
id = QString();
|
|
|
|
}
|
|
|
|
|
|
|
|
int trackerId;
|
|
|
|
KeyStoreListContext *ksl;
|
|
|
|
int contextId; // store context id
|
|
|
|
QString id; // public store id
|
|
|
|
};
|
|
|
|
|
|
|
|
KeyStore::KeyStore(const QString &id, QObject *parent)
|
|
|
|
:QObject(parent)
|
|
|
|
{
|
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
d = new Private;
|
|
|
|
d->trackerId = tracker_register(this, id);
|
|
|
|
if(d->trackerId != -1)
|
|
|
|
{
|
|
|
|
d->ksl = tracker_get_owner(d->trackerId);
|
|
|
|
d->contextId = tracker_get_storeContextId(d->trackerId);
|
|
|
|
d->id = tracker_get_storeId(d->trackerId);
|
|
|
|
}
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
KeyStore::~KeyStore()
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId != -1)
|
|
|
|
tracker_unregister(this, d->trackerId);
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KeyStore::isValid() const
|
|
|
|
{
|
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
return (d->trackerId != -1);
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
KeyStore::Type KeyStore::type() const
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return KeyStore::System;
|
|
|
|
return d->ksl->type(d->contextId);
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString KeyStore::name() const
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
// FIXME: QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return QString();
|
|
|
|
return d->ksl->name(d->contextId);
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString KeyStore::id() const
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return QString();
|
|
|
|
return d->id;
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool KeyStore::isReadOnly() const
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return false;
|
|
|
|
return d->ksl->isReadOnly(d->contextId);
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QList<KeyStoreEntry> KeyStore::entryList() const
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
2005-04-09 07:43:15 +00:00
|
|
|
QList<KeyStoreEntry> out;
|
2005-07-28 12:17:09 +00:00
|
|
|
if(d->trackerId == -1)
|
|
|
|
return out;
|
|
|
|
QList<KeyStoreEntryContext*> list = d->ksl->entryList(d->contextId);
|
2005-04-09 07:43:15 +00:00
|
|
|
for(int n = 0; n < list.count(); ++n)
|
|
|
|
{
|
|
|
|
KeyStoreEntry entry;
|
|
|
|
entry.change(list[n]);
|
|
|
|
out.append(entry);
|
|
|
|
}
|
2005-04-21 02:49:25 +00:00
|
|
|
//printf("KeyStore::entryList(): %d entries\n", out.count());
|
2005-04-09 07:43:15 +00:00
|
|
|
return out;
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
2005-04-09 07:43:15 +00:00
|
|
|
bool KeyStore::holdsTrustedCertificates() const
|
2005-03-28 07:11:58 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return false;
|
|
|
|
QList<KeyStoreEntry::Type> list = d->ksl->entryTypes(d->contextId);
|
2005-04-09 07:43:15 +00:00
|
|
|
if(list.contains(KeyStoreEntry::TypeCertificate) || list.contains(KeyStoreEntry::TypeCRL))
|
|
|
|
return true;
|
2005-03-28 07:11:58 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-04-09 07:43:15 +00:00
|
|
|
bool KeyStore::holdsIdentities() const
|
2005-03-28 07:11:58 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return false;
|
|
|
|
QList<KeyStoreEntry::Type> list = d->ksl->entryTypes(d->contextId);
|
2005-04-09 07:43:15 +00:00
|
|
|
if(list.contains(KeyStoreEntry::TypeKeyBundle) || list.contains(KeyStoreEntry::TypePGPSecretKey))
|
|
|
|
return true;
|
2005-03-28 07:11:58 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2005-04-09 07:43:15 +00:00
|
|
|
bool KeyStore::holdsPGPPublicKeys() const
|
2005-03-28 07:11:58 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return false;
|
|
|
|
QList<KeyStoreEntry::Type> list = d->ksl->entryTypes(d->contextId);
|
2005-04-09 07:43:15 +00:00
|
|
|
if(list.contains(KeyStoreEntry::TypePGPPublicKey))
|
|
|
|
return true;
|
2005-03-28 07:11:58 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KeyStore::writeEntry(const KeyBundle &kb)
|
|
|
|
{
|
2005-07-06 22:27:02 +00:00
|
|
|
// TODO
|
2005-03-28 07:11:58 +00:00
|
|
|
Q_UNUSED(kb);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KeyStore::writeEntry(const Certificate &cert)
|
|
|
|
{
|
2005-07-06 22:27:02 +00:00
|
|
|
// TODO
|
2005-03-28 07:11:58 +00:00
|
|
|
Q_UNUSED(cert);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KeyStore::writeEntry(const CRL &crl)
|
|
|
|
{
|
2005-07-06 22:27:02 +00:00
|
|
|
// TODO
|
2005-03-28 07:11:58 +00:00
|
|
|
Q_UNUSED(crl);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
PGPKey KeyStore::writeEntry(const PGPKey &key)
|
|
|
|
{
|
2005-07-06 22:27:02 +00:00
|
|
|
// TODO
|
2005-03-28 07:11:58 +00:00
|
|
|
Q_UNUSED(key);
|
|
|
|
return PGPKey();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KeyStore::removeEntry(const QString &id)
|
|
|
|
{
|
2005-07-06 22:27:02 +00:00
|
|
|
// TODO
|
2005-03-28 07:11:58 +00:00
|
|
|
Q_UNUSED(id);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2006-04-06 21:44:41 +00:00
|
|
|
/*void KeyStore::submitPassphrase(int requestId, const QSecureArray &passphrase)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
// FIXME: QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return;
|
2005-07-31 05:12:42 +00:00
|
|
|
d->ksl->submitPassphrase(d->contextId, requestId, passphrase);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KeyStore::rejectPassphraseRequest(int requestId)
|
|
|
|
{
|
|
|
|
// FIXME: QMutexLocker locker(keyStoreMutex);
|
|
|
|
if(d->trackerId == -1)
|
|
|
|
return;
|
|
|
|
d->ksl->rejectPassphraseRequest(d->contextId, requestId);
|
2006-04-06 21:44:41 +00:00
|
|
|
}*/
|
2005-07-28 12:17:09 +00:00
|
|
|
|
|
|
|
void KeyStore::invalidate()
|
|
|
|
{
|
|
|
|
d->invalidate();
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-03-28 07:11:58 +00:00
|
|
|
//----------------------------------------------------------------------------
|
2005-07-28 12:17:09 +00:00
|
|
|
// KeyStoreTracker
|
2005-03-28 07:11:58 +00:00
|
|
|
//----------------------------------------------------------------------------
|
2005-04-09 07:43:15 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
How this stuff works:
|
|
|
|
|
|
|
|
KeyStoreListContext is queried for a list of KeyStoreContexts. A signal
|
|
|
|
is used to indicate when the list may have changed, so polling for changes
|
|
|
|
is not necessary. Every context object created internally by the provider
|
|
|
|
will have a unique contextId, and this is used for detecting changes. Even
|
|
|
|
if a user removes and inserts the same smart card device, which has the
|
|
|
|
same deviceId, the contextId will ALWAYS be different. If a previously
|
|
|
|
known contextId is missing from a later queried list, then it means the
|
|
|
|
associated KeyStoreContext has been deleted by the provider (the manager
|
|
|
|
here does not delete them, it just throws away any references). It is
|
|
|
|
recommended that the provider just use a counter for the contextId,
|
|
|
|
incrementing the value anytime a new context is made.
|
|
|
|
*/
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
/*
|
|
|
|
- all keystorelistcontexts in a side thread
|
|
|
|
- all keystores also exist in the same side thread
|
|
|
|
- mutex protect the entire system, so that nothing happens simultaneously:
|
|
|
|
- every keystore / keystoreentry access method
|
|
|
|
- provider scanning
|
|
|
|
- keystore removal
|
|
|
|
- call keystoremanager.start() to initiate system
|
|
|
|
- waitfordiscovery counts for all providers found on first scan
|
|
|
|
|
|
|
|
- maybe keystore should thread-safe protect all calls
|
|
|
|
|
|
|
|
scenarios to handle:
|
|
|
|
- ksm.start shouldn't block
|
|
|
|
- keystore in available list, but gone by the time it is requested
|
|
|
|
- keystore is unavailable during a call to a keystoreentry method
|
|
|
|
- keystore/keystoreentry methods called simultaneously from different threads
|
|
|
|
- and of course, objects from keystores should work, despite being created
|
|
|
|
in the keystore thread
|
|
|
|
*/
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
class KeyStoreManagerPrivate
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
public:
|
|
|
|
KeyStoreManager *q;
|
|
|
|
KeyStoreThread *thread;
|
|
|
|
QString dtext;
|
|
|
|
|
|
|
|
KeyStoreManagerPrivate(KeyStoreManager *);
|
|
|
|
~KeyStoreManagerPrivate();
|
|
|
|
};
|
|
|
|
|
|
|
|
class KeyStoreTracker;
|
|
|
|
static KeyStoreTracker *trackerInstance = 0;
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
class KeyStoreTracker : public QObject
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2005-07-28 12:17:09 +00:00
|
|
|
// "public"
|
2005-04-09 07:43:15 +00:00
|
|
|
class Item
|
|
|
|
{
|
|
|
|
public:
|
2005-07-28 12:17:09 +00:00
|
|
|
int trackerId;
|
|
|
|
KeyStoreListContext *owner;
|
|
|
|
int storeContextId;
|
|
|
|
QString storeId;
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
Item() : trackerId(-1), owner(0), storeContextId(-1) {}
|
2005-04-09 07:43:15 +00:00
|
|
|
};
|
2005-07-28 12:17:09 +00:00
|
|
|
QList<Item*> stores;
|
|
|
|
QHash<int, Item*> storesByTrackerId;
|
|
|
|
QHash<QString, Item*> storesByStoreId;
|
|
|
|
|
|
|
|
typedef QList<KeyStore*> PublicReferences;
|
|
|
|
QHash<int, PublicReferences> refHash;
|
|
|
|
|
|
|
|
// "private"
|
|
|
|
KeyStoreManager *ksm;
|
|
|
|
int trackerId_at;
|
|
|
|
QSet<Provider*> providerSet;
|
|
|
|
bool first_scan;
|
|
|
|
QList<KeyStoreListContext*> sources;
|
|
|
|
QSet<KeyStoreListContext*> initialDiscoverySet;
|
|
|
|
bool has_initdisco;
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
QList<Item> added;
|
|
|
|
QList<int> removed;
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
KeyStoreTracker(QObject *parent = 0) : QObject(parent)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
trackerInstance = this;
|
|
|
|
trackerId_at = 0;
|
|
|
|
first_scan = true;
|
|
|
|
ksm = keyStoreManager(); // global qca function
|
|
|
|
keyStoreMutex = new QMutex;
|
|
|
|
has_initdisco = false;
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
~KeyStoreTracker()
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
qDeleteAll(stores);
|
|
|
|
qDeleteAll(sources);
|
|
|
|
delete keyStoreMutex;
|
|
|
|
keyStoreMutex = 0;
|
|
|
|
trackerInstance = 0;
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
bool hasInitialDiscovery() const
|
|
|
|
{
|
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
return has_initdisco;
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
public slots:
|
2005-04-09 07:43:15 +00:00
|
|
|
void scan()
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
//QTimer::singleShot(3000, this, SIGNAL(initialDiscovery()));
|
|
|
|
//QTimer::singleShot(6000, this, SIGNAL(initialDiscovery()));
|
|
|
|
|
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
|
2005-04-09 07:43:15 +00:00
|
|
|
// grab providers (and default)
|
|
|
|
ProviderList list = providers();
|
|
|
|
list.append(defaultProvider());
|
|
|
|
|
|
|
|
for(int n = 0; n < list.count(); ++n)
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
Provider *p = list[n];
|
|
|
|
if(p->features().contains("keystorelist") && !providerSet.contains(p))
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
KeyStoreListContext *c = static_cast<KeyStoreListContext *>(getContext("keystorelist", p));
|
|
|
|
if(!c)
|
|
|
|
continue;
|
|
|
|
providerSet += p;
|
|
|
|
sources += c;
|
|
|
|
if(first_scan)
|
|
|
|
{
|
|
|
|
initialDiscoverySet += c;
|
|
|
|
connect(c, SIGNAL(busyEnd()), SLOT(ksl_busyEnd()));
|
|
|
|
}
|
2005-07-31 05:12:42 +00:00
|
|
|
connect(c, SIGNAL(updated()), SLOT(ksl_updated()));
|
|
|
|
connect(c, SIGNAL(diagnosticText(const QString &)), SLOT(ksl_diagnosticText(const QString &)));
|
|
|
|
connect(c, SIGNAL(storeUpdated(int)), SLOT(ksl_storeUpdated(int)));
|
2006-04-06 21:44:41 +00:00
|
|
|
//connect(c, SIGNAL(storeNeedPassphrase(int, int, const QString &)), SLOT(ksl_storeNeedPassphrase(int, int, const QString &)), Qt::DirectConnection);
|
2005-07-28 12:17:09 +00:00
|
|
|
c->start();
|
2006-03-30 09:11:00 +00:00
|
|
|
c->setUpdatesEnabled(true);
|
2005-04-09 07:43:15 +00:00
|
|
|
check(c);
|
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
|
|
|
|
flush();
|
|
|
|
|
|
|
|
// nothing found?
|
|
|
|
if(first_scan && initialDiscoverySet.isEmpty())
|
|
|
|
emit initialDiscovery();
|
|
|
|
|
|
|
|
first_scan = false;
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
signals:
|
|
|
|
void initialDiscovery();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void ksl_busyEnd()
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
|
|
|
|
//printf("ksl_initialDiscovery [%p]\n", sender);
|
|
|
|
|
|
|
|
KeyStoreListContext *ksl = (KeyStoreListContext *)sender();
|
|
|
|
check(ksl);
|
|
|
|
flush();
|
|
|
|
|
|
|
|
if(!initialDiscoverySet.contains(ksl))
|
|
|
|
return;
|
|
|
|
|
|
|
|
//keyStoreMutex->lock();
|
|
|
|
initialDiscoverySet.remove(ksl);
|
|
|
|
if(initialDiscoverySet.isEmpty())
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
// keyStoreMutex->unlock();
|
|
|
|
has_initdisco = true;
|
|
|
|
emit initialDiscovery();
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
//else
|
|
|
|
// keyStoreMutex->unlock();
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-07-31 05:12:42 +00:00
|
|
|
void ksl_updated()
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QMutexLocker locker(keyStoreMutex);
|
2005-07-31 05:12:42 +00:00
|
|
|
KeyStoreListContext *ksl = (KeyStoreListContext *)sender();
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-31 05:12:42 +00:00
|
|
|
check(ksl);
|
2005-07-28 12:17:09 +00:00
|
|
|
flush();
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-31 05:12:42 +00:00
|
|
|
void ksl_diagnosticText(const QString &str)
|
2005-07-28 12:17:09 +00:00
|
|
|
{
|
2005-07-31 05:12:42 +00:00
|
|
|
KeyStoreListContext *ksl = (KeyStoreListContext *)sender();
|
|
|
|
QString name = ksl->provider()->name();
|
2005-07-28 12:17:09 +00:00
|
|
|
ksm->d->dtext += QString("%1: %2\n").arg(name).arg(str);
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-31 05:12:42 +00:00
|
|
|
void ksl_storeUpdated(int contextId)
|
2005-07-28 12:17:09 +00:00
|
|
|
{
|
|
|
|
QMutexLocker locker(keyStoreMutex);
|
2005-07-31 05:12:42 +00:00
|
|
|
KeyStoreListContext *ksl = (KeyStoreListContext *)sender();
|
2005-07-28 12:17:09 +00:00
|
|
|
|
2005-07-31 05:12:42 +00:00
|
|
|
Item *item = findByOwnerAndContext(ksl, contextId);
|
2005-07-28 12:17:09 +00:00
|
|
|
if(!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
PublicReferences refs = refHash.value(item->trackerId);
|
|
|
|
for(int n = 0; n < refs.count(); ++n)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
KeyStore *ks = refs[n];
|
|
|
|
emit ks->updated();
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
}
|
|
|
|
|
2006-04-06 21:44:41 +00:00
|
|
|
/*void ksl_storeNeedPassphrase(int contextId, int requestId, const QString &entryId)
|
2005-07-28 12:17:09 +00:00
|
|
|
{
|
2005-07-31 05:12:42 +00:00
|
|
|
KeyStoreListContext *ksl = (KeyStoreListContext *)sender();
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
PublicReferences refs;
|
2005-04-09 07:43:15 +00:00
|
|
|
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
// FIXME: QMutexLocker locker(keyStoreMutex);
|
|
|
|
|
|
|
|
//printf("ksl_storeNeedPassphrase [%p]\n", sender);
|
|
|
|
|
2005-07-31 05:12:42 +00:00
|
|
|
Item *item = findByOwnerAndContext(ksl, contextId);
|
2005-07-28 12:17:09 +00:00
|
|
|
if(!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
refs = refHash.value(item->trackerId);
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
for(int n = 0; n < refs.count(); ++n)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
KeyStore *ks = refs[n];
|
2005-07-31 05:12:42 +00:00
|
|
|
emit ks->needPassphrase(requestId, entryId); // FIXME
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
2006-04-06 21:44:41 +00:00
|
|
|
}*/
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
private:
|
|
|
|
Item *findByOwnerAndContext(KeyStoreListContext *owner, int contextId)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
Item *item = 0;
|
|
|
|
for(int n = 0; n < stores.count(); ++n)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
if(stores[n]->owner == owner && stores[n]->storeContextId == contextId)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
item = stores[n];
|
|
|
|
break;
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
return item;
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
bool have_store_local(KeyStoreListContext *c, int id)
|
|
|
|
{
|
|
|
|
for(int n = 0; n < stores.count(); ++n)
|
|
|
|
{
|
|
|
|
if(stores[n]->owner == c && stores[n]->storeContextId == id)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
bool have_store_incoming(const QList<int> &keyStores, int id)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
for(int n = 0; n < keyStores.count(); ++n)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
if(keyStores[n] == id)
|
|
|
|
return true;
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
return false;
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void check(KeyStoreListContext *c)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
QList<int> keyStores = c->keyStores();
|
|
|
|
for(int n = 0; n < keyStores.count(); ++n)
|
|
|
|
{
|
|
|
|
if(!have_store_local(c, keyStores[n]))
|
|
|
|
{
|
|
|
|
Item i;
|
|
|
|
i.owner = c;
|
|
|
|
i.storeContextId = keyStores[n];
|
|
|
|
added += i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(int n = 0; n < stores.count(); ++n)
|
|
|
|
{
|
|
|
|
if(stores[n]->owner == c && !have_store_incoming(keyStores, stores[n]->storeContextId))
|
|
|
|
removed += stores[n]->trackerId;
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void flush()
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
// removed
|
|
|
|
for(int n = 0; n < removed.count(); ++n)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
int trackerId = removed[n];
|
|
|
|
int index = -1;
|
|
|
|
for(int i = 0; i < stores.count(); ++i)
|
|
|
|
{
|
|
|
|
if(stores[i]->trackerId == trackerId)
|
|
|
|
{
|
|
|
|
index = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(index != -1)
|
|
|
|
{
|
|
|
|
Item *item = stores[index];
|
|
|
|
stores.removeAt(index);
|
|
|
|
storesByTrackerId.remove(item->trackerId);
|
|
|
|
storesByStoreId.remove(item->storeId);
|
|
|
|
delete item;
|
|
|
|
PublicReferences refs = refHash.value(trackerId);
|
|
|
|
refHash.remove(trackerId);
|
2006-04-30 07:05:10 +00:00
|
|
|
for(int refIdx = 0; refIdx < refs.count(); ++refIdx)
|
2005-07-28 12:17:09 +00:00
|
|
|
{
|
2006-04-29 06:40:31 +00:00
|
|
|
KeyStore *ks = refs[refIdx];
|
2005-07-28 12:17:09 +00:00
|
|
|
ks->invalidate();
|
|
|
|
emit ks->unavailable();
|
|
|
|
}
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
removed.clear();
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
// added
|
|
|
|
for(int n = 0; n < added.count(); ++n)
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
Item *i = new Item(added[n]);
|
|
|
|
i->storeId = i->owner->storeId(i->storeContextId);
|
|
|
|
if(i->storeId.isEmpty())
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
delete i;
|
|
|
|
continue;
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
i->trackerId = trackerId_at++;
|
|
|
|
stores += i;
|
|
|
|
storesByTrackerId[i->trackerId] = i;
|
|
|
|
storesByStoreId[i->storeId] = i;
|
|
|
|
emit ksm->keyStoreAvailable(i->storeId);
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
added.clear();
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
2005-07-28 12:17:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
int tracker_register(KeyStore *ks, const QString &str)
|
|
|
|
{
|
|
|
|
KeyStoreTracker::Item *item = trackerInstance->storesByStoreId.value(str);
|
|
|
|
if(!item)
|
|
|
|
return -1;
|
|
|
|
int trackerId = item->trackerId;
|
|
|
|
trackerInstance->refHash[trackerId] += ks;
|
|
|
|
return trackerId;
|
|
|
|
}
|
|
|
|
|
|
|
|
void tracker_unregister(KeyStore *ks, int trackerId)
|
|
|
|
{
|
|
|
|
trackerInstance->refHash[trackerId].removeAll(ks);
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
KeyStoreListContext *tracker_get_owner(int trackerId)
|
|
|
|
{
|
|
|
|
KeyStoreTracker::Item *item = trackerInstance->storesByTrackerId.value(trackerId);
|
|
|
|
if(!item)
|
|
|
|
return 0;
|
|
|
|
return item->owner;
|
|
|
|
}
|
|
|
|
|
|
|
|
int tracker_get_storeContextId(int trackerId)
|
|
|
|
{
|
|
|
|
KeyStoreTracker::Item *item = trackerInstance->storesByTrackerId.value(trackerId);
|
|
|
|
if(!item)
|
|
|
|
return -1;
|
|
|
|
return item->storeContextId;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString tracker_get_storeId(int trackerId)
|
|
|
|
{
|
|
|
|
KeyStoreTracker::Item *item = trackerInstance->storesByTrackerId.value(trackerId);
|
|
|
|
if(!item)
|
|
|
|
return QString();
|
|
|
|
return item->storeId;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*class KeyStoreApp : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
KeyStoreApp()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~KeyStoreApp()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void foo();
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void quit()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
};*/
|
|
|
|
|
|
|
|
class KeyStoreThread : public QThread
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
QMutex control_mutex;
|
|
|
|
QWaitCondition control_wait;
|
|
|
|
QEventLoop *loop;
|
|
|
|
bool waiting;
|
|
|
|
|
|
|
|
KeyStoreThread(QObject *parent) : QThread(parent)
|
|
|
|
{
|
|
|
|
loop = 0;
|
|
|
|
waiting = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
~KeyStoreThread()
|
|
|
|
{
|
|
|
|
stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void start()
|
|
|
|
{
|
|
|
|
control_mutex.lock();
|
|
|
|
QThread::start();
|
|
|
|
control_wait.wait(&control_mutex);
|
|
|
|
control_mutex.unlock();
|
|
|
|
//printf("thread: started\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void stop()
|
|
|
|
{
|
|
|
|
//printf("thread: stopping\n");
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&control_mutex);
|
|
|
|
if(loop)
|
|
|
|
QMetaObject::invokeMethod(loop, "quit");
|
|
|
|
}
|
|
|
|
wait();
|
|
|
|
//printf("thread: stopped\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void scan()
|
2005-04-09 07:43:15 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
//printf("scan\n");
|
|
|
|
QMetaObject::invokeMethod(trackerInstance, "scan", Qt::QueuedConnection);
|
|
|
|
}
|
|
|
|
|
|
|
|
void waitForInitialDiscovery()
|
|
|
|
{
|
|
|
|
if(trackerInstance->hasInitialDiscovery())
|
|
|
|
return;
|
|
|
|
|
|
|
|
//printf("thread: waiting for initial discovery\n");
|
|
|
|
control_mutex.lock();
|
|
|
|
waiting = true;
|
|
|
|
control_wait.wait(&control_mutex);
|
|
|
|
waiting = false;
|
|
|
|
control_mutex.unlock();
|
|
|
|
//printf("thread: wait finished\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void run()
|
|
|
|
{
|
|
|
|
control_mutex.lock();
|
|
|
|
KeyStoreTracker tracker;
|
|
|
|
connect(&tracker, SIGNAL(initialDiscovery()), SLOT(tracker_initialDiscovery()), Qt::DirectConnection);
|
|
|
|
//KeyStoreApp app;
|
|
|
|
//connect(&app, SIGNAL(foo()), SLOT(tracker_initialDiscovery()), Qt::DirectConnection);
|
|
|
|
//QTimer::singleShot(3000, &app, SIGNAL(foo()));
|
|
|
|
//QTimer::singleShot(6000, &app, SIGNAL(foo()));
|
2006-02-24 08:44:09 +00:00
|
|
|
loop = new QEventLoop; // TODO: delete this at some point
|
2005-07-28 12:17:09 +00:00
|
|
|
control_wait.wakeOne();
|
|
|
|
control_mutex.unlock();
|
|
|
|
loop->exec();
|
|
|
|
QMutexLocker locker(&control_mutex);
|
|
|
|
loop = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void tracker_initialDiscovery()
|
|
|
|
{
|
|
|
|
//printf("tracker_initialDiscovery\n");
|
|
|
|
control_mutex.lock();
|
|
|
|
if(waiting)
|
|
|
|
{
|
|
|
|
control_wait.wakeOne();
|
|
|
|
control_mutex.unlock();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
control_mutex.unlock();
|
|
|
|
KeyStoreManager *ksm = keyStoreManager();
|
|
|
|
emit ksm->busyFinished();
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// KeyStoreManager
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
KeyStoreManagerPrivate::KeyStoreManagerPrivate(KeyStoreManager *_q)
|
|
|
|
:q(_q)
|
|
|
|
{
|
|
|
|
thread = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
KeyStoreManagerPrivate::~KeyStoreManagerPrivate()
|
|
|
|
{
|
|
|
|
delete thread;
|
|
|
|
}
|
|
|
|
|
2005-03-28 07:11:58 +00:00
|
|
|
KeyStoreManager::KeyStoreManager()
|
|
|
|
{
|
2005-04-09 07:43:15 +00:00
|
|
|
d = new KeyStoreManagerPrivate(this);
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
KeyStoreManager::~KeyStoreManager()
|
|
|
|
{
|
2005-04-09 07:43:15 +00:00
|
|
|
delete d;
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void KeyStoreManager::start()
|
2005-03-28 07:11:58 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
if(d->thread)
|
|
|
|
return;
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2006-02-24 08:44:09 +00:00
|
|
|
moveToThread(QCoreApplication::instance()->thread());
|
2005-07-28 12:17:09 +00:00
|
|
|
d->thread = new KeyStoreThread(this);
|
|
|
|
d->thread->start();
|
2005-04-09 07:43:15 +00:00
|
|
|
scan();
|
2005-07-28 12:17:09 +00:00
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-30 09:16:05 +00:00
|
|
|
void KeyStoreManager::start(const QString &provider)
|
|
|
|
{
|
|
|
|
Q_UNUSED(provider);
|
|
|
|
start();
|
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
bool KeyStoreManager::isBusy() const
|
|
|
|
{
|
|
|
|
return !(trackerInstance->hasInitialDiscovery());
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
void KeyStoreManager::waitForBusyFinished()
|
2005-03-28 07:11:58 +00:00
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
d->thread->waitForInitialDiscovery();
|
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
|
2005-07-28 12:17:09 +00:00
|
|
|
QStringList KeyStoreManager::keyStores() const
|
|
|
|
{
|
|
|
|
if(trackerInstance)
|
|
|
|
{
|
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
QStringList out;
|
|
|
|
for(int n = 0; n < trackerInstance->stores.count(); ++n)
|
|
|
|
{
|
|
|
|
KeyStoreTracker::Item *i = trackerInstance->stores[n];
|
|
|
|
out += i->storeId;
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return QStringList();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int KeyStoreManager::count() const
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
if(trackerInstance)
|
|
|
|
{
|
|
|
|
QMutexLocker locker(keyStoreMutex);
|
|
|
|
return trackerInstance->stores.count();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2005-04-02 17:37:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
QString KeyStoreManager::diagnosticText() const
|
|
|
|
{
|
2005-07-28 12:17:09 +00:00
|
|
|
return d->dtext;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KeyStoreManager::clearDiagnosticText()
|
|
|
|
{
|
|
|
|
d->dtext = QString();
|
2005-04-02 17:37:52 +00:00
|
|
|
}
|
|
|
|
|
2005-04-09 07:43:15 +00:00
|
|
|
void KeyStoreManager::scan() const
|
|
|
|
{
|
|
|
|
scanForPlugins();
|
2005-07-28 12:17:09 +00:00
|
|
|
d->thread->scan();
|
2005-03-28 07:11:58 +00:00
|
|
|
}
|
2005-04-09 07:43:15 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "qca_keystore.moc"
|