KDESu

stubprocess.cpp
1 /*
2  This file is part of the KDE project, module kdesu.
3  SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <[email protected]>
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 
19 extern int kdesuDebugArea();
20 
21 namespace KDESu
22 {
23 using namespace KDESuPrivate;
24 
25 StubProcess::StubProcess()
26  : StubProcess(*new StubProcessPrivate)
27 {
28 }
29 
30 StubProcess::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 
40 StubProcess::~StubProcess()
41 {
42  delete m_cookie;
43 }
44 
45 void StubProcess::setCommand(const QByteArray &command)
46 {
47  m_command = command;
48 }
49 
51 {
52  m_user = user;
53 }
54 
55 void StubProcess::setXOnly(bool xonly)
56 {
57  m_XOnly = xonly;
58 }
59 
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 
72 {
73  m_scheduler = sched;
74 }
75 
76 QByteArray StubProcess::commaSeparatedList(const QList<QByteArray> &lst)
77 {
78  QByteArray str;
79  for (const auto &ba : lst) {
80  str += ',';
81  str += ba;
82  }
83  return str;
84 }
85 
86 void StubProcess::writeString(const QByteArray &str)
87 {
88  QByteArray out;
89  out.reserve(str.size() + 8);
90  for (const uchar c : str) {
91  if (c < 32) {
92  out.append('\\');
93  out.append(c + '@');
94  } else if (c == '\\') {
95  out.append('\\');
96  out.append('/');
97  } else {
98  out.append(c);
99  }
100  }
101  writeLine(out);
102 }
103 
104 /*
105  * Map pid_t to a signed integer type that makes sense for QByteArray;
106  * only the most common sizes 16 bit and 32 bit are special-cased.
107  */
108 template<int T>
109 struct PIDType {
110  typedef pid_t PID_t;
111 };
112 template<>
113 struct PIDType<2> {
114  typedef qint16 PID_t;
115 };
116 template<>
117 struct PIDType<4> {
118  typedef qint32 PID_t;
119 };
120 
121 /*
122  * Conversation with kdesu_stub. This is how we pass the authentication
123  * tokens (X11) and other stuff to kdesu_stub.
124  * return values: -1 = error, 0 = ok, 1 = kill me
125  */
126 
128 {
129  QByteArray line;
130  QByteArray tmp;
131 
132  while (1) {
133  line = readLine();
134  if (line.isNull()) {
135  return -1;
136  }
137 
138  if (line == "kdesu_stub") {
139  // This makes parsing a lot easier.
140  enableLocalEcho(false);
141  if (check) {
142  writeLine("stop");
143  } else {
144  writeLine("ok");
145  }
146  break;
147  }
148  }
149 
150  while (1) {
151  line = readLine();
152  if (line.isNull()) {
153  return -1;
154  }
155 
156  if (line == "display") {
157  writeLine(display());
158  } else if (line == "display_auth") {
159 #if HAVE_X11
161 #else
162  writeLine("");
163 #endif
164  } else if (line == "command") {
165  writeString(m_command);
166  } else if (line == "path") {
167  QByteArray path = qgetenv("PATH");
168  if (!path.isEmpty() && path[0] == ':') {
169  path = path.mid(1);
170  }
171  if (m_user == "root") {
172  if (!path.isEmpty()) {
173  path = "/sbin:/bin:/usr/sbin:/usr/bin:" + path;
174  } else {
175  path = "/sbin:/bin:/usr/sbin:/usr/bin";
176  }
177  }
178  writeLine(path);
179  } else if (line == "user") {
180  writeLine(m_user);
181  } else if (line == "priority") {
182  tmp.setNum(m_priority);
183  writeLine(tmp);
184  } else if (line == "scheduler") {
185  if (m_scheduler == SchedRealtime) {
186  writeLine("realtime");
187  } else {
188  writeLine("normal");
189  }
190  } else if (line == "xwindows_only") {
191  if (m_XOnly) {
192  writeLine("no");
193  } else {
194  writeLine("yes");
195  }
196  } else if (line == "app_startup_id") {
197  const QList<QByteArray> env = environment();
198  QByteArray tmp;
199  static const char startup_env[] = "DESKTOP_STARTUP_ID=";
200  static const std::size_t size = sizeof(startup_env);
201  for (const auto &var : env) {
202  if (var.startsWith(startup_env)) {
203  tmp = var.mid(size - 1);
204  }
205  }
206  if (tmp.isEmpty()) {
207  tmp = "0"; // krazy:exclude=doublequote_chars
208  }
209  writeLine(tmp);
210  } else if (line == "app_start_pid") { // obsolete
211  // Force the pid_t returned from getpid() into
212  // something QByteArray understands; avoids ambiguity
213  // between short and unsigned short in particular.
214  tmp.setNum((PIDType<sizeof(pid_t)>::PID_t)(getpid()));
215  writeLine(tmp);
216  } else if (line == "environment") { // additional env vars
217  const QList<QByteArray> env = environment();
218  for (const auto &var : env) {
219  writeString(var);
220  }
221  writeLine("");
222  } else if (line == "end") {
223  return 0;
224  } else {
225  qCWarning(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
226  << "Unknown request:" << line;
227  return 1;
228  }
229  }
230 
231  return 0;
232 }
233 
235 {
236  return m_cookie->display();
237 }
238 
240 {
241 #if HAVE_X11
242  return m_cookie->displayAuth();
243 #else
244  return QByteArray();
245 #endif
246 }
247 
248 void StubProcess::virtual_hook(int id, void *data)
249 {
250  PtyProcess::virtual_hook(id, data);
251 }
252 
253 } // namespace KDESu
bool isNull() const const
void writeLine(const QByteArray &line, bool addNewline=true)
Writes a line of text to the program's standard in.
Definition: ptyprocess.cpp:236
QByteArray & append(char ch)
int enableLocalEcho(bool enable=true)
Enables/disables local echo on the pseudo tty.
Definition: ptyprocess.cpp:372
QByteArray & setNum(short n, int base)
int converseStub(int check)
Exchange all parameters with kdesu_stub.
virtual QByteArray display()
This virtual function can be overloaded when special behavior is desired.
QByteArray readLine(bool block=true)
Reads a line from the program's standard out.
Definition: ptyprocess.cpp:215
virtual void virtual_hook(int id, void *data)
Standard hack to add virtual methods in a BC way.
Definition: ptyprocess.cpp:514
void setPriority(int prio)
Set the priority of the process.
Definition: stubprocess.cpp:60
void setScheduler(int sched)
Set the scheduler type.
Definition: stubprocess.cpp:71
QList< QByteArray > environment() const
Returns the additional environment variables set by setEnvironment()
Definition: ptyprocess.cpp:159
QByteArray mid(int pos, int len) const const
void setXOnly(bool xonly)
Set to "X only mode": Sycoca is not built and kdeinit is not launched.
Definition: stubprocess.cpp:55
void setCommand(const QByteArray &command)
Set the command.
Definition: stubprocess.cpp:45
virtual QByteArray displayAuth()
See display.
bool isEmpty() const const
void reserve(int size)
int size() const const
void virtual_hook(int id, void *data) override
Standard hack to add virtual methods in a BC way.
void setUser(const QByteArray &user)
Set the target user.
Definition: stubprocess.cpp:50
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sun Jun 26 2022 03:48:58 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.