File indexing completed on 2024-05-12 03:55:00

0001 // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0002 // SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
0003 
0004 #include "ksandbox.h"
0005 
0006 #include <QDebug>
0007 #include <QFileInfo>
0008 
0009 #include <kcoreaddons_debug.h>
0010 
0011 bool KSandbox::isInside()
0012 {
0013     static const bool isInside = isFlatpak() || isSnap();
0014     return isInside;
0015 }
0016 
0017 bool KSandbox::isFlatpak()
0018 {
0019     static const bool isFlatpak = QFileInfo::exists(QStringLiteral("/.flatpak-info"));
0020     return isFlatpak;
0021 }
0022 
0023 bool KSandbox::isSnap()
0024 {
0025     static const bool isSnap = qEnvironmentVariableIsSet("SNAP");
0026     return isSnap;
0027 }
0028 
0029 bool checkHasFlatpakSpawnPrivileges()
0030 {
0031     QFile f(QStringLiteral("/.flatpak-info"));
0032     if (!f.open(QIODevice::ReadOnly)) {
0033         return false;
0034     }
0035 
0036     return f.readAll().contains("\norg.freedesktop.Flatpak=talk\n");
0037 }
0038 
0039 KSandbox::ProcessContext KSandbox::makeHostContext(const QProcess &process)
0040 {
0041     if (!KSandbox::isFlatpak()) {
0042         return {process.program(), process.arguments()};
0043     }
0044 
0045     static const bool hasFlatpakSpawnPrivileges = checkHasFlatpakSpawnPrivileges();
0046     if (!hasFlatpakSpawnPrivileges) {
0047         qCWarning(KCOREADDONS_DEBUG) << "Process execution expects 'org.freedesktop.Flatpak=talk'" << process.program();
0048         return {process.program(), process.arguments()};
0049     }
0050 
0051     QStringList args{QStringLiteral("--watch-bus"), QStringLiteral("--host"), QStringLiteral("--forward-fd=1"), QStringLiteral("--forward-fd=2")};
0052     if (!process.workingDirectory().isEmpty()) {
0053         args << QStringLiteral("--directory=%1").arg(process.workingDirectory());
0054     }
0055     const auto systemEnvironment = QProcessEnvironment::systemEnvironment().toStringList();
0056     const auto processEnvironment = process.processEnvironment().toStringList();
0057     for (const auto &variable : processEnvironment) {
0058         if (systemEnvironment.contains(variable)) {
0059             continue;
0060         }
0061         args << QStringLiteral("--env=%1").arg(variable);
0062     }
0063     if (!process.program().isEmpty()) { // some callers are cheeky and pass no program but put it into the arguments (e.g. konsole)
0064         args << process.program();
0065     }
0066     args += process.arguments();
0067     return {QStringLiteral("/usr/bin/flatpak-spawn"), args};
0068 }
0069 
0070 KCOREADDONS_EXPORT void KSandbox::startHostProcess(QProcess &process, QProcess::OpenMode mode)
0071 {
0072     const auto context = makeHostContext(process);
0073     process.start(context.program, context.arguments, mode);
0074 }