From e8f5e95c041d34b861cb5e8a8f9e80f48e143aa1 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Fri, 10 Nov 2023 08:18:51 +0100 Subject: [PATCH 1/7] don't redefine M_PI it's already defined in /usr/include/math.h on OpenBSD --- render.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/render.c b/render.c index 7be79b64..6ad1a9fc 100644 --- a/render.c +++ b/render.c @@ -7,7 +7,9 @@ #include "swaylock.h" #include "log.h" +#ifndef M_PI #define M_PI 3.14159265358979323846 +#endif const float TYPE_INDICATOR_RANGE = M_PI / 3.0f; static void set_color_for_state(cairo_t *cairo, struct swaylock_state *state, From aa0cd8a30c830aa0d9e1fd08121f2d7f8da0b908 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Fri, 10 Nov 2023 08:20:51 +0100 Subject: [PATCH 2/7] OpenBSD doesn't have wordexp(), make it optional sprinkle #if HAVE_WORDEXP where used include config.h first to only include wordexp.h if needed --- main.c | 9 +++++++++ meson.build | 1 + 2 files changed, 10 insertions(+) diff --git a/main.c b/main.c index 07e66673..a648f5c9 100644 --- a/main.c +++ b/main.c @@ -14,7 +14,10 @@ #include #include #include +#include "config.h" +#if HAVE_WORDEXP #include +#endif #include "background-image.h" #include "cairo.h" #include "comm.h" @@ -322,6 +325,7 @@ static cairo_surface_t *select_image(struct swaylock_state *state, return default_image; } +#if HAVE_WORDEXP static char *join_args(char **argv, int argc) { assert(argc > 0); int len = 0, i; @@ -338,6 +342,7 @@ static char *join_args(char **argv, int argc) { res[len - 1] = '\0'; return res; } +#endif static void load_image(char *arg, struct swaylock_state *state) { // [[]:] @@ -375,18 +380,22 @@ static void load_image(char *arg, struct swaylock_state *state) { // The shell will not expand ~ to the value of $HOME when an output name is // given. Also, any image paths given in the config file need to have shell // expansions performed +#if HAVE_WORDEXP wordexp_t p; +#endif while (strstr(image->path, " ")) { image->path = realloc(image->path, strlen(image->path) + 2); char *ptr = strstr(image->path, " ") + 1; memmove(ptr + 1, ptr, strlen(ptr) + 1); *ptr = '\\'; } +#if HAVE_WORDEXP if (wordexp(image->path, &p, 0) == 0) { free(image->path); image->path = join_args(p.we_wordv, p.we_wordc); wordfree(&p); } +#endif // Load the actual image image->cairo_surface = load_background_image(image->path); diff --git a/meson.build b/meson.build index 144d8a6d..5af36455 100644 --- a/meson.build +++ b/meson.build @@ -79,6 +79,7 @@ conf_data = configuration_data() conf_data.set_quoted('SYSCONFDIR', get_option('prefix') / get_option('sysconfdir')) conf_data.set_quoted('SWAYLOCK_VERSION', version) conf_data.set10('HAVE_GDK_PIXBUF', gdk_pixbuf.found()) +conf_data.set10('HAVE_WORDEXP', cc.check_header('wordexp.h')) subdir('include') From b464ea1fbb9a6a3b5c9cb3ae17914d072a1ff448 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Fri, 10 Nov 2023 08:22:05 +0100 Subject: [PATCH 3/7] get_config_path: provide an alternative when wordexp() isn't available more lines, but functionally equivalent. --- main.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/main.c b/main.c index a648f5c9..06670d61 100644 --- a/main.c +++ b/main.c @@ -966,6 +966,7 @@ static bool file_exists(const char *path) { } static char *get_config_path(void) { +#if HAVE_WORDEXP static const char *config_paths[] = { "$HOME/.swaylock/config", "$XDG_CONFIG_HOME/swaylock/config", @@ -989,7 +990,50 @@ static char *get_config_path(void) { free(path); } } +#else + char *home = getenv("HOME"); + char *path; + int n, len; + if (home) { + len = strlen(home) + strlen("/.swaylock/config") + 1; + path = malloc(len); + if (path == NULL) + return NULL; + n = snprintf(path, len, "%s/.swaylock/config", home); + if (n < len && file_exists(path)) + return path; + free(path); + char *config_home = getenv("XDG_CONFIG_HOME"); + if (!config_home || config_home[0] == '\0') { + len = strlen(home) + strlen("/.config/swaylock/config") + 1; + path = malloc(len); + if (path == NULL) + return NULL; + n = snprintf(path, len, "%s/.config/swaylock/config", home); + if (n < len && file_exists(path)) + return path; + free(path); + } else { + len = strlen(config_home) + strlen("/swaylock/config") + 1; + path = malloc(len); + if (path == NULL) + return NULL; + n = snprintf(path, len, "%s/swaylock/config", config_home); + if (n < len && file_exists(path)) + return path; + free(path); + } + } + len = strlen(SYSCONFDIR "/swaylock/config") + 1; + path = malloc(len); + if (path == NULL) + return NULL; + n = snprintf(path, len, "%s/swaylock/config", SYSCONFDIR); + if (n < len && file_exists(path)) + return path; + free(path); +#endif return NULL; } From a90e0ca75a74d7ab1175ed78cc86ddccd8d04974 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Fri, 10 Nov 2023 08:25:22 +0100 Subject: [PATCH 4/7] meson.build: add support for OpenBSD detection OpenBSD doesn't have/need libcrypt or librt --- meson.build | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/meson.build b/meson.build index 5af36455..62ebf749 100644 --- a/meson.build +++ b/meson.build @@ -26,6 +26,7 @@ is_freebsd = host_machine.system().startswith('freebsd') if is_freebsd add_project_arguments('-D_C11_SOURCE', language: 'c') endif +is_openbsd = host_machine.system().startswith('openbsd') wayland_client = dependency('wayland-client', version: '>=1.20.0') wayland_protos = dependency('wayland-protocols', version: '>=1.25', fallback: 'wayland-protocols') @@ -34,9 +35,9 @@ xkbcommon = dependency('xkbcommon') cairo = dependency('cairo') gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: get_option('gdk-pixbuf')) libpam = cc.find_library('pam', required: get_option('pam')) -crypt = cc.find_library('crypt', required: not libpam.found()) +crypt = cc.find_library('crypt', required: not libpam.found() and not is_openbsd) math = cc.find_library('m') -rt = cc.find_library('rt') +rt = cc.find_library('rt', required: not is_openbsd) git = find_program('git', required: false) scdoc = find_program('scdoc', required: get_option('man-pages')) @@ -87,7 +88,6 @@ dependencies = [ cairo, gdk_pixbuf, math, - rt, xkbcommon, wayland_client, ] @@ -109,13 +109,13 @@ sources = [ if libpam.found() sources += ['pam.c'] - dependencies += [libpam] + dependencies += [libpam, rt] else warning('The swaylock binary often needs to be setuid when compiled without libpam') warning('You must do this manually post-install: chmod a+s /path/to/swaylock') warning('See the "Without PAM" section of the README for details.') sources += ['shadow.c'] - dependencies += [crypt] + dependencies += [crypt, rt] endif swaylock_inc = include_directories('include') From c24bb251df458a87bb0d2a1532d55b494b63253a Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Fri, 10 Nov 2023 08:26:21 +0100 Subject: [PATCH 5/7] add support for bsd_auth for OpenBSD --- bsdauth.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ meson.build | 4 ++++ 2 files changed, 55 insertions(+) create mode 100644 bsdauth.c diff --git a/bsdauth.c b/bsdauth.c new file mode 100644 index 00000000..68d6063a --- /dev/null +++ b/bsdauth.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "comm.h" +#include "log.h" +#include "password-buffer.h" +#include "swaylock.h" + +void initialize_pw_backend(int argc, char **argv) { + if (!spawn_comm_child()) { + exit(EXIT_FAILURE); + } +} +void run_pw_backend_child(void) { + struct passwd *pwent = getpwuid(getuid()); + if (!pwent) { + swaylock_log_errno(LOG_ERROR, "failed to getpwuid"); + exit(EXIT_FAILURE); + } + struct group *authg = getgrnam("auth"); + if (!authg || !authg->gr_name || !*authg->gr_name) { + exit(EXIT_FAILURE); + } + /* we need setgid(auth) to use auth_userokay() */ + if (setgid(authg->gr_gid)) { + exit(EXIT_FAILURE); + } + while (1) { + char *buf; + ssize_t size = read_comm_request(&buf); + if (size < 0) { + exit(EXIT_FAILURE); + } else if (size == 0) { + break; + } + bool success = auth_userokay((char *)pwent->pw_name, NULL, "swaylock", buf); + if (!write_comm_reply(success)) { + exit(EXIT_FAILURE); + } + + sleep(2); + } + + exit(EXIT_SUCCESS); +} diff --git a/meson.build b/meson.build index 62ebf749..2b2d4c0f 100644 --- a/meson.build +++ b/meson.build @@ -110,6 +110,10 @@ sources = [ if libpam.found() sources += ['pam.c'] dependencies += [libpam, rt] +elif is_openbsd + warning('The swaylock binary must be setgid when compiled with bsd auth') + warning('You must do this manually post-install: chgrp auth /path/to/swaylock ; chmod g+s /path/to/swaylock') + sources += ['bsdauth.c'] else warning('The swaylock binary often needs to be setuid when compiled without libpam') warning('You must do this manually post-install: chmod a+s /path/to/swaylock') From 2991e66aa5e9aadf55ddc4754dd3253077d5c135 Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Fri, 10 Nov 2023 12:36:51 +0100 Subject: [PATCH 6/7] drop wordexp() usage backports/adapted from swaywm/sway@1d62d6bf note: as a side effect, env vars can't be used anymore for image paths --- main.c | 137 +++++++++++++++++----------------------------------- meson.build | 1 - 2 files changed, 43 insertions(+), 95 deletions(-) diff --git a/main.c b/main.c index 06670d61..89304ac8 100644 --- a/main.c +++ b/main.c @@ -15,9 +15,6 @@ #include #include #include "config.h" -#if HAVE_WORDEXP -#include -#endif #include "background-image.h" #include "cairo.h" #include "comm.h" @@ -325,25 +322,6 @@ static cairo_surface_t *select_image(struct swaylock_state *state, return default_image; } -#if HAVE_WORDEXP -static char *join_args(char **argv, int argc) { - assert(argc > 0); - int len = 0, i; - for (i = 0; i < argc; ++i) { - len += strlen(argv[i]) + 1; - } - char *res = malloc(len); - len = 0; - for (i = 0; i < argc; ++i) { - strcpy(res + len, argv[i]); - len += strlen(argv[i]); - res[len++] = ' '; - } - res[len - 1] = '\0'; - return res; -} -#endif - static void load_image(char *arg, struct swaylock_state *state) { // [[]:] struct swaylock_image *image = calloc(1, sizeof(struct swaylock_image)); @@ -380,22 +358,12 @@ static void load_image(char *arg, struct swaylock_state *state) { // The shell will not expand ~ to the value of $HOME when an output name is // given. Also, any image paths given in the config file need to have shell // expansions performed -#if HAVE_WORDEXP - wordexp_t p; -#endif while (strstr(image->path, " ")) { image->path = realloc(image->path, strlen(image->path) + 2); char *ptr = strstr(image->path, " ") + 1; memmove(ptr + 1, ptr, strlen(ptr) + 1); *ptr = '\\'; } -#if HAVE_WORDEXP - if (wordexp(image->path, &p, 0) == 0) { - free(image->path); - image->path = join_args(p.we_wordv, p.we_wordc); - wordfree(&p); - } -#endif // Load the actual image image->cairo_surface = load_background_image(image->path); @@ -965,76 +933,57 @@ static bool file_exists(const char *path) { return path && access(path, R_OK) != -1; } +static char *config_path(const char *prefix, const char *config_folder) { + if (!prefix || !prefix[0] || !config_folder || !config_folder[0]) { + return NULL; + } + + const char *filename = "config"; + + size_t size = 3 + strlen(prefix) + strlen(config_folder) + strlen(filename); + char *path = calloc(size, sizeof(char)); + snprintf(path, size, "%s/%s/%s", prefix, config_folder, filename); + return path; +} + static char *get_config_path(void) { -#if HAVE_WORDEXP - static const char *config_paths[] = { - "$HOME/.swaylock/config", - "$XDG_CONFIG_HOME/swaylock/config", - SYSCONFDIR "/swaylock/config", + char *path = NULL; + const char *home = getenv("HOME"); + size_t size_fallback = 1 + strlen(home) + strlen("/.config"); + char *config_home_fallback = calloc(size_fallback, sizeof(char)); + snprintf(config_home_fallback, size_fallback, "%s/.config", home); + + const char *config_home = getenv("XDG_CONFIG_HOME"); + if (config_home == NULL || config_home[0] == '\0') { + config_home = config_home_fallback; + } + + struct config_path { + const char *prefix; + const char *config_folder; }; - char *config_home = getenv("XDG_CONFIG_HOME"); - if (!config_home || config_home[0] == '\0') { - config_paths[1] = "$HOME/.config/swaylock/config"; - } + struct config_path config_paths[] = { + { .prefix = home, .config_folder = ".swaylock"}, + { .prefix = config_home, .config_folder = "swaylock"}, + { .prefix = SYSCONFDIR, .config_folder = "swaylock"}, + }; - wordexp_t p; - char *path; - for (size_t i = 0; i < sizeof(config_paths) / sizeof(char *); ++i) { - if (wordexp(config_paths[i], &p, 0) == 0) { - path = strdup(p.we_wordv[0]); - wordfree(&p); - if (file_exists(path)) { - return path; - } - free(path); + size_t num_config_paths = sizeof(config_paths)/sizeof(config_paths[0]); + for (size_t i = 0; i < num_config_paths; i++) { + path = config_path(config_paths[i].prefix, config_paths[i].config_folder); + if (!path) { + continue; } - } -#else - char *home = getenv("HOME"); - char *path; - int n, len; - if (home) { - len = strlen(home) + strlen("/.swaylock/config") + 1; - path = malloc(len); - if (path == NULL) - return NULL; - n = snprintf(path, len, "%s/.swaylock/config", home); - if (n < len && file_exists(path)) - return path; - free(path); - char *config_home = getenv("XDG_CONFIG_HOME"); - if (!config_home || config_home[0] == '\0') { - len = strlen(home) + strlen("/.config/swaylock/config") + 1; - path = malloc(len); - if (path == NULL) - return NULL; - n = snprintf(path, len, "%s/.config/swaylock/config", home); - if (n < len && file_exists(path)) - return path; - free(path); - } else { - len = strlen(config_home) + strlen("/swaylock/config") + 1; - path = malloc(len); - if (path == NULL) - return NULL; - n = snprintf(path, len, "%s/swaylock/config", config_home); - if (n < len && file_exists(path)) - return path; - free(path); + if (file_exists(path)) { + break; } + free(path); + path = NULL; } - len = strlen(SYSCONFDIR "/swaylock/config") + 1; - path = malloc(len); - if (path == NULL) - return NULL; - n = snprintf(path, len, "%s/swaylock/config", SYSCONFDIR); - if (n < len && file_exists(path)) - return path; - free(path); -#endif - return NULL; + free(config_home_fallback); + return path; } static int load_config(char *path, struct swaylock_state *state, diff --git a/meson.build b/meson.build index 2b2d4c0f..7e0129fb 100644 --- a/meson.build +++ b/meson.build @@ -80,7 +80,6 @@ conf_data = configuration_data() conf_data.set_quoted('SYSCONFDIR', get_option('prefix') / get_option('sysconfdir')) conf_data.set_quoted('SWAYLOCK_VERSION', version) conf_data.set10('HAVE_GDK_PIXBUF', gdk_pixbuf.found()) -conf_data.set10('HAVE_WORDEXP', cc.check_header('wordexp.h')) subdir('include') From 6d85ad38f4922483aa6dc0f07a8e49e212c311ab Mon Sep 17 00:00:00 2001 From: Landry Breuil Date: Fri, 10 Nov 2023 12:40:42 +0100 Subject: [PATCH 7/7] no need to include config.h anymore --- main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/main.c b/main.c index 89304ac8..245deddb 100644 --- a/main.c +++ b/main.c @@ -14,7 +14,6 @@ #include #include #include -#include "config.h" #include "background-image.h" #include "cairo.h" #include "comm.h"