Название: QSslSocket Клиент-сервер
Отправлено: Magvaj от Июля 30, 2009, 21:20
Нелепая проблема, но никак не могу найти решение. Делаю по докам: переопределил QTcpServer::incomingConnection(): void SslServer::incomingConnection(int socketDescriptor) { QSslSocket *serverSocket=new QSslSocket(this); if(serverSocket->setSocketDescriptor(socketDescriptor)) { QObject::connect(serverSocket, SIGNAL(encrypted()), this, SLOT(socketReady())); QObject::connect(serverSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &))); QObject::connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); serverSocket->startServerEncryption(); } else { delete serverSocket; } } На стороне клиента создаю сокет и подсоединяюсь(всё по докам): socket=new QSslSocket(this); QObject::connect(socket, SIGNAL(encrypted()), this, SLOT(socketReady())); QObject::connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &))); QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); socket->connectToHostEncrypted(this->serverHost, this->serverPort); Что только не делал выдаёт ошибку: Error during SSL handshake: error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher Что это и как это исправить?
Название: Re: QSslSocket Клиент-сервер
Отправлено: VAP от Июля 30, 2009, 23:17
Возможно ошибка криптографии. Полезный материал по теме здесь: http://lists.trolltech.com/qt4-preview-feedback/2007-05/thread00001-0.html
Название: Re: QSslSocket Клиент-сервер
Отправлено: Magvaj от Июля 31, 2009, 09:07
почитал.. там идёт явная установка ключа и сертификата... я же ничего не устанавливаю... без этого же можно обойтись?
Название: Re: QSslSocket Клиент-сервер
Отправлено: Magvaj от Июля 31, 2009, 11:43
попробовал с сертификатами- та же лажа: вот код сервера: #include "sslserver.h" #include <QSslConfiguration> #include <QFile>
SslServer::SslServer(QObject *parent): QTcpServer(parent) {
}
void SslServer::socketReady() { qDebug("Connected!"); }
void SslServer::socketSslErrors(const QList<QSslError> &errors) { emit logString(qobject_cast<QSslSocket*>(sender())->errorString(), SSLSERVER_LOG_ERROR); }
void SslServer::socketError(QAbstractSocket::SocketError socketError) { emit logString(qobject_cast<QSslSocket*>(sender())->errorString(), SSLSERVER_LOG_ERROR); }
void SslServer::incomingConnection(int socketDescriptor) { QSslSocket *serverSocket=new QSslSocket(this); if(serverSocket->setSocketDescriptor(socketDescriptor)) {
QSslConfiguration a; QFile *f=new QFile("./RSA/server.crt"); QFile *f1=new QFile("./RSA/server.key"); f->open(QIODevice::ReadWrite); f1->open(QIODevice::ReadWrite); a.setCaCertificates(QSslCertificate::fromDevice(f)); a.setPrivateKey(QSslKey(f1, QSsl::Rsa)); f->close(); f1->close(); serverSocket->setSslConfiguration(a); serverSocket->setCiphers("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5");
QObject::connect(serverSocket, SIGNAL(encrypted()), this, SLOT(socketReady())); QObject::connect(serverSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &))); QObject::connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); serverSocket->startServerEncryption(); } else { delete serverSocket; } }
и клиента: MegaConnector::MegaConnector() { socket=new QSslSocket(this); QObject::connect(socket, SIGNAL(encrypted()), this, SLOT(socketReady())); QObject::connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &))); QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); }
MegaConnector::~MegaConnector() { delete socket; }
void MegaConnector::connect() { socket->connectToHostEncrypted(this->serverHost, this->serverPort); }
void MegaConnector::socketReady() { qDebug("Ready!"); }
void MegaConnector::socketSslErrors(const QList<QSslError> &errors) { qDebug("SSL error"); }
void MegaConnector::socketError(QAbstractSocket::SocketError socketError) { qDebug("Error"); qDebug(QVariant(socketError).toString().toAscii()); qDebug(socket->errorString().toAscii()); } может кто посмотрит? может я вообще чтото нелепое упустил...
Название: Re: QSslSocket Клиент-сервер
Отправлено: denka от Июля 31, 2009, 11:59
Попробуй в MegaConnector::socketSslErrors вызвать QSslSocket::ignoreSslErrors
Название: Re: QSslSocket Клиент-сервер
Отправлено: Magvaj от Августа 03, 2009, 10:06
Попробуй в MegaConnector::socketSslErrors вызвать QSslSocket::ignoreSslErrors
он туда даже не попадает... на клиенте ошибка сокета QAbstractSocket::RemoteHostClosedError, а на сервере QAbstractSocket::SslHandshakeFailedError
Название: Re: QSslSocket Клиент-сервер
Отправлено: Magvaj от Августа 05, 2009, 08:31
решение было выпрошено у поддержки Qt. Питер Хартманн любезно объяснил причину возникновения сей ситуации, за что ему поклон. Для того чтобы соединение проходило нормально, надо на сервере установить локальный сертификат и приватный ключ: serverSocket->setPrivateKey("../rsa/server.key"); serverSocket->setLocalCertificate("../rsa/server.pem"); для каждого вновь созданного сокета... Также было обещано включить сие в документацию, чтобы подобные вопросы больше не мучали умы людей ;-) Вот оригинал конечного сообщения из переписки: ...In order to make SSL encryption work on the server side, you need to set the local certificate and the private key. So you want to do something like the following in your code: ---------------- serverSocket->setPrivateKey("../rsa/server.key"); serverSocket->setLocalCertificate("../rsa/server.pem"); ---------------- Then it should work. In case you also get an error about wrong version numbers, you can also set ---------------- serverSocket->setProtocol(QSsl::AnyProtocol); ---------------- However, that might be a security risk and you probably only want to use SSLv3 and TLS. But I agree that this is not well documented, so I am planning to either extend the documentation or just write a small SSL server example and put that on the documentation pages, because you are not the first one to ask about this...
|