4
0
mirror of https://github.com/QuasarApp/qca.git synced 2025-05-09 09:19:33 +00:00

tlssocket, just like qt 4.3 qsslsocket. okay not really yet

svn path=/trunk/kdesupport/qca/; revision=646994
This commit is contained in:
Justin Karneges 2007-03-27 02:36:32 +00:00
parent 1da0693471
commit 73d2a85ff7
5 changed files with 246 additions and 3 deletions

@ -16,6 +16,5 @@ SUBDIRS += \
sasltest \
saslservtest \
ssltest \
sslservtest
sslservtest \
tlssocket

@ -0,0 +1,14 @@
#include "tlssocket.h"
int main(int argc, char **argv)
{
QCoreApplication qapp(argc, argv);
TLSSocket socket;
socket.connectToHostEncrypted("www.paypal.com", 443);
socket.write("GET / HTTP/1.0\r\n\r\n");
while(socket.waitForReadyRead())
printf("%s", socket.readAll().data());
return 0;
}

@ -0,0 +1,192 @@
#include "tlssocket.h"
class TLSSocket::Private : public QObject
{
Q_OBJECT
public:
TLSSocket *q;
QTcpSocket *sock;
QCA::TLS *tls;
QString host;
bool encrypted;
bool error, done;
QByteArray readbuf, writebuf;
QCA::Synchronizer sync;
bool waiting;
Private(TLSSocket *_q) : QObject(_q), q(_q), sync(_q)
{
sock = new QTcpSocket(this);
connect(sock, SIGNAL(connected()), SLOT(sock_connected()));
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()));
connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64)));
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError)));
tls = new QCA::TLS(this);
connect(tls, SIGNAL(handshaken()), SLOT(tls_handshaken()));
connect(tls, SIGNAL(readyRead()), SLOT(tls_readyRead()));
connect(tls, SIGNAL(readyReadOutgoing()), SLOT(tls_readyReadOutgoing()));
connect(tls, SIGNAL(closed()), SLOT(tls_closed()));
connect(tls, SIGNAL(error()), SLOT(tls_error()));
tls->setTrustedCertificates(QCA::systemStore());
encrypted = false;
error = false;
waiting = false;
done = false;
}
bool waitForReadyRead(int msecs)
{
waiting = true;
bool ok = sync.waitForCondition(msecs);
//while(1)
// QCoreApplication::instance()->processEvents();
waiting = false;
if(error || done)
return false;
return ok;
}
private slots:
void sock_connected()
{
//printf("sock connected\n");
tls->startClient(host);
}
void sock_readyRead()
{
//printf("sock ready read\n");
QByteArray buf = sock->readAll();
//printf("%d bytes\n", buf.size());
tls->writeIncoming(buf);
}
void sock_bytesWritten(qint64 x)
{
Q_UNUSED(x);
//printf("sock bytes written: %d\n", (int)x);
}
void sock_error(QAbstractSocket::SocketError x)
{
//printf("sock error: %d\n", x);
Q_UNUSED(x);
done = true;
if(waiting)
sync.conditionMet();
}
void tls_handshaken()
{
//printf("tls handshaken\n");
if(tls->peerIdentityResult() != QCA::TLS::Valid)
{
printf("not valid\n");
sock->abort();
tls->reset();
error = true;
}
else
{
//printf("valid\n");
encrypted = true;
//printf("%d bytes in writebuf\n", writebuf.size());
if(!writebuf.isEmpty())
{
//printf("[%s]\n", writebuf.data());
tls->write(writebuf);
writebuf.clear();
}
}
if(waiting)
sync.conditionMet();
}
void tls_readyRead()
{
//printf("tls ready read\n");
if(waiting)
sync.conditionMet();
}
void tls_readyReadOutgoing()
{
//printf("tls ready read outgoing\n");
QByteArray buf = tls->readOutgoing();
//printf("%d bytes\n", buf.size());
sock->write(buf);
}
void tls_closed()
{
//printf("tls closed\n");
}
void tls_error()
{
//printf("tls error\n");
}
};
TLSSocket::TLSSocket(QObject *parent)
:QTcpSocket(parent)
{
d = new Private(this);
}
TLSSocket::~TLSSocket()
{
delete d;
}
void TLSSocket::connectToHostEncrypted(const QString &host, quint16 port)
{
d->host = host;
setOpenMode(QIODevice::ReadWrite);
d->sock->connectToHost(host, port);
}
QCA::TLS *TLSSocket::tls()
{
return d->tls;
}
bool TLSSocket::waitForReadyRead(int msecs)
{
/*if(d->readbuf.isEmpty())
return false;
if(d->tls->bytesAvailable() == 0)
return false;*/
return d->waitForReadyRead(msecs);
}
qint64 TLSSocket::readData(char *data, qint64 maxlen)
{
if(!d->error)
d->readbuf += d->tls->read();
unsigned char *p = (unsigned char *)d->readbuf.data();
int size = d->readbuf.size();
int readsize = qMin(size, (int)maxlen);
int newsize = size - readsize;
memcpy(data, p, readsize);
memmove(p, p + readsize, newsize);
d->readbuf.resize(newsize);
return readsize;
}
qint64 TLSSocket::writeData(const char *data, qint64 len)
{
//printf("write %d bytes\n", (int)len);
QByteArray buf(data, len);
if(d->encrypted)
d->tls->write(buf);
else
d->writebuf += buf;
return len;
}
#include "tlssocket.moc"

@ -0,0 +1,29 @@
#ifndef TLSSOCKET_H
#include <QtCore>
#include <QtCrypto>
#include <QTcpSocket>
class TLSSocket : public QTcpSocket
{
public:
TLSSocket(QObject *parent = 0);
~TLSSocket();
void connectToHostEncrypted(const QString &host, quint16 port);
QCA::TLS *tls();
bool waitForReadyRead(int msecs = -1);
protected:
// from qiodevice
virtual qint64 readData(char *data, qint64 maxlen);
virtual qint64 writeData(const char *data, qint64 len);
private:
class Private;
friend class Private;
Private *d;
};
#endif

@ -0,0 +1,9 @@
CONFIG -= app_bundle
CONFIG += console
QT -= gui
QT += network
HEADERS += tlssocket.h
SOURCES += tlssocket.cpp main.cpp
include(../examples.pri)