Nyphel
22nd June 2007, 15:37
Hi !
I'm under Windows 2000 Pro, using the beautifull Qt4.3 open source version.
This has not been recompiled, and it is configured in shared/debug.
I've downloaed and installed the OpenSSL library, but I don't think this will help me.
I was using a QtcpSocket on Qt4.2.3 to connect an IMAP server.
Now I replaced it by a QSslSocket, that inherits from QtcpSocket, but I'm having troubles.
Myclass.h :
#include <QObject>
#include <QTcpSocket>
#include <QList>
#include <QString>
#include <QSslSocket>
#include <QProcess>
class MailChecker : public QObject
{
Q_OBJECT
public:
MailChecker();
void Check();
private slots:
void SLOT_socket_proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
void SLOT_socket_sslErrors(const QList<QSslError>);
void SLOT_socket_stateChanged(QAbstractSocket::SocketSt ate);
void SLOT_socket_connected();
void SLOT_socket_disconnected();
void SLOT_socket_encrypted();
void SLOT_socket_hostFound();
private:
QSslSocket *sockect_ssl;
// Socket management
void openSocket();
void closeSocket();
bool readLineFromSocket(QByteArray&);
bool writeToSocket(const QString &);
};
Myclass.cpp :
MailChecker::MailChecker() : QObject()
{ sockect_ssl = new QSslSocket(this);
connect(sockect_ssl, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy & proxy, QAuthenticator * authenticator)),
this, SLOT(SLOT_socket_proxyAuthenticationRequired(const QNetworkProxy & proxy, QAuthenticator * authenticator)));
connect(sockect_ssl, SIGNAL(sslErrors(const QList<QSslError>)),this, SLOT(SLOT_socket_sslErrors(const QList<QSslError>)));
connect(sockect_ssl, SIGNAL(stateChanged), this, SLOT(SLOT_socket_stateChanged(QAbstractSocket::Soc ketState socketState)));
connect(sockect_ssl, SIGNAL(connected()), this, SLOT(SLOT_socket_connected()));
connect(sockect_ssl, SIGNAL(disconnected()),this, SLOT(SLOT_socket_disconnected()));
connect(sockect_ssl, SIGNAL(encrypted()), this, SLOT(SLOT_socket_encrypted()));
connect(sockect_ssl, SIGNAL(hostFound()), this, SLOT(SLOT_socket_hostFound()));
}
// ---------------------------------------------------------------------------------
void MailChecker::SLOT_socket_proxyAuthenticationRequir ed(const QNetworkProxy & proxy, QAuthenticator * authenticator)
{
cout << "PROXY AUTHENTIFICATION REQUIRED" << endl;
}
void MailChecker::SLOT_socket_sslErrors(const QList<QSslError> errors)
{
cout << "SSL ERRORS !" << endl;
}
void MailChecker::SLOT_socket_stateChanged(QAbstractSoc ket::SocketState socketState)
{
cout << "STATE CHANGED" << endl;
}
void MailChecker::SLOT_socket_connected()
{
cout << "CONNECTED" << endl;
}
void MailChecker::SLOT_socket_disconnected()
{
cout << "DISCONNECTED" << endl;
}
void MailChecker::SLOT_socket_encrypted()
{
cout << "ENCRYPTED" << endl;
}
void MailChecker::SLOT_socket_hostFound()
{
cout << "HOST FOUND" << endl;
}
// ---------------------------------------------------------------------------------
void MailChecker::openSocket()
{
sockect_ssl = new QSslSocket();
}
void MailChecker::closeSocket()
{
if ( sockect_ssl )
{
sockect_ssl->close();
sockect_ssl->deleteLater();
}
}
bool MailChecker::readLineFromSocket( QByteArray& data )
{
while ( !sockect_ssl->canReadLine() )
{
if ( !sockect_ssl->waitForReadyRead( 30 * 1000 ) )
{
closeSocket();
return 0;
}
}
if (sockect_ssl->readLine(data.data(), data.size()) == -1)
{
closeSocket();
return false;
}
return true;
}
bool MailChecker::writeToSocket( const QString & str )
{
QByteArray ba = str.toLocal8Bit();
qint64 wrote = 0;
while ( wrote < (qint64)ba.size() )
{
qint64 ret = sockect_ssl->write( ba.data() + wrote, ba.size() - wrote );
if ( ret == -1 )
return false; // error
wrote += ret;
}
sockect_ssl->waitForBytesWritten();
return true;
}
My first trouble is that the Slot are never called by my application... And they should be.
I don't understand why...
(1) Using the QSslSocket like a QTcpSocket (no encryption) :
void MailChecker::Check()
{
sockect_ssl->connectToHost(IMAP_host, IMAP_port);
if (sockect_ssl->waitForConnected(15000))
{
if (readLineFromSocket(line))
{
...
}
else
{
cout << "\n ERROR - Unable to read server response. " << endl;
}
}
This worked well for my old class using the QTcpSocket.
Now, this works well too, with the QSslSocket... But the data isn't encrypted.
(2) Using the QSslSocket with encryption :
void MailChecker::Check()
{
sockect_ssl->connectToHostEncrypted(IMAP_host, IMAP_port);
if (sockect_ssl->waitForConnected(15000))
{
if (readLineFromSocket(line))
{
...
}
else
{
cout << "\n ERROR - Unable to read server response. " << endl;
}
}
This should work. This is like the example given is the documentation...
But I get the ERROR message immediately : the socket hasn't waited for 15s. trying to connect to host with the encrypted mode.
(3) Using the QSslSocket with encryption :
void MailChecker::Check()
{
sockect_ssl->connectToHost(IMAP_host, IMAP_port);
if (sockect_ssl->waitForConnected(15000))
{
sockect_ssl->startClientEncryption();
if (readLineFromSocket(line))
{
...
}
else
{
cout << "\n ERROR - Unable to read server response. " << endl;
}
}
This is the sameThis code should do the same job as the (2) solution, but is provided for a TLS support. In my case, I get the ERROR like before, without any wait for connection.
If someone has an idea ?
Thanks :)
I'm under Windows 2000 Pro, using the beautifull Qt4.3 open source version.
This has not been recompiled, and it is configured in shared/debug.
I've downloaed and installed the OpenSSL library, but I don't think this will help me.
I was using a QtcpSocket on Qt4.2.3 to connect an IMAP server.
Now I replaced it by a QSslSocket, that inherits from QtcpSocket, but I'm having troubles.
Myclass.h :
#include <QObject>
#include <QTcpSocket>
#include <QList>
#include <QString>
#include <QSslSocket>
#include <QProcess>
class MailChecker : public QObject
{
Q_OBJECT
public:
MailChecker();
void Check();
private slots:
void SLOT_socket_proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *);
void SLOT_socket_sslErrors(const QList<QSslError>);
void SLOT_socket_stateChanged(QAbstractSocket::SocketSt ate);
void SLOT_socket_connected();
void SLOT_socket_disconnected();
void SLOT_socket_encrypted();
void SLOT_socket_hostFound();
private:
QSslSocket *sockect_ssl;
// Socket management
void openSocket();
void closeSocket();
bool readLineFromSocket(QByteArray&);
bool writeToSocket(const QString &);
};
Myclass.cpp :
MailChecker::MailChecker() : QObject()
{ sockect_ssl = new QSslSocket(this);
connect(sockect_ssl, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy & proxy, QAuthenticator * authenticator)),
this, SLOT(SLOT_socket_proxyAuthenticationRequired(const QNetworkProxy & proxy, QAuthenticator * authenticator)));
connect(sockect_ssl, SIGNAL(sslErrors(const QList<QSslError>)),this, SLOT(SLOT_socket_sslErrors(const QList<QSslError>)));
connect(sockect_ssl, SIGNAL(stateChanged), this, SLOT(SLOT_socket_stateChanged(QAbstractSocket::Soc ketState socketState)));
connect(sockect_ssl, SIGNAL(connected()), this, SLOT(SLOT_socket_connected()));
connect(sockect_ssl, SIGNAL(disconnected()),this, SLOT(SLOT_socket_disconnected()));
connect(sockect_ssl, SIGNAL(encrypted()), this, SLOT(SLOT_socket_encrypted()));
connect(sockect_ssl, SIGNAL(hostFound()), this, SLOT(SLOT_socket_hostFound()));
}
// ---------------------------------------------------------------------------------
void MailChecker::SLOT_socket_proxyAuthenticationRequir ed(const QNetworkProxy & proxy, QAuthenticator * authenticator)
{
cout << "PROXY AUTHENTIFICATION REQUIRED" << endl;
}
void MailChecker::SLOT_socket_sslErrors(const QList<QSslError> errors)
{
cout << "SSL ERRORS !" << endl;
}
void MailChecker::SLOT_socket_stateChanged(QAbstractSoc ket::SocketState socketState)
{
cout << "STATE CHANGED" << endl;
}
void MailChecker::SLOT_socket_connected()
{
cout << "CONNECTED" << endl;
}
void MailChecker::SLOT_socket_disconnected()
{
cout << "DISCONNECTED" << endl;
}
void MailChecker::SLOT_socket_encrypted()
{
cout << "ENCRYPTED" << endl;
}
void MailChecker::SLOT_socket_hostFound()
{
cout << "HOST FOUND" << endl;
}
// ---------------------------------------------------------------------------------
void MailChecker::openSocket()
{
sockect_ssl = new QSslSocket();
}
void MailChecker::closeSocket()
{
if ( sockect_ssl )
{
sockect_ssl->close();
sockect_ssl->deleteLater();
}
}
bool MailChecker::readLineFromSocket( QByteArray& data )
{
while ( !sockect_ssl->canReadLine() )
{
if ( !sockect_ssl->waitForReadyRead( 30 * 1000 ) )
{
closeSocket();
return 0;
}
}
if (sockect_ssl->readLine(data.data(), data.size()) == -1)
{
closeSocket();
return false;
}
return true;
}
bool MailChecker::writeToSocket( const QString & str )
{
QByteArray ba = str.toLocal8Bit();
qint64 wrote = 0;
while ( wrote < (qint64)ba.size() )
{
qint64 ret = sockect_ssl->write( ba.data() + wrote, ba.size() - wrote );
if ( ret == -1 )
return false; // error
wrote += ret;
}
sockect_ssl->waitForBytesWritten();
return true;
}
My first trouble is that the Slot are never called by my application... And they should be.
I don't understand why...
(1) Using the QSslSocket like a QTcpSocket (no encryption) :
void MailChecker::Check()
{
sockect_ssl->connectToHost(IMAP_host, IMAP_port);
if (sockect_ssl->waitForConnected(15000))
{
if (readLineFromSocket(line))
{
...
}
else
{
cout << "\n ERROR - Unable to read server response. " << endl;
}
}
This worked well for my old class using the QTcpSocket.
Now, this works well too, with the QSslSocket... But the data isn't encrypted.
(2) Using the QSslSocket with encryption :
void MailChecker::Check()
{
sockect_ssl->connectToHostEncrypted(IMAP_host, IMAP_port);
if (sockect_ssl->waitForConnected(15000))
{
if (readLineFromSocket(line))
{
...
}
else
{
cout << "\n ERROR - Unable to read server response. " << endl;
}
}
This should work. This is like the example given is the documentation...
But I get the ERROR message immediately : the socket hasn't waited for 15s. trying to connect to host with the encrypted mode.
(3) Using the QSslSocket with encryption :
void MailChecker::Check()
{
sockect_ssl->connectToHost(IMAP_host, IMAP_port);
if (sockect_ssl->waitForConnected(15000))
{
sockect_ssl->startClientEncryption();
if (readLineFromSocket(line))
{
...
}
else
{
cout << "\n ERROR - Unable to read server response. " << endl;
}
}
This is the sameThis code should do the same job as the (2) solution, but is provided for a TLS support. In my case, I get the ERROR like before, without any wait for connection.
If someone has an idea ?
Thanks :)