From c450793f314547eb3573d3a3dc8c75aef82c19bf Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Wed, 18 Jul 2018 13:41:29 -0500 Subject: [PATCH] Port from xauth to libXau Rebase https://github.com/sddm/sddm/pull/863 As part of an effort to support https://github.com/sddm/sddm/issues/733 and make sddm more resilient to hostname changes --- CMakeLists.txt | 3 ++ cmake/FindXAU.cmake | 54 ++++++++++++++++++++++++++++ src/daemon/CMakeLists.txt | 4 ++- src/daemon/XorgDisplayServer.cpp | 62 ++++++++++++++++++++++++-------- src/helper/CMakeLists.txt | 2 +- src/helper/UserSession.cpp | 55 +++++++++++++++++++++------- 6 files changed, 150 insertions(+), 30 deletions(-) create mode 100644 cmake/FindXAU.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 8500c65..4e62a4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,9 @@ find_package(XCB REQUIRED) # XKB find_package(XKB REQUIRED) +# XAU +find_package(XAU REQUIRED) + # Qt 5 find_package(Qt5 5.8.0 CONFIG REQUIRED Core DBus Gui Qml Quick LinguistTools Test) diff --git a/cmake/FindXAU.cmake b/cmake/FindXAU.cmake new file mode 100644 index 0000000..03cafb7 --- /dev/null +++ b/cmake/FindXAU.cmake @@ -0,0 +1,54 @@ +# - Try to find libXau +# Once done this will define +# +# LIBXAU_FOUND - system has libXau +# LIBXAU_LIBRARIES - Link these to use libXau +# LIBXAU_INCLUDE_DIR - the libXau include dir +# LIBXAU_DEFINITIONS - compiler switches required for using libXau + +# Copyright (c) 2008 Helio Chissini de Castro, +# Copyright (c) 2007, Matthias Kretz, +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +IF (NOT WIN32) + IF (LIBXAU_INCLUDE_DIR AND LIBXAU_LIBRARIES) + # in cache already + SET(XAU_FIND_QUIETLY TRUE) + ENDIF (LIBXAU_INCLUDE_DIR AND LIBXAU_LIBRARIES) + + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_XAU xau) + + SET(LIBXAU_DEFINITIONS ${PKG_XAU_CFLAGS}) + + FIND_PATH(LIBXAU_INCLUDE_DIR XAuth.h ${PKG_XAU_INCLUDE_DIR}) + FIND_LIBRARY(LIBXAU_LIBRARIES NAMES Xau libXau PATHS ${PKG_XAU_LIBRARY_DIRS}) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(XAU DEFAULT_MSG LIBXAU_LIBRARIES) + + MARK_AS_ADVANCED(LIBXAU_INCLUDE_DIR LIBXAU_LIBRARIES) +ENDIF (NOT WIN32) diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 5d767c8..befc13d 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -57,7 +57,9 @@ target_link_libraries(sddm Qt5::DBus Qt5::Network Qt5::Qml - ${LIBXCB_LIBRARIES}) + ${LIBXCB_LIBRARIES} + ${LIBXAU_LIBRARIES} +) if(PAM_FOUND) target_link_libraries(sddm ${PAM_LIBRARIES}) else() diff --git a/src/daemon/XorgDisplayServer.cpp b/src/daemon/XorgDisplayServer.cpp index 28ce524..13faf03 100644 --- a/src/daemon/XorgDisplayServer.cpp +++ b/src/daemon/XorgDisplayServer.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -88,28 +89,59 @@ namespace SDDM { } void XorgDisplayServer::addCookie(const QString &file) { - // log message + Xauth auth = { 0 }; + char localhost[HOST_NAME_MAX + 1] = { 0 }; + qDebug() << "Adding cookie to" << file; - // Touch file - QFile file_handler(file); - file_handler.open(QIODevice::Append); - file_handler.close(); + if (gethostname(localhost, HOST_NAME_MAX) < 0) { + strcpy(localhost, "localhost"); + } - QString cmd = QStringLiteral("%1 -f %2 -q").arg(mainConfig.X11.XauthPath.get()).arg(file); + // libXau expects binary data, not a string + QByteArray cookieBinary = QByteArray::fromHex(m_cookie.toLatin1()); + + // set up the auth entry + char cookieName[] = "MIT-MAGIC-COOKIE-1"; + char displayNumber[m_display.size() + 1] = { 0 }; + strcpy(displayNumber, qPrintable(m_display.mid(1))); // Need to skip the ':' + auth.family = FamilyLocal; + auth.address = localhost; + auth.address_length = strlen(auth.address); + auth.number = displayNumber; + auth.number_length = strlen(auth.number); + auth.name = cookieName; + auth.name_length = strlen(cookieName); + auth.data_length = cookieBinary.count(); + auth.data = cookieBinary.data(); + + // create the path + QFileInfo finfo(file); + QDir().mkpath(finfo.absolutePath()); + + // open the file + FILE *fp = fopen(qPrintable(file), "w"); + if (!fp) { + qWarning() << "Opening the Xauthority file at" << file << "failed"; + return; + } - // execute xauth - FILE *fp = popen(qPrintable(cmd), "w"); + // write the Xauth data + if (!XauWriteAuth (fp, &auth) || fflush (fp) == EOF) { + qWarning() << "Writing the FamilyLocal information to" << file << "failed"; + fclose(fp); + return; + } - // check file - if (!fp) + auth.family = FamilyWild; + + if (!XauWriteAuth (fp, &auth) || fflush (fp) == EOF) { + qWarning() << "Writing the FamilyWild information to" << file << "failed"; + fclose(fp); return; - fprintf(fp, "remove %s\n", qPrintable(m_display)); - fprintf(fp, "add %s . %s\n", qPrintable(m_display), qPrintable(m_cookie)); - fprintf(fp, "exit\n"); + } - // close pipe - pclose(fp); + fclose(fp); } bool XorgDisplayServer::start() { diff --git a/src/helper/CMakeLists.txt b/src/helper/CMakeLists.txt index ebf4a6e..51d47ef 100644 --- a/src/helper/CMakeLists.txt +++ b/src/helper/CMakeLists.txt @@ -31,7 +31,7 @@ else() endif() add_executable(sddm-helper ${HELPER_SOURCES}) -target_link_libraries(sddm-helper Qt5::Network Qt5::DBus Qt5::Qml) +target_link_libraries(sddm-helper Qt5::Network Qt5::DBus Qt5::Qml ${LIBXAU_LIBRARIES}) if(PAM_FOUND) target_link_libraries(sddm-helper ${PAM_LIBRARIES}) else() diff --git a/src/helper/UserSession.cpp b/src/helper/UserSession.cpp index d4fd2cf..d597935 100644 --- a/src/helper/UserSession.cpp +++ b/src/helper/UserSession.cpp @@ -34,6 +34,9 @@ #include #include +#include + + namespace SDDM { UserSession::UserSession(HelperApp *parent) : QProcess(parent) { @@ -270,31 +273,57 @@ namespace SDDM { if (!cookie.isEmpty()) { QString file = processEnvironment().value(QStringLiteral("XAUTHORITY")); QString display = processEnvironment().value(QStringLiteral("DISPLAY")); + Xauth auth = { 0 }; + char localhost[HOST_NAME_MAX + 1] = { 0 }; + qDebug() << "Adding cookie to" << file; + if (gethostname(localhost, HOST_NAME_MAX) < 0) { + strcpy(localhost, "localhost"); + } + + // libXau expects binary data, not a string + QByteArray cookieBinary = QByteArray::fromHex(cookie.toLatin1()); + + // set up the auth entry + char cookieName[] = "MIT-MAGIC-COOKIE-1"; + char displayNumber[display.size() + 1] = { 0 }; + strcpy(displayNumber, qPrintable(display.mid(1))); // Need to skip the ':' + auth.family = FamilyLocal; + auth.address = localhost; + auth.address_length = strlen(auth.address); + auth.number = displayNumber; + auth.number_length = strlen(auth.number); + auth.name = cookieName; + auth.name_length = strlen(cookieName); + auth.data_length = cookieBinary.count(); + auth.data = cookieBinary.data(); // create the path QFileInfo finfo(file); QDir().mkpath(finfo.absolutePath()); - QFile file_handler(file); - file_handler.open(QIODevice::Append); - file_handler.close(); + // open the file + FILE *fp = fopen(qPrintable(file), "w"); + if (!fp) + qWarning() << "Opening the Xauthority file at" << file << "failed"; - QString cmd = QStringLiteral("%1 -f %2 -q").arg(mainConfig.X11.XauthPath.get()).arg(file); + // write the Xauth data + if (!XauWriteAuth (fp, &auth) || fflush (fp) == EOF) { + qCritical() << "Writing the FamilyLocal information to" << file << "failed"; + fclose(fp); + return; + } - // execute xauth - FILE *fp = popen(qPrintable(cmd), "w"); + auth.family = FamilyWild; - // check file - if (!fp) + if (!XauWriteAuth (fp, &auth) || fflush (fp) == EOF) { + qCritical() << "Writing the FamilyWild information to" << file << "failed"; + fclose(fp); return; - fprintf(fp, "remove %s\n", qPrintable(display)); - fprintf(fp, "add %s . %s\n", qPrintable(display), qPrintable(cookie)); - fprintf(fp, "exit\n"); + } - // close pipe - pclose(fp); + fclose(fp); } } -- 2.17.1