Ejemplo n.º 1
0
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();
}
Ejemplo n.º 3
0
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
}