File indexing completed on 2024-04-14 03:53:03

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2020 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "untrustedprogramhandlerinterface.h"
0009 
0010 #include "kiocoredebug.h"
0011 #include <QFile>
0012 #include <QSaveFile>
0013 
0014 using namespace KIO;
0015 
0016 UntrustedProgramHandlerInterface::UntrustedProgramHandlerInterface(QObject *parent)
0017     : QObject(parent)
0018     , d(nullptr)
0019 {
0020 }
0021 
0022 UntrustedProgramHandlerInterface::~UntrustedProgramHandlerInterface()
0023 {
0024 }
0025 
0026 void UntrustedProgramHandlerInterface::showUntrustedProgramWarning(KJob *job, const QString &programName)
0027 {
0028     Q_UNUSED(job)
0029     Q_UNUSED(programName)
0030     Q_EMIT result(false);
0031 }
0032 
0033 bool UntrustedProgramHandlerInterface::makeServiceFileExecutable(const QString &fileName, QString &errorString)
0034 {
0035     // Open the file and read the first two characters, check if it's
0036     // #!.  If not, create a new file, prepend appropriate lines, and copy
0037     // over.
0038     QFile desktopFile(fileName);
0039     if (!desktopFile.open(QFile::ReadOnly)) {
0040         errorString = desktopFile.errorString();
0041         qCWarning(KIO_CORE) << "Error opening service" << fileName << errorString;
0042         return false;
0043     }
0044 
0045     QByteArray header = desktopFile.peek(2); // First two chars of file
0046     if (header.size() == 0) {
0047         errorString = desktopFile.errorString();
0048         qCWarning(KIO_CORE) << "Error inspecting service" << fileName << errorString;
0049         return false; // Some kind of error
0050     }
0051 
0052     if (header != "#!") {
0053         // Add header
0054         QSaveFile saveFile;
0055         saveFile.setFileName(fileName);
0056         if (!saveFile.open(QIODevice::WriteOnly)) {
0057             errorString = saveFile.errorString();
0058             qCWarning(KIO_CORE) << "Unable to open replacement file for" << fileName << errorString;
0059             return false;
0060         }
0061 
0062         QByteArray shebang("#!/usr/bin/env xdg-open\n");
0063         if (saveFile.write(shebang) != shebang.size()) {
0064             errorString = saveFile.errorString();
0065             qCWarning(KIO_CORE) << "Error occurred adding header for" << fileName << errorString;
0066             saveFile.cancelWriting();
0067             return false;
0068         }
0069 
0070         // Now copy the one into the other and then close and reopen desktopFile
0071         QByteArray desktopData(desktopFile.readAll());
0072         if (desktopData.isEmpty()) {
0073             errorString = desktopFile.errorString();
0074             qCWarning(KIO_CORE) << "Unable to read service" << fileName << errorString;
0075             saveFile.cancelWriting();
0076             return false;
0077         }
0078 
0079         if (saveFile.write(desktopData) != desktopData.size()) {
0080             errorString = saveFile.errorString();
0081             qCWarning(KIO_CORE) << "Error copying service" << fileName << errorString;
0082             saveFile.cancelWriting();
0083             return false;
0084         }
0085 
0086         desktopFile.close();
0087         if (!saveFile.commit()) { // Figures....
0088             errorString = saveFile.errorString();
0089             qCWarning(KIO_CORE) << "Error committing changes to service" << fileName << errorString;
0090             return false;
0091         }
0092 
0093         if (!desktopFile.open(QFile::ReadOnly)) {
0094             errorString = desktopFile.errorString();
0095             qCWarning(KIO_CORE) << "Error re-opening service" << fileName << errorString;
0096             return false;
0097         }
0098     } // Add header
0099 
0100     return setExecuteBit(fileName, errorString);
0101 }
0102 
0103 bool UntrustedProgramHandlerInterface::setExecuteBit(const QString &fileName, QString &errorString)
0104 {
0105     QFile file(fileName);
0106 
0107     // corresponds to owner on unix, which will have to do since if the user
0108     // isn't the owner we can't change perms anyways.
0109     if (!file.setPermissions(QFile::ExeUser | file.permissions())) {
0110         errorString = file.errorString();
0111         qCWarning(KIO_CORE) << "Unable to change permissions for" << fileName << errorString;
0112         return false;
0113     }
0114 
0115     return true;
0116 }
0117 
0118 #include "moc_untrustedprogramhandlerinterface.cpp"