mirror of
https://github.com/fairyglade/ly.git
synced 2026-09-22 12:00:19 +00:00
Merge branch 'master' of codeberg.org:fairyglade/ly into zig-0.17
Signed-off-by: AnErrupTion <anerruption@disroot.org>
This commit is contained in:
82
src/auth.zig
82
src/auth.zig
@@ -26,6 +26,14 @@ pub const AuthOptions = struct {
|
||||
use_kmscon_vt: bool,
|
||||
};
|
||||
|
||||
const PamAppdata = struct {
|
||||
username: []const u8,
|
||||
password: []const u8,
|
||||
authreq_requested: bool,
|
||||
authreq_responded: bool,
|
||||
new_password: []const u8,
|
||||
};
|
||||
|
||||
var xorg_pid: std.posix.pid_t = 0;
|
||||
pub fn xorgSignalHandler(sig: std.posix.SIG) callconv(.c) void {
|
||||
if (xorg_pid > 0) _ = std.c.kill(xorg_pid, sig);
|
||||
@@ -36,7 +44,15 @@ pub fn sessionSignalHandler(sig: std.posix.SIG) callconv(.c) void {
|
||||
if (child_pid > 0) _ = std.c.kill(child_pid, sig);
|
||||
}
|
||||
|
||||
pub fn authenticate(allocator: std.mem.Allocator, io: std.Io, log_file: *LogFile, options: AuthOptions, current_environment: Environment, login: []const u8, password: []const u8) !void {
|
||||
pub fn authenticate(
|
||||
allocator: std.mem.Allocator,
|
||||
io: std.Io,
|
||||
log_file: *LogFile,
|
||||
options: AuthOptions,
|
||||
current_environment: Environment,
|
||||
login: []const u8,
|
||||
password: []const u8,
|
||||
) !void {
|
||||
var tty_buffer: [3]u8 = undefined;
|
||||
const tty_str = try std.fmt.bufPrint(&tty_buffer, "{d}", .{options.tty});
|
||||
|
||||
@@ -49,13 +65,14 @@ pub fn authenticate(allocator: std.mem.Allocator, io: std.Io, log_file: *LogFile
|
||||
|
||||
// Open the PAM session
|
||||
try log_file.info(io, "auth/pam", "encoding credentials", .{});
|
||||
const login_z = try allocator.dupeSentinel(u8, login, 0);
|
||||
defer allocator.free(login_z);
|
||||
|
||||
const password_z = try allocator.dupeSentinel(u8, password, 0);
|
||||
defer allocator.free(password_z);
|
||||
|
||||
var credentials = [_:null]?[*:0]const u8{ login_z, password_z };
|
||||
var credentials: PamAppdata = .{
|
||||
.username = login,
|
||||
.password = password,
|
||||
.authreq_requested = false,
|
||||
.authreq_responded = false,
|
||||
.new_password = "",
|
||||
};
|
||||
|
||||
const conv = interop.pam.pam_conv{
|
||||
.conv = loginConv,
|
||||
@@ -80,6 +97,11 @@ pub fn authenticate(allocator: std.mem.Allocator, io: std.Io, log_file: *LogFile
|
||||
|
||||
try log_file.info(io, "auth/pam", "validating account", .{});
|
||||
status = interop.pam.pam_acct_mgmt(handle, 0);
|
||||
if (status == interop.pam.PAM_NEW_AUTHTOK_REQD) {
|
||||
// credentials.authreq_requested = true;
|
||||
// credentials.new_password = "";
|
||||
// status = interop.pam.pam_chauthtok(handle, interop.pam.PAM_CHANGE_EXPIRED_AUTHTOK);
|
||||
}
|
||||
if (status != interop.pam.PAM_SUCCESS) return pamDiagnose(status);
|
||||
|
||||
try log_file.info(io, "auth/pam", "setting credentials", .{});
|
||||
@@ -98,7 +120,7 @@ pub fn authenticate(allocator: std.mem.Allocator, io: std.Io, log_file: *LogFile
|
||||
defer interop.closePasswordDatabase();
|
||||
|
||||
// Get password structure from username
|
||||
user_entry = interop.getUsernameEntry(login_z) orelse return error.GetPasswordNameFailed;
|
||||
user_entry = interop.getUsernameEntry(allocator, login) orelse return error.GetPasswordNameFailed;
|
||||
}
|
||||
|
||||
// Set user shell if it hasn't already been set
|
||||
@@ -276,6 +298,7 @@ fn loginConv(
|
||||
resp: ?*?[*]interop.pam.pam_response,
|
||||
appdata_ptr: ?*anyopaque,
|
||||
) callconv(.c) c_int {
|
||||
const data: *PamAppdata = @ptrCast(@alignCast(appdata_ptr));
|
||||
const message_count: u32 = @intCast(num_msg);
|
||||
const messages = msg.?;
|
||||
|
||||
@@ -289,20 +312,36 @@ fn loginConv(
|
||||
var username: ?[:0]u8 = null;
|
||||
var password: ?[:0]u8 = null;
|
||||
var status: c_int = interop.pam.PAM_SUCCESS;
|
||||
defer {
|
||||
if (status != interop.pam.PAM_SUCCESS) {
|
||||
// Memory is freed by pam otherwise
|
||||
allocator.free(response);
|
||||
if (username) |str| allocator.free(str);
|
||||
if (password) |str| allocator.free(str);
|
||||
} else {
|
||||
resp.?.* = response.ptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (0..message_count) |i| set_credentials: {
|
||||
switch (messages[i].?.msg_style) {
|
||||
interop.pam.PAM_PROMPT_ECHO_ON => {
|
||||
const data: [*][*:0]u8 = @ptrCast(@alignCast(appdata_ptr));
|
||||
username = allocator.dupeSentinel(u8, std.mem.span(data[0]), 0) catch {
|
||||
username = allocator.dupeZ(u8, data.username) catch {
|
||||
status = interop.pam.PAM_BUF_ERR;
|
||||
break :set_credentials;
|
||||
};
|
||||
response[i].resp = username.?;
|
||||
},
|
||||
interop.pam.PAM_PROMPT_ECHO_OFF => {
|
||||
const data: [*][*:0]u8 = @ptrCast(@alignCast(appdata_ptr));
|
||||
password = allocator.dupeSentinel(u8, std.mem.span(data[1]), 0) catch {
|
||||
var pass = data.password;
|
||||
if (data.authreq_requested) {
|
||||
if (data.authreq_responded) {
|
||||
pass = data.new_password;
|
||||
}
|
||||
data.authreq_responded = true;
|
||||
}
|
||||
|
||||
password = allocator.dupeZ(u8, pass) catch {
|
||||
status = interop.pam.PAM_BUF_ERR;
|
||||
break :set_credentials;
|
||||
};
|
||||
@@ -316,15 +355,6 @@ fn loginConv(
|
||||
}
|
||||
}
|
||||
|
||||
if (status != interop.pam.PAM_SUCCESS) {
|
||||
// Memory is freed by pam otherwise
|
||||
allocator.free(response);
|
||||
if (username) |str| allocator.free(str);
|
||||
if (password) |str| allocator.free(str);
|
||||
} else {
|
||||
resp.?.* = response.ptr;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -574,7 +604,15 @@ fn executeCmd(global_log_file: *LogFile, allocator: std.mem.Allocator, io: std.I
|
||||
fn redirectStandardStreams(global_log_file: *LogFile, io: std.Io, session_log: []const u8, create: bool) !std.Io.File {
|
||||
create_session_log_dir: {
|
||||
const session_log_dir = std.Io.Dir.path.dirname(session_log) orelse break :create_session_log_dir;
|
||||
std.Io.Dir.cwd().createDirPath(io, session_log_dir) catch |err| {
|
||||
|
||||
var buffer = std.mem.zeroes([std.Io.Dir.max_path_bytes]u8);
|
||||
const len = std.Io.Dir.cwd().realPathFile(io, session_log_dir, &buffer) catch |err| {
|
||||
try global_log_file.err(io, "auth/sys", "failed to resolve path for session log file directory: {s}", .{@errorName(err)});
|
||||
return err;
|
||||
};
|
||||
const resolved_path = buffer[0..len];
|
||||
|
||||
std.Io.Dir.cwd().createDirPath(io, resolved_path) catch |err| {
|
||||
try global_log_file.err(io, "auth/sys", "failed to create session log file directory: {s}", .{@errorName(err)});
|
||||
return err;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user