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 | kcookie.cpp: KDE authentication cookies. |
8 | */ |
9 | |
10 | #include "kcookie_p.h" |
11 | |
12 | #include <ksu_debug.h> |
13 | |
14 | #include <QProcess> |
15 | #include <QStandardPaths> |
16 | #include <QString> |
17 | #include <QStringList> |
18 | |
19 | extern int kdesuDebugArea(); |
20 | |
21 | namespace KDESu |
22 | { |
23 | namespace KDESuPrivate |
24 | { |
25 | class KCookiePrivate |
26 | { |
27 | public: |
28 | QByteArray display; |
29 | #if HAVE_X11 |
30 | QByteArray displayAuth; |
31 | #endif |
32 | }; |
33 | |
34 | KCookie::KCookie() |
35 | : d(new KCookiePrivate) |
36 | { |
37 | #if HAVE_X11 |
38 | getXCookie(); |
39 | #endif |
40 | } |
41 | |
42 | KCookie::~KCookie() = default; |
43 | |
44 | QByteArray KCookie::display() const |
45 | { |
46 | return d->display; |
47 | } |
48 | |
49 | #if HAVE_X11 |
50 | QByteArray KCookie::displayAuth() const |
51 | { |
52 | return d->displayAuth; |
53 | } |
54 | #endif |
55 | |
56 | void KCookie::getXCookie() |
57 | { |
58 | #if HAVE_X11 |
59 | d->display = qgetenv(varName: "DISPLAY" ); |
60 | if (d->display.isEmpty()) { |
61 | // maybe we are on Wayland? |
62 | d->display = qgetenv(varName: "WAYLAND_DISPLAY" ); |
63 | if (!d->display.isEmpty()) { |
64 | // don't go into the xauth code path |
65 | return; |
66 | } |
67 | } |
68 | #else |
69 | d->display = qgetenv("QWS_DISPLAY" ); |
70 | #endif |
71 | if (d->display.isEmpty()) { |
72 | qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] " |
73 | << "$DISPLAY is not set." ; |
74 | return; |
75 | } |
76 | #if HAVE_X11 // No need to mess with X Auth stuff |
77 | QByteArray disp = d->display; |
78 | if (disp.startsWith(bv: "localhost:" )) { // krazy:exclude=strings |
79 | disp.remove(index: 0, len: 9); |
80 | } |
81 | |
82 | const QString xauthExec = QStandardPaths::findExecutable(QStringLiteral("xauth" )); |
83 | if (xauthExec.isEmpty()) { |
84 | qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] " |
85 | << "Could not run xauth, not found in path" ; |
86 | return; |
87 | } |
88 | |
89 | QProcess proc; |
90 | proc.start(program: xauthExec, arguments: QStringList{QStringLiteral("list" ), QString::fromUtf8(ba: disp)}); |
91 | if (!proc.waitForStarted()) { |
92 | qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] " |
93 | << "Could not run xauth. Found in path:" << xauthExec; |
94 | return; |
95 | } |
96 | proc.waitForReadyRead(msecs: 100); |
97 | |
98 | QByteArray output = proc.readLine().simplified(); |
99 | if (output.isEmpty()) { |
100 | qCWarning(KSU_LOG) << "No X authentication info set for display" << d->display; |
101 | return; |
102 | } |
103 | |
104 | QList<QByteArray> lst = output.split(sep: ' '); |
105 | if (lst.count() != 3) { |
106 | qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] " |
107 | << "parse error." ; |
108 | return; |
109 | } |
110 | d->displayAuth = (lst[1] + ' ' + lst[2]); |
111 | proc.waitForFinished(msecs: 100); // give QProcess a chance to clean up gracefully |
112 | #endif |
113 | } |
114 | |
115 | } // namespace KDESuPrivate |
116 | } // namespace KDESu |
117 | |