2004-11-05 08:54:01 +00:00
|
|
|
/*
|
|
|
|
* qca_securelayer.cpp - Qt Cryptographic Architecture
|
|
|
|
* Copyright (C) 2004 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 <qtimer.h>
|
|
|
|
#include <qhostaddress.h>
|
|
|
|
#include <qguardedptr.h>
|
|
|
|
#include "qcaprovider.h"
|
|
|
|
|
|
|
|
namespace QCA {
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// SecureFilter
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
SecureFilter::~SecureFilter()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SecureFilter::isClosable() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SecureFilter::haveClosed() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SecureFilter::close()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QSecureArray SecureFilter::readUnprocessed()
|
|
|
|
{
|
|
|
|
return QSecureArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// SecureLayer
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
SecureLayer::SecureLayer(QObject *parent, const char *name)
|
|
|
|
:QObject(parent, name)
|
|
|
|
{
|
2004-11-17 00:28:34 +00:00
|
|
|
_signals = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SecureLayer::setStatefulOnly(bool b)
|
|
|
|
{
|
|
|
|
_signals = !b;
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SecureLayer::layerUpdateBegin()
|
|
|
|
{
|
|
|
|
_read = bytesAvailable();
|
|
|
|
_readout = bytesOutgoingAvailable();
|
|
|
|
_closed = haveClosed();
|
|
|
|
_error = haveError();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SecureLayer::layerUpdateEnd()
|
|
|
|
{
|
2004-11-17 00:28:34 +00:00
|
|
|
if(_signals)
|
|
|
|
{
|
|
|
|
if(_read > bytesAvailable())
|
|
|
|
QTimer::singleShot(0, this, SIGNAL(readyRead()));
|
|
|
|
if(_readout > bytesOutgoingAvailable())
|
|
|
|
QTimer::singleShot(0, this, SIGNAL(readyReadOutgoing()));
|
|
|
|
if(!_closed && haveClosed())
|
|
|
|
QTimer::singleShot(0, this, SIGNAL(closed()));
|
|
|
|
if(!_error && haveError())
|
|
|
|
QTimer::singleShot(0, this, SIGNAL(error()));
|
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// TLS
|
|
|
|
//----------------------------------------------------------------------------
|
2004-11-07 11:40:11 +00:00
|
|
|
class TLS::Private
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
Private()
|
|
|
|
{
|
|
|
|
store = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset()
|
|
|
|
{
|
|
|
|
handshaken = false;
|
|
|
|
closing = false;
|
|
|
|
in.resize(0);
|
|
|
|
out.resize(0);
|
|
|
|
from_net.resize(0);
|
|
|
|
to_net.resize(0);
|
2004-12-31 04:21:08 +00:00
|
|
|
host = QString();
|
2004-11-05 08:54:01 +00:00
|
|
|
hostMismatch = false;
|
|
|
|
cert = Certificate();
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
|
|
|
Certificate cert;
|
|
|
|
CertValidity certValidity;
|
|
|
|
TLSContext *c;
|
|
|
|
QByteArray in, out, to_net, from_net;
|
|
|
|
int bytesEncoded;
|
|
|
|
bool tryMore;
|
|
|
|
bool handshaken;
|
|
|
|
QString host;
|
|
|
|
bool hostMismatch;
|
|
|
|
bool closing;
|
|
|
|
Error errorCode;
|
|
|
|
|
|
|
|
Certificate ourCert;
|
|
|
|
PrivateKey ourKey;
|
|
|
|
Store *store;
|
|
|
|
};
|
|
|
|
|
|
|
|
TLS::TLS(QObject *parent, const char *name, const QString &provider)
|
2004-11-07 11:40:11 +00:00
|
|
|
:SecureLayer(parent, name), Algorithm("tls", provider)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
d = new Private;
|
|
|
|
d->c = (TLSContext *)context();
|
|
|
|
}
|
|
|
|
|
|
|
|
TLS::~TLS()
|
|
|
|
{
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TLS::setCertificate(const Certificate &cert, const PrivateKey &key)
|
|
|
|
{
|
|
|
|
d->ourCert = cert;
|
|
|
|
d->ourKey = key;
|
|
|
|
}
|
|
|
|
|
2004-11-07 11:40:11 +00:00
|
|
|
void TLS::setStore(const Store &store)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-07 11:40:11 +00:00
|
|
|
d->store = new Store(store);
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
void TLS::setConstraints(SecurityLevel s)
|
|
|
|
{
|
|
|
|
Q_UNUSED(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TLS::setConstraints(int, int)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void TLS::setCompressionEnabled(bool b)
|
|
|
|
{
|
|
|
|
Q_UNUSED(b);
|
|
|
|
}
|
|
|
|
|
2004-11-05 08:54:01 +00:00
|
|
|
void TLS::reset()
|
|
|
|
{
|
|
|
|
d->reset();
|
|
|
|
// TODO: d->c->reset ??
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TLS::startClient(const QString &host)
|
|
|
|
{
|
|
|
|
d->reset();
|
|
|
|
d->host = host;
|
|
|
|
|
2004-11-07 11:40:11 +00:00
|
|
|
if(!d->c->startClient(*((StoreContext *)d->store->context()), *((CertContext *)d->ourCert.context()), *((PKeyContext *)d->ourKey.context())))
|
2004-11-05 08:54:01 +00:00
|
|
|
return false;
|
|
|
|
QTimer::singleShot(0, this, SLOT(update()));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TLS::startServer()
|
|
|
|
{
|
|
|
|
d->reset();
|
|
|
|
|
2004-11-07 11:40:11 +00:00
|
|
|
if(!d->c->startServer(*((StoreContext *)d->store->context()), *((CertContext *)d->ourCert.context()), *((PKeyContext *)d->ourKey.context())))
|
2004-11-05 08:54:01 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
QString TLS::cipherName() const
|
|
|
|
{
|
2004-12-31 04:21:08 +00:00
|
|
|
return QString();
|
2004-11-17 00:28:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int TLS::cipherBits() const
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-11-05 08:54:01 +00:00
|
|
|
TLS::Error TLS::errorCode() const
|
|
|
|
{
|
|
|
|
return d->errorCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TLS::isClosable() const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2004-11-07 11:40:11 +00:00
|
|
|
bool TLS::haveClosed() const
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-07 11:40:11 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TLS::haveError() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TLS::bytesAvailable() const
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TLS::bytesOutgoingAvailable() const
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TLS::write(const QSecureArray &a)
|
|
|
|
{
|
|
|
|
d->appendArray(&d->out, a.toByteArray());
|
2004-11-13 10:13:12 +00:00
|
|
|
//update();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-07 11:40:11 +00:00
|
|
|
QSecureArray TLS::read()
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
QByteArray a = d->in.copy();
|
|
|
|
d->in.resize(0);
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TLS::writeIncoming(const QByteArray &a)
|
|
|
|
{
|
|
|
|
d->appendArray(&d->from_net, a);
|
2004-11-13 10:13:12 +00:00
|
|
|
//update();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
QByteArray TLS::readOutgoing(int *plainBytes)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
Q_UNUSED(plainBytes);
|
2004-11-05 08:54:01 +00:00
|
|
|
QByteArray a = d->to_net.copy();
|
|
|
|
d->to_net.resize(0);
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2004-11-07 11:40:11 +00:00
|
|
|
QSecureArray TLS::readUnprocessed()
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
QByteArray a = d->from_net.copy();
|
|
|
|
d->from_net.resize(0);
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
TLS::IdentityResult TLS::peerIdentityResult() const
|
|
|
|
{
|
|
|
|
if(d->cert.isNull())
|
|
|
|
return NoCert;
|
|
|
|
|
|
|
|
if(d->certValidity != QCA::Valid)
|
|
|
|
return BadCert;
|
|
|
|
|
|
|
|
if(d->hostMismatch)
|
|
|
|
return HostMismatch;
|
|
|
|
|
|
|
|
return Valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
CertValidity TLS::peerCertificateValidity() const
|
|
|
|
{
|
|
|
|
return d->certValidity;
|
|
|
|
}
|
|
|
|
|
|
|
|
Certificate TLS::localCertificate() const
|
|
|
|
{
|
|
|
|
return d->ourCert;
|
|
|
|
}
|
|
|
|
|
|
|
|
Certificate TLS::peerCertificate() const
|
|
|
|
{
|
|
|
|
return d->cert;
|
|
|
|
}
|
2004-11-13 10:13:12 +00:00
|
|
|
#if 0
|
2004-11-05 08:54:01 +00:00
|
|
|
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 == TLSContext::Error) {
|
|
|
|
reset();
|
|
|
|
d->errorCode = ErrHandshake;
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(r == TLSContext::Success) {
|
2004-11-07 11:40:11 +00:00
|
|
|
d->from_net = d->c->unprocessed().toByteArray().copy();
|
2004-11-05 08:54:01 +00:00
|
|
|
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 == TLSContext::Error) {
|
|
|
|
reset();
|
|
|
|
d->errorCode = ErrHandshake;
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
d->appendArray(&d->to_net, a);
|
|
|
|
if(r == TLSContext::Success) {
|
2004-11-07 11:40:11 +00:00
|
|
|
/*Certificate cert = d->c->peerCertificate();
|
2004-11-05 08:54:01 +00:00
|
|
|
d->certValidity = d->c->peerCertificateValidity();
|
|
|
|
if(!cert.isNull() && !d->host.isEmpty() && d->certValidity == QCA::Valid) {
|
|
|
|
if(!cert.matchesAddress(d->host))
|
|
|
|
d->hostMismatch = true;
|
|
|
|
}
|
2004-11-07 11:40:11 +00:00
|
|
|
d->cert = cert;*/
|
2004-11-05 08:54:01 +00:00
|
|
|
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();
|
|
|
|
d->errorCode = ErrCrypt;
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
d->bytesEncoded += enc;
|
|
|
|
if(more)
|
|
|
|
d->tryMore = true;
|
|
|
|
d->appendArray(&d->to_net, a);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(!d->from_net.isEmpty() || force_read) {
|
2004-11-07 11:40:11 +00:00
|
|
|
QSecureArray a;
|
|
|
|
QByteArray b;
|
2004-11-05 08:54:01 +00:00
|
|
|
bool ok = d->c->decode(d->from_net, &a, &b);
|
|
|
|
eof = d->c->eof();
|
|
|
|
d->from_net.resize(0);
|
|
|
|
if(!ok) {
|
|
|
|
reset();
|
|
|
|
d->errorCode = ErrCrypt;
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
2004-11-07 11:40:11 +00:00
|
|
|
d->appendArray(&d->in, a.toByteArray());
|
2004-11-05 08:54:01 +00:00
|
|
|
d->appendArray(&d->to_net, b);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!d->in.isEmpty()) {
|
|
|
|
readyRead();
|
|
|
|
if(!self)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!d->to_net.isEmpty()) {
|
2004-11-07 11:40:11 +00:00
|
|
|
//int bytes = d->bytesEncoded;
|
2004-11-05 08:54:01 +00:00
|
|
|
d->bytesEncoded = 0;
|
2004-11-07 11:40:11 +00:00
|
|
|
readyReadOutgoing();
|
2004-11-05 08:54:01 +00:00
|
|
|
if(!self)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(eof) {
|
|
|
|
close();
|
|
|
|
if(!self)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(d->closing && done) {
|
|
|
|
reset();
|
|
|
|
closed();
|
|
|
|
}
|
|
|
|
}
|
2004-11-13 10:13:12 +00:00
|
|
|
#endif
|
2004-11-05 08:54:01 +00:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// SASL
|
|
|
|
//----------------------------------------------------------------------------
|
2004-11-13 10:13:12 +00:00
|
|
|
QString *saslappname = 0;
|
2004-11-05 08:54:01 +00:00
|
|
|
class SASL::Private
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
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;
|
|
|
|
SASLContext *c;
|
|
|
|
QHostAddress localAddr, remoteAddr;
|
|
|
|
int localPort, remotePort;
|
|
|
|
QByteArray stepData;
|
|
|
|
bool allowCSF;
|
|
|
|
bool first, server;
|
|
|
|
Error errorCode;
|
|
|
|
|
|
|
|
QByteArray inbuf, outbuf;
|
|
|
|
};
|
|
|
|
|
|
|
|
SASL::SASL(QObject *parent, const char *name, const QString &provider)
|
2004-11-13 10:13:12 +00:00
|
|
|
:SecureLayer(parent, name), Algorithm("sasl", provider)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
d = new Private;
|
|
|
|
d->c = (SASLContext *)context();
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
SASL::~SASL()
|
|
|
|
{
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
/*void SASL::setAppName(const QString &name)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
if(!saslappname)
|
|
|
|
saslappname = new QString;
|
|
|
|
*saslappname = name;
|
2004-11-13 10:13:12 +00:00
|
|
|
}*/
|
2004-11-05 08:54:01 +00:00
|
|
|
|
|
|
|
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;
|
2004-12-31 04:21:08 +00:00
|
|
|
d->ext_authid = QString();
|
2004-11-05 08:54:01 +00:00
|
|
|
d->ext_ssf = 0;
|
|
|
|
|
|
|
|
d->inbuf.resize(0);
|
|
|
|
d->outbuf.resize(0);
|
|
|
|
|
|
|
|
d->c->reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
SASL::Error SASL::errorCode() const
|
|
|
|
{
|
|
|
|
return d->errorCode;
|
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
SASL::AuthCondition SASL::authCondition() const
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
return (AuthCondition)d->c->authError();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
void SASL::setConstraints(AuthFlags f, SecurityLevel s)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-17 00:28:34 +00:00
|
|
|
Q_UNUSED(f);
|
|
|
|
Q_UNUSED(s);
|
|
|
|
|
|
|
|
/*d->noPlain = (f & SAllowPlain) ? false: true;
|
2004-11-05 08:54:01 +00:00
|
|
|
d->noAnon = (f & SAllowAnonymous) ? false: true;
|
2004-11-13 10:13:12 +00:00
|
|
|
//d->noActive = (f & SAllowActiveVulnerable) ? false: true;
|
|
|
|
//d->noDict = (f & SAllowDictVulnerable) ? false: true;
|
2004-11-05 08:54:01 +00:00
|
|
|
d->reqForward = (f & SRequireForwardSecrecy) ? true : false;
|
|
|
|
d->reqCreds = (f & SRequirePassCredentials) ? true : false;
|
2004-11-17 00:28:34 +00:00
|
|
|
d->reqMutual = (f & SRequireMutualAuth) ? true : false;*/
|
|
|
|
|
|
|
|
//d->ssfmin = minSSF;
|
|
|
|
//d->ssfmax = maxSSF;
|
|
|
|
}
|
2004-11-05 08:54:01 +00:00
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
void SASL::setConstraints(AuthFlags, int, int)
|
|
|
|
{
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-12-20 08:08:39 +00:00
|
|
|
void SASL::setExternalAuthId(const QString &authid)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
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)
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
SASLContext::HostPort la, ra;
|
2004-11-05 08:54:01 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2004-11-17 00:28:34 +00:00
|
|
|
bool SASL::startServer(const QString &service, const QString &host, const QString &realm, QStringList *mechlist, bool allowServerSendLast)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
2004-11-17 00:28:34 +00:00
|
|
|
Q_UNUSED(allowServerSendLast);
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
SASLContext::HostPort la, ra;
|
2004-11-05 08:54:01 +00:00
|
|
|
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();
|
|
|
|
|
|
|
|
QString appname;
|
|
|
|
if(saslappname)
|
|
|
|
appname = *saslappname;
|
|
|
|
else
|
|
|
|
appname = "qca";
|
|
|
|
|
|
|
|
if(!d->c->serverStart(realm, mechlist, appname))
|
|
|
|
return false;
|
|
|
|
d->first = true;
|
|
|
|
d->server = true;
|
|
|
|
d->tried = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::putServerFirstStep(const QString &mech)
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
/*int r =*/ d->c->serverFirstStep(mech, 0);
|
|
|
|
//handleServerFirstStep(r);
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::putServerFirstStep(const QString &mech, const QByteArray &clientInit)
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
/*int r =*/ d->c->serverFirstStep(mech, &clientInit);
|
|
|
|
//handleServerFirstStep(r);
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
/*void SASL::handleServerFirstStep(int r)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
if(r == SASLContext::Success)
|
|
|
|
authenticated();
|
|
|
|
else if(r == SASLContext::Continue)
|
|
|
|
nextStep(d->c->result());
|
|
|
|
else if(r == SASLContext::AuthCheck)
|
|
|
|
tryAgain();
|
|
|
|
else {
|
|
|
|
d->errorCode = ErrAuth;
|
|
|
|
error();
|
|
|
|
}
|
2004-11-13 10:13:12 +00:00
|
|
|
}*/
|
2004-11-05 08:54:01 +00:00
|
|
|
|
|
|
|
void SASL::putStep(const QByteArray &stepData)
|
|
|
|
{
|
|
|
|
d->stepData = stepData.copy();
|
2004-11-13 10:13:12 +00:00
|
|
|
//tryAgain();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
void SASL::setPassword(const QSecureArray &pass)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
d->c->setClientParams(0, 0, &pass, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::setRealm(const QString &realm)
|
|
|
|
{
|
|
|
|
d->c->setClientParams(0, 0, 0, &realm);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::continueAfterParams()
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
//tryAgain();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::continueAfterAuthCheck()
|
|
|
|
{
|
2004-11-13 10:13:12 +00:00
|
|
|
//tryAgain();
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
/*void SASL::tryAgain()
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
int r;
|
|
|
|
|
|
|
|
if(d->server) {
|
|
|
|
if(!d->tried) {
|
|
|
|
r = d->c->nextStep(d->stepData);
|
|
|
|
d->tried = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
r = d->c->tryAgain();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(r == SASLContext::Error) {
|
|
|
|
d->errorCode = ErrAuth;
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(r == SASLContext::Continue) {
|
|
|
|
d->tried = false;
|
|
|
|
nextStep(d->c->result());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(r == 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 == SASLContext::Error) {
|
|
|
|
d->errorCode = ErrAuth;
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(r == 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 == SASLContext::Error) {
|
|
|
|
d->errorCode = ErrAuth;
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if(r == 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 == SASLContext::Success)
|
|
|
|
authenticated();
|
|
|
|
else if(r == SASLContext::Error) {
|
|
|
|
d->errorCode = ErrAuth;
|
|
|
|
error();
|
|
|
|
}
|
2004-11-13 10:13:12 +00:00
|
|
|
}*/
|
2004-11-05 08:54:01 +00:00
|
|
|
|
|
|
|
int SASL::ssf() const
|
|
|
|
{
|
|
|
|
return d->c->security();
|
|
|
|
}
|
|
|
|
|
2004-11-13 10:13:12 +00:00
|
|
|
/*void SASL::write(const QByteArray &a)
|
2004-11-05 08:54:01 +00:00
|
|
|
{
|
|
|
|
QByteArray b;
|
|
|
|
if(!d->c->encode(a, &b)) {
|
|
|
|
d->errorCode = ErrCrypt;
|
|
|
|
error();
|
|
|
|
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)) {
|
|
|
|
d->errorCode = ErrCrypt;
|
|
|
|
error();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
*/
|
2004-11-13 10:13:12 +00:00
|
|
|
|
|
|
|
bool SASL::haveError() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int SASL::bytesAvailable() const
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int SASL::bytesOutgoingAvailable() const
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::close()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::write(const QSecureArray &a)
|
|
|
|
{
|
|
|
|
Q_UNUSED(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
QSecureArray SASL::read()
|
|
|
|
{
|
|
|
|
return QSecureArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SASL::writeIncoming(const QByteArray &a)
|
|
|
|
{
|
|
|
|
Q_UNUSED(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray SASL::readOutgoing(int *plainBytes)
|
|
|
|
{
|
|
|
|
Q_UNUSED(plainBytes);
|
|
|
|
return QByteArray();
|
|
|
|
}
|
|
|
|
|
2004-11-05 08:54:01 +00:00
|
|
|
}
|