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; } }
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; }
//======================= // 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; }
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(); }
/*! 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; } } }
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); }
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); }
// 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); }
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; }
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(); }
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)); } } } }
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(); }
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())); }
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; }
void CoreAuthHandler::onSslErrors() { QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket()); Q_ASSERT(sslSocket); sslSocket->ignoreSslErrors(); }
QList<QSslError> SslTlsSocket::sslErrors() const { QSslSocket *sock = qobject_cast<QSslSocket *>(d); Q_ASSERT(sock); return sock->sslErrors(); }
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; }
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); }
// 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; } } }
void QwwSmtpClientPrivate::onError(QAbstractSocket::SocketError e) { emit q->socketError(e, socket->errorString()); onDisconnected(); }
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; } } }
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; }
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); } } }
void SslServer::incomingConnection(int v) { QSslSocket *s = new QSslSocket(this); s->setSocketDescriptor(v); qlSockets.append(s); }
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 {
// 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 }