mirror of
https://github.com/QuasarApp/qca.git
synced 2025-05-13 11:09:34 +00:00
use q_interface for plugins, add diagnostic text
svn path=/trunk/kdesupport/qca/; revision=513017
This commit is contained in:
parent
a7e91276cf
commit
7722e56837
include/QtCrypto
plugins/qca-openssl
src
tools/qcatool
@ -299,6 +299,16 @@ namespace QCA
|
||||
*/
|
||||
QCA_EXPORT void unloadAllPlugins();
|
||||
|
||||
/**
|
||||
* Retrieve plugin diagnostic text
|
||||
*/
|
||||
QCA_EXPORT QString pluginDiagnosticText();
|
||||
|
||||
/**
|
||||
* Clear plugin diagnostic text
|
||||
*/
|
||||
QCA_EXPORT void clearPluginDiagnosticText();
|
||||
|
||||
/**
|
||||
* Set a global property
|
||||
*/
|
||||
|
@ -38,16 +38,15 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
#define QCA_PLUGIN_VERSION 2
|
||||
|
||||
class QCA_EXPORT QCAPlugin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
virtual int version() const = 0;
|
||||
virtual QCA::Provider *createProvider() = 0;
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(QCAPlugin, "com.affinix.qca.Plugin/1.0")
|
||||
|
||||
namespace QCA {
|
||||
|
||||
class QCA_EXPORT RandomContext : public Provider::Context
|
||||
|
@ -5205,12 +5205,12 @@ public:
|
||||
class opensslPlugin : public QCAPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QCAPlugin)
|
||||
public:
|
||||
virtual int version() const { return QCA_PLUGIN_VERSION; }
|
||||
virtual Provider *createProvider() { return new opensslProvider; }
|
||||
};
|
||||
|
||||
#include "qca-openssl.moc"
|
||||
|
||||
Q_EXPORT_PLUGIN(opensslPlugin);
|
||||
Q_EXPORT_PLUGIN2(qca-openssl, opensslPlugin);
|
||||
|
||||
|
@ -282,6 +282,18 @@ void unloadAllPlugins()
|
||||
global->manager.unloadAll();
|
||||
}
|
||||
|
||||
QString pluginDiagnosticText()
|
||||
{
|
||||
QMutexLocker lock(&global->manager_mutex);
|
||||
return global->manager.diagnosticText();
|
||||
}
|
||||
|
||||
void clearPluginDiagnosticText()
|
||||
{
|
||||
QMutexLocker lock(&global->manager_mutex);
|
||||
global->manager.clearDiagnosticText();
|
||||
}
|
||||
|
||||
void setProperty(const QString &name, const QVariant &value)
|
||||
{
|
||||
QMutexLocker lock(&global->manager_mutex);
|
||||
|
@ -26,6 +26,116 @@
|
||||
|
||||
namespace QCA {
|
||||
|
||||
static ProviderManager *g_pluginman = 0;
|
||||
|
||||
static void logDebug(const QString &str)
|
||||
{
|
||||
if(g_pluginman)
|
||||
g_pluginman->appendDiagnosticText(str + '\n');
|
||||
}
|
||||
|
||||
class PluginInstance
|
||||
{
|
||||
private:
|
||||
QPluginLoader *_loader;
|
||||
QObject *_instance;
|
||||
bool _ownInstance;
|
||||
|
||||
PluginInstance()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static PluginInstance *fromFile(const QString &fname)
|
||||
{
|
||||
logDebug(QString("PluginInstance fromFile [%1]").arg(fname));
|
||||
QPluginLoader *loader = new QPluginLoader(fname);
|
||||
if(!loader->load())
|
||||
{
|
||||
logDebug("failed to load");
|
||||
delete loader;
|
||||
return 0;
|
||||
}
|
||||
QObject *obj = loader->instance();
|
||||
if(!obj)
|
||||
{
|
||||
logDebug("failed to get instance");
|
||||
loader->unload();
|
||||
delete loader;
|
||||
return 0;
|
||||
}
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = loader;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = true;
|
||||
logDebug(QString("loaded as [%1]").arg(obj->metaObject()->className()));
|
||||
return i;
|
||||
}
|
||||
|
||||
static PluginInstance *fromStatic(QObject *obj)
|
||||
{
|
||||
logDebug("PluginInstance fromStatic");
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = 0;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = false;
|
||||
logDebug(QString("loaded as [%1]").arg(obj->metaObject()->className()));
|
||||
return i;
|
||||
}
|
||||
|
||||
static PluginInstance *fromInstance(QObject *obj)
|
||||
{
|
||||
logDebug("PluginInstance fromInstance");
|
||||
PluginInstance *i = new PluginInstance;
|
||||
i->_loader = 0;
|
||||
i->_instance = obj;
|
||||
i->_ownInstance = true;
|
||||
logDebug(QString("loaded as [%1]").arg(obj->metaObject()->className()));
|
||||
return i;
|
||||
}
|
||||
|
||||
~PluginInstance()
|
||||
{
|
||||
QString str;
|
||||
if(_instance)
|
||||
str = _instance->metaObject()->className();
|
||||
|
||||
if(_ownInstance)
|
||||
delete _instance;
|
||||
|
||||
if(_loader)
|
||||
{
|
||||
_loader->unload();
|
||||
delete _loader;
|
||||
}
|
||||
logDebug(QString("PluginInstance deleted [%1]").arg(str));
|
||||
}
|
||||
|
||||
void claim()
|
||||
{
|
||||
if(_loader)
|
||||
_loader->moveToThread(0);
|
||||
if(_ownInstance)
|
||||
_instance->moveToThread(0);
|
||||
}
|
||||
|
||||
QObject *instance()
|
||||
{
|
||||
return _instance;
|
||||
}
|
||||
|
||||
bool sameType(const PluginInstance *other)
|
||||
{
|
||||
if(!_instance || !other->_instance)
|
||||
return false;
|
||||
|
||||
if(qstrcmp(_instance->metaObject()->className(), other->_instance->metaObject()->className()) != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ProviderItem
|
||||
{
|
||||
public:
|
||||
@ -35,61 +145,63 @@ public:
|
||||
|
||||
static ProviderItem *load(const QString &fname)
|
||||
{
|
||||
//printf("trying to load [%s]\n", qPrintable(fname));
|
||||
QPluginLoader *lib = new QPluginLoader(fname);
|
||||
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(lib->instance());
|
||||
if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
|
||||
PluginInstance *i = PluginInstance::fromFile(fname);
|
||||
if(!i)
|
||||
return 0;
|
||||
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(i->instance());
|
||||
if(!plugin)
|
||||
{
|
||||
delete plugin;
|
||||
delete lib;
|
||||
logDebug("not a QCAPlugin or wrong interface");
|
||||
delete i;
|
||||
return 0;
|
||||
}
|
||||
//printf("success\n");
|
||||
|
||||
Provider *p = plugin->createProvider();
|
||||
if(!p)
|
||||
{
|
||||
delete plugin;
|
||||
delete lib;
|
||||
logDebug("unable to create provider");
|
||||
delete i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ProviderItem *i = new ProviderItem(lib, plugin, p);
|
||||
i->fname = fname;
|
||||
return i;
|
||||
ProviderItem *pi = new ProviderItem(i, p);
|
||||
pi->fname = fname;
|
||||
return pi;
|
||||
}
|
||||
|
||||
static ProviderItem *loadStatic(QObject *instance)
|
||||
{
|
||||
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(instance);
|
||||
if(!plugin || plugin->version() != QCA_PLUGIN_VERSION)
|
||||
PluginInstance *i = PluginInstance::fromStatic(instance);
|
||||
QCAPlugin *plugin = qobject_cast<QCAPlugin*>(i->instance());
|
||||
if(!plugin)
|
||||
{
|
||||
delete plugin;
|
||||
logDebug("not a QCAPlugin or wrong interface");
|
||||
delete i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Provider *p = plugin->createProvider();
|
||||
if(!p)
|
||||
{
|
||||
delete plugin;
|
||||
logDebug("unable to create provider");
|
||||
delete i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ProviderItem *i = new ProviderItem(0, plugin, p);
|
||||
return i;
|
||||
ProviderItem *pi = new ProviderItem(i, p);
|
||||
return pi;
|
||||
}
|
||||
|
||||
static ProviderItem *fromClass(Provider *p)
|
||||
{
|
||||
ProviderItem *i = new ProviderItem(0, 0, p);
|
||||
return i;
|
||||
ProviderItem *pi = new ProviderItem(0, p);
|
||||
return pi;
|
||||
}
|
||||
|
||||
~ProviderItem()
|
||||
{
|
||||
delete p;
|
||||
delete qcaPlugin;
|
||||
delete lib;
|
||||
delete instance;
|
||||
}
|
||||
|
||||
void ensureInit()
|
||||
@ -101,34 +213,33 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
QPluginLoader *lib;
|
||||
QCAPlugin *qcaPlugin;
|
||||
PluginInstance *instance;
|
||||
bool init_done;
|
||||
|
||||
ProviderItem(QPluginLoader *_lib, QCAPlugin *_qcaPlugin, Provider *_p)
|
||||
ProviderItem(PluginInstance *_instance, Provider *_p)
|
||||
{
|
||||
lib = _lib;
|
||||
qcaPlugin = _qcaPlugin;
|
||||
instance = _instance;
|
||||
p = _p;
|
||||
init_done = false;
|
||||
|
||||
// disassociate from threads
|
||||
if(qcaPlugin)
|
||||
qcaPlugin->moveToThread(0);
|
||||
if(lib)
|
||||
lib->moveToThread(0);
|
||||
instance->claim();
|
||||
logDebug(QString("ProviderItem created: [%1]").arg(p->name()));
|
||||
}
|
||||
};
|
||||
|
||||
ProviderManager::ProviderManager()
|
||||
{
|
||||
g_pluginman = this;
|
||||
def = 0;
|
||||
scanned_static = false;
|
||||
}
|
||||
|
||||
ProviderManager::~ProviderManager()
|
||||
{
|
||||
unloadAll();
|
||||
delete def;
|
||||
g_pluginman = 0;
|
||||
}
|
||||
|
||||
void ProviderManager::scan()
|
||||
@ -146,6 +257,7 @@ void ProviderManager::scan()
|
||||
|
||||
if(i->p && haveAlready(i->p->name()))
|
||||
{
|
||||
logDebug("skipping, we already have it");
|
||||
delete i;
|
||||
continue;
|
||||
}
|
||||
@ -157,8 +269,11 @@ void ProviderManager::scan()
|
||||
|
||||
// check plugin files
|
||||
QStringList dirs = QCoreApplication::libraryPaths();
|
||||
if(dirs.isEmpty())
|
||||
logDebug("no Qt plugin paths");
|
||||
for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it)
|
||||
{
|
||||
logDebug(QString("checking in path: [%1]").arg(*it));
|
||||
QDir libpath(*it);
|
||||
QDir dir(libpath.filePath(PLUGIN_SUBDIR));
|
||||
if(!dir.exists())
|
||||
@ -172,6 +287,13 @@ void ProviderManager::scan()
|
||||
continue;
|
||||
QString fname = fi.filePath();
|
||||
|
||||
logDebug(QString("checking file: [%1]").arg(fname));
|
||||
if(!QLibrary::isLibrary(fname))
|
||||
{
|
||||
logDebug("skipping, not a library\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure we haven't loaded this file before
|
||||
bool haveFile = false;
|
||||
for(int n = 0; n < providerItemList.count(); ++n)
|
||||
@ -184,7 +306,10 @@ void ProviderManager::scan()
|
||||
}
|
||||
}
|
||||
if(haveFile)
|
||||
{
|
||||
logDebug("skipping, we already loaded this file");
|
||||
continue;
|
||||
}
|
||||
|
||||
ProviderItem *i = ProviderItem::load(fname);
|
||||
if(!i)
|
||||
@ -192,6 +317,7 @@ void ProviderManager::scan()
|
||||
|
||||
if(i->p && haveAlready(i->p->name()))
|
||||
{
|
||||
logDebug("skipping, we already have it");
|
||||
delete i;
|
||||
continue;
|
||||
}
|
||||
@ -203,8 +329,12 @@ void ProviderManager::scan()
|
||||
|
||||
bool ProviderManager::add(Provider *p, int priority)
|
||||
{
|
||||
logDebug(QString("adding pre-made provider: [%1]").arg(p->name()));
|
||||
if(haveAlready(p->name()))
|
||||
{
|
||||
logDebug("skipping, we already have it");
|
||||
return false;
|
||||
}
|
||||
|
||||
ProviderItem *i = ProviderItem::fromClass(p);
|
||||
addItem(i, priority);
|
||||
@ -366,6 +496,21 @@ const ProviderList & ProviderManager::providers() const
|
||||
return providerList;
|
||||
}
|
||||
|
||||
QString ProviderManager::diagnosticText() const
|
||||
{
|
||||
return dtext;
|
||||
}
|
||||
|
||||
void ProviderManager::appendDiagnosticText(const QString &str)
|
||||
{
|
||||
dtext += str;
|
||||
}
|
||||
|
||||
void ProviderManager::clearDiagnosticText()
|
||||
{
|
||||
dtext = QString();
|
||||
}
|
||||
|
||||
void ProviderManager::addItem(ProviderItem *item, int priority)
|
||||
{
|
||||
if(priority < 0)
|
||||
@ -397,6 +542,8 @@ void ProviderManager::addItem(ProviderItem *item, int priority)
|
||||
providerItemList.insert(n, item);
|
||||
providerList.insert(n, item->p);
|
||||
}
|
||||
|
||||
logDebug(QString("item added [%1]").arg(item->p->name()));
|
||||
}
|
||||
|
||||
bool ProviderManager::haveAlready(const QString &name) const
|
||||
|
@ -51,7 +51,12 @@ namespace QCA
|
||||
|
||||
static void mergeFeatures(QStringList *a, const QStringList &b);
|
||||
|
||||
QString diagnosticText() const;
|
||||
void appendDiagnosticText(const QString &str);
|
||||
void clearDiagnosticText();
|
||||
|
||||
private:
|
||||
QString dtext;
|
||||
QList<ProviderItem*> providerItemList;
|
||||
ProviderList providerList;
|
||||
Provider *def;
|
||||
|
@ -531,7 +531,7 @@ static QString getKeyStore(const QString &name)
|
||||
int n = findByString(getKeyStoreStrings(storeList), name);
|
||||
if(n != -1)
|
||||
return storeList[n];
|
||||
return 0;
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QCA::KeyStoreEntry getKeyStoreEntry(QCA::KeyStore *store, const QString &name)
|
||||
@ -668,6 +668,7 @@ static void usage()
|
||||
printf("usage: qcatool [--command] (options)\n");
|
||||
printf("commands:\n");
|
||||
printf(" --help\n");
|
||||
printf(" --plugins [-d]\n");
|
||||
printf("\n");
|
||||
printf(" --genrsa [bits] (passphrase)\n");
|
||||
printf(" --gendsa [512|768|1024] (passphrase)\n");
|
||||
@ -782,6 +783,64 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(args[0] == "--plugins")
|
||||
{
|
||||
printf("Qt Library Paths:\n");
|
||||
QStringList paths = QCoreApplication::libraryPaths();
|
||||
if(!paths.isEmpty())
|
||||
{
|
||||
for(int n = 0; n < paths.count(); ++n)
|
||||
{
|
||||
printf(" %s\n", qPrintable(paths[n]));
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(" (none)\n");
|
||||
|
||||
QCA::scanForPlugins();
|
||||
QCA::ProviderList list = QCA::providers();
|
||||
|
||||
bool debug = false;
|
||||
for(int n = 1; n < args.count(); ++n)
|
||||
{
|
||||
if(args[n] == "-d")
|
||||
{
|
||||
debug = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(debug)
|
||||
{
|
||||
QString str = QCA::pluginDiagnosticText();
|
||||
QCA::clearPluginDiagnosticText();
|
||||
QStringList lines = str.split('\n', QString::SkipEmptyParts);
|
||||
for(int n = 0; n < lines.count(); ++n)
|
||||
printf("qca: %s\n", qPrintable(lines[n]));
|
||||
}
|
||||
|
||||
printf("Available Providers:\n");
|
||||
if(!list.isEmpty())
|
||||
{
|
||||
for(int n = 0; n < list.count(); ++n)
|
||||
{
|
||||
printf(" %s\n", qPrintable(list[n]->name()));
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(" (none)\n");
|
||||
|
||||
QCA::unloadAllPlugins();
|
||||
if(debug)
|
||||
{
|
||||
QString str = QCA::pluginDiagnosticText();
|
||||
QCA::clearPluginDiagnosticText();
|
||||
QStringList lines = str.split('\n', QString::SkipEmptyParts);
|
||||
for(int n = 0; n < lines.count(); ++n)
|
||||
printf("qca: %s\n", qPrintable(lines[n]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// activate the KeyStoreManager and block until ready
|
||||
QCA::keyStoreManager()->start();
|
||||
QCA::keyStoreManager()->waitForBusyFinished();
|
||||
@ -1232,7 +1291,7 @@ int main(int argc, char **argv)
|
||||
//info[QCA::URI] = "http://psi.affinix.com/";
|
||||
//info[QCA::DNS] = "psi.affinix.com";
|
||||
//info[QCA::IPAddress] = "192.168.0.1";
|
||||
//info[QCA::XMPP] = "justin@andbit.net";
|
||||
//info.insert(QCA::XMPP, "justin@andbit.net");
|
||||
|
||||
opts.setInfo(info);
|
||||
if(do_ca)
|
||||
|
Loading…
x
Reference in New Issue
Block a user