void CoreAuthHandler::startSsl() { #ifdef HAVE_SSL QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket()); Q_ASSERT(sslSocket); qDebug() << qPrintable(tr("Starting encryption for Client:")) << _peer->description(); connect(sslSocket, SIGNAL(sslErrors(const QList<QSslError> &)), SLOT(onSslErrors())); sslSocket->flush(); // ensure that the write cache is flushed before we switch to ssl (bug 682) sslSocket->startServerEncryption(); #endif }
void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socketError) { if (!socket) return; QNetworkReply::NetworkError errorCode = QNetworkReply::UnknownNetworkError; switch (socketError) { case QAbstractSocket::HostNotFoundError: errorCode = QNetworkReply::HostNotFoundError; break; case QAbstractSocket::ConnectionRefusedError: errorCode = QNetworkReply::ConnectionRefusedError; break; case QAbstractSocket::RemoteHostClosedError: // try to reconnect/resend before sending an error. // while "Reading" the _q_disconnected() will handle this. if (state != QHttpNetworkConnectionChannel::IdleState && state != QHttpNetworkConnectionChannel::ReadingState) { if (reconnectAttempts-- > 0) { closeAndResendCurrentRequest(); return; } else { errorCode = QNetworkReply::RemoteHostClosedError; } } else if (state == QHttpNetworkConnectionChannel::ReadingState) { if (!reply->d_func()->expectContent()) { // No content expected, this is a valid way to have the connection closed by the server return; } if (reply->contentLength() == -1 && !reply->d_func()->isChunked()) { // There was no content-length header and it's not chunked encoding, // so this is a valid way to have the connection closed by the server return; } // ok, we got a disconnect even though we did not expect it // Try to read everything from the socket before we emit the error. if (socket->bytesAvailable()) { // Read everything from the socket into the reply buffer. // we can ignore the readbuffersize as the data is already // in memory and we will not receive more data on the socket. reply->setReadBufferSize(0); _q_receiveReply(); #ifndef QT_NO_SSL if (ssl) { // QT_NO_OPENSSL. The QSslSocket can still have encrypted bytes in the plainsocket. // So we need to check this if the socket is a QSslSocket. When the socket is flushed // it will force a decrypt of the encrypted data in the plainsocket. QSslSocket *sslSocket = static_cast<QSslSocket*>(socket); qint64 beforeFlush = sslSocket->encryptedBytesAvailable(); while (sslSocket->encryptedBytesAvailable()) { sslSocket->flush(); _q_receiveReply(); qint64 afterFlush = sslSocket->encryptedBytesAvailable(); if (afterFlush == beforeFlush) break; beforeFlush = afterFlush; } } #endif } errorCode = QNetworkReply::RemoteHostClosedError; } else { errorCode = QNetworkReply::RemoteHostClosedError; } break; case QAbstractSocket::SocketTimeoutError: // try to reconnect/resend before sending an error. if (state == QHttpNetworkConnectionChannel::WritingState && (reconnectAttempts-- > 0)) { closeAndResendCurrentRequest(); return; } errorCode = QNetworkReply::TimeoutError; break; case QAbstractSocket::ProxyAuthenticationRequiredError: errorCode = QNetworkReply::ProxyAuthenticationRequiredError; break; case QAbstractSocket::SslHandshakeFailedError: errorCode = QNetworkReply::SslHandshakeFailedError; break; default: // all other errors are treated as NetworkError errorCode = QNetworkReply::UnknownNetworkError; break; } QPointer<QHttpNetworkConnection> that = connection; QString errorString = connection->d_func()->errorDetail(errorCode, socket, socket->errorString()); // In the InProgress state the channel should not emit the error. // This will instead be handled by the connection. if (!connection->d_func()->shouldEmitChannelError(socket)) return; // Need to dequeu the request so that we can emit the error. if (!reply) connection->d_func()->dequeueRequest(socket); if (reply) { reply->d_func()->errorString = errorString; emit reply->finishedWithError(errorCode, errorString); reply = 0; } // send the next request QMetaObject::invokeMethod(that, "_q_startNextRequest", Qt::QueuedConnection); if (that) //signal emission triggered event loop close(); }
bool ssh::dossh() { #ifdef USE_QSSH { if(m_connection && m_connection->state() != QSsh::SshConnection::Unconnected) { helpers::log("ssh: already connecting...", LOG_INF, qApp, 0); return true; } m_connection = new QSsh::SshConnection(params, this); connect(m_connection, SIGNAL(connected()), SLOT(onQsshConnected())); connect(m_connection, SIGNAL(error(QSsh::SshError)), SLOT(onQsshConnectionError(QSsh::SshError))); helpers::log("ssh: connecting START...", LOG_INF, qApp, 0); m_connection->connectToHost(); return false; } #else helpers::log("ssh: START: " + QString::number(QSslSocket::supportsSsl()), QSslSocket::supportsSsl() ? LOG_INF : LOG_ERR, qApp, 0); //http://stackoverflow.com/questions/15213139/simple-qssl-client-server-cannot-start-handshake-on-non-plain-connection QSslSocket *socket = new QSslSocket(this); socket->ignoreSslErrors(); socket->setPeerVerifyMode(QSslSocket::VerifyNone); socket->setProtocol(QSsl::SslV3); connect(socket, SIGNAL(encrypted()), this, SLOT(ready())); connect(socket, SIGNAL(encryptedBytesWritten(qint64)), this, SLOT(encryptedBytesWritten(qint64))); connect(socket, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(modeChanged(QSslSocket::SslMode))); connect(socket, SIGNAL(peerVerifyError(const QSslError &)), this, SLOT(peerVerifyError(const QSslError &))); connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &))); connect(socket, SIGNAL(connected()), this, SLOT(connected())); connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); connect(socket, SIGNAL(hostFound()), this, SLOT(hostFound())); connect(socket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)), this, SLOT(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *))); connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(stateChanged(QAbstractSocket::SocketState))); connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); { { QFile file( "c:/Users/gherczeg/.ssh/id_boot2docker" ); if( ! file.open( QIODevice::ReadOnly ) ) { QMessageBox::question(0, "Erreur", "Impossible de charger id_boot2docker"); return; } QSslKey key(&file); file.close(); helpers::log("ssh:keyok: "+QString::number(!key.isNull()), !key.isNull() ? LOG_INF : LOG_ERR, qApp, 0); socket->setPrivateKey( key ); } foreach (const QSslCertificate &cert, QSslCertificate::fromPath("c:/Users/gherczeg/.boot2docker/certs/boot2docker-vm/*.pem", QSsl::Pem, QRegExp::Wildcard)) { helpers::log("ssh:certok1: "+QString::number(!cert.isNull()), !cert.isNull() ? LOG_INF : LOG_ERR, qApp, 0); socket->setLocalCertificate( cert ); socket->sslConfiguration().caCertificates().append(cert); socket->addCaCertificate( cert ); socket->addDefaultCaCertificate(cert); } } socket->connectToHostEncrypted("127.0.0.1", 2022); //socket->connectToHost("127.0.0.1", 2022); bool bok = socket->waitForEncrypted(100000); //bool bok = socket->waitForConnected(100000); if(!bok) { helpers::log("ssh:!waited:"+QString::number(bok),LOG_ERR, qApp, 0); return; } helpers::log("ssh:waited4ecnrypt/connect:"+QString::number(bok),LOG_INF, qApp, 0); socket->startClientEncryption(); bool wait4Read1 = socket->waitForReadyRead(100000); helpers::log("ssh:wait4Read1:"+QString::number(wait4Read1),wait4Read1 ? LOG_INF : LOG_ERR, qApp, 0); QString s = "docker: do!"; qint64 written = socket->write(s.toStdString().c_str()); helpers::log("ssh:written:"+QString::number(written),written > 0 ? LOG_INF : LOG_ERR, qApp, 0); bool flushed = socket->flush(); helpers::log("ssh:flush:"+QString::number(flushed),flushed ? LOG_INF : LOG_ERR, qApp, 0); bool wait4Write = socket->waitForBytesWritten(100000); helpers::log("ssh:wait4Write:"+QString::number(wait4Write),wait4Write ? LOG_INF : LOG_ERR, qApp, 0); bool wait4Read2 = socket->waitForReadyRead(100000); helpers::log("ssh:wait4Read2:"+QString::number(wait4Read2),wait4Read2 ? LOG_INF : LOG_ERR, qApp, 0); socket->disconnectFromHost(); #endif }