run authentication in a child process

This commit is contained in:
Kinzie 2024-04-06 00:56:09 +01:00
parent 27a7b731e5
commit b46cb949e5
2 changed files with 30 additions and 23 deletions

View File

@ -42,7 +42,6 @@ pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, logi
defer allocator.free(service_name_z);
var status = interop.pam.pam_start(service_name_z.ptr, null, &conv, &handle);
if (status != interop.pam.PAM_SUCCESS) return pamDiagnose(status);
// Do the PAM routine
@ -58,9 +57,6 @@ pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, logi
status = interop.pam.pam_open_session(handle, 0);
if (status != interop.pam.PAM_SUCCESS) return pamDiagnose(status);
// Clear the password
password.clear();
// Get password structure from username
const maybe_pwd = interop.getpwnam(login_text_z.ptr);
interop.endpwent();
@ -87,11 +83,6 @@ pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, logi
}
}
// Restore the previous terminal mode
interop.termbox.tb_clear();
interop.termbox.tb_present();
interop.termbox.tb_shutdown();
var shared_err = try SharedError.init();
defer shared_err.deinit();
@ -188,10 +179,6 @@ pub fn authenticate(allocator: Allocator, config: Config, desktop: Desktop, logi
try resetTerminal(allocator, pwd.pw_shell, config.term_reset_cmd);
// Re-initialize termbox
_ = interop.termbox.tb_init();
_ = interop.termbox.tb_select_output_mode(interop.termbox.TB_OUTPUT_NORMAL);
// Close the PAM session
status = interop.pam.pam_close_session(handle, 0);
if (status != 0) return pamDiagnose(status);

View File

@ -16,6 +16,7 @@ const Lang = @import("config/Lang.zig");
const Save = @import("config/Save.zig");
const LogFile = @import("logger/LogFile.zig");
const ViMode = @import("enums.zig").ViMode;
const SharedError = @import("SharedError.zig");
const Ini = ini.Ini;
const termbox = interop.termbox;
@ -123,6 +124,9 @@ pub fn main() !void {
_ = termbox.tb_select_output_mode(termbox.TB_OUTPUT_NORMAL);
termbox.tb_clear();
// we need this to reset it after auth.
const orig_tios = try std.os.tcgetattr(std.os.STDIN_FILENO);
// Initialize terminal buffer
const labels_max_length = @max(lang.login.len, lang.password.len);
@ -431,12 +435,12 @@ pub fn main() !void {
if (animate) {
timeout = config.min_refresh_delta;
} else if (config.bigclock and config.clock == null) {
var tv = std.mem.zeroes(std.c.timeval);
var tv: std.c.timeval = undefined;
_ = std.c.gettimeofday(&tv, null);
timeout = @intCast((60 - @rem(tv.tv_sec, 60)) * 1000 - @divTrunc(tv.tv_usec, 1000) + 1);
} else if (config.clock != null or auth_fails >= 10) {
var tv = std.mem.zeroes(std.c.timeval);
var tv: std.c.timeval = undefined;
_ = std.c.gettimeofday(&tv, null);
timeout = @intCast(1000 - @divTrunc(tv.tv_usec, 1000) + 1);
@ -513,20 +517,36 @@ pub fn main() !void {
ini.writeFromStruct(save_data, file.writer(), null) catch break :save_last_settings;
}
var has_error = false;
var shared_err = try SharedError.init();
defer shared_err.deinit();
const session_pid = try std.os.fork();
if (session_pid == 0) {
auth.authenticate(allocator, config, desktop, login, &password) catch |err| {
has_error = true;
shared_err.writeError(err);
std.os.exit(1);
};
std.os.exit(0);
}
_ = std.os.waitpid(session_pid, 0);
var auth_err = shared_err.readError();
if (auth_err) |err| {
auth_fails += 1;
active_input = .password;
info_line = getAuthErrorMsg(err, lang);
if (config.clear_password) password.clear();
};
update = true;
} else {
password.clear();
info_line = lang.logout;
}
if (!has_error) info_line = lang.logout;
try std.os.tcsetattr(std.os.STDIN_FILENO, .FLUSH, orig_tios);
termbox.tb_clear();
termbox.tb_present();
update = true;
const pid = try std.os.fork();
if (pid == 0) {