Add IPC security policy command handlers
This commit is contained in:
parent
e9e1a6a409
commit
c8dc4925d1
|
@ -120,6 +120,7 @@ sway_cmd cmd_gaps;
|
||||||
sway_cmd cmd_hide_edge_borders;
|
sway_cmd cmd_hide_edge_borders;
|
||||||
sway_cmd cmd_include;
|
sway_cmd cmd_include;
|
||||||
sway_cmd cmd_input;
|
sway_cmd cmd_input;
|
||||||
|
sway_cmd cmd_ipc;
|
||||||
sway_cmd cmd_kill;
|
sway_cmd cmd_kill;
|
||||||
sway_cmd cmd_layout;
|
sway_cmd cmd_layout;
|
||||||
sway_cmd cmd_log_colors;
|
sway_cmd cmd_log_colors;
|
||||||
|
@ -192,4 +193,8 @@ sway_cmd input_cmd_pointer_accel;
|
||||||
sway_cmd input_cmd_scroll_method;
|
sway_cmd input_cmd_scroll_method;
|
||||||
sway_cmd input_cmd_tap;
|
sway_cmd input_cmd_tap;
|
||||||
|
|
||||||
|
sway_cmd cmd_ipc_cmd;
|
||||||
|
sway_cmd cmd_ipc_events;
|
||||||
|
sway_cmd cmd_ipc_event_cmd;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -180,6 +180,7 @@ static struct cmd_handler handlers[] = {
|
||||||
{ "hide_edge_borders", cmd_hide_edge_borders },
|
{ "hide_edge_borders", cmd_hide_edge_borders },
|
||||||
{ "include", cmd_include },
|
{ "include", cmd_include },
|
||||||
{ "input", cmd_input },
|
{ "input", cmd_input },
|
||||||
|
{ "ipc", cmd_ipc },
|
||||||
{ "kill", cmd_kill },
|
{ "kill", cmd_kill },
|
||||||
{ "layout", cmd_layout },
|
{ "layout", cmd_layout },
|
||||||
{ "log_colors", cmd_log_colors },
|
{ "log_colors", cmd_log_colors },
|
||||||
|
@ -292,6 +293,26 @@ static struct cmd_handler bar_colors_handlers[] = {
|
||||||
{ "urgent_workspace", bar_colors_cmd_urgent_workspace },
|
{ "urgent_workspace", bar_colors_cmd_urgent_workspace },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct cmd_handler ipc_handlers[] = {
|
||||||
|
{ "bar-config", cmd_ipc_cmd },
|
||||||
|
{ "command", cmd_ipc_cmd },
|
||||||
|
{ "events", cmd_ipc_events },
|
||||||
|
{ "inputs", cmd_ipc_cmd },
|
||||||
|
{ "marks", cmd_ipc_cmd },
|
||||||
|
{ "outputs", cmd_ipc_cmd },
|
||||||
|
{ "tree", cmd_ipc_cmd },
|
||||||
|
{ "workspaces", cmd_ipc_cmd },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct cmd_handler ipc_event_handlers[] = {
|
||||||
|
{ "binding", cmd_ipc_event_cmd },
|
||||||
|
{ "input", cmd_ipc_event_cmd },
|
||||||
|
{ "mode", cmd_ipc_event_cmd },
|
||||||
|
{ "output", cmd_ipc_event_cmd },
|
||||||
|
{ "window", cmd_ipc_event_cmd },
|
||||||
|
{ "workspace", cmd_ipc_event_cmd },
|
||||||
|
};
|
||||||
|
|
||||||
static int handler_compare(const void *_a, const void *_b) {
|
static int handler_compare(const void *_a, const void *_b) {
|
||||||
const struct cmd_handler *a = _a;
|
const struct cmd_handler *a = _a;
|
||||||
const struct cmd_handler *b = _b;
|
const struct cmd_handler *b = _b;
|
||||||
|
@ -311,10 +332,17 @@ static struct cmd_handler *find_handler(char *line, enum cmd_status block) {
|
||||||
sizeof(bar_colors_handlers) / sizeof(struct cmd_handler),
|
sizeof(bar_colors_handlers) / sizeof(struct cmd_handler),
|
||||||
sizeof(struct cmd_handler), handler_compare);
|
sizeof(struct cmd_handler), handler_compare);
|
||||||
} else if (block == CMD_BLOCK_INPUT) {
|
} else if (block == CMD_BLOCK_INPUT) {
|
||||||
sway_log(L_DEBUG, "looking at input handlers");
|
|
||||||
res = bsearch(&d, input_handlers,
|
res = bsearch(&d, input_handlers,
|
||||||
sizeof(input_handlers) / sizeof(struct cmd_handler),
|
sizeof(input_handlers) / sizeof(struct cmd_handler),
|
||||||
sizeof(struct cmd_handler), handler_compare);
|
sizeof(struct cmd_handler), handler_compare);
|
||||||
|
} else if (block == CMD_BLOCK_IPC) {
|
||||||
|
res = bsearch(&d, ipc_handlers,
|
||||||
|
sizeof(ipc_handlers) / sizeof(struct cmd_handler),
|
||||||
|
sizeof(struct cmd_handler), handler_compare);
|
||||||
|
} else if (block == CMD_BLOCK_IPC_EVENTS) {
|
||||||
|
res = bsearch(&d, ipc_event_handlers,
|
||||||
|
sizeof(ipc_event_handlers) / sizeof(struct cmd_handler),
|
||||||
|
sizeof(struct cmd_handler), handler_compare);
|
||||||
} else {
|
} else {
|
||||||
res = bsearch(&d, handlers,
|
res = bsearch(&d, handlers,
|
||||||
sizeof(handlers) / sizeof(struct cmd_handler),
|
sizeof(handlers) / sizeof(struct cmd_handler),
|
||||||
|
|
140
sway/commands/ipc.c
Normal file
140
sway/commands/ipc.c
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sway/commands.h"
|
||||||
|
#include "sway/config.h"
|
||||||
|
#include "ipc.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
struct cmd_results *cmd_ipc(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "ipc", EXPECTED_EQUAL_TO, 1))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->reading && strcmp("{", argv[0]) != 0) {
|
||||||
|
return cmd_results_new(CMD_INVALID, "ipc",
|
||||||
|
"Expected '{' at start of IPC config definition.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config->reading) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "ipc", "Can only be used in config file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cmd_results *cmd_ipc_events(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "events", EXPECTED_EQUAL_TO, 1))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config->reading && strcmp("{", argv[0]) != 0) {
|
||||||
|
return cmd_results_new(CMD_INVALID, "events",
|
||||||
|
"Expected '{' at start of IPC event config definition.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config->reading) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "events", "Can only be used in config file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd_results_new(CMD_BLOCK_IPC_EVENTS, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cmd_results *cmd_ipc_cmd(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "ipc", EXPECTED_EQUAL_TO, 1))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
if (strcmp(argv[0], "enabled") == 0) {
|
||||||
|
enabled = true;
|
||||||
|
} else if (strcmp(argv[0], "disabled") == 0) {
|
||||||
|
enabled = false;
|
||||||
|
} else {
|
||||||
|
return cmd_results_new(CMD_INVALID, argv[-1],
|
||||||
|
"Argument must be one of 'enabled' or 'disabled'");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char *name;
|
||||||
|
enum ipc_command_type type;
|
||||||
|
} types[] = {
|
||||||
|
{ "command", IPC_COMMAND },
|
||||||
|
{ "workspaces", IPC_GET_WORKSPACES },
|
||||||
|
{ "outputs", IPC_GET_OUTPUTS },
|
||||||
|
{ "tree", IPC_GET_TREE },
|
||||||
|
{ "marks", IPC_GET_MARKS },
|
||||||
|
{ "bar-config", IPC_GET_BAR_CONFIG },
|
||||||
|
{ "inputs", IPC_GET_INPUTS },
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t type = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i) {
|
||||||
|
if (strcmp(types[i].name, argv[-1]) == 0) {
|
||||||
|
type = types[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
config->ipc_policy |= type;
|
||||||
|
sway_log(L_DEBUG, "Enabled IPC %s feature", argv[-1]);
|
||||||
|
} else {
|
||||||
|
config->ipc_policy &= ~type;
|
||||||
|
sway_log(L_DEBUG, "Disabled IPC %s feature", argv[-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cmd_results *cmd_ipc_event_cmd(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "ipc", EXPECTED_EQUAL_TO, 1))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
if (strcmp(argv[0], "enabled") == 0) {
|
||||||
|
enabled = true;
|
||||||
|
} else if (strcmp(argv[0], "disabled") == 0) {
|
||||||
|
enabled = false;
|
||||||
|
} else {
|
||||||
|
return cmd_results_new(CMD_INVALID, argv[-1],
|
||||||
|
"Argument must be one of 'enabled' or 'disabled'");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char *name;
|
||||||
|
enum ipc_command_type type;
|
||||||
|
} types[] = {
|
||||||
|
{ "workspace", event_mask(IPC_EVENT_WORKSPACE) },
|
||||||
|
{ "output", event_mask(IPC_EVENT_OUTPUT) },
|
||||||
|
{ "mode", event_mask(IPC_EVENT_MODE) },
|
||||||
|
{ "window", event_mask(IPC_EVENT_WINDOW) },
|
||||||
|
{ "binding", event_mask(IPC_EVENT_BINDING) },
|
||||||
|
{ "input", event_mask(IPC_EVENT_INPUT) },
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t type = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i) {
|
||||||
|
if (strcmp(types[i].name, argv[-1]) == 0) {
|
||||||
|
type = types[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
config->ipc_policy |= type;
|
||||||
|
sway_log(L_DEBUG, "Enabled IPC %s event", argv[-1]);
|
||||||
|
} else {
|
||||||
|
config->ipc_policy &= ~type;
|
||||||
|
sway_log(L_DEBUG, "Disabled IPC %s event", argv[-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||||
|
}
|
|
@ -641,6 +641,22 @@ bool read_config(FILE *file, struct sway_config *config) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CMD_BLOCK_IPC:
|
||||||
|
if (block == CMD_BLOCK_END) {
|
||||||
|
block = CMD_BLOCK_IPC;
|
||||||
|
} else {
|
||||||
|
sway_log(L_ERROR, "Invalid block '%s'", line);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_BLOCK_IPC_EVENTS:
|
||||||
|
if (block == CMD_BLOCK_IPC) {
|
||||||
|
block = CMD_BLOCK_IPC_EVENTS;
|
||||||
|
} else {
|
||||||
|
sway_log(L_ERROR, "Invalid block '%s'", line);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_BLOCK_END:
|
case CMD_BLOCK_END:
|
||||||
switch(block) {
|
switch(block) {
|
||||||
case CMD_BLOCK_MODE:
|
case CMD_BLOCK_MODE:
|
||||||
|
@ -671,6 +687,16 @@ bool read_config(FILE *file, struct sway_config *config) {
|
||||||
block = CMD_BLOCK_END;
|
block = CMD_BLOCK_END;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CMD_BLOCK_IPC:
|
||||||
|
sway_log(L_DEBUG, "End of IPC block");
|
||||||
|
block = CMD_BLOCK_END;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMD_BLOCK_IPC_EVENTS:
|
||||||
|
sway_log(L_DEBUG, "End of IPC events block");
|
||||||
|
block = CMD_BLOCK_IPC;
|
||||||
|
break;
|
||||||
|
|
||||||
case CMD_BLOCK_END:
|
case CMD_BLOCK_END:
|
||||||
sway_log(L_ERROR, "Unmatched }");
|
sway_log(L_ERROR, "Unmatched }");
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue