mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
LockScreen: use /etc/pam.d/ files for auth
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
|
||||
QtObject {
|
||||
id: root
|
||||
|
||||
function migrate(adapter, logger, rawJson) {
|
||||
logger.i("Migration46", "Removing legacy PAM configuration file");
|
||||
|
||||
const shellName = "noctalia";
|
||||
const configDir = Quickshell.env("NOCTALIA_CONFIG_DIR") || (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + "/" + shellName + "/";
|
||||
const pamConfigDir = configDir + "pam";
|
||||
const pamConfigFile = pamConfigDir + "/password.conf";
|
||||
|
||||
// Remove the file if it exists
|
||||
const script = `rm -f '${pamConfigFile}'`;
|
||||
Quickshell.execDetached(["sh", "-c", script]);
|
||||
|
||||
// Attempt to remove the directory if empty (ignore errors)
|
||||
const rmdirScript = `rmdir '${pamConfigDir}' 2>/dev/null || true`;
|
||||
Quickshell.execDetached(["sh", "-c", rmdirScript]);
|
||||
|
||||
logger.d("Migration46", "Cleaned up legacy PAM config");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ QtObject {
|
||||
43: migration43Component,
|
||||
44: migration44Component,
|
||||
45: migration45Component
|
||||
// 46: migration46Component
|
||||
})
|
||||
|
||||
// Migration components
|
||||
@@ -36,4 +37,5 @@ QtObject {
|
||||
property Component migration43Component: Migration43 {}
|
||||
property Component migration44Component: Migration44 {}
|
||||
property Component migration45Component: Migration45 {}
|
||||
// property Component migration46Component: Migration46 {}
|
||||
}
|
||||
|
||||
@@ -48,11 +48,6 @@ Singleton {
|
||||
Quickshell.execDetached(["mkdir", "-p", configDir]);
|
||||
Quickshell.execDetached(["mkdir", "-p", cacheDir]);
|
||||
|
||||
// Ensure PAM config file exists in configDir (create once, never override)
|
||||
if (!Quickshell.env("NOCTALIA_PAM_CONFIG")) {
|
||||
ensurePamConfig();
|
||||
}
|
||||
|
||||
// Mark directories as created and trigger file loading
|
||||
directoriesCreated = true;
|
||||
|
||||
@@ -1102,56 +1097,6 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Ensure PAM password.conf exists in configDir (create once, never override)
|
||||
function ensurePamConfig() {
|
||||
var pamConfigDir = configDir + "pam";
|
||||
var pamConfigFile = pamConfigDir + "/password.conf";
|
||||
|
||||
// Check if file already exists
|
||||
fileCheckPamProcess.command = ["test", "-f", pamConfigFile];
|
||||
fileCheckPamProcess.running = true;
|
||||
}
|
||||
|
||||
function doCreatePamConfig() {
|
||||
var pamConfigDir = configDir + "pam";
|
||||
var pamConfigFile = pamConfigDir + "/password.conf";
|
||||
var pamConfigDirEsc = pamConfigDir.replace(/'/g, "'\\''");
|
||||
var pamConfigFileEsc = pamConfigFile.replace(/'/g, "'\\''");
|
||||
|
||||
// Ensure directory exists
|
||||
Quickshell.execDetached(["mkdir", "-p", pamConfigDir]);
|
||||
|
||||
// Generate the PAM config file content
|
||||
var configContent = "auth sufficient pam_fprintd.so timeout=-1\n";
|
||||
configContent += "auth sufficient /run/current-system/sw/lib/security/pam_fprintd.so timeout=-1 # for NixOS\n";
|
||||
configContent += "auth required pam_unix.so\n";
|
||||
|
||||
// Write the config file using heredoc to avoid escaping issues
|
||||
var script = `cat > '${pamConfigFileEsc}' << 'EOF'\n`;
|
||||
script += configContent;
|
||||
script += "EOF\n";
|
||||
Quickshell.execDetached(["sh", "-c", script]);
|
||||
|
||||
Logger.d("Settings", "PAM config file created at:", pamConfigFile);
|
||||
}
|
||||
|
||||
// Process for checking if PAM config file exists
|
||||
Process {
|
||||
id: fileCheckPamProcess
|
||||
running: false
|
||||
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode === 0) {
|
||||
// File exists, skip creation
|
||||
Logger.d("Settings", "PAM config file already exists, skipping creation");
|
||||
} else {
|
||||
// File doesn't exist, create it
|
||||
doCreatePamConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Function to clean up deprecated user/custom bar widgets settings
|
||||
function upgradeWidget(widget) {
|
||||
|
||||
@@ -19,16 +19,50 @@ Scope {
|
||||
property string infoMessage: ""
|
||||
property bool fprintdAvailable: false
|
||||
|
||||
readonly property string pamConfigDirectory: Quickshell.env("NOCTALIA_PAM_CONFIG") ? "/etc/pam.d" : Settings.configDir + "pam"
|
||||
readonly property string pamConfig: Quickshell.env("NOCTALIA_PAM_CONFIG") || "password.conf"
|
||||
readonly property string pamConfigDirectory: "/etc/pam.d"
|
||||
property string pamConfig: Quickshell.env("NOCTALIA_PAM_SERVICE") || "login"
|
||||
property bool pamReady: false
|
||||
|
||||
Component.onCompleted: {
|
||||
checkFprintdProc.running = true;
|
||||
|
||||
if (Quickshell.env("NOCTALIA_PAM_CONFIG")) {
|
||||
Logger.i("LockContext", "NOCTALIA_PAM_CONFIG is set, using system PAM config: /etc/pam.d/" + pamConfig);
|
||||
if (Quickshell.env("NOCTALIA_PAM_SERVICE")) {
|
||||
Logger.i("LockContext", "NOCTALIA_PAM_SERVICE is set, using system PAM config: /etc/pam.d/" + pamConfig);
|
||||
pamReady = true;
|
||||
} else {
|
||||
Logger.i("LockContext", "Using generated PAM config:", pamConfigDirectory + "/" + pamConfig);
|
||||
Logger.i("LockContext", "Probing for best PAM service...");
|
||||
detectPamServiceProc.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: detectPamServiceProc
|
||||
command: ["sh", "-c", "
|
||||
if [ -f /etc/pam.d/login ]; then echo 'login'; exit 0; fi;
|
||||
if [ -f /etc/pam.d/system-auth ]; then echo 'system-auth'; exit 0; fi;
|
||||
if [ -f /etc/pam.d/common-auth ]; then echo 'common-auth'; exit 0; fi;
|
||||
echo 'login';
|
||||
"]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
const service = String(text || "").trim();
|
||||
if (service.length > 0) {
|
||||
root.pamConfig = service;
|
||||
Logger.i("LockContext", "Detected PAM service: " + service);
|
||||
} else {
|
||||
Logger.w("LockContext", "Failed to detect PAM service, defaulting to login");
|
||||
}
|
||||
root.pamReady = true;
|
||||
}
|
||||
}
|
||||
stderr: StdioCollector {}
|
||||
}
|
||||
|
||||
onPamReadyChanged: {
|
||||
if (pamReady) {
|
||||
if (Settings.data.general.autoStartAuth && currentText === "") {
|
||||
pam.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,13 +90,18 @@ Scope {
|
||||
}
|
||||
} else {
|
||||
occupyFingerprintSensorProc.running = false;
|
||||
if (Settings.data.general.autoStartAuth) {
|
||||
if (pamReady && Settings.data.general.autoStartAuth) {
|
||||
pam.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function tryUnlock() {
|
||||
if (!pamReady) {
|
||||
Logger.w("LockContext", "PAM not ready yet, ignoring unlock attempt");
|
||||
return;
|
||||
}
|
||||
|
||||
if (waitingForPassword) {
|
||||
pam.respond(currentText);
|
||||
unlockInProgress = true;
|
||||
|
||||
Reference in New Issue
Block a user