From 1172566d4e298aa6c3555a0d606af4ff31d0db48 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Sat, 17 Dec 2016 15:19:50 -0500 Subject: Change how security config is loaded --- config.d/security.in | 50 ------------------------------------------------ include/sway/config.h | 5 +++++ security.in | 46 ++++++++++++++++++++++++++++++++++++++++++++ sway/CMakeLists.txt | 2 +- sway/commands/commands.c | 5 +++++ sway/commands/ipc.c | 5 +++++ sway/commands/permit.c | 10 ++++++++++ sway/config.c | 8 ++++++-- sway/main.c | 31 ------------------------------ sway/sway-security.7.txt | 18 ++--------------- 10 files changed, 80 insertions(+), 100 deletions(-) delete mode 100644 config.d/security.in create mode 100644 security.in diff --git a/config.d/security.in b/config.d/security.in deleted file mode 100644 index 36170d42..00000000 --- a/config.d/security.in +++ /dev/null @@ -1,50 +0,0 @@ -# sway security rules -# -# Read sway-security(7) for details on how to secure your sway install. -# -# You MUST read this man page if you intend to attempt to secure your sway -# 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 - -# Configures which IPC features are enabled -ipc { - command enabled - outputs enabled - workspaces enabled - tree enabled - marks enabled - bar-config enabled - inputs enabled - - events { - workspace enabled - output enabled - mode enabled - window enabled - input enabled - binding disabled - } -} - -# Limits the contexts from which certain commands are permitted -commands { - * all - - fullscreen binding criteria - bindsym config - exit binding - kill binding - - # You should not change these unless you know what you're doing - it could - # cripple your security - reload binding - permit config - reject config - ipc config -} 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); */ extern struct sway_config *config; +/** + * Config file currently being read. + */ +extern const char *current_config_path; + #endif diff --git a/security.in b/security.in new file mode 100644 index 00000000..16897ade --- /dev/null +++ b/security.in @@ -0,0 +1,46 @@ +# sway security rules +# +# Read sway-security(7) for details on how to secure your sway install. +# +# You MUST read this man page if you intend to attempt to secure your sway +# installation. +# +# This file should live at __SYSCONFDIR__/sway/security and will be +# automatically read by sway. + +# 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 + +# Configures which IPC features are enabled +ipc { + command enabled + outputs enabled + workspaces enabled + tree enabled + marks enabled + bar-config enabled + inputs enabled + + events { + workspace enabled + output enabled + mode enabled + window enabled + input enabled + binding disabled + } +} + +# Limits the contexts from which certain commands are permitted +commands { + * all + + fullscreen binding criteria + bindsym config + exit binding + kill binding +} 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) endfunction() add_config(config config sway) -add_config(security config.d/security sway/config.d) +add_config(security security sway) add_manpage(sway 1) 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) { return cmd_results_new(CMD_FAILURE, "commands", "Can only be used in config file."); } + if (!current_config_path || strcmp(SYSCONFDIR "/sway/security", current_config_path) != 0) { + return cmd_results_new(CMD_INVALID, "permit", + "This command is only permitted to run from " SYSCONFDIR "/sway/security"); + } + return cmd_results_new(CMD_BLOCK_COMMANDS, NULL, NULL); } 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) { return cmd_results_new(CMD_FAILURE, "ipc", "Can only be used in config file."); } + if (!current_config_path || strcmp(SYSCONFDIR "/sway/security", current_config_path) != 0) { + return cmd_results_new(CMD_INVALID, "permit", + "This command is only permitted to run from " SYSCONFDIR "/sway/security"); + } + return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL); } 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) { return error; } + if (!current_config_path || strcmp(SYSCONFDIR "/sway/security", current_config_path) != 0) { + return cmd_results_new(CMD_INVALID, "permit", + "This command is only permitted to run from " SYSCONFDIR "/sway/security"); + } + struct feature_policy *policy = get_policy(argv[0]); policy->features |= get_features(argc, argv, &error); @@ -83,6 +88,11 @@ struct cmd_results *cmd_reject(int argc, char **argv) { return error; } + if (!current_config_path || strcmp(SYSCONFDIR "/sway/security", current_config_path) != 0) { + return cmd_results_new(CMD_INVALID, "permit", + "This command is only permitted to run from " SYSCONFDIR "/sway/security"); + } + struct feature_policy *policy = get_policy(argv[0]); policy->features &= ~get_features(argc, argv, &error); 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) { return NULL; // Not reached } +const char *current_config_path; + static bool load_config(const char *path, struct sway_config *config) { sway_log(L_INFO, "Loading config from %s", path); + current_config_path = path; struct stat sb; 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) { bool config_load_success = read_config(f, config); fclose(f); - if (!config_load_success) { sway_log(L_ERROR, "Error(s) loading config!"); } + current_config_path = NULL; return true; } @@ -509,7 +512,8 @@ bool load_main_config(const char *file, bool is_active) { list_add(config->config_chain, path); config->reading = true; - bool success = load_config(path, config); + bool success = load_config(SYSCONFDIR "/sway/security", config); + success = success && load_config(path, config); if (is_active) { 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() { "!! DANGER !! " SYSCONFDIR "/sway is not secure! It should be owned by root and set to 0755 at the minimum"); } } - struct { - char *command; - enum command_context context; - bool checked; - } expected[] = { - { "reload", CONTEXT_BINDING, false }, - { "permit", CONTEXT_CONFIG, false }, - { "reject", CONTEXT_CONFIG, false }, - { "ipc", CONTEXT_CONFIG, false }, - }; - int expected_len = 4; - for (int i = 0; i < config->command_policies->length; ++i) { - struct command_policy *policy = config->command_policies->items[i]; - for (int j = 0; j < expected_len; ++j) { - if (strcmp(expected[j].command, policy->command) == 0) { - expected[j].checked = true; - if (expected[j].context != policy->context) { - sway_log(L_ERROR, - "!! DANGER !! Command security policy for %s should be set to %s", - expected[j].command, command_policy_str(expected[j].context)); - } - } - } - } - for (int j = 0; j < expected_len; ++j) { - if (!expected[j].checked) { - sway_log(L_ERROR, - "!! DANGER !! Command security policy for %s should be set to %s", - expected[j].command, command_policy_str(expected[j].context)); - } - } } 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 environment in their distro. Sway provides a number of means of securing it but you must make a few changes external to sway first. -Configuration security ----------------------- - -Many of Sway's security features are configurable. It's important that a possibly -untrusted program is not able to edit this. Security rules are kept in -_/etc/sway/config.d/security_ (usually), which should only be writable by root. -However, configuration of security rules is not limited to this file - any config -file that sway loads (including i.e. _~/.config/sway/config_) should not be editable -by the user you intend to run programs as. One simple strategy is to use -/etc/sway/config instead of a config file in your home directory, but that doesn't -work well for multi-user systems. A more robust strategy is to run untrusted -programs as another user, or in a sandbox. Configuring this is up to you. - -Note that _/etc/sway/config.d/*_ must be included explicitly from your config file. -This is done by default in /etc/sway/config but you must check your own config if -you choose to place it in other locations. +Security-related configuration is only valid in /etc/sway/config (or whatever path +is appropriate for your system). Environment security -------------------- -- cgit v1.2.3-70-g09d2