commit 76cab04b4d7828f3c4f607c49e1e6ad78aa6e3da
parent 1a8a42f372e1bed146623e3357dbb12d8947e654
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 1 Dec 2016 21:36:43 -0500
Implement permit and reject commands
Diffstat:
10 files changed, 360 insertions(+), 267 deletions(-)
diff --git a/config b/config
@@ -1,204 +0,0 @@
-# Default config for sway
-#
-# Copy this to ~/.config/sway/config and edit it to your liking.
-#
-# Read `man 5 sway` for a complete reference.
-
-### Variables
-#
-# Logo key. Use Mod1 for Alt.
-set $mod Mod4
-# Home row direction keys, like vim
-set $left h
-set $down j
-set $up k
-set $right l
-# Your preferred terminal emulator
-set $term urxvt
-# Your preferred application launcher
-set $menu dmenu_run
-
-### Output configuration
-#
-# Default wallpaper (more resolutions are available in /usr/share/sway/)
-output * bg /usr/share/sway/Sway_Wallpaper_Blue_1920x1080.png fill
-#
-# Example configuration:
-#
-# output HDMI-A-1 resolution 1920x1080 position 1920,0
-#
-# You can get the names of your outputs by running: swaymsg -t get_outputs
-
-### Input configuration
-#
-# Example configuration:
-#
-# input "2:14:SynPS/2_Synaptics_TouchPad" {
-# dwt enabled
-# tap enabled
-# natural_scroll enabled
-# middle_emulation enabled
-# }
-#
-# You can get the names of your inputs by running: swaymsg -t get_inputs
-# The escape symbol "\" has to be removed.
-# Read `man 5 sway-input` for more information about this section.
-
-### Key bindings
-#
-# Basics:
-#
- # start a terminal
- bindsym $mod+Return exec $term
-
- # kill focused window
- bindsym $mod+Shift+q kill
-
- # start your launcher
- bindsym $mod+d exec $menu
-
- # Drag floating windows by holding down $mod and left mouse button.
- # Resize them with right mouse button + $mod.
- # Despite the name, also works for non-floating windows.
- # Change normal to inverse to use left mouse button for resizing and right
- # mouse button for dragging.
- floating_modifier $mod normal
-
- # reload the configuration file
- bindsym $mod+Shift+c reload
-
- # exit sway (logs you out of your wayland session)
- bindsym $mod+Shift+e exit
-#
-# Moving around:
-#
- # Move your focus around
- bindsym $mod+$left focus left
- bindsym $mod+$down focus down
- bindsym $mod+$up focus up
- bindsym $mod+$right focus right
- # or use $mod+[up|down|left|right]
- bindsym $mod+Left focus left
- bindsym $mod+Down focus down
- bindsym $mod+Up focus up
- bindsym $mod+Right focus right
-
- # _move_ the focused window with the same, but add Shift
- bindsym $mod+Shift+$left move left
- bindsym $mod+Shift+$down move down
- bindsym $mod+Shift+$up move up
- bindsym $mod+Shift+$right move right
- # ditto, with arrow keys
- bindsym $mod+Shift+Left move left
- bindsym $mod+Shift+Down move down
- bindsym $mod+Shift+Up move up
- bindsym $mod+Shift+Right move right
-#
-# Workspaces:
-#
- # switch to workspace
- bindsym $mod+1 workspace 1
- bindsym $mod+2 workspace 2
- bindsym $mod+3 workspace 3
- bindsym $mod+4 workspace 4
- bindsym $mod+5 workspace 5
- bindsym $mod+6 workspace 6
- bindsym $mod+7 workspace 7
- bindsym $mod+8 workspace 8
- bindsym $mod+9 workspace 9
- bindsym $mod+0 workspace 10
- # move focused container to workspace
- bindsym $mod+Shift+1 move container to workspace 1
- bindsym $mod+Shift+2 move container to workspace 2
- bindsym $mod+Shift+3 move container to workspace 3
- bindsym $mod+Shift+4 move container to workspace 4
- bindsym $mod+Shift+5 move container to workspace 5
- bindsym $mod+Shift+6 move container to workspace 6
- bindsym $mod+Shift+7 move container to workspace 7
- bindsym $mod+Shift+8 move container to workspace 8
- bindsym $mod+Shift+9 move container to workspace 9
- bindsym $mod+Shift+0 move container to workspace 10
- # Note: workspaces can have any name you want, not just numbers.
- # We just use 1-10 as the default.
-#
-# Layout stuff:
-#
- # You can "split" the current object of your focus with
- # $mod+b or $mod+v, for horizontal and vertical splits
- # respectively.
- bindsym $mod+b splith
- bindsym $mod+v splitv
-
- # Switch the current container between different layout styles
- bindsym $mod+s layout stacking
- bindsym $mod+w layout tabbed
- bindsym $mod+e layout toggle split
-
- # Make the current focus fullscreen
- bindsym $mod+f fullscreen
-
- # Toggle the current focus between tiling and floating mode
- bindsym $mod+Shift+space floating toggle
-
- # Swap focus between the tiling area and the floating area
- bindsym $mod+space focus mode_toggle
-
- # move focus to the parent container
- bindsym $mod+a focus parent
-#
-# Scratchpad:
-#
- # Sway has a "scratchpad", which is a bag of holding for windows.
- # You can send windows there and get them back later.
-
- # Move the currently focused window to the scratchpad
- bindsym $mod+Shift+minus move scratchpad
-
- # Show the next scratchpad window or hide the focused scratchpad window.
- # If there are multiple scratchpad windows, this command cycles through them.
- bindsym $mod+minus scratchpad show
-#
-# Resizing containers:
-#
-mode "resize" {
- # left will shrink the containers width
- # right will grow the containers width
- # up will shrink the containers height
- # down will grow the containers height
- bindsym $left resize shrink width 10 px or 10 ppt
- bindsym $down resize grow height 10 px or 10 ppt
- bindsym $up resize shrink height 10 px or 10 ppt
- bindsym $right resize grow width 10 px or 10 ppt
-
- # ditto, with arrow keys
- bindsym Left resize shrink width 10 px or 10 ppt
- bindsym Down resize grow height 10 px or 10 ppt
- bindsym Up resize shrink height 10 px or 10 ppt
- bindsym Right resize grow width 10 px or 10 ppt
-
- # return to default mode
- bindsym Return mode "default"
- bindsym Escape mode "default"
-}
-bindsym $mod+r mode "resize"
-
-#
-# Status Bar:
-#
-# Read `man 5 sway-bar` for more information about this section.
-bar {
- position top
- colors {
- statusline #ffffff
- background #323232
- inactive_workspace #32323200 #32323200 #5c5c5c
- }
-}
-
-# You may want this:
-#
-# include ~/.config/sway/conf.d/*
-#
-# Protip:
-#
-# include ~/.config/sway/`hostname`/*
diff --git a/config.d/security b/config.d/security
@@ -1,52 +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 $PREFIX/swaylock lock
-permit $PREFIX/swaybar panel
-permit $PREFIX/swaybg background
-permit $PREFIX/swaygrab screenshot
-
-permit * fullscreen keyboard mouse
-
-# 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
- bar-config enabled
- binding enabled
- modifier enabled
- input enabled
- }
-}
-
-# Limits the contexts from which certain commands are permitted
-commands {
- 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
- restart binding
- permit config
- reject config
- ipc config
-}
diff --git a/config.d/security.in b/config.d/security.in
@@ -0,0 +1,52 @@
+# 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 __PREFIX__/swaylock lock
+permit __PREFIX__/swaybar panel
+permit __PREFIX__/swaybg background
+permit __PREFIX__/swaygrab screenshot
+
+permit * fullscreen keyboard mouse
+
+# 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
+ bar-config enabled
+ binding enabled
+ modifier enabled
+ input enabled
+ }
+}
+
+# Limits the contexts from which certain commands are permitted
+commands {
+ 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
+ restart binding
+ permit config
+ reject config
+ ipc config
+}
diff --git a/config.in b/config.in
@@ -0,0 +1,198 @@
+# Default config for sway
+#
+# Copy this to ~/.config/sway/config and edit it to your liking.
+#
+# Read `man 5 sway` for a complete reference.
+
+### Variables
+#
+# Logo key. Use Mod1 for Alt.
+set $mod Mod4
+# Home row direction keys, like vim
+set $left h
+set $down j
+set $up k
+set $right l
+# Your preferred terminal emulator
+set $term urxvt
+# Your preferred application launcher
+set $menu dmenu_run
+
+### Output configuration
+#
+# Default wallpaper (more resolutions are available in /usr/share/sway/)
+output * bg /usr/share/sway/Sway_Wallpaper_Blue_1920x1080.png fill
+#
+# Example configuration:
+#
+# output HDMI-A-1 resolution 1920x1080 position 1920,0
+#
+# You can get the names of your outputs by running: swaymsg -t get_outputs
+
+### Input configuration
+#
+# Example configuration:
+#
+# input "2:14:SynPS/2_Synaptics_TouchPad" {
+# dwt enabled
+# tap enabled
+# natural_scroll enabled
+# middle_emulation enabled
+# }
+#
+# You can get the names of your inputs by running: swaymsg -t get_inputs
+# The escape symbol "\" has to be removed.
+# Read `man 5 sway-input` for more information about this section.
+
+### Key bindings
+#
+# Basics:
+#
+ # start a terminal
+ bindsym $mod+Return exec $term
+
+ # kill focused window
+ bindsym $mod+Shift+q kill
+
+ # start your launcher
+ bindsym $mod+d exec $menu
+
+ # Drag floating windows by holding down $mod and left mouse button.
+ # Resize them with right mouse button + $mod.
+ # Despite the name, also works for non-floating windows.
+ # Change normal to inverse to use left mouse button for resizing and right
+ # mouse button for dragging.
+ floating_modifier $mod normal
+
+ # reload the configuration file
+ bindsym $mod+Shift+c reload
+
+ # exit sway (logs you out of your wayland session)
+ bindsym $mod+Shift+e exit
+#
+# Moving around:
+#
+ # Move your focus around
+ bindsym $mod+$left focus left
+ bindsym $mod+$down focus down
+ bindsym $mod+$up focus up
+ bindsym $mod+$right focus right
+ # or use $mod+[up|down|left|right]
+ bindsym $mod+Left focus left
+ bindsym $mod+Down focus down
+ bindsym $mod+Up focus up
+ bindsym $mod+Right focus right
+
+ # _move_ the focused window with the same, but add Shift
+ bindsym $mod+Shift+$left move left
+ bindsym $mod+Shift+$down move down
+ bindsym $mod+Shift+$up move up
+ bindsym $mod+Shift+$right move right
+ # ditto, with arrow keys
+ bindsym $mod+Shift+Left move left
+ bindsym $mod+Shift+Down move down
+ bindsym $mod+Shift+Up move up
+ bindsym $mod+Shift+Right move right
+#
+# Workspaces:
+#
+ # switch to workspace
+ bindsym $mod+1 workspace 1
+ bindsym $mod+2 workspace 2
+ bindsym $mod+3 workspace 3
+ bindsym $mod+4 workspace 4
+ bindsym $mod+5 workspace 5
+ bindsym $mod+6 workspace 6
+ bindsym $mod+7 workspace 7
+ bindsym $mod+8 workspace 8
+ bindsym $mod+9 workspace 9
+ bindsym $mod+0 workspace 10
+ # move focused container to workspace
+ bindsym $mod+Shift+1 move container to workspace 1
+ bindsym $mod+Shift+2 move container to workspace 2
+ bindsym $mod+Shift+3 move container to workspace 3
+ bindsym $mod+Shift+4 move container to workspace 4
+ bindsym $mod+Shift+5 move container to workspace 5
+ bindsym $mod+Shift+6 move container to workspace 6
+ bindsym $mod+Shift+7 move container to workspace 7
+ bindsym $mod+Shift+8 move container to workspace 8
+ bindsym $mod+Shift+9 move container to workspace 9
+ bindsym $mod+Shift+0 move container to workspace 10
+ # Note: workspaces can have any name you want, not just numbers.
+ # We just use 1-10 as the default.
+#
+# Layout stuff:
+#
+ # You can "split" the current object of your focus with
+ # $mod+b or $mod+v, for horizontal and vertical splits
+ # respectively.
+ bindsym $mod+b splith
+ bindsym $mod+v splitv
+
+ # Switch the current container between different layout styles
+ bindsym $mod+s layout stacking
+ bindsym $mod+w layout tabbed
+ bindsym $mod+e layout toggle split
+
+ # Make the current focus fullscreen
+ bindsym $mod+f fullscreen
+
+ # Toggle the current focus between tiling and floating mode
+ bindsym $mod+Shift+space floating toggle
+
+ # Swap focus between the tiling area and the floating area
+ bindsym $mod+space focus mode_toggle
+
+ # move focus to the parent container
+ bindsym $mod+a focus parent
+#
+# Scratchpad:
+#
+ # Sway has a "scratchpad", which is a bag of holding for windows.
+ # You can send windows there and get them back later.
+
+ # Move the currently focused window to the scratchpad
+ bindsym $mod+Shift+minus move scratchpad
+
+ # Show the next scratchpad window or hide the focused scratchpad window.
+ # If there are multiple scratchpad windows, this command cycles through them.
+ bindsym $mod+minus scratchpad show
+#
+# Resizing containers:
+#
+mode "resize" {
+ # left will shrink the containers width
+ # right will grow the containers width
+ # up will shrink the containers height
+ # down will grow the containers height
+ bindsym $left resize shrink width 10 px or 10 ppt
+ bindsym $down resize grow height 10 px or 10 ppt
+ bindsym $up resize shrink height 10 px or 10 ppt
+ bindsym $right resize grow width 10 px or 10 ppt
+
+ # ditto, with arrow keys
+ bindsym Left resize shrink width 10 px or 10 ppt
+ bindsym Down resize grow height 10 px or 10 ppt
+ bindsym Up resize shrink height 10 px or 10 ppt
+ bindsym Right resize grow width 10 px or 10 ppt
+
+ # return to default mode
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+bindsym $mod+r mode "resize"
+
+#
+# Status Bar:
+#
+# Read `man 5 sway-bar` for more information about this section.
+bar {
+ position top
+ colors {
+ statusline #ffffff
+ background #323232
+ inactive_workspace #32323200 #32323200 #5c5c5c
+ }
+}
+
+include __SYSCONFDIR__/etc/sway/config.d/*
diff --git a/include/security.h b/include/security.h
@@ -1,9 +0,0 @@
-#ifndef _SWAY_SECURITY_H
-#define _SWAY_SECURITY_H
-#include <unistd.h>
-#include "sway/config.h"
-
-enum secure_features get_feature_policy(pid_t pid);
-enum command_context get_command_policy(const char *cmd);
-
-#endif
diff --git a/include/sway/commands.h b/include/sway/commands.h
@@ -122,6 +122,8 @@ sway_cmd cmd_new_float;
sway_cmd cmd_new_window;
sway_cmd cmd_orientation;
sway_cmd cmd_output;
+sway_cmd cmd_permit;
+sway_cmd cmd_reject;
sway_cmd cmd_reload;
sway_cmd cmd_resize;
sway_cmd cmd_scratchpad;
diff --git a/include/sway/security.h b/include/sway/security.h
@@ -3,7 +3,9 @@
#include <unistd.h>
#include "sway/config.h"
-const struct feature_permissions *get_permissions(pid_t pid);
-enum command_context get_command_context(const char *cmd);
+enum secure_feature get_feature_policy(pid_t pid);
+enum command_context get_command_policy(const char *cmd);
+
+struct feature_policy *alloc_feature_policy(const char *program);
#endif
diff --git a/sway/commands.c b/sway/commands.c
@@ -187,6 +187,8 @@ static struct cmd_handler handlers[] = {
{ "new_float", cmd_new_float },
{ "new_window", cmd_new_window },
{ "output", cmd_output },
+ { "permit", cmd_permit },
+ { "reject", cmd_reject },
{ "reload", cmd_reload },
{ "resize", cmd_resize },
{ "scratchpad", cmd_scratchpad },
diff --git a/sway/commands/permit.c b/sway/commands/permit.c
@@ -0,0 +1,95 @@
+#include <string.h>
+#include "sway/commands.h"
+#include "sway/config.h"
+#include "sway/security.h"
+#include "log.h"
+
+static enum secure_feature get_features(int argc, char **argv,
+ struct cmd_results **error) {
+ enum secure_feature features = 0;
+
+ struct {
+ char *name;
+ enum secure_feature feature;
+ } feature_names[] = {
+ { "lock", FEATURE_LOCK },
+ { "panel", FEATURE_PANEL },
+ { "background", FEATURE_BACKGROUND },
+ { "screenshot", FEATURE_SCREENSHOT },
+ { "fullscreen", FEATURE_FULLSCREEN },
+ { "keyboard", FEATURE_KEYBOARD },
+ { "mouse", FEATURE_MOUSE },
+ };
+ size_t names_len = sizeof(feature_names) /
+ (sizeof(char *) + sizeof(enum secure_feature));
+
+ for (int i = 1; i < argc; ++i) {
+ size_t j;
+ for (j = 0; j < names_len; ++j) {
+ if (strcmp(feature_names[j].name, argv[i]) == 0) {
+ break;
+ }
+ }
+ if (j == names_len) {
+ *error = cmd_results_new(CMD_INVALID,
+ "permit", "Invalid feature grant %s", argv[i]);
+ return 0;
+ }
+ features |= feature_names[j].feature;
+ }
+ return features;
+}
+
+static struct feature_policy *get_policy(const char *name) {
+ struct feature_policy *policy = NULL;
+ for (int i = 0; i < config->feature_policies->length; ++i) {
+ struct feature_policy *p = config->feature_policies->items[i];
+ if (strcmp(p->program, name) == 0) {
+ policy = p;
+ break;
+ }
+ }
+ if (!policy) {
+ policy = alloc_feature_policy(name);
+ list_add(config->feature_policies, policy);
+ }
+ return policy;
+}
+
+struct cmd_results *cmd_permit(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "permit", EXPECTED_MORE_THAN, 1))) {
+ return error;
+ }
+
+ struct feature_policy *policy = get_policy(argv[0]);
+ policy->features |= get_features(argc, argv, &error);
+
+ if (error) {
+ return error;
+ }
+
+ sway_log(L_DEBUG, "Permissions granted to %s for features %d",
+ policy->program, policy->features);
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
+
+struct cmd_results *cmd_reject(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "reject", EXPECTED_MORE_THAN, 1))) {
+ return error;
+ }
+
+ struct feature_policy *policy = get_policy(argv[0]);
+ policy->features &= ~get_features(argc, argv, &error);
+
+ if (error) {
+ return error;
+ }
+
+ sway_log(L_DEBUG, "Permissions granted to %s for features %d",
+ policy->program, policy->features);
+
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/security.c b/sway/security.c
@@ -4,6 +4,13 @@
#include "sway/security.h"
#include "log.h"
+struct feature_policy *alloc_feature_policy(const char *program) {
+ struct feature_policy *policy = malloc(sizeof(struct feature_policy));
+ policy->program = strdup(program);
+ policy->features = FEATURE_FULLSCREEN | FEATURE_KEYBOARD | FEATURE_MOUSE;
+ return policy;
+}
+
enum secure_feature get_feature_policy(pid_t pid) {
const char *fmt = "/proc/%d/exe";
int pathlen = snprintf(NULL, 0, fmt, pid);