1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 2020 David Faure <faure@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL |
6 | */ |
7 | |
8 | #include "untrustedprogramhandlerinterface.h" |
9 | |
10 | #include "kiocoredebug.h" |
11 | #include <QFile> |
12 | #include <QSaveFile> |
13 | |
14 | using namespace KIO; |
15 | |
16 | UntrustedProgramHandlerInterface::UntrustedProgramHandlerInterface(QObject *parent) |
17 | : QObject(parent) |
18 | , d(nullptr) |
19 | { |
20 | } |
21 | |
22 | UntrustedProgramHandlerInterface::~UntrustedProgramHandlerInterface() |
23 | { |
24 | } |
25 | |
26 | void UntrustedProgramHandlerInterface::showUntrustedProgramWarning(KJob *job, const QString &programName) |
27 | { |
28 | Q_UNUSED(job) |
29 | Q_UNUSED(programName) |
30 | Q_EMIT result(confirmed: false); |
31 | } |
32 | |
33 | bool UntrustedProgramHandlerInterface::makeServiceFileExecutable(const QString &fileName, QString &errorString) |
34 | { |
35 | // Open the file and read the first two characters, check if it's |
36 | // #!. If not, create a new file, prepend appropriate lines, and copy |
37 | // over. |
38 | QFile desktopFile(fileName); |
39 | if (!desktopFile.open(flags: QFile::ReadOnly)) { |
40 | errorString = desktopFile.errorString(); |
41 | qCWarning(KIO_CORE) << "Error opening service" << fileName << errorString; |
42 | return false; |
43 | } |
44 | |
45 | QByteArray = desktopFile.peek(maxlen: 2); // First two chars of file |
46 | if (header.size() == 0) { |
47 | errorString = desktopFile.errorString(); |
48 | qCWarning(KIO_CORE) << "Error inspecting service" << fileName << errorString; |
49 | return false; // Some kind of error |
50 | } |
51 | |
52 | if (header != "#!" ) { |
53 | // Add header |
54 | QSaveFile saveFile; |
55 | saveFile.setFileName(fileName); |
56 | if (!saveFile.open(flags: QIODevice::WriteOnly)) { |
57 | errorString = saveFile.errorString(); |
58 | qCWarning(KIO_CORE) << "Unable to open replacement file for" << fileName << errorString; |
59 | return false; |
60 | } |
61 | |
62 | QByteArray shebang("#!/usr/bin/env xdg-open\n" ); |
63 | if (saveFile.write(data: shebang) != shebang.size()) { |
64 | errorString = saveFile.errorString(); |
65 | qCWarning(KIO_CORE) << "Error occurred adding header for" << fileName << errorString; |
66 | saveFile.cancelWriting(); |
67 | return false; |
68 | } |
69 | |
70 | // Now copy the one into the other and then close and reopen desktopFile |
71 | QByteArray desktopData(desktopFile.readAll()); |
72 | if (desktopData.isEmpty()) { |
73 | errorString = desktopFile.errorString(); |
74 | qCWarning(KIO_CORE) << "Unable to read service" << fileName << errorString; |
75 | saveFile.cancelWriting(); |
76 | return false; |
77 | } |
78 | |
79 | if (saveFile.write(data: desktopData) != desktopData.size()) { |
80 | errorString = saveFile.errorString(); |
81 | qCWarning(KIO_CORE) << "Error copying service" << fileName << errorString; |
82 | saveFile.cancelWriting(); |
83 | return false; |
84 | } |
85 | |
86 | desktopFile.close(); |
87 | if (!saveFile.commit()) { // Figures.... |
88 | errorString = saveFile.errorString(); |
89 | qCWarning(KIO_CORE) << "Error committing changes to service" << fileName << errorString; |
90 | return false; |
91 | } |
92 | |
93 | if (!desktopFile.open(flags: QFile::ReadOnly)) { |
94 | errorString = desktopFile.errorString(); |
95 | qCWarning(KIO_CORE) << "Error re-opening service" << fileName << errorString; |
96 | return false; |
97 | } |
98 | } // Add header |
99 | |
100 | return setExecuteBit(fileName, errorString); |
101 | } |
102 | |
103 | bool UntrustedProgramHandlerInterface::setExecuteBit(const QString &fileName, QString &errorString) |
104 | { |
105 | QFile file(fileName); |
106 | |
107 | // corresponds to owner on unix, which will have to do since if the user |
108 | // isn't the owner we can't change perms anyways. |
109 | if (!file.setPermissions(QFile::ExeUser | file.permissions())) { |
110 | errorString = file.errorString(); |
111 | qCWarning(KIO_CORE) << "Unable to change permissions for" << fileName << errorString; |
112 | return false; |
113 | } |
114 | |
115 | return true; |
116 | } |
117 | |
118 | #include "moc_untrustedprogramhandlerinterface.cpp" |
119 | |