Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.1:Staging:B
kwin5
0001-Use-Xauthority-for-Xwayland.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-Use-Xauthority-for-Xwayland.patch of Package kwin5
From 10011387cd146f6b92f337b4c10ac4000c981891 Mon Sep 17 00:00:00 2001 From: Fabian Vogt <fabian@ritter-vogt.de> Date: Sat, 17 Mar 2018 23:25:56 +0100 Subject: [PATCH] Use Xauthority for Xwayland References: boo#1084737 Needed by kdesu, su, ... If creation fails, it will fall back to not using it. --- CMakeLists.txt | 1 + main_wayland.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- main_wayland.h | 2 ++ 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cbf9529ca..ba9ac6584 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -579,6 +579,7 @@ set(kwin_XLIB_LIBS ${X11_X11_LIB} ${X11_ICE_LIB} ${X11_SM_LIB} + ${X11_Xau_LIB} ) set(kwin_XCB_LIBS diff --git a/main_wayland.cpp b/main_wayland.cpp index 2107bc85a..b3e5c6cf3 100644 --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -70,6 +70,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <sys/capability.h> #endif +#include <X11/Xauth.h> + #include <sched.h> #include <iostream> @@ -157,6 +159,16 @@ void ApplicationWayland::performStartup() { if (m_startXWayland) { setOperationMode(OperationModeXwayland); + + QString dir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); + if (!dir.isEmpty()) { + m_xwaylandAuthority.setFileTemplate(dir + QStringLiteral("/xauth_XXXXXX")); + m_xwaylandAuthority.open(); + } + + if (m_xwaylandAuthority.fileName().isEmpty()) { + std::cerr << "Warning: Could not create a Xauthority file for Xwayland." << std::endl; + } } // first load options - done internally by a different thread createOptions(); @@ -206,8 +218,89 @@ void ApplicationWayland::continueStartupWithSceen() notifyKSplash(); } +static QByteArray getRandomData(qint64 bytes) +{ + QFile random(QStringLiteral("/dev/urandom")); + if (!random.open(QIODevice::ReadOnly)) + return {}; + + QByteArray data; + data.resize(bytes); + while (bytes) { + auto bytesRead = random.read(data.data() + data.size() - bytes, bytes); + if (bytesRead == -1) + return {}; + + bytes -= bytesRead; + } + + return data; +} + +static bool addCookieToFile(QString filename, QString &hostname) +{ + QByteArray cookie = getRandomData(16); + char *displayNumber = getenv("DISPLAY"); + + if(displayNumber == nullptr || displayNumber[0] == '\0' || cookie.count() != 16) { + return false; + } + + FILE *authFp = fopen(qPrintable(filename), "wb"); + if (authFp == nullptr) { + return false; + } + + char localhost[HOST_NAME_MAX + 1] = ""; + if (gethostname(localhost, HOST_NAME_MAX) < 0) { + strcpy(localhost, "localhost"); + } + + hostname = QString::fromUtf8(localhost); + + Xauth auth = {}; + char cookieName[] = "MIT-MAGIC-COOKIE-1"; + + auth.family = FamilyLocal; + auth.address = localhost; + auth.address_length = strlen(auth.address); + auth.number = displayNumber + 1; + auth.number_length = strlen(auth.number); + auth.name = cookieName; + auth.name_length = sizeof(cookieName) - 1; + auth.data = cookie.data(); + auth.data_length = cookie.count(); + + if (XauWriteAuth(authFp, &auth) == 0) { + fclose(authFp); + return false; + } + + auth.family = FamilyWild; + bool success = XauWriteAuth(authFp, &auth) != 0 && fflush(authFp) != EOF; + + fclose(authFp); + + return success; +} + void ApplicationWayland::continueStartupWithX() { + if (!m_xwaylandAuthority.fileName().isEmpty()) { + QString hostname; + if (addCookieToFile(m_xwaylandAuthority.fileName(), hostname)) { + setenv("XAUTHORITY", qPrintable(m_xwaylandAuthority.fileName()), 1); + setenv("XAUTHLOCALHOSTNAME", qPrintable(hostname), 1); + m_environment.insert(QStringLiteral("XAUTHORITY"), m_xwaylandAuthority.fileName()); + m_environment.insert(QStringLiteral("XAUTHLOCALHOSTNAME"), hostname); + } + else { + std::cerr << "Could not generate Xauthority entry" << std::endl; + // We can't authenticate using it so the server must not see any entries either + m_xwaylandAuthority.resize(0); + } + } + createX11Connection(); xcb_connection_t *c = x11Connection(); if (!c) { @@ -377,11 +470,15 @@ void ApplicationWayland::startXwaylandServer() env.insert("WAYLAND_SOCKET", QByteArray::number(wlfd)); env.insert("EGL_PLATFORM", QByteArrayLiteral("DRM")); m_xwaylandProcess->setProcessEnvironment(env); - m_xwaylandProcess->setArguments({QStringLiteral("-displayfd"), + QStringList args{QStringLiteral("-displayfd"), QString::number(pipeFds[1]), QStringLiteral("-rootless"), QStringLiteral("-wm"), - QString::number(fd)}); + QString::number(fd)}; + if (!m_xwaylandAuthority.fileName().isEmpty()) { + args << QStringLiteral("-auth") << m_xwaylandAuthority.fileName(); + } + m_xwaylandProcess->setArguments(args); m_xwaylandFailConnection = connect(m_xwaylandProcess, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::error), this, [] (QProcess::ProcessError error) { if (error == QProcess::FailedToStart) { diff --git a/main_wayland.h b/main_wayland.h index 31b7ebd55..37f9b2882 100644 --- a/main_wayland.h +++ b/main_wayland.h @@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #define KWIN_MAIN_WAYLAND_H #include "main.h" #include <QProcessEnvironment> +#include <QTemporaryFile> class QProcess; @@ -74,6 +75,7 @@ private: QMetaObject::Connection m_xwaylandFailConnection; QProcessEnvironment m_environment; QString m_sessionArgument; + QTemporaryFile m_xwaylandAuthority; }; } -- 2.16.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor