Blob Blame History Raw
From 6532fa6c875481566f4e98daf944627b75355613 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20B=C5=99=C3=ADza?= <mbriza@redhat.com>
Date: Tue, 15 Aug 2017 17:23:56 +0200
Subject: [PATCH] Port from xauth to libXau

---
 CMakeLists.txt                   |  3 +++
 cmake/FindXAU.cmake              | 54 ++++++++++++++++++++++++++++++++++++++
 src/daemon/CMakeLists.txt        |  4 ++-
 src/daemon/XorgDisplayServer.cpp | 56 +++++++++++++++++++++++++++++-----------
 src/helper/CMakeLists.txt        |  5 +++-
 src/helper/UserSession.cpp       | 52 +++++++++++++++++++++++++++----------
 6 files changed, 143 insertions(+), 31 deletions(-)
 create mode 100644 cmake/FindXAU.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 23e0383..abb9b7e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -88,6 +88,9 @@ find_package(XCB REQUIRED)
 # XKB
 find_package(XKB REQUIRED)
 
+# XKB
+find_package(XAU REQUIRED)
+
 # Qt 5
 find_package(Qt5 5.6.0 CONFIG REQUIRED Core DBus Gui Qml Quick LinguistTools)
 
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, <helio@kde.org>
+# Copyright (c) 2007, Matthias Kretz, <kretz@kde.org>
+#
+# 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 77fe55e..054d526 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -39,7 +39,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 7656856..46e7452 100644
--- a/src/daemon/XorgDisplayServer.cpp
+++ b/src/daemon/XorgDisplayServer.cpp
@@ -33,6 +33,7 @@
 #include <random>
 
 #include <xcb/xcb.h>
+#include <X11/Xauth.h>
 
 #include <pwd.h>
 #include <unistd.h>
@@ -87,28 +88,57 @@ 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::WriteOnly);
-        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";
 
-        // execute xauth
-        FILE *fp = popen(qPrintable(cmd), "w");
+        // write the Xauth data
+        if (!XauWriteAuth (fp, &auth) || fflush (fp) == EOF) {
+            qCritical() << "Writing the FamilyLocal information to" << file << "failed";
+            fclose(fp);
+            return;
+        }
 
-        // check file
-        if (!fp)
+        auth.family = FamilyWild;
+
+        if (!XauWriteAuth (fp, &auth) || fflush (fp) == EOF) {
+            qCritical() << "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 8163d94..3e76577 100644
--- a/src/helper/CMakeLists.txt
+++ b/src/helper/CMakeLists.txt
@@ -27,7 +27,10 @@ else()
 endif()
 
 add_executable(sddm-helper ${HELPER_SOURCES})
-target_link_libraries(sddm-helper Qt5::Network)
+target_link_libraries(sddm-helper
+    Qt5::Network
+    ${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 587888d..8690cb0 100644
--- a/src/helper/UserSession.cpp
+++ b/src/helper/UserSession.cpp
@@ -31,6 +31,9 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+#include <X11/Xauth.h>
+
+
 namespace SDDM {
     UserSession::UserSession(HelperApp *parent)
             : QProcess(parent) {
@@ -169,31 +172,57 @@
         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::WriteOnly);
-            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.13.4