aboutsummaryrefslogtreecommitdiffstats
path: root/sway
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2016-12-02 08:17:45 -0500
committerLibravatar Drew DeVault <sir@cmpwn.com>2016-12-02 08:17:45 -0500
commit39cf9a82f7c1f7e5d7b4952cabf215c8459a99e2 (patch)
tree267efa5b40f7272bdfec16eac054961df6f4d417 /sway
parentAdd support for command policies in config file (diff)
downloadsway-39cf9a82f7c1f7e5d7b4952cabf215c8459a99e2.tar.gz
sway-39cf9a82f7c1f7e5d7b4952cabf215c8459a99e2.tar.zst
sway-39cf9a82f7c1f7e5d7b4952cabf215c8459a99e2.zip
Enforce command policies
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c12
-rw-r--r--sway/handlers.c14
-rw-r--r--sway/ipc-server.c2
-rw-r--r--sway/security.c17
4 files changed, 36 insertions, 9 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 0bfe9d13..5d5087b1 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -323,7 +323,7 @@ static struct cmd_handler *find_handler(char *line, enum cmd_status block) {
323 return res; 323 return res;
324} 324}
325 325
326struct cmd_results *handle_command(char *_exec) { 326struct cmd_results *handle_command(char *_exec, enum command_context context) {
327 // Even though this function will process multiple commands we will only 327 // Even though this function will process multiple commands we will only
328 // return the last error, if any (for now). (Since we have access to an 328 // return the last error, if any (for now). (Since we have access to an
329 // error string we could e.g. concatonate all errors there.) 329 // error string we could e.g. concatonate all errors there.)
@@ -397,6 +397,16 @@ struct cmd_results *handle_command(char *_exec) {
397 free_argv(argc, argv); 397 free_argv(argc, argv);
398 goto cleanup; 398 goto cleanup;
399 } 399 }
400 if (!(get_command_policy(argv[0]) & context)) {
401 if (results) {
402 free_cmd_results(results);
403 }
404 results = cmd_results_new(CMD_INVALID, cmd,
405 "Permission denied for %s via %s", cmd,
406 command_policy_str(context));
407 free_argv(argc, argv);
408 goto cleanup;
409 }
400 struct cmd_results *res = handler->handle(argc-1, argv+1); 410 struct cmd_results *res = handler->handle(argc-1, argv+1);
401 if (res->status != CMD_SUCCESS) { 411 if (res->status != CMD_SUCCESS) {
402 free_argv(argc, argv); 412 free_argv(argc, argv);
diff --git a/sway/handlers.c b/sway/handlers.c
index a329329d..ee52ba38 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -386,7 +386,7 @@ static bool handle_view_created(wlc_handle handle) {
386 struct criteria *crit = criteria->items[i]; 386 struct criteria *crit = criteria->items[i];
387 sway_log(L_DEBUG, "for_window '%s' matches new view %p, cmd: '%s'", 387 sway_log(L_DEBUG, "for_window '%s' matches new view %p, cmd: '%s'",
388 crit->crit_raw, newview, crit->cmdlist); 388 crit->crit_raw, newview, crit->cmdlist);
389 struct cmd_results *res = handle_command(crit->cmdlist); 389 struct cmd_results *res = handle_command(crit->cmdlist, CONTEXT_CRITERIA);
390 if (res->status != CMD_SUCCESS) { 390 if (res->status != CMD_SUCCESS) {
391 sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error); 391 sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
392 } 392 }
@@ -585,7 +585,7 @@ static void handle_binding_command(struct sway_binding *binding) {
585 reload = true; 585 reload = true;
586 } 586 }
587 587
588 struct cmd_results *res = handle_command(binding->command); 588 struct cmd_results *res = handle_command(binding->command, CONTEXT_BINDING);
589 if (res->status != CMD_SUCCESS) { 589 if (res->status != CMD_SUCCESS) {
590 sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error); 590 sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
591 } 591 }
@@ -936,18 +936,18 @@ bool handle_pointer_scroll(wlc_handle view, uint32_t time, const struct wlc_modi
936 int y_amount = (int)_amount[1]; 936 int y_amount = (int)_amount[1];
937 937
938 if (x_amount > 0 && strcmp(config->floating_scroll_up_cmd, "")) { 938 if (x_amount > 0 && strcmp(config->floating_scroll_up_cmd, "")) {
939 handle_command(config->floating_scroll_up_cmd); 939 handle_command(config->floating_scroll_up_cmd, CONTEXT_BINDING);
940 return EVENT_HANDLED; 940 return EVENT_HANDLED;
941 } else if (x_amount < 0 && strcmp(config->floating_scroll_down_cmd, "")) { 941 } else if (x_amount < 0 && strcmp(config->floating_scroll_down_cmd, "")) {
942 handle_command(config->floating_scroll_down_cmd); 942 handle_command(config->floating_scroll_down_cmd, CONTEXT_BINDING);
943 return EVENT_HANDLED; 943 return EVENT_HANDLED;
944 } 944 }
945 945
946 if (y_amount > 0 && strcmp(config->floating_scroll_right_cmd, "")) { 946 if (y_amount > 0 && strcmp(config->floating_scroll_right_cmd, "")) {
947 handle_command(config->floating_scroll_right_cmd); 947 handle_command(config->floating_scroll_right_cmd, CONTEXT_BINDING);
948 return EVENT_HANDLED; 948 return EVENT_HANDLED;
949 } else if (y_amount < 0 && strcmp(config->floating_scroll_left_cmd, "")) { 949 } else if (y_amount < 0 && strcmp(config->floating_scroll_left_cmd, "")) {
950 handle_command(config->floating_scroll_left_cmd); 950 handle_command(config->floating_scroll_left_cmd, CONTEXT_BINDING);
951 return EVENT_HANDLED; 951 return EVENT_HANDLED;
952 } 952 }
953 } 953 }
@@ -960,7 +960,7 @@ static void handle_wlc_ready(void) {
960 config->active = true; 960 config->active = true;
961 while (config->cmd_queue->length) { 961 while (config->cmd_queue->length) {
962 char *line = config->cmd_queue->items[0]; 962 char *line = config->cmd_queue->items[0];
963 struct cmd_results *res = handle_command(line); 963 struct cmd_results *res = handle_command(line, CONTEXT_CONFIG);
964 if (res->status != CMD_SUCCESS) { 964 if (res->status != CMD_SUCCESS) {
965 sway_log(L_ERROR, "Error on line '%s': %s", line, res->error); 965 sway_log(L_ERROR, "Error on line '%s': %s", line, res->error);
966 } 966 }
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index ebb5ce58..e575081b 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -312,7 +312,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
312 switch (client->current_command) { 312 switch (client->current_command) {
313 case IPC_COMMAND: 313 case IPC_COMMAND:
314 { 314 {
315 struct cmd_results *results = handle_command(buf); 315 struct cmd_results *results = handle_command(buf, CONTEXT_IPC);
316 const char *json = cmd_results_to_json(results); 316 const char *json = cmd_results_to_json(results);
317 char reply[256]; 317 char reply[256];
318 int length = snprintf(reply, sizeof(reply), "%s", json); 318 int length = snprintf(reply, sizeof(reply), "%s", json);
diff --git a/sway/security.c b/sway/security.c
index 670cae56..2ccc30fd 100644
--- a/sway/security.c
+++ b/sway/security.c
@@ -64,3 +64,20 @@ enum command_context get_command_policy(const char *cmd) {
64 64
65 return default_policy; 65 return default_policy;
66} 66}
67
68const char *command_policy_str(enum command_context context) {
69 switch (context) {
70 case CONTEXT_ALL:
71 return "all";
72 case CONTEXT_CONFIG:
73 return "config";
74 case CONTEXT_BINDING:
75 return "binding";
76 case CONTEXT_IPC:
77 return "IPC";
78 case CONTEXT_CRITERIA:
79 return "criteria";
80 default:
81 return "unknown";
82 }
83}