KDESu

stubprocess.cpp
1/*
2 This file is part of the KDE project, module kdesu.
3 SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
4
5 SPDX-License-Identifier: GPL-2.0-only
6
7 stubprocess.cpp: Conversation with kdesu_stub.
8*/
9
10#include "stubprocess.h"
11#include "kcookie_p.h"
12#include "stubprocess_p.h"
13
14#include <config-kdesu.h>
15#include <ksu_debug.h>
16
17#include <unistd.h>
18
19extern int kdesuDebugArea();
20
21namespace KDESu
22{
23using namespace KDESuPrivate;
24
25StubProcess::StubProcess()
26 : StubProcess(*new StubProcessPrivate)
27{
28}
29
30StubProcess::StubProcess(StubProcessPrivate &dd)
31 : PtyProcess(dd)
32{
33 m_user = "root";
34 m_scheduler = SchedNormal;
35 m_priority = 50;
36 m_cookie = new KCookie;
37 m_XOnly = true;
38}
39
40StubProcess::~StubProcess()
41{
42 delete m_cookie;
43}
44
45void StubProcess::setCommand(const QByteArray &command)
46{
47 m_command = command;
48}
49
50void StubProcess::setUser(const QByteArray &user)
51{
52 m_user = user;
53}
54
55void StubProcess::setXOnly(bool xonly)
56{
57 m_XOnly = xonly;
58}
59
60void StubProcess::setPriority(int prio)
61{
62 if (prio > 100) {
63 m_priority = 100;
64 } else if (prio < 0) {
65 m_priority = 0;
66 } else {
67 m_priority = prio;
68 }
69}
70
71void StubProcess::setScheduler(int sched)
72{
73 m_scheduler = sched;
74}
75
76void StubProcess::writeString(const QByteArray &str)
77{
78 QByteArray out;
79 out.reserve(str.size() + 8);
80 for (const uchar c : str) {
81 if (c < 32) {
82 out.append('\\');
83 out.append(c + '@');
84 } else if (c == '\\') {
85 out.append('\\');
86 out.append('/');
87 } else {
88 out.append(c);
89 }
90 }
91 writeLine(out);
92}
93
94/*
95 * Map pid_t to a signed integer type that makes sense for QByteArray;
96 * only the most common sizes 16 bit and 32 bit are special-cased.
97 */
98template<int T>
99struct PIDType {
100 typedef pid_t PID_t;
101};
102template<>
103struct PIDType<2> {
104 typedef qint16 PID_t;
105};
106template<>
107struct PIDType<4> {
108 typedef qint32 PID_t;
109};
110
111/*
112 * Conversation with kdesu_stub. This is how we pass the authentication
113 * tokens (X11) and other stuff to kdesu_stub.
114 * return values: -1 = error, 0 = ok, 1 = kill me
115 */
116
117int StubProcess::converseStub(int check)
118{
119 QByteArray line;
120 QByteArray tmp;
121
122 while (1) {
123 line = readLine();
124 if (line.isNull()) {
125 return -1;
126 }
127
128 if (line == "kdesu_stub") {
129 // This makes parsing a lot easier.
130 enableLocalEcho(false);
131 if (check) {
132 writeLine("stop");
133 } else {
134 writeLine("ok");
135 }
136 break;
137 }
138 }
139
140 while (1) {
141 line = readLine();
142 if (line.isNull()) {
143 return -1;
144 }
145
146 if (line == "display") {
147 writeLine(display());
148 } else if (line == "display_auth") {
149#if HAVE_X11
150 writeLine(displayAuth());
151#else
152 writeLine("");
153#endif
154 } else if (line == "command") {
155 writeString(m_command);
156 } else if (line == "path") {
157 QByteArray path = qgetenv("PATH");
158 if (!path.isEmpty() && path[0] == ':') {
159 path = path.mid(1);
160 }
161 if (m_user == "root") {
162 if (!path.isEmpty()) {
163 path = "/sbin:/bin:/usr/sbin:/usr/bin:" + path;
164 } else {
165 path = "/sbin:/bin:/usr/sbin:/usr/bin";
166 }
167 }
168 writeLine(path);
169 } else if (line == "user") {
170 writeLine(m_user);
171 } else if (line == "priority") {
172 tmp.setNum(m_priority);
173 writeLine(tmp);
174 } else if (line == "scheduler") {
175 if (m_scheduler == SchedRealtime) {
176 writeLine("realtime");
177 } else {
178 writeLine("normal");
179 }
180 } else if (line == "xwindows_only") {
181 if (m_XOnly) {
182 writeLine("no");
183 } else {
184 writeLine("yes");
185 }
186 } else if (line == "app_startup_id") {
187 const QList<QByteArray> env = environment();
188 QByteArray tmp;
189 static const char startup_env[] = "DESKTOP_STARTUP_ID=";
190 static const std::size_t size = sizeof(startup_env);
191 for (const auto &var : env) {
192 if (var.startsWith(startup_env)) {
193 tmp = var.mid(size - 1);
194 }
195 }
196 if (tmp.isEmpty()) {
197 tmp = "0"; // krazy:exclude=doublequote_chars
198 }
199 writeLine(tmp);
200 } else if (line == "app_start_pid") { // obsolete
201 // Force the pid_t returned from getpid() into
202 // something QByteArray understands; avoids ambiguity
203 // between short and unsigned short in particular.
204 tmp.setNum((PIDType<sizeof(pid_t)>::PID_t)(getpid()));
205 writeLine(tmp);
206 } else if (line == "environment") { // additional env vars
207 const QList<QByteArray> env = environment();
208 for (const auto &var : env) {
209 writeString(var);
210 }
211 writeLine("");
212 } else if (line == "end") {
213 return 0;
214 } else {
215 qCWarning(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
216 << "Unknown request:" << line;
217 return 1;
218 }
219 }
220
221 return 0;
222}
223
224QByteArray StubProcess::display()
225{
226 return m_cookie->display();
227}
228
229QByteArray StubProcess::displayAuth()
230{
231#if HAVE_X11
232 return m_cookie->displayAuth();
233#else
234 return QByteArray();
235#endif
236}
237
238void StubProcess::virtual_hook(int id, void *data)
239{
240 PtyProcess::virtual_hook(id, data);
241}
242
243} // namespace KDESu
QByteArray & append(QByteArrayView data)
bool isEmpty() const const
bool isNull() const const
QByteArray mid(qsizetype pos, qsizetype len) const const
void reserve(qsizetype size)
QByteArray & setNum(double n, char format, int precision)
qsizetype size() const const
bool isEmpty() const const
QString mid(qsizetype position, qsizetype n) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:55 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.