File indexing completed on 2023-09-24 04:08:45
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"