atemple
20th August 2008, 21:13
Hello, I have sifted through lots of documentation and google pages to try and get a working example of a SSL server. The issue I'm having is only with SSL and using QSslSocket; non-SSL through just QTcpSocket works just fine.
A client (which I did write a sample program for) connects to my server (through QSslSocket::connectToHostEncrypted() ) and I get the connection, but my server always disconnects the socket before it can read the data, or signal encrypted(). Here's my sample server code.
HttpServer.h
#ifndef HTTPSERVER_H
#define HTTPSERVER_H
#include <QtNetwork>
class QTcpServer;
class HttpServer : public QTcpServer
{
Q_OBJECT
public:
HttpServer();
~HttpServer();
protected:
void incomingConnection (int socket);
protected slots:
void gotHeaderData();
void ready();
void sslErrors( const QList<QSslError> &errors );
void gotDisconnected();
private:
bool mySSLFlag;
};
#endif
HttpServer.cpp
#include <stdlib.h>
//My Include
#include "HttpServer.h"
HttpServer::HttpServer()
{
mySSLFlag = true;
//Create a new server, and have it listen for any http requests on port 7072
if (!listen(QHostAddress::Any, 7072))
{
fprintf(stderr, "Unable to start the server %s", this->errorString().toLatin1());
return;
}
printf("The server is running on port %d\n", this->serverPort());
}
HttpServer::~HttpServer()
{
}
void HttpServer::incomingConnection(int socketDescriptor)
{
QSslSocket *serverSocket = new QSslSocket(this);
if (serverSocket->setSocketDescriptor(socketDescriptor))
{
connect(serverSocket, SIGNAL(encrypted()), this, SLOT(ready()));
connect(serverSocket, SIGNAL(disconnected()),
this, SLOT(gotDisconnected()));
connect(serverSocket, SIGNAL(readyRead()),
this, SLOT(gotHeaderData()));
connect( serverSocket, SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(sslErrors(QList<QSslError>)) );
serverSocket->setLocalCertificate( "ssl.pem" );
serverSocket->setPrivateKey( "ssl.pem" );
serverSocket->startServerEncryption();
}
else
{
delete serverSocket;
}
}
void HttpServer::gotDisconnected()
{
qDebug("Ooops...\n");
sender()->deleteLater();
}
void HttpServer::ready()
{
qDebug("READY! \n");
}
void HttpServer::sslErrors( const QList<QSslError> &errors )
{
foreach( const QSslError &error, errors )
{
switch( error.error() )
{
case QSslError::NoPeerCertificate: dynamic_cast<QSslSocket *>(sender())->ignoreSslErrors(); break;
default:
qWarning( "CLIENT SSL: error %s", qPrintable(error.errorString()) );
disconnect(); return;
}
}
}
void HttpServer::gotHeaderData()
{
/*code*/
}
The signals encrypted, readyRead, and sslErrors never gets called. On my client, I'm also setting a private cert and key of ":ssl.pem" before calling connectToHostEncrypted(). The only hint I get of what the error could be is that in QSslSocketBackendPrivate::testConnection(), an error string comes out as SSL3_GET_CLIENT_HELLO:no shared cipher. This happens right before the disconnect signal is called. The ciphers on both ends are the qt defaults, and they both match. The server disconnects right after it finishes IncomingConnection(), and only after I call startServerEncryption().
Any ideas on why the server keeps disconnecting? Thank you for your time.
- Adam
A client (which I did write a sample program for) connects to my server (through QSslSocket::connectToHostEncrypted() ) and I get the connection, but my server always disconnects the socket before it can read the data, or signal encrypted(). Here's my sample server code.
HttpServer.h
#ifndef HTTPSERVER_H
#define HTTPSERVER_H
#include <QtNetwork>
class QTcpServer;
class HttpServer : public QTcpServer
{
Q_OBJECT
public:
HttpServer();
~HttpServer();
protected:
void incomingConnection (int socket);
protected slots:
void gotHeaderData();
void ready();
void sslErrors( const QList<QSslError> &errors );
void gotDisconnected();
private:
bool mySSLFlag;
};
#endif
HttpServer.cpp
#include <stdlib.h>
//My Include
#include "HttpServer.h"
HttpServer::HttpServer()
{
mySSLFlag = true;
//Create a new server, and have it listen for any http requests on port 7072
if (!listen(QHostAddress::Any, 7072))
{
fprintf(stderr, "Unable to start the server %s", this->errorString().toLatin1());
return;
}
printf("The server is running on port %d\n", this->serverPort());
}
HttpServer::~HttpServer()
{
}
void HttpServer::incomingConnection(int socketDescriptor)
{
QSslSocket *serverSocket = new QSslSocket(this);
if (serverSocket->setSocketDescriptor(socketDescriptor))
{
connect(serverSocket, SIGNAL(encrypted()), this, SLOT(ready()));
connect(serverSocket, SIGNAL(disconnected()),
this, SLOT(gotDisconnected()));
connect(serverSocket, SIGNAL(readyRead()),
this, SLOT(gotHeaderData()));
connect( serverSocket, SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(sslErrors(QList<QSslError>)) );
serverSocket->setLocalCertificate( "ssl.pem" );
serverSocket->setPrivateKey( "ssl.pem" );
serverSocket->startServerEncryption();
}
else
{
delete serverSocket;
}
}
void HttpServer::gotDisconnected()
{
qDebug("Ooops...\n");
sender()->deleteLater();
}
void HttpServer::ready()
{
qDebug("READY! \n");
}
void HttpServer::sslErrors( const QList<QSslError> &errors )
{
foreach( const QSslError &error, errors )
{
switch( error.error() )
{
case QSslError::NoPeerCertificate: dynamic_cast<QSslSocket *>(sender())->ignoreSslErrors(); break;
default:
qWarning( "CLIENT SSL: error %s", qPrintable(error.errorString()) );
disconnect(); return;
}
}
}
void HttpServer::gotHeaderData()
{
/*code*/
}
The signals encrypted, readyRead, and sslErrors never gets called. On my client, I'm also setting a private cert and key of ":ssl.pem" before calling connectToHostEncrypted(). The only hint I get of what the error could be is that in QSslSocketBackendPrivate::testConnection(), an error string comes out as SSL3_GET_CLIENT_HELLO:no shared cipher. This happens right before the disconnect signal is called. The ciphers on both ends are the qt defaults, and they both match. The server disconnects right after it finishes IncomingConnection(), and only after I call startServerEncryption().
Any ideas on why the server keeps disconnecting? Thank you for your time.
- Adam