Label-based security on privileged globals

This adds a command (security_label) which is used to allow or deny access to
privileged interfaces on a client-by-client basis. If no security configuration
it present, all privileged operations are allowed to all clients.

 - "security_label deny default *" will deny clients access to all privileged
   operations
 - "security_label set default layer_shell" will overwrite the access list for
   the label "default" and only allow access to the layer_shell interface
 - "security_label permit recorder screencopy_manager" allows connections that
   have the label "recorder" access to screencopy_manager in addition to the
   current permissions of the "recorder" label

If a client does not have a label or if the label's permissions were not
defined using security_label, the permissions for the "default" label are used;
if no definition for "default" is present, all interfaces are allowed.

Using permit or deny on a new label does not copy the default.

The security configuration state is reset on a config reload (similar to the
assign and for_window lists).  Currently, the security policy is only enforced
during the binding or enumeration of global resources; existing handles to
privileged interfaces are not invalided by a change in policy, and existing
clients are not informed of the presence of newly available interfaces.
This commit is contained in:
Daniel De Graaf 2021-02-18 23:03:51 -05:00
parent e840cc72db
commit c292679c5c
11 changed files with 317 additions and 4 deletions

View file

@ -308,5 +308,6 @@ sway_cmd cmd_ipc_events;
sway_cmd cmd_ipc_event_cmd;
sway_cmd cmd_sandbox_socket;
sway_cmd cmd_security_label;
#endif

View file

@ -14,6 +14,7 @@
#include "swaynag.h"
#include "tree/container.h"
#include "sway/input/tablet.h"
#include "sway/security.h"
#include "sway/tree/root.h"
#include "wlr-layer-shell-unstable-v1-protocol.h"
@ -286,6 +287,11 @@ struct output_config {
enum config_dpms dpms_state;
};
struct security_config {
char* name;
security_perm_mask_t permitted;
};
/**
* Stores size of gaps for each side
*/
@ -488,6 +494,7 @@ struct sway_config {
list_t *criteria;
list_t *no_focus;
list_t *active_bar_modifiers;
list_t *security_configs;
struct sway_mode *current_mode;
struct bar_config *current_bar;
uint32_t floating_mod;

27
include/sway/security.h Normal file
View file

@ -0,0 +1,27 @@
#pragma once
enum security_perm {
PRIV_DATA_CONTROL_MANAGER,
PRIV_FOREIGN_TOPLEVEL_MANAGER,
PRIV_GAMMA_CONTROL_MANAGER,
PRIV_INPUT_INHIBIT,
PRIV_INPUT_KEYBOARD_SHORTCUTS_INHIBIT,
PRIV_INPUT_METHOD,
PRIV_INPUT_VIRTUAL_KEYBOARD,
PRIV_INPUT_VIRTUAL_POINTER,
PRIV_LAYER_SHELL,
PRIV_OUTPUT_MANAGER,
PRIV_OUTPUT_POWER_MANAGER,
PRIV_SCREENSHOT,
PRIV_SESSION_LOCK,
PRIV_LAST, /* not an actual permission */
};
typedef uint32_t security_perm_mask_t;
bool security_global_filter(const struct wl_client *client, const struct wl_global *global, void *data);
/**
* Get permission value associated with the given name, or PRIV_LAST if there is none
*/
enum security_perm security_get_perm_by_name(const char *name);

View file

@ -44,6 +44,7 @@ struct sway_server {
struct wlr_linux_dmabuf_v1 *linux_dmabuf_v1;
struct wlr_data_device_manager *data_device_manager;
struct wlr_gamma_control_manager_v1 *gamma_control_manager;
struct sway_input_manager *input;
@ -98,6 +99,10 @@ struct sway_server {
struct wlr_xdg_activation_v1 *xdg_activation_v1;
struct wl_listener xdg_activation_v1_request_activate;
struct wlr_export_dmabuf_manager_v1 *dmabuf_manager;
struct wlr_screencopy_manager_v1 *screencopy_manager;
struct wlr_data_control_manager_v1 *data_control_manager;
// The timeout for transactions, after which a transaction is applied
// regardless of readiness.
size_t txn_timeout_ms;