diff --git a/include/sway/config.h b/include/sway/config.h index 0f2e2aa47..0861712e1 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -263,14 +263,13 @@ enum sway_popup_during_fullscreen { }; enum secure_feature { - FEATURE_FULLSCREEN = 1 << 0, - FEATURE_DATA_CONTROL_MGR = 1 << 1, - FEATURE_DMABUF_EXPORT = 1 << 2, - FEATURE_SCREENCOPY = 1 << 3, - FEATURE_GAMMA_CONTROL = 1 << 4, - FEATURE_INPUT_INHIBIT = 1 << 5, - FEATURE_LAYER_SHELL = 1 << 6, - FEATURE_VIRTUAL_KEYBOARD = 1 << 7, + FEATURE_DATA_CONTROL_MGR = 1 << 0, + FEATURE_DMABUF_EXPORT = 1 << 1, + FEATURE_SCREENCOPY = 1 << 2, + FEATURE_GAMMA_CONTROL = 1 << 3, + FEATURE_INPUT_INHIBIT = 1 << 4, + FEATURE_LAYER_SHELL = 1 << 5, + FEATURE_VIRTUAL_KEYBOARD = 1 << 6, }; struct feature_policy { diff --git a/include/sway/security.h b/include/sway/security.h index c3dfe2b74..d18676338 100644 --- a/include/sway/security.h +++ b/include/sway/security.h @@ -14,4 +14,11 @@ struct feature_policy *get_feature_policy( struct wl_client *create_secure_client(struct wl_display *display, int fd, const struct feature_policy *policy); +struct feature_name { + char *name; + uint64_t value; +}; + +extern struct feature_name feature_names[]; + #endif diff --git a/meson.build b/meson.build index f8303dd51..b593b5a90 100644 --- a/meson.build +++ b/meson.build @@ -114,7 +114,7 @@ if scdoc.found() endforeach endif -add_project_arguments('-DSYSCONFDIR="/@0@/@1@"'.format(prefix, sysconfdir), language : 'c') +add_project_arguments('-DSYSCONFDIR="@0@"'.format(sysconfdir), language : 'c') version = get_option('sway-version') if version != '' diff --git a/security.d/00-defaults.in b/security.d/00-defaults.in index ffda922bd..a059d1a92 100644 --- a/security.d/00-defaults.in +++ b/security.d/00-defaults.in @@ -10,7 +10,6 @@ # Override these defaults by writing new files in # @sysconfdir@/sway/security.d/* -permit * fullscreen -permit @prefix@/bin/swaylock zwlr_layer_shell_v1 zwlr_input_inhibt_manager_v1 -permit @prefix@/bin/swaybg zwlr_layer_shell_v1 -permit @prefix@/bin/swaybar zwlr_layer_shell_v1 +permit @prefix@/bin/swaylock layer_shell input_inhibit +permit @prefix@/bin/swaybg layer_shell +permit @prefix@/bin/swaybar layer_shell diff --git a/sway/commands/permit.c b/sway/commands/permit.c index 0508c9c92..8c9700569 100644 --- a/sway/commands/permit.c +++ b/sway/commands/permit.c @@ -1,4 +1,8 @@ +#include +#include #include "sway/commands.h" +#include "sway/config.h" +#include "sway/security.h" struct cmd_results *cmd_permit(int argc, char **argv) { struct cmd_results *error = NULL; @@ -6,7 +10,23 @@ struct cmd_results *cmd_permit(int argc, char **argv) { return error; } - // TODO + struct feature_policy *policy = get_feature_policy(config, argv[0]); + for (int i = 1; i < argc; ++i) { + int j; + for (j = 0; feature_names[j].name; ++j) { + if (strcmp(argv[i], feature_names[j].name) == 0) { + policy->permit_features |= feature_names[j].value; + break; + } + } + if (!feature_names[j].name) { + return cmd_results_new(CMD_INVALID, "permit", + "'%s' is not a valid feature policy", argv[i]); + } + } + + wlr_log(WLR_DEBUG, "Permitting features %08X for %s", + policy->permit_features, argv[0]); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/reject.c b/sway/commands/reject.c index 55a9b3a12..8e5985a2e 100644 --- a/sway/commands/reject.c +++ b/sway/commands/reject.c @@ -1,4 +1,8 @@ +#include +#include #include "sway/commands.h" +#include "sway/config.h" +#include "sway/security.h" struct cmd_results *cmd_reject(int argc, char **argv) { struct cmd_results *error = NULL; @@ -6,7 +10,23 @@ struct cmd_results *cmd_reject(int argc, char **argv) { return error; } - // TODO + struct feature_policy *policy = get_feature_policy(config, argv[0]); + for (int i = 1; i < argc; ++i) { + int j; + for (j = 0; feature_names[j].name; ++j) { + if (strcmp(argv[i], feature_names[j].name) == 0) { + policy->reject_features |= feature_names[j].value; + break; + } + } + if (!feature_names[j].name) { + return cmd_results_new(CMD_INVALID, "reject", + "'%s' is not a valid feature policy", argv[i]); + } + } + + wlr_log(WLR_DEBUG, "Rejecting features %08X for %s", + policy->reject_features, argv[0]); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/config.c b/sway/config.c index 55933e6e9..f8223cbc3 100644 --- a/sway/config.c +++ b/sway/config.c @@ -439,6 +439,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) { closedir(dir); list_qsort(secconfigs, qstrcmp); + config->secure = true; for (int i = 0; i < secconfigs->length; ++i) { char *_path = secconfigs->items[i]; @@ -455,6 +456,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) { } } + config->secure = false; free_flat_list(secconfigs); } diff --git a/sway/security.c b/sway/security.c index 5bca2f2a8..ef9e81c46 100644 --- a/sway/security.c +++ b/sway/security.c @@ -3,6 +3,17 @@ #include #include "sway/security.h" +struct feature_name feature_names[] = { + { "data_control_manager", FEATURE_DATA_CONTROL_MGR }, + { "export_dmabuf_manager", FEATURE_DMABUF_EXPORT }, + { "screencopy_manager", FEATURE_SCREENCOPY }, + { "gamma_control", FEATURE_GAMMA_CONTROL }, + { "input_inhibit", FEATURE_INPUT_INHIBIT }, + { "layer_shell", FEATURE_LAYER_SHELL }, + { "virtual_keyboard", FEATURE_VIRTUAL_KEYBOARD }, + { NULL, 0 }, +}; + struct feature_policy *get_feature_policy( struct sway_config *config, const char *program) { if (!program) { diff --git a/sway/sway-security.7.scd b/sway/sway-security.7.scd index f8f040c96..3aa973b42 100644 --- a/sway/sway-security.7.scd +++ b/sway/sway-security.7.scd @@ -81,22 +81,22 @@ to control a program's access: By default, the following Wayland globals are hidden by default unless a *permit* statement is issued for them: -*zwlr\_data\_control\_manager\_v1* +*data\_control\_manager* Used to monitor all clipboard activity. -*zwlr\_export\_dmabuf\_manager\_v1*, *zwlr\_screencopy\_manager\_v1* +*export\_dmabuf\_manager*, *screencopy\_manager* Both of these protocols are used to capture images of your screen. -*zwlr\_gamma\_control\_manager\_v1* +*gamma\_control\_manager* Used to control gamma settings, i.e. Redshift functionality. -*zwlr\_input\_inhibit\_manager\_v1* +*input\_inhibit\_manager* Used to obtain exclusive input access, by lock screens and the like. -*zwlr\_layer\_shell\_v1* +*layer\_shell* Used for panels, wallpapers, notifications, and other desktop components. -*zwp\_virtual\_keyboard\_manager\_v1* +*virtual\_keyboard\_manager* Used by on-screen keyboards. *IMPORTANT*: Sway is only able to enforce the security policy for clients which