Use QAuth for authentication

Now that SDDM includes QAuth we can take advantage of its improved
authentication support.

This is based on PR #155 by Martin Bříza <mbriza@redhat.com>
This commit is contained in:
Pier Luigi Fiorini 2014-06-05 05:03:48 +02:00
parent dba8027899
commit 17e31aaef0
11 changed files with 163 additions and 558 deletions

View File

@ -125,6 +125,8 @@ set(DATA_INSTALL_DIR "${CMAKE_INSTALL_FULL_DATADIR}/sddm"
set(DBUS_CONFIG_DIR "${CMAKE_INSTALL_SYSCONFDIR}/dbus-1/system.d" CACHE PATH "DBus config files directory")
set(STATE_DIR "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/sddm" CACHE PATH "State directory")
set(SESSION_COMMAND "${DATA_INSTALL_DIR}/scripts/Xsession" CACHE PATH "Script to execute when starting the desktop session")
set(CONFIG_FILE "${CMAKE_INSTALL_FULL_SYSCONFDIR}/sddm.conf" CACHE PATH "Path of the sddm config file")
set(LOG_FILE "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/log/sddm.log" CACHE PATH "Path of the sddm log file")
set(COMPONENTS_TRANSLATION_DIR "${DATA_INSTALL_DIR}/translations" CACHE PATH "Components translations directory")

View File

@ -70,7 +70,7 @@ All options are configured in the [General] section:
`SessionCommand=`
Path of script to execute when starting the desktop session.
Default value is "@DATA_INSTALL_DIR@/scripts/Xsession".
Default value is "@SESSION_COMMAND@".
`FacesDir=`
Path of the directory containing face files,

View File

@ -35,7 +35,7 @@ LastSession=
RememberLastSession=true
# Path of script to execute when starting the desktop session
SessionCommand=${DATA_INSTALL_DIR}/scripts/Xsession
SessionCommand=@SESSION_COMMAND@
# Path of the directory containing face files
# Face files should be in username.face.icon format

View File

@ -9,7 +9,6 @@ set(DAEMON_SOURCES
common/Configuration.cpp
common/SafeDataStream.cpp
common/SocketWriter.cpp
daemon/Authenticator.cpp
daemon/DaemonApp.cpp
daemon/Display.cpp
daemon/DisplayManager.cpp

View File

@ -28,9 +28,9 @@
#define COMPONENTS_TRANSLATION_DIR "@COMPONENTS_TRANSLATION_DIR@"
#define STATE_DIR "@STATE_DIR@"
#define SESSION_COMMAND "@SESSION_COMMAND@"
#define CONFIG_FILE "@CONFIG_FILE@"
#define LOG_FILE "@LOG_FILE@"
#define QAUTH_XSESSION_PATH "/etc/X11/xinit/Xsession"
#endif // SDDM_CONSTANTS_H

View File

@ -1,463 +0,0 @@
/***************************************************************************
* Copyright (c) 2013 Abdurrahman AVCI <abdurrahmanavci@gmail.com>
*
* 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 "Authenticator.h"
#include "Configuration.h"
#include "DaemonApp.h"
#include "Display.h"
#include "DisplayManager.h"
#include "Seat.h"
#include "Session.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QTextStream>
#ifdef USE_PAM
#include <security/pam_appl.h>
#else
#include <crypt.h>
#include <shadow.h>
#endif
#include <grp.h>
#include <pwd.h>
#include <unistd.h>
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<PamService *>(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<PamService *>(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;
}
*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();
#ifdef USE_PAM
delete m_pam;
#endif
}
Display *Authenticator::display() const {
return m_display;
}
bool Authenticator::start(const QString &user, const QString &session) {
return doStart(user, QString(), session, true);
}
bool Authenticator::start(const QString &user, const QString &password, const QString &session) {
return doStart(user, password, session, false);
}
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 xdgSessionName = "";
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);
// Desktop names, change the separator
if (line.startsWith("DesktopNames=")) {
xdgSessionName = line.mid(13);
xdgSessionName.replace(';', ':');
}
}
// close file
file.close();
}
// remove extension
sessionName = session.left(session.lastIndexOf("."));
} else {
command = session;
sessionName = session;
}
if (command.isEmpty()) {
// log error
qCritical() << "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;
if (!passwordless)
m_pam = new PamService("sddm", user, password, passwordless);
else
m_pam = new PamService("sddm-autologin", user, password, passwordless);
if (!m_pam)
return false;
// 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;
// specify session information for logind
if ((pam_putenv(m_pam->handle, "XDG_SESSION_CLASS=user")) != PAM_SUCCESS)
return false;
if ((pam_putenv(m_pam->handle, "XDG_SESSION_TYPE=x11")) != PAM_SUCCESS)
return false;
if ((pam_putenv(m_pam->handle, qPrintable("XDG_SESSION_DESKTOP=" + xdgSessionName))) != PAM_SUCCESS)
return false;
//set the seat name. This is saves the logind PAM module trying to find it.
//The logind pam module is not always able to find it if we have only just started the X server
QString pamSeatEnv = "XDG_SEAT=" + seat->name();
pam_putenv(m_pam->handle, qPrintable(pamSeatEnv));
QString pamVtnrEnv = "XDG_VTNR=" + QString::number(m_display->terminalId());
pam_putenv(m_pam->handle, qPrintable(pamVtnrEnv));
// 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() << "Failed to get user entry.";
// return fail
return false;
}
struct spwd *sp;
if ((sp = getspnam(pw->pw_name)) == nullptr) {
// log error
qCritical() << "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;
}
}
char *mapped = strdup(qPrintable(user));
#endif
// user name
struct passwd *pw;
if ((pw = getpwnam(mapped)) == nullptr) {
// log error
qCritical() << "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()), m_display, 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);
// session information
env.insert("XDG_SESSION_CLASS", "user");
env.insert("XDG_SESSION_TYPE", "x11");
env.insert("XDG_SESSION_DESKTOP", xdgSessionName);
#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_CURRENT_DESKTOP", xdgSessionName);
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);
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() << "Failed to start user session.";
// return fail
return false;
}
// log message
qDebug() << "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
if (!m_started)
return;
// log message
qDebug() << "User session stopping...";
// terminate process
process->terminate();
// wait for finished
if (!process->waitForFinished(5000))
process->kill();
process->deleteLater();
process = nullptr;
}
void Authenticator::finished() {
// check flag
if (!m_started)
return;
// reset flag
m_started = false;
// log message
qDebug() << "User session ended.";
// unregister from the display manager
daemonApp->displayManager()->RemoveSession(process->name());
// delete session process
process->deleteLater();
process = nullptr;
#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);
delete m_pam;
m_pam = nullptr;
}
#endif
// emit signal
emit stopped();
}
}

View File

@ -1,65 +0,0 @@
/***************************************************************************
* Copyright (c) 2013 Abdurrahman AVCI <abdurrahmanavci@gmail.com>
*
* 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_AUTHENTICATOR_H
#define SDDM_AUTHENTICATOR_H
#include <QObject>
namespace SDDM {
#ifdef USE_PAM
class PamService;
#endif
class Display;
class Session;
class Authenticator : public QObject {
Q_OBJECT
Q_DISABLE_COPY(Authenticator)
public:
Authenticator(Display *parent);
~Authenticator();
Display *display() const;
public slots:
bool start(const QString &user, const QString &session);
bool start(const QString &user, const QString &password, const QString &session);
void stop();
void finished();
signals:
void stopped();
private:
bool doStart(const QString &user, const QString &password, const QString &session, bool passwordless);
bool m_started { false };
Display *m_display { nullptr };
#ifdef USE_PAM
PamService *m_pam { nullptr };
#endif
Session *process { nullptr };
};
}
#endif // SDDM_AUTHENTICATOR_H

View File

@ -1,4 +1,6 @@
/***************************************************************************
* Copyright (c) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
* Copyright (c) 2014 Martin Bříza <mbriza@redhat.com>
* Copyright (c) 2013 Abdurrahman AVCI <abdurrahmanavci@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@ -19,9 +21,9 @@
#include "Display.h"
#include "Authenticator.h"
#include "Configuration.h"
#include "DaemonApp.h"
#include "DisplayManager.h"
#include "DisplayServer.h"
#include "Seat.h"
#include "SocketServer.h"
@ -33,13 +35,14 @@
#include <QFile>
#include <QTimer>
#include <grp.h>
#include <pwd.h>
#include <unistd.h>
namespace SDDM {
Display::Display(const int displayId, const int terminalId, Seat *parent) : QObject(parent),
m_displayId(displayId), m_terminalId(terminalId),
m_authenticator(new Authenticator(this)),
m_auth(new QAuth(this)),
m_displayServer(new DisplayServer(this)),
m_seat(parent),
m_socketServer(new SocketServer(this)),
@ -47,8 +50,14 @@ namespace SDDM {
m_display = QString(":%1").arg(m_displayId);
// restart display after user session ended
connect(m_authenticator, SIGNAL(stopped()), this, SLOT(stop()));
// respond to authentication requests
m_auth->setVerbose(true);
connect(m_auth, SIGNAL(requestChanged()), this, SLOT(slotRequestChanged()));
connect(m_auth, SIGNAL(authentication(QString,bool)), this, SLOT(slotAuthenticationFinished(QString,bool)));
connect(m_auth, SIGNAL(session(bool)), this, SLOT(slotSessionStarted(bool)));
connect(m_auth, SIGNAL(finished(bool)), this, SLOT(slotHelperFinished(bool)));
connect(m_auth, SIGNAL(info(QString,QAuth::Info)), this, SLOT(slotAuthInfo(QString,QAuth::Info)));
connect(m_auth, SIGNAL(error(QString,QAuth::Error)), this, SLOT(slotAuthError(QString,QAuth::Error)));
// restart display after display server ended
connect(m_displayServer, SIGNAL(stopped()), this, SLOT(stop()));
@ -168,7 +177,8 @@ namespace SDDM {
m_started = true;
// start session
m_authenticator->start(daemonApp->configuration()->autoUser(), daemonApp->configuration()->lastSession());
m_auth->setAutologin(true);
startAuth(daemonApp->configuration()->autoUser(), QString(), daemonApp->configuration()->lastSession());
// return
return;
@ -198,11 +208,6 @@ namespace SDDM {
if (!m_started)
return;
// stop user session
m_authenticator->blockSignals(true);
m_authenticator->stop();
m_authenticator->blockSignals(false);
// stop the greeter
m_greeter->stop();
@ -225,21 +230,133 @@ 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);
m_socket = socket;
startAuth(user, password, session);
}
// return
void Display::startAuth(const QString &user, const QString &password, const QString &session) {
QString sessionName;
QString xdgSessionName;
QString command;
m_passPhrase = password;
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);
// Desktop names, change the separator
if (line.startsWith("DesktopNames=")) {
xdgSessionName = line.mid(13);
xdgSessionName.replace(';', ':');
}
}
// close file
file.close();
}
// remove extension
sessionName = session.left(session.lastIndexOf("."));
} else {
command = session;
sessionName = session;
}
if (command.isEmpty()) {
qCritical() << "Failed to find command for session:" << session;
return;
}
// save last user and last session
daemonApp->configuration()->setLastUser(user);
daemonApp->configuration()->setLastSession(session);
daemonApp->configuration()->save();
// save session desktop file name, we'll use it to set the
// last session later, in slotAuthenticationFinished()
m_sessionName = session;
// emit signal
emit loginSucceeded(socket);
QProcessEnvironment env;
env.insert("PATH", daemonApp->configuration()->defaultPath());
env.insert("DISPLAY", name());
env.insert("XDG_SEAT", seat()->name());
env.insert("XDG_SEAT_PATH", daemonApp->displayManager()->seatPath(seat()->name()));
env.insert("XDG_SESSION_PATH", daemonApp->displayManager()->sessionPath(QString("Session%1").arg(daemonApp->newSessionId())));
env.insert("XDG_VTNR", QString::number(terminalId()));
env.insert("DESKTOP_SESSION", sessionName);
env.insert("XDG_CURRENT_DESKTOP", xdgSessionName);
env.insert("XDG_SESSION_CLASS", "user");
env.insert("XDG_SESSION_TYPE", "x11");
env.insert("XDG_SESSION_DESKTOP", xdgSessionName);
m_auth->insertEnvironment(env);
m_auth->setUser(user);
m_auth->setSession(command);
m_auth->start();
}
void Display::slotAuthenticationFinished(const QString &user, bool success) {
if (success) {
qDebug() << "Authenticated successfully";
struct passwd *pw = getpwnam(qPrintable(user));
if (pw) {
addCookie(QString("%1/.Xauthority").arg(pw->pw_dir));
chown(qPrintable(QString("%1/.Xauthority").arg(pw->pw_dir)), pw->pw_uid, pw->pw_gid);
}
// save last user and session
daemonApp->configuration()->setLastUser(m_auth->user());
daemonApp->configuration()->setLastSession(m_sessionName);
daemonApp->configuration()->save();
if (m_socket)
emit loginSucceeded(m_socket);
} else if (m_socket) {
qDebug() << "Authentication failure";
emit loginFailed(m_socket);
}
m_socket = nullptr;
}
void Display::slotAuthInfo(const QString &message, QAuth::Info info) {
// TODO: presentable to the user, eventually
Q_UNUSED(info);
qWarning() << "Authentication information:" << message;
}
void Display::slotAuthError(const QString &message, QAuth::Error error) {
// TODO: presentable to the user, eventually
Q_UNUSED(error);
qWarning() << "Authentication error:" << message;
}
void Display::slotHelperFinished(bool success) {
stop();
}
void Display::slotRequestChanged() {
if (m_auth->request()->prompts().length() == 1) {
m_auth->request()->prompts()[0]->setResponse(qPrintable(m_passPhrase));
m_auth->request()->done();
} else if (m_auth->request()->prompts().length() == 2) {
m_auth->request()->prompts()[0]->setResponse(qPrintable(m_auth->user()));
m_auth->request()->prompts()[1]->setResponse(qPrintable(m_passPhrase));
m_auth->request()->done();
}
}
void Display::slotSessionStarted(bool success) {
qDebug() << "Session started";
}
}

View File

@ -1,4 +1,6 @@
/***************************************************************************
* Copyright (c) 2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
* Copyright (c) 2014 Martin Bříza <mbriza@redhat.com>
* Copyright (c) 2013 Abdurrahman AVCI <abdurrahmanavci@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
@ -22,6 +24,8 @@
#include <QObject>
#include "qauth/QAuth.h"
class QLocalSocket;
namespace SDDM {
@ -61,6 +65,8 @@ namespace SDDM {
void loginSucceeded(QLocalSocket *socket);
private:
void startAuth(const QString &user, const QString &password, const QString &session);
bool m_relogin { true };
bool m_started { false };
@ -69,14 +75,24 @@ namespace SDDM {
QString m_display { ":0" };
QString m_cookie { "" };
QString m_socket { "" };
QString m_authPath { "" };
QString m_passPhrase;
QString m_sessionName;
Authenticator *m_authenticator { nullptr };
QAuth *m_auth { nullptr };
DisplayServer *m_displayServer { nullptr };
Seat *m_seat { nullptr };
SocketServer *m_socketServer { nullptr };
QLocalSocket *m_socket { nullptr };
Greeter *m_greeter { nullptr };
private slots:
void slotRequestChanged();
void slotAuthenticationFinished(const QString &user, bool success);
void slotSessionStarted(bool success);
void slotHelperFinished(bool success);
void slotAuthInfo(const QString &message, QAuth::Info info);
void slotAuthError(const QString &message, QAuth::Error error);
};
}

View File

@ -19,7 +19,6 @@
#include "Session.h"
#include "Authenticator.h"
#include "Configuration.h"
#include "DaemonApp.h"
#include "Display.h"

View File

@ -36,7 +36,7 @@ QAuthSession::~QAuthSession() {
}
bool QAuthSession::start() {
QProcess::start(QAUTH_XSESSION_PATH, {m_path});
QProcess::start(SESSION_COMMAND, {m_path});
return waitForStarted();
}