bool AlarmTransferClient::send(UserTransferMessagePtr utm) { NetworkPackage np; (*utm)[_TagServiceId] = m_serviceId; np.setUTM(utm); return sendPackage(np); }
//I'm the existing device, a new device is kindly introducing itself. //I will create a TcpSocket and try to connect. This can result in either connected() or connectError(). void LanLinkProvider::newUdpConnection() { while (mUdpServer->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(mUdpServer->pendingDatagramSize()); QHostAddress sender; mUdpServer->readDatagram(datagram.data(), datagram.size(), &sender); NetworkPackage* receivedPackage = new NetworkPackage(""); bool success = NetworkPackage::unserialize(datagram, receivedPackage); if (!success || receivedPackage->type() != PACKAGE_TYPE_IDENTITY) { delete receivedPackage; continue; } if (receivedPackage->get<QString>("deviceId") == KdeConnectConfig::instance()->deviceId()) { //qCDebug(KDECONNECT_CORE) << "Ignoring my own broadcast"; delete receivedPackage; continue; } int tcpPort = receivedPackage->get<int>("tcpPort", port); //qCDebug(KDECONNECT_CORE) << "Received Udp identity package from" << sender << " asking for a tcp connection on port " << tcpPort; QTcpSocket* socket = new QTcpSocket(this); receivedIdentityPackages[socket].np = receivedPackage; receivedIdentityPackages[socket].sender = sender; connect(socket, SIGNAL(connected()), this, SLOT(connected())); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError())); socket->connectToHost(sender, tcpPort); } }
QDebug operator<<(QDebug s, const NetworkPackage& pkg) { s.nospace() << "NetworkPackage(" << pkg.type() << ':' << pkg.body(); if (pkg.hasPayload()) { s.nospace() << ":withpayload"; } s.nospace() << ')'; return s.space(); }
//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; } }
bool LanDeviceLink::sendPackage(NetworkPackage& np) { if (np.hasPayload()) { UploadJob* job = new UploadJob(np.payload()); job->start(); np.setPayloadTransferInfo(job->getTransferInfo()); } int written = mSocketLineReader->write(np.serialize()); //TODO: Actually detect if a package is received or not, now we keep TCP //"ESTABLISHED" connections that look legit (return true when we use them), //but that are actually broken return (written != -1); }
void AlarmTransferClient::registerService() { UserTransferMessagePtr utm = UTM::create(_EvtRegisterService); (*utm)[_TagServiceId] = m_serviceId; (*utm)[_TagServiceName] = m_procname; (*utm)[_TagStartTime] = m_starttime; (*utm)[_TagFilePath] = m_path; (*utm)[_TagMessage] = m_version; (*utm)[_TagAppName] = m_dispName; NetworkPackage np; np.setUTM(utm); sendPackage(np); }
bool LoopbackDeviceLink::sendPackage(NetworkPackage& input) { NetworkPackage output(QString::null); NetworkPackage::unserialize(input.serialize(), &output); //LoopbackDeviceLink does not need deviceTransferInfo if (input.hasPayload()) { bool b = input.payload()->open(QIODevice::ReadOnly); Q_ASSERT(b); output.setPayload(input.payload(), input.payloadSize()); } Q_EMIT receivedPackage(output); return true; }
//I'm the existing device, a new device is kindly introducing itself. //I will create a TcpSocket and try to connect. This can result in either connected() or connectError(). void LanLinkProvider::newUdpConnection() //udpBroadcastReceived { while (mUdpSocket.hasPendingDatagrams()) { QByteArray datagram; datagram.resize(mUdpSocket.pendingDatagramSize()); QHostAddress sender; mUdpSocket.readDatagram(datagram.data(), datagram.size(), &sender); if (sender.isLoopback() && !mTestMode) continue; NetworkPackage* receivedPackage = new NetworkPackage(QLatin1String("")); bool success = NetworkPackage::unserialize(datagram, receivedPackage); //qCDebug(KDECONNECT_CORE) << "udp connection from " << receivedPackage->; //qCDebug(KDECONNECT_CORE) << "Datagram " << datagram.data() ; if (!success || receivedPackage->type() != PACKAGE_TYPE_IDENTITY) { delete receivedPackage; continue; } if (receivedPackage->get<QString>(QStringLiteral("deviceId")) == KdeConnectConfig::instance()->deviceId()) { //qCDebug(KDECONNECT_CORE) << "Ignoring my own broadcast"; delete receivedPackage; continue; } int tcpPort = receivedPackage->get<int>(QStringLiteral("tcpPort"), PORT); //qCDebug(KDECONNECT_CORE) << "Received Udp identity package from" << sender << " asking for a tcp connection on port " << tcpPort; QSslSocket* socket = new QSslSocket(this); receivedIdentityPackages[socket].np = receivedPackage; receivedIdentityPackages[socket].sender = sender; connect(socket, &QAbstractSocket::connected, this, &LanLinkProvider::connected); connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectError())); socket->connectToHost(sender, tcpPort); } }
bool TransferServer::sendPackage(unsigned int clientid, NetworkPackage& np) { Stream stream; stream.reserve(4096); stream.put32(0); np.encode(stream); Stream::put32((u8*)stream.getWriteBuffer(0), (u32)stream.size()-4); return send(clientid, stream.getWriteBuffer(), (int)stream.size()) == stream.size(); }
bool SharePlugin::receivePackage(const NetworkPackage& np) { /* //TODO: Write a test like this if (np.type() == PACKAGE_TYPE_PING) { qCDebug(KDECONNECT_PLUGIN_SHARE) << "sending file" << (QDesktopServices::storageLocation(QDesktopServices::HomeLocation) + "/.bashrc"); NetworkPackage out(PACKAGE_TYPE_SHARE); out.set("filename", mDestinationDir + "itworks.txt"); AutoClosingQFile* file = new AutoClosingQFile(QDesktopServices::storageLocation(QDesktopServices::HomeLocation) + "/.bashrc"); //Test file to transfer out.setPayload(file, file->size()); device()->sendPackage(out); return true; } */ qCDebug(KDECONNECT_PLUGIN_SHARE) << "File transfer"; if (np.hasPayload()) { //qCDebug(KDECONNECT_PLUGIN_SHARE) << "receiving file"; const QString filename = np.get<QString>("filename", QString::number(QDateTime::currentMSecsSinceEpoch())); const QUrl dir = destinationDir().adjusted(QUrl::StripTrailingSlash); QUrl destination(dir.toString() + '/' + filename); if (destination.isLocalFile() && QFile::exists(destination.toLocalFile())) { destination = QUrl(dir.toString() + '/' + KIO::suggestName(dir, filename)); } FileTransferJob* job = np.createPayloadTransferJob(destination); job->setDeviceName(device()->name()); connect(job, SIGNAL(result(KJob*)), this, SLOT(finished(KJob*))); KIO::getJobTracker()->registerJob(job); job->start(); } else if (np.has("text")) {
bool RunCommandPlugin::receivePackage(const NetworkPackage& np) { if (np.get<bool>("requestCommandList", false)) { sendConfig(); return true; } if (np.has("key")) { QJsonDocument commandsDocument = QJsonDocument::fromJson(config()->get<QByteArray>("commands", "{}")); QJsonObject commands = commandsDocument.object(); QString key = np.get<QString>("key"); QJsonValue value = commands[key]; if (value == QJsonValue::Undefined) { qCWarning(KDECONNECT_PLUGIN_RUNCOMMAND) << key << "is not a configured command"; } const QJsonObject command = value.toObject(); QString name = command["name"].toString(); QStringList commandLine = KShell::splitArgs(command["command"].toString()); QProcess::startDetached(commandLine.at(0), commandLine.mid(1)); return true; } return false; }
void Mounter::onPakcageReceived(const NetworkPackage& np) { if (np.get<bool>("stop", false)) { qCDebug(KDECONNECT_PLUGIN_SFTP) << "SFTP server stopped"; unmount(); return; } //This is the previous code, to access sftp server using KIO. Now we are //using the external binary sshfs, and accessing it as a local filesystem. /* * QUrl url; * url.setScheme("sftp"); * url.setHost(np.get<QString>("ip")); * url.setPort(np.get<QString>("port").toInt()); * url.setUserName(np.get<QString>("user")); * url.setPassword(np.get<QString>("password")); * url.setPath(np.get<QString>("path")); * new KRun(url, 0); * Q_EMIT mounted(); */ unmount(); m_proc = new KProcess(this); m_proc->setOutputChannelMode(KProcess::MergedChannels); connect(m_proc, SIGNAL(started()), SLOT(onStarted())); connect(m_proc, SIGNAL(error(QProcess::ProcessError)), SLOT(onError(QProcess::ProcessError))); connect(m_proc, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(onFinished(int,QProcess::ExitStatus))); QDir().mkpath(m_mountPoint); const QString program = "sshfs"; QString path; if (np.has("multiPaths")) path = '/'; else path = np.get<QString>("path"); const QStringList arguments = QStringList() << QString("%1@%2:%3") .arg(np.get<QString>("user")) .arg(np.get<QString>("ip")) .arg(path) << m_mountPoint << "-p" << np.get<QString>("port") << "-f" << "-o" << "IdentityFile=" + KdeConnectConfig::instance()->privateKeyPath() << "-o" << "StrictHostKeyChecking=no" //Do not ask for confirmation because it is not a known host << "-o" << "UserKnownHostsFile=/dev/null" //Prevent storing as a known host << "-o" << "HostKeyAlgorithms=ssh-dss" //https://bugs.kde.org/show_bug.cgi?id=351725 << "-o" << "password_stdin" ; m_proc->setProgram(program, arguments); qCDebug(KDECONNECT_PLUGIN_SFTP) << "Starting process: " << m_proc->program().join(" "); m_proc->start(); //qCDebug(KDECONNECT_PLUGIN_SFTP) << "Passing password: "******"password").toLatin1(); m_proc->write(np.get<QString>("password").toLatin1()); m_proc->write("\n"); }
bool SharePlugin::receivePackage(const NetworkPackage& np) { /* //TODO: Write a test like this if (np.type() == PACKAGE_TYPE_PING) { qCDebug(KDECONNECT_PLUGIN_SHARE) << "sending file" << (QDesktopServices::storageLocation(QDesktopServices::HomeLocation) + "/.bashrc"); NetworkPackage out(PACKAGE_TYPE_SHARE_REQUEST); out.set("filename", mDestinationDir + "itworks.txt"); AutoClosingQFile* file = new AutoClosingQFile(QDesktopServices::storageLocation(QDesktopServices::HomeLocation) + "/.bashrc"); //Test file to transfer out.setPayload(file, file->size()); device()->sendPackage(out); return true; } */ qCDebug(KDECONNECT_PLUGIN_SHARE) << "File transfer"; if (np.hasPayload()) { //qCDebug(KDECONNECT_PLUGIN_SHARE) << "receiving file"; const QString filename = np.get<QString>(QStringLiteral("filename"), QString::number(QDateTime::currentMSecsSinceEpoch())); const QUrl dir = destinationDir().adjusted(QUrl::StripTrailingSlash); QUrl destination(dir.toString() + '/' + filename); if (destination.isLocalFile() && QFile::exists(destination.toLocalFile())) { destination = QUrl(dir.toString() + '/' + KIO::suggestName(dir, filename)); } FileTransferJob* job = np.createPayloadTransferJob(destination); job->setOriginName(device()->name() + ": " + filename); connect(job, &KJob::result, this, &SharePlugin::finished); KIO::getJobTracker()->registerJob(job); job->start(); } else if (np.has(QStringLiteral("text"))) { QString text = np.get<QString>(QStringLiteral("text")); if (!QStandardPaths::findExecutable(QStringLiteral("kate")).isEmpty()) { QProcess* proc = new QProcess(); connect(proc, SIGNAL(finished(int)), proc, SLOT(deleteLater())); proc->start(QStringLiteral("kate"), QStringList(QStringLiteral("--stdin"))); proc->write(text.toUtf8()); proc->closeWriteChannel(); } else { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); tmpFile.open(); tmpFile.write(text.toUtf8()); tmpFile.close(); const QUrl url = QUrl::fromLocalFile(tmpFile.fileName()); Q_EMIT shareReceived(url); QDesktopServices::openUrl(url); } } else if (np.has(QStringLiteral("url"))) { QUrl url = QUrl::fromEncoded(np.get<QByteArray>(QStringLiteral("url"))); QDesktopServices::openUrl(url); Q_EMIT shareReceived(url); } else { qCDebug(KDECONNECT_PLUGIN_SHARE) << "Error: Nothing attached!"; } return true; }