File indexing completed on 2024-04-21 03:53:58

0001 /*
0002     This file is part of the KDE project, module kdesu.
0003     SPDX-FileCopyrightText: 1999, 2000 Geert Jansen <jansen@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-only
0006 
0007     kcookie.cpp: KDE authentication cookies.
0008 */
0009 
0010 #include "kcookie_p.h"
0011 
0012 #include <ksu_debug.h>
0013 
0014 #include <QProcess>
0015 #include <QStandardPaths>
0016 #include <QString>
0017 #include <QStringList>
0018 
0019 extern int kdesuDebugArea();
0020 
0021 namespace KDESu
0022 {
0023 namespace KDESuPrivate
0024 {
0025 class KCookiePrivate
0026 {
0027 public:
0028     QByteArray display;
0029 #if HAVE_X11
0030     QByteArray displayAuth;
0031 #endif
0032 };
0033 
0034 KCookie::KCookie()
0035     : d(new KCookiePrivate)
0036 {
0037 #if HAVE_X11
0038     getXCookie();
0039 #endif
0040 }
0041 
0042 KCookie::~KCookie() = default;
0043 
0044 QByteArray KCookie::display() const
0045 {
0046     return d->display;
0047 }
0048 
0049 #if HAVE_X11
0050 QByteArray KCookie::displayAuth() const
0051 {
0052     return d->displayAuth;
0053 }
0054 #endif
0055 
0056 void KCookie::getXCookie()
0057 {
0058 #if HAVE_X11
0059     d->display = qgetenv("DISPLAY");
0060     if (d->display.isEmpty()) {
0061         // maybe we are on Wayland?
0062         d->display = qgetenv("WAYLAND_DISPLAY");
0063         if (!d->display.isEmpty()) {
0064             // don't go into the xauth code path
0065             return;
0066         }
0067     }
0068 #else
0069     d->display = qgetenv("QWS_DISPLAY");
0070 #endif
0071     if (d->display.isEmpty()) {
0072         qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
0073                             << "$DISPLAY is not set.";
0074         return;
0075     }
0076 #if HAVE_X11 // No need to mess with X Auth stuff
0077     QByteArray disp = d->display;
0078     if (disp.startsWith("localhost:")) { // krazy:exclude=strings
0079         disp.remove(0, 9);
0080     }
0081 
0082     const QString xauthExec = QStandardPaths::findExecutable(QStringLiteral("xauth"));
0083     if (xauthExec.isEmpty()) {
0084         qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
0085                             << "Could not run xauth, not found in path";
0086         return;
0087     }
0088 
0089     QProcess proc;
0090     proc.start(xauthExec, QStringList{QStringLiteral("list"), QString::fromUtf8(disp)});
0091     if (!proc.waitForStarted()) {
0092         qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
0093                             << "Could not run xauth. Found in path:" << xauthExec;
0094         return;
0095     }
0096     proc.waitForReadyRead(100);
0097 
0098     QByteArray output = proc.readLine().simplified();
0099     if (output.isEmpty()) {
0100         qCWarning(KSU_LOG) << "No X authentication info set for display" << d->display;
0101         return;
0102     }
0103 
0104     QList<QByteArray> lst = output.split(' ');
0105     if (lst.count() != 3) {
0106         qCCritical(KSU_LOG) << "[" << __FILE__ << ":" << __LINE__ << "] "
0107                             << "parse error.";
0108         return;
0109     }
0110     d->displayAuth = (lst[1] + ' ' + lst[2]);
0111     proc.waitForFinished(100); // give QProcess a chance to clean up gracefully
0112 #endif
0113 }
0114 
0115 } // namespace KDESuPrivate
0116 } // namespace KDESu