diff options
-rw-r--r-- | config.d/security.in | 5 | ||||
-rw-r--r-- | sway/commands.c | 2 | ||||
-rw-r--r-- | sway/security.c | 21 | ||||
-rw-r--r-- | sway/sway-security.7.txt | 19 |
4 files changed, 34 insertions, 13 deletions
diff --git a/config.d/security.in b/config.d/security.in index b5690dc7..47592b05 100644 --- a/config.d/security.in +++ b/config.d/security.in | |||
@@ -6,13 +6,12 @@ | |||
6 | # installation. | 6 | # installation. |
7 | 7 | ||
8 | # Configures which programs are allowed to use which sway features | 8 | # Configures which programs are allowed to use which sway features |
9 | permit * fullscreen keyboard mouse ipc | ||
9 | permit __PREFIX__/bin/swaylock lock | 10 | permit __PREFIX__/bin/swaylock lock |
10 | permit __PREFIX__/bin/swaybar panel | 11 | permit __PREFIX__/bin/swaybar panel |
11 | permit __PREFIX__/bin/swaybg background | 12 | permit __PREFIX__/bin/swaybg background |
12 | permit __PREFIX__/bin/swaygrab screenshot | 13 | permit __PREFIX__/bin/swaygrab screenshot |
13 | 14 | ||
14 | permit * fullscreen keyboard mouse | ||
15 | |||
16 | # Configures which IPC features are enabled | 15 | # Configures which IPC features are enabled |
17 | ipc { | 16 | ipc { |
18 | command enabled | 17 | command enabled |
@@ -36,6 +35,8 @@ ipc { | |||
36 | 35 | ||
37 | # Limits the contexts from which certain commands are permitted | 36 | # Limits the contexts from which certain commands are permitted |
38 | commands { | 37 | commands { |
38 | * all | ||
39 | |||
39 | fullscreen binding criteria | 40 | fullscreen binding criteria |
40 | bindsym config | 41 | bindsym config |
41 | exit binding | 42 | exit binding |
diff --git a/sway/commands.c b/sway/commands.c index 3d8f8c5b..d87d0084 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -524,7 +524,7 @@ struct cmd_results *config_commands_command(char *exec) { | |||
524 | } | 524 | } |
525 | 525 | ||
526 | struct cmd_handler *handler = find_handler(cmd, CMD_BLOCK_END); | 526 | struct cmd_handler *handler = find_handler(cmd, CMD_BLOCK_END); |
527 | if (!handler) { | 527 | if (!handler && strcmp(cmd, "*") != 0) { |
528 | char *input = cmd ? cmd : "(empty)"; | 528 | char *input = cmd ? cmd : "(empty)"; |
529 | results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); | 529 | results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); |
530 | goto cleanup; | 530 | goto cleanup; |
diff --git a/sway/security.c b/sway/security.c index 1d236b1d..f16fdd1f 100644 --- a/sway/security.c +++ b/sway/security.c | |||
@@ -5,16 +5,25 @@ | |||
5 | #include "log.h" | 5 | #include "log.h" |
6 | 6 | ||
7 | struct feature_policy *alloc_feature_policy(const char *program) { | 7 | struct feature_policy *alloc_feature_policy(const char *program) { |
8 | uint32_t default_policy = 0; | ||
9 | for (int i = 0; i < config->feature_policies->length; ++i) { | ||
10 | struct feature_policy *policy = config->feature_policies->items[i]; | ||
11 | if (strcmp(policy->program, "*") == 0) { | ||
12 | default_policy = policy->features; | ||
13 | break; | ||
14 | } | ||
15 | } | ||
16 | |||
8 | struct feature_policy *policy = malloc(sizeof(struct feature_policy)); | 17 | struct feature_policy *policy = malloc(sizeof(struct feature_policy)); |
9 | policy->program = strdup(program); | 18 | policy->program = strdup(program); |
10 | policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE | FEATURE_IPC; | 19 | policy->features = default_policy; |
11 | return policy; | 20 | return policy; |
12 | } | 21 | } |
13 | 22 | ||
14 | struct command_policy *alloc_command_policy(const char *command) { | 23 | struct command_policy *alloc_command_policy(const char *command) { |
15 | struct command_policy *policy = malloc(sizeof(struct command_policy)); | 24 | struct command_policy *policy = malloc(sizeof(struct command_policy)); |
16 | policy->command = strdup(command); | 25 | policy->command = strdup(command); |
17 | policy->context = CONTEXT_ALL; | 26 | policy->context = 0; |
18 | return policy; | 27 | return policy; |
19 | } | 28 | } |
20 | 29 | ||
@@ -25,8 +34,7 @@ enum secure_feature get_feature_policy(pid_t pid) { | |||
25 | snprintf(path, pathlen + 1, fmt, pid); | 34 | snprintf(path, pathlen + 1, fmt, pid); |
26 | static char link[2048]; | 35 | static char link[2048]; |
27 | 36 | ||
28 | enum secure_feature default_policy = | 37 | uint32_t default_policy = 0; |
29 | FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; | ||
30 | 38 | ||
31 | ssize_t len = readlink(path, link, sizeof(link)); | 39 | ssize_t len = readlink(path, link, sizeof(link)); |
32 | if (len < 0) { | 40 | if (len < 0) { |
@@ -53,10 +61,13 @@ enum secure_feature get_feature_policy(pid_t pid) { | |||
53 | } | 61 | } |
54 | 62 | ||
55 | enum command_context get_command_policy(const char *cmd) { | 63 | enum command_context get_command_policy(const char *cmd) { |
56 | enum command_context default_policy = CONTEXT_ALL; | 64 | uint32_t default_policy = 0; |
57 | 65 | ||
58 | for (int i = 0; i < config->command_policies->length; ++i) { | 66 | for (int i = 0; i < config->command_policies->length; ++i) { |
59 | struct command_policy *policy = config->command_policies->items[i]; | 67 | struct command_policy *policy = config->command_policies->items[i]; |
68 | if (strcmp(policy->command, "*") == 0) { | ||
69 | default_policy = policy->context; | ||
70 | } | ||
60 | if (strcmp(policy->command, cmd) == 0) { | 71 | if (strcmp(policy->command, cmd) == 0) { |
61 | return policy->context; | 72 | return policy->context; |
62 | } | 73 | } |
diff --git a/sway/sway-security.7.txt b/sway/sway-security.7.txt index 53c7b876..9a2581b1 100644 --- a/sway/sway-security.7.txt +++ b/sway/sway-security.7.txt | |||
@@ -124,8 +124,14 @@ To work correctly, sway's own programs require the following permissions: | |||
124 | 124 | ||
125 | - swaybg: background | 125 | - swaybg: background |
126 | - swaylock: lock, keyboard | 126 | - swaylock: lock, keyboard |
127 | - swaybar: panel, mouse | 127 | - swaybar: panel, mouse, ipc |
128 | - swaygrab: screenshot | 128 | - swaygrab: screenshot, ipc |
129 | |||
130 | When you first declare a policy for an executable, it will inherit the default | ||
131 | policy. Further changes to the default policy will not retroactively affect which | ||
132 | permissions an earlier policy inherits. You must explicitly reject any features | ||
133 | from the default policy that you do not want an executable to receive permission | ||
134 | for. | ||
129 | 135 | ||
130 | Command policies | 136 | Command policies |
131 | ---------------- | 137 | ---------------- |
@@ -145,6 +151,9 @@ contexts you can control are: | |||
145 | **criteria**:: | 151 | **criteria**:: |
146 | Can be run when evaluating window criteria. | 152 | Can be run when evaluating window criteria. |
147 | 153 | ||
154 | **all**:: | ||
155 | Shorthand for granting permission in all contexts. | ||
156 | |||
148 | By default a command is allowed to execute in any context. To configure this, open | 157 | By default a command is allowed to execute in any context. To configure this, open |
149 | a commands block and fill it with policies: | 158 | a commands block and fill it with policies: |
150 | 159 | ||
@@ -160,13 +169,13 @@ binding and critiera: | |||
160 | focus binding criteria | 169 | focus binding criteria |
161 | } | 170 | } |
162 | 171 | ||
172 | Setting a command policy overwrites any previous policy that was in place. | ||
173 | |||
163 | IPC policies | 174 | IPC policies |
164 | ------------ | 175 | ------------ |
165 | 176 | ||
166 | By default all programs can connect to IPC for backwards compatability with i3. | 177 | You may whitelist IPC access like so: |
167 | However, you can whitelist IPC access like so: | ||
168 | 178 | ||
169 | reject * ipc | ||
170 | permit /usr/bin/swaybar ipc | 179 | permit /usr/bin/swaybar ipc |
171 | permit /usr/bin/swaygrab ipc | 180 | permit /usr/bin/swaygrab ipc |
172 | # etc | 181 | # etc |