File indexing completed on 2024-11-10 04:57:38

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0006     SPDX-FileCopyrightText: 2021 David Edmundson <davidedmundson@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "xauthority.h"
0012 
0013 #include <QDataStream>
0014 #include <QRandomGenerator>
0015 #include <QStandardPaths>
0016 #include <QSysInfo>
0017 #include <QTemporaryFile>
0018 
0019 static void writeXauthorityEntry(QDataStream &stream, quint16 family,
0020                                  const QByteArray &address, const QByteArray &display,
0021                                  const QByteArray &name, const QByteArray &cookie)
0022 {
0023     stream << quint16(family);
0024 
0025     auto writeArray = [&stream](const QByteArray &str) {
0026         stream << quint16(str.size());
0027         stream.writeRawData(str.constData(), str.size());
0028     };
0029 
0030     writeArray(address);
0031     writeArray(display);
0032     writeArray(name);
0033     writeArray(cookie);
0034 }
0035 
0036 static QByteArray generateXauthorityCookie()
0037 {
0038     QByteArray cookie;
0039     cookie.resize(16); // Cookie must be 128bits
0040 
0041     QRandomGenerator *generator = QRandomGenerator::system();
0042     for (int i = 0; i < cookie.size(); ++i) {
0043         cookie[i] = uint8_t(generator->bounded(256));
0044     }
0045     return cookie;
0046 }
0047 
0048 bool generateXauthorityFile(int display, QTemporaryFile *authorityFile)
0049 {
0050     const QString runtimeDirectory = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation);
0051 
0052     authorityFile->setFileTemplate(runtimeDirectory + QStringLiteral("/xauth_XXXXXX"));
0053     if (!authorityFile->open()) {
0054         return false;
0055     }
0056 
0057     const QByteArray hostname = QSysInfo::machineHostName().toUtf8();
0058     const QByteArray displayName = QByteArray::number(display);
0059     const QByteArray name = QByteArrayLiteral("MIT-MAGIC-COOKIE-1");
0060     const QByteArray cookie = generateXauthorityCookie();
0061 
0062     QDataStream stream(authorityFile);
0063     stream.setByteOrder(QDataStream::BigEndian);
0064 
0065     // Write entry with FamilyLocal and the host name as address
0066     writeXauthorityEntry(stream, 256 /* FamilyLocal */, hostname, displayName, name, cookie);
0067 
0068     // Write entry with FamilyWild, no address
0069     writeXauthorityEntry(stream, 65535 /* FamilyWild */, QByteArray{}, displayName, name, cookie);
0070 
0071     if (stream.status() != QDataStream::Ok || !authorityFile->flush()) {
0072         authorityFile->remove();
0073         return false;
0074     }
0075 
0076     return true;
0077 }