diff options
author | Drew DeVault <sir@cmpwn.com> | 2016-12-17 15:19:50 -0500 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2016-12-17 15:21:57 -0500 |
commit | 1172566d4e298aa6c3555a0d606af4ff31d0db48 (patch) | |
tree | a6afcfbbecef26cc6ecaac0fad75268175fe9a51 | |
parent | Merge pull request #996 from woutershep/datadir (diff) | |
download | sway-1172566d4e298aa6c3555a0d606af4ff31d0db48.tar.gz sway-1172566d4e298aa6c3555a0d606af4ff31d0db48.tar.zst sway-1172566d4e298aa6c3555a0d606af4ff31d0db48.zip |
Change how security config is loaded0.11-rc3
-rw-r--r-- | include/sway/config.h | 5 | ||||
-rw-r--r-- | security.in (renamed from config.d/security.in) | 10 | ||||
-rw-r--r-- | sway/CMakeLists.txt | 2 | ||||
-rw-r--r-- | sway/commands/commands.c | 5 | ||||
-rw-r--r-- | sway/commands/ipc.c | 5 | ||||
-rw-r--r-- | sway/commands/permit.c | 10 | ||||
-rw-r--r-- | sway/config.c | 8 | ||||
-rw-r--r-- | sway/main.c | 31 | ||||
-rw-r--r-- | sway/sway-security.7.txt | 18 |
9 files changed, 37 insertions, 57 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index 2c6b83e7..4a14cd36 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -373,4 +373,9 @@ struct bar_config *default_bar_config(void); | |||
373 | */ | 373 | */ |
374 | extern struct sway_config *config; | 374 | extern struct sway_config *config; |
375 | 375 | ||
376 | /** | ||
377 | * Config file currently being read. | ||
378 | */ | ||
379 | extern const char *current_config_path; | ||
380 | |||
376 | #endif | 381 | #endif |
diff --git a/config.d/security.in b/security.in index 36170d42..16897ade 100644 --- a/config.d/security.in +++ b/security.in | |||
@@ -4,6 +4,9 @@ | |||
4 | # | 4 | # |
5 | # You MUST read this man page if you intend to attempt to secure your sway | 5 | # You MUST read this man page if you intend to attempt to secure your sway |
6 | # installation. | 6 | # installation. |
7 | # | ||
8 | # This file should live at __SYSCONFDIR__/sway/security and will be | ||
9 | # automatically read by sway. | ||
7 | 10 | ||
8 | # Configures which programs are allowed to use which sway features | 11 | # Configures which programs are allowed to use which sway features |
9 | permit * fullscreen keyboard mouse ipc | 12 | permit * fullscreen keyboard mouse ipc |
@@ -40,11 +43,4 @@ commands { | |||
40 | bindsym config | 43 | bindsym config |
41 | exit binding | 44 | exit binding |
42 | kill binding | 45 | kill binding |
43 | |||
44 | # You should not change these unless you know what you're doing - it could | ||
45 | # cripple your security | ||
46 | reload binding | ||
47 | permit config | ||
48 | reject config | ||
49 | ipc config | ||
50 | } | 46 | } |
diff --git a/sway/CMakeLists.txt b/sway/CMakeLists.txt index 448335cc..d5453003 100644 --- a/sway/CMakeLists.txt +++ b/sway/CMakeLists.txt | |||
@@ -91,7 +91,7 @@ function(add_config name source destination) | |||
91 | endfunction() | 91 | endfunction() |
92 | 92 | ||
93 | add_config(config config sway) | 93 | add_config(config config sway) |
94 | add_config(security config.d/security sway/config.d) | 94 | add_config(security security sway) |
95 | 95 | ||
96 | add_manpage(sway 1) | 96 | add_manpage(sway 1) |
97 | add_manpage(sway 5) | 97 | add_manpage(sway 5) |
diff --git a/sway/commands/commands.c b/sway/commands/commands.c index 5d248e30..8c7ed487 100644 --- a/sway/commands/commands.c +++ b/sway/commands/commands.c | |||
@@ -19,5 +19,10 @@ struct cmd_results *cmd_commands(int argc, char **argv) { | |||
19 | return cmd_results_new(CMD_FAILURE, "commands", "Can only be used in config file."); | 19 | return cmd_results_new(CMD_FAILURE, "commands", "Can only be used in config file."); |
20 | } | 20 | } |
21 | 21 | ||
22 | if (!current_config_path || strcmp(SYSCONFDIR "/sway/security", current_config_path) != 0) { | ||
23 | return cmd_results_new(CMD_INVALID, "permit", | ||
24 | "This command is only permitted to run from " SYSCONFDIR "/sway/security"); | ||
25 | } | ||
26 | |||
22 | return cmd_results_new(CMD_BLOCK_COMMANDS, NULL, NULL); | 27 | return cmd_results_new(CMD_BLOCK_COMMANDS, NULL, NULL); |
23 | } | 28 | } |
diff --git a/sway/commands/ipc.c b/sway/commands/ipc.c index 222be0dd..113a975b 100644 --- a/sway/commands/ipc.c +++ b/sway/commands/ipc.c | |||
@@ -21,6 +21,11 @@ struct cmd_results *cmd_ipc(int argc, char **argv) { | |||
21 | return cmd_results_new(CMD_FAILURE, "ipc", "Can only be used in config file."); | 21 | return cmd_results_new(CMD_FAILURE, "ipc", "Can only be used in config file."); |
22 | } | 22 | } |
23 | 23 | ||
24 | if (!current_config_path || strcmp(SYSCONFDIR "/sway/security", current_config_path) != 0) { | ||
25 | return cmd_results_new(CMD_INVALID, "permit", | ||
26 | "This command is only permitted to run from " SYSCONFDIR "/sway/security"); | ||
27 | } | ||
28 | |||
24 | return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL); | 29 | return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL); |
25 | } | 30 | } |
26 | 31 | ||
diff --git a/sway/commands/permit.c b/sway/commands/permit.c index dee246d7..1b2a30bf 100644 --- a/sway/commands/permit.c +++ b/sway/commands/permit.c | |||
@@ -64,6 +64,11 @@ struct cmd_results *cmd_permit(int argc, char **argv) { | |||
64 | return error; | 64 | return error; |
65 | } | 65 | } |
66 | 66 | ||
67 | if (!current_config_path || strcmp(SYSCONFDIR "/sway/security", current_config_path) != 0) { | ||
68 | return cmd_results_new(CMD_INVALID, "permit", | ||
69 | "This command is only permitted to run from " SYSCONFDIR "/sway/security"); | ||
70 | } | ||
71 | |||
67 | struct feature_policy *policy = get_policy(argv[0]); | 72 | struct feature_policy *policy = get_policy(argv[0]); |
68 | policy->features |= get_features(argc, argv, &error); | 73 | policy->features |= get_features(argc, argv, &error); |
69 | 74 | ||
@@ -83,6 +88,11 @@ struct cmd_results *cmd_reject(int argc, char **argv) { | |||
83 | return error; | 88 | return error; |
84 | } | 89 | } |
85 | 90 | ||
91 | if (!current_config_path || strcmp(SYSCONFDIR "/sway/security", current_config_path) != 0) { | ||
92 | return cmd_results_new(CMD_INVALID, "permit", | ||
93 | "This command is only permitted to run from " SYSCONFDIR "/sway/security"); | ||
94 | } | ||
95 | |||
86 | struct feature_policy *policy = get_policy(argv[0]); | 96 | struct feature_policy *policy = get_policy(argv[0]); |
87 | policy->features &= ~get_features(argc, argv, &error); | 97 | policy->features &= ~get_features(argc, argv, &error); |
88 | 98 | ||
diff --git a/sway/config.c b/sway/config.c index 4164cefa..8af8cfdd 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -452,8 +452,11 @@ static char *get_config_path(void) { | |||
452 | return NULL; // Not reached | 452 | return NULL; // Not reached |
453 | } | 453 | } |
454 | 454 | ||
455 | const char *current_config_path; | ||
456 | |||
455 | static bool load_config(const char *path, struct sway_config *config) { | 457 | static bool load_config(const char *path, struct sway_config *config) { |
456 | sway_log(L_INFO, "Loading config from %s", path); | 458 | sway_log(L_INFO, "Loading config from %s", path); |
459 | current_config_path = path; | ||
457 | 460 | ||
458 | struct stat sb; | 461 | struct stat sb; |
459 | if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { | 462 | if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { |
@@ -474,11 +477,11 @@ static bool load_config(const char *path, struct sway_config *config) { | |||
474 | bool config_load_success = read_config(f, config); | 477 | bool config_load_success = read_config(f, config); |
475 | fclose(f); | 478 | fclose(f); |
476 | 479 | ||
477 | |||
478 | if (!config_load_success) { | 480 | if (!config_load_success) { |
479 | sway_log(L_ERROR, "Error(s) loading config!"); | 481 | sway_log(L_ERROR, "Error(s) loading config!"); |
480 | } | 482 | } |
481 | 483 | ||
484 | current_config_path = NULL; | ||
482 | return true; | 485 | return true; |
483 | } | 486 | } |
484 | 487 | ||
@@ -509,7 +512,8 @@ bool load_main_config(const char *file, bool is_active) { | |||
509 | list_add(config->config_chain, path); | 512 | list_add(config->config_chain, path); |
510 | 513 | ||
511 | config->reading = true; | 514 | config->reading = true; |
512 | bool success = load_config(path, config); | 515 | bool success = load_config(SYSCONFDIR "/sway/security", config); |
516 | success = success && load_config(path, config); | ||
513 | 517 | ||
514 | if (is_active) { | 518 | if (is_active) { |
515 | config->reloading = false; | 519 | config->reloading = false; |
diff --git a/sway/main.c b/sway/main.c index d41eb292..e8a02e7a 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -179,37 +179,6 @@ static void security_sanity_check() { | |||
179 | "!! DANGER !! " SYSCONFDIR "/sway is not secure! It should be owned by root and set to 0755 at the minimum"); | 179 | "!! DANGER !! " SYSCONFDIR "/sway is not secure! It should be owned by root and set to 0755 at the minimum"); |
180 | } | 180 | } |
181 | } | 181 | } |
182 | struct { | ||
183 | char *command; | ||
184 | enum command_context context; | ||
185 | bool checked; | ||
186 | } expected[] = { | ||
187 | { "reload", CONTEXT_BINDING, false }, | ||
188 | { "permit", CONTEXT_CONFIG, false }, | ||
189 | { "reject", CONTEXT_CONFIG, false }, | ||
190 | { "ipc", CONTEXT_CONFIG, false }, | ||
191 | }; | ||
192 | int expected_len = 4; | ||
193 | for (int i = 0; i < config->command_policies->length; ++i) { | ||
194 | struct command_policy *policy = config->command_policies->items[i]; | ||
195 | for (int j = 0; j < expected_len; ++j) { | ||
196 | if (strcmp(expected[j].command, policy->command) == 0) { | ||
197 | expected[j].checked = true; | ||
198 | if (expected[j].context != policy->context) { | ||
199 | sway_log(L_ERROR, | ||
200 | "!! DANGER !! Command security policy for %s should be set to %s", | ||
201 | expected[j].command, command_policy_str(expected[j].context)); | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | for (int j = 0; j < expected_len; ++j) { | ||
207 | if (!expected[j].checked) { | ||
208 | sway_log(L_ERROR, | ||
209 | "!! DANGER !! Command security policy for %s should be set to %s", | ||
210 | expected[j].command, command_policy_str(expected[j].context)); | ||
211 | } | ||
212 | } | ||
213 | } | 182 | } |
214 | 183 | ||
215 | int main(int argc, char **argv) { | 184 | int main(int argc, char **argv) { |
diff --git a/sway/sway-security.7.txt b/sway/sway-security.7.txt index 588684b9..7d8aa4ad 100644 --- a/sway/sway-security.7.txt +++ b/sway/sway-security.7.txt | |||
@@ -19,22 +19,8 @@ usually best suited to a distro maintainer who wants to ship a secure sway | |||
19 | environment in their distro. Sway provides a number of means of securing it but | 19 | environment in their distro. Sway provides a number of means of securing it but |
20 | you must make a few changes external to sway first. | 20 | you must make a few changes external to sway first. |
21 | 21 | ||
22 | Configuration security | 22 | Security-related configuration is only valid in /etc/sway/config (or whatever path |
23 | ---------------------- | 23 | is appropriate for your system). |
24 | |||
25 | Many of Sway's security features are configurable. It's important that a possibly | ||
26 | untrusted program is not able to edit this. Security rules are kept in | ||
27 | _/etc/sway/config.d/security_ (usually), which should only be writable by root. | ||
28 | However, configuration of security rules is not limited to this file - any config | ||
29 | file that sway loads (including i.e. _~/.config/sway/config_) should not be editable | ||
30 | by the user you intend to run programs as. One simple strategy is to use | ||
31 | /etc/sway/config instead of a config file in your home directory, but that doesn't | ||
32 | work well for multi-user systems. A more robust strategy is to run untrusted | ||
33 | programs as another user, or in a sandbox. Configuring this is up to you. | ||
34 | |||
35 | Note that _/etc/sway/config.d/*_ must be included explicitly from your config file. | ||
36 | This is done by default in /etc/sway/config but you must check your own config if | ||
37 | you choose to place it in other locations. | ||
38 | 24 | ||
39 | Environment security | 25 | Environment security |
40 | -------------------- | 26 | -------------------- |