Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions data/scripts/Xsetup
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#!/bin/sh
# Xsetup - run as root before the login dialog appears

# Allow all client connect to the Xorg server. Since our X server is started as
# root, but sessions are started as user.
xhost +
39 changes: 38 additions & 1 deletion src/auth/Auth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,16 @@ namespace DDM {
QLocalSocket *socket { nullptr };
QString displayServerCmd;
QString sessionPath { };
Session::Type sessionType { Session::UnknownSession };
QString sessionFileName { };
QString user { };
QString password { };
QByteArray cookie { };
bool autologin { false };
bool greeter { false };
bool singleMode { false };
bool identifyOnly { false };
bool skipAuth { false };
QProcessEnvironment environment { };
qint64 id { 0 };
static qint64 lastId;
Expand Down Expand Up @@ -317,6 +320,18 @@ namespace DDM {
return d->sessionId;
}

Session::Type Auth::sessionType() const {
return d->sessionType;
}

QString Auth::sessionFileName() const {
return d->sessionFileName;
}

bool Auth::isSingleMode() const {
return d->singleMode;
}

bool Auth::isActive() const {
return d->child->state() != QProcess::NotRunning;
}
Expand Down Expand Up @@ -394,6 +409,14 @@ namespace DDM {
}
}

void Auth::setSessionType(const Session::Type type) {
d->sessionType = type;
}

void Auth::setSessionFileName(const QString &fileName) {
d->sessionFileName = fileName;
}

int Auth::tty() const {
return d->tty;
}
Expand Down Expand Up @@ -424,6 +447,12 @@ namespace DDM {
}
}

void Auth::setSkipAuth(bool on) {
if (on != d->skipAuth) {
d->skipAuth = on;
}
}

void Auth::start() {
QStringList args;
args << QStringLiteral("--socket") << SocketServer::instance()->fullServerName();
Expand All @@ -442,6 +471,8 @@ namespace DDM {
args << QStringLiteral("--single-mode");
if (d->identifyOnly)
args << QStringLiteral("--identify-only");
if (d->skipAuth)
args << QStringLiteral("--skip-auth");
d->child->start(QStringLiteral("%1/ddm-helper").arg(QStringLiteral(LIBEXEC_INSTALL_DIR)), args);
}

Expand All @@ -453,7 +484,13 @@ namespace DDM {
d->child->terminate();

// wait for finished
if (!d->child->waitForFinished(5000))
// TODO: Cut off the waiting.
// The code will be executed when user trying to start sessions other
// than treeland, which will stop the currentAuth and start a new one.
// This process involves the removal of seatd client, which needs a
// small amount of time to wait. Consider to make this process under
// control.
if (!d->child->waitForFinished(500))
d->child->kill();
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/auth/Auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@

#include "AuthRequest.h"
#include "AuthPrompt.h"
#include "Session.h"

Check warning on line 26 in src/auth/Auth.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "Session.h" not found.

#include <QtCore/QObject>

Check warning on line 28 in src/auth/Auth.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QtCore/QObject> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QtCore/QProcessEnvironment>

Check warning on line 29 in src/auth/Auth.h

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QtCore/QProcessEnvironment> not found. Please note: Cppcheck does not need standard library headers to get proper results.

namespace DDM {
/**
Expand Down Expand Up @@ -97,12 +98,15 @@
bool isGreeter() const;
bool verbose() const;
bool identifyOnly() const;
bool isSingleMode() const;
const QByteArray &cookie() const;
const QString &user() const;
const QString &session() const;
const QString &password() const;
AuthRequest *request();
QString sessionId() const;
Session::Type sessionType() const;
QString sessionFileName() const;
int tty() const;

void setTTY(int tty);
Expand Down Expand Up @@ -146,6 +150,8 @@
void setVerbose(bool on = true);

void setIdentifyOnly(bool on = false);

void setSkipAuth(bool on = true);
/**
* Sets the user which will then authenticate
* @param user username
Expand Down Expand Up @@ -179,7 +185,11 @@
*/
void setSingleMode(bool on = true);

void setSessionId(const QString& sessionId);
void setSessionId(const QString &sessionId);

void setSessionType(const Session::Type type);

void setSessionFileName(const QString &fileName);

public Q_SLOTS:
/**
Expand Down
56 changes: 49 additions & 7 deletions src/daemon/Display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,11 +590,13 @@ namespace DDM {
}

auth->setUser(user);
auth->setSessionType(session.type());
auth->setSessionFileName(session.fileName());
if (m_reuseSessionId.isNull()) {
auth->setSession(session.exec());
}
auth->insertEnvironment(env);
auth->setSingleMode(m_displayServerType == DisplayServerType::SingleCompositerServerType);
auth->setSingleMode(session.isSingleMode());
auth->start();
}

Expand Down Expand Up @@ -634,22 +636,61 @@ namespace DDM {
else
stateConfig.Last.User.setDefault();
if (mainConfig.Users.RememberLastSession.get())
stateConfig.Last.Session.set(auth->session());
stateConfig.Last.Session.set(auth->sessionFileName());
else
stateConfig.Last.Session.setDefault();
stateConfig.save();

if (m_displayServerType == DisplayServerType::SingleCompositerServerType) {
if (auth->isSingleMode()) {
auto* server = reinterpret_cast<SingleWaylandDisplayServer*>(m_displayServer);
server->onLoginSucceeded(user);
switchToUser(auth->user());
} else {
if (m_socket) {
emit loginSucceeded(m_socket, user);
daemonApp->displayManager()->setLastSession(auth->sessionId());
}
}
if (auth->identifyOnly())
return;

switchToUser(auth->user());
// Stop the original suit of displayServer since it has finished its job.
disconnect(m_displayServer, &DisplayServer::stopped, this, &Display::stop);
m_displayServer->stop();
delete m_displayServer;
m_greeter->stop();
delete m_greeter;
m_currentAuth->stop();
m_socketServer->stop();
delete m_socketServer;

// Start the target displayServer
m_terminalId = m_sessionTerminalId = fetchAvailableVt();
m_started = false;

if (auth->sessionType() == Session::X11Session) {
m_displayServer = new XorgDisplayServer(this);
m_displayServerType = X11DisplayServerType;
} else {
m_displayServer = new WaylandDisplayServer(this);
m_displayServerType = WaylandDisplayServerType;
}
connect(m_displayServer, &DisplayServer::started, this, &Display::displayServerStarted);
connect(m_displayServer, &DisplayServer::stopped, this, &Display::stop);

m_socketServer = new SocketServer(this);

// The greeter here is used to start user session.
m_greeter = new Greeter(this);
m_greeter->setDisplayServerCommand(auth->session());
m_greeter->setUser(user);
m_greeter->setSkipAuth();

connect(m_greeter, &Greeter::failed, this, &Display::stop);
connect(m_greeter, &Greeter::displayServerFailed, this, &Display::displayServerFailed);
connect(m_greeter, &Greeter::succeed, this, &Display::stop);

m_displayServer->start();
}
}
m_socket = nullptr;
}
Expand Down Expand Up @@ -711,7 +752,8 @@ namespace DDM {
}
}

if (status != Auth::HELPER_AUTH_ERROR && m_displayServerType != DisplayServerType::SingleCompositerServerType)
// Don't restart display when ddm-helper crashed (exit code 9)
if (status != Auth::HELPER_AUTH_ERROR && status != Auth::HelperExitStatus(9) && m_displayServerType != DisplayServerType::SingleCompositerServerType)
stop();
}

Expand All @@ -730,7 +772,7 @@ namespace DDM {
void Display::slotSessionStarted(bool success) {
qDebug() << "Session started" << success;
Auth* auth = qobject_cast<Auth*>(sender());
if (m_displayServerType == SingleCompositerServerType) {
if (auth->isSingleMode()) {
switchToUser(auth->user());
}

Expand Down
19 changes: 17 additions & 2 deletions src/daemon/Greeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ namespace DDM {
m_singleMode = on;
}

void Greeter::setUser(const QString &user) {
m_user = user;
}

void Greeter::setSkipAuth(bool on) {
m_skipAuth = on;
}

void Greeter::setUserActivated(bool active) {
m_userActivated = active;
}
Expand Down Expand Up @@ -226,7 +234,8 @@ namespace DDM {
if (m_display->displayServerType() == Display::X11DisplayServerType) {
env.insert(QStringLiteral("DISPLAY"), m_display->name());
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("xcb"));
m_auth->setCookie(qobject_cast<XorgDisplayServer*>(displayServer)->cookie());
if (m_display->sessionType() == "x11")
m_auth->setCookie(qobject_cast<XorgDisplayServer*>(displayServer)->cookie());
} else if (m_display->displayServerType() == Display::WaylandDisplayServerType) {
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
env.insert(QStringLiteral("QT_WAYLAND_SHELL_INTEGRATION"), QStringLiteral("fullscreen-shell-v1"));
Expand All @@ -240,7 +249,7 @@ namespace DDM {
qDebug() << "Greeter starting...";

// start greeter
m_auth->setUser(QStringLiteral("dde"));
m_auth->setUser(m_user);
QString displayServerCmd = m_displayServerCmd;
if (m_singleMode) {
displayServerCmd += " --lockscreen";
Expand All @@ -255,6 +264,10 @@ namespace DDM {
return true;
}

if (m_skipAuth) {
m_auth->setSkipAuth();
}

m_auth->start();

m_tryTimer->start();
Expand Down Expand Up @@ -371,6 +384,8 @@ namespace DDM {
Q_EMIT ttyFailed();
} else if (status == Auth::HELPER_SESSION_ERROR) {
Q_EMIT failed();
} else if (status == Auth::HELPER_SUCCESS) {
Q_EMIT succeed();
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/daemon/Greeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ namespace DDM {
void setSocket(const QString &socket);
void setTheme(const QString &theme);
void setSingleMode(bool on = true);
void setUser(const QString &user);
void setSkipAuth(bool on = true);
void setUserActivated(bool active);

QString displayServerCommand() const;
Expand All @@ -67,6 +69,7 @@ namespace DDM {
void ttyFailed();
void failed();
void displayServerFailed();
void succeed();
void greeterStarted();

private:
Expand All @@ -75,6 +78,8 @@ namespace DDM {
bool m_userActivated { false };
int m_currentRetry { 0 };
int m_maxRetry{ 3 };
QString m_user = QStringLiteral("dde");
bool m_skipAuth { false };

Display * const m_display { nullptr };
QString m_socket;
Expand Down
6 changes: 5 additions & 1 deletion src/helper/HelperApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ namespace DDM {
m_backend->setIdentifyOnly(true);
}

if ((pos = args.indexOf(QStringLiteral("--skip-auth"))) >= 0) {
m_skipAuth = true;
}

if (server.isEmpty() || m_id <= 0) {
qCritical() << "This application is not supposed to be executed manually";
exit(Auth::HELPER_OTHER_ERROR);
Expand Down Expand Up @@ -163,7 +167,7 @@ namespace DDM {
}

Q_ASSERT(getuid() == 0);
if (!m_backend->authenticate()) {
if (!m_skipAuth && !m_backend->authenticate()) {
authenticated(QString());

// write failed login to btmp
Expand Down
1 change: 1 addition & 0 deletions src/helper/HelperApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ namespace DDM {
QString m_user { };
// TODO: get rid of this in a nice clean way along the way with moving to user session X server
QByteArray m_cookie { };
bool m_skipAuth = false;

/*!
\brief Write utmp/wtmp/btmp records when a user logs in
Expand Down
13 changes: 4 additions & 9 deletions src/helper/UserSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,9 @@ namespace DDM {
}

qInfo() << "Starting X11 session:" << m_displayServerCmd << command;
if (m_displayServerCmd.isEmpty()) {
auto args = QProcess::splitCommand(command);
setProgram(args.takeFirst());
setArguments(args);
} else {
setProgram(QStringLiteral(LIBEXEC_INSTALL_DIR "/ddm-helper-start-x11user"));
setArguments({m_displayServerCmd, command});
}
auto args = QProcess::splitCommand(m_displayServerCmd);
setProgram(args.takeFirst());
setArguments(args);
QProcess::start();

} else if (env.value(QStringLiteral("XDG_SESSION_TYPE")) == QLatin1String("wayland")) {
Expand Down Expand Up @@ -238,7 +233,7 @@ namespace DDM {

// take control of the tty
if (takeControl) {
if (ioctl(STDIN_FILENO, TIOCSCTTY, 0) < 0) {
if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0) {
const auto error = strerror(errno);
qCritical().nospace() << "Failed to take control of " << ttyString << " (" << QFileInfo(ttyString).owner() << "): " << error;
_exit(Auth::HELPER_TTY_ERROR);
Expand Down