aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--main.c68
2 files changed, 60 insertions, 10 deletions
diff --git a/README.md b/README.md
index 2188697..eb1a2db 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,6 @@ so a password prompt will show up.
The reason all of this is needed is because `setcap cap_sys_admin+ep gsr-kms-server` can't be done in the flatpak because of sandboxing so this is only done when you install GPU Screen Recorder
from source/aur to workaround that limitation.
-This program also installs gsr-global-hotkeys from the GPU Screen Recorder flatpak to ~/.local/share/gpu-screen-recorder.
+This program also launches gsr-global-hotkeys from the GPU Screen Recorder flatpak with root privileges.
The depends directory contains libcap from the libcap project, available here: https://mirrors.edge.kernel.org/pub/linux/libs/security/linux-privs/libcap2/. The version used is libcap-2.69. \ No newline at end of file
diff --git a/main.c b/main.c
index 9b28b53..4a59882 100644
--- a/main.c
+++ b/main.c
@@ -120,6 +120,7 @@ static int copy_file_atomic_set_capabilities(const char *source_path, const char
static void usage(void) {
fprintf(stderr, "usage alt.1: kms-server-proxy <initial_socket_path> <card_path> <user_homepath>\n");
fprintf(stderr, "usage alt.2: kms-server-proxy setup-gsr-ui [user_homepath]\n");
+ fprintf(stderr, "usage alt.3: kms-server-proxy launch-gsr-global-hotkeys <user_homepath> [args...]\n");
exit(1);
}
@@ -140,14 +141,14 @@ static int setup_gsr_ui(const char *user_homepath) {
/* Update kms-server-proxy-N to kms-server-proxy-N+1 on update (update that needs to run before this program launches itself) */
snprintf(kms_server_proxy_local_filepath, sizeof(kms_server_proxy_local_filepath), "%s/.local/share/gpu-screen-recorder/kms-server-proxy-1", user_homepath);
- char gsr_global_hotkeys_local_filepath[PATH_MAX];
- snprintf(gsr_global_hotkeys_local_filepath, sizeof(gsr_global_hotkeys_local_filepath), "%s/.local/share/gpu-screen-recorder/gsr-global-hotkeys", user_homepath);
+ //char gsr_global_hotkeys_local_filepath[PATH_MAX];
+ //snprintf(gsr_global_hotkeys_local_filepath, sizeof(gsr_global_hotkeys_local_filepath), "%s/.local/share/gpu-screen-recorder/gsr-global-hotkeys", user_homepath);
if(geteuid() == 0) { /* is current user root? */
int success = 1;
success &= (file_set_capabilities(GSR_KMS_SERVER_FILEPATH, (const cap_value_t[]){ CAP_SYS_ADMIN }, 1) == 1);
- success &= (copy_file_atomic_set_capabilities(self_path, kms_server_proxy_local_filepath, (const cap_value_t[]){ CAP_SYS_ADMIN, CAP_SETFCAP }, 2) == 1);
- success &= (copy_file_atomic_set_capabilities(GSR_GLOBAL_HOTKEYS_FILEPATH, gsr_global_hotkeys_local_filepath, (const cap_value_t[]){ CAP_SETUID }, 1) == 1);
+ success &= (copy_file_atomic_set_capabilities(self_path, kms_server_proxy_local_filepath, (const cap_value_t[]){ CAP_SYS_ADMIN, CAP_SETFCAP, CAP_SETUID }, 3) == 1);
+ //success &= (copy_file_atomic_set_capabilities(GSR_GLOBAL_HOTKEYS_FILEPATH, gsr_global_hotkeys_local_filepath, (const cap_value_t[]){ CAP_SETUID }, 1) == 1);
return success ? 0 : 1;
} else {
if(create_local_kms_server_proxy_directory(user_homepath) != 1)
@@ -199,7 +200,7 @@ static int launch_gsr_kms_server(const char *initial_socket_path, const char *ca
return execvp(args[0], (char *const*)args);
} else if(geteuid() == 0) { /* is current user root? */
file_set_capabilities(GSR_KMS_SERVER_FILEPATH, (const cap_value_t[]){ CAP_SYS_ADMIN }, 1);
- copy_file_atomic_set_capabilities(self_path, kms_server_proxy_local_filepath, (const cap_value_t[]){ CAP_SYS_ADMIN, CAP_SETFCAP }, 2);
+ copy_file_atomic_set_capabilities(self_path, kms_server_proxy_local_filepath, (const cap_value_t[]){ CAP_SYS_ADMIN, CAP_SETFCAP, CAP_SETUID }, 3);
const char *args[] = { GSR_KMS_SERVER_FILEPATH, initial_socket_path, card_path, NULL };
return execv(args[0], (char *const*)args);
@@ -211,18 +212,67 @@ static int launch_gsr_kms_server(const char *initial_socket_path, const char *ca
}
}
+static int launch_gsr_global_hotkeys(char **argv) {
+ char self_path[PATH_MAX];
+ if(!readlink_realpath("/proc/self/exe", self_path)) {
+ fprintf(stderr, "failed to resolve /proc/self/exe\n");
+ return 1;
+ }
+
+ const char *user_homepath = argv[2];
+
+ char kms_server_proxy_local_filepath[PATH_MAX];
+ /* Update kms-server-proxy-N to kms-server-proxy-N+1 on update (update that needs to run before this program launches itself) */
+ snprintf(kms_server_proxy_local_filepath, sizeof(kms_server_proxy_local_filepath), "%s/.local/share/gpu-screen-recorder/kms-server-proxy-1", user_homepath);
+
+ if(!file_has_sys_admin_capability(kms_server_proxy_local_filepath)) {
+ fprintf(stderr, "Error: kms-server-proxy is missing cap sys admin capability\n");
+ return 1;
+ }
+
+ /* Need to resolve kms_server_proxy_local_filepath because /home can be a symlink to another location */
+ char kms_server_proxy_local_filepath_full[PATH_MAX];
+ if(!readlink_realpath(kms_server_proxy_local_filepath, kms_server_proxy_local_filepath_full)) {
+ fprintf(stderr, "failed to resolve %s\n", kms_server_proxy_local_filepath);
+ return 1;
+ }
+
+ /*
+ Run cached ~/.local/share/gpu-screen-recorder/kms-server-proxy which has sys admin capability.
+ The one in flatpak location gets capabilities overwritten on flatpak update.
+ */
+ if(strcmp(self_path, kms_server_proxy_local_filepath_full) != 0) {
+ argv[0] = kms_server_proxy_local_filepath_full;
+ return execv(argv[0], (char *const*)argv);
+ }
+
+ if(setuid(0) == -1) {
+ fprintf(stderr, "Error: failed to switch to root user to launch gsr-global-hotkeys\n");
+ return 1;
+ }
+
+ argv[2] = GSR_GLOBAL_HOTKEYS_FILEPATH;
+ return execv(argv[2], argv + 3);
+}
+
int main(int argc, char **argv) {
- if(argc == 2 || argc == 3) {
+ if(argc < 2)
+ usage();
+
+ if(strcmp(argv[1], "setup-gsr-ui") == 0) {
const char *user_homepath = argc == 3 ? argv[2] : NULL;
- if(strcmp(argv[1], "setup-gsr-ui") == 0) {
- return setup_gsr_ui(user_homepath);
+ return setup_gsr_ui(user_homepath);
+ } else if(strcmp(argv[1], "launch-gsr-global-hotkeys") == 0) {
+ if(argc >= 3) {
+ return launch_gsr_global_hotkeys(argv);
} else {
- fprintf(stderr, "error: invalid option \"%s\".\n", argv[1]);
+ fprintf(stderr, "Error: missing user_homepath argument to launch-gsr-global-hotkeys\n");
usage();
}
} else if(argc == 4) {
return launch_gsr_kms_server(argv[1], argv[2], argv[3]);
} else {
+ fprintf(stderr, "error: invalid option \"%s\".\n", argv[1]);
usage();
}
}