void ClientSyncer::clientInitAck(const QVariantMap &msg) { // Core has accepted our version info and sent its own. Let's see if we accept it as well... uint ver = msg["ProtocolVersion"].toUInt(); if(ver < Quassel::buildInfo().clientNeedsProtocol) { emit connectionError(tr("<b>The Quassel Core you are trying to connect to is too old!</b><br>" "Need at least core/client protocol v%1 to connect.").arg(Quassel::buildInfo().clientNeedsProtocol)); disconnectFromCore(); return; } emit connectionMsg(msg["CoreInfo"].toString()); #ifndef QT_NO_COMPRESS if(msg["SupportsCompression"].toBool()) { _socket->setProperty("UseCompression", true); } #endif _coreMsgBuffer = msg; #ifdef HAVE_SSL if(coreConnectionInfo["useSsl"].toBool()) { if(msg["SupportSsl"].toBool()) { QSslSocket *sslSocket = qobject_cast<QSslSocket *>(_socket); Q_ASSERT(sslSocket); connect(sslSocket, SIGNAL(encrypted()), this, SLOT(sslSocketEncrypted())); connect(sslSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &))); sslSocket->startClientEncryption(); } else {
void IODeviceSocket::startTls() { QSslSocket *sock = qobject_cast<QSslSocket *>(d); if (! sock) throw std::invalid_argument("This IODeviceSocket is not a QSslSocket, and therefore doesn't support STARTTLS."); #if TROJITA_COMPRESS_DEFLATE if (m_compressor || m_decompressor) throw std::invalid_argument("DEFLATE is already active, cannot STARTTLS"); #endif sock->startClientEncryption(); }
//I'm the new device and this is the answer to my UDP identity package (data received) void LanLinkProvider::dataReceived() { QSslSocket* socket = qobject_cast<QSslSocket*>(sender()); const QByteArray data = socket->readLine(); //qCDebug(KDECONNECT_CORE) << "LanLinkProvider received reply:" << data; NetworkPackage* np = new NetworkPackage(QLatin1String("")); bool success = NetworkPackage::unserialize(data, np); if (!success) { delete np; return; } if (np->type() != PACKAGE_TYPE_IDENTITY) { qCWarning(KDECONNECT_CORE) << "LanLinkProvider/newConnection: Expected identity, received " << np->type(); delete np; return; } // Needed in "encrypted" if ssl is used, similar to "connected" receivedIdentityPackages[socket].np = np; const QString& deviceId = np->get<QString>(QStringLiteral("deviceId")); //qCDebug(KDECONNECT_CORE) << "Handshaking done (i'm the new device)"; //This socket will now be owned by the LanDeviceLink or we don't want more data to be received, forget about it disconnect(socket, &QIODevice::readyRead, this, &LanLinkProvider::dataReceived); if (np->get<int>(QStringLiteral("protocolVersion")) >= MIN_VERSION_WITH_SSL_SUPPORT) { bool isDeviceTrusted = KdeConnectConfig::instance()->trustedDevices().contains(deviceId); configureSslSocket(socket, deviceId, isDeviceTrusted); qCDebug(KDECONNECT_CORE) << "Starting client ssl (but I'm the server TCP socket)"; connect(socket, &QSslSocket::encrypted, this, &LanLinkProvider::encrypted); if (isDeviceTrusted) { connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>))); } socket->startClientEncryption(); } else { qWarning() << np->get<QString>(QStringLiteral("deviceName")) << "uses an old protocol version, this won't work"; //addLink(deviceId, socket, np, LanDeviceLink::Locally); delete receivedIdentityPackages.take(socket).np; } }
void Transfer::onConnected() { QSslSocket *socket = qobject_cast<QSslSocket*>(mSocket); if (socket) { if (mDirection == TransferModel::Send) { socket->startClientEncryption(); } else { socket->startServerEncryption(); } } else { initTransfer(); } }
void TLSFeature::handleEndElement(const QStringRef &name, const QStringRef &uri) { Q_UNUSED(uri); if (name == QLatin1String("proceed")) { DirectConnection *connection = qobject_cast<DirectConnection*>(m_client->connection()); Q_ASSERT(connection); QSslSocket *socket = qobject_cast<QSslSocket*>(connection->socket()); Q_ASSERT(socket); m_socket = socket; socket->setProtocol(QSsl::TlsV1); socket->setPeerVerifyMode(QSslSocket::VerifyNone); connect(socket, SIGNAL(encrypted()), this, SLOT(onHandshaken())); connect(socket, SIGNAL(disconnected()), this, SLOT(onDisconnected())); connect(socket, SIGNAL(peerVerifyError(QSslError)), SLOT(onPeerVerifyError(QSslError))); socket->startClientEncryption(); } }
// 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; } } }
bool SenderPrivate::connectToHost() { Q_Q(Sender); QSslSocket *sslSock = nullptr; switch (connectionType) { case Sender::TlsConnection: case Sender::TcpConnection: qCDebug(SIMPLEMAIL_SENDER) << "Connecting to host" << host << port; socket->connectToHost(host, port); break; case Sender::SslConnection: { sslSock = qobject_cast<QSslSocket*>(socket); if (sslSock) { qCDebug(SIMPLEMAIL_SENDER) << "Connecting to host encrypted" << host << port; sslSock->connectToHostEncrypted(host, port); } else { return false; } } break; } // Tries to connect to server if (!socket->waitForConnected(connectionTimeout)) { lastError = socket->errorString(); qCDebug(SIMPLEMAIL_SENDER) << "Connection failed" << socket->errorString(); Q_EMIT q->smtpError(Sender::ConnectionTimeoutError); return false; } // If the response code is not 220 (Service ready) // means that is something wrong with the server if (!waitForResponse(220)) { Q_EMIT q->smtpError(Sender::ServerError); return false; } qCDebug(SIMPLEMAIL_SENDER) << "Sending EHLO" << name; // Send a EHLO/HELO message to the server // The client's first command must be EHLO/HELO sendMessage("EHLO " + name.toLatin1()); // The response code needs to be 250. if (!waitForResponse(250)) { Q_EMIT q->smtpError(Sender::ServerError); return false; } qCDebug(SIMPLEMAIL_SENDER) << "Sent hello"; if (connectionType == Sender::TlsConnection) { qCDebug(SIMPLEMAIL_SENDER) << "Sending STARTTLS"; // send a request to start TLS handshake sendMessage(QByteArrayLiteral("STARTTLS")); // The response code needs to be 220. if (!waitForResponse(220)) { Q_EMIT q->smtpError(Sender::ServerError); return false; }; if (sslSock) { qCDebug(SIMPLEMAIL_SENDER) << "Starting client encryption"; sslSock->startClientEncryption(); if (!sslSock->waitForEncrypted(connectionTimeout)) { qCDebug(SIMPLEMAIL_SENDER) << "Failed to encrypt connection" << sslSock->errorString(); Q_EMIT q->smtpError(Sender::ConnectionTimeoutError); return false; } } qCDebug(SIMPLEMAIL_SENDER) << "Sending second EHLO" << name; // Send ELHO one more time sendMessage(QByteArrayLiteral("EHLO ") + name.toLatin1()); // The response code needs to be 250. if (!waitForResponse(250)) { Q_EMIT q->smtpError(Sender::ServerError); return false; } } state = SenderPrivate::Connected; // If no errors occured the function returns true. return true; }
bool ssh::dossh() { #ifdef USE_QSSH { if(m_connection && m_connection->state() != QSsh::SshConnection::Unconnected) { helpers::log("ssh: already connecting...", LOG_INF, qApp, 0); return true; } m_connection = new QSsh::SshConnection(params, this); connect(m_connection, SIGNAL(connected()), SLOT(onQsshConnected())); connect(m_connection, SIGNAL(error(QSsh::SshError)), SLOT(onQsshConnectionError(QSsh::SshError))); helpers::log("ssh: connecting START...", LOG_INF, qApp, 0); m_connection->connectToHost(); return false; } #else helpers::log("ssh: START: " + QString::number(QSslSocket::supportsSsl()), QSslSocket::supportsSsl() ? LOG_INF : LOG_ERR, qApp, 0); //http://stackoverflow.com/questions/15213139/simple-qssl-client-server-cannot-start-handshake-on-non-plain-connection QSslSocket *socket = new QSslSocket(this); socket->ignoreSslErrors(); socket->setPeerVerifyMode(QSslSocket::VerifyNone); socket->setProtocol(QSsl::SslV3); connect(socket, SIGNAL(encrypted()), this, SLOT(ready())); connect(socket, SIGNAL(encryptedBytesWritten(qint64)), this, SLOT(encryptedBytesWritten(qint64))); connect(socket, SIGNAL(modeChanged(QSslSocket::SslMode)), this, SLOT(modeChanged(QSslSocket::SslMode))); connect(socket, SIGNAL(peerVerifyError(const QSslError &)), this, SLOT(peerVerifyError(const QSslError &))); connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(sslErrors(const QList<QSslError> &))); connect(socket, SIGNAL(connected()), this, SLOT(connected())); connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(error(QAbstractSocket::SocketError))); connect(socket, SIGNAL(hostFound()), this, SLOT(hostFound())); connect(socket, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *)), this, SLOT(proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *))); connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(stateChanged(QAbstractSocket::SocketState))); connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); { { QFile file( "c:/Users/gherczeg/.ssh/id_boot2docker" ); if( ! file.open( QIODevice::ReadOnly ) ) { QMessageBox::question(0, "Erreur", "Impossible de charger id_boot2docker"); return; } QSslKey key(&file); file.close(); helpers::log("ssh:keyok: "+QString::number(!key.isNull()), !key.isNull() ? LOG_INF : LOG_ERR, qApp, 0); socket->setPrivateKey( key ); } foreach (const QSslCertificate &cert, QSslCertificate::fromPath("c:/Users/gherczeg/.boot2docker/certs/boot2docker-vm/*.pem", QSsl::Pem, QRegExp::Wildcard)) { helpers::log("ssh:certok1: "+QString::number(!cert.isNull()), !cert.isNull() ? LOG_INF : LOG_ERR, qApp, 0); socket->setLocalCertificate( cert ); socket->sslConfiguration().caCertificates().append(cert); socket->addCaCertificate( cert ); socket->addDefaultCaCertificate(cert); } } socket->connectToHostEncrypted("127.0.0.1", 2022); //socket->connectToHost("127.0.0.1", 2022); bool bok = socket->waitForEncrypted(100000); //bool bok = socket->waitForConnected(100000); if(!bok) { helpers::log("ssh:!waited:"+QString::number(bok),LOG_ERR, qApp, 0); return; } helpers::log("ssh:waited4ecnrypt/connect:"+QString::number(bok),LOG_INF, qApp, 0); socket->startClientEncryption(); bool wait4Read1 = socket->waitForReadyRead(100000); helpers::log("ssh:wait4Read1:"+QString::number(wait4Read1),wait4Read1 ? LOG_INF : LOG_ERR, qApp, 0); QString s = "docker: do!"; qint64 written = socket->write(s.toStdString().c_str()); helpers::log("ssh:written:"+QString::number(written),written > 0 ? LOG_INF : LOG_ERR, qApp, 0); bool flushed = socket->flush(); helpers::log("ssh:flush:"+QString::number(flushed),flushed ? LOG_INF : LOG_ERR, qApp, 0); bool wait4Write = socket->waitForBytesWritten(100000); helpers::log("ssh:wait4Write:"+QString::number(wait4Write),wait4Write ? LOG_INF : LOG_ERR, qApp, 0); bool wait4Read2 = socket->waitForReadyRead(100000); helpers::log("ssh:wait4Read2:"+QString::number(wait4Read2),wait4Read2 ? LOG_INF : LOG_ERR, qApp, 0); socket->disconnectFromHost(); #endif }