Ejemplo n.º 1
1
void HttpsServer::incomingConnection(qintptr socketDescriptor)
#endif
{
    QSslSocket* sslSocket = new QSslSocket(this);
    if (sslSocket->setSocketDescriptor(socketDescriptor))
    {
        sslSocket->setPrivateKey(privateKey());
        sslSocket->setLocalCertificate(certificate());
        sslSocket->startServerEncryption();
        connect(sslSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslSocket_sslErrors(QList<QSslError>)));
        connect(sslSocket, SIGNAL(encrypted()), this, SLOT(sslSocket_encrypted()));
        addPendingConnection(sslSocket);
        nextPendingConnection();
        createHttpConnection()->initialize(sslSocket, sslSocket);
    }
    else
    {
        qWarning() << "HttpsServer::incomingConnection: failed to set socket descriptor '" << socketDescriptor << "' on ssl socket.";
        delete sslSocket;
    }
}
Ejemplo n.º 2
0
void QwwSmtpClientPrivate::sendRcpt() {
    SMTPCommand &cmd = commandqueue.head();
    QVariantList vlist = cmd.data.toList();
    QList<QVariant> rcptlist = vlist.at(1).toList();
    QByteArray buf = QByteArray("RCPT TO:<").append(rcptlist.first().toByteArray()).append(">\r\n");
    qDebug() << "SMTP >>>" << buf;
    socket->write(buf);
    rcptlist.removeFirst();
    vlist[1] = rcptlist;
    cmd.data = vlist;

    if (rcptlist.isEmpty()) cmd.extra = 1;
}
Ejemplo n.º 3
0
//=======================
//       PRIVATE SLOTS
//=======================
//GENERIC SERVER SIGNALS
// New Connection Signals
void WebServer::NewSocketConnection(){
  WebSocket *sock = 0;
  if(WSServer!=0){
    if(WSServer->hasPendingConnections()){ 
      QWebSocket *ws = WSServer->nextPendingConnection();
      if( !allowConnection(ws->peerAddress()) ){ ws->close(); }
      else{ sock = new WebSocket( ws, generateID(), AUTH); }
    }
  }else if(TCPServer!=0){
    if(TCPServer->hasPendingConnections()){ 
	QSslSocket *ss = TCPServer->nextPendingConnection();
	if( !allowConnection(ss->peerAddress()) ){ ss->close(); }    
	else{ sock = new WebSocket( ss, generateID(), AUTH); }
    }
  }
  if(sock==0){ return; } //no new connection
  qDebug() << "New Socket Connection";	
  connect(sock, SIGNAL(SocketClosed(QString)), this, SLOT(SocketClosed(QString)) );
  connect(EVENTS, SIGNAL(NewEvent(EventWatcher::EVENT_TYPE, QJsonValue)), sock, SLOT(EventUpdate(EventWatcher::EVENT_TYPE, QJsonValue)) );
  connect(sock, SIGNAL(BlackListAddress(QHostAddress)), this, SLOT(BlackListConnection(QHostAddress)) );
  OpenSockets << sock;
}
Ejemplo n.º 4
0
void Server::sendFortune()
{
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
    qDebug() << "In sendFortune";
    out << (quint16)0;
    out << fortunes.at(qrand() % fortunes.size());
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));

    QSslSocket *clientConnection = sslServer->nextPendingConnection();
    if (!clientConnection->waitForEncrypted(1000)){
        qDebug() << "Waited for 1 second for encryption handshake without success";
        return;
    }
    qDebug() << "Successfully waited for secure handshake...";
    connect(clientConnection, SIGNAL(disconnected()),
            clientConnection, SLOT(deleteLater()));
    clientConnection->write(block);
    clientConnection->disconnectFromHost();
}
Ejemplo n.º 5
0
/*!
    Called when a new connection is established.

    Converts \a socket to a QSslSocket.

    \internal
*/
void QSslServer::incomingConnection(qintptr socket)
{
    QSslSocket *pSslSocket = new QSslSocket();

    if (Q_LIKELY(pSslSocket)) {
        pSslSocket->setSslConfiguration(m_sslConfiguration);

        if (Q_LIKELY(pSslSocket->setSocketDescriptor(socket))) {
            connect(pSslSocket, &QSslSocket::peerVerifyError, this, &QSslServer::peerVerifyError);

            typedef void (QSslSocket::* sslErrorsSignal)(const QList<QSslError> &);
            connect(pSslSocket, static_cast<sslErrorsSignal>(&QSslSocket::sslErrors),
                    this, &QSslServer::sslErrors);
            connect(pSslSocket, &QSslSocket::encrypted, this, &QSslServer::newEncryptedConnection);

            addPendingConnection(pSslSocket);

            pSslSocket->startServerEncryption();
        } else {
           delete pSslSocket;
        }
    }
}
Ejemplo n.º 6
0
void QuazaaIRC::startIrc()
{
	systemLog.postLog(LogSeverity::Debug, QString("QuazaaIRC::startIRC() %1").arg(quazaaSettings.Chat.IrcServerName));
	//qDebug() << "QuazaaIRC::startIrc() " << ircServer;
	ircSession = new Irc::Session(this);
	sServer = quazaaSettings.Chat.IrcServerName;
	bLoginCompleted = false;



	// stripNicks / echoMessages
	ircSession->setOptions(Irc::Session::EchoMessages);

	if (quazaaSettings.Chat.IrcUseSSL)
	{
		QSslSocket* socket = new QSslSocket(ircSession);
		socket->ignoreSslErrors();
		socket->setPeerVerifyMode(QSslSocket::VerifyNone);
		ircSession->setSocket(socket);
	}

        ircSession->setObjectName("IrcSession");
	connect(ircSession, SIGNAL(connected()), this, SLOT(on_IrcSession_connected()));
	connect(ircSession, SIGNAL(disconnected()), this, SLOT(on_IrcSession_disconnected()));
	connect(ircSession, SIGNAL(welcomed()), this, SLOT(on_IrcSession_welcomed()));
	connect(ircSession, SIGNAL(bufferAdded(Irc::Buffer*)), this, SLOT(on_IrcSession_bufferAdded(Irc::Buffer*)));
	connect(ircSession, SIGNAL(bufferRemoved(Irc::Buffer*)), this, SLOT(on_IrcSession_bufferRemoved(Irc::Buffer*)));

	ircSession->setNick(quazaaSettings.Profile.IrcNickname);
	sNick = quazaaSettings.Profile.IrcNickname;
	ircSession->setIdent("QuazaaIRC");
	ircSession->setRealName(quazaaSettings.Profile.RealName);
	sRealName = quazaaSettings.Profile.RealName;
	ircSession->setAutoJoinChannels(quazaaSettings.Chat.AutoJoinChannels);

	ircSession->connectToServer(quazaaSettings.Chat.IrcServerName, quazaaSettings.Chat.IrcServerPort);
}
Ejemplo n.º 7
0
void SslTlsSocket::delayedStart()
{
    QSslSocket *sock = qobject_cast<QSslSocket *>(d);
    Q_ASSERT(sock);

    switch (m_proxySettings) {
    case Streams::ProxySettings::RespectSystemProxy:
    {
        QNetworkProxy setting;
        QNetworkProxyQuery query = QNetworkProxyQuery(host, port, m_protocolTag, QNetworkProxyQuery::TcpSocket);

        // set to true if a capable setting is found
        bool capableSettingFound = false;

        // set to true if at least one valid setting is found
        bool settingFound = false;

        // FIXME: this static function works particularly slow in Windows
        QList<QNetworkProxy> proxySettingsList = QNetworkProxyFactory::systemProxyForQuery(query);

        /* Proxy Settings are read from the user's environment variables by the above static method.
         * A peculiar case is with *nix systems, where an undefined environment variable is returned as
         * an empty string. Such entries *might* exist in our proxySettingsList, and shouldn't be processed.
         * One good check is to use hostName() of the QNetworkProxy object, and treat the Proxy Setting as invalid if
         * the host name is empty. */
        Q_FOREACH (setting, proxySettingsList) {
            if (!setting.hostName().isEmpty()) {
                settingFound = true;

                // now check whether setting has capabilities
                if (setting.capabilities().testFlag(QNetworkProxy::TunnelingCapability)) {
                    sock->setProxy(setting);
                    capableSettingFound = true;
                    break;
                }
            }
        }

        if (!settingFound || proxySettingsList.isEmpty()) {
            sock->setProxy(QNetworkProxy::NoProxy);
        } else if (!capableSettingFound) {
            emit disconnected(tr("The underlying socket is having troubles when processing connection to %1:%2: %3")
                              .arg(host, QString::number(port), QStringLiteral("Cannot find proxy setting capable of tunneling")));
        }
        break;
    }
    case Streams::ProxySettings::DirectConnect:
        sock->setProxy(QNetworkProxy::NoProxy);
        break;
    }

    if (startEncrypted)
        sock->connectToHostEncrypted(host, port);
    else
        sock->connectToHost(host, port);
}
Ejemplo n.º 8
0
// Test buffered socket being properly closed on remote disconnect
void tst_QAbstractSocket::serverDisconnectWithBuffered()
{
    QTcpServer tcpServer;
#ifndef QT_NO_SSL
    QSslSocket testSocket;
#else
    QTcpSocket testSocket;
#endif

    QVERIFY(tcpServer.listen(QHostAddress::LocalHost));
    testSocket.connectToHost(tcpServer.serverAddress(), tcpServer.serverPort());
    // Accept connection on server side
    QVERIFY(tcpServer.waitForNewConnection(5000));
    QTcpSocket *newConnection = tcpServer.nextPendingConnection();
    // Send one char and drop link
    QVERIFY(newConnection != NULL);
    QVERIFY(newConnection->putChar(0));
    QVERIFY(newConnection->flush());
    delete newConnection;

    QVERIFY(testSocket.waitForConnected(5000)); // ready for write
    QVERIFY(testSocket.state() == QAbstractSocket::ConnectedState);

    QSignalSpy spyStateChanged(&testSocket, SIGNAL(stateChanged(QAbstractSocket::SocketState)));
    QSignalSpy spyDisconnected(&testSocket, SIGNAL(disconnected()));

    QVERIFY(testSocket.waitForReadyRead(5000)); // have one char already in internal buffer
    char buf[128];
    QCOMPARE(testSocket.read(buf, sizeof(buf)), Q_INT64_C(1));
    if (testSocket.state() != QAbstractSocket::UnconnectedState) {
        QVERIFY(testSocket.waitForDisconnected(5000));
        QVERIFY(testSocket.state() == QAbstractSocket::UnconnectedState);
    }
    // Test signal emitting
    QVERIFY(spyDisconnected.count() == 1);
    QVERIFY(spyStateChanged.count() > 0);
    QVERIFY(qvariant_cast<QAbstractSocket::SocketState>(spyStateChanged.last().first())
            == QAbstractSocket::UnconnectedState);
}
Ejemplo n.º 9
0
void LanLinkProvider::connectError()
{
    QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
    if (!socket) return;
    disconnect(socket, SIGNAL(connected()), this, SLOT(connected()));
    disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));

    qCDebug(KDECONNECT_CORE) << "Fallback (1), try reverse connection (send udp packet)" << socket->errorString();
    NetworkPackage np("");
    NetworkPackage::createIdentityPackage(&np);
    np.set("tcpPort", mTcpPort);
    mUdpSocket.writeDatagram(np.serialize(), receivedIdentityPackages[socket].sender, port);

    //The socket we created didn't work, and we didn't manage
    //to create a LanDeviceLink from it, deleting everything.
    delete receivedIdentityPackages.take(socket).np;
    delete socket;
}
Ejemplo n.º 10
0
void SslServer::newConnectionPrivate(qintptr descriptor)
{
    QSslSocket *socket = new QSslSocket(this);
    socket->setSocketDescriptor(descriptor);

    if (m_max_connections == 0)
    {
        socket->abort();
        return;
    }

    socket->setProtocol(QSsl::TlsV1_2OrLater);

    socket->addCaCertificate(m_cert);
    socket->setLocalCertificate(m_cert);
    socket->setPrivateKey(m_key);

    //New connection done, set one less available connection
    m_max_connections--;

    QByteArray m_buffer;
    qint32 size = 0;

    m_socket_list.append(socket);
    m_descriptor_hash.insert(socket, descriptor);
    m_socket_hash.insert(descriptor, socket);
    m_buffer_hash.insert(socket, m_buffer);
    m_size_hash.insert(socket, size);

    connect(socket, &QSslSocket::encrypted, this, &SslServer::encrypted);
    connect(socket, &QSslSocket::disconnected, this, &SslServer::disconnectedPrivate);
    connect(socket, static_cast<void(QSslSocket::*)(const QList<QSslError>&)>(&QSslSocket::sslErrors), this, &SslServer::sslErrors);

    m_alive_hash[socket].start();

    socket->startServerEncryption();
}
Ejemplo n.º 11
0
void SslServer::readyReadPrivate()
{
    QSslSocket *socket = qobject_cast<QSslSocket*>(sender());

    if (!socket)
        return;

    QByteArray *m_buffer = &m_buffer_hash[socket];
    qint32 &m_size = m_size_hash[socket];

    while (socket->bytesAvailable() > 0)
    {
        m_buffer->append(socket->readAll());

        while ((m_size == 0 && m_buffer->size() >= 4) || (m_size > 0 && m_buffer->size() >= m_size))
        {
            if (m_size == 0 && m_buffer->size() >= 4)
            {
                m_size = getValue<qint32>(m_buffer->mid(0, 4));
                m_buffer->remove(0, 4);

                if (m_size < 0 || m_size > MAX_NETWORK_CHUNK_SIZE)
                {
                    socket->abort();
                    return;
                }
            }
            if (m_size > 0 && m_buffer->size() >= m_size)
            {
                QByteArray data = m_buffer->mid(0, m_size);
                m_buffer->remove(0, m_size);
                m_size = 0;

                QHostAddress host = socket->peerAddress();
                qintptr descriptor = socket->socketDescriptor();

                PeerData pd;
                pd.data = data;
                pd.host = host;
                pd.descriptor = descriptor;

                QMetaObject::invokeMethod(this, "process", Qt::QueuedConnection, Q_ARG(PeerData, pd));
            }
        }
    }
}
Ejemplo n.º 12
0
void SSLServer::incomingConnection(int socketDescriptor)
{
    // On an incoming connection we want
    // to create a new secure socket.
    QSslSocket *secureSocket = new QSslSocket;

    // Add to list so that we can find it with
    // nextConnection
    m_secureSocketList.append(secureSocket);

    // We need to read in the local certificate and
    // and the private key that we generated
    // with openssl.  Read the README to see
    // how these are generated.
    secureSocket->setLocalCertificate("cacert.pem");
    secureSocket->setPrivateKey("privkey.pem");

    // check that the certificate / private key are not null
    if (secureSocket->localCertificate().isNull()) {
        qDebug() << "WARNING: The local certificate appears to be null! ";
    }
    if (secureSocket->privateKey().isNull()) {
        qDebug() << "WARNING: The private key appears to be null! ";
    }

    // debug message on success
    qDebug() << "Created the SSL socket, Read local cert. / private key files";

    // From incoming connection we obtain the socket descriptor,
    // we associate this with our new SSL socket
    secureSocket->setSocketDescriptor(socketDescriptor);

    // Begin encryption.  Note from the documentation
    // all the key stuff must be done prior to doing this.
    secureSocket->startServerEncryption();
    qDebug() << "Started encryption for new secure socket";
}
void QHttpNetworkConnectionChannel::init()
{
#ifndef QT_NO_SSL
    if (connection->d_func()->encrypt)
        socket = new QSslSocket;
    else
        socket = new QTcpSocket;
#else
    socket = new QTcpSocket;
#endif
#ifndef QT_NO_BEARERMANAGEMENT
    //push session down to socket
    if (networkSession)
        socket->setProperty("_q_networksession", QVariant::fromValue(networkSession));
#endif
#ifndef QT_NO_NETWORKPROXY
    // Set by QNAM anyway, but let's be safe here
    socket->setProxy(QNetworkProxy::NoProxy);
#endif

    QObject::connect(socket, SIGNAL(bytesWritten(qint64)),
                     this, SLOT(_q_bytesWritten(qint64)),
                     Qt::DirectConnection);
    QObject::connect(socket, SIGNAL(connected()),
                     this, SLOT(_q_connected()),
                     Qt::DirectConnection);
    QObject::connect(socket, SIGNAL(readyRead()),
                     this, SLOT(_q_readyRead()),
                     Qt::DirectConnection);

    // The disconnected() and error() signals may already come
    // while calling connectToHost().
    // In case of a cached hostname or an IP this
    // will then emit a signal to the user of QNetworkReply
    // but cannot be caught because the user did not have a chance yet
    // to connect to QNetworkReply's signals.
    qRegisterMetaType<QAbstractSocket::SocketError>();
    QObject::connect(socket, SIGNAL(disconnected()),
                     this, SLOT(_q_disconnected()),
                     Qt::QueuedConnection);
    QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
                     this, SLOT(_q_error(QAbstractSocket::SocketError)),
                     Qt::QueuedConnection);


#ifndef QT_NO_NETWORKPROXY
    QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
                     this, SLOT(_q_proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
                     Qt::DirectConnection);
#endif

#ifndef QT_NO_SSL
    QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
    if (sslSocket) {
        // won't be a sslSocket if encrypt is false
        QObject::connect(sslSocket, SIGNAL(encrypted()),
                         this, SLOT(_q_encrypted()),
                         Qt::DirectConnection);
        QObject::connect(sslSocket, SIGNAL(sslErrors(QList<QSslError>)),
                         this, SLOT(_q_sslErrors(QList<QSslError>)),
                         Qt::DirectConnection);
        QObject::connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)),
                         this, SLOT(_q_encryptedBytesWritten(qint64)),
                         Qt::DirectConnection);

        if (ignoreAllSslErrors)
            sslSocket->ignoreSslErrors();

        if (!ignoreSslErrorsList.isEmpty())
            sslSocket->ignoreSslErrors(ignoreSslErrorsList);

        if (!sslConfiguration.isNull())
            sslSocket->setSslConfiguration(sslConfiguration);
    }

#endif

#ifndef QT_NO_NETWORKPROXY
    if (proxy.type() != QNetworkProxy::NoProxy)
        socket->setProxy(proxy);
#endif
    isInitialized = true;
}
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.º 15
0
void WebSocketWorker::SetupSocket()
{
    if (m_connectionType == kSSLServer)
    {

#ifndef QT_NO_OPENSSL
        QSslSocket *pSslSocket = new QSslSocket();
        if (pSslSocket->setSocketDescriptor(m_socketFD)
           && gCoreContext->CheckSubnet(pSslSocket))
        {
            pSslSocket->setSslConfiguration(m_sslConfig);
            pSslSocket->startServerEncryption();
            if (pSslSocket->waitForEncrypted(5000))
            {
                LOG(VB_HTTP, LOG_INFO, "SSL Handshake occurred, connection encrypted");
                LOG(VB_HTTP, LOG_INFO, QString("Using %1 cipher").arg(pSslSocket->sessionCipher().name()));
            }
            else
            {
                LOG(VB_HTTP, LOG_WARNING, "SSL Handshake FAILED, connection terminated");
                delete pSslSocket;
                pSslSocket = nullptr;
            }
        }
        else
        {
            delete pSslSocket;
            pSslSocket = nullptr;
        }

        if (pSslSocket)
            m_socket = dynamic_cast<QTcpSocket *>(pSslSocket);
        else
            return;
#else
        return;
#endif
    }
    else // Plain old unencrypted socket
    {
        m_socket = new QTcpSocket();
        m_socket->setSocketDescriptor(m_socketFD);
        if (!gCoreContext->CheckSubnet(m_socket))
        {
            delete m_socket;
            m_socket = nullptr;
            return;
        }

    }

    m_socket->setSocketOption(QAbstractSocket::KeepAliveOption, QVariant(1));

    connect(m_socket, SIGNAL(readyRead()), SLOT(doRead()));
    connect(m_socket, SIGNAL(disconnected()), SLOT(CloseConnection()));

    // Setup heartbeat
    m_heartBeat->setInterval(20000); // 20 second
    m_heartBeat->setSingleShot(false);
    connect(m_heartBeat, SIGNAL(timeout()), SLOT(SendHeartBeat()));
}
Ejemplo n.º 16
0
bool QHttpNetworkConnectionChannel::ensureConnection()
{
    QAbstractSocket::SocketState socketState = socket->state();

    // resend this request after we receive the disconnected signal
    if (socketState == QAbstractSocket::ClosingState) {
        resendCurrent = true;
        return false;
    }

    // already trying to connect?
    if (socketState == QAbstractSocket::HostLookupState ||
        socketState == QAbstractSocket::ConnectingState) {
        return false;
    }

    // make sure that this socket is in a connected state, if not initiate
    // connection to the host.
    if (socketState != QAbstractSocket::ConnectedState) {
        // connect to the host if not already connected.
        state = QHttpNetworkConnectionChannel::ConnectingState;
        pendingEncrypt = connection->d_func()->encrypt;

        // reset state
        pipeliningSupported = PipeliningSupportUnknown;

        // This workaround is needed since we use QAuthenticator for NTLM authentication. The "phase == Done"
        // is the usual criteria for emitting authentication signals. The "phase" is set to "Done" when the
        // last header for Authorization is generated by the QAuthenticator. Basic & Digest logic does not
        // check the "phase" for generating the Authorization header. NTLM authentication is a two stage
        // process & needs the "phase". To make sure the QAuthenticator uses the current username/password
        // the phase is reset to Start.
        QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(authenticator);
        if (priv && priv->phase == QAuthenticatorPrivate::Done)
            priv->phase = QAuthenticatorPrivate::Start;
        priv = QAuthenticatorPrivate::getPrivate(proxyAuthenticator);
        if (priv && priv->phase == QAuthenticatorPrivate::Done)
            priv->phase = QAuthenticatorPrivate::Start;

        QString connectHost = connection->d_func()->hostName;
        qint16 connectPort = connection->d_func()->port;

#ifndef QT_NO_NETWORKPROXY
        // HTTPS always use transparent proxy.
        if (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy && !connection->d_func()->encrypt) {
            connectHost = connection->d_func()->networkProxy.hostName();
            connectPort = connection->d_func()->networkProxy.port();
        }
#endif
        if (connection->d_func()->encrypt) {
#ifndef QT_NO_OPENSSL
            QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
            sslSocket->connectToHostEncrypted(connectHost, connectPort);
            if (ignoreAllSslErrors)
                sslSocket->ignoreSslErrors();
            sslSocket->ignoreSslErrors(ignoreSslErrorsList);
#else
            connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError);
#endif
        } else {
            socket->connectToHost(connectHost, connectPort);
        }
        return false;
    }
    return true;
}
Ejemplo n.º 17
0
void CoreAuthHandler::onSslErrors()
{
    QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket());
    Q_ASSERT(sslSocket);
    sslSocket->ignoreSslErrors();
}
Ejemplo n.º 18
0
QList<QSslError> SslTlsSocket::sslErrors() const
{
    QSslSocket *sock = qobject_cast<QSslSocket *>(d);
    Q_ASSERT(sock);
    return sock->sslErrors();
}
Ejemplo n.º 19
0
bool QHttpNetworkConnectionChannel::ensureConnection()
{
    QAbstractSocket::SocketState socketState = socket->state();

    // resend this request after we receive the disconnected signal
    if (socketState == QAbstractSocket::ClosingState) {
        if (reply)
            resendCurrent = true;
        return false;
    }

    // already trying to connect?
    if (socketState == QAbstractSocket::HostLookupState ||
        socketState == QAbstractSocket::ConnectingState) {
        return false;
    }

    // make sure that this socket is in a connected state, if not initiate
    // connection to the host.
    if (socketState != QAbstractSocket::ConnectedState) {
        // connect to the host if not already connected.
        state = QHttpNetworkConnectionChannel::ConnectingState;
        pendingEncrypt = ssl;

        // reset state
        pipeliningSupported = PipeliningSupportUnknown;
        authenticationCredentialsSent = false;
        proxyCredentialsSent = false;
        authenticator.detach();
        QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(authenticator);
        priv->hasFailed = false;
        proxyAuthenticator.detach();
        priv = QAuthenticatorPrivate::getPrivate(proxyAuthenticator);
        priv->hasFailed = false;

        // This workaround is needed since we use QAuthenticator for NTLM authentication. The "phase == Done"
        // is the usual criteria for emitting authentication signals. The "phase" is set to "Done" when the
        // last header for Authorization is generated by the QAuthenticator. Basic & Digest logic does not
        // check the "phase" for generating the Authorization header. NTLM authentication is a two stage
        // process & needs the "phase". To make sure the QAuthenticator uses the current username/password
        // the phase is reset to Start.
        priv = QAuthenticatorPrivate::getPrivate(authenticator);
        if (priv && priv->phase == QAuthenticatorPrivate::Done)
            priv->phase = QAuthenticatorPrivate::Start;
        priv = QAuthenticatorPrivate::getPrivate(proxyAuthenticator);
        if (priv && priv->phase == QAuthenticatorPrivate::Done)
            priv->phase = QAuthenticatorPrivate::Start;

        QString connectHost = connection->d_func()->hostName;
        qint16 connectPort = connection->d_func()->port;

#ifndef QT_NO_NETWORKPROXY
        // HTTPS always use transparent proxy.
        if (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy && !ssl) {
            connectHost = connection->d_func()->networkProxy.hostName();
            connectPort = connection->d_func()->networkProxy.port();
        }
        if (socket->proxy().type() == QNetworkProxy::HttpProxy) {
            // Make user-agent field available to HTTP proxy socket engine (QTBUG-17223)
            QByteArray value;
            // ensureConnection is called before any request has been assigned, but can also be called again if reconnecting
            if (request.url().isEmpty())
                value = connection->d_func()->predictNextRequest().headerField("user-agent");
            else
                value = request.headerField("user-agent");
            if (!value.isEmpty()) {
                QNetworkProxy proxy(socket->proxy());
                proxy.setRawHeader("User-Agent", value); //detaches
                socket->setProxy(proxy);
            }
        }
#endif
        if (ssl) {
#ifndef QT_NO_OPENSSL
            QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
            sslSocket->connectToHostEncrypted(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference);
            if (ignoreAllSslErrors)
                sslSocket->ignoreSslErrors();
            sslSocket->ignoreSslErrors(ignoreSslErrorsList);

            // limit the socket read buffer size. we will read everything into
            // the QHttpNetworkReply anyway, so let's grow only that and not
            // here and there.
            socket->setReadBufferSize(64*1024);
#else
            connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ProtocolUnknownError);
#endif
        } else {
            // In case of no proxy we can use the Unbuffered QTcpSocket
#ifndef QT_NO_NETWORKPROXY
            if (connection->d_func()->networkProxy.type() == QNetworkProxy::NoProxy
                    && connection->cacheProxy().type() == QNetworkProxy::NoProxy
                    && connection->transparentProxy().type() == QNetworkProxy::NoProxy) {
#endif
                socket->connectToHost(connectHost, connectPort, QIODevice::ReadWrite | QIODevice::Unbuffered, networkLayerPreference);
                // For an Unbuffered QTcpSocket, the read buffer size has a special meaning.
                socket->setReadBufferSize(1*1024);
#ifndef QT_NO_NETWORKPROXY
            } else {
                socket->connectToHost(connectHost, connectPort, QIODevice::ReadWrite, networkLayerPreference);

                // limit the socket read buffer size. we will read everything into
                // the QHttpNetworkReply anyway, so let's grow only that and not
                // here and there.
                socket->setReadBufferSize(64*1024);
            }
#endif
        }
        return false;
    }
    return true;
}
Ejemplo n.º 20
0
void QwwSmtpClientPrivate::processNextCommand(bool ok) {
    if (inProgress && !commandqueue.isEmpty()) {
        emit q->commandFinished(commandqueue.head().id, !ok);
        commandqueue.dequeue();
    }
    if (commandqueue.isEmpty()) {
        inProgress = false;
        emit q->done(false);
        return;
    }
    const SMTPCommand &cmd = commandqueue.head();
    switch (cmd.type) {
    case SMTPCommand::Connect: {
        QString hostName = cmd.data.toList().at(0).toString();
        uint port = cmd.data.toList().at(1).toUInt();
        bool ssl = cmd.data.toList().at(2).toBool();
        if(ssl){
            qDebug() << "SMTP ** connectToHostEncrypted";
            socket->connectToHostEncrypted(hostName, port);
        } else {
            qDebug() << "SMTP ** connectToHost";
            socket->connectToHost(hostName, port);
        }
        setState(QwwSmtpClient::Connecting);
    }
    break;
    case SMTPCommand::Disconnect: {
        sendQuit();
    }
    break;
    case SMTPCommand::StartTLS: {
        qDebug() << "SMTP >>> STARTTLS";
        socket->write("STARTTLS\r\n");
        setState(QwwSmtpClient::TLSRequested);
    }
    break;
    case SMTPCommand::Authenticate: {
        QwwSmtpClient::AuthMode authmode = (QwwSmtpClient::AuthMode)cmd.data.toList().at(0).toInt();
        switch (authmode) {
        case QwwSmtpClient::AuthPlain:
            qDebug() << "SMTP >>> AUTH PLAIN";
            socket->write("AUTH PLAIN\r\n");
            setState(QwwSmtpClient::Authenticating);
            break;
        case QwwSmtpClient::AuthLogin:
            qDebug() << "SMTP >>> AUTH LOGIN";
            socket->write("AUTH LOGIN\r\n");
            setState(QwwSmtpClient::Authenticating);
            break;
        default:
            qWarning("Unsupported or unknown authentication scheme");
            //processNextCommand(false);
        }
    }
    break;
    case SMTPCommand::Mail:
    case SMTPCommand::MailBurl:
    {
        setState(QwwSmtpClient::Sending);
        QByteArray buf = QByteArray("MAIL FROM:<").append(cmd.data.toList().at(0).toByteArray()).append(">\r\n");
        qDebug() << "SMTP >>>" << buf;
        socket->write(buf);
        break;
    }
    case SMTPCommand::RawCommand: {
	QString cont = cmd.data.toString();
	if(!cont.endsWith("\r\n")) cont.append("\r\n");
    setState(QwwSmtpClient::Sending);
    qDebug() << "SMTP >>>" << cont;
	socket->write(cont.toUtf8());
	} break;
    }
    inProgress = true;
    emit q->commandStarted(cmd.id);
}
Ejemplo n.º 21
0
// main logic of the component - a slot triggered upon data entering the socket
// comments inline...
void QwwSmtpClientPrivate::_q_readFromSocket() {
    while (socket->canReadLine()) {
        QString line = socket->readLine();
        qDebug() << "SMTP <<<" << line.toUtf8().constData();
        QRegExp rx("(\\d+)-(.*)\n");        // multiline response (aka 250-XYZ)
        QRegExp rxlast("(\\d+) (.*)\n");    // single or last line response (aka 250 XYZ)
        bool mid = rx.exactMatch(line);
        bool last = rxlast.exactMatch(line);
        // multiline
        if (mid){
            int status = rx.cap(1).toInt();
            SMTPCommand &cmd = commandqueue.head();
            switch (cmd.type) {
            // trying to connect
            case SMTPCommand::Connect: {
                    int stage = cmd.extra.toInt();
                    // stage 0 completed with success - socket is connected and EHLO was sent
                    if(stage==1 && status==250){
                        QString arg = rx.cap(2).trimmed();
                        parseOption(arg);   // we're probably receiving options
                    }
                }
                break;
            // trying to establish deferred SSL handshake
            case SMTPCommand::StartTLS: {
                    int stage = cmd.extra.toInt();
                    // stage 0 (negotiation) completed ok
                    if(stage==1 && status==250){
                        QString arg = rx.cap(2).trimmed();
                        parseOption(arg);   // we're probably receiving options
                    }
                }
                default: break;
            }
        } else
        // single line
        if (last) {
            int status = rxlast.cap(1).toInt();
            SMTPCommand &cmd = commandqueue.head();
            switch (cmd.type) {
            // trying to connect
            case SMTPCommand::Connect: {
                int stage = cmd.extra.toInt();
                // connection established, server sent its banner
                if (stage==0 && status==220) {
                    sendEhlo(); // connect ok, send ehlo
                }
                // server responded to EHLO
                if (stage==1 && status==250){
                    // success (EHLO)
                    parseOption(rxlast.cap(2).trimmed()); // we're probably receiving the last option
                    errorString.clear();
                    setState(QwwSmtpClient::Connected);
                    processNextCommand();
                }
                // server responded to HELO (EHLO failed)
                if (state==2 && status==250) {
                    // success (HELO)
                    errorString.clear();
                    setState(QwwSmtpClient::Connected);
                    processNextCommand();
                }
                // EHLO failed, reason given in errorString
                if (stage==1 && (status==554 || status==501 || status==502 || status==421)) {
                    errorString = rxlast.cap(2).trimmed();
                    sendHelo(); // ehlo failed, send helo
                    cmd.extra = 2;
                }
                //abortDialog();
            }
            break;
            // trying to establish a delayed SSL handshake
            case SMTPCommand::StartTLS: {
                int stage = cmd.extra.toInt();
                // received an invitation from the server to enter TLS mode
                if (stage==0 && status==220) {
                    qDebug() << "SMTP ** startClientEncruption";
                    socket->startClientEncryption();
                }
                // TLS established, connection is encrypted, EHLO was sent
                else if (stage==1 && status==250) {
                    setState(QwwSmtpClient::Connected);
                    parseOption(rxlast.cap(2).trimmed());   // we're probably receiving options
                    errorString.clear();
                    emit q->tlsStarted();
                    processNextCommand();
                }
                // starttls failed
                else {
                    qDebug() << "TLS failed at stage " << stage << ": " << line;
                    errorString = "TLS failed";
                    emit q->done(false);
                }
            }
            break;
            // trying to authenticate the client to the server
            case SMTPCommand::Authenticate: {
                int stage = cmd.extra.toInt();
                if (stage==0 && status==334) {
                    // AUTH mode was accepted by the server, 1st challenge sent
                    QwwSmtpClient::AuthMode authmode = (QwwSmtpClient::AuthMode)cmd.data.toList().at(0).toInt();
                    errorString.clear();
                    switch (authmode) {
                    case QwwSmtpClient::AuthPlain:
                        sendAuthPlain(cmd.data.toList().at(1).toString(), cmd.data.toList().at(2).toString());
                        break;
                    case QwwSmtpClient::AuthLogin:
                        sendAuthLogin(cmd.data.toList().at(1).toString(), cmd.data.toList().at(2).toString(), 1);
                        break;
                    default:
                        qWarning("I shouldn't be here");
                        setState(QwwSmtpClient::Connected);
                        processNextCommand();
                        break;
                    }
                    cmd.extra = stage+1;
                } else if (stage==1 && status==334) {
                    // AUTH mode and user names were acccepted by the server, 2nd challenge sent
                    QwwSmtpClient::AuthMode authmode = (QwwSmtpClient::AuthMode)cmd.data.toList().at(0).toInt();
                    errorString.clear();
                    switch (authmode) {
                    case QwwSmtpClient::AuthPlain:
                        // auth failed
                        setState(QwwSmtpClient::Connected);
                        processNextCommand();
                        break;
                    case QwwSmtpClient::AuthLogin:
                        sendAuthLogin(cmd.data.toList().at(1).toString(), cmd.data.toList().at(2).toString(), 2);
                        break;
                    default:
                        qWarning("I shouldn't be here");
                        setState(QwwSmtpClient::Connected);
                        processNextCommand();
                        break;
                    }
                } else if (stage==2 && status==334) {
                    // auth failed
                    errorString = rxlast.cap(2).trimmed();
                    setState(QwwSmtpClient::Connected);
                    processNextCommand();
                } else if (status==235) {
                    // auth ok
                    errorString.clear();
                    emit q->authenticated();
                    setState(QwwSmtpClient::Connected);
                    processNextCommand();
                } else {
                    errorString = rxlast.cap(2).trimmed();
                    setState(QwwSmtpClient::Connected);
                    emit q->done(false);
                }
            }
            break;
            // trying to send mail
            case SMTPCommand::Mail:
            case SMTPCommand::MailBurl:
            {
                int stage = cmd.extra.toInt();
                // temporary failure upon receiving the sender address (greylisting probably)
                if (status==421 && stage==0) {
                    errorString = rxlast.cap(2).trimmed();
                    // temporary envelope failure (greylisting)
                    setState(QwwSmtpClient::Connected);
                    processNextCommand(false);
                }
                if (status==250 && stage==0) {
                    // sender accepted
                    errorString.clear();
                    sendRcpt();
                } else if (status==250 && stage==1) {
                    // all receivers accepted
                    if (cmd.type == SMTPCommand::MailBurl) {
                        errorString.clear();
                        QByteArray url = cmd.data.toList().at(2).toByteArray();
                        qDebug() << "SMTP >>> BURL" << url << "LAST";
                        socket->write("BURL " + url + " LAST\r\n");
                        cmd.extra=2;
                    } else {
                        errorString.clear();
                        qDebug() << "SMTP >>> DATA";
                        socket->write("DATA\r\n");
                        cmd.extra=2;
                    }
                } else if ((cmd.type == SMTPCommand::Mail && status==354 && stage==2)) {
                    // DATA command accepted
                    errorString.clear();
                    QByteArray toBeWritten = cmd.data.toList().at(2).toString().toUtf8();
                    qDebug() << "SMTP >>>" << toBeWritten << "\r\n.\r\n";
                    socket->write(toBeWritten); // expecting data to be already escaped (CRLF.CRLF)
                    socket->write("\r\n.\r\n"); // termination token - CRLF.CRLF
                    cmd.extra=3;
                } else if ((cmd.type == SMTPCommand::MailBurl && status==354 && stage==2)) {
                    // BURL succeeded
                    setState(QwwSmtpClient::Connected);
                    errorString.clear();
                    processNextCommand();
                } else if ((cmd.type == SMTPCommand::Mail && status==250 && stage==3)) {
                    // mail queued
                    setState(QwwSmtpClient::Connected);
                    errorString.clear();
                    processNextCommand();
                } else {
                    // something went wrong
                    errorString = rxlast.cap(2).trimmed();
                    setState(QwwSmtpClient::Connected);
                    emit q->done(false);
                    processNextCommand();
                }
            }
                default: break;
            }
        } else {
            qDebug() << "None of two regular expressions matched the input" << line;
        }
    }
}
Ejemplo n.º 22
0
void QwwSmtpClientPrivate::onError(QAbstractSocket::SocketError e)
{
    emit q->socketError(e, socket->errorString());
    onDisconnected();
}
Ejemplo n.º 23
0
void SslServer::process(const PeerData &pd)
{
    QByteArray data = pd.data;

    if (data.isEmpty())
        return;

    quint8 command = getValue<quint8>(data.mid(0, 1));
    data.remove(0, 1);

    QSslSocket *socket = m_socket_hash[pd.descriptor];

    if (!socket)
        return;

    switch (command)
    {
    case ServerCommand::PeerTryConnect:
    {
        if (data.size() != 20)
        {
            removeSocket(socket);
            return;
        }

        QByteArray peer_id = data;

        peer_id = cleanString(QLatin1String(peer_id)).toLatin1().leftJustified(peer_id.length(), char(0), true);

        if (m_unavailable_list.contains(peer_id))
        {
            DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket))
                           << "User target:" << qPrintable(peer_id) << "Attempt to connect to unavailable user!");
            writeWarning(socket, "You're trying to connect to a unavailable user!");
            return;
        }

        if (peer_id == m_id_hash[socket])
        {
            DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket))
                           << "User target:" << qPrintable(peer_id) << "Attempt to connect to itself!");
            writeWarning(socket, "You're trying to connect to itself!");
            return;
        }

        if (!m_id_list.contains(peer_id))
        {
            DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket))
                           << "User target:" << qPrintable(peer_id) << "Attempt to connect to non connected user!");
            writeWarning(socket, "You're trying to connect to a non connected user!");
            return;
        }

        QSslSocket *target_socket = m_id_hash.key(peer_id);

        if (m_connecting_connected_list.contains(target_socket))
        {
            DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket))
                           << "User target:" << qPrintable(peer_id) << "Attempt to connect to already connected user!");
            writeWarning(socket, "User already connected!");
            return;
        }

        m_connecting_connected_list.append(socket);
        m_connecting_connected_list.append(target_socket);

        QByteArray data;
        data.append(getBytes<quint8>(ServerCommand::ConnectionRequested));
        data.append(getBytes<quint32>(socket->localAddress().toIPv4Address()));
        data.append(m_id_hash[socket]);

        m_accept_hash.insert(target_socket, socket);

        DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket))
                       << "User target:" << qPrintable(peer_id) << "Trying to connect to peer!");

        target_socket->write(getBytes<qint32>(data.size()));
        target_socket->write(data);

        break;
    }
    case ServerCommand::ConnectionAnswer:
    {
        if (data.size() != 1)
        {
            removeSocket(socket);
            return;
        }

        QSslSocket *socket_starter = m_accept_hash[socket];

        bool accepted = getValue<bool>(data.mid(0, 1));

        if (!socket_starter)
        {
            m_connecting_connected_list.removeAll(socket_starter);
            m_connecting_connected_list.removeAll(socket);

            if (accepted)
            {
                DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket))
                               << "User disconnected or canceled operation!");
                writeWarning(socket, "Can't connect to user because it's disconnected or canceled operation!");
            }

            return;
        }

        if (!accepted)
        {
            QSslSocket *socket1 = socket_starter;
            QSslSocket *socket2 = socket;

            m_accept_hash.remove(socket1);
            m_accept_hash.remove(socket2);

            m_connecting_connected_list.removeAll(socket1);
            m_connecting_connected_list.removeAll(socket2);

            DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket))
                           << "User target:" << qPrintable(m_id_hash.value(socket_starter)) << "User refused connection!");
            writeWarning(socket_starter, "User refused connection!");

            return;
        }

        QSslSocket *socket1 = socket;
        QSslSocket *socket2 = socket_starter;

        m_connected_1.insert(socket1, socket2);
        m_connected_2.insert(socket2, socket1);

        QByteArray data1;
        QByteArray data2;

        data1.append(getBytes<quint8>(ServerCommand::ConnectedToPeer));
        data2.append(getBytes<quint8>(ServerCommand::ConnectedToPeer));

        QByteArray password = OpenSslLib::RANDbytes(32);

        data1.append(m_id_hash[socket1]);
        data1.append(password);

        data2.append(m_id_hash[socket2]);
        data2.append(password);

        socket1->write(getBytes<qint32>(data2.size()));
        socket1->write(data2);

        socket2->write(getBytes<qint32>(data1.size()));
        socket2->write(data1);

        DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket_starter))
                       << "User target:" << qPrintable(m_id_hash.value(socket)) << "Connected!");

        break;
    }
    case ServerCommand::DisconnectedFromPeer:
    {
        QSslSocket *target_socket = m_connected_1.value(socket);

        if (!target_socket)
            target_socket = m_connected_2.value(socket);

        DEBUG_FUNCTION("IP:" << qPrintable(socket->peerAddress().toString()) << "User origin:" << qPrintable(m_id_hash.value(socket))
                       << "User target:" << qPrintable(m_id_hash.value(target_socket)) << "Disconnected from peer!");

        disconnectedFromPeer(socket);

        break;
    }
    case ServerCommand::P2PData:
    {
        QSslSocket *target_socket = m_connected_1.value(socket);

        if (!target_socket)
            target_socket = m_connected_2.value(socket);

        if (!target_socket)
            break;

        data.prepend(getBytes<quint8>(ServerCommand::P2PData));

        target_socket->write(getBytes<qint32>(data.size()));
        target_socket->write(data);

        m_alive_hash[socket].restart();

        m_alive_hash[target_socket].restart();

        break;
    }
    case ServerCommand::Alive:
    {
        m_alive_hash[socket].restart();

        break;
    }
    case ServerCommand::XML:
    {
        processCommandXML(socket, data);

        break;
    }
    default:
    {
        removeSocket(socket);
        return;
    }
    }
}
Ejemplo n.º 24
0
bool QHttpNetworkConnectionChannel::sendRequest()
{
    if (!reply) {
        // heh, how should that happen!
        qWarning() << "QHttpNetworkConnectionChannel::sendRequest() called without QHttpNetworkReply";
        state = QHttpNetworkConnectionChannel::IdleState;
        return false;
    }

    switch (state) {
    case QHttpNetworkConnectionChannel::IdleState: { // write the header
        if (!ensureConnection()) {
            // wait for the connection (and encryption) to be done
            // sendRequest will be called again from either
            // _q_connected or _q_encrypted
            return false;
        }
        written = 0; // excluding the header
        bytesTotal = 0;

        QHttpNetworkReplyPrivate *replyPrivate = reply->d_func();
        replyPrivate->clear();
        replyPrivate->connection = connection;
        replyPrivate->connectionChannel = this;
        replyPrivate->autoDecompress = request.d->autoDecompress;
        replyPrivate->pipeliningUsed = false;

        // if the url contains authentication parameters, use the new ones
        // both channels will use the new authentication parameters
        if (!request.url().userInfo().isEmpty() && request.withCredentials()) {
            QUrl url = request.url();
            QAuthenticator &auth = authenticator;
            if (url.userName() != auth.user()
                || (!url.password().isEmpty() && url.password() != auth.password())) {
                auth.setUser(url.userName());
                auth.setPassword(url.password());
                connection->d_func()->copyCredentials(connection->d_func()->indexOf(socket), &auth, false);
            }
            // clear the userinfo,  since we use the same request for resending
            // userinfo in url can conflict with the one in the authenticator
            url.setUserInfo(QString());
            request.setUrl(url);
        }
        // Will only be false if QtWebKit is performing a cross-origin XMLHttpRequest
        // and withCredentials has not been set to true.
        if (request.withCredentials())
            connection->d_func()->createAuthorization(socket, request);
#ifndef QT_NO_NETWORKPROXY
        QByteArray header = QHttpNetworkRequestPrivate::header(request,
            (connection->d_func()->networkProxy.type() != QNetworkProxy::NoProxy));
#else
        QByteArray header = QHttpNetworkRequestPrivate::header(request, false);
#endif
        socket->write(header);
        // flushing is dangerous (QSslSocket calls transmit which might read or error)
//        socket->flush();
        QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
        if (uploadByteDevice) {
            // connect the signals so this function gets called again
            QObject::connect(uploadByteDevice, SIGNAL(readyRead()),this, SLOT(_q_uploadDataReadyRead()));

            bytesTotal = request.contentLength();

            state = QHttpNetworkConnectionChannel::WritingState; // start writing data
            sendRequest(); //recurse
        } else {
            state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
            sendRequest(); //recurse
        }

        break;
    }
    case QHttpNetworkConnectionChannel::WritingState:
    {
        // write the data
        QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
        if (!uploadByteDevice || bytesTotal == written) {
            if (uploadByteDevice)
                emit reply->dataSendProgress(written, bytesTotal);
            state = QHttpNetworkConnectionChannel::WaitingState; // now wait for response
            sendRequest(); // recurse
            break;
        }

        // only feed the QTcpSocket buffer when there is less than 32 kB in it
        const qint64 socketBufferFill = 32*1024;
        const qint64 socketWriteMaxSize = 16*1024;


#ifndef QT_NO_OPENSSL
        QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
        // if it is really an ssl socket, check more than just bytesToWrite()
        while ((socket->bytesToWrite() + (sslSocket ? sslSocket->encryptedBytesToWrite() : 0))
                <= socketBufferFill && bytesTotal != written)
#else
        while (socket->bytesToWrite() <= socketBufferFill
               && bytesTotal != written)
#endif
        {
            // get pointer to upload data
            qint64 currentReadSize = 0;
            qint64 desiredReadSize = qMin(socketWriteMaxSize, bytesTotal - written);
            const char *readPointer = uploadByteDevice->readPointer(desiredReadSize, currentReadSize);

            if (currentReadSize == -1) {
                // premature eof happened
                connection->d_func()->emitReplyError(socket, reply, QNetworkReply::UnknownNetworkError);
                return false;
                break;
            } else if (readPointer == 0 || currentReadSize == 0) {
                // nothing to read currently, break the loop
                break;
            } else {
                qint64 currentWriteSize = socket->write(readPointer, currentReadSize);
                if (currentWriteSize == -1 || currentWriteSize != currentReadSize) {
                    // socket broke down
                    connection->d_func()->emitReplyError(socket, reply, QNetworkReply::UnknownNetworkError);
                    return false;
                } else {
                    written += currentWriteSize;
                    uploadByteDevice->advanceReadPointer(currentWriteSize);

                    emit reply->dataSendProgress(written, bytesTotal);

                    if (written == bytesTotal) {
                        // make sure this function is called once again
                        state = QHttpNetworkConnectionChannel::WaitingState;
                        sendRequest();
                        break;
                    }
                }
            }
        }
        break;
    }

    case QHttpNetworkConnectionChannel::WaitingState:
    {
        QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice();
        if (uploadByteDevice) {
            QObject::disconnect(uploadByteDevice, SIGNAL(readyRead()), this, SLOT(_q_uploadDataReadyRead()));
        }

        // HTTP pipelining
        //connection->d_func()->fillPipeline(socket);
        //socket->flush();

        // ensure we try to receive a reply in all cases, even if _q_readyRead_ hat not been called
        // this is needed if the sends an reply before we have finished sending the request. In that
        // case receiveReply had been called before but ignored the server reply
        if (socket->bytesAvailable())
            QMetaObject::invokeMethod(this, "_q_receiveReply", Qt::QueuedConnection);
        break;
    }
    case QHttpNetworkConnectionChannel::ReadingState:
        // ignore _q_bytesWritten in these states
        // fall through
    default:
        break;
    }
    return true;
}
Ejemplo n.º 25
0
void LanLinkProvider::connected()
{
    qCDebug(KDECONNECT_CORE) << "Socket connected";

    QSslSocket* socket = qobject_cast<QSslSocket*>(sender());
    if (!socket) return;
    disconnect(socket, SIGNAL(connected()), this, SLOT(connected()));
    disconnect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError()));

    configureSocket(socket);

    // If socket disconnects due to any reason after connection, link on ssl faliure
    connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));

    NetworkPackage* receivedPackage = receivedIdentityPackages[socket].np;
    const QString& deviceId = receivedPackage->get<QString>("deviceId");
    //qCDebug(KDECONNECT_CORE) << "Connected" << socket->isWritable();

    // If network is on ssl, do not believe when they are connected, believe when handshake is completed
    NetworkPackage np2("");
    NetworkPackage::createIdentityPackage(&np2);
    socket->write(np2.serialize());
    bool success = socket->waitForBytesWritten();

    if (success) {

        qCDebug(KDECONNECT_CORE) << "Handshaking done (i'm the existing device)";

        // if ssl supported
        if (receivedPackage->get<int>("protocolVersion") >= NetworkPackage::ProtocolVersion) {
            // since I support ssl and remote device support ssl

            socket->setPeerVerifyName(deviceId);

            QString certString = KdeConnectConfig::instance()->getDeviceProperty(deviceId, "certificate", QString());
            if (!certString.isEmpty()) {
                qCDebug(KDECONNECT_CORE) << "Device trusted";
                socket->addCaCertificate(QSslCertificate(certString.toLatin1()));
                socket->setPeerVerifyMode(QSslSocket::VerifyPeer);
                connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
            } else {
                qCDebug(KDECONNECT_CORE) << "Device untrusted";
                // Do not care about ssl errors here, socket will not be closed due to errors because of query peer
                socket->setPeerVerifyMode(QSslSocket::QueryPeer);
                connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrorsLogButIgnore(QList<QSslError>)));
            }
            qCDebug(KDECONNECT_CORE) << "Starting server ssl (I'm the client TCP socket)";
            connect(socket, SIGNAL(encrypted()), this, SLOT(encrypted()));

            socket->startServerEncryption();
            return; // Return statement prevents from deleting received package, needed in slot "encrypted"
        } else {
            qWarning() << "Incompatible protocol version, this won't work";
            //addLink(deviceId, socket, receivedPackage, LanDeviceLink::Remotely);
        }

    } else {
        //I think this will never happen, but if it happens the deviceLink
        //(or the socket that is now inside it) might not be valid. Delete them.
        qCDebug(KDECONNECT_CORE) << "Fallback (2), try reverse connection (send udp packet)";
        mUdpSocket.writeDatagram(np2.serialize(), receivedIdentityPackages[socket].sender, port);
    }

    delete receivedIdentityPackages.take(socket).np;
    //We don't delete the socket because now it's owned by the LanDeviceLink
}
/*!
    \internal
 */
void QWebSocketPrivate::open(const QUrl &url, bool mask)
{
    //just delete the old socket for the moment;
    //later, we can add more 'intelligent' handling by looking at the URL
    //m_pSocket.reset();
    Q_Q(QWebSocket);
    if (!url.isValid() || url.toString().contains(QStringLiteral("\r\n"))) {
        setErrorString(QWebSocket::tr("Invalid URL."));
        Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
        return;
    }
    QTcpSocket *pTcpSocket = m_pSocket.take();
    if (pTcpSocket) {
        releaseConnections(pTcpSocket);
        pTcpSocket->deleteLater();
    }
    //if (m_url != url)
    if (Q_LIKELY(!m_pSocket)) {
        m_dataProcessor.clear();
        m_isClosingHandshakeReceived = false;
        m_isClosingHandshakeSent = false;

        setRequestUrl(url);
        QString resourceName = url.path();
        if (resourceName.contains(QStringLiteral("\r\n"))) {
            setRequestUrl(QUrl());  //clear requestUrl
            setErrorString(QWebSocket::tr("Invalid resource name."));
            Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
            return;
        }
        if (!url.query().isEmpty()) {
            if (!resourceName.endsWith(QChar::fromLatin1('?'))) {
                resourceName.append(QChar::fromLatin1('?'));
            }
            resourceName.append(url.query());
        }
        if (resourceName.isEmpty())
            resourceName = QStringLiteral("/");
        setResourceName(resourceName);
        enableMasking(mask);

    #ifndef QT_NO_SSL
        if (url.scheme() == QStringLiteral("wss")) {
            if (!QSslSocket::supportsSsl()) {
                const QString message =
                        QWebSocket::tr("SSL Sockets are not supported on this platform.");
                setErrorString(message);
                Q_EMIT q->error(QAbstractSocket::UnsupportedSocketOperationError);
            } else {
                QSslSocket *sslSocket = new QSslSocket;
                m_pSocket.reset(sslSocket);
                if (Q_LIKELY(m_pSocket)) {
                    m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
                    m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
                    m_pSocket->setReadBufferSize(m_readBufferSize);
                    m_pSocket->setPauseMode(m_pauseMode);

                    makeConnections(m_pSocket.data());
                    QObject::connect(sslSocket, &QSslSocket::encryptedBytesWritten, q,
                                     &QWebSocket::bytesWritten);
                    typedef void (QSslSocket:: *sslErrorSignalType)(const QList<QSslError> &);
                    QObject::connect(sslSocket,
                                     static_cast<sslErrorSignalType>(&QSslSocket::sslErrors),
                                     q, &QWebSocket::sslErrors);
                    setSocketState(QAbstractSocket::ConnectingState);

                    sslSocket->setSslConfiguration(m_configuration.m_sslConfiguration);
                    if (Q_UNLIKELY(m_configuration.m_ignoreSslErrors))
                        sslSocket->ignoreSslErrors();
                    else
                        sslSocket->ignoreSslErrors(m_configuration.m_ignoredSslErrors);
    #ifndef QT_NO_NETWORKPROXY
                    sslSocket->setProxy(m_configuration.m_proxy);
    #endif
                    sslSocket->connectToHostEncrypted(url.host(), url.port(443));
                } else {
                    const QString message = QWebSocket::tr("Out of memory.");
                    setErrorString(message);
                    Q_EMIT q->error(QAbstractSocket::SocketResourceError);
                }
            }
        } else
    #endif
        if (url.scheme() == QStringLiteral("ws")) {
            m_pSocket.reset(new QTcpSocket);
            if (Q_LIKELY(m_pSocket)) {
                m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
                m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
                m_pSocket->setReadBufferSize(m_readBufferSize);
                m_pSocket->setPauseMode(m_pauseMode);

                makeConnections(m_pSocket.data());
                QObject::connect(m_pSocket.data(), &QAbstractSocket::bytesWritten, q,
                                 &QWebSocket::bytesWritten);
                setSocketState(QAbstractSocket::ConnectingState);
    #ifndef QT_NO_NETWORKPROXY
                m_pSocket->setProxy(m_configuration.m_proxy);
    #endif
                m_pSocket->connectToHost(url.host(), url.port(80));
            } else {
                const QString message = QWebSocket::tr("Out of memory.");
                setErrorString(message);
                Q_EMIT q->error(QAbstractSocket::SocketResourceError);
            }
        } else {
            const QString message =
                    QWebSocket::tr("Unsupported WebSocket scheme: %1").arg(url.scheme());
            setErrorString(message);
            Q_EMIT q->error(QAbstractSocket::UnsupportedSocketOperationError);
        }
    }
}
Ejemplo n.º 27
0
void SslServer::incomingConnection(int v) {
	QSslSocket *s = new QSslSocket(this);
	s->setSocketDescriptor(v);
	qlSockets.append(s);
}
Ejemplo n.º 28
0
QXmppClient::QXmppClient(QObject *parent)
    : QObject(parent),
    d(new QXmppClientPrivate)
{
    QSslSocket *socket = new QSslSocket;
    d->stream = new QXmppStream(socket, this);
    socket->setParent(d->stream);
    d->clientPresence.setExtensions(d->stream->presenceExtensions());

    bool check = connect(d->stream, SIGNAL(elementReceived(const QDomElement&, bool&)),
                         this, SIGNAL(elementReceived(const QDomElement&, bool&)));
    Q_ASSERT(check);

    check = connect(d->stream, SIGNAL(messageReceived(const QXmppMessage&)),
                         this, SIGNAL(messageReceived(const QXmppMessage&)));
    Q_ASSERT(check);

    check = connect(d->stream, SIGNAL(presenceReceived(const QXmppPresence&)),
                    this, SIGNAL(presenceReceived(const QXmppPresence&)));
    Q_ASSERT(check);

    check = connect(d->stream, SIGNAL(iqReceived(const QXmppIq&)), this,
        SIGNAL(iqReceived(const QXmppIq&)));
    Q_ASSERT(check);

    check = connect(d->stream, SIGNAL(discoveryIqReceived(const QXmppDiscoveryIq&)), this,
        SIGNAL(discoveryIqReceived(const QXmppDiscoveryIq&)));
    Q_ASSERT(check);

    check = connect(d->stream, SIGNAL(disconnected()), this,
        SIGNAL(disconnected()));
    Q_ASSERT(check);

    check = connect(d->stream, SIGNAL(xmppConnected()), this,
        SLOT(xmppConnected()));
    Q_ASSERT(check);

    check = connect(d->stream, SIGNAL(xmppConnected()), this,
        SIGNAL(connected()));
    Q_ASSERT(check);

    check = connect(d->stream, SIGNAL(error(QXmppClient::Error)), this,
        SIGNAL(error(QXmppClient::Error)));
    Q_ASSERT(check);

    check = setReconnectionManager(new QXmppReconnectionManager(this));
    Q_ASSERT(check);

    // rpc
    check = connect(d->stream, SIGNAL(rpcCallInvoke(QXmppRpcInvokeIq)),
        this, SLOT(invokeInterfaceMethod(QXmppRpcInvokeIq)));
    Q_ASSERT(check);

    // logging
    check = connect(this, SIGNAL(logMessage(QXmppLogger::MessageType, QString)),
        d->stream, SIGNAL(logMessage(QXmppLogger::MessageType, QString)));
    Q_ASSERT(check);

    // create managers
    d->rosterManager = new QXmppRosterManager(d->stream, this);
    d->archiveManager = new QXmppArchiveManager(d->stream, this);
    d->callManager = new QXmppCallManager(d->stream, this);
    d->mucManager = new QXmppMucManager(d->stream, this);
    d->transferManager = new QXmppTransferManager(d->stream, this);
    d->vCardManager = new QXmppVCardManager(d->stream, this);
}
void QHttpNetworkConnectionChannel::init()
{
#ifndef QT_NO_SSL
    if (connection->d_func()->encrypt)
        socket = new QSslSocket;
    else
        socket = new QTcpSocket;
#else
    socket = new QTcpSocket;
#endif
#ifndef QT_NO_BEARERMANAGEMENT
    //push session down to socket
    if (networkSession)
        socket->setProperty("_q_networksession", QVariant::fromValue(networkSession));
#endif
#ifndef QT_NO_NETWORKPROXY
    // Set by QNAM anyway, but let's be safe here
    socket->setProxy(QNetworkProxy::NoProxy);
#endif

    // After some back and forth in all the last years, this is now a DirectConnection because otherwise
    // the state inside the *Socket classes gets messed up, also in conjunction with the socket notifiers
    // which behave slightly differently on Windows vs Linux
    QObject::connect(socket, SIGNAL(bytesWritten(qint64)),
                     this, SLOT(_q_bytesWritten(qint64)),
                     Qt::DirectConnection);
    QObject::connect(socket, SIGNAL(connected()),
                     this, SLOT(_q_connected()),
                     Qt::DirectConnection);
    QObject::connect(socket, SIGNAL(readyRead()),
                     this, SLOT(_q_readyRead()),
                     Qt::DirectConnection);

    // The disconnected() and error() signals may already come
    // while calling connectToHost().
    // In case of a cached hostname or an IP this
    // will then emit a signal to the user of QNetworkReply
    // but cannot be caught because the user did not have a chance yet
    // to connect to QNetworkReply's signals.
    qRegisterMetaType<QAbstractSocket::SocketError>();
    QObject::connect(socket, SIGNAL(disconnected()),
                     this, SLOT(_q_disconnected()),
                     Qt::DirectConnection);
    QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
                     this, SLOT(_q_error(QAbstractSocket::SocketError)),
                     Qt::DirectConnection);


#ifndef QT_NO_NETWORKPROXY
    QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
                     this, SLOT(_q_proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
                     Qt::DirectConnection);
#endif

#ifndef QT_NO_SSL
    QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
    if (sslSocket) {
        // won't be a sslSocket if encrypt is false
        QObject::connect(sslSocket, SIGNAL(encrypted()),
                         this, SLOT(_q_encrypted()),
                         Qt::DirectConnection);
        QObject::connect(sslSocket, SIGNAL(sslErrors(QList<QSslError>)),
                         this, SLOT(_q_sslErrors(QList<QSslError>)),
                         Qt::DirectConnection);
        QObject::connect(sslSocket, SIGNAL(preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)),
                         this, SLOT(_q_preSharedKeyAuthenticationRequired(QSslPreSharedKeyAuthenticator*)),
                         Qt::DirectConnection);
        QObject::connect(sslSocket, SIGNAL(encryptedBytesWritten(qint64)),
                         this, SLOT(_q_encryptedBytesWritten(qint64)),
                         Qt::DirectConnection);

        if (ignoreAllSslErrors)
            sslSocket->ignoreSslErrors();

        if (!ignoreSslErrorsList.isEmpty())
            sslSocket->ignoreSslErrors(ignoreSslErrorsList);

        if (!sslConfiguration.isNull())
           sslSocket->setSslConfiguration(sslConfiguration);
    } else {
Ejemplo n.º 30
-1
// Accept connection from server and initiate the SSL handshake
void Server::acceptConnection()
{
	if (sockets.empty() == false)
		std::cout << "Server is mad efor 1 connection also. Need to update to handle multiple connections" << std::endl;

  QSslSocket *socket = dynamic_cast<QSslSocket *>(server.nextPendingConnection());
  assert(socket);


  // Report any SSL errors that occur
  connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &)));

  connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionFailure()));

  
  // QSslSocket emits the encrypted() signal after the encrypted connection is established
#define _USE_ENCRYPTION
#ifdef _USE_ENCRYPTION
  connect(socket, SIGNAL(encrypted()), this, SLOT(handshakeComplete()));
  socket->setPrivateKey(key);
  socket->setLocalCertificate(certificate);

  socket->setPeerVerifyMode(QSslSocket::VerifyNone);
  socket->startServerEncryption();
#else
  connect(socket, SIGNAL(disconnected()), this, SLOT(connectionClosed()));
  connect(socket, SIGNAL(readyRead()), this, SLOT(receiveMessage()));
  sockets.push_back(socket);
  std::cout << "Accepted connection from " << socket->peerAddress().toString().toStdString() << ":" << socket->peerPort() << " .Encrypted : " << socket->isEncrypted() << std::endl;
#endif
}