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 @@ # installation. # Configures which programs are allowed to use which sway features +permit * fullscreen keyboard mouse ipc permit __PREFIX__/bin/swaylock lock permit __PREFIX__/bin/swaybar panel permit __PREFIX__/bin/swaybg background permit __PREFIX__/bin/swaygrab screenshot -permit * fullscreen keyboard mouse - # Configures which IPC features are enabled ipc { command enabled @@ -36,6 +35,8 @@ ipc { # Limits the contexts from which certain commands are permitted commands { + * all + fullscreen binding criteria bindsym config 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) { } struct cmd_handler *handler = find_handler(cmd, CMD_BLOCK_END); - if (!handler) { + if (!handler && strcmp(cmd, "*") != 0) { char *input = cmd ? cmd : "(empty)"; results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); 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 @@ #include "log.h" struct feature_policy *alloc_feature_policy(const char *program) { + uint32_t default_policy = 0; + for (int i = 0; i < config->feature_policies->length; ++i) { + struct feature_policy *policy = config->feature_policies->items[i]; + if (strcmp(policy->program, "*") == 0) { + default_policy = policy->features; + break; + } + } + struct feature_policy *policy = malloc(sizeof(struct feature_policy)); policy->program = strdup(program); - policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE | FEATURE_IPC; + policy->features = default_policy; return policy; } struct command_policy *alloc_command_policy(const char *command) { struct command_policy *policy = malloc(sizeof(struct command_policy)); policy->command = strdup(command); - policy->context = CONTEXT_ALL; + policy->context = 0; return policy; } @@ -25,8 +34,7 @@ enum secure_feature get_feature_policy(pid_t pid) { snprintf(path, pathlen + 1, fmt, pid); static char link[2048]; - enum secure_feature default_policy = - FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE; + uint32_t default_policy = 0; ssize_t len = readlink(path, link, sizeof(link)); if (len < 0) { @@ -53,10 +61,13 @@ enum secure_feature get_feature_policy(pid_t pid) { } enum command_context get_command_policy(const char *cmd) { - enum command_context default_policy = CONTEXT_ALL; + uint32_t default_policy = 0; for (int i = 0; i < config->command_policies->length; ++i) { struct command_policy *policy = config->command_policies->items[i]; + if (strcmp(policy->command, "*") == 0) { + default_policy = policy->context; + } if (strcmp(policy->command, cmd) == 0) { return policy->context; } 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: - swaybg: background - swaylock: lock, keyboard -- swaybar: panel, mouse -- swaygrab: screenshot +- swaybar: panel, mouse, ipc +- swaygrab: screenshot, ipc + +When you first declare a policy for an executable, it will inherit the default +policy. Further changes to the default policy will not retroactively affect which +permissions an earlier policy inherits. You must explicitly reject any features +from the default policy that you do not want an executable to receive permission +for. Command policies ---------------- @@ -145,6 +151,9 @@ contexts you can control are: **criteria**:: Can be run when evaluating window criteria. +**all**:: + Shorthand for granting permission in all contexts. + By default a command is allowed to execute in any context. To configure this, open a commands block and fill it with policies: @@ -160,13 +169,13 @@ binding and critiera: focus binding criteria } +Setting a command policy overwrites any previous policy that was in place. + IPC policies ------------ -By default all programs can connect to IPC for backwards compatability with i3. -However, you can whitelist IPC access like so: +You may whitelist IPC access like so: - reject * ipc permit /usr/bin/swaybar ipc permit /usr/bin/swaygrab ipc # etc