From 367665f1cf4a198f4d003ba8a982e447caedfb61 Mon Sep 17 00:00:00 2001 From: Sasasu Date: Wed, 20 Jun 2018 20:03:15 +0800 Subject: [PATCH 1/2] use fingerprint and password at same time #284 --- data/man/sddm.conf.rst.in | 12 ++++++++++ services/CMakeLists.txt | 2 ++ services/sddm-fingerprint.pam | 20 ++++++++++++++++ src/auth/Auth.cpp | 25 +++++++++++++++++--- src/auth/Auth.h | 10 ++++++++ src/common/Configuration.h | 5 ++++ src/daemon/Display.cpp | 39 +++++++++++++++++++++++++++++++ src/daemon/Display.h | 1 + src/daemon/SocketServer.cpp | 2 +- src/daemon/SocketServer.h | 2 +- src/helper/Backend.cpp | 5 ++++ src/helper/Backend.h | 5 ++++ src/helper/HelperApp.cpp | 4 ++++ src/helper/backend/PamBackend.cpp | 3 +++ 14 files changed, 130 insertions(+), 5 deletions(-) create mode 100755 services/sddm-fingerprint.pam diff --git a/data/man/sddm.conf.rst.in b/data/man/sddm.conf.rst.in index 32bebf837..de8b155c9 100644 --- a/data/man/sddm.conf.rst.in +++ b/data/man/sddm.conf.rst.in @@ -246,6 +246,18 @@ The `UserAuthFile=` option was removed, the file is always created as only the first time. Default value is false. +[Fingerprintlogin] section: + +`User=` + Name of the user who uses fingerprint login when the + system starts first time. + Default value is empty. + +`Session=` + Name of the user who uses fingerprint login when the + system starts first time. + Default value is empty. + SEE ALSO ======== diff --git a/services/CMakeLists.txt b/services/CMakeLists.txt index 856319df2..0a6e19cd6 100644 --- a/services/CMakeLists.txt +++ b/services/CMakeLists.txt @@ -19,6 +19,8 @@ else() endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sddm-greeter.pam.in" "${CMAKE_CURRENT_BINARY_DIR}/sddm-greeter.pam") +install(FILES sddm-fingerprint.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME sddm-fingerprint) + if(EXISTS "/etc/debian_version") install(FILES debian.sddm-autologin.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME sddm-autologin) install(FILES debian.sddm-greeter.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME sddm-greeter) diff --git a/services/sddm-fingerprint.pam b/services/sddm-fingerprint.pam new file mode 100755 index 000000000..938973415 --- /dev/null +++ b/services/sddm-fingerprint.pam @@ -0,0 +1,20 @@ +#%PAM-1.0 + +auth required pam_env.so +auth required pam_faillock.so preauth +auth required pam_shells.so +auth required pam_nologin.so +auth required pam_fprintd.so +auth optional pam_permit.so +-auth optional pam_gnome_keyring.so +-auth optional pam_kwallet5.so + +account include system-local-login +password include system-local-login +session include system-local-login + +password required pam_fprintd.so +password optional pam_permit.so + +-session optional pam_gnome_keyring.so auto_start +-session optional pam_kwallet5.so auto_start diff --git a/src/auth/Auth.cpp b/src/auth/Auth.cpp index 6c9b5c6b4..dbc854868 100644 --- a/src/auth/Auth.cpp +++ b/src/auth/Auth.cpp @@ -67,6 +67,7 @@ namespace SDDM { QString user { }; QByteArray cookie { }; bool autologin { false }; + bool fingerprintlogin { false }; bool greeter { false }; QProcessEnvironment environment { }; qint64 id { 0 }; @@ -225,12 +226,13 @@ namespace SDDM { Q_EMIT qobject_cast(parent())->error(child->errorString(), ERROR_INTERNAL); } - if (exitCode == HELPER_SUCCESS) + if (exitCode == HELPER_SUCCESS) { qDebug() << "Auth: sddm-helper exited successfully"; + emit qobject_cast(parent())->finished(static_cast(exitCode)); + } + else qWarning("Auth: sddm-helper exited with %d", exitCode); - - Q_EMIT qobject_cast(parent())->finished((Auth::HelperExitStatus)exitCode); } void Auth::Private::childError(QProcess::ProcessError error) { @@ -276,6 +278,10 @@ namespace SDDM { return d->autologin; } + bool Auth::fingerprintlogin() const { + return d->fingerprintlogin; + } + bool Auth::isGreeter() const { return d->greeter; @@ -334,6 +340,12 @@ namespace SDDM { } } + void Auth::setFingerprintlogin(bool on){ + if(on != d->fingerprintlogin){ + d->fingerprintlogin = on; + } + } + void Auth::setGreeter(bool on) { if (on != d->greeter) { @@ -377,10 +389,17 @@ namespace SDDM { args << QStringLiteral("--user") << d->user; if (d->autologin) args << QStringLiteral("--autologin"); + if (d->fingerprintlogin) + args << QStringLiteral("--fingerprintlogin"); if (!d->displayServerCmd.isEmpty()) args << QStringLiteral("--display-server") << d->displayServerCmd; if (d->greeter) args << QStringLiteral("--greeter"); + if(d->child->state() != QProcess::NotRunning){ + d->child->terminate(); + d->child->waitForFinished(); + } + qDebug() << "starting sddm-helper with" << args; d->child->start(QStringLiteral("%1/sddm-helper").arg(QStringLiteral(LIBEXEC_INSTALL_DIR)), args); } diff --git a/src/auth/Auth.h b/src/auth/Auth.h index c78da55fb..148853ac0 100644 --- a/src/auth/Auth.h +++ b/src/auth/Auth.h @@ -52,6 +52,7 @@ namespace SDDM { Q_OBJECT // not setting NOTIFY for the properties - they should be set only once before calling start Q_PROPERTY(bool autologin READ autologin WRITE setAutologin NOTIFY autologinChanged) + Q_PROPERTY(bool fingerprintlogin READ fingerprintlogin WRITE setFingerprintlogin NOTIFY fingerprintloginChanged) Q_PROPERTY(bool greeter READ isGreeter WRITE setGreeter NOTIFY greeterChanged) Q_PROPERTY(bool verbose READ verbose WRITE setVerbose NOTIFY verboseChanged) Q_PROPERTY(QByteArray cookie READ cookie WRITE setCookie NOTIFY cookieChanged) @@ -93,6 +94,7 @@ namespace SDDM { static void registerTypes(); bool autologin() const; + bool fingerprintlogin() const; bool isGreeter() const; bool verbose() const; const QByteArray &cookie() const; @@ -126,6 +128,13 @@ namespace SDDM { */ void setAutologin(bool on = true); + /** + * Set mode to fingerprint login. + * Ignored if session is not started + * @param on true if should use fingerprint login + */ + void setFingerprintlogin(bool on = true); + /** * Set mode to greeter * This will bypass authentication checks @@ -175,6 +184,7 @@ namespace SDDM { Q_SIGNALS: void autologinChanged(); + void fingerprintloginChanged(); void greeterChanged(); void verboseChanged(); void cookieChanged(); diff --git a/src/common/Configuration.h b/src/common/Configuration.h index 54bcace0b..5c008ca6c 100644 --- a/src/common/Configuration.h +++ b/src/common/Configuration.h @@ -104,6 +104,11 @@ namespace SDDM { Entry(Session, QString, QString(), _S("Name of session file for autologin session (if empty try last logged in)")); Entry(Relogin, bool, false, _S("Whether sddm should automatically log back into sessions when they exit")); ); + + Section(Fingerprintlogin, + Entry(User, QString, QString(), _S("Username for default user")); + Entry(Session, QString, QString(), _S("Name of session file for fingerprint login session (if empty try last logged in)")); + ); ); Config(StateConfig, []()->QString{auto tmp = getpwnam("sddm"); return tmp ? QString::fromLocal8Bit(tmp->pw_dir) : QStringLiteral(STATE_DIR);}().append(QStringLiteral("/state.conf")), QString(), QString(), diff --git a/src/daemon/Display.cpp b/src/daemon/Display.cpp index a9c80dceb..7580ffab4 100644 --- a/src/daemon/Display.cpp +++ b/src/daemon/Display.cpp @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -149,6 +150,11 @@ namespace SDDM { // connect login signal connect(m_socketServer, &SocketServer::login, this, &Display::login); + connect(m_socketServer, &SocketServer::connected, [this](QLocalSocket* socket){ + m_socket = socket; + fingerprintLogin(); + }); + // connect login result signals connect(this, &Display::loginFailed, m_socketServer, &SocketServer::loginFailed); connect(this, &Display::loginSucceeded, m_socketServer, &SocketServer::loginSucceeded); @@ -261,6 +267,34 @@ namespace SDDM { startSocketServerAndGreeter(); } + bool Display::fingerprintLogin(){ + if(mainConfig.Fingerprintlogin.User.get().isEmpty()){ + return false; + } + + Session::Type sessionType = Session::X11Session; + + QString fingerprintSession = mainConfig.Fingerprintlogin.Session.get(); + if(fingerprintSession.isEmpty()){ + fingerprintSession = stateConfig.Last.Session.get(); + } + if (findSessionEntry(mainConfig.X11.SessionDir.get(), fingerprintSession)) { + sessionType = Session::X11Session; + } else if (findSessionEntry(mainConfig.Wayland.SessionDir.get(), fingerprintSession)) { + sessionType = Session::WaylandSession; + } else { + qCritical() << "Unable to find autologin session entry" << fingerprintSession; + return false; + } + Session session; + session.setTo(sessionType, fingerprintSession); + + m_auth->setFingerprintlogin(true); + startAuth(mainConfig.Fingerprintlogin.User.get(), QString(), session); + m_auth->setFingerprintlogin(false); + return true; + } + void Display::displayServerStarted() { // check flag if (m_started) @@ -327,6 +361,11 @@ namespace SDDM { return; } + if(password.isEmpty() && !m_auth->fingerprintlogin()){ + qDebug() << "use fingerprint because password is empty"; + m_auth->setFingerprintlogin(true); + } + // authenticate startAuth(user, password, session); } diff --git a/src/daemon/Display.h b/src/daemon/Display.h index 98ca00665..99040513d 100644 --- a/src/daemon/Display.h +++ b/src/daemon/Display.h @@ -73,6 +73,7 @@ namespace SDDM { const QString &user, const QString &password, const Session &session); bool attemptAutologin(); + bool fingerprintLogin(); void displayServerStarted(); signals: diff --git a/src/daemon/SocketServer.cpp b/src/daemon/SocketServer.cpp index 488f9a5f2..aece1a3f4 100644 --- a/src/daemon/SocketServer.cpp +++ b/src/daemon/SocketServer.cpp @@ -128,7 +128,7 @@ namespace SDDM { SocketWriter(socket) << quint32(DaemonMessages::HostName) << daemonApp->hostName(); // emit signal - emit connected(); + emit connected(socket); } break; case GreeterMessages::Login: { diff --git a/src/daemon/SocketServer.h b/src/daemon/SocketServer.h index 0552e012d..1ced1b499 100644 --- a/src/daemon/SocketServer.h +++ b/src/daemon/SocketServer.h @@ -54,7 +54,7 @@ namespace SDDM { void login(QLocalSocket *socket, const QString &user, const QString &password, const Session &session); - void connected(); + void connected(QLocalSocket *socket); private: QLocalServer *m_server { nullptr }; diff --git a/src/helper/Backend.cpp b/src/helper/Backend.cpp index 5a1dd6076..a12e7cbdd 100644 --- a/src/helper/Backend.cpp +++ b/src/helper/Backend.cpp @@ -54,6 +54,11 @@ namespace SDDM { m_displayServer = on; } + void Backend::setFingerPrintLogin(bool on) + { + m_fingerprintlogin = on; + } + void Backend::setGreeter(bool on) { m_greeter = on; } diff --git a/src/helper/Backend.h b/src/helper/Backend.h index 915d09ca8..9b187fae4 100644 --- a/src/helper/Backend.h +++ b/src/helper/Backend.h @@ -36,7 +36,11 @@ namespace SDDM { static Backend *get(HelperApp *parent); void setAutologin(bool on = true); + void setDisplayServer(bool on = true); + + void setFingerPrintLogin(bool on = true); + void setGreeter(bool on = true); public slots: @@ -53,6 +57,7 @@ namespace SDDM { bool m_autologin { false }; bool m_displayServer = false; bool m_greeter { false }; + bool m_fingerprintlogin { false }; }; } diff --git a/src/helper/HelperApp.cpp b/src/helper/HelperApp.cpp index 14cf27612..c5a9000b9 100644 --- a/src/helper/HelperApp.cpp +++ b/src/helper/HelperApp.cpp @@ -115,6 +115,10 @@ namespace SDDM { m_backend->setAutologin(true); } + if((pos = args.indexOf(QStringLiteral("--fingerprintlogin"))) >= 0) { + m_backend->setFingerPrintLogin(true); + } + if ((pos = args.indexOf(QStringLiteral("--greeter"))) >= 0) { m_backend->setGreeter(true); } diff --git a/src/helper/backend/PamBackend.cpp b/src/helper/backend/PamBackend.cpp index 8ffa24ab6..5ba8e39e7 100644 --- a/src/helper/backend/PamBackend.cpp +++ b/src/helper/backend/PamBackend.cpp @@ -223,6 +223,9 @@ namespace SDDM { service = QStringLiteral("sddm-greeter"); else if (m_autologin) service = QStringLiteral("sddm-autologin"); + else if (m_fingerprintlogin) + service = QStringLiteral("sddm-fingerprint"); + qDebug() << "[PAM] using service name" << service; result = m_pam->start(service, user); if (!result) From 56ece624b2e120dcb06e22d59e420d60c5ba21a5 Mon Sep 17 00:00:00 2001 From: Sasasu Date: Tue, 28 Nov 2023 18:01:57 +0800 Subject: [PATCH 2/2] fix man page --- data/man/sddm.conf.rst.in | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/man/sddm.conf.rst.in b/data/man/sddm.conf.rst.in index de8b155c9..8a0e142c7 100644 --- a/data/man/sddm.conf.rst.in +++ b/data/man/sddm.conf.rst.in @@ -249,14 +249,14 @@ The `UserAuthFile=` option was removed, the file is always created as [Fingerprintlogin] section: `User=` - Name of the user who uses fingerprint login when the - system starts first time. - Default value is empty. + Name of the user who uses fingerprint login when the + system starts first time. + Default value is empty. `Session=` - Name of the user who uses fingerprint login when the - system starts first time. - Default value is empty. + Name of the session to automatically log in when the + system starts first time. + Default value is empty. SEE ALSO ========