mirror of
https://codeberg.org/fairyglade/ly.git
synced 2026-08-09 15:19:13 +02:00
feat: implement username whitelist
This commit is contained in:
parent
c6446db3e2
commit
3777d0801c
2 changed files with 58 additions and 9 deletions
|
|
@ -93,3 +93,4 @@ x_cmd: []const u8 = build_options.prefix_directory ++ "/bin/X",
|
|||
xauth_cmd: []const u8 = build_options.prefix_directory ++ "/bin/xauth",
|
||||
xinitrc: ?[]const u8 = "~/.xinitrc",
|
||||
xsessions: []const u8 = build_options.prefix_directory ++ "/share/xsessions",
|
||||
username_whitelist: ?[]const u8 = null,
|
||||
|
|
|
|||
66
src/main.zig
66
src/main.zig
|
|
@ -223,7 +223,7 @@ pub fn main() !void {
|
|||
}
|
||||
|
||||
var maybe_uid_range_error: ?anyerror = null;
|
||||
var usernames = try getAllUsernames(allocator, config.login_defs_path, &maybe_uid_range_error);
|
||||
var usernames = try getAllUsernames(allocator, config.login_defs_path, config.username_whitelist, &maybe_uid_range_error);
|
||||
defer {
|
||||
for (usernames.items) |username| allocator.free(username);
|
||||
usernames.deinit(allocator);
|
||||
|
|
@ -486,7 +486,7 @@ pub fn main() !void {
|
|||
const auto_user = config.auto_login_user orelse break :check_autologin;
|
||||
const auto_session = config.auto_login_session orelse break :check_autologin;
|
||||
|
||||
if (!isValidUsername(auto_user, usernames)) {
|
||||
if (!stringListContains(auto_user, usernames)) {
|
||||
try info_line.addMessage(lang.err_pam_user_unknown, config.error_bg, config.error_fg);
|
||||
try log_writer.print("autologin failed: username '{s}' not found\n", .{auto_user});
|
||||
break :check_autologin;
|
||||
|
|
@ -1294,9 +1294,9 @@ fn crawl(session: *Session, lang: Lang, path: []const u8, display_server: Displa
|
|||
}
|
||||
}
|
||||
|
||||
fn isValidUsername(username: []const u8, usernames: StringList) bool {
|
||||
for (usernames.items) |valid_username| {
|
||||
if (std.mem.eql(u8, username, valid_username)) return true;
|
||||
fn stringListContains(needle: []const u8, list: StringList) bool {
|
||||
for (list.items) |valid_username| {
|
||||
if (std.mem.eql(u8, needle, valid_username)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1314,7 +1314,8 @@ fn findSessionByName(session: *Session, name: []const u8) ?usize {
|
|||
return null;
|
||||
}
|
||||
|
||||
fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8, uid_range_error: *?anyerror) !StringList {
|
||||
fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8, username_whitelist_string: ?[]const u8, uid_range_error: *?anyerror) !StringList {
|
||||
// Find all valid usernames
|
||||
const uid_range = interop.getUserIdRange(allocator, login_defs_path) catch |err| no_uid_range: {
|
||||
uid_range_error.* = err;
|
||||
break :no_uid_range UidRange{
|
||||
|
|
@ -1323,13 +1324,30 @@ fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8, ui
|
|||
};
|
||||
};
|
||||
|
||||
var whitelisted_usernames: StringList = .empty;
|
||||
|
||||
if (username_whitelist_string) |s| {
|
||||
whitelisted_usernames = try parseCSVString(allocator, s);
|
||||
}
|
||||
|
||||
var usernames: StringList = .empty;
|
||||
var maybe_entry = interop.getNextUsernameEntry();
|
||||
|
||||
while (maybe_entry) |entry| {
|
||||
// We check if the UID is equal to 0 because we always want to add root
|
||||
// as a username (even if you can't log into it)
|
||||
if (entry.uid >= uid_range.uid_min and entry.uid <= uid_range.uid_max or entry.uid == 0 and entry.username != null) {
|
||||
var valid: bool = true;
|
||||
// Check if not in valid UID range and not o
|
||||
// because we always want to add root as a username (even if you can't log into it)
|
||||
if ((entry.uid < uid_range.uid_min or entry.uid > uid_range.uid_max) and entry.uid != 0) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// Check if not whitelist if enabled
|
||||
if (username_whitelist_string != null and !stringListContains(entry.username.?, whitelisted_usernames)) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// Valid and not null, add
|
||||
if (valid and entry.username != null) {
|
||||
const username = try allocator.dupe(u8, entry.username.?);
|
||||
try usernames.append(allocator, username);
|
||||
}
|
||||
|
|
@ -1337,10 +1355,40 @@ fn getAllUsernames(allocator: std.mem.Allocator, login_defs_path: []const u8, ui
|
|||
maybe_entry = interop.getNextUsernameEntry();
|
||||
}
|
||||
|
||||
defer {
|
||||
// Cleanup whitelisted_usernames
|
||||
if (username_whitelist_string != null) {
|
||||
for (whitelisted_usernames.items) |username| allocator.free(username);
|
||||
whitelisted_usernames.deinit(allocator);
|
||||
}
|
||||
}
|
||||
|
||||
interop.closePasswordDatabase();
|
||||
return usernames;
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn parseCSVString(allocator: std.mem.Allocator, input: []const u8) !StringList {
|
||||
var list = StringList{};
|
||||
|
||||
var start: usize = 0;
|
||||
while (start < input.len) {
|
||||
var end = start;
|
||||
while (end < input.len and input[end] != ',') : (end += 1) {}
|
||||
|
||||
const token = std.mem.trim(u8, input[start..end], " \t\n\r");
|
||||
if (token.len > 0) { // Only add non-empty tokens
|
||||
const duped = try allocator.dupe(u8, token);
|
||||
try list.append(allocator, duped);
|
||||
}
|
||||
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
fn adjustBrightness(allocator: std.mem.Allocator, cmd: []const u8) !void {
|
||||
var brightness = std.process.Child.init(&[_][]const u8{ "/bin/sh", "-c", cmd }, allocator);
|
||||
brightness.stdout_behavior = .Ignore;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue