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 }