diff options
Diffstat (limited to 'kopete/protocols/jabber/libiris/qca/src')
-rw-r--r-- | kopete/protocols/jabber/libiris/qca/src/Makefile.am | 7 | ||||
-rw-r--r-- | kopete/protocols/jabber/libiris/qca/src/qca.cpp | 1481 | ||||
-rw-r--r-- | kopete/protocols/jabber/libiris/qca/src/qca.h | 466 | ||||
-rw-r--r-- | kopete/protocols/jabber/libiris/qca/src/qcaprovider.h | 191 |
4 files changed, 2145 insertions, 0 deletions
diff --git a/kopete/protocols/jabber/libiris/qca/src/Makefile.am b/kopete/protocols/jabber/libiris/qca/src/Makefile.am new file mode 100644 index 00000000..b43d303e --- /dev/null +++ b/kopete/protocols/jabber/libiris/qca/src/Makefile.am @@ -0,0 +1,7 @@ +METASOURCES = AUTO + +noinst_LTLIBRARIES = libqca.la +INCLUDES = $(all_includes) + +libqca_la_SOURCES = \ + qca.cpp diff --git a/kopete/protocols/jabber/libiris/qca/src/qca.cpp b/kopete/protocols/jabber/libiris/qca/src/qca.cpp new file mode 100644 index 00000000..5b67e6e3 --- /dev/null +++ b/kopete/protocols/jabber/libiris/qca/src/qca.cpp @@ -0,0 +1,1481 @@ +/* + * qca.cpp - Qt Cryptographic Architecture + * Copyright (C) 2003 Justin Karneges + * + * 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.h" + +#include<qptrlist.h> +#include<qdir.h> +#include<qfileinfo.h> +#include<qstringlist.h> +#include<qlibrary.h> +#include<qtimer.h> +#include<qhostaddress.h> +#include<qapplication.h> +#include<qguardedptr.h> +#include<stdlib.h> +#include"qcaprovider.h" + +#if defined(Q_OS_WIN32) +#define PLUGIN_EXT "dll" +#elif defined(Q_OS_MAC) +#define PLUGIN_EXT "dylib" +#else +#define PLUGIN_EXT "so" +#endif + +using namespace QCA; + +class ProviderItem +{ +public: + QCAProvider *p; + QString fname; + + static ProviderItem *load(const QString &fname) + { + QLibrary *lib = new QLibrary(fname); + if(!lib->load()) { + delete lib; + return 0; + } + void *s = lib->resolve("createProvider"); + if(!s) { + delete lib; + return 0; + } + QCAProvider *(*createProvider)() = (QCAProvider *(*)())s; + QCAProvider *p = createProvider(); + if(!p) { + delete lib; + return 0; + } + ProviderItem *i = new ProviderItem(lib, p); + i->fname = fname; + return i; + } + + static ProviderItem *fromClass(QCAProvider *p) + { + ProviderItem *i = new ProviderItem(0, p); + return i; + } + + ~ProviderItem() + { + delete p; + delete lib; + } + + void ensureInit() + { + if(init_done) + return; + init_done = true; + p->init(); + } + +private: + QLibrary *lib; + bool init_done; + + ProviderItem(QLibrary *_lib, QCAProvider *_p) + { + lib = _lib; + p = _p; + init_done = false; + } +}; + +static QPtrList<ProviderItem> providerList; +static bool qca_init = false; + +static bool plugin_have(const QString &fname) +{ + QPtrListIterator<ProviderItem> it(providerList); + for(ProviderItem *i; (i = it.current()); ++it) { + if(i->fname == fname) + return true; + } + return false; +} + +static void plugin_scan() +{ + QStringList dirs = QApplication::libraryPaths(); + for(QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) { + QDir libpath(*it); + QDir dir(libpath.filePath("crypto")); + if(!dir.exists()) + continue; + + QStringList list = dir.entryList(); + for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) { + QFileInfo fi(dir.filePath(*it)); + if(fi.isDir()) + continue; + if(fi.extension() != PLUGIN_EXT) + continue; + QString fname = fi.filePath(); + + // don't load the same plugin again! + if(plugin_have(fname)) + continue; + //printf("f=[%s]\n", fname.latin1()); + + ProviderItem *i = ProviderItem::load(fname); + if(!i) + continue; + if(i->p->qcaVersion() != QCA_PLUGIN_VERSION) { + delete i; + continue; + } + + providerList.append(i); + } + } +} + +static void plugin_addClass(QCAProvider *p) +{ + ProviderItem *i = ProviderItem::fromClass(p); + providerList.prepend(i); +} + +static void plugin_unloadall() +{ + providerList.clear(); +} + +static int plugin_caps() +{ + int caps = 0; + QPtrListIterator<ProviderItem> it(providerList); + for(ProviderItem *i; (i = it.current()); ++it) + caps |= i->p->capabilities(); + return caps; +} + +QString QCA::arrayToHex(const QByteArray &a) +{ + QString out; + for(int n = 0; n < (int)a.size(); ++n) { + QString str; + str.sprintf("%02x", (uchar)a[n]); + out.append(str); + } + return out; +} + +QByteArray QCA::hexToArray(const QString &str) +{ + QByteArray out(str.length() / 2); + int at = 0; + for(int n = 0; n + 1 < (int)str.length(); n += 2) { + uchar a = str[n]; + uchar b = str[n+1]; + uchar c = ((a & 0x0f) << 4) + (b & 0x0f); + out[at++] = c; + } + return out; +} + +void QCA::init() +{ + if(qca_init) + return; + qca_init = true; + providerList.setAutoDelete(true); +} + +bool QCA::isSupported(int capabilities) +{ + init(); + + int caps = plugin_caps(); + if(caps & capabilities) + return true; + + // ok, try scanning for new stuff + plugin_scan(); + caps = plugin_caps(); + if(caps & capabilities) + return true; + + return false; +} + +void QCA::insertProvider(QCAProvider *p) +{ + plugin_addClass(p); +} + +void QCA::unloadAllPlugins() +{ + plugin_unloadall(); +} + +static void *getContext(int cap) +{ + init(); + + // this call will also trip a scan for new plugins if needed + if(!QCA::isSupported(cap)) + return 0; + + QPtrListIterator<ProviderItem> it(providerList); + for(ProviderItem *i; (i = it.current()); ++it) { + if(i->p->capabilities() & cap) { + i->ensureInit(); + return i->p->context(cap); + } + } + return 0; +} + + +//---------------------------------------------------------------------------- +// Hash +//---------------------------------------------------------------------------- +class Hash::Private +{ +public: + Private() + { + c = 0; + } + + ~Private() + { + delete c; + } + + void reset() + { + c->reset(); + } + + QCA_HashContext *c; +}; + +Hash::Hash(QCA_HashContext *c) +{ + d = new Private; + d->c = c; +} + +Hash::Hash(const Hash &from) +{ + d = new Private; + *this = from; +} + +Hash & Hash::operator=(const Hash &from) +{ + delete d->c; + d->c = from.d->c->clone(); + return *this; +} + +Hash::~Hash() +{ + delete d; +} + +void Hash::clear() +{ + d->reset(); +} + +void Hash::update(const QByteArray &a) +{ + d->c->update(a.data(), a.size()); +} + +QByteArray Hash::final() +{ + QByteArray buf; + d->c->final(&buf); + return buf; +} + + +//---------------------------------------------------------------------------- +// Cipher +//---------------------------------------------------------------------------- +class Cipher::Private +{ +public: + Private() + { + c = 0; + } + + ~Private() + { + delete c; + } + + void reset() + { + dir = Encrypt; + key.resize(0); + iv.resize(0); + err = false; + } + + QCA_CipherContext *c; + int dir; + int mode; + QByteArray key, iv; + bool err; +}; + +Cipher::Cipher(QCA_CipherContext *c, int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad) +{ + d = new Private; + d->c = c; + reset(dir, mode, key, iv, pad); +} + +Cipher::Cipher(const Cipher &from) +{ + d = new Private; + *this = from; +} + +Cipher & Cipher::operator=(const Cipher &from) +{ + delete d->c; + d->c = from.d->c->clone(); + d->dir = from.d->dir; + d->mode = from.d->mode; + d->key = from.d->key.copy(); + d->iv = from.d->iv.copy(); + d->err = from.d->err; + return *this; +} + +Cipher::~Cipher() +{ + delete d; +} + +QByteArray Cipher::dyn_generateKey(int size) const +{ + QByteArray buf; + if(size != -1) + buf.resize(size); + else + buf.resize(d->c->keySize()); + if(!d->c->generateKey(buf.data(), size)) + return QByteArray(); + return buf; +} + +QByteArray Cipher::dyn_generateIV() const +{ + QByteArray buf(d->c->blockSize()); + if(!d->c->generateIV(buf.data())) + return QByteArray(); + return buf; +} + +void Cipher::reset(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad) +{ + d->reset(); + + d->dir = dir; + d->mode = mode; + d->key = key.copy(); + d->iv = iv.copy(); + if(!d->c->setup(d->dir, d->mode, d->key.isEmpty() ? 0: d->key.data(), d->key.size(), d->iv.isEmpty() ? 0 : d->iv.data(), pad)) { + d->err = true; + return; + } +} + +bool Cipher::update(const QByteArray &a) +{ + if(d->err) + return false; + + if(!a.isEmpty()) { + if(!d->c->update(a.data(), a.size())) { + d->err = true; + return false; + } + } + return true; +} + +QByteArray Cipher::final(bool *ok) +{ + if(ok) + *ok = false; + if(d->err) + return QByteArray(); + + QByteArray out; + if(!d->c->final(&out)) { + d->err = true; + return QByteArray(); + } + if(ok) + *ok = true; + return out; +} + + +//---------------------------------------------------------------------------- +// SHA1 +//---------------------------------------------------------------------------- +SHA1::SHA1() +:Hash((QCA_HashContext *)getContext(CAP_SHA1)) +{ +} + + +//---------------------------------------------------------------------------- +// SHA256 +//---------------------------------------------------------------------------- +SHA256::SHA256() +:Hash((QCA_HashContext *)getContext(CAP_SHA256)) +{ +} + + +//---------------------------------------------------------------------------- +// MD5 +//---------------------------------------------------------------------------- +MD5::MD5() +:Hash((QCA_HashContext *)getContext(CAP_MD5)) +{ +} + + +//---------------------------------------------------------------------------- +// BlowFish +//---------------------------------------------------------------------------- +BlowFish::BlowFish(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad) +:Cipher((QCA_CipherContext *)getContext(CAP_BlowFish), dir, mode, key, iv, pad) +{ +} + + +//---------------------------------------------------------------------------- +// TripleDES +//---------------------------------------------------------------------------- +TripleDES::TripleDES(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad) +:Cipher((QCA_CipherContext *)getContext(CAP_TripleDES), dir, mode, key, iv, pad) +{ +} + + +//---------------------------------------------------------------------------- +// AES128 +//---------------------------------------------------------------------------- +AES128::AES128(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad) +:Cipher((QCA_CipherContext *)getContext(CAP_AES128), dir, mode, key, iv, pad) +{ +} + + +//---------------------------------------------------------------------------- +// AES256 +//---------------------------------------------------------------------------- +AES256::AES256(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad) +:Cipher((QCA_CipherContext *)getContext(CAP_AES256), dir, mode, key, iv, pad) +{ +} + + +//---------------------------------------------------------------------------- +// RSAKey +//---------------------------------------------------------------------------- +class RSAKey::Private +{ +public: + Private() + { + c = 0; + } + + ~Private() + { + delete c; + } + + QCA_RSAKeyContext *c; +}; + +RSAKey::RSAKey() +{ + d = new Private; + d->c = (QCA_RSAKeyContext *)getContext(CAP_RSA); +} + +RSAKey::RSAKey(const RSAKey &from) +{ + d = new Private; + *this = from; +} + +RSAKey & RSAKey::operator=(const RSAKey &from) +{ + delete d->c; + d->c = from.d->c->clone(); + return *this; +} + +RSAKey::~RSAKey() +{ + delete d; +} + +bool RSAKey::isNull() const +{ + return d->c->isNull(); +} + +bool RSAKey::havePublic() const +{ + return d->c->havePublic(); +} + +bool RSAKey::havePrivate() const +{ + return d->c->havePrivate(); +} + +QByteArray RSAKey::toDER(bool publicOnly) const +{ + QByteArray out; + if(!d->c->toDER(&out, publicOnly)) + return QByteArray(); + return out; +} + +bool RSAKey::fromDER(const QByteArray &a) +{ + return d->c->createFromDER(a.data(), a.size()); +} + +QString RSAKey::toPEM(bool publicOnly) const +{ + QByteArray out; + if(!d->c->toPEM(&out, publicOnly)) + return QByteArray(); + + QCString cs; + cs.resize(out.size()+1); + memcpy(cs.data(), out.data(), out.size()); + return QString::fromLatin1(cs); +} + +bool RSAKey::fromPEM(const QString &str) +{ + QCString cs = str.latin1(); + QByteArray a(cs.length()); + memcpy(a.data(), cs.data(), a.size()); + return d->c->createFromPEM(a.data(), a.size()); +} + +bool RSAKey::fromNative(void *p) +{ + return d->c->createFromNative(p); +} + +bool RSAKey::encrypt(const QByteArray &a, QByteArray *b, bool oaep) const +{ + QByteArray out; + if(!d->c->encrypt(a, &out, oaep)) + return false; + *b = out; + return true; +} + +bool RSAKey::decrypt(const QByteArray &a, QByteArray *b, bool oaep) const +{ + QByteArray out; + if(!d->c->decrypt(a, &out, oaep)) + return false; + *b = out; + return true; +} + +bool RSAKey::generate(unsigned int bits) +{ + return d->c->generate(bits); +} + + +//---------------------------------------------------------------------------- +// RSA +//---------------------------------------------------------------------------- +RSA::RSA() +{ +} + +RSA::~RSA() +{ +} + +RSAKey RSA::key() const +{ + return v_key; +} + +void RSA::setKey(const RSAKey &k) +{ + v_key = k; +} + +bool RSA::encrypt(const QByteArray &a, QByteArray *b, bool oaep) const +{ + if(v_key.isNull()) + return false; + return v_key.encrypt(a, b, oaep); +} + +bool RSA::decrypt(const QByteArray &a, QByteArray *b, bool oaep) const +{ + if(v_key.isNull()) + return false; + return v_key.decrypt(a, b, oaep); +} + +RSAKey RSA::generateKey(unsigned int bits) +{ + RSAKey k; + k.generate(bits); + return k; +} + + +//---------------------------------------------------------------------------- +// Cert +//---------------------------------------------------------------------------- +class Cert::Private +{ +public: + Private() + { + c = 0; + } + + ~Private() + { + delete c; + } + + QCA_CertContext *c; +}; + +Cert::Cert() +{ + d = new Private; + d->c = (QCA_CertContext *)getContext(CAP_X509); +} + +Cert::Cert(const Cert &from) +{ + d = new Private; + *this = from; +} + +Cert & Cert::operator=(const Cert &from) +{ + delete d->c; + d->c = from.d->c->clone(); + return *this; +} + +Cert::~Cert() +{ + delete d; +} + +void Cert::fromContext(QCA_CertContext *ctx) +{ + delete d->c; + d->c = ctx; +} + +bool Cert::isNull() const +{ + return d->c->isNull(); +} + +QString Cert::commonName() const +{ + CertProperties props = subject(); + return props["CN"]; +} + +QString Cert::serialNumber() const +{ + return d->c->serialNumber(); +} + +QString Cert::subjectString() const +{ + return d->c->subjectString(); +} + +QString Cert::issuerString() const +{ + return d->c->issuerString(); +} + +CertProperties Cert::subject() const +{ + QValueList<QCA_CertProperty> list = d->c->subject(); + CertProperties props; + for(QValueList<QCA_CertProperty>::ConstIterator it = list.begin(); it != list.end(); ++it) + props[(*it).var] = (*it).val; + return props; +} + +CertProperties Cert::issuer() const +{ + QValueList<QCA_CertProperty> list = d->c->issuer(); + CertProperties props; + for(QValueList<QCA_CertProperty>::ConstIterator it = list.begin(); it != list.end(); ++it) + props[(*it).var] = (*it).val; + return props; +} + +QDateTime Cert::notBefore() const +{ + return d->c->notBefore(); +} + +QDateTime Cert::notAfter() const +{ + return d->c->notAfter(); +} + +QByteArray Cert::toDER() const +{ + QByteArray out; + if(!d->c->toDER(&out)) + return QByteArray(); + return out; +} + +bool Cert::fromDER(const QByteArray &a) +{ + return d->c->createFromDER(a.data(), a.size()); +} + +QString Cert::toPEM() const +{ + QByteArray out; + if(!d->c->toPEM(&out)) + return QByteArray(); + + QCString cs; + cs.resize(out.size()+1); + memcpy(cs.data(), out.data(), out.size()); + return QString::fromLatin1(cs); +} + +bool Cert::fromPEM(const QString &str) +{ + QCString cs = str.latin1(); + QByteArray a(cs.length()); + memcpy(a.data(), cs.data(), a.size()); + return d->c->createFromPEM(a.data(), a.size()); +} + + +//---------------------------------------------------------------------------- +// TLS +//---------------------------------------------------------------------------- +class TLS::Private +{ +public: + Private() + { + c = (QCA_TLSContext *)getContext(CAP_TLS); + } + + ~Private() + { + delete c; + } + + void reset() + { + handshaken = false; + closing = false; + in.resize(0); + out.resize(0); + from_net.resize(0); + to_net.resize(0); + host = ""; + hostMismatch = false; + cert = Cert(); + bytesEncoded = 0; + tryMore = false; + } + + void appendArray(QByteArray *a, const QByteArray &b) + { + int oldsize = a->size(); + a->resize(oldsize + b.size()); + memcpy(a->data() + oldsize, b.data(), b.size()); + } + + Cert cert; + QCA_TLSContext *c; + QByteArray in, out, to_net, from_net; + int bytesEncoded; + bool tryMore; + bool handshaken; + QString host; + bool hostMismatch; + bool closing; + + Cert ourCert; + RSAKey ourKey; + QPtrList<QCA_CertContext> store; +}; + +TLS::TLS(QObject *parent) +:QObject(parent) +{ + d = new Private; +} + +TLS::~TLS() +{ + delete d; +} + +void TLS::setCertificate(const Cert &cert, const RSAKey &key) +{ + d->ourCert = cert; + d->ourKey = key; +} + +void TLS::setCertificateStore(const QPtrList<Cert> &store) +{ + // convert the cert list into a context list + d->store.clear(); + QPtrListIterator<Cert> it(store); + for(Cert *cert; (cert = it.current()); ++it) + d->store.append(cert->d->c); +} + +void TLS::reset() +{ + d->reset(); +} + +bool TLS::startClient(const QString &host) +{ + d->reset(); + d->host = host; + + if(!d->c->startClient(d->store, *d->ourCert.d->c, *d->ourKey.d->c)) + return false; + QTimer::singleShot(0, this, SLOT(update())); + return true; +} + +bool TLS::startServer() +{ + d->reset(); + + if(!d->c->startServer(d->store, *d->ourCert.d->c, *d->ourKey.d->c)) + return false; + QTimer::singleShot(0, this, SLOT(update())); + return true; +} + +void TLS::close() +{ + if(!d->handshaken || d->closing) + return; + + d->closing = true; + QTimer::singleShot(0, this, SLOT(update())); +} + +bool TLS::isHandshaken() const +{ + return d->handshaken; +} + +void TLS::write(const QByteArray &a) +{ + d->appendArray(&d->out, a); + update(); +} + +QByteArray TLS::read() +{ + QByteArray a = d->in.copy(); + d->in.resize(0); + return a; +} + +void TLS::writeIncoming(const QByteArray &a) +{ + d->appendArray(&d->from_net, a); + update(); +} + +QByteArray TLS::readOutgoing() +{ + QByteArray a = d->to_net.copy(); + d->to_net.resize(0); + return a; +} + +QByteArray TLS::readUnprocessed() +{ + QByteArray a = d->from_net.copy(); + d->from_net.resize(0); + return a; +} + +const Cert & TLS::peerCertificate() const +{ + return d->cert; +} + +int TLS::certificateValidityResult() const +{ + if(d->hostMismatch) + return QCA::TLS::HostMismatch; + else + return d->c->validityResult(); +} + +void TLS::update() +{ + bool force_read = false; + bool eof = false; + bool done = false; + QGuardedPtr<TLS> self = this; + + if(d->closing) { + QByteArray a; + int r = d->c->shutdown(d->from_net, &a); + d->from_net.resize(0); + if(r == QCA_TLSContext::Error) { + reset(); + error(ErrHandshake); + return; + } + if(r == QCA_TLSContext::Success) { + d->from_net = d->c->unprocessed().copy(); + done = true; + } + d->appendArray(&d->to_net, a); + } + else { + if(!d->handshaken) { + QByteArray a; + int r = d->c->handshake(d->from_net, &a); + d->from_net.resize(0); + if(r == QCA_TLSContext::Error) { + reset(); + error(ErrHandshake); + return; + } + d->appendArray(&d->to_net, a); + if(r == QCA_TLSContext::Success) { + QCA_CertContext *cc = d->c->peerCertificate(); + if(cc && !d->host.isEmpty() && d->c->validityResult() == QCA::TLS::Valid) { + if(!cc->matchesAddress(d->host)) + d->hostMismatch = true; + } + d->cert.fromContext(cc); + d->handshaken = true; + handshaken(); + if(!self) + return; + + // there is a teeny tiny possibility that incoming data awaits. let us get it. + force_read = true; + } + } + + if(d->handshaken) { + if(!d->out.isEmpty() || d->tryMore) { + d->tryMore = false; + QByteArray a; + int enc; + bool more = false; + bool ok = d->c->encode(d->out, &a, &enc); + eof = d->c->eof(); + if(ok && enc < (int)d->out.size()) + more = true; + d->out.resize(0); + if(!eof) { + if(!ok) { + reset(); + error(ErrCrypt); + return; + } + d->bytesEncoded += enc; + if(more) + d->tryMore = true; + d->appendArray(&d->to_net, a); + } + } + if(!d->from_net.isEmpty() || force_read) { + QByteArray a, b; + bool ok = d->c->decode(d->from_net, &a, &b); + eof = d->c->eof(); + d->from_net.resize(0); + if(!ok) { + reset(); + error(ErrCrypt); + return; + } + d->appendArray(&d->in, a); + d->appendArray(&d->to_net, b); + } + + if(!d->in.isEmpty()) { + readyRead(); + if(!self) + return; + } + } + } + + if(!d->to_net.isEmpty()) { + int bytes = d->bytesEncoded; + d->bytesEncoded = 0; + readyReadOutgoing(bytes); + if(!self) + return; + } + + if(eof) { + close(); + if(!self) + return; + return; + } + + if(d->closing && done) { + reset(); + closed(); + } +} + + +//---------------------------------------------------------------------------- +// SASL +//---------------------------------------------------------------------------- +QString saslappname = "qca"; +class SASL::Private +{ +public: + Private() + { + c = (QCA_SASLContext *)getContext(CAP_SASL); + } + + ~Private() + { + delete c; + } + + void setSecurityProps() + { + c->setSecurityProps(noPlain, noActive, noDict, noAnon, reqForward, reqCreds, reqMutual, ssfmin, ssfmax, ext_authid, ext_ssf); + } + + // security opts + bool noPlain, noActive, noDict, noAnon, reqForward, reqCreds, reqMutual; + int ssfmin, ssfmax; + QString ext_authid; + int ext_ssf; + + bool tried; + QCA_SASLContext *c; + QHostAddress localAddr, remoteAddr; + int localPort, remotePort; + QByteArray stepData; + bool allowCSF; + bool first, server; + + QByteArray inbuf, outbuf; +}; + +SASL::SASL(QObject *parent) +:QObject(parent) +{ + d = new Private; + reset(); +} + +SASL::~SASL() +{ + delete d; +} + +void SASL::setAppName(const QString &name) +{ + saslappname = name; +} + +void SASL::reset() +{ + d->localPort = -1; + d->remotePort = -1; + + d->noPlain = false; + d->noActive = false; + d->noDict = false; + d->noAnon = false; + d->reqForward = false; + d->reqCreds = false; + d->reqMutual = false; + d->ssfmin = 0; + d->ssfmax = 0; + d->ext_authid = ""; + d->ext_ssf = 0; + + d->inbuf.resize(0); + d->outbuf.resize(0); + + d->c->reset(); +} + +int SASL::errorCondition() const +{ + return d->c->errorCond(); +} + +void SASL::setAllowPlain(bool b) +{ + d->noPlain = !b; +} + +void SASL::setAllowAnonymous(bool b) +{ + d->noAnon = !b; +} + +void SASL::setAllowActiveVulnerable(bool b) +{ + d->noActive = !b; +} + +void SASL::setAllowDictionaryVulnerable(bool b) +{ + d->noDict = !b; +} + +void SASL::setRequireForwardSecrecy(bool b) +{ + d->reqForward = b; +} + +void SASL::setRequirePassCredentials(bool b) +{ + d->reqCreds = b; +} + +void SASL::setRequireMutualAuth(bool b) +{ + d->reqMutual = b; +} + +void SASL::setMinimumSSF(int x) +{ + d->ssfmin = x; +} + +void SASL::setMaximumSSF(int x) +{ + d->ssfmax = x; +} + +void SASL::setExternalAuthID(const QString &authid) +{ + d->ext_authid = authid; +} + +void SASL::setExternalSSF(int x) +{ + d->ext_ssf = x; +} + +void SASL::setLocalAddr(const QHostAddress &addr, Q_UINT16 port) +{ + d->localAddr = addr; + d->localPort = port; +} + +void SASL::setRemoteAddr(const QHostAddress &addr, Q_UINT16 port) +{ + d->remoteAddr = addr; + d->remotePort = port; +} + +bool SASL::startClient(const QString &service, const QString &host, const QStringList &mechlist, bool allowClientSendFirst) +{ + QCA_SASLHostPort la, ra; + if(d->localPort != -1) { + la.addr = d->localAddr; + la.port = d->localPort; + } + if(d->remotePort != -1) { + ra.addr = d->remoteAddr; + ra.port = d->remotePort; + } + + d->allowCSF = allowClientSendFirst; + d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0); + d->setSecurityProps(); + + if(!d->c->clientStart(mechlist)) + return false; + d->first = true; + d->server = false; + d->tried = false; + QTimer::singleShot(0, this, SLOT(tryAgain())); + return true; +} + +bool SASL::startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist) +{ + QCA_SASLHostPort la, ra; + if(d->localPort != -1) { + la.addr = d->localAddr; + la.port = d->localPort; + } + if(d->remotePort != -1) { + ra.addr = d->remoteAddr; + ra.port = d->remotePort; + } + + d->c->setCoreProps(service, host, d->localPort != -1 ? &la : 0, d->remotePort != -1 ? &ra : 0); + d->setSecurityProps(); + + if(!d->c->serverStart(realm, mechlist, saslappname)) + return false; + d->first = true; + d->server = true; + d->tried = false; + return true; +} + +void SASL::putServerFirstStep(const QString &mech) +{ + int r = d->c->serverFirstStep(mech, 0); + handleServerFirstStep(r); +} + +void SASL::putServerFirstStep(const QString &mech, const QByteArray &clientInit) +{ + int r = d->c->serverFirstStep(mech, &clientInit); + handleServerFirstStep(r); +} + +void SASL::handleServerFirstStep(int r) +{ + if(r == QCA_SASLContext::Success) + authenticated(); + else if(r == QCA_SASLContext::Continue) + nextStep(d->c->result()); + else if(r == QCA_SASLContext::AuthCheck) + tryAgain(); + else + error(ErrAuth); +} + +void SASL::putStep(const QByteArray &stepData) +{ + d->stepData = stepData.copy(); + tryAgain(); +} + +void SASL::setUsername(const QString &user) +{ + d->c->setClientParams(&user, 0, 0, 0); +} + +void SASL::setAuthzid(const QString &authzid) +{ + d->c->setClientParams(0, &authzid, 0, 0); +} + +void SASL::setPassword(const QString &pass) +{ + d->c->setClientParams(0, 0, &pass, 0); +} + +void SASL::setRealm(const QString &realm) +{ + d->c->setClientParams(0, 0, 0, &realm); +} + +void SASL::continueAfterParams() +{ + tryAgain(); +} + +void SASL::continueAfterAuthCheck() +{ + tryAgain(); +} + +void SASL::tryAgain() +{ + int r; + + if(d->server) { + if(!d->tried) { + r = d->c->nextStep(d->stepData); + d->tried = true; + } + else { + r = d->c->tryAgain(); + } + + if(r == QCA_SASLContext::Error) { + error(ErrAuth); + return; + } + else if(r == QCA_SASLContext::Continue) { + d->tried = false; + nextStep(d->c->result()); + return; + } + else if(r == QCA_SASLContext::AuthCheck) { + authCheck(d->c->username(), d->c->authzid()); + return; + } + } + else { + if(d->first) { + if(!d->tried) { + r = d->c->clientFirstStep(d->allowCSF); + d->tried = true; + } + else + r = d->c->tryAgain(); + + if(r == QCA_SASLContext::Error) { + error(ErrAuth); + return; + } + else if(r == QCA_SASLContext::NeedParams) { + //d->tried = false; + QCA_SASLNeedParams np = d->c->clientParamsNeeded(); + needParams(np.user, np.authzid, np.pass, np.realm); + return; + } + + QString mech = d->c->mech(); + const QByteArray *clientInit = d->c->clientInit(); + + d->first = false; + d->tried = false; + clientFirstStep(mech, clientInit); + } + else { + if(!d->tried) { + r = d->c->nextStep(d->stepData); + d->tried = true; + } + else + r = d->c->tryAgain(); + + if(r == QCA_SASLContext::Error) { + error(ErrAuth); + return; + } + else if(r == QCA_SASLContext::NeedParams) { + //d->tried = false; + QCA_SASLNeedParams np = d->c->clientParamsNeeded(); + needParams(np.user, np.authzid, np.pass, np.realm); + return; + } + d->tried = false; + //else if(r == QCA_SASLContext::Continue) { + nextStep(d->c->result()); + // return; + //} + } + } + + if(r == QCA_SASLContext::Success) + authenticated(); + else if(r == QCA_SASLContext::Error) + error(ErrAuth); +} + +int SASL::ssf() const +{ + return d->c->security(); +} + +void SASL::write(const QByteArray &a) +{ + QByteArray b; + if(!d->c->encode(a, &b)) { + error(ErrCrypt); + return; + } + int oldsize = d->outbuf.size(); + d->outbuf.resize(oldsize + b.size()); + memcpy(d->outbuf.data() + oldsize, b.data(), b.size()); + readyReadOutgoing(a.size()); +} + +QByteArray SASL::read() +{ + QByteArray a = d->inbuf.copy(); + d->inbuf.resize(0); + return a; +} + +void SASL::writeIncoming(const QByteArray &a) +{ + QByteArray b; + if(!d->c->decode(a, &b)) { + error(ErrCrypt); + return; + } + int oldsize = d->inbuf.size(); + d->inbuf.resize(oldsize + b.size()); + memcpy(d->inbuf.data() + oldsize, b.data(), b.size()); + readyRead(); +} + +QByteArray SASL::readOutgoing() +{ + QByteArray a = d->outbuf.copy(); + d->outbuf.resize(0); + return a; +} + +#include "qca.moc" diff --git a/kopete/protocols/jabber/libiris/qca/src/qca.h b/kopete/protocols/jabber/libiris/qca/src/qca.h new file mode 100644 index 00000000..e7cd1609 --- /dev/null +++ b/kopete/protocols/jabber/libiris/qca/src/qca.h @@ -0,0 +1,466 @@ +/* + * qca.h - Qt Cryptographic Architecture + * Copyright (C) 2003 Justin Karneges + * + * 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 + * + */ + +#ifndef QCA_H +#define QCA_H + +#include<qstring.h> +#include<qcstring.h> +#include<qdatetime.h> +#include<qmap.h> +#include<qptrlist.h> +#include<qobject.h> + +#ifdef Q_OS_WIN32 +# ifndef QCA_STATIC +# ifdef QCA_MAKEDLL +# define QCA_EXPORT __declspec(dllexport) +# else +# define QCA_EXPORT __declspec(dllimport) +# endif +# endif +#endif +#ifndef QCA_EXPORT +#define QCA_EXPORT +#endif + +#ifdef Q_OS_WIN32 +# ifdef QCA_PLUGIN_DLL +# define QCA_PLUGIN_EXPORT extern "C" __declspec(dllexport) +# else +# define QCA_PLUGIN_EXPORT extern "C" __declspec(dllimport) +# endif +#endif +#ifndef QCA_PLUGIN_EXPORT +#define QCA_PLUGIN_EXPORT extern "C" +#endif + +class QHostAddress; +class QStringList; + +class QCAProvider; +class QCA_HashContext; +class QCA_CipherContext; +class QCA_CertContext; + +namespace QCA +{ + enum { + CAP_SHA1 = 0x0001, + CAP_SHA256 = 0x0002, + CAP_MD5 = 0x0004, + CAP_BlowFish = 0x0008, + CAP_TripleDES = 0x0010, + CAP_AES128 = 0x0020, + CAP_AES256 = 0x0040, + CAP_RSA = 0x0080, + CAP_X509 = 0x0100, + CAP_TLS = 0x0200, + CAP_SASL = 0x0400 + }; + + enum { + CBC = 0x0001, + CFB = 0x0002 + }; + + enum { + Encrypt = 0x0001, + Decrypt = 0x0002 + }; + + QCA_EXPORT void init(); + QCA_EXPORT bool isSupported(int capabilities); + QCA_EXPORT void insertProvider(QCAProvider *); + QCA_EXPORT void unloadAllPlugins(); + + QCA_EXPORT QString arrayToHex(const QByteArray &); + QCA_EXPORT QByteArray hexToArray(const QString &); + + class QCA_EXPORT Hash + { + public: + Hash(const Hash &); + Hash & operator=(const Hash &); + ~Hash(); + + void clear(); + void update(const QByteArray &a); + QByteArray final(); + + protected: + Hash(QCA_HashContext *); + + private: + class Private; + Private *d; + }; + + template <class T> + class QCA_EXPORT HashStatic + { + public: + HashStatic<T>() {} + + static QByteArray hash(const QByteArray &a) + { + T obj; + obj.update(a); + return obj.final(); + } + + static QByteArray hash(const QCString &cs) + { + QByteArray a(cs.length()); + memcpy(a.data(), cs.data(), a.size()); + return hash(a); + } + + static QString hashToString(const QByteArray &a) + { + return arrayToHex(hash(a)); + } + + static QString hashToString(const QCString &cs) + { + return arrayToHex(hash(cs)); + } + }; + + class QCA_EXPORT Cipher + { + public: + Cipher(const Cipher &); + Cipher & operator=(const Cipher &); + ~Cipher(); + + QByteArray dyn_generateKey(int size=-1) const; + QByteArray dyn_generateIV() const; + void reset(int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad=true); + bool update(const QByteArray &a); + QByteArray final(bool *ok=0); + + protected: + Cipher(QCA_CipherContext *, int dir, int mode, const QByteArray &key, const QByteArray &iv, bool pad); + + private: + class Private; + Private *d; + }; + + template <class T> + class QCA_EXPORT CipherStatic + { + public: + CipherStatic<T>() {} + + static QByteArray generateKey(int size=-1) + { + T obj; + return obj.dyn_generateKey(size); + } + + static QByteArray generateIV() + { + T obj; + return obj.dyn_generateIV(); + } + }; + + class QCA_EXPORT SHA1 : public Hash, public HashStatic<SHA1> + { + public: + SHA1(); + }; + + class QCA_EXPORT SHA256 : public Hash, public HashStatic<SHA256> + { + public: + SHA256(); + }; + + class QCA_EXPORT MD5 : public Hash, public HashStatic<MD5> + { + public: + MD5(); + }; + + class QCA_EXPORT BlowFish : public Cipher, public CipherStatic<BlowFish> + { + public: + BlowFish(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true); + }; + + class QCA_EXPORT TripleDES : public Cipher, public CipherStatic<TripleDES> + { + public: + TripleDES(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true); + }; + + class QCA_EXPORT AES128 : public Cipher, public CipherStatic<AES128> + { + public: + AES128(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true); + }; + + class QCA_EXPORT AES256 : public Cipher, public CipherStatic<AES256> + { + public: + AES256(int dir=Encrypt, int mode=CBC, const QByteArray &key=QByteArray(), const QByteArray &iv=QByteArray(), bool pad=true); + }; + + class RSA; + class QCA_EXPORT RSAKey + { + public: + RSAKey(); + RSAKey(const RSAKey &from); + RSAKey & operator=(const RSAKey &from); + ~RSAKey(); + + bool isNull() const; + bool havePublic() const; + bool havePrivate() const; + + QByteArray toDER(bool publicOnly=false) const; + bool fromDER(const QByteArray &a); + + QString toPEM(bool publicOnly=false) const; + bool fromPEM(const QString &); + + // only call if you know what you are doing + bool fromNative(void *); + + private: + class Private; + Private *d; + + friend class RSA; + friend class TLS; + bool encrypt(const QByteArray &a, QByteArray *out, bool oaep) const; + bool decrypt(const QByteArray &a, QByteArray *out, bool oaep) const; + bool generate(unsigned int bits); + }; + + class QCA_EXPORT RSA + { + public: + RSA(); + ~RSA(); + + RSAKey key() const; + void setKey(const RSAKey &); + + bool encrypt(const QByteArray &a, QByteArray *out, bool oaep=false) const; + bool decrypt(const QByteArray &a, QByteArray *out, bool oaep=false) const; + + static RSAKey generateKey(unsigned int bits); + + private: + RSAKey v_key; + }; + + typedef QMap<QString, QString> CertProperties; + class QCA_EXPORT Cert + { + public: + Cert(); + Cert(const Cert &); + Cert & operator=(const Cert &); + ~Cert(); + + bool isNull() const; + + QString commonName() const; + QString serialNumber() const; + QString subjectString() const; + QString issuerString() const; + CertProperties subject() const; + CertProperties issuer() const; + QDateTime notBefore() const; + QDateTime notAfter() const; + + QByteArray toDER() const; + bool fromDER(const QByteArray &a); + + QString toPEM() const; + bool fromPEM(const QString &); + + private: + class Private; + Private *d; + + friend class TLS; + void fromContext(QCA_CertContext *); + }; + + class QCA_EXPORT TLS : public QObject + { + Q_OBJECT + public: + enum Validity { + NoCert, + Valid, + HostMismatch, + Rejected, + Untrusted, + SignatureFailed, + InvalidCA, + InvalidPurpose, + SelfSigned, + Revoked, + PathLengthExceeded, + Expired, + Unknown + }; + enum Error { ErrHandshake, ErrCrypt }; + + TLS(QObject *parent=0); + ~TLS(); + + void setCertificate(const Cert &cert, const RSAKey &key); + void setCertificateStore(const QPtrList<Cert> &store); // note: store must persist + + void reset(); + bool startClient(const QString &host=""); + bool startServer(); + void close(); + bool isHandshaken() const; + + // plain (application side) + void write(const QByteArray &a); + QByteArray read(); + + // encoded (socket side) + void writeIncoming(const QByteArray &a); + QByteArray readOutgoing(); + QByteArray readUnprocessed(); + + // cert related + const Cert & peerCertificate() const; + int certificateValidityResult() const; + + signals: + void handshaken(); + void readyRead(); + void readyReadOutgoing(int plainBytes); + void closed(); + void error(int); + + private slots: + void update(); + + private: + class Private; + Private *d; + }; + + class QCA_EXPORT SASL : public QObject + { + Q_OBJECT + public: + enum Error { ErrAuth, ErrCrypt }; + enum ErrorCond { + NoMech, + BadProto, + BadServ, + BadAuth, + NoAuthzid, + TooWeak, + NeedEncrypt, + Expired, + Disabled, + NoUser, + RemoteUnavail + }; + SASL(QObject *parent=0); + ~SASL(); + + static void setAppName(const QString &name); + + void reset(); + int errorCondition() const; + + // options + void setAllowPlain(bool); + void setAllowAnonymous(bool); + void setAllowActiveVulnerable(bool); + void setAllowDictionaryVulnerable(bool); + void setRequireForwardSecrecy(bool); + void setRequirePassCredentials(bool); + void setRequireMutualAuth(bool); + + void setMinimumSSF(int); + void setMaximumSSF(int); + void setExternalAuthID(const QString &authid); + void setExternalSSF(int); + + void setLocalAddr(const QHostAddress &addr, Q_UINT16 port); + void setRemoteAddr(const QHostAddress &addr, Q_UINT16 port); + + // initialize + bool startClient(const QString &service, const QString &host, const QStringList &mechlist, bool allowClientSendFirst=true); + bool startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist); + + // authentication + void putStep(const QByteArray &stepData); + void putServerFirstStep(const QString &mech); + void putServerFirstStep(const QString &mech, const QByteArray &clientInit); + void setUsername(const QString &user); + void setAuthzid(const QString &auth); + void setPassword(const QString &pass); + void setRealm(const QString &realm); + void continueAfterParams(); + void continueAfterAuthCheck(); + + // security layer + int ssf() const; + void write(const QByteArray &a); + QByteArray read(); + void writeIncoming(const QByteArray &a); + QByteArray readOutgoing(); + + signals: + // for authentication + void clientFirstStep(const QString &mech, const QByteArray *clientInit); + void nextStep(const QByteArray &stepData); + void needParams(bool user, bool authzid, bool pass, bool realm); + void authCheck(const QString &user, const QString &authzid); + void authenticated(); + + // for security layer + void readyRead(); + void readyReadOutgoing(int plainBytes); + + // error + void error(int); + + private slots: + void tryAgain(); + + private: + class Private; + Private *d; + + void handleServerFirstStep(int r); + }; +} + +#endif diff --git a/kopete/protocols/jabber/libiris/qca/src/qcaprovider.h b/kopete/protocols/jabber/libiris/qca/src/qcaprovider.h new file mode 100644 index 00000000..a7f1805b --- /dev/null +++ b/kopete/protocols/jabber/libiris/qca/src/qcaprovider.h @@ -0,0 +1,191 @@ +/* + * qcaprovider.h - QCA Plugin API + * Copyright (C) 2003 Justin Karneges + * + * 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 + * + */ + +#ifndef QCAPROVIDER_H +#define QCAPROVIDER_H + +#include<qglobal.h> +#include<qstring.h> +#include<qdatetime.h> +#include<qobject.h> +#include<qhostaddress.h> +#include"qca.h" + +#define QCA_PLUGIN_VERSION 1 + +class QCAProvider +{ +public: + QCAProvider() {} + virtual ~QCAProvider() {} + + virtual void init()=0; + virtual int qcaVersion() const=0; + virtual int capabilities() const=0; + virtual void *context(int cap)=0; +}; + +class QCA_HashContext +{ +public: + virtual ~QCA_HashContext() {} + + virtual QCA_HashContext *clone()=0; + virtual void reset()=0; + virtual void update(const char *in, unsigned int len)=0; + virtual void final(QByteArray *out)=0; +}; + +class QCA_CipherContext +{ +public: + virtual ~QCA_CipherContext() {} + + virtual QCA_CipherContext *clone()=0; + virtual int keySize()=0; + virtual int blockSize()=0; + virtual bool generateKey(char *out, int keysize=-1)=0; + virtual bool generateIV(char *out)=0; + + virtual bool setup(int dir, int mode, const char *key, int keysize, const char *iv, bool pad)=0; + virtual bool update(const char *in, unsigned int len)=0; + virtual bool final(QByteArray *out)=0; +}; + +class QCA_RSAKeyContext +{ +public: + virtual ~QCA_RSAKeyContext() {} + + virtual QCA_RSAKeyContext *clone() const=0; + virtual bool isNull() const=0; + virtual bool havePublic() const=0; + virtual bool havePrivate() const=0; + virtual bool createFromDER(const char *in, unsigned int len)=0; + virtual bool createFromPEM(const char *in, unsigned int len)=0; + virtual bool createFromNative(void *in)=0; + virtual bool generate(unsigned int bits)=0; + virtual bool toDER(QByteArray *out, bool publicOnly)=0; + virtual bool toPEM(QByteArray *out, bool publicOnly)=0; + + virtual bool encrypt(const QByteArray &in, QByteArray *out, bool oaep)=0; + virtual bool decrypt(const QByteArray &in, QByteArray *out, bool oaep)=0; +}; + +struct QCA_CertProperty +{ + QString var; + QString val; +}; + +class QCA_CertContext +{ +public: + virtual ~QCA_CertContext() {} + + virtual QCA_CertContext *clone() const=0; + virtual bool isNull() const=0; + virtual bool createFromDER(const char *in, unsigned int len)=0; + virtual bool createFromPEM(const char *in, unsigned int len)=0; + virtual bool toDER(QByteArray *out)=0; + virtual bool toPEM(QByteArray *out)=0; + + virtual QString serialNumber() const=0; + virtual QString subjectString() const=0; + virtual QString issuerString() const=0; + virtual QValueList<QCA_CertProperty> subject() const=0; + virtual QValueList<QCA_CertProperty> issuer() const=0; + virtual QDateTime notBefore() const=0; + virtual QDateTime notAfter() const=0; + virtual bool matchesAddress(const QString &realHost) const=0; +}; + +class QCA_TLSContext +{ +public: + enum Result { Success, Error, Continue }; + virtual ~QCA_TLSContext() {} + + virtual void reset()=0; + virtual bool startClient(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &cert, const QCA_RSAKeyContext &key)=0; + virtual bool startServer(const QPtrList<QCA_CertContext> &store, const QCA_CertContext &cert, const QCA_RSAKeyContext &key)=0; + + virtual int handshake(const QByteArray &in, QByteArray *out)=0; + virtual int shutdown(const QByteArray &in, QByteArray *out)=0; + virtual bool encode(const QByteArray &plain, QByteArray *to_net, int *encoded)=0; + virtual bool decode(const QByteArray &from_net, QByteArray *plain, QByteArray *to_net)=0; + virtual bool eof() const=0; + virtual QByteArray unprocessed()=0; + + virtual QCA_CertContext *peerCertificate() const=0; + virtual int validityResult() const=0; +}; + +struct QCA_SASLHostPort +{ + QHostAddress addr; + Q_UINT16 port; +}; + +struct QCA_SASLNeedParams +{ + bool user, authzid, pass, realm; +}; + +class QCA_SASLContext +{ +public: + enum Result { Success, Error, NeedParams, AuthCheck, Continue }; + virtual ~QCA_SASLContext() {} + + // common + virtual void reset()=0; + virtual void setCoreProps(const QString &service, const QString &host, QCA_SASLHostPort *local, QCA_SASLHostPort *remote)=0; + virtual void setSecurityProps(bool noPlain, bool noActive, bool noDict, bool noAnon, bool reqForward, bool reqCreds, bool reqMutual, int ssfMin, int ssfMax, const QString &_ext_authid, int _ext_ssf)=0; + virtual int security() const=0; + virtual int errorCond() const=0; + + // init / first step + virtual bool clientStart(const QStringList &mechlist)=0; + virtual int clientFirstStep(bool allowClientSendFirst)=0; + virtual bool serverStart(const QString &realm, QStringList *mechlist, const QString &name)=0; + virtual int serverFirstStep(const QString &mech, const QByteArray *in)=0; + + // get / set params + virtual QCA_SASLNeedParams clientParamsNeeded() const=0; + virtual void setClientParams(const QString *user, const QString *authzid, const QString *pass, const QString *realm)=0; + virtual QString username() const=0; + virtual QString authzid() const=0; + + // continue steps + virtual int nextStep(const QByteArray &in)=0; + virtual int tryAgain()=0; + + // results + virtual QString mech() const=0; + virtual const QByteArray *clientInit() const=0; + virtual QByteArray result() const=0; + + // security layer + virtual bool encode(const QByteArray &in, QByteArray *out)=0; + virtual bool decode(const QByteArray &in, QByteArray *out)=0; +}; + +#endif |