mirror of
https://github.com/fairyglade/ly.git
synced 2026-02-04 08:24:55 +00:00
Improve authentication logging
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
44
src/auth.zig
44
src/auth.zig
@@ -42,9 +42,11 @@ pub fn authenticate(allocator: std.mem.Allocator, log_file: *LogFile, options: A
|
|||||||
const pam_tty_str = try std.fmt.bufPrintZ(&pam_tty_buffer, "tty{d}", .{options.tty});
|
const pam_tty_str = try std.fmt.bufPrintZ(&pam_tty_buffer, "tty{d}", .{options.tty});
|
||||||
|
|
||||||
// Set the XDG environment variables
|
// Set the XDG environment variables
|
||||||
|
try log_file.info("auth/env", "setting xdg environment variables", .{});
|
||||||
try setXdgEnv(allocator, tty_str, current_environment);
|
try setXdgEnv(allocator, tty_str, current_environment);
|
||||||
|
|
||||||
// Open the PAM session
|
// Open the PAM session
|
||||||
|
try log_file.info("auth/pam", "encoding credentials", .{});
|
||||||
const login_z = try allocator.dupeZ(u8, login);
|
const login_z = try allocator.dupeZ(u8, login);
|
||||||
defer allocator.free(login_z);
|
defer allocator.free(login_z);
|
||||||
|
|
||||||
@@ -88,6 +90,7 @@ pub fn authenticate(allocator: std.mem.Allocator, log_file: *LogFile, options: A
|
|||||||
if (status != interop.pam.PAM_SUCCESS) return pamDiagnose(status);
|
if (status != interop.pam.PAM_SUCCESS) return pamDiagnose(status);
|
||||||
defer status = interop.pam.pam_close_session(handle, 0);
|
defer status = interop.pam.pam_close_session(handle, 0);
|
||||||
|
|
||||||
|
try log_file.info("auth/passwd", "getting struct", .{});
|
||||||
var user_entry: interop.UsernameEntry = undefined;
|
var user_entry: interop.UsernameEntry = undefined;
|
||||||
{
|
{
|
||||||
defer interop.closePasswordDatabase();
|
defer interop.closePasswordDatabase();
|
||||||
@@ -97,6 +100,7 @@ pub fn authenticate(allocator: std.mem.Allocator, log_file: *LogFile, options: A
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set user shell if it hasn't already been set
|
// Set user shell if it hasn't already been set
|
||||||
|
try log_file.info("auth/passwd", "setting user shell", .{});
|
||||||
if (user_entry.shell == null) interop.setUserShell(&user_entry);
|
if (user_entry.shell == null) interop.setUserShell(&user_entry);
|
||||||
|
|
||||||
var shared_err = try SharedError.init();
|
var shared_err = try SharedError.init();
|
||||||
@@ -107,7 +111,7 @@ pub fn authenticate(allocator: std.mem.Allocator, log_file: *LogFile, options: A
|
|||||||
child_pid = try std.posix.fork();
|
child_pid = try std.posix.fork();
|
||||||
if (child_pid == 0) {
|
if (child_pid == 0) {
|
||||||
try log_file.reinit();
|
try log_file.reinit();
|
||||||
try log_file.info("auth", "starting session", .{});
|
try log_file.info("auth/sys", "starting session", .{});
|
||||||
|
|
||||||
startSession(log_file, allocator, options, tty_str, user_entry, handle, current_environment) catch |e| {
|
startSession(log_file, allocator, options, tty_str, user_entry, handle, current_environment) catch |e| {
|
||||||
shared_err.writeError(e);
|
shared_err.writeError(e);
|
||||||
@@ -144,6 +148,7 @@ pub fn authenticate(allocator: std.mem.Allocator, log_file: *LogFile, options: A
|
|||||||
|
|
||||||
try log_file.reinit();
|
try log_file.reinit();
|
||||||
|
|
||||||
|
try log_file.info("auth/utmp", "removing utmp entry", .{});
|
||||||
removeUtmpEntry(&entry);
|
removeUtmpEntry(&entry);
|
||||||
|
|
||||||
if (shared_err.readError()) |err| return err;
|
if (shared_err.readError()) |err| return err;
|
||||||
@@ -159,12 +164,15 @@ fn startSession(
|
|||||||
current_environment: Environment,
|
current_environment: Environment,
|
||||||
) !void {
|
) !void {
|
||||||
// Set the user's GID & PID
|
// Set the user's GID & PID
|
||||||
|
try log_file.info("auth/passwd", "setting user context", .{});
|
||||||
try interop.setUserContext(allocator, user_entry);
|
try interop.setUserContext(allocator, user_entry);
|
||||||
|
|
||||||
// Set up the environment
|
// Set up the environment
|
||||||
|
try log_file.info("auth/env", "setting environment variables", .{});
|
||||||
try initEnv(allocator, user_entry, options.path);
|
try initEnv(allocator, user_entry, options.path);
|
||||||
|
|
||||||
// Reset the XDG environment variables
|
// Reset the XDG environment variables
|
||||||
|
try log_file.info("auth/env", "resetting xdg environment variables", .{});
|
||||||
try setXdgEnv(allocator, tty_str, current_environment);
|
try setXdgEnv(allocator, tty_str, current_environment);
|
||||||
try setXdgRuntimeDir(allocator);
|
try setXdgRuntimeDir(allocator);
|
||||||
|
|
||||||
@@ -173,12 +181,18 @@ fn startSession(
|
|||||||
if (pam_env_vars == null) return error.GetEnvListFailed;
|
if (pam_env_vars == null) return error.GetEnvListFailed;
|
||||||
|
|
||||||
const env_list = std.mem.span(pam_env_vars.?);
|
const env_list = std.mem.span(pam_env_vars.?);
|
||||||
for (env_list) |env_var| try interop.putEnvironmentVariable(env_var);
|
for (env_list) |env_var| {
|
||||||
|
if (env_var == null) continue;
|
||||||
|
try log_file.info("auth/env", "setting pam environment variable: {s}", .{std.mem.span(env_var.?)});
|
||||||
|
try interop.putEnvironmentVariable(env_var);
|
||||||
|
}
|
||||||
|
|
||||||
// Change to the user's home directory
|
// Change to the user's home directory
|
||||||
|
try log_file.info("auth/sys", "changing cwd to user home", .{});
|
||||||
std.posix.chdir(user_entry.home.?) catch return error.ChangeDirectoryFailed;
|
std.posix.chdir(user_entry.home.?) catch return error.ChangeDirectoryFailed;
|
||||||
|
|
||||||
// Signal to the session process to give up control on the TTY
|
// Signal to the session process to give up control on the TTY
|
||||||
|
try log_file.info("auth/sys", "releasing tty", .{});
|
||||||
std.posix.kill(options.session_pid, std.posix.SIG.CHLD) catch return error.TtyControlTransferFailed;
|
std.posix.kill(options.session_pid, std.posix.SIG.CHLD) catch return error.TtyControlTransferFailed;
|
||||||
|
|
||||||
// Execute what the user requested
|
// Execute what the user requested
|
||||||
@@ -187,6 +201,8 @@ fn startSession(
|
|||||||
.xinitrc, .x11 => if (build_options.enable_x11_support) {
|
.xinitrc, .x11 => if (build_options.enable_x11_support) {
|
||||||
var vt_buf: [5]u8 = undefined;
|
var vt_buf: [5]u8 = undefined;
|
||||||
const vt = try std.fmt.bufPrint(&vt_buf, "vt{d}", .{options.x_vt orelse options.tty});
|
const vt = try std.fmt.bufPrint(&vt_buf, "vt{d}", .{options.x_vt orelse options.tty});
|
||||||
|
|
||||||
|
try log_file.info("auth/x11", "setting vt to {s}", .{vt});
|
||||||
try executeX11Cmd(log_file, allocator, user_entry.shell.?, user_entry.home.?, options, current_environment.cmd orelse "", vt);
|
try executeX11Cmd(log_file, allocator, user_entry.shell.?, user_entry.home.?, options, current_environment.cmd orelse "", vt);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -322,7 +338,7 @@ fn getXPid(display_num: u8) !i32 {
|
|||||||
return std.fmt.parseInt(i32, std.mem.trim(u8, buffer[0..written], " "), 10);
|
return std.fmt.parseInt(i32, std.mem.trim(u8, buffer[0..written], " "), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createXauthFile(pwd: []const u8, buffer: []u8) ![]const u8 {
|
fn createXauthFile(log_file: *LogFile, pwd: []const u8, buffer: []u8) ![]const u8 {
|
||||||
var xauth_buf: [100]u8 = undefined;
|
var xauth_buf: [100]u8 = undefined;
|
||||||
var xauth_dir: []const u8 = undefined;
|
var xauth_dir: []const u8 = undefined;
|
||||||
const xdg_rt_dir = std.posix.getenv("XDG_RUNTIME_DIR");
|
const xdg_rt_dir = std.posix.getenv("XDG_RUNTIME_DIR");
|
||||||
@@ -368,6 +384,8 @@ fn createXauthFile(pwd: []const u8, buffer: []u8) ![]const u8 {
|
|||||||
|
|
||||||
std.fs.cwd().makePath(trimmed_xauth_dir) catch {};
|
std.fs.cwd().makePath(trimmed_xauth_dir) catch {};
|
||||||
|
|
||||||
|
try log_file.info("auth/x11", "creating xauth file: {s}", .{xauthority});
|
||||||
|
|
||||||
const file = try std.fs.createFileAbsolute(xauthority, .{});
|
const file = try std.fs.createFileAbsolute(xauthority, .{});
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
@@ -385,7 +403,7 @@ fn mcookie() [Md5.digest_length * 2]u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn xauth(log_file: *LogFile, allocator: std.mem.Allocator, display_name: []u8, shell: [*:0]const u8, home: []const u8, xauth_buffer: []u8, options: AuthOptions) !void {
|
fn xauth(log_file: *LogFile, allocator: std.mem.Allocator, display_name: []u8, shell: [*:0]const u8, home: []const u8, xauth_buffer: []u8, options: AuthOptions) !void {
|
||||||
const xauthority = try createXauthFile(home, xauth_buffer);
|
const xauthority = try createXauthFile(log_file, home, xauth_buffer);
|
||||||
try interop.setEnvironmentVariable(allocator, "XAUTHORITY", xauthority, true);
|
try interop.setEnvironmentVariable(allocator, "XAUTHORITY", xauthority, true);
|
||||||
try interop.setEnvironmentVariable(allocator, "DISPLAY", display_name, true);
|
try interop.setEnvironmentVariable(allocator, "DISPLAY", display_name, true);
|
||||||
|
|
||||||
@@ -396,6 +414,7 @@ fn xauth(log_file: *LogFile, allocator: std.mem.Allocator, display_name: []u8, s
|
|||||||
var cmd_buffer: [1024]u8 = undefined;
|
var cmd_buffer: [1024]u8 = undefined;
|
||||||
const cmd_str = std.fmt.bufPrintZ(&cmd_buffer, "{s} add {s} . {s}", .{ options.xauth_cmd, display_name, magic_cookie }) catch std.process.exit(1);
|
const cmd_str = std.fmt.bufPrintZ(&cmd_buffer, "{s} add {s} . {s}", .{ options.xauth_cmd, display_name, magic_cookie }) catch std.process.exit(1);
|
||||||
|
|
||||||
|
try log_file.info("auth/x11", "executing: {s} -c {s}", .{ shell, cmd_str });
|
||||||
const args = [_:null]?[*:0]const u8{ shell, "-c", cmd_str };
|
const args = [_:null]?[*:0]const u8{ shell, "-c", cmd_str };
|
||||||
std.posix.execveZ(shell, &args, std.c.environ) catch {};
|
std.posix.execveZ(shell, &args, std.c.environ) catch {};
|
||||||
std.process.exit(1);
|
std.process.exit(1);
|
||||||
@@ -415,6 +434,7 @@ fn executeX11Cmd(log_file: *LogFile, allocator: std.mem.Allocator, shell: []cons
|
|||||||
const display_num = try getFreeDisplay();
|
const display_num = try getFreeDisplay();
|
||||||
var buf: [4]u8 = undefined;
|
var buf: [4]u8 = undefined;
|
||||||
const display_name = try std.fmt.bufPrint(&buf, ":{d}", .{display_num});
|
const display_name = try std.fmt.bufPrint(&buf, ":{d}", .{display_num});
|
||||||
|
try log_file.info("auth/x11", "got free display: {d}", .{display_num});
|
||||||
|
|
||||||
const shell_z = try allocator.dupeZ(u8, shell);
|
const shell_z = try allocator.dupeZ(u8, shell);
|
||||||
defer allocator.free(shell_z);
|
defer allocator.free(shell_z);
|
||||||
@@ -427,12 +447,14 @@ fn executeX11Cmd(log_file: *LogFile, allocator: std.mem.Allocator, shell: []cons
|
|||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
var cmd_buffer: [1024]u8 = undefined;
|
var cmd_buffer: [1024]u8 = undefined;
|
||||||
const cmd_str = std.fmt.bufPrintZ(&cmd_buffer, "{s} {s} {s}", .{ options.x_cmd, display_name, vt }) catch std.process.exit(1);
|
const cmd_str = std.fmt.bufPrintZ(&cmd_buffer, "{s} {s} {s}", .{ options.x_cmd, display_name, vt }) catch std.process.exit(1);
|
||||||
|
try log_file.info("auth/x11", "executing: {s} -c {s}", .{ shell, cmd_str });
|
||||||
|
|
||||||
const args = [_:null]?[*:0]const u8{ shell_z, "-c", cmd_str };
|
const args = [_:null]?[*:0]const u8{ shell_z, "-c", cmd_str };
|
||||||
std.posix.execveZ(shell_z, &args, std.c.environ) catch {};
|
std.posix.execveZ(shell_z, &args, std.c.environ) catch {};
|
||||||
std.process.exit(1);
|
std.process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try log_file.info("auth/x11", "waiting for xcb connection", .{});
|
||||||
var ok: c_int = -1;
|
var ok: c_int = -1;
|
||||||
var xcb: ?*interop.xcb.xcb_connection_t = null;
|
var xcb: ?*interop.xcb.xcb_connection_t = null;
|
||||||
while (ok != 0) {
|
while (ok != 0) {
|
||||||
@@ -447,12 +469,14 @@ fn executeX11Cmd(log_file: *LogFile, allocator: std.mem.Allocator, shell: []cons
|
|||||||
// PID can be fetched from /tmp/X{d}.lock
|
// PID can be fetched from /tmp/X{d}.lock
|
||||||
try log_file.info("auth/x11", "getting x server pid", .{});
|
try log_file.info("auth/x11", "getting x server pid", .{});
|
||||||
const x_pid = try getXPid(display_num);
|
const x_pid = try getXPid(display_num);
|
||||||
|
try log_file.info("auth/x11", "got x server pid: {d}", .{x_pid});
|
||||||
|
|
||||||
try log_file.info("auth/x11", "launching environment", .{});
|
try log_file.info("auth/x11", "launching environment", .{});
|
||||||
xorg_pid = try std.posix.fork();
|
xorg_pid = try std.posix.fork();
|
||||||
if (xorg_pid == 0) {
|
if (xorg_pid == 0) {
|
||||||
var cmd_buffer: [1024]u8 = undefined;
|
var cmd_buffer: [1024]u8 = undefined;
|
||||||
const cmd_str = std.fmt.bufPrintZ(&cmd_buffer, "{s} {s} {s}", .{ options.setup_cmd, options.login_cmd orelse "", desktop_cmd }) catch std.process.exit(1);
|
const cmd_str = std.fmt.bufPrintZ(&cmd_buffer, "{s} {s} {s}", .{ options.setup_cmd, options.login_cmd orelse "", desktop_cmd }) catch std.process.exit(1);
|
||||||
|
try log_file.info("auth/x11", "executing: {s} -c {s}", .{ shell, cmd_str });
|
||||||
|
|
||||||
const args = [_:null]?[*:0]const u8{ shell_z, "-c", cmd_str };
|
const args = [_:null]?[*:0]const u8{ shell_z, "-c", cmd_str };
|
||||||
std.posix.execveZ(shell_z, &args, std.c.environ) catch {};
|
std.posix.execveZ(shell_z, &args, std.c.environ) catch {};
|
||||||
@@ -468,6 +492,8 @@ fn executeX11Cmd(log_file: *LogFile, allocator: std.mem.Allocator, shell: []cons
|
|||||||
std.posix.sigaction(std.posix.SIG.TERM, &act, null);
|
std.posix.sigaction(std.posix.SIG.TERM, &act, null);
|
||||||
|
|
||||||
_ = std.posix.waitpid(xorg_pid, 0);
|
_ = std.posix.waitpid(xorg_pid, 0);
|
||||||
|
|
||||||
|
try log_file.info("auth/x11", "disconnecting xcb", .{});
|
||||||
interop.xcb.xcb_disconnect(xcb);
|
interop.xcb.xcb_disconnect(xcb);
|
||||||
|
|
||||||
// TODO: Find a more robust way to ensure that X has been terminated (pidfds?)
|
// TODO: Find a more robust way to ensure that X has been terminated (pidfds?)
|
||||||
@@ -479,12 +505,15 @@ fn executeX11Cmd(log_file: *LogFile, allocator: std.mem.Allocator, shell: []cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn executeCmd(global_log_file: *LogFile, allocator: std.mem.Allocator, shell: []const u8, options: AuthOptions, is_terminal: bool, exec_cmd: ?[]const u8) !void {
|
fn executeCmd(global_log_file: *LogFile, allocator: std.mem.Allocator, shell: []const u8, options: AuthOptions, is_terminal: bool, exec_cmd: ?[]const u8) !void {
|
||||||
|
try global_log_file.info("auth/sys", "launching wayland/shell/custom session", .{});
|
||||||
|
|
||||||
var maybe_log_file: ?std.fs.File = null;
|
var maybe_log_file: ?std.fs.File = null;
|
||||||
if (!is_terminal) {
|
if (!is_terminal) {
|
||||||
// For custom desktop entries, the "Terminal" value here determines if
|
// For custom desktop entries, the "Terminal" value here determines if
|
||||||
// we redirect standard output & error or not. That is, we redirect only
|
// we redirect standard output & error or not. That is, we redirect only
|
||||||
// if it's equal to false (so if it's not running in a TTY).
|
// if it's equal to false (so if it's not running in a TTY).
|
||||||
if (options.session_log) |log_path| {
|
if (options.session_log) |log_path| {
|
||||||
|
try global_log_file.info("auth/sys", "setting up stdio & stderr redirection", .{});
|
||||||
maybe_log_file = try redirectStandardStreams(global_log_file, log_path, true);
|
maybe_log_file = try redirectStandardStreams(global_log_file, log_path, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -496,6 +525,7 @@ fn executeCmd(global_log_file: *LogFile, allocator: std.mem.Allocator, shell: []
|
|||||||
var cmd_buffer: [1024]u8 = undefined;
|
var cmd_buffer: [1024]u8 = undefined;
|
||||||
const cmd_str = try std.fmt.bufPrintZ(&cmd_buffer, "{s} {s} {s}", .{ options.setup_cmd, options.login_cmd orelse "", exec_cmd orelse shell });
|
const cmd_str = try std.fmt.bufPrintZ(&cmd_buffer, "{s} {s} {s}", .{ options.setup_cmd, options.login_cmd orelse "", exec_cmd orelse shell });
|
||||||
|
|
||||||
|
try global_log_file.info("auth/sys", "executing: {s} -c {s}", .{ shell, cmd_str });
|
||||||
const args = [_:null]?[*:0]const u8{ shell_z, "-c", cmd_str };
|
const args = [_:null]?[*:0]const u8{ shell_z, "-c", cmd_str };
|
||||||
return std.posix.execveZ(shell_z, &args, std.c.environ);
|
return std.posix.execveZ(shell_z, &args, std.c.environ);
|
||||||
}
|
}
|
||||||
@@ -504,16 +534,16 @@ fn redirectStandardStreams(global_log_file: *LogFile, session_log: []const u8, c
|
|||||||
create_session_log_dir: {
|
create_session_log_dir: {
|
||||||
const session_log_dir = std.fs.path.dirname(session_log) orelse break :create_session_log_dir;
|
const session_log_dir = std.fs.path.dirname(session_log) orelse break :create_session_log_dir;
|
||||||
std.fs.cwd().makePath(session_log_dir) catch |err| {
|
std.fs.cwd().makePath(session_log_dir) catch |err| {
|
||||||
try global_log_file.file_writer.interface.print("failed to create session log file directory: {s}\n", .{@errorName(err)});
|
try global_log_file.err("auth/sys", "failed to create session log file directory: {s}", .{@errorName(err)});
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const log_file = if (create) (std.fs.cwd().createFile(session_log, .{ .mode = 0o666 }) catch |err| {
|
const log_file = if (create) (std.fs.cwd().createFile(session_log, .{ .mode = 0o666 }) catch |err| {
|
||||||
try global_log_file.file_writer.interface.print("failed to create new session log file: {s}\n", .{@errorName(err)});
|
try global_log_file.err("auth/sys", "failed to create new session log file: {s}", .{@errorName(err)});
|
||||||
return err;
|
return err;
|
||||||
}) else (std.fs.cwd().openFile(session_log, .{ .mode = .read_write }) catch |err| {
|
}) else (std.fs.cwd().openFile(session_log, .{ .mode = .read_write }) catch |err| {
|
||||||
try global_log_file.file_writer.interface.print("failed to open existing session log file: {s}\n", .{@errorName(err)});
|
try global_log_file.err("auth/sys", "failed to open existing session log file: {s}", .{@errorName(err)});
|
||||||
return err;
|
return err;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -989,7 +989,7 @@ pub fn main() !void {
|
|||||||
update = true;
|
update = true;
|
||||||
},
|
},
|
||||||
termbox.TB_KEY_ENTER => authenticate: {
|
termbox.TB_KEY_ENTER => authenticate: {
|
||||||
try log_file.info("auth", "authenticating...", .{});
|
try log_file.info("auth", "starting authentication", .{});
|
||||||
|
|
||||||
if (!config.allow_empty_password and password.text.items.len == 0) {
|
if (!config.allow_empty_password and password.text.items.len == 0) {
|
||||||
// Let's not log this message for security reasons
|
// Let's not log this message for security reasons
|
||||||
|
|||||||
Reference in New Issue
Block a user