From b46cb949e55965d3f8b1d8bcf456f06b65d317aa Mon Sep 17 00:00:00 2001 From: Kinzie Date: Sat, 6 Apr 2024 00:56:09 +0100 Subject: [PATCH] run authentication in a child process --- src/auth.zig | 13 ------------- src/main.zig | 40 ++++++++++++++++++++++++++++++---------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/auth.zig b/src/auth.zig index 3df14cb..a106d3c 100644 --- a/src/auth.zig +++ b/src/auth.zig @@ -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); diff --git a/src/main.zig b/src/main.zig index 4a8a204..7ba26e5 100644 --- a/src/main.zig +++ b/src/main.zig @@ -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(); - auth.authenticate(allocator, config, desktop, login, &password) catch |err| { - has_error = true; + const session_pid = try std.os.fork(); + if (session_pid == 0) { + auth.authenticate(allocator, config, desktop, login, &password) catch |err| { + 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) {