diff options
Diffstat (limited to 'sway/config.c')
-rw-r--r-- | sway/config.c | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/sway/config.c b/sway/config.c index 9e758c90..88e6fad1 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <libinput.h> | 11 | #include <libinput.h> |
12 | #include <limits.h> | 12 | #include <limits.h> |
13 | #include <float.h> | 13 | #include <float.h> |
14 | #include <dirent.h> | ||
14 | #include "wayland-desktop-shell-server-protocol.h" | 15 | #include "wayland-desktop-shell-server-protocol.h" |
15 | #include "sway/commands.h" | 16 | #include "sway/commands.h" |
16 | #include "sway/config.h" | 17 | #include "sway/config.h" |
@@ -379,7 +380,7 @@ static void config_defaults(struct sway_config *config) { | |||
379 | // Security | 380 | // Security |
380 | if (!(config->command_policies = create_list())) goto cleanup; | 381 | if (!(config->command_policies = create_list())) goto cleanup; |
381 | if (!(config->feature_policies = create_list())) goto cleanup; | 382 | if (!(config->feature_policies = create_list())) goto cleanup; |
382 | config->ipc_policy = UINT32_MAX; | 383 | if (!(config->ipc_policies = create_list())) goto cleanup; |
383 | 384 | ||
384 | return; | 385 | return; |
385 | cleanup: | 386 | cleanup: |
@@ -485,6 +486,10 @@ static bool load_config(const char *path, struct sway_config *config) { | |||
485 | return true; | 486 | return true; |
486 | } | 487 | } |
487 | 488 | ||
489 | static int qstrcmp(const void* a, const void* b) { | ||
490 | return strcmp(*((char**) a), *((char**) b)); | ||
491 | } | ||
492 | |||
488 | bool load_main_config(const char *file, bool is_active) { | 493 | bool load_main_config(const char *file, bool is_active) { |
489 | input_init(); | 494 | input_init(); |
490 | 495 | ||
@@ -512,7 +517,43 @@ bool load_main_config(const char *file, bool is_active) { | |||
512 | list_add(config->config_chain, path); | 517 | list_add(config->config_chain, path); |
513 | 518 | ||
514 | config->reading = true; | 519 | config->reading = true; |
515 | bool success = load_config(SYSCONFDIR "/sway/security", config); | 520 | |
521 | // Read security configs | ||
522 | bool success = true; | ||
523 | DIR *dir = opendir(SYSCONFDIR "/sway/security.d"); | ||
524 | if (!dir) { | ||
525 | sway_log(L_ERROR, "%s does not exist, sway will have no security configuration" | ||
526 | " and will probably be broken", SYSCONFDIR "/sway/security.d"); | ||
527 | } else { | ||
528 | list_t *secconfigs = create_list(); | ||
529 | char *base = SYSCONFDIR "/sway/security.d/"; | ||
530 | struct dirent *ent = readdir(dir); | ||
531 | while (ent != NULL) { | ||
532 | if (ent->d_type == DT_REG) { | ||
533 | char *_path = malloc(strlen(ent->d_name) + strlen(base) + 1); | ||
534 | strcpy(_path, base); | ||
535 | strcat(_path, ent->d_name); | ||
536 | list_add(secconfigs, _path); | ||
537 | } | ||
538 | ent = readdir(dir); | ||
539 | } | ||
540 | closedir(dir); | ||
541 | |||
542 | list_qsort(secconfigs, qstrcmp); | ||
543 | for (int i = 0; i < secconfigs->length; ++i) { | ||
544 | char *_path = secconfigs->items[i]; | ||
545 | struct stat s; | ||
546 | if (stat(_path, &s) || s.st_uid != 0 || s.st_gid != 0 || (s.st_mode & 0777) != 0644) { | ||
547 | sway_log(L_ERROR, "Refusing to load %s - it must be owned by root and mode 644", _path); | ||
548 | success = false; | ||
549 | } else { | ||
550 | success = success && load_config(_path, config); | ||
551 | } | ||
552 | } | ||
553 | |||
554 | free_flat_list(secconfigs); | ||
555 | } | ||
556 | |||
516 | success = success && load_config(path, config); | 557 | success = success && load_config(path, config); |
517 | 558 | ||
518 | if (is_active) { | 559 | if (is_active) { |
@@ -620,6 +661,15 @@ bool load_include_configs(const char *path, struct sway_config *config) { | |||
620 | return true; | 661 | return true; |
621 | } | 662 | } |
622 | 663 | ||
664 | struct cmd_results *check_security_config() { | ||
665 | if (!current_config_path || strncmp(SYSCONFDIR "/sway/security.d/", current_config_path, | ||
666 | strlen(SYSCONFDIR "/sway/security.d/")) != 0) { | ||
667 | return cmd_results_new(CMD_INVALID, "permit", | ||
668 | "This command is only permitted to run from " SYSCONFDIR "/sway/security.d/*"); | ||
669 | } | ||
670 | return NULL; | ||
671 | } | ||
672 | |||
623 | bool read_config(FILE *file, struct sway_config *config) { | 673 | bool read_config(FILE *file, struct sway_config *config) { |
624 | bool success = true; | 674 | bool success = true; |
625 | enum cmd_status block = CMD_BLOCK_END; | 675 | enum cmd_status block = CMD_BLOCK_END; |