From 8d111c2f63a021266afbd6b156ed526c541d5f27 Mon Sep 17 00:00:00 2001 From: Martin Briza Date: Mon, 16 Dec 2013 15:31:34 +0100 Subject: [PATCH] Revert all work done on authentication for now --- ...0.2.0-0.11.20130914git50ca5b20-xdmcp.patch | 461 ++- sddm-auth.patch | 2596 ----------------- sddm-pam_end.patch | 14 + sddm-passwordless.pam | 16 - sddm-savelast.patch | 10 - sddm.spec | 21 +- 6 files changed, 231 insertions(+), 2887 deletions(-) delete mode 100644 sddm-auth.patch create mode 100644 sddm-pam_end.patch delete mode 100644 sddm-passwordless.pam delete mode 100644 sddm-savelast.patch diff --git a/sddm-0.2.0-0.11.20130914git50ca5b20-xdmcp.patch b/sddm-0.2.0-0.11.20130914git50ca5b20-xdmcp.patch index 845676f..b145c68 100644 --- a/sddm-0.2.0-0.11.20130914git50ca5b20-xdmcp.patch +++ b/sddm-0.2.0-0.11.20130914git50ca5b20-xdmcp.patch @@ -77,7 +77,7 @@ index cbef261..4b610d8 100644 bool testing { false }; diff --git a/src/daemon/DaemonApp.cpp b/src/daemon/DaemonApp.cpp -index c40cdea..616282e 100644 +index 9ad226b..9feb734 100644 --- a/src/daemon/DaemonApp.cpp +++ b/src/daemon/DaemonApp.cpp @@ -25,6 +25,7 @@ @@ -124,30 +124,28 @@ index 81f955c..2088010 100644 } diff --git a/src/daemon/Display.cpp b/src/daemon/Display.cpp -index 8517124..80aa95a 100644 +index f1a54b4..48137e6 100644 --- a/src/daemon/Display.cpp +++ b/src/daemon/Display.cpp -@@ -53,6 +53,19 @@ namespace SDDM { +@@ -53,6 +53,17 @@ namespace SDDM { return name; } -+ Display::Display(const QString& hostname, const int displayId, QObject* parent) -+ : QObject(parent) -+ , m_displayId(displayId) -+ , m_authenticator(new Authenticator(this)) -+ , m_displayServer(nullptr) -+ , m_socketServer(new SocketServer(this)) -+ , m_greeter(new Greeter(this)) -+ { ++ Display::Display(const QString& hostname, const int displayId, QObject* parent) : QObject(parent), ++ m_displayId(displayId), ++ m_authenticator(new Authenticator(this)), ++ m_displayServer(nullptr), ++ m_socketServer(new SocketServer(this)), ++ m_greeter(new Greeter(this)) { + m_display = QString("%1:%2").arg(hostname).arg(displayId); + + init(); + } + - Display::Display(const int displayId, const int terminalId, QObject *parent) : QObject(parent), + Display::Display(const int displayId, const int terminalId, Seat *parent) : QObject(parent), m_displayId(displayId), m_terminalId(terminalId), m_authenticator(new Authenticator(this)), -@@ -62,12 +75,17 @@ namespace SDDM { +@@ -63,12 +74,17 @@ namespace SDDM { m_display = QString(":%1").arg(m_displayId); @@ -168,7 +166,7 @@ index 8517124..80aa95a 100644 // connect login signal connect(m_socketServer, SIGNAL(login(QLocalSocket*,QString,QString,QString)), this, SLOT(login(QLocalSocket*,QString,QString,QString))); -@@ -90,6 +108,22 @@ namespace SDDM { +@@ -91,6 +107,22 @@ namespace SDDM { // set socket name m_socket = QString("sddm-%1-%2").arg(m_display).arg(generateName(6)); @@ -191,7 +189,7 @@ index 8517124..80aa95a 100644 } Display::~Display() { -@@ -112,6 +146,16 @@ namespace SDDM { +@@ -113,6 +145,16 @@ namespace SDDM { return m_cookie; } @@ -205,10 +203,10 @@ index 8517124..80aa95a 100644 + return cookie; + } + - void Display::addCookie(const QString &file) { - // log message - qDebug() << " DAEMON: Adding cookie to" << file; -@@ -139,28 +183,14 @@ namespace SDDM { + Seat *Display::seat() const { + return m_seat; + } +@@ -144,28 +186,14 @@ namespace SDDM { if (m_started) return; @@ -216,14 +214,14 @@ index 8517124..80aa95a 100644 - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(0, 15); -- -- // resever 32 bytes -- m_cookie.reserve(32); + if (m_displayServer != nullptr) { + // set display server params + m_displayServer->setDisplay(m_display); + m_displayServer->setAuthPath(m_authPath); +- // resever 32 bytes +- m_cookie.reserve(32); +- - // create a random hexadecimal number - const char *digits = "0123456789abcdef"; - for (int i = 0; i < 32; ++i) @@ -244,7 +242,7 @@ index 8517124..80aa95a 100644 if ((daemonApp->configuration()->first || daemonApp->configuration()->autoRelogin()) && !daemonApp->configuration()->autoUser().isEmpty() && !daemonApp->configuration()->lastSession().isEmpty()) { -@@ -216,9 +246,11 @@ namespace SDDM { +@@ -221,9 +249,11 @@ namespace SDDM { m_socketServer->stop(); // stop display server @@ -260,26 +258,26 @@ index 8517124..80aa95a 100644 // remove authority file QFile::remove(m_authPath); diff --git a/src/daemon/Display.h b/src/daemon/Display.h -index 9d82678..9c475a9 100644 +index 46d320b..9556209 100644 --- a/src/daemon/Display.h +++ b/src/daemon/Display.h -@@ -34,6 +34,7 @@ namespace SDDM { +@@ -35,6 +35,7 @@ namespace SDDM { Q_OBJECT Q_DISABLE_COPY(Display) public: + explicit Display(const QString& hostname, const int displayId, QObject *parent = 0); - explicit Display(const int displayId, const int terminalId, QObject *parent = 0); + explicit Display(const int displayId, const int terminalId, Seat *parent); ~Display(); -@@ -43,6 +44,7 @@ namespace SDDM { +@@ -44,6 +45,7 @@ namespace SDDM { const QString &name() const; const QString &cookie() const; + const QByteArray rawCookie() const; void addCookie(const QString &file); - public slots: -@@ -58,6 +60,8 @@ namespace SDDM { + Seat *seat() const; +@@ -61,6 +63,8 @@ namespace SDDM { void loginSucceeded(QLocalSocket *socket); private: @@ -290,10 +288,10 @@ index 9d82678..9c475a9 100644 diff --git a/src/daemon/xdmcp/Packet.cpp b/src/daemon/xdmcp/Packet.cpp new file mode 100644 -index 0000000..90688d0 +index 0000000..3a0c3d9 --- /dev/null +++ b/src/daemon/xdmcp/Packet.cpp -@@ -0,0 +1,435 @@ +@@ -0,0 +1,397 @@ +/* + * Packet type handling for X Display Control Protocol + * Copyright (C) 2013 Martin Bříza @@ -325,17 +323,15 @@ index 0000000..90688d0 +* PLUMBING + ******************************************************************************/ + -+ Packet::Packet(const QHostAddress& host, quint16 port) -+ : m_host(host) -+ , m_port(port) -+ , m_valid(true) { ++ Packet::Packet(const QHostAddress &host, quint16 port) : m_host(host), ++ m_port(port), ++ m_valid(true) { + + } + -+ Packet::Packet(const QHostAddress& host, quint16 port, Reader& r) -+ : m_host(host) -+ , m_port(port) -+ , m_valid(false) { ++ Packet::Packet(const QHostAddress &host, quint16 port, Reader &r) : m_host(host), ++ m_port(port), ++ m_valid(false) { + + } + @@ -348,7 +344,7 @@ index 0000000..90688d0 + } + + // static -+ Packet *Packet::decode(const QByteArray& data, const QHostAddress& host, quint16 port) { ++ Packet *Packet::decode(const QByteArray &data, const QHostAddress &host, quint16 port) { + Reader reader(data); + uint16_t version, opcode, length; + @@ -360,45 +356,45 @@ index 0000000..90688d0 + return nullptr; + + switch (opcode) { -+ case _Query: -+ return new Query(host, port, reader); -+ case _BroadcastQuery: -+ return new BroadcastQuery(host, port, reader); -+ case _IndirectQuery: -+ return new IndirectQuery(host, port, reader); -+ case _ForwardQuery: -+ return new ForwardQuery(host, port, reader); -+ case _Willing: -+ return new Willing(host, port, reader); -+ case _Unwilling: -+ return new Unwilling(host, port, reader); -+ case _Request: -+ return new Request(host, port, reader); -+ case _Accept: -+ return new Accept(host, port, reader); -+ case _Decline: -+ return new Decline(host, port, reader); -+ case _Manage: -+ return new Manage(host, port, reader); -+ case _Refuse: -+ return new Refuse(host, port, reader); -+ case _Failed: -+ return new Failed(host, port, reader); -+ case _KeepAlive: -+ return new KeepAlive(host, port, reader); -+ case _Alive: -+ return new Alive(host, port, reader); -+ default: -+ qDebug() << " XDMCP: Got packet of an unknown type" << opcode; -+ return nullptr; ++ case _Query: ++ return new Query(host, port, reader); ++ case _BroadcastQuery: ++ return new BroadcastQuery(host, port, reader); ++ case _IndirectQuery: ++ return new IndirectQuery(host, port, reader); ++ case _ForwardQuery: ++ return new ForwardQuery(host, port, reader); ++ case _Willing: ++ return new Willing(host, port, reader); ++ case _Unwilling: ++ return new Unwilling(host, port, reader); ++ case _Request: ++ return new Request(host, port, reader); ++ case _Accept: ++ return new Accept(host, port, reader); ++ case _Decline: ++ return new Decline(host, port, reader); ++ case _Manage: ++ return new Manage(host, port, reader); ++ case _Refuse: ++ return new Refuse(host, port, reader); ++ case _Failed: ++ return new Failed(host, port, reader); ++ case _KeepAlive: ++ return new KeepAlive(host, port, reader); ++ case _Alive: ++ return new Alive(host, port, reader); ++ default: ++ qDebug() << " XDMCP: Got packet of an unknown type" << opcode; ++ return nullptr; + } + } + -+ void Packet::setHost(const QHostAddress host) { ++ void Packet::setHost(const QHostAddress &host) { + m_host = QHostAddress(host); + } + -+ QHostAddress Packet::host() const { ++ const QHostAddress& Packet::host() const { + return m_host; + } + @@ -424,12 +420,10 @@ index 0000000..90688d0 + return nullptr; + } + -+ Packet::Query::Query(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::Query::Query(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_authenticationNames; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Query::encode() const { @@ -438,12 +432,10 @@ index 0000000..90688d0 + return w.finalize(Packet::_Query); + } + -+ Packet::BroadcastQuery::BroadcastQuery(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::BroadcastQuery::BroadcastQuery(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_authenticationNames; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::BroadcastQuery::encode() const { @@ -452,12 +444,10 @@ index 0000000..90688d0 + return w.finalize(Packet::_BroadcastQuery); + } + -+ Packet::IndirectQuery::IndirectQuery(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::IndirectQuery::IndirectQuery(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_authenticationNames; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::IndirectQuery::encode() const { @@ -466,11 +456,10 @@ index 0000000..90688d0 + return w.finalize(Packet::_IndirectQuery); + } + -+ Packet::ForwardQuery::ForwardQuery(const QHostAddress& host, quint16 port, Reader& r) : Packet(host, port, r) { ++ Packet::ForwardQuery::ForwardQuery(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_clientAddress >> m_clientPort >> m_authenticationNames; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::ForwardQuery::encode() const { @@ -479,20 +468,17 @@ index 0000000..90688d0 + return w.finalize(Packet::_ForwardQuery); + } + -+ Packet::Willing::Willing(const QHostAddress& host, quint16 port, const QString& authenticationName, const QString& hostname, const QString& status) -+ : Packet(host, port) -+ , m_authenticationName(authenticationName.toLatin1()) -+ , m_hostname(hostname.toLatin1()) -+ , m_status(status.toLatin1()) { ++ Packet::Willing::Willing(const QHostAddress &host, quint16 port, const QString &authenticationName, const QString &hostname, const QString &status) : Packet(host, port), ++ m_authenticationName(authenticationName.toLatin1()), ++ m_hostname(hostname.toLatin1()), ++ m_status(status.toLatin1()) { + qDebug() << " XDMCP: Prepared Willing reply for" << host << port << "with contents" << authenticationName << hostname << status; + } + -+ Packet::Willing::Willing(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::Willing::Willing(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_authenticationName >> m_hostname >> m_status; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Willing::encode() const { @@ -501,19 +487,16 @@ index 0000000..90688d0 + return w.finalize(Packet::_Willing); + } + -+ Packet::Unwilling::Unwilling(const QHostAddress& host, quint16 port, const QString& hostname, const QString& status) -+ : Packet(host, port) -+ , m_hostname(hostname.toLatin1()) -+ , m_status(status.toLatin1()) { ++ Packet::Unwilling::Unwilling(const QHostAddress &host, quint16 port, const QString &hostname, const QString &status) : Packet(host, port), ++ m_hostname(hostname.toLatin1()), ++ m_status(status.toLatin1()) { + qDebug() << " XDMCP: Prepared Unwilling reply for" << host << port << "with contents" << hostname << status; + } + -+ Packet::Unwilling::Unwilling(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::Unwilling::Unwilling(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_hostname >> m_status; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Unwilling::encode() const { @@ -522,64 +505,50 @@ index 0000000..90688d0 + return w.finalize(Packet::_Unwilling); + } + -+ Packet::Request::Request(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { -+ r >> m_displayNumber >> m_connectionTypes >> m_connectionAddresses -+ >> m_authenticationName >> m_authenticationData >> m_authorizationNames -+ >> m_manufacturerDisplayID; -+ if (r.isFinished()) { ++ Packet::Request::Request(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { ++ r >> m_displayNumber >> m_connectionTypes >> m_connectionAddresses >> m_authenticationName >> m_authenticationData >> m_authorizationNames >> m_manufacturerDisplayID; ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Request::encode() const { + Writer w; -+ w << m_displayNumber << m_connectionTypes << m_connectionAddresses -+ << m_authenticationName << m_authenticationData << m_authorizationNames -+ << m_manufacturerDisplayID; ++ w << m_displayNumber << m_connectionTypes << m_connectionAddresses << m_authenticationName << m_authenticationData << m_authorizationNames << m_manufacturerDisplayID; + return w.finalize(Packet::_Request); + } + -+ Packet::Accept::Accept(const QHostAddress& host, quint16 port, uint32_t sessionId, const QString authenticationName, const QByteArray authenticationData, const QString authorizationName, const QByteArray authorizationData) -+ : Packet(host, port) -+ , m_sessionID(sessionId) -+ , m_authenticationName(authenticationName.toLatin1()) -+ , m_authenticationData(authenticationData) -+ , m_authorizationName(authorizationName.toLatin1()) -+ , m_authorizationData(authorizationData) { ++ Packet::Accept::Accept(const QHostAddress &host, quint16 port, uint32_t sessionId, const QString authenticationName, const QByteArray authenticationData, const QString authorizationName, const QByteArray authorizationData) : Packet(host, port), ++ m_sessionID(sessionId), ++ m_authenticationName(authenticationName.toLatin1()), ++ m_authenticationData(authenticationData), ++ m_authorizationName(authorizationName.toLatin1()), ++ m_authorizationData(authorizationData) { + qDebug() << " XDMCP: Prepared Accept reply for" << host << port << "with contents" << sessionId << authenticationName << authenticationData << authorizationName << authorizationData; + } + -+ Packet::Accept::Accept(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { -+ r >> m_sessionID >> m_authenticationName >> m_authenticationData -+ >> m_authorizationName >> m_authorizationData; -+ if (r.isFinished()) { ++ Packet::Accept::Accept(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { ++ r >> m_sessionID >> m_authenticationName >> m_authenticationData >> m_authorizationName >> m_authorizationData; ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Accept::encode() const { + Writer w; -+ w << m_sessionID << m_authenticationName << m_authenticationData -+ << m_authorizationName << m_authorizationData; ++ w << m_sessionID << m_authenticationName << m_authenticationData << m_authorizationName << m_authorizationData; + return w.finalize(Packet::_Accept); + } + -+ Packet::Decline::Decline(const QHostAddress& host, quint16 port, const QString status, const QString authenticationName, const QByteArray authenticationData) -+ : Packet(host, port) -+ , m_status(status.toLatin1()) -+ , m_authenticationName(authenticationName.toLatin1()) -+ , m_authenticationData(authenticationData) { ++ Packet::Decline::Decline(const QHostAddress &host, quint16 port, const QString status, const QString authenticationName, const QByteArray authenticationData) : Packet(host, port), ++ m_status(status.toLatin1()), ++ m_authenticationName(authenticationName.toLatin1()), ++ m_authenticationData(authenticationData) { + qDebug() << " XDMCP: Prepared Decline reply for" << host << port << "with contents" << status << authenticationName << authenticationData; + } + -+ Packet::Decline::Decline(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::Decline::Decline(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_status >> m_authenticationName >> m_authenticationData; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Decline::encode() const { @@ -588,12 +557,10 @@ index 0000000..90688d0 + return w.finalize(Packet::_Decline); + } + -+ Packet::Manage::Manage(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::Manage::Manage(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_sessionID >> m_displayNumber >> m_displayClass; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Manage::encode() const { @@ -602,17 +569,15 @@ index 0000000..90688d0 + return w.finalize(Packet::_Manage); + } + -+ Packet::Refuse::Refuse(const QHostAddress& host, quint16 port, uint32_t sessionID) -+ : Packet(host, port) -+ , m_sessionID(sessionID) { ++ Packet::Refuse::Refuse(const QHostAddress &host, quint16 port, uint32_t sessionID) : Packet(host, port), ++ m_sessionID(sessionID) { + qDebug() << " XDMCP: Prepared Refuse reply for" << host << port << "with contents" << sessionID; + } + -+ Packet::Refuse::Refuse(const QHostAddress& host, quint16 port, Reader& r) : Packet(host, port, r) { ++ Packet::Refuse::Refuse(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_sessionID; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Refuse::encode() const { @@ -621,19 +586,16 @@ index 0000000..90688d0 + return w.finalize(Packet::_Refuse); + } + -+ Packet::Failed::Failed(const QHostAddress& host, quint16 port, uint32_t sessionID, const QString& status) -+ : Packet(host, port) -+ , m_sessionID(sessionID) -+ , m_status(status.toLatin1()) { ++ Packet::Failed::Failed(const QHostAddress &host, quint16 port, uint32_t sessionID, const QString &status) : Packet(host, port), ++ m_sessionID(sessionID), ++ m_status(status.toLatin1()) { + qDebug() << " XDMCP: Prepared Failed reply for" << host << port << "with contents" << sessionID << status; + } + -+ Packet::Failed::Failed(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::Failed::Failed(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_sessionID >> m_status; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Failed::encode() const { @@ -642,12 +604,10 @@ index 0000000..90688d0 + return w.finalize(Packet::_Failed); + } + -+ Packet::KeepAlive::KeepAlive(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::KeepAlive::KeepAlive(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_displayNumber >> m_sessionID; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::KeepAlive::encode() const { @@ -656,19 +616,16 @@ index 0000000..90688d0 + return w.finalize(Packet::_KeepAlive); + } + -+ Packet::Alive::Alive(const QHostAddress& host, quint16 port, uint8_t sessionRunning, uint32_t sessionID) -+ : Packet(host, port) -+ , m_sessionRunning(sessionRunning) -+ , m_sessionID(sessionID) { ++ Packet::Alive::Alive(const QHostAddress &host, quint16 port, uint8_t sessionRunning, uint32_t sessionID) : Packet(host, port), ++ m_sessionRunning(sessionRunning), ++ m_sessionID(sessionID) { + qDebug() << " XDMCP: Prepared Alive reply for" << host << port << "with contents" << sessionRunning << sessionID; + } + -+ Packet::Alive::Alive(const QHostAddress& host, quint16 port, Reader& r) -+ : Packet(host, port, r) { ++ Packet::Alive::Alive(const QHostAddress &host, quint16 port, Reader &r) : Packet(host, port, r) { + r >> m_sessionRunning >> m_sessionID; -+ if (r.isFinished()) { ++ if (r.isFinished()) + m_valid = true; -+ } + } + + QByteArray Packet::Alive::encode() const { @@ -682,45 +639,48 @@ index 0000000..90688d0 + ******************************************************************************/ + + Packet *Packet::Query::onServerReceived() const { -+ if (m_authenticationNames.isEmpty()) { ++ if (m_authenticationNames.isEmpty()) + return new Willing(m_host, m_port, "", Server::instance()->hostname(), Server::instance()->status()); -+ } -+ else { -+ return new Unwilling(m_host, m_port, Server::instance()->hostname(), "Server does not support authentication"); -+ } ++ ++ return new Unwilling(m_host, m_port, Server::instance()->hostname(), "Server does not support authentication"); + } + + Packet* Packet::Request::onServerReceived() const { + qDebug() << " XDMCP: Server: Received Request" << m_displayNumber << m_connectionTypes << m_connectionAddresses << m_authenticationName << m_authenticationData << m_authorizationNames << m_manufacturerDisplayID; ++ + if (m_authorizationNames.contains("MIT-MAGIC-COOKIE-1")) { + uint32_t sessionId = Server::instance()->newSessionId(); ++ // FIXME for obvious reasons + QHostAddress addr(QString("%1.%2.%3.%4").arg((uint) m_connectionAddresses.first()[0]).arg((uint) m_connectionAddresses.first()[1]).arg((uint) m_connectionAddresses.first()[2]).arg((uint) m_connectionAddresses.first()[3])); + Display *display = Server::instance()->newDisplay(sessionId, addr.toString(), m_displayNumber); ++ + return new Accept(m_host, m_port, sessionId, m_authenticationName, m_authenticationData, "MIT-MAGIC-COOKIE-1", display->rawCookie()); -+ } else { -+ return new Decline(m_host, m_port, Server::instance()->status(), m_authenticationName, m_authenticationData); + } ++ ++ return new Decline(m_host, m_port, Server::instance()->status(), m_authenticationName, m_authenticationData); + } + + Packet* Packet::Manage::onServerReceived() const { + Display *display = Server::instance()->getDisplay(m_sessionID); ++ + if (display != nullptr) { + display->start(); -+ return nullptr; -+ } else { -+ return new Refuse(m_host, m_port, m_sessionID); ++ return nullptr; // this packet doesn't have any response on success + } ++ ++ return new Refuse(m_host, m_port, m_sessionID); + } + + Packet* Packet::KeepAlive::onServerReceived() const { + Display *display = Server::instance()->getDisplay(m_sessionID); ++ + if (display == nullptr) + return new Alive(m_host, m_port, 0, m_sessionID); -+ else if (display->displayId() != m_displayNumber) ++ ++ if (display->displayId() != m_displayNumber) + return new Alive(m_host, m_port, 0, m_sessionID); -+ else { -+ return new Alive(m_host, m_port, 1, m_sessionID); -+ } ++ ++ return new Alive(m_host, m_port, 1, m_sessionID); + } + +/******************************************************************************* @@ -731,7 +691,7 @@ index 0000000..90688d0 +}; diff --git a/src/daemon/xdmcp/Packet.h b/src/daemon/xdmcp/Packet.h new file mode 100644 -index 0000000..507b1b4 +index 0000000..9246541 --- /dev/null +++ b/src/daemon/xdmcp/Packet.h @@ -0,0 +1,394 @@ @@ -807,21 +767,21 @@ index 0000000..507b1b4 + * \param port Source port of the packet + * \return Parsed packet + */ -+ static Packet *decode(const QByteArray& data, const QHostAddress& host = QHostAddress(), quint16 port = 0); ++ static Packet *decode(const QByteArray &data, const QHostAddress &host = QHostAddress(), quint16 port = 0); + + /** + * Set the packet's source/destination host + * + * \param host The host + */ -+ void setHost(const QHostAddress host); ++ void setHost(const QHostAddress &host); + + /** + * Get the packet's source/destination host + * + * \return The host + */ -+ QHostAddress host() const; ++ const QHostAddress& host() const; + + /** + * Set the packet's source/destination host @@ -881,7 +841,7 @@ index 0000000..507b1b4 + * \param host Destination host for the response + * \param port Destination port for the response + */ -+ Packet(const QHostAddress& host, quint16 port); ++ Packet(const QHostAddress &host, quint16 port); + /** + * C'tor targetted for parsing raw data + * @@ -889,7 +849,7 @@ index 0000000..507b1b4 + * \param port Destination port for the response + * \param r Reader containing the packet's raw data + */ -+ Packet(const QHostAddress& host, quint16 port, Reader& r); ++ Packet(const QHostAddress &host, quint16 port, Reader &r); + + QHostAddress m_host; + quint16 m_port { 0 }; @@ -898,7 +858,7 @@ index 0000000..507b1b4 + + class Packet::BroadcastQuery : public Packet { + public: -+ BroadcastQuery(const QHostAddress& host, quint16 port, Reader& r); ++ BroadcastQuery(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + private: + QVector m_authenticationNames; @@ -906,7 +866,7 @@ index 0000000..507b1b4 + + class Packet::Query : public Packet { + public: -+ Query(const QHostAddress& host, quint16 port, Reader& r); ++ Query(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + /** + * Server side handling of Query packet @@ -933,7 +893,7 @@ index 0000000..507b1b4 + + class Packet::IndirectQuery : public Packet { + public: -+ IndirectQuery(const QHostAddress& host, quint16 port, Reader& r); ++ IndirectQuery(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + private: + QVector m_authenticationNames; @@ -941,7 +901,7 @@ index 0000000..507b1b4 + + class Packet::ForwardQuery : public Packet { + public: -+ ForwardQuery(const QHostAddress& host, quint16 port, Reader& r); ++ ForwardQuery(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + private: + QByteArray m_clientAddress; @@ -951,10 +911,10 @@ index 0000000..507b1b4 + + class Packet::Willing : public Packet { + public: -+ Willing(const QHostAddress& host, quint16 port, -+ const QString& authenticationName, const QString& hostname, -+ const QString& status); -+ Willing(const QHostAddress& host, quint16 port, Reader& r); ++ Willing(const QHostAddress &host, quint16 port, ++ const QString &authenticationName, const QString &hostname, ++ const QString &status); ++ Willing(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + /** + * Client side handling of Willing packet @@ -974,9 +934,9 @@ index 0000000..507b1b4 + + class Packet::Unwilling : public Packet { + public: -+ Unwilling(const QHostAddress& host, quint16 port, -+ const QString& hostname, const QString& status); -+ Unwilling(const QHostAddress& host, quint16 port, Reader& r); ++ Unwilling(const QHostAddress &host, quint16 port, ++ const QString &hostname, const QString &status); ++ Unwilling(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + private: + QByteArray m_hostname; @@ -985,7 +945,7 @@ index 0000000..507b1b4 + + class Packet::Request : public Packet { + public: -+ Request(const QHostAddress& host, quint16 port, Reader& r); ++ Request(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + /** + * Server side handling of Request packet @@ -1016,10 +976,10 @@ index 0000000..507b1b4 + + class Packet::Accept : public Packet { + public: -+ Accept(const QHostAddress& host, quint16 port, uint32_t sessionId, ++ Accept(const QHostAddress &host, quint16 port, uint32_t sessionId, + const QString authenticationName, const QByteArray authenticationData, + const QString authorizationName, const QByteArray authorizationData); -+ Accept(const QHostAddress& host, quint16 port, Reader& r); ++ Accept(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + /** + * Client side handling of Accept packet @@ -1041,9 +1001,9 @@ index 0000000..507b1b4 + + class Packet::Decline : public Packet { + public: -+ Decline(const QHostAddress& host, quint16 port, const QString status, ++ Decline(const QHostAddress &host, quint16 port, const QString status, + const QString authenticationName, const QByteArray authenticationData); -+ Decline(const QHostAddress& host, quint16 port, Reader& r); ++ Decline(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + private: + QByteArray m_status; @@ -1053,7 +1013,7 @@ index 0000000..507b1b4 + + class Packet::Manage : public Packet { + public: -+ Manage(const QHostAddress& host, quint16 port, Reader& r); ++ Manage(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + /** + * Server side handling of Manage packet @@ -1080,8 +1040,8 @@ index 0000000..507b1b4 + + class Packet::Refuse : public Packet { + public: -+ Refuse(const QHostAddress& host, quint16 port, uint32_t sessionID); -+ Refuse(const QHostAddress& host, quint16 port, Reader& r); ++ Refuse(const QHostAddress &host, quint16 port, uint32_t sessionID); ++ Refuse(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + private: + uint32_t m_sessionID; @@ -1089,8 +1049,8 @@ index 0000000..507b1b4 + + class Packet::Failed : public Packet { + public: -+ Failed(const QHostAddress& host, quint16 port, uint32_t sessionID, const QString& status); -+ Failed(const QHostAddress& host, quint16 port, Reader& r); ++ Failed(const QHostAddress &host, quint16 port, uint32_t sessionID, const QString &status); ++ Failed(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + private: + uint32_t m_sessionID; @@ -1099,7 +1059,7 @@ index 0000000..507b1b4 + + class Packet::KeepAlive : public Packet { + public: -+ KeepAlive(const QHostAddress& host, quint16 port, Reader& r); ++ KeepAlive(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + /** + * Server side handling of KeepAlive packet @@ -1117,8 +1077,8 @@ index 0000000..507b1b4 + + class Packet::Alive : public Packet { + public: -+ Alive(const QHostAddress& host, quint16 port, uint8_t sessionRunning, uint32_t sessionID); -+ Alive(const QHostAddress& host, quint16 port, Reader& r); ++ Alive(const QHostAddress &host, quint16 port, uint8_t sessionRunning, uint32_t sessionID); ++ Alive(const QHostAddress &host, quint16 port, Reader &r); + virtual QByteArray encode() const; + private: + uint8_t m_sessionRunning; @@ -1131,10 +1091,10 @@ index 0000000..507b1b4 +#endif // SDDM_XDMCP_PACKET_H diff --git a/src/daemon/xdmcp/Server.cpp b/src/daemon/xdmcp/Server.cpp new file mode 100644 -index 0000000..edfdff4 +index 0000000..b4dc6e1 --- /dev/null +++ b/src/daemon/xdmcp/Server.cpp -@@ -0,0 +1,149 @@ +@@ -0,0 +1,148 @@ +/* + * Server implementation for X Display Control Protocol + * Copyright (C) 2013 Martin Bříza @@ -1174,9 +1134,8 @@ index 0000000..edfdff4 + return self; + } + -+ Server::Server(DaemonApp* parent) -+ : QUdpSocket(parent) -+ , m_hostname(QHostInfo::localHostName()) { ++ Server::Server(DaemonApp* parent) : QUdpSocket(parent), ++ m_hostname(QHostInfo::localHostName()) { + + } + @@ -1225,7 +1184,7 @@ index 0000000..edfdff4 + return m_lastSession++; + } + -+ Display* Server::newDisplay(uint32_t sessionId, QString hostName, uint32_t displayNumber) { ++ Display* Server::newDisplay(uint32_t sessionId, const QString &hostName, uint32_t displayNumber) { + if (m_displays.contains(sessionId)) + return nullptr; + Display *display = new Display(hostName, displayNumber, this); @@ -1237,12 +1196,12 @@ index 0000000..edfdff4 + Display* Server::getDisplay(uint32_t id) { + if (m_displays.contains(id)) + return m_displays[id]; -+ else -+ return nullptr; ++ return nullptr; + } + + void Server::removeDisplay(QObject* obj) { + int key = m_displays.key(qobject_cast(obj), -1); ++ + if (key == -1) + return; + @@ -1286,7 +1245,7 @@ index 0000000..edfdff4 +#include "Server.moc" diff --git a/src/daemon/xdmcp/Server.h b/src/daemon/xdmcp/Server.h new file mode 100644 -index 0000000..2898381 +index 0000000..6f7bdae --- /dev/null +++ b/src/daemon/xdmcp/Server.h @@ -0,0 +1,118 @@ @@ -1381,7 +1340,7 @@ index 0000000..2898381 + /** + * Create a new display + */ -+ Display *newDisplay(uint32_t sessionId, QString hostName, uint32_t displayNumber); ++ Display *newDisplay(uint32_t sessionId, const QString &hostName, uint32_t displayNumber); + Display *getDisplay(uint32_t id); + QString status() const; + QString hostname() const; @@ -1410,10 +1369,10 @@ index 0000000..2898381 +#endif // SDDM_XDMCP_SERVER_H diff --git a/src/daemon/xdmcp/Utils.cpp b/src/daemon/xdmcp/Utils.cpp new file mode 100644 -index 0000000..92e1d6a +index 0000000..53ac7e3 --- /dev/null +++ b/src/daemon/xdmcp/Utils.cpp -@@ -0,0 +1,145 @@ +@@ -0,0 +1,143 @@ +/* + * Utilities for X Display Control Protocol + * Copyright (C) 2013 Martin Bříza @@ -1441,28 +1400,27 @@ index 0000000..92e1d6a +namespace SDDM { +namespace XDMCP { + -+ Reader::Reader(const QByteArray& data) -+ : m_data(data) -+ , m_stream(&m_data, QIODevice::ReadOnly | QIODevice::Unbuffered) { ++ Reader::Reader(const QByteArray &data) : m_data(data), ++ m_stream(&m_data, QIODevice::ReadOnly | QIODevice::Unbuffered) { + m_stream.setByteOrder(QDataStream::BigEndian); + } + -+ Reader& Reader::operator>>(uint8_t& byte) { ++ Reader& Reader::operator>>(uint8_t &byte) { + m_stream >> byte; + return *this; + } + -+ Reader& Reader::operator>>(uint16_t& word) { ++ Reader& Reader::operator>>(uint16_t &word) { + m_stream >> word; + return *this; + } + -+ Reader& Reader::operator>>(uint32_t& doubleword) { ++ Reader& Reader::operator>>(uint32_t &doubleword) { + m_stream >> doubleword; + return *this; + } + -+ Reader& Reader::operator>>(QByteArray& array) { ++ Reader& Reader::operator>>(QByteArray &array) { + uint16_t arrayLen; + *this >> arrayLen; + while (arrayLen--) { @@ -1473,7 +1431,7 @@ index 0000000..92e1d6a + return *this; + } + -+ Reader& Reader::operator>>(QVector< uint16_t >& wordArray) { ++ Reader& Reader::operator>>(QVector< uint16_t > &wordArray) { + uint8_t arrayLen; + *this >> arrayLen; + while (arrayLen--) { @@ -1484,7 +1442,7 @@ index 0000000..92e1d6a + return *this; + } + -+ Reader& Reader::operator>>(QVector< QByteArray >& arrayOfArrays) { ++ Reader& Reader::operator>>(QVector< QByteArray > &arrayOfArrays) { + uint8_t arrayCount; + *this >> arrayCount; + while (arrayCount--) { @@ -1502,9 +1460,8 @@ index 0000000..92e1d6a + return false; + } + -+ Writer::Writer() -+ : m_data() -+ , m_stream(&m_data, QIODevice::WriteOnly | QIODevice::Unbuffered) { ++ Writer::Writer() : m_data(), ++ m_stream(&m_data, QIODevice::WriteOnly | QIODevice::Unbuffered) { + m_stream.setByteOrder(QDataStream::BigEndian); + } + @@ -1524,23 +1481,23 @@ index 0000000..92e1d6a + return *this; + } + -+ Writer& Writer::operator<<(const QByteArray& array) { ++ Writer& Writer::operator<<(const QByteArray &array) { + *this << (uint16_t) array.count(); + for (uint8_t c : array) + m_stream << c; + return *this; + } + -+ Writer& Writer::operator<<(const QVector< uint16_t >& wordArray) { ++ Writer& Writer::operator<<(const QVector< uint16_t > &wordArray) { + *this << (uint8_t) wordArray.count(); -+ for (const uint16_t& i : wordArray) ++ for (const uint16_t &i : wordArray) + *this << i; + return *this; + } + -+ Writer& Writer::operator<<(const QVector< QByteArray >& arrayOfArrays) { ++ Writer& Writer::operator<<(const QVector< QByteArray > &arrayOfArrays) { + *this << (uint16_t) arrayOfArrays.count(); -+ for (const QByteArray& i : arrayOfArrays) ++ for (const QByteArray &i : arrayOfArrays) + *this << i; + return *this; + } @@ -1562,7 +1519,7 @@ index 0000000..92e1d6a \ No newline at end of file diff --git a/src/daemon/xdmcp/Utils.h b/src/daemon/xdmcp/Utils.h new file mode 100644 -index 0000000..9457ef1 +index 0000000..bd96708 --- /dev/null +++ b/src/daemon/xdmcp/Utils.h @@ -0,0 +1,93 @@ @@ -1609,12 +1566,12 @@ index 0000000..9457ef1 + public: + Reader(const QByteArray &data); + ~Reader() {} -+ Reader& operator>>(uint8_t& byte); -+ Reader& operator>>(uint16_t& word); -+ Reader& operator>>(uint32_t& doubleword); -+ Reader& operator>>(QByteArray& array); -+ Reader& operator>>(QVector& wordArray); -+ Reader& operator>>(QVector& arrayOfArrays); ++ Reader& operator>>(uint8_t &byte); ++ Reader& operator>>(uint16_t &word); ++ Reader& operator>>(uint32_t &doubleword); ++ Reader& operator>>(QByteArray &array); ++ Reader& operator>>(QVector &wordArray); ++ Reader& operator>>(QVector &arrayOfArrays); + /** + * Returns true if the stream is at its end and no errors occured + * @@ -1640,9 +1597,9 @@ index 0000000..9457ef1 + Writer& operator<<(const uint8_t byte); + Writer& operator<<(const uint16_t word); + Writer& operator<<(const uint32_t doubleword); -+ Writer& operator<<(const QByteArray& array); -+ Writer& operator<<(const QVector& wordArray); -+ Writer& operator<<(const QVector& arrayOfArrays); ++ Writer& operator<<(const QByteArray &array); ++ Writer& operator<<(const QVector &wordArray); ++ Writer& operator<<(const QVector &arrayOfArrays); + /** + * Finalizes building of the packet + * diff --git a/sddm-auth.patch b/sddm-auth.patch deleted file mode 100644 index a11887a..0000000 --- a/sddm-auth.patch +++ /dev/null @@ -1,2596 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 78f33fe..4384274 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -7,6 +7,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) - set(CMAKE_AUTOMOC ON) - - add_definitions(-Wall -march=native -std=c++11) -+include(FeatureSummary) -+ - - if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) -@@ -27,7 +29,7 @@ find_package(PkgConfig) - - # PAM - if(NOT NO_PAM) -- find_package(PAM) -+ find_package(PAM REQUIRED) - - if(PAM_FOUND) - add_definitions(-DUSE_PAM) -@@ -42,6 +44,9 @@ find_package(XKB REQUIRED) - - if(USE_QT5) - find_package(Qt5Core REQUIRED) -+ find_package(Qt5Quick REQUIRED) -+ find_package(Qt5Gui REQUIRED) -+ find_package(Qt5Network REQUIRED) - find_package(Qt5DBus REQUIRED) - find_package(Qt5LinguistTools REQUIRED) - -@@ -97,6 +102,8 @@ set(CONFIG_FILE "${SYS_CONFIG_DIR}/sddm.conf" CACH - set(LOG_FILE "/var/log/sddm.log" CACHE PATH "Path of the sddm log file") - set(COMPONENTS_TRANSLATION_DIR "${DATA_INSTALL_DIR}/translations" CACHE PATH "Components translations directory") - -+feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) -+ - add_subdirectory(components) - add_subdirectory(data) - add_subdirectory(services) -diff --git a/data/themes/maldives/GeosansLight.ttf b/data/themes/maldives/GeosansLight.ttf -new file mode 100644 -index 0000000..055932a -Binary files /dev/null and b/data/themes/maldives/GeosansLight.ttf differ -diff --git a/data/themes/maldives/Main.qml b/data/themes/maldives/Main.qml -index ab5b013..037beb3 100644 ---- a/data/themes/maldives/Main.qml -+++ b/data/themes/maldives/Main.qml -@@ -46,7 +46,7 @@ Rectangle { - } - } - -- FontLoader { id: clockFont; source: "Sans" } -+ FontLoader { id: clockFont; source: "GeosansLight.ttf" } - - Repeater { - model: screenModel -diff --git a/data/themes/maui/GeosansLight.ttf b/data/themes/maui/GeosansLight.ttf -new file mode 100644 -index 0000000..055932a -Binary files /dev/null and b/data/themes/maui/GeosansLight.ttf differ -diff --git a/data/themes/maui/Main.qml b/data/themes/maui/Main.qml -index 1aa9bec..f5f062d 100644 ---- a/data/themes/maui/Main.qml -+++ b/data/themes/maui/Main.qml -@@ -45,7 +45,7 @@ Rectangle { - } - } - -- FontLoader { id: clockFont; source: "Sans" } -+ FontLoader { id: clockFont; source: "GeosansLight.ttf" } - - Repeater { - model: screenModel -diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index a82ae45..a66e5d1 100644 ---- a/src/CMakeLists.txt -+++ b/src/CMakeLists.txt -@@ -7,6 +7,7 @@ configure_file(common/Constants.h.in common/Constants.h IMMEDIATE @ONLY) - - set(DAEMON_SOURCES - common/Configuration.cpp -+ common/SafeDataStream.cpp - common/SocketWriter.cpp - daemon/Authenticator.cpp - daemon/DaemonApp.cpp -@@ -17,7 +18,6 @@ set(DAEMON_SOURCES - daemon/PowerManager.cpp - daemon/Seat.cpp - daemon/SeatManager.cpp -- daemon/Session.cpp - daemon/SignalHandler.cpp - daemon/SocketServer.cpp - ) -@@ -28,13 +28,7 @@ if(USE_QT5) - qt5_add_dbus_adaptor(DAEMON_SOURCES ${CMAKE_SOURCE_DIR}/data/interfaces/org.freedesktop.DisplayManager.Session.xml daemon/DisplayManager.h SDDM::DisplayManagerSession) - - add_executable(sddm ${DAEMON_SOURCES}) -- target_link_libraries(sddm ${LIBXCB_LIBRARIES}) -- if(PAM_FOUND) -- target_link_libraries(sddm ${PAM_LIBRARIES}) -- else() -- target_link_libraries(sddm crypt) -- endif() -- qt5_use_modules(sddm DBus Network) -+ target_link_libraries(sddm ${LIBXCB_LIBRARIES} Qt5::Core Qt5::DBus Qt5::Network) - else() - set(QT_USE_QTNETWORK TRUE) - set(QT_USE_QTDBUS TRUE) -@@ -55,6 +49,41 @@ endif() - - install(TARGETS sddm DESTINATION ${BIN_INSTALL_DIR}) - -+## AUTHENTICATOR ## -+ -+set(AUTHENTICATOR_SOURCES -+ auth/AuthenticatorApp.cpp -+ auth/Method.cpp -+ auth/PAM.cpp -+ auth/Session.cpp -+ common/Configuration.cpp -+ common/SafeDataStream.cpp -+) -+ -+if(USE_QT5) -+ add_executable(sddm-auth ${AUTHENTICATOR_SOURCES}) -+ target_link_libraries(sddm-auth Qt5::Core) -+ if(PAM_FOUND) -+ target_link_libraries(sddm-auth ${PAM_LIBRARIES}) -+ set_target_properties(sddm-auth PROPERTIES COMPILE_DEFINITIONS "USE_PAM=1") -+ -+ else() -+ target_link_libraries(sddm-auth crypt) -+ endif() -+else() -+ include(${QT_USE_FILE}) -+ -+ add_executable(sddm-auth ${AUTHENTICATOR_SOURCES}) -+ target_link_libraries(sddm-auth ${LIBXCB_LIBRARIES} ${QT_LIBRARIES}) -+ if(PAM_FOUND) -+ target_link_libraries(sddm-auth ${PAM_LIBRARIES}) -+ else() -+ target_link_libraries(sddm-auth crypt) -+ endif() -+endif() -+ -+install(TARGETS sddm-auth DESTINATION ${BIN_INSTALL_DIR}) -+ - ## GREETER ## - - set(GREETER_SOURCES -@@ -72,8 +101,7 @@ set(GREETER_SOURCES - - if(USE_QT5) - add_executable(sddm-greeter ${GREETER_SOURCES}) -- target_link_libraries(sddm-greeter ${LIBXCB_LIBRARIES} ${LIBXKB_LIBRARIES}) -- qt5_use_modules(sddm-greeter Quick) -+ target_link_libraries(sddm-greeter ${LIBXCB_LIBRARIES} ${LIBXKB_LIBRARIES} Qt5::Core Qt5::Quick Qt5::Gui) - else() - set(QT_USE_QTDECLARATIVE TRUE) - include(${QT_USE_FILE}) -diff --git a/src/auth/AuthenticatorApp.cpp b/src/auth/AuthenticatorApp.cpp -new file mode 100644 -index 0000000..be72de2 ---- /dev/null -+++ b/src/auth/AuthenticatorApp.cpp -@@ -0,0 +1,206 @@ -+/* -+ * -+ * Copyright (C) 2013 Martin Bříza -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#include "AuthenticatorApp.h" -+#include "Configuration.h" -+#include "Constants.h" -+#include "Method.h" -+#include "PAM.h" -+#include "Session.h" -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+namespace SDDM { -+ AuthenticatorApp *AuthenticatorApp::self = nullptr; -+ -+ AuthenticatorApp::AuthenticatorApp(int argc, char **argv) -+ : QCoreApplication(argc, argv) -+ , m_method(new Method(this)) -+ , m_notifier(new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this)) { -+ if (!self) -+ self = this; -+ new Configuration(CONFIG_FILE, this); -+ connect(this, SIGNAL(started(QString,QString,QString,bool)), m_method, SLOT(start(QString,QString,QString,bool))); -+ connect(this, SIGNAL(stopped()), m_method, SLOT(stop())); -+ connect(m_method, SIGNAL(loginFailed()), this, SLOT(slotLoginFailed())); -+ connect(m_method, SIGNAL(loginSucceeded(QString)), this, SLOT(slotLoginSucceeded(QString))); -+ connect(m_method, SIGNAL(sessionTerminated()), this, SLOT(quit())); -+ connect(m_notifier, SIGNAL(activated(int)), this, SLOT(readFromParent(int))); -+ m_notifier->setEnabled(true); -+ -+ m_input.open(fileno(stdin), QIODevice::ReadOnly | QIODevice::Unbuffered); -+ m_output.open(fileno(stdout), QIODevice::WriteOnly | QIODevice::Unbuffered); -+ -+ qCritical() << " AUTH: Started"; -+ } -+ -+ AuthenticatorApp* AuthenticatorApp::instance() { -+ return self; -+ } -+ -+ void AuthenticatorApp::readFromParent(int fd) { -+ qDebug() << " AUTH: Message received" << m_input.bytesAvailable(); -+ SafeDataStream inStream(&m_input); -+ quint32 command = quint32(AuthMessages::AuthNone); -+ inStream.receive(); -+ inStream >> command; -+ qDebug() << "Command" << command; -+ handleMessage(AuthMessages(command), inStream); -+ } -+ -+ void AuthenticatorApp::handleMessage(AuthMessages command, SafeDataStream& inStream) { -+ switch (command) { -+ case AuthMessages::Start: { -+ QString user, session, password; -+ bool passwordless; -+ inStream >> user >> session >> password >> passwordless; -+ emit started(user, session, password, passwordless); -+ break; -+ } -+ case AuthMessages::End: -+ emit stopped(); -+ break; -+ default: -+ break; -+ } -+ } -+ -+ QProcessEnvironment AuthenticatorApp::requestEnvironment(const QString &user) { -+ qDebug() << " AUTH: requestEnvironment start"; -+ SafeDataStream inStream(&m_input); -+ SafeDataStream outStream(&m_output); -+ quint32 command = quint32(AuthMessages::AuthNone); -+ int count; -+ QStringList envList; -+ QProcessEnvironment env; -+ -+ qDebug() << "Requesting environment for user" << user; -+ outStream << quint32(AuthMessages::RequestEnv) << user; -+ outStream.send(); -+ -+ inStream.receive(); -+ inStream >> command >> envList; -+ if (command != quint32(AuthMessages::Env)) { -+ qDebug() << " AUTH: Received out of order message" << command << "when waiting for Env"; -+ handleMessage(AuthMessages(command), inStream); -+ return env; -+ } -+ qDebug() << " AUTH: Received environment:" << envList; -+ -+ foreach (const QString &s, envList) -+ env.insert(s.left(s.indexOf("=")), s.mid(s.indexOf("=") + 1)); -+ -+ return env; -+ } -+ -+ int AuthenticatorApp::requestSessionId() { -+ qDebug() << " AUTH: requestSessionId start"; -+ SafeDataStream inStream(&m_input); -+ SafeDataStream outStream(&m_output); -+ quint32 command = quint32(AuthMessages::AuthNone); -+ int id; -+ -+ outStream << quint32(AuthMessages::RequestSessionID); -+ outStream.send(); -+ -+ inStream.receive(); -+ inStream >> command; -+ if (command != quint32(AuthMessages::SessionID)) { -+ qDebug() << " AUTH: Received out of order message" << command << "when waiting for SessionID"; -+ handleMessage(AuthMessages(command), inStream); -+ return -1; -+ } -+ inStream >> id; -+ -+ qDebug() << " AUTH: requestSessionId end"; -+ return id; -+ } -+ -+ bool AuthenticatorApp::requestCookieTo(const QString& path, const QString &user) { -+ qDebug() << " AUTH: requestCookieTo start"; -+ SafeDataStream inStream(&m_input); -+ SafeDataStream outStream(&m_output); -+ quint32 command = quint32(AuthMessages::AuthNone); -+ qDebug() << " AUTH: Requesting Cookie to path" << path << "for user" << user; -+ -+ outStream << quint32(AuthMessages::RequestCookieLink) << path << user; -+ outStream.send(); -+ -+ inStream.receive(); -+ inStream >> command; -+ if (command != quint32(AuthMessages::CookieLink)) { -+ qDebug() << " AUTH: Received out of order message" << command << "when waiting for CookieLink"; -+ handleMessage(AuthMessages(command), inStream); -+ return false; -+ } -+ -+ qDebug() << " AUTH: requestCookieTo end"; -+ return true; -+ } -+ -+ QString AuthenticatorApp::requestDisplay() { -+ qDebug() << " AUTH: requestDisplay start"; -+ SafeDataStream inStream(&m_input); -+ SafeDataStream outStream(&m_output); -+ quint32 command = quint32(AuthMessages::AuthNone); -+ qDebug() << " AUTH: Requesting Display"; -+ QString display; -+ -+ outStream << quint32(AuthMessages::RequestDisplay); -+ outStream.send(); -+ -+ inStream.receive(); -+ inStream >> command; -+ if (command != quint32(AuthMessages::Display)) { -+ qDebug() << " AUTH: Received out of order message" << command << "when waiting for Display"; -+ handleMessage(AuthMessages(command), inStream); -+ return display; -+ } -+ inStream >> display; -+ -+ qDebug() << " AUTH: requestDisplay end"; -+ return display; -+ } -+ -+ void AuthenticatorApp::slotLoginFailed() { -+ SafeDataStream outStream(&m_output); -+ outStream << quint32(AuthMessages::LoginFailed); -+ outStream.send(); -+ } -+ -+ void AuthenticatorApp::slotLoginSucceeded(QString user) { -+ SafeDataStream outStream(&m_output); -+ outStream << quint32(AuthMessages::LoginSucceeded) << m_method->name() << user; -+ outStream.send(); -+ } -+} -+ -+int main(int argc, char **argv) { -+ SDDM::AuthenticatorApp app(argc, argv); -+ return app.exec(); -+} -+ -+#include "AuthenticatorApp.moc" -diff --git a/src/auth/AuthenticatorApp.h b/src/auth/AuthenticatorApp.h -new file mode 100644 -index 0000000..6c54d02 ---- /dev/null -+++ b/src/auth/AuthenticatorApp.h -@@ -0,0 +1,70 @@ -+/* -+ * -+ * Copyright (C) 2013 Martin Bříza -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#ifndef AUTHENTICATORAPP_H -+#define AUTHENTICATORAPP_H -+ -+#include "Messages.h" -+#include "SafeDataStream.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+namespace SDDM { -+ -+ class Method; -+ class AuthenticatorApp : public QCoreApplication -+ { -+ Q_OBJECT -+ public: -+ explicit AuthenticatorApp(int argc, char **argv); -+ static AuthenticatorApp *instance(); -+ -+ QProcessEnvironment requestEnvironment(const QString &user); -+ int requestSessionId(); -+ bool requestCookieTo(const QString &path, const QString &user); -+ QString requestDisplay(); -+ -+ signals: -+ void started(const QString &user, const QString &session, const QString &password, bool passwordless); -+ void stopped(); -+ -+ public slots: -+ void slotLoginSucceeded(QString user); -+ void slotLoginFailed(); -+ -+ private slots: -+ void readFromParent(int fd); -+ void handleMessage(AuthMessages command, SafeDataStream &inStream); -+ -+ private: -+ static AuthenticatorApp *self; -+ -+ Method *m_method { nullptr }; -+ QSocketNotifier *m_notifier { nullptr }; -+ QFile m_input { }; -+ QFile m_output { }; -+ }; -+} -+ -+#endif // AUTHENTICATORAPP_H -diff --git a/src/auth/Method.cpp b/src/auth/Method.cpp -new file mode 100644 -index 0000000..aef1661 ---- /dev/null -+++ b/src/auth/Method.cpp -@@ -0,0 +1,330 @@ -+/* -+ * -+ * Copyright (C) 2013 Martin Bříza -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#include "Method.h" -+#include "Configuration.h" -+#include "Session.h" -+#include "AuthenticatorApp.h" -+ -+#include -+#include -+#include -+ -+#ifndef USE_PAM -+#include -+#include -+#else -+#include "PAM.h" -+#endif -+ -+#include -+#include -+#include -+ -+namespace SDDM { -+ Method::Method(QObject* parent) -+ : QObject(parent) { -+ -+ } -+ -+ QString Method::name() const { -+ if (m_started) -+ return m_process->name(); -+ else -+ return QString(); -+ } -+ -+ void Method::start(const QString& user, const QString& session, const QString& password, bool passwordless) { -+ if (doStart(user, session, password, passwordless)) -+ emit loginSucceeded(user); -+ else -+ emit loginFailed(); -+ } -+ -+ void Method::buildSessionName(const QString& session) { -+ if (session.endsWith(".desktop")) { -+ // session directory -+ QDir dir(Configuration::instance()->sessionsDir()); -+ -+ // session file -+ QFile file(dir.absoluteFilePath(session)); -+ -+ // open file -+ if (file.open(QIODevice::ReadOnly)) { -+ -+ // read line-by-line -+ QTextStream in(&file); -+ while (!in.atEnd()) { -+ QString line = in.readLine(); -+ -+ // line starting with Exec -+ if (line.startsWith("Exec=")) -+ m_sessionCommand = line.mid(5); -+ } -+ -+ // close file -+ file.close(); -+ } -+ -+ // remove extension -+ m_sessionName = QString(session.left(session.lastIndexOf("."))); -+ } else { -+ m_sessionCommand = QString(session); -+ m_sessionName = QString(session); -+ } -+ } -+ -+ bool Method::authenticate() { -+#ifdef USE_PAM -+ if (m_pam) -+ m_pam->deleteLater(); -+ -+ m_pam = new PamService(m_user, m_password, m_passwordless); -+ -+ if (!m_pam) -+ return false; -+ -+ QString display = AuthenticatorApp::instance()->requestDisplay(); -+ -+ // set tty -+ if (!m_pam->setItem(PAM_TTY, qPrintable(display))) -+ return false; -+ -+ // set display name -+ if (!m_pam->setItem(PAM_XDISPLAY, qPrintable(display))) -+ return false; -+ -+ // set username -+ if (!m_pam->setItem(PAM_USER, qPrintable(m_user))) -+ return false; -+ -+ // authenticate the applicant -+ if (!m_pam->authenticate()) -+ return false; -+ -+ // get mapped user name; PAM may have changed it -+ const char *mapped = (const char *) m_pam->getItem(PAM_USER); -+ if (mapped == NULL) -+ return false; -+ // TODO: Find out if PAM changing the name is a good or a bad thing -+ //m_user = QString(mapped); -+ -+ if (!m_pam->acctMgmt()) -+ return false; -+#else -+ if (!m_passwordless) { -+ // user name -+ struct passwd *pw; -+ if ((pw = getpwnam(qPrintable(m_user))) == nullptr) { -+ // log error -+ qCritical() << " AUTH: Failed to get user entry."; -+ -+ // return fail -+ return false; -+ } -+ -+ struct spwd *sp; -+ if ((sp = getspnam(pw->pw_name)) == nullptr) { -+ // log error -+ qCritical() << " AUTH: Failed to get shadow entry."; -+ -+ // return fail -+ return false; -+ } -+ -+ // check if password is not empty -+ if (sp->sp_pwdp && sp->sp_pwdp[0]) { -+ -+ // encrypt password -+ char *encrypted = crypt(qPrintable(m_password), sp->sp_pwdp); -+ -+ if (strcmp(encrypted, sp->sp_pwdp)) -+ return false; -+ } -+ } -+ -+ char *mapped = strdup(qPrintable(m_user)); -+ m_user = QString(mapped); -+ free(mapped); -+#endif -+ return true; -+ } -+ -+ bool Method::setupUser() { -+ // user name -+ struct passwd *pw; -+ if ((pw = getpwnam(qPrintable(m_user))) == nullptr) { -+ // log error -+ qCritical() << " AUTH: Failed to get user name."; -+ -+ // return fail -+ return false; -+ } -+ -+ if (pw->pw_shell[0] == '\0') { -+ setusershell(); -+ strcpy(pw->pw_shell, getusershell()); -+ endusershell(); -+ } -+ -+ // set session m_process params -+ m_process->setUser(pw->pw_name); -+ m_process->setDir(pw->pw_dir); -+ m_process->setUid(pw->pw_uid); -+ m_process->setGid(pw->pw_gid); -+ // redirect error output to ~/.xession-errors -+ m_process->setStandardErrorFile(QString("%1/.xsession-errors").arg(pw->pw_dir)); -+ if (!AuthenticatorApp::instance()->requestCookieTo(QString("%1/.Xauthority").arg(pw->pw_dir), m_user)) -+ return false; -+ return true; -+ } -+ -+ QProcessEnvironment Method::setupEnvironment() { // set m_process environment -+ QProcessEnvironment env = AuthenticatorApp::instance()->requestEnvironment(m_user); -+#ifdef USE_PAM -+ env.insert(m_pam->getEnv()); -+ m_pam->putEnv(env); -+#endif -+ env.insert("DESKTOP_SESSION", m_sessionName); -+ env.insert("GDMSESSION", m_sessionName); -+ return env; -+ } -+ -+ bool Method::startSession() { -+#ifdef USE_PAM -+ // set credentials -+ if (!m_pam->setCred(PAM_ESTABLISH_CRED)) -+ return false; -+ -+ // open session -+ if (!m_pam->openSession()) -+ return false; -+ -+ // set credentials -+ if (!m_pam->setCred(PAM_REINITIALIZE_CRED)) -+ return false; -+#endif -+ // start session -+ m_process->start(Configuration::instance()->sessionCommand(), { m_sessionCommand }); -+ return true; -+ } -+ -+ -+ bool Method::doStart(const QString &user, const QString &session, const QString &password, bool passwordless) { -+ m_user = user; -+ m_password = password; -+ m_passwordless = passwordless; -+ // check flag -+ if (m_started) -+ return false; -+ -+ buildSessionName(session); -+ -+ if (m_sessionCommand.isEmpty()) { -+ // log error -+ qCritical() << " AUTH: Failed to find command for session:" << session; -+ -+ // return fail -+ return false; -+ } -+ -+ if (!authenticate()) -+ return false; -+ -+ qDebug() << " AUTH: Authenticated for user" << m_user; -+ -+ // create user session m_process -+ m_process = new Session(QString("Session%1").arg(AuthenticatorApp::instance()->requestSessionId()), this); -+ connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished())); -+ -+ if (!setupUser()) -+ return false; -+ -+ m_process->setProcessEnvironment(setupEnvironment()); -+ -+ if (!startSession()) -+ return false; -+ -+ qDebug() << " AUTH: User session" << m_sessionName << "set up."; -+ -+ // wait for started -+ if (!m_process->waitForStarted()) { -+ // log error -+ qDebug() << " AUTH: Failed to start user session."; -+ -+ // return fail -+ return false; -+ } -+ -+ // log message -+ qDebug() << " AUTH: User session started."; -+ -+ // register to the display manager FIXME -+ // daemonApp->displayManager()->AddSession(m_process->name(), seat->name(), pw->pw_name); -+ -+ // set flag -+ m_started = true; -+ -+ // return success -+ return true; -+ } -+ -+ void Method::stop() { -+ // check flag -+ if (!m_started) -+ return; -+ -+ // log message -+ qDebug() << " AUTH: User session stopping..."; -+ -+ // terminate m_process -+ m_process->terminate(); -+ -+ // wait for finished -+ if (!m_process->waitForFinished(5000)) -+ m_process->kill(); -+ } -+ -+ void Method::finished() { -+ // check flag -+ if (!m_started) -+ return; -+ -+ // reset flag -+ m_started = false; -+ -+ // log message -+ qDebug() << " AUTH: User session ended."; -+ -+ // delete session process -+ m_process->deleteLater(); -+ m_process = nullptr; -+ -+#ifdef USE_PAM -+ delete m_pam; -+ m_pam = nullptr; -+#endif -+ -+ emit sessionTerminated(); -+ } -+ -+}; -+ -+#include "Method.moc" -diff --git a/src/auth/Method.h b/src/auth/Method.h -new file mode 100644 -index 0000000..e13133a ---- /dev/null -+++ b/src/auth/Method.h -@@ -0,0 +1,73 @@ -+/* -+ * -+ * Copyright (C) 2013 Martin Bříza -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#ifndef METHOD_H -+#define METHOD_H -+ -+#include -+#include -+ -+namespace SDDM { -+#ifdef USE_PAM -+ class PamService; -+#endif -+ class Session; -+ class Method : public QObject -+ { -+ Q_OBJECT -+ public: -+ explicit Method(QObject *parent = nullptr); -+ QString name() const; -+ -+ protected: -+ virtual bool authenticate(); -+ virtual bool setupUser(); -+ virtual QProcessEnvironment setupEnvironment(); -+ virtual bool startSession(); -+ -+ signals: -+ void loginSucceeded(QString); -+ void loginFailed(); -+ void sessionTerminated(); -+ -+ public slots: -+ void start(const QString &user, const QString &session, const QString &password, bool passwordless); -+ void stop(); -+ void finished(); -+ -+ private: -+ bool doStart(const QString &user, const QString &session, const QString &password, bool passwordless); -+ void buildSessionName(const QString& session); -+ -+ bool m_passwordless { false }; -+ QString m_user { }; -+ QString m_password { }; -+ QString m_sessionName { }; -+ QString m_sessionCommand { }; -+ -+ Session *m_process { nullptr }; -+ bool m_started { false }; -+#ifdef USE_PAM -+ PamService *m_pam { nullptr }; -+#endif -+ }; -+} -+ -+#endif // METHOD_H -diff --git a/src/auth/PAM.cpp b/src/auth/PAM.cpp -new file mode 100644 -index 0000000..5229891 ---- /dev/null -+++ b/src/auth/PAM.cpp -@@ -0,0 +1,266 @@ -+/* -+ * PAM Authenticator backend -+ * -+ * Based on the work of: -+ * SDDM Authenticator implementation: Abdurrahman AVCI -+ * SLiM PAM implementation: Martin Parm -+ * -+ * Copyright (C) 2013 Martin Bříza -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#ifdef USE_PAM -+#include "PAM.h" -+ -+#include -+ -+namespace SDDM { -+ -+ bool PamService::putEnv(const QProcessEnvironment& env) { -+ foreach (const QString& s, env.toStringList()) { -+ result = pam_putenv(handle, s.toLatin1()); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: putEnv:" << pam_strerror(handle, result); -+ return false; -+ } -+ } -+ return true; -+ } -+ -+ QProcessEnvironment PamService::getEnv() { -+ QProcessEnvironment env; -+ // get pam environment -+ char **envlist = pam_getenvlist(handle); -+ if (envlist == NULL) { -+ qWarning() << " AUTH: PAM: getEnv: Returned NULL"; -+ return env; -+ } -+ -+ // copy it to the env map -+ for (int i = 0; envlist[i] != nullptr; ++i) { -+ QString s(envlist[i]); -+ -+ // find equal sign -+ int index = s.indexOf('='); -+ -+ // add to the hash -+ if (index != -1) -+ env.insert(s.left(index), s.mid(index + 1)); -+ -+ free(envlist[i]); -+ } -+ free(envlist); -+ return env; -+ } -+ -+ bool PamService::chAuthTok(int flags) { -+ result = pam_chauthtok(handle, flags | m_silent); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: chAuthTok:" << pam_strerror(handle, result); -+ } -+ return result == PAM_SUCCESS; -+ } -+ -+ bool PamService::acctMgmt(int flags) { -+ result = pam_acct_mgmt(handle, flags | m_silent); -+ if (result == PAM_NEW_AUTHTOK_REQD) { -+ // TODO see if this should really return the value or just true regardless of the outcome -+ return chAuthTok(PAM_CHANGE_EXPIRED_AUTHTOK); -+ } -+ else if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: acctMgmt:" << pam_strerror(handle, result); -+ return false; -+ } -+ return true; -+ } -+ -+ bool PamService::authenticate(int flags) { -+ result = pam_authenticate(handle, flags | m_silent); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: authenticate:" << pam_strerror(handle, result); -+ } -+ return result == PAM_SUCCESS; -+ } -+ -+ bool PamService::setCred(int flags) { -+ result = pam_setcred(handle, flags | m_silent); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: setCred:" << pam_strerror(handle, result); -+ } -+ return result == PAM_SUCCESS; -+ } -+ -+ bool PamService::openSession() { -+ result = pam_open_session(handle, m_silent); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: openSession:" << pam_strerror(handle, result); -+ } -+ return result == PAM_SUCCESS; -+ } -+ -+ bool PamService::closeSession() { -+ result = pam_close_session(handle, m_silent); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: closeSession:" << pam_strerror(handle, result); -+ } -+ return result == PAM_SUCCESS; -+ } -+ -+ bool PamService::setItem(int item_type, const void* item) { -+ result = pam_set_item(handle, item_type, item); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: setItem:" << pam_strerror(handle, result); -+ } -+ return result == PAM_SUCCESS; -+ } -+ -+ const void* PamService::getItem(int item_type) { -+ const void *item; -+ result = pam_get_item(handle, item_type, &item); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: getItem:" << pam_strerror(handle, result); -+ } -+ return item; -+ } -+ -+ int PamService::converse(int n, const struct pam_message **msg, struct pam_response **resp, void *data) { -+ PamService *c = static_cast(data); -+ return c->doConverse(n, msg, resp); -+ } -+ -+ int PamService::doConverse(int n, const struct pam_message **msg, struct pam_response **resp) { -+ struct pam_response *aresp; -+ -+ // check size of the message buffer -+ if ((n <= 0) || (n > PAM_MAX_NUM_MSG)) -+ return PAM_CONV_ERR; -+ -+ // create response buffer -+ if ((aresp = (struct pam_response *) calloc(n, sizeof(struct pam_response))) == nullptr) -+ return PAM_BUF_ERR; -+ -+ bool failed = false; -+ -+ // if we don't require password, bail on any request from PAM -+ if (passwordless) { -+ for (int i = 0; i < n; ++i) { -+ switch(msg[i]->msg_style) { -+ case PAM_ERROR_MSG: -+ case PAM_TEXT_INFO: -+ qDebug() << " AUTH: PAM: Message" << msg[i]->msg; -+ break; -+ case PAM_PROMPT_ECHO_OFF: -+ case PAM_PROMPT_ECHO_ON: -+ default: -+ failed = true; -+ break; -+ } -+ } -+ } -+ // else, respond to the messages -+ else { -+ for (int i = 0; i < n; ++i) { -+ aresp[i].resp_retcode = 0; -+ aresp[i].resp = nullptr; -+ switch (msg[i]->msg_style) { -+ case PAM_PROMPT_ECHO_OFF: -+ // set password - WARNING this is just assumption it's a password, beware! -+ aresp[i].resp = strdup(qPrintable(password)); -+ if (aresp[i].resp == nullptr) -+ failed = true; -+ // clear password -+ password = ""; -+ break; -+ case PAM_PROMPT_ECHO_ON: -+ // set user - WARNING again, just an assumption, in more complicated environments this won't suffice! -+ aresp[i].resp = strdup(qPrintable(user)); -+ if (aresp[i].resp == nullptr) -+ failed = true; -+ // clear user -+ user = ""; -+ break; -+ case PAM_ERROR_MSG: -+ case PAM_TEXT_INFO: -+ qDebug() << " AUTH: PAM: Message:" << msg[i]->msg; -+ break; -+ default: -+ failed = true; -+ } -+ } -+ } -+ -+ if (failed) { -+ for (int i = 0; i < n; ++i) { -+ if (aresp[i].resp != nullptr) { -+ memset(aresp[i].resp, 0, strlen(aresp[i].resp)); -+ free(aresp[i].resp); -+ } -+ } -+ memset(aresp, 0, n * sizeof(struct pam_response)); -+ free(aresp); -+ *resp = nullptr; -+ return PAM_CONV_ERR; -+ } -+ -+ *resp = aresp; -+ return PAM_SUCCESS; -+ } -+ -+ bool PamService::start(const char *service_name, const char *user, const struct pam_conv *pam_conversation) { -+ result = pam_start(service_name, user, pam_conversation, &handle); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: start" << pam_strerror(handle, result); -+ return false; -+ } -+ else { -+ qDebug() << " AUTH: PAM: Starting..."; -+ } -+ return true; -+ } -+ -+ bool PamService::end(int flags) { -+ result = pam_end(handle, result | flags); -+ if (result != PAM_SUCCESS) { -+ qWarning() << " AUTH: PAM: end:" << pam_strerror(handle, result); -+ return false; -+ } -+ else { -+ qDebug() << " AUTH: PAM: Ended."; -+ } -+ return true; -+ } -+ -+ PamService::PamService(const QString &user, const QString &password, bool passwordless, QObject *parent) -+ : QObject(parent), user(user), password(password), passwordless(passwordless) { -+ // create context -+ m_converse = { &PamService::converse, this }; -+ // start service -+ if (passwordless) -+ start("sddm-passwordless", nullptr, &m_converse); -+ else -+ start("sddm", nullptr, &m_converse); -+ } -+ -+ PamService::~PamService() { -+ // stop service -+ end(); -+ } -+}; -+ -+#include "PAM.moc" -+ -+#endif // USE_PAM -diff --git a/src/auth/PAM.h b/src/auth/PAM.h -new file mode 100644 -index 0000000..51134ab ---- /dev/null -+++ b/src/auth/PAM.h -@@ -0,0 +1,217 @@ -+/* -+ * PAM Authenticator backend -+ * Copyright (C) 2013 Martin Bříza -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#ifndef PAM_H -+#define PAM_H -+#ifdef USE_PAM -+ -+#include -+#include -+ -+#include -+ -+namespace SDDM { -+ /** -+ * Class wrapping the standard Linux-PAM library calls -+ * -+ * Almost everything is left the same except the following things: -+ * -+ * Mainly, state returns - if you call pam_start, pam_open_session and then -+ * pam_start again, the session will get closed and the conversation closed -+ * -+ * You don't need to pass PAM_SILENT to every call if you want PAM to be quiet. -+ * You can set the flag globally by using the \ref setSilence method. -+ * -+ * \ref acctMgmt doesn't require you to handle the PAM_NEW_AUTHTOK_REQD condition, -+ * it calls chAuthTok on its own. -+ * -+ * Error messages are automatically reported to qDebug -+ */ -+ class PamService : public QObject { -+ Q_OBJECT -+ -+ public: -+ /** -+ * ctor -+ * -+ * \param service PAM service name, e.g. "sddm" -+ * \param user username -+ * \param password user's password -+ * \param passwordless true if no password is required -+ * \param parent parent QObject -+ */ -+ PamService(const QString &user, const QString &password, bool passwordless, QObject *parent = 0); -+ -+ ~PamService(); -+ -+ /** -+ * Conversation function for the pam_conv structure -+ * -+ * Calls ((PamService*)pam_conv.appdata_ptr)->doConverse() with its parameters -+ */ -+ static int converse(int n, const struct pam_message **msg, struct pam_response **resp, void *data); -+ -+ /** -+ * The main conversation method -+ * -+ * This method relates to this particular session / login attempt only, it's called on the object -+ * that it belongs to. -+ * -+ * So far its architecture is quite silly and relies both on previously entered username and password. -+ * In the future, I'm intending to use it to request information from the greeter by calling its methods to -+ * supply the required information. (And this won't be just passwords, we'd like to have the possibility to -+ * log in using just a USB key, fingerprint reader, whatever you want.) -+ * -+ * I hope this task will be easier to implement by moving the whole thing into a class. -+ */ -+ int doConverse(int n, const struct pam_message **msg, struct pam_response **resp); -+ -+ /** -+ * pam_set_item - set and update PAM informations -+ * -+ * \param item_type PAM item type -+ * \param item item pointer -+ * -+ * \return true on success -+ */ -+ bool setItem(int item_type, const void *item); -+ -+ /** -+ * pam_get_item - getting PAM informations -+ * -+ * \param item_type -+ * -+ * \return item pointer or NULL on failure -+ */ -+ const void *getItem(int item_type); -+ -+ /** -+ * pam_open_session - start PAM session management -+ * -+ * \return true on success -+ */ -+ bool openSession(); -+ -+ /** -+ * pam_close_session - terminate PAM session management -+ * -+ * \return true on success -+ */ -+ bool closeSession(); -+ -+ /** -+ * pam_setcred - establish / delete user credentials -+ * -+ * \param flags PAM flag(s) -+ * -+ * \return true on success -+ */ -+ bool setCred(int flags = 0); -+ -+ /** -+ * pam_authenticate - account authentication -+ * -+ * \param flags PAM flag(s) -+ * -+ * \return true on success -+ */ -+ bool authenticate(int flags = 0); -+ -+ /** -+ * pam_acct_mgmt - PAM account validation management -+ * -+ * @note Automatically calls setCred if the password is expired -+ * -+ * \param flags PAM flag(s) -+ * -+ * \return true on success -+ */ -+ bool acctMgmt(int flags = 0); -+ -+ /** -+ * pam_chauthtok - updating authentication tokens -+ * -+ * \param flags PAM flag(s) -+ * -+ * \return true on success -+ */ -+ bool chAuthTok(int flags = 0); -+ -+ /** -+ * pam_getenv - get PAM environment -+ * -+ * \return Complete process environment -+ */ -+ QProcessEnvironment getEnv(); -+ -+ /** -+ * pam_putenv - set or change PAM environment -+ * -+ * \param env environment to be merged into the PAM one -+ * -+ * \return true on success -+ */ -+ bool putEnv(const QProcessEnvironment& env); -+ -+ /** -+ * pam_end - termination of PAM transaction -+ * -+ * \param flags to be OR'd with the status (PAM_DATA_SILENT) -+ * \return true on success -+ */ -+ bool end(int flags = 0); -+ -+ /** -+ * pam_start - initialization of PAM transaction -+ * -+ * \param service PAM service name, e.g. "sddm" -+ * \param user username -+ * \param pam_conversation pointer to the PAM conversation structure to be used -+ * -+ * \return true on success -+ */ -+ bool start(const char *service_name, const char *user, const struct pam_conv *pam_conversation); -+ -+ /** -+ * Set PAM_SILENT upon the contained calls -+ * \param silent true if silent -+ */ -+ inline void setSilence(bool silent){ -+ if (silent) -+ m_silent |= PAM_SILENT; -+ else -+ m_silent &= (~PAM_SILENT); -+ } -+ -+ private: -+ int m_silent { 0 }; ///< flag mask for silence of the contained calls -+ -+ struct pam_conv m_converse; ///< the current conversation -+ pam_handle_t *handle { nullptr }; ///< PAM handle -+ int result { PAM_SUCCESS }; ///< PAM result -+ -+ QString user { "" }; ///< user -+ QString password { "" }; ///< password -+ bool passwordless { false }; ///< true if doesn't require password -+ }; -+}; -+ -+#endif // USE_PAM -+#endif // PAM_H -diff --git a/src/auth/Session.cpp b/src/auth/Session.cpp -new file mode 100644 -index 0000000..006a70e ---- /dev/null -+++ b/src/auth/Session.cpp -@@ -0,0 +1,103 @@ -+/*************************************************************************** -+* Copyright (c) 2013 Abdurrahman AVCI -+* -+* This program is free software; you can redistribute it and/or modify -+* it under the terms of the GNU General Public License as published by -+* the Free Software Foundation; either version 2 of the License, or -+* (at your option) any later version. -+* -+* This program is distributed in the hope that it will be useful, -+* but WITHOUT ANY WARRANTY; without even the implied warranty of -+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+* GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License -+* along with this program; if not, write to the -+* Free Software Foundation, Inc., -+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+***************************************************************************/ -+ -+#include "Session.h" -+ -+#include "Configuration.h" -+ -+#include -+ -+#include -+#include -+#include -+ -+namespace SDDM { -+ Session::Session(const QString &name, QObject *parent) : QProcess(parent), m_name(name) { -+ } -+ -+ const QString &Session::name() const { -+ return m_name; -+ } -+ -+ void Session::setUser(const QString &user) { -+ m_user = user; -+ } -+ -+ void Session::setDir(const QString &dir) { -+ m_dir = dir; -+ } -+ -+ void Session::setUid(int uid) { -+ m_uid = uid; -+ } -+ -+ void Session::setGid(int gid) { -+ m_gid = gid; -+ } -+ -+ void Session::setupChildProcess() { -+ if (initgroups(qPrintable(m_user), m_gid)) { -+ qCritical() << " AUTH: Failed to initialize user groups."; -+ -+ // emit signal -+ emit finished(EXIT_FAILURE, QProcess::NormalExit); -+ -+ // exit -+ exit(EXIT_FAILURE); -+ } -+ -+ if (setsid() < 0) { -+ qCritical() << " AUTH: Can't create a new session."; -+ emit finished(EXIT_FAILURE, QProcess::NormalExit); -+ exit(EXIT_FAILURE); -+ } -+ -+ if (setgid(m_gid)) { -+ qCritical() << " AUTH: Failed to set group id."; -+ -+ // emit signal -+ emit finished(EXIT_FAILURE, QProcess::NormalExit); -+ -+ // exit -+ exit(EXIT_FAILURE); -+ } -+ -+ if (setuid(m_uid)) { -+ qCritical() << " AUTH: Failed to set user id."; -+ -+ // emit signal -+ emit finished(EXIT_FAILURE, QProcess::NormalExit); -+ -+ // exit -+ exit(EXIT_FAILURE); -+ -+ } -+ -+ // change to user home dir -+ if (chdir(qPrintable(m_dir))) { -+ qCritical() << " AUTH: Failed to change dir to user home."; -+ -+ // emit signal -+ emit finished(EXIT_FAILURE, QProcess::NormalExit); -+ -+ // exit -+ exit(EXIT_FAILURE); -+ } -+ } -+} -diff --git a/src/auth/Session.h b/src/auth/Session.h -new file mode 100644 -index 0000000..ebf4979 ---- /dev/null -+++ b/src/auth/Session.h -@@ -0,0 +1,54 @@ -+/*************************************************************************** -+* Copyright (c) 2013 Abdurrahman AVCI -+* -+* This program is free software; you can redistribute it and/or modify -+* it under the terms of the GNU General Public License as published by -+* the Free Software Foundation; either version 2 of the License, or -+* (at your option) any later version. -+* -+* This program is distributed in the hope that it will be useful, -+* but WITHOUT ANY WARRANTY; without even the implied warranty of -+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+* GNU General Public License for more details. -+* -+* You should have received a copy of the GNU General Public License -+* along with this program; if not, write to the -+* Free Software Foundation, Inc., -+* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+***************************************************************************/ -+ -+#ifndef SDDM_SESSION_H -+#define SDDM_SESSION_H -+ -+#include -+ -+namespace SDDM { -+ -+ class Session : public QProcess { -+ Q_OBJECT -+ Q_DISABLE_COPY(Session) -+ public: -+ explicit Session(const QString &name, QObject *parent); -+ -+ const QString &name() const; -+ -+ void setUser(const QString &user); -+ void setDir(const QString &dir); -+ void setUid(int uid); -+ void setGid(int gid); -+ -+ protected: -+ void setupChildProcess(); -+ -+ private: -+ -+ QString m_name { "" }; -+ QString m_user { "" }; -+ QString m_dir { "" }; -+ -+ int m_uid { 0 }; -+ int m_gid { 0 }; -+ }; -+} -+ -+#endif // SDDM_SESSION_H -diff --git a/src/common/.AuthenticatorWrapper.cpp.kate-swp b/src/common/.AuthenticatorWrapper.cpp.kate-swp -new file mode 100644 -index 0000000..3253e12 -Binary files /dev/null and b/src/common/.AuthenticatorWrapper.cpp.kate-swp differ -diff --git a/src/common/Messages.h b/src/common/Messages.h -index c779791..40470cb 100644 ---- a/src/common/Messages.h -+++ b/src/common/Messages.h -@@ -40,6 +40,22 @@ namespace SDDM { - LoginFailed - }; - -+ enum class AuthMessages { -+ AuthNone = 0, -+ Start, -+ End, -+ RequestEnv, -+ Env, -+ LoginFailed, -+ LoginSucceeded, -+ RequestSessionID, -+ SessionID, -+ RequestCookieLink, -+ CookieLink, -+ RequestDisplay, -+ Display -+ }; -+ - enum Capability { - None = 0x0000, - PowerOff = 0x0001, -diff --git a/src/common/SafeDataStream.cpp b/src/common/SafeDataStream.cpp -new file mode 100644 -index 0000000..eb41563 ---- /dev/null -+++ b/src/common/SafeDataStream.cpp -@@ -0,0 +1,64 @@ -+/* -+ * -+ * Copyright (C) 2013 Martin Bříza -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#include "SafeDataStream.h" -+ -+#include -+ -+namespace SDDM { -+ -+ SafeDataStream::SafeDataStream(QIODevice* stream) : QDataStream(new QByteArray(), QIODevice::ReadWrite), -+ m_stream(stream) { -+ } -+ -+ void SafeDataStream::clear() { -+ QBuffer *buf = qobject_cast(device()); -+ if (buf) { -+ buf->reset(); -+ buf->buffer().clear(); -+ } -+ } -+ -+ void SafeDataStream::receive() { -+ QByteArray header; -+ header = m_stream->read(sizeof(uint)); -+ if (header.size() < sizeof(uint)) { -+ m_stream->waitForReadyRead(-1); -+ header.append(m_stream->read(sizeof(uint) - header.size())); -+ } -+ uint len = *(uint *) header.constData(); -+ while (len > 0) { -+ QByteArray chunk = m_stream->read(len); -+ len -= chunk.size(); -+ this->writeRawData(chunk.constData(), chunk.size()); -+ } -+ device()->reset(); -+ } -+ -+ void SafeDataStream::send() { -+ device()->reset(); -+ QByteArray data = device()->readAll(); -+ uint len = data.size(); -+ m_stream->write((char *) &len, sizeof(uint)); -+ qint64 status = m_stream->write(data.constData(), data.size()); -+ m_stream->waitForBytesWritten(-1); -+ } -+ -+} -diff --git a/src/common/SafeDataStream.h b/src/common/SafeDataStream.h -new file mode 100644 -index 0000000..80c333f ---- /dev/null -+++ b/src/common/SafeDataStream.h -@@ -0,0 +1,42 @@ -+/* -+ * This class wraps QDataStream in a blocking way waiting for the entire message to be received -+ * Copyright (C) 2013 Martin Bříza -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ */ -+ -+#ifndef SAFEDATASTREAM_H -+#define SAFEDATASTREAM_H -+ -+#include -+#include -+ -+namespace SDDM { -+ -+ class SafeDataStream : public QDataStream -+ { -+ public: -+ SafeDataStream(QIODevice *stream); -+ void clear(); -+ void send(); -+ void receive(); -+ private: -+ QIODevice *m_stream; -+ }; -+ -+} -+ -+#endif // SAFEDATASTREAM_H -diff --git a/src/daemon/Authenticator.cpp b/src/daemon/Authenticator.cpp -index 47b77f4..7503d65 100644 ---- a/src/daemon/Authenticator.cpp -+++ b/src/daemon/Authenticator.cpp -@@ -18,414 +18,130 @@ - ***************************************************************************/ - - #include "Authenticator.h" -- --#include "Configuration.h" - #include "DaemonApp.h" - #include "Display.h" - #include "DisplayManager.h" -+#include "SeatManager.h" - #include "Seat.h" --#include "Session.h" -- --#include --#include --#include --#include -+#include "Constants.h" - --#ifdef USE_PAM --#include --#else --#include --#include --#endif -+#include -+#include - --#include - #include - #include - - namespace SDDM { --#ifdef USE_PAM -- class PamService { -- public: -- PamService(const char *service, const QString &user, const QString &password, bool passwordless); -- ~PamService(); -- -- struct pam_conv m_converse; -- pam_handle_t *handle { nullptr }; -- int result { PAM_SUCCESS }; -- -- QString user { "" }; -- QString password { "" }; -- bool passwordless { false }; -- }; -- -- int converse(int n, const struct pam_message **msg, struct pam_response **resp, void *data) { -- struct pam_response *aresp; -- -- // check size of the message buffer -- if ((n <= 0) || (n > PAM_MAX_NUM_MSG)) -- return PAM_CONV_ERR; -- -- // create response buffer -- if ((aresp = (struct pam_response *) calloc(n, sizeof(struct pam_response))) == nullptr) -- return PAM_BUF_ERR; -- -- // respond to the messages -- bool failed = false; -- for (int i = 0; i < n; ++i) { -- aresp[i].resp_retcode = 0; -- aresp[i].resp = nullptr; -- switch (msg[i]->msg_style) { -- case PAM_PROMPT_ECHO_OFF: { -- PamService *c = static_cast(data); -- // set password -- aresp[i].resp = strdup(qPrintable(c->password)); -- if (aresp[i].resp == nullptr) -- failed = true; -- // clear password -- c->password = ""; -- } -- break; -- case PAM_PROMPT_ECHO_ON: { -- PamService *c = static_cast(data); -- // set user -- aresp[i].resp = strdup(qPrintable(c->user)); -- if (aresp[i].resp == nullptr) -- failed = true; -- // clear user -- c->user = ""; -- } -- break; -- case PAM_ERROR_MSG: -- case PAM_TEXT_INFO: -- break; -- default: -- failed = true; -- } -- } -- -- if (failed) { -- for (int i = 0; i < n; ++i) { -- if (aresp[i].resp != nullptr) { -- memset(aresp[i].resp, 0, strlen(aresp[i].resp)); -- free(aresp[i].resp); -- } -- } -- memset(aresp, 0, n * sizeof(struct pam_response)); -- free(aresp); -- *resp = nullptr; -- return PAM_CONV_ERR; -+ Authenticator::Authenticator(Display *parent) -+ : QProcess(parent) -+ , m_display(parent) { -+ connect(this, SIGNAL(finished(int)), this, SIGNAL(stopped())); -+ setReadChannel(QProcess::StandardOutput); -+ connect(this, SIGNAL(readyRead()), this, SLOT(readFromChild())); -+ connect(this, SIGNAL(readyReadStandardError()), SLOT(forwardErrorOutput())); -+ -+ QProcess::start(QString("%1/sddm-auth").arg(BIN_INSTALL_DIR)); -+ if (!waitForStarted()) { -+ qCritical() << " DAEMON: Failed to start authenticator process:" << errorString(); -+ return; - } - -- *resp = aresp; -- return PAM_SUCCESS; -- } -- -- PamService::PamService(const char *service, const QString &user, const QString &password, bool passwordless) : user(user), password(password), passwordless(passwordless) { -- // create context -- m_converse = { &converse, this }; -- -- // start service -- pam_start(service, nullptr, &m_converse, &handle); -- } -- -- PamService::~PamService() { -- // stop service -- pam_end(handle, result); -- } --#endif -- -- Authenticator::Authenticator(Display *parent) : QObject(parent), m_display(parent) { -- } -- -- Authenticator::~Authenticator() { -- stop(); -- } -- -- Display *Authenticator::display() const { -- return m_display; -+ m_started = true; -+ qDebug() << " DAEMON: Started the authenticator process."; - } - -- bool Authenticator::start(const QString &user, const QString &session) { -- return doStart(user, QString(), session, true); -+ void Authenticator::forwardErrorOutput() { -+ QFile err; -+ err.open(fileno(stderr), QIODevice::WriteOnly | QIODevice::Unbuffered); -+ err.write(this->readAllStandardError()); - } - -- bool Authenticator::start(const QString &user, const QString &password, const QString &session) { -- return doStart(user, password, session, false); -+ void Authenticator::readFromChild() { -+ SafeDataStream stream(this); -+ quint32 command; -+ stream.receive(); -+ stream >> command; -+ qDebug() << " DAEMON: Received message" << command << "from the authenticator"; -+ handleMessage(AuthMessages(command), stream); - } - -- bool Authenticator::doStart(const QString &user, const QString &password, const QString &session, bool passwordless) { -- // check flag -- if (m_started) -- return false; -- -- // convert session to command -- QString sessionName = ""; -- QString command = ""; -- -- if (session.endsWith(".desktop")) { -- // session directory -- QDir dir(daemonApp->configuration()->sessionsDir()); -- -- // session file -- QFile file(dir.absoluteFilePath(session)); -- -- // open file -- if (file.open(QIODevice::ReadOnly)) { -- -- // read line-by-line -- QTextStream in(&file); -- while (!in.atEnd()) { -- QString line = in.readLine(); -- -- // line starting with Exec -- if (line.startsWith("Exec=")) -- command = line.mid(5); -- } -- -- // close file -- file.close(); -+ void Authenticator::handleMessage(AuthMessages command, SafeDataStream &stream) { -+ switch (command) { -+ case AuthMessages::RequestEnv: { -+ QString user; -+ stream >> user; -+ QStringList env = m_display->sessionEnv(user).toStringList(); -+ qDebug() << "Environment for user" << user << "will be" << env; -+ stream.clear(); -+ stream << quint32(AuthMessages::Env) << env; -+ stream.send(); -+ break; - } -- -- // remove extension -- sessionName = session.left(session.lastIndexOf(".")); -- } else { -- command = session; -- sessionName = session; -- } -- -- if (command.isEmpty()) { -- // log error -- qCritical() << " DAEMON: Failed to find command for session:" << session; -- -- // return fail -- return false; -- } -- -- // get display and display -- Seat *seat = m_display->seat(); -- --#ifdef USE_PAM -- if (m_pam) -- delete m_pam; -- -- m_pam = new PamService("sddm", user, password, passwordless); -- -- if (!m_pam) -- return false; -- -- if (!passwordless) { -- // authenticate the applicant -- if ((m_pam->result = pam_authenticate(m_pam->handle, 0)) != PAM_SUCCESS) -- return false; -- -- if ((m_pam->result = pam_acct_mgmt(m_pam->handle, 0)) == PAM_NEW_AUTHTOK_REQD) -- m_pam->result = pam_chauthtok(m_pam->handle, PAM_CHANGE_EXPIRED_AUTHTOK); -- -- if (m_pam->result != PAM_SUCCESS) -- return false; -- } -- -- // set username -- if ((m_pam->result = pam_set_item(m_pam->handle, PAM_USER, qPrintable(user))) != PAM_SUCCESS) -- return false; -- -- // set credentials -- if ((m_pam->result = pam_setcred(m_pam->handle, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) -- return false; -- -- // set tty -- if ((m_pam->result = pam_set_item(m_pam->handle, PAM_TTY, qPrintable(m_display->name()))) != PAM_SUCCESS) -- return false; -- -- // set display name -- if ((m_pam->result = pam_set_item(m_pam->handle, PAM_XDISPLAY, qPrintable(m_display->name()))) != PAM_SUCCESS) -- return false; -- -- // open session -- if ((m_pam->result = pam_open_session(m_pam->handle, 0)) != PAM_SUCCESS) -- return false; -- -- // get mapped user name; PAM may have changed it -- char *mapped; -- if ((m_pam->result = pam_get_item(m_pam->handle, PAM_USER, (const void **)&mapped)) != PAM_SUCCESS) -- return false; --#else -- if (!passwordless) { -- // user name -- struct passwd *pw; -- if ((pw = getpwnam(qPrintable(user))) == nullptr) { -- // log error -- qCritical() << " DAEMON: Failed to get user entry."; -- -- // return fail -- return false; -+ case AuthMessages::LoginFailed: -+ emit loginFailed(m_parentSocket); -+ break; -+ case AuthMessages::LoginSucceeded: { -+ QString user; -+ stream >> m_name >> user; -+ daemonApp->displayManager()->AddSession(m_name, qobject_cast(m_display->parent())->name(), user); -+ emit loginSucceeded(m_parentSocket); -+ break; - } -- -- struct spwd *sp; -- if ((sp = getspnam(pw->pw_name)) == nullptr) { -- // log error -- qCritical() << " DAEMON: Failed to get shadow entry."; -- -- // return fail -- return false; -- } -- -- // check if password is not empty -- if (sp->sp_pwdp && sp->sp_pwdp[0]) { -- -- // encrypt password -- char *encrypted = crypt(qPrintable(password), sp->sp_pwdp); -- -- if (strcmp(encrypted, sp->sp_pwdp)) -- return false; -+ case AuthMessages::RequestSessionID: -+ stream.clear(); -+ stream << quint32(AuthMessages::SessionID) << int(DaemonApp::instance()->newSessionId()); -+ stream.send(); -+ break; -+ case AuthMessages::RequestCookieLink: { -+ QString path, user; -+ struct passwd *pw; -+ stream >> path >> user; -+ qDebug() << "The path is" << path << "and the user" << user; -+ m_display->addCookie(path); -+ pw = getpwnam(qPrintable(user)); -+ if(pw) -+ chown(qPrintable(path), pw->pw_uid, pw->pw_gid); -+ stream.clear(); -+ stream << quint32(AuthMessages::CookieLink); -+ stream.send(); -+ break; - } -+ case AuthMessages::RequestDisplay: -+ stream.clear(); -+ stream << quint32(AuthMessages::Display) << m_display->name(); -+ stream.send(); -+ break; -+ default: -+ qWarning() << " DAEMON: Child sent message type" << quint32(command) << "which cannot be handled."; -+ break; - } -- -- char *mapped = strdup(qPrintable(user)); --#endif -- -- // user name -- struct passwd *pw; -- if ((pw = getpwnam(mapped)) == nullptr) { -- // log error -- qCritical() << " DAEMON: Failed to get user name."; -- -- // return fail -- return false; -- } -- -- if (pw->pw_shell[0] == '\0') { -- setusershell(); -- strcpy(pw->pw_shell, getusershell()); -- endusershell(); -- } -- -- // create user session process -- process = new Session(QString("Session%1").arg(daemonApp->newSessionId()), this); -- -- // set session process params -- process->setUser(pw->pw_name); -- process->setDir(pw->pw_dir); -- process->setUid(pw->pw_uid); -- process->setGid(pw->pw_gid); -- -- // set process environment -- QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); --#ifdef USE_PAM -- // get pam environment -- char **envlist = pam_getenvlist(m_pam->handle); -- -- // copy it to the env map -- for (int i = 0; envlist[i] != nullptr; ++i) { -- QString s(envlist[i]); -- -- // find equal sign -- int index = s.indexOf('='); -- -- // add to the hash -- if (index != -1) -- env.insert(s.left(index), s.mid(index + 1)); -- -- free(envlist[i]); -- } -- free(envlist); --#else -- // we strdup'd the string before in this branch -- free(mapped); --#endif -- env.insert("HOME", pw->pw_dir); -- env.insert("PWD", pw->pw_dir); -- env.insert("SHELL", pw->pw_shell); -- env.insert("USER", pw->pw_name); -- env.insert("LOGNAME", pw->pw_name); -- env.insert("PATH", daemonApp->configuration()->defaultPath()); -- env.insert("DISPLAY", m_display->name()); -- env.insert("XAUTHORITY", QString("%1/.Xauthority").arg(pw->pw_dir)); -- env.insert("XDG_SEAT", seat->name()); -- env.insert("XDG_SEAT_PATH", daemonApp->displayManager()->seatPath(seat->name())); -- env.insert("XDG_SESSION_PATH", daemonApp->displayManager()->sessionPath(process->name())); -- env.insert("XDG_VTNR", QString::number(m_display->terminalId())); -- env.insert("DESKTOP_SESSION", sessionName); -- env.insert("GDMSESSION", sessionName); -- process->setProcessEnvironment(env); -- -- // redirect error output to ~/.xession-errors -- process->setStandardErrorFile(QString("%1/.xsession-errors").arg(pw->pw_dir)); -- -- // start session -- process->start(daemonApp->configuration()->sessionCommand(), { command }); -- -- // connect signal -- connect(process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished())); -- -- // wait for started -- if (!process->waitForStarted()) { -- // log error -- qDebug() << " DAEMON: Failed to start user session."; -- -- // return fail -- return false; -- } -- -- // log message -- qDebug() << " DAEMON: User session started."; -- -- // register to the display manager -- daemonApp->displayManager()->AddSession(process->name(), seat->name(), pw->pw_name); -- -- // set flag -- m_started = true; -- -- // return success -- return true; - } - -- void Authenticator::stop() { -- // check flag -+ void Authenticator::start(QLocalSocket *socket, const QString& user, const QString& session, const QString& password, bool passwordless) { - if (!m_started) - return; - -- // log message -- qDebug() << " DAEMON: User session stopping..."; -+ m_parentSocket = socket; - -- // terminate process -- process->terminate(); -+ SafeDataStream stream(this); -+ stream << quint32(AuthMessages::Start) << user << session << password << passwordless; -+ stream.send(); - -- // wait for finished -- if (!process->waitForFinished(5000)) -- process->kill(); -+ qDebug() << " DAEMON: Starting authentication for user" << user; - } - -- void Authenticator::finished() { -- // check flag -+ void Authenticator::stop() { - if (!m_started) - return; - -- // reset flag -- m_started = false; -- -- // log message -- qDebug() << " DAEMON: User session ended."; -- - // unregister from the display manager -- daemonApp->displayManager()->RemoveSession(process->name()); -+ daemonApp->displayManager()->RemoveSession(m_name); - -- // delete session process -- process->deleteLater(); -- process = nullptr; -+ SafeDataStream stream(this); -+ stream << quint32(AuthMessages::End); -+ stream.send(); - --#ifdef USE_PAM -- if (m_pam) { -- m_pam->result = pam_close_session(m_pam->handle, 0); -- m_pam->result = pam_setcred(m_pam->handle, PAM_DELETE_CRED); -- // for some reason this has to be called here too -- pam_end(m_pam->handle, m_pam->result); -- delete m_pam; -- m_pam = nullptr; -- } --#endif -- -- // emit signal -- emit stopped(); -+ m_started = false; -+ qDebug() << " DAEMON: Stopped the authenticator process"; - } - } -diff --git a/src/daemon/Authenticator.h b/src/daemon/Authenticator.h -index b6c8261..ff9a26b 100644 ---- a/src/daemon/Authenticator.h -+++ b/src/daemon/Authenticator.h -@@ -20,45 +20,41 @@ - #ifndef SDDM_AUTHENTICATOR_H - #define SDDM_AUTHENTICATOR_H - -+#include "Messages.h" -+#include "SafeDataStream.h" -+ - #include -+#include - -+class QLocalSocket; - namespace SDDM { --#ifdef USE_PAM -- class PamService; --#endif -- class Display; -- class Session; - -- class Authenticator : public QObject { -+ class Display; -+ class Authenticator : public QProcess { - Q_OBJECT - Q_DISABLE_COPY(Authenticator) - public: -- Authenticator(Display *parent); -- ~Authenticator(); -+ explicit Authenticator(Display *parent = nullptr); - -- Display *display() const; -+ private slots: -+ void readFromChild(); -+ void handleMessage(AuthMessages command, SafeDataStream &stream); -+ void forwardErrorOutput(); - - public slots: -- bool start(const QString &user, const QString &session); -- bool start(const QString &user, const QString &password, const QString &session); -- -+ void start(QLocalSocket *socket, const QString& user, const QString& session, const QString& password, bool passwordless); - void stop(); -- void finished(); - - signals: -+ void loginFailed(QLocalSocket*); -+ void loginSucceeded(QLocalSocket*); - void stopped(); - - private: -- bool doStart(const QString &user, const QString &password, const QString &session, bool passwordless); -- -- bool m_started { false }; -+ QString m_name; - Display *m_display { nullptr }; -- --#ifdef USE_PAM -- PamService *m_pam { nullptr }; --#endif -- -- Session *process { nullptr }; -+ QLocalSocket *m_parentSocket { nullptr }; // to be got rid of soon -+ bool m_started { false }; - }; - } - -diff --git a/src/daemon/Display.cpp b/src/daemon/Display.cpp -index f1a54b4..d18d839 100644 ---- a/src/daemon/Display.cpp -+++ b/src/daemon/Display.cpp -@@ -23,9 +23,11 @@ - #include "Configuration.h" - #include "DaemonApp.h" - #include "DisplayServer.h" -+#include "DisplayManager.h" - #include "Seat.h" - #include "SocketServer.h" - #include "Greeter.h" -+#include - - #include - #include -@@ -117,12 +119,38 @@ namespace SDDM { - return m_seat; - } - -+ QProcessEnvironment Display::sessionEnv(const QString& user) const { -+ struct passwd *pw; -+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); -+ Seat *seat = qobject_cast(parent()); -+ -+ if ((pw = getpwnam(qPrintable(user))) == nullptr) { -+ // log error -+ qCritical() << " DAEMON: Failed to get user name."; -+ -+ // return fail -+ return QProcessEnvironment(); -+ } -+ env.insert("HOME", pw->pw_dir); -+ env.insert("PWD", pw->pw_dir); -+ env.insert("SHELL", pw->pw_shell); -+ env.insert("USER", pw->pw_name); -+ env.insert("LOGNAME", pw->pw_name); -+ env.insert("PATH", daemonApp->configuration()->defaultPath()); -+ env.insert("DISPLAY", name()); -+ env.insert("XAUTHORITY", QString("%1/.Xauthority").arg(pw->pw_dir)); -+ env.insert("XDG_SEAT", seat->name()); -+ env.insert("XDG_SEAT_PATH", daemonApp->displayManager()->seatPath(seat->name())); -+ env.insert("XDG_VTNR", QString::number(terminalId())); -+ return env; -+ } -+ - void Display::addCookie(const QString &file) { - // log message - qDebug() << " DAEMON: Adding cookie to" << file; - -- // remove file -- QFile::remove(file); -+ // remove the file -+ QFile::remove(m_authPath); - - QString cmd = QString("%1 -f %2 -q").arg(daemonApp->configuration()->xauthPath()).arg(file); - -@@ -176,7 +204,7 @@ namespace SDDM { - m_started = true; - - // start session -- m_authenticator->start(daemonApp->configuration()->autoUser(), daemonApp->configuration()->lastSession()); -+ m_authenticator->start(nullptr, daemonApp->configuration()->autoUser(), daemonApp->configuration()->lastSession(), QString(), true); - - // return - return; -@@ -237,20 +265,18 @@ namespace SDDM { - - void Display::login(QLocalSocket *socket, const QString &user, const QString &password, const QString &session) { - // start session -- if (!m_authenticator->start(user, password, session)) { -- // emit signal -- emit loginFailed(socket); -+ connect(m_authenticator, SIGNAL(loginFailed(QLocalSocket*)), this, SIGNAL(loginFailed(QLocalSocket*))); -+ connect(m_authenticator, SIGNAL(loginSucceeded(QLocalSocket*)), this, SIGNAL(loginSucceeded(QLocalSocket*))); -+ m_authenticator->start(socket, user, session, password, false); - -- // return -- return; -- } -+ m_user = user; -+ m_session = session; -+ } - -- // save last user and last session -- daemonApp->configuration()->setLastUser(user); -- daemonApp->configuration()->setLastSession(session); -+ void Display::slotLoginSucceeded(QLocalSocket* sock) { -+ daemonApp->configuration()->setLastUser(m_user); -+ daemonApp->configuration()->setLastSession(m_session); - daemonApp->configuration()->save(); -- -- // emit signal -- emit loginSucceeded(socket); - } -+ - } -diff --git a/src/daemon/Display.h b/src/daemon/Display.h -index 46d320b..c163853 100644 ---- a/src/daemon/Display.h -+++ b/src/daemon/Display.h -@@ -21,6 +21,7 @@ - #define SDDM_DISPLAY_H - - #include -+#include - - class QLocalSocket; - -@@ -40,6 +41,7 @@ namespace SDDM { - - const int displayId() const; - const int terminalId() const; -+ QProcessEnvironment sessionEnv(const QString& user) const; - - const QString &name() const; - -@@ -54,11 +56,13 @@ namespace SDDM { - - void login(QLocalSocket *socket, const QString &user, const QString &password, const QString &session); - -+ void slotLoginSucceeded(QLocalSocket *sock); -+ - signals: - void stopped(); - -- void loginFailed(QLocalSocket *socket); -- void loginSucceeded(QLocalSocket *socket); -+ void loginFailed(QLocalSocket*); -+ void loginSucceeded(QLocalSocket*); - - private: - bool m_relogin { true }; -@@ -71,6 +75,8 @@ namespace SDDM { - QString m_cookie { "" }; - QString m_socket { "" }; - QString m_authPath { "" }; -+ QString m_user { "" }; -+ QString m_session { "" }; - - Authenticator *m_authenticator { nullptr }; - DisplayServer *m_displayServer { nullptr }; -diff --git a/src/daemon/Session.cpp b/src/daemon/Session.cpp -deleted file mode 100644 -index ec61498..0000000 ---- a/src/daemon/Session.cpp -+++ /dev/null -@@ -1,106 +0,0 @@ --/*************************************************************************** --* Copyright (c) 2013 Abdurrahman AVCI --* --* This program is free software; you can redistribute it and/or modify --* it under the terms of the GNU General Public License as published by --* the Free Software Foundation; either version 2 of the License, or --* (at your option) any later version. --* --* This program is distributed in the hope that it will be useful, --* but WITHOUT ANY WARRANTY; without even the implied warranty of --* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --* GNU General Public License for more details. --* --* You should have received a copy of the GNU General Public License --* along with this program; if not, write to the --* Free Software Foundation, Inc., --* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --***************************************************************************/ -- --#include "Session.h" -- --#include "Authenticator.h" --#include "Configuration.h" --#include "DaemonApp.h" --#include "Display.h" -- --#include -- --#include --#include --#include -- --namespace SDDM { -- Session::Session(const QString &name, Authenticator *parent) : QProcess(parent), m_authenticator(parent), m_name(name) { -- } -- -- const QString &Session::name() const { -- return m_name; -- } -- -- void Session::setUser(const QString &user) { -- m_user = user; -- } -- -- void Session::setDir(const QString &dir) { -- m_dir = dir; -- } -- -- void Session::setUid(int uid) { -- m_uid = uid; -- } -- -- void Session::setGid(int gid) { -- m_gid = gid; -- } -- -- void Session::setupChildProcess() { -- if (daemonApp->configuration()->testing) -- return; -- -- if (initgroups(qPrintable(m_user), m_gid)) { -- qCritical() << " DAEMON: Failed to initialize user groups."; -- -- // emit signal -- emit finished(EXIT_FAILURE, QProcess::NormalExit); -- -- // exit -- exit(EXIT_FAILURE); -- } -- -- if (setgid(m_gid)) { -- qCritical() << " DAEMON: Failed to set group id."; -- -- // emit signal -- emit finished(EXIT_FAILURE, QProcess::NormalExit); -- -- // exit -- exit(EXIT_FAILURE); -- } -- -- if (setuid(m_uid)) { -- qCritical() << " DAEMON: Failed to set user id."; -- -- // emit signal -- emit finished(EXIT_FAILURE, QProcess::NormalExit); -- -- // exit -- exit(EXIT_FAILURE); -- -- } -- -- // add cookie -- m_authenticator->display()->addCookie(QString("%1/.Xauthority").arg(m_dir)); -- -- // change to user home dir -- if (chdir(qPrintable(m_dir))) { -- qCritical() << " DAEMON: Failed to change dir to user home."; -- -- // emit signal -- emit finished(EXIT_FAILURE, QProcess::NormalExit); -- -- // exit -- exit(EXIT_FAILURE); -- } -- } --} -diff --git a/src/daemon/Session.h b/src/daemon/Session.h -deleted file mode 100644 -index eb27402..0000000 ---- a/src/daemon/Session.h -+++ /dev/null -@@ -1,56 +0,0 @@ --/*************************************************************************** --* Copyright (c) 2013 Abdurrahman AVCI --* --* This program is free software; you can redistribute it and/or modify --* it under the terms of the GNU General Public License as published by --* the Free Software Foundation; either version 2 of the License, or --* (at your option) any later version. --* --* This program is distributed in the hope that it will be useful, --* but WITHOUT ANY WARRANTY; without even the implied warranty of --* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --* GNU General Public License for more details. --* --* You should have received a copy of the GNU General Public License --* along with this program; if not, write to the --* Free Software Foundation, Inc., --* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --***************************************************************************/ -- --#ifndef SDDM_SESSION_H --#define SDDM_SESSION_H -- --#include -- --namespace SDDM { -- class Authenticator; -- -- class Session : public QProcess { -- Q_OBJECT -- Q_DISABLE_COPY(Session) -- public: -- explicit Session(const QString &name, Authenticator *parent); -- -- const QString &name() const; -- -- void setUser(const QString &user); -- void setDir(const QString &dir); -- void setUid(int uid); -- void setGid(int gid); -- -- protected: -- void setupChildProcess(); -- -- private: -- Authenticator *m_authenticator; -- -- QString m_name { "" }; -- QString m_user { "" }; -- QString m_dir { "" }; -- -- int m_uid { 0 }; -- int m_gid { 0 }; -- }; --} -- --#endif // SDDM_SESSION_H -diff --git a/src/greeter/ScreenModel.cpp b/src/greeter/ScreenModel.cpp -index fc2b586..abadb0a 100644 ---- a/src/greeter/ScreenModel.cpp -+++ b/src/greeter/ScreenModel.cpp -@@ -28,6 +28,7 @@ - #include - #include - #endif -+#include - - namespace SDDM { - class Screen { -@@ -168,11 +169,14 @@ namespace SDDM { - - for (int i = 0; i < screenCount; ++i) { - QRect geometry = QApplication::desktop()->screenGeometry(i); -+ qDebug() << "Screen" << geometry << QApplication::desktop()->screen(i)->pos(); - // add to the screens list - d->screens << ScreenPtr { new Screen { QString("Screen %1").arg(i + 1), geometry } }; - // extend available geometry - d->geometry = d->geometry.united(geometry); - } -+ QApplication::desktop()->screen()->setGeometry(d->geometry); -+ QApplication::desktop()->screen()->showMaximized(); - #endif - endResetModel(); - diff --git a/sddm-pam_end.patch b/sddm-pam_end.patch new file mode 100644 index 0000000..f9f9391 --- /dev/null +++ b/sddm-pam_end.patch @@ -0,0 +1,14 @@ +--- sddm-7a008602f5f0a4ed8586ce24012983458a687d4e/src/daemon/Authenticator.cpp.pam_end 2013-12-16 15:26:35.749298583 +0100 ++++ sddm-7a008602f5f0a4ed8586ce24012983458a687d4e/src/daemon/Authenticator.cpp 2013-12-16 15:26:45.273274332 +0100 +@@ -418,10 +418,9 @@ namespace SDDM { + if (m_pam) { + m_pam->result = pam_close_session(m_pam->handle, 0); + m_pam->result = pam_setcred(m_pam->handle, PAM_DELETE_CRED); +- // for some reason this has to be called here too +- pam_end(m_pam->handle, m_pam->result); + delete m_pam; + m_pam = nullptr; ++ daemonApp->exit(0); // until PAM is fixed, we have to restart the whole service with audit + } + #endif + \ No newline at end of file diff --git a/sddm-passwordless.pam b/sddm-passwordless.pam deleted file mode 100644 index 0616e66..0000000 --- a/sddm-passwordless.pam +++ /dev/null @@ -1,16 +0,0 @@ - #%PAM-1.0 -auth required pam_env.so -auth required pam_permit.so -auth include postlogin -account required pam_nologin.so -account include system-auth -password include system-auth -session required pam_selinux.so close -session required pam_loginuid.so -session optional pam_console.so --session optional pam_ck_connector.so -session required pam_selinux.so open -session optional pam_keyinit.so force revoke -session required pam_namespace.so -session include system-auth -session include postlogin diff --git a/sddm-savelast.patch b/sddm-savelast.patch deleted file mode 100644 index 6bad2c7..0000000 --- a/sddm-savelast.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- sddm-7a008602f5f0a4ed8586ce24012983458a687d4e/src/daemon/Display.cpp.savelast 2013-11-25 19:41:15.824359536 +0100 -+++ sddm-7a008602f5f0a4ed8586ce24012983458a687d4e/src/daemon/Display.cpp 2013-11-25 19:41:58.793247508 +0100 -@@ -77,6 +77,7 @@ namespace SDDM { - // connect login result signals - connect(this, SIGNAL(loginFailed(QLocalSocket*)), m_socketServer, SLOT(loginFailed(QLocalSocket*))); - connect(this, SIGNAL(loginSucceeded(QLocalSocket*)), m_socketServer, SLOT(loginSucceeded(QLocalSocket*))); -+ connect(this, SIGNAL(loginSucceeded(QLocalSocket*)), this, SLOT(slotLoginSucceeded(QLocalSocket*))); - - // get auth dir - QString authDir = daemonApp->configuration()->authDir(); diff --git a/sddm.spec b/sddm.spec index 35ef24f..0ff970e 100644 --- a/sddm.spec +++ b/sddm.spec @@ -3,7 +3,7 @@ Name: sddm Version: 0.2.0 -Release: 0.22.20131125git%(echo %{sddm_commit} | cut -c-8)%{?dist} +Release: 0.23.20131125git%(echo %{sddm_commit} | cut -c-8)%{?dist} # code GPLv2+, fedora theme CC-BY-SA License: GPLv2+ and CC-BY-SA Summary: QML based X11 desktop manager @@ -20,8 +20,6 @@ Source12: sddm.service # systesmd tmpfiles support for /var/run/sddm Source13: tmpfiles-sddm.conf -Source14: sddm-passwordless.pam - # fedora theme files Source21: fedora-Main.qml Source22: fedora-metadata.desktop @@ -31,9 +29,8 @@ Source23: fedora-theme.conf Patch2: sddm-git.e707e229-session-list.patch Patch3: sddm-0.2.0-0.11.20130914git50ca5b20-xdmcp.patch - -Patch4: sddm-auth.patch -Patch5: sddm-savelast.patch +# Don't end the PAM session twice +Patch4: sddm-pam_end.patch Provides: service(graphical-login) = sddm @@ -74,10 +71,8 @@ A collection of sddm themes, including: circles, elarun, maldives, maui. %setup -q -n %{name}-%{sddm_commit} %patch2 -p1 -b .session-list -# disabled for now -#%patch3 -p1 -b .xdmcp -%patch4 -p1 -b .auth -%patch5 -p1 -b .savelast +%patch3 -p1 -b .xdmcp +%patch4 -p1 -b .pam_end # get rid of the architecture flag sed -i "s/-march=native//" CMakeLists.txt @@ -99,7 +94,6 @@ install -Dpm 644 %{SOURCE10} %{buildroot}%{_sysconfdir}/sddm.conf install -Dpm 644 %{SOURCE11} %{buildroot}%{_sysconfdir}/pam.d/sddm install -Dpm 644 %{SOURCE12} %{buildroot}%{_unitdir}/sddm.service install -Dpm 644 %{SOURCE13} %{buildroot}%{_tmpfilesdir}/sddm.conf -install -Dpm 644 %{SOURCE14} %{buildroot}%{_sysconfdir}/pam.d/sddm-passwordless mkdir -p %{buildroot}%{_localstatedir}/run/sddm # install fedora theme @@ -121,10 +115,8 @@ install -Dpm 644 %{SOURCE23} %{buildroot}%{_datadir}/apps/sddm/themes/fedora/the %doc COPYING README.md CONTRIBUTORS %config %{_sysconfdir}/sddm.conf %config(noreplace) %{_sysconfdir}/pam.d/sddm -%config(noreplace) %{_sysconfdir}/pam.d/sddm-passwordless %config(noreplace) %{_sysconfdir}/dbus-1/system.d/org.freedesktop.DisplayManager.conf %{_bindir}/sddm -%{_bindir}/sddm-auth %{_bindir}/sddm-greeter %{_tmpfilesdir}/sddm.conf %attr(0711,root,root) %dir %{_localstatedir}/run/sddm @@ -150,6 +142,9 @@ install -Dpm 644 %{SOURCE23} %{buildroot}%{_datadir}/apps/sddm/themes/fedora/the %{_datadir}/apps/sddm/themes/maui/ %changelog +* Mon Dec 16 2013 Martin Briza - 0.2.0-0.23.20131125git7a008602 +- Revert all work done on authentication, doesn't support multiple logins right now + * Mon Nov 25 2013 Martin Briza - 0.2.0-0.22.20131125git7a008602 - Fix saving of last session and user